mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 15:02:25 +00:00
b4c4681733
* differentiates request types that where merged formerly per module; e.g. instead of type Superblock_control::Request, there are now types * Superblock_control::Read_vbas * Superblock_control::Write_vbas * Superblock_control::Rekey * Superblock_control::Initialize * ... each holding only the state and functionality that is required for exactly that request * removes all classes of the Tresor module framework and adapts all Tresor- and File-Vault- related libs, apps, and tests accordingly * the former "channel" state is merged into the new request types, meaning, a request manages no longer only the "call" to a functionality but also the execution of that functionality; every request has a lifetime equal to the "call" and an execute method to be driven forward * state that is used by a request but has a longer lifetime (e.g. VFS file handles in Tresor::Crypto) is managed by the top level of the user and handed over via the execute arguments; however, the synchronization of multiple requests on this state is done by the module (e.g. Tresor::Crypto) * requests are now driven explicitly as first argument of the (overloaded) execute method of their module; the module can, however, stall a request by returning false without doing anything (used for synchronization on resources) * introduces Request_helper, Generated_request and Generatable_request in the Tresor namespace in order to avoid the redundancy of sub-request generation and execution * moves access to Client-Data pointers up to Tresor::Virtual_block_device in order to simplify Tresor::Block_io and Tresor::Crypto * removes Tresor::Client_data and introduces pure interface Client_data_interface in order to remove Tresor::Client_data and move management of Client Data to the top level of a Tresor user * introduces pure interface Crypto_files_interface in order to move management of Crypto files to the top level of a Tresor user * moves management of Block-IO and Trust-Anchor files to the top level of a Tresor user * adapts all execute methods, so, that they return the progress state instead of modifying a reference argument * removes Tresor::Request_and Tresor:Request and instead implements scheduling at the top level of the Tresor user * the Tresor Tester uses a list as schedule that holds Command objects; this list ensures, that commands are started in the order of configuration the Command type is a merge of the state of all possible commands that can be configured at the Tresor Tester; the actual Tresor requests (if any) are then allocated on-demand only * the Tresor VFS plugin does not use a dynamic data structure for scheduling; the plugin has 5 members that each reflect a distinct type of operation: * initialize operation * deinitialize operation * data operation * extend operation * rekey operation consequently, of each type, there can be only one operation in-flight at a time; at the user front-end each operation (except "initialize") can be controlled through a dedicated VFS file; for each of these files, the VFS expects only one handle to be open at a time and only one file operation (read, write, sync) active at a time; once an operation gets started it is finished without preemtion (except of the interleaving at rekey and extend); when multiple operations are waiting to be started the plugin follows a static priority scheme: init op > deinit op > data op > extend op > rekey op there are some operation-specific details * the initialize operation is started only by the plugin itself on startup and will be driven as side effect by subsequent user calls to file operations * the data file is the only contiguous file in the front end and the file operations work as on usual data files * the other 3 files are transactional files and the user is expected to follow this scheme when operating on them 1) stat (to determine file size) 2) seek to offset 0 3) read entire file once (this will be queued until there is no operation of this type pending anymore and return the last result: "none" | "failed" | "succeeded"; used primarily for synchronization) 4) write operation parameters (this returns immediately and marks the operation as "requested") 5) read entire file once (the same as above but this time in order to determine the operation result) * the rekey op and deinitialize op are requested by writing "true" * the extend op is requested by writing "tree=[TREE], blocks=[BLOCKS]" where TREE is either "vbd" or "ft" and BLOCKS is the number of physical 4K blocks by which the physical range of the tresor container expands (the physical range always starts at block address 0 and is always expanded upwards) * replaces the former <trust-anchor op="initialize"> command at the Tresor Tester with <initialize-trust-achor> as there are no other trust anchor operations that can be requested through the Tester config anyway * removes the "sync" attribute from all commands at the Tresor Tester except from <request op="rekey">, <request "extend_ft">, <request op="extend_vbd">; as the Tester controls scheduling now, requests are generally synchronous; at the rekeying and extension commands, the "sync" attribute determines wether subsequent commands are interleaved with the execution of these commands (if possible) * removes "debug" config attribute from Tresor VFS plugin and reworks "verbose" attribute to generate more sensible output * removes NONCOPYABLE macro and instead uses Genode::Noncopyable and in-place Constructors deletion * introduces types Attr and Execute_attr where a constructor or execute method have many arguments in order to raise readability * renames the "hashsum" file that is provided by the Tresor Trust-Anchor VFS plugin to "hash" in order to become conformant with the wording in the Tresor lib * makes the VFS Tresor test an automated test by merging in the functionality of vfs_tresor_init.run and removing the interactive front end; removes vfs_tresor_init.run as it is not needed anymore; adds consideration for autopilot file structure in the Test and adds it to autopilot.list * removes all snapshot controls and the progress files for rekeying and extending from the Tresor VFS plugin; both functionalities were tested only rudimentary by the VFS Tresor test and are not supported with the only real user, the File Vault * use /* .. */ instead of // .. * use (..) instead of { .. } in init lists Ref #5148
235 lines
4.8 KiB
Bash
235 lines
4.8 KiB
Bash
#!/bin/bash
|
|
|
|
echo "--- Automated Tresor testing ---"
|
|
|
|
produce_pattern() {
|
|
local pattern="$1"
|
|
local size="$2"
|
|
[ "$pattern" = "" ] && exit 1
|
|
|
|
local tmp_file="/tmp/pattern.tmp"
|
|
local N=1041
|
|
# prints numbers until N and uses pattern as delimiter and
|
|
# generates about 4 KiB of data with a 1 byte pattern
|
|
seq -s "$pattern" $N > $tmp_file
|
|
dd if=$tmp_file count=1 bs=$size 2>/dev/null
|
|
}
|
|
|
|
test_write_1() {
|
|
local data_file="$1"
|
|
local offset=$2
|
|
|
|
local pattern_file="/tmp/pattern"
|
|
dd bs=4096 count=1 if=$pattern_file of=$data_file seek=$offset 2>/dev/null || exit 1
|
|
}
|
|
|
|
test_read_seq_unaligned_512() {
|
|
local data_file="$1"
|
|
local length="$2"
|
|
dd bs=512 count=$((length / 512)) if=$data_file of=/dev/null
|
|
}
|
|
|
|
test_read_compare_1() {
|
|
local data_file="$1"
|
|
local offset=$2
|
|
|
|
local pattern_file="/tmp/pattern"
|
|
rm $pattern_file.out 2>/dev/null
|
|
|
|
dd bs=4096 count=1 if=$data_file of=$pattern_file.out skip=$offset 2>/dev/null || exit 1
|
|
local sha1=$(sha1sum $pattern_file)
|
|
local sha1_sum=${sha1:0:40}
|
|
|
|
local sha1out=$(sha1sum $pattern_file.out)
|
|
local sha1out_sum=${sha1out:0:40}
|
|
|
|
if [ "$sha1_sum" != "$sha1out_sum" ]; then
|
|
echo "mismatch for block $offset:"
|
|
echo " expected: $sha1_sum"
|
|
echo -n " "
|
|
dd if=$pattern_file bs=32 count=1 2>/dev/null; echo
|
|
echo " got: $sha1out_sum"
|
|
echo -n " "
|
|
dd if=$pattern_file.out bs=32 count=1 2>/dev/null; echo
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
test_deinitialize() {
|
|
local tresor_dir="$1"
|
|
echo "Deinitialize"
|
|
local state="$(< $tresor_dir/control/deinitialize)"
|
|
echo true > $tresor_dir/control/deinitialize
|
|
}
|
|
|
|
wait_for_deinitialize() {
|
|
local tresor_dir="$1"
|
|
echo "Wait for deinitialize"
|
|
local state="$(< $tresor_dir/control/deinitialize)"
|
|
}
|
|
|
|
test_rekey_start() {
|
|
local tresor_dir="$1"
|
|
|
|
echo "Start rekeying"
|
|
local state="$(< $tresor_dir/control/rekey)"
|
|
echo true > $tresor_dir/control/rekey
|
|
echo "Reykeying started"
|
|
}
|
|
|
|
test_vbd_extension() {
|
|
local tresor_dir="$1"
|
|
local nr_of_phys_blocks="$2"
|
|
|
|
echo "Start extending VBD"
|
|
echo tree=vbd, blocks=$nr_of_phys_blocks > $tresor_dir/control/extend
|
|
echo "VBD extension started"
|
|
}
|
|
|
|
test_ft_extension() {
|
|
local tresor_dir="$1"
|
|
local nr_of_phys_blocks="$2"
|
|
|
|
echo "Start extending FT"
|
|
echo tree=ft, blocks=$nr_of_phys_blocks > $tresor_dir/control/extend
|
|
echo "FT extension started"
|
|
}
|
|
|
|
test_rekey_state() {
|
|
local tresor_dir="$1"
|
|
local state="$(< $tresor_dir/control/rekey)"
|
|
local progress="$(< $tresor_dir/control/rekey_progress)"
|
|
|
|
local result="unknown"
|
|
case "$progress" in
|
|
*at*)
|
|
result="$progress"
|
|
;;
|
|
*idle*)
|
|
result="done"
|
|
;;
|
|
esac
|
|
|
|
echo "Rekeying state: $state progress: $result"
|
|
}
|
|
|
|
test_rekey() {
|
|
local tresor_dir="$1"
|
|
|
|
test_rekey_start "$tresor_dir"
|
|
|
|
wait_for_rekeying "$tresor_dir" "yes"
|
|
}
|
|
|
|
wait_for_rekeying() {
|
|
local tresor_dir="$1"
|
|
local verbose="$2"
|
|
local result="unknown"
|
|
|
|
echo "Wait for rekeying to finish..."
|
|
while : ; do
|
|
local done=0
|
|
local file_content="$(< $tresor_dir/control/rekey)"
|
|
# XXX remove later
|
|
echo "file_content: ${file_content}"
|
|
case "$file_content" in
|
|
*failed*)
|
|
done=1;
|
|
;;
|
|
*succeeded*)
|
|
done=1;
|
|
;;
|
|
esac
|
|
if [ $done -gt 0 ]; then
|
|
break
|
|
fi
|
|
done
|
|
echo "Rekeying done"
|
|
}
|
|
|
|
wait_for_vbd_extension() {
|
|
local tresor_dir="$1"
|
|
|
|
echo "Wait for VBD extension to finish..."
|
|
while : ; do
|
|
local done=0
|
|
local file_content="$(< $tresor_dir/control/extend)"
|
|
# XXX remove later
|
|
echo "file_content: ${file_content}"
|
|
case "$file_content" in
|
|
*failed*)
|
|
done=1;
|
|
;;
|
|
*succeeded*)
|
|
done=1;
|
|
;;
|
|
esac
|
|
if [ $done -gt 0 ]; then
|
|
break
|
|
fi
|
|
done
|
|
echo "VBD extension done"
|
|
}
|
|
|
|
wait_for_ft_extension() {
|
|
local tresor_dir="$1"
|
|
|
|
echo "Wait for FT extension to finish..."
|
|
while : ; do
|
|
local done=0
|
|
local file_content="$(< $tresor_dir/control/extend)"
|
|
# XXX remove later
|
|
echo "file_content: ${file_content}"
|
|
case "$file_content" in
|
|
*failed*)
|
|
done=1;
|
|
;;
|
|
*succeeded*)
|
|
done=1;
|
|
;;
|
|
esac
|
|
if [ $done -gt 0 ]; then
|
|
break
|
|
fi
|
|
done
|
|
echo "FT extension done"
|
|
}
|
|
|
|
main() {
|
|
local tresor_dir="/dev/tresor"
|
|
local data_file="$tresor_dir/current/data"
|
|
echo "list files..."
|
|
ls -l $tresor_dir
|
|
echo "produce pattern..."
|
|
local pattern_file="/tmp/pattern"
|
|
produce_pattern "1" "4096" > $pattern_file
|
|
echo "write..."
|
|
test_write_1 "$data_file" "20"
|
|
echo "read..."
|
|
test_read_compare_1 "$data_file" "20"
|
|
test_write_1 "$data_file" "20"
|
|
echo "extend VBD..."
|
|
test_vbd_extension "$tresor_dir" "100"
|
|
test_write_1 "$data_file" "2"
|
|
test_read_compare_1 "$data_file" "2"
|
|
wait_for_vbd_extension "$tresor_dir"
|
|
echo "extend FT..."
|
|
test_ft_extension "$tresor_dir" "100"
|
|
test_write_1 "$data_file" "2"
|
|
test_read_compare_1 "$data_file" "2"
|
|
wait_for_ft_extension "$tresor_dir"
|
|
echo "rekey..."
|
|
test_rekey_start "$tresor_dir"
|
|
test_write_1 "$data_file" "2"
|
|
test_read_compare_1 "$data_file" "2"
|
|
wait_for_rekeying "$tresor_dir" "no"
|
|
test_deinitialize "$tresor_dir"
|
|
wait_for_deinitialize "$tresor_dir"
|
|
echo "done!"
|
|
}
|
|
|
|
main "$@"
|
|
|
|
# just drop into shell
|
|
exit 0
|