diff options
Diffstat (limited to 'tests/luks2-reencryption-mangle-test')
-rwxr-xr-x | tests/luks2-reencryption-mangle-test | 156 |
1 files changed, 99 insertions, 57 deletions
diff --git a/tests/luks2-reencryption-mangle-test b/tests/luks2-reencryption-mangle-test index 8f308f5..5aa62e4 100755 --- a/tests/luks2-reencryption-mangle-test +++ b/tests/luks2-reencryption-mangle-test @@ -9,6 +9,7 @@ CRYPTSETUP_VALGRIND=../.libs/cryptsetup CRYPTSETUP_LIB_VALGRIND=../.libs IMG=reenc-mangle-data IMG_HDR=$IMG.hdr +IMG_HDR_BCP=$IMG_HDR.bcp IMG_JSON=$IMG.json KEY1=key1 DEV_NAME=reenc3492834 @@ -21,7 +22,7 @@ JSON_MSIZE=16384 function remove_mapping() { [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME - rm -f $IMG $IMG_HDR $IMG_JSON $KEY1 >/dev/null 2>&1 + rm -f $IMG $IMG_HDR $IMG_HDR_BCP $IMG_JSON $KEY1 >/dev/null 2>&1 } function fail() @@ -43,15 +44,15 @@ function skip() function bin_check() { - which $1 >/dev/null 2>&1 || skip "WARNING: test require $1 binary, test skipped." + command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." } function img_json_save() { + local _hdr=$IMG + [ -z "$1" ] || _hdr="$1" # FIXME: why --json-file cannot be used? - #$CRYPTSETUP luksDump --dump-json-metadata $IMG | jq -c -M | tr -d '\n' >$IMG_JSON - local LUKS2_JSON_SIZE=$(($JSON_MSIZE - 4096)) - _dd if=$IMG count=$LUKS2_JSON_SIZE skip=4096 | jq -c -M . | tr -d '\n' >$IMG_JSON + $CRYPTSETUP luksDump --dump-json-metadata $_hdr | jq -c -M . | tr -d '\n' >$IMG_JSON } function img_json_dump() @@ -86,7 +87,6 @@ function img_prepare_raw() # $1 options function img_prepare() # $1 options { img_prepare_raw - # FIXME: resilience is not saved here (always none)? $CRYPTSETUP reencrypt $IMG $CS_PARAMS -q --init-only --resilience none $1 >/dev/null 2>&1 [ $? -ne 0 ] && skip "Reencryption unsupported, test skipped." img_json_save @@ -101,6 +101,7 @@ function _dd() # header mangle functions function img_update_json() { + local _hdr="$IMG" local LUKS2_BIN1_OFFSET=448 local LUKS2_BIN2_OFFSET=$((LUKS2_BIN1_OFFSET + $JSON_MSIZE)) local LUKS2_JSON_SIZE=$(($JSON_MSIZE - 4096)) @@ -113,24 +114,26 @@ function img_update_json() echo $JSON | tr -d '\n' >$IMG_JSON || fail fi + [ -z "$2" ] || _hdr="$2" + # wipe JSON areas - _dd if=/dev/zero of=$IMG count=$LUKS2_JSON_SIZE seek=4096 - _dd if=/dev/zero of=$IMG count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) + _dd if=/dev/zero of=$_hdr count=$LUKS2_JSON_SIZE seek=4096 + _dd if=/dev/zero of=$_hdr count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) # write JSON data - _dd if=$IMG_JSON of=$IMG count=$LUKS2_JSON_SIZE seek=4096 - _dd if=$IMG_JSON of=$IMG count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) + _dd if=$IMG_JSON of=$_hdr count=$LUKS2_JSON_SIZE seek=4096 + _dd if=$IMG_JSON of=$_hdr count=$LUKS2_JSON_SIZE seek=$(($JSON_MSIZE + 4096)) # erase sha256 checksums - _dd if=/dev/zero of=$IMG count=64 seek=$LUKS2_BIN1_OFFSET - _dd if=/dev/zero of=$IMG count=64 seek=$LUKS2_BIN2_OFFSET + _dd if=/dev/zero of=$_hdr count=64 seek=$LUKS2_BIN1_OFFSET + _dd if=/dev/zero of=$_hdr count=64 seek=$LUKS2_BIN2_OFFSET # calculate sha256 and write chexksums - local SUM1_HEX=$(_dd if=$IMG count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) - echo $SUM1_HEX | xxd -r -p | _dd of=$IMG seek=$LUKS2_BIN1_OFFSET count=64 || fail + local SUM1_HEX=$(_dd if=$_hdr count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM1_HEX | xxd -r -p | _dd of=$_hdr seek=$LUKS2_BIN1_OFFSET count=64 || fail - local SUM2_HEX=$(_dd if=$IMG skip=$JSON_MSIZE count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) - echo $SUM2_HEX | xxd -r -p | _dd of=$IMG seek=$LUKS2_BIN2_OFFSET count=64 || fail + local SUM2_HEX=$(_dd if=$_hdr skip=$JSON_MSIZE count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM2_HEX | xxd -r -p | _dd of=$_hdr seek=$LUKS2_BIN2_OFFSET count=64 || fail img_hash_save } @@ -145,6 +148,12 @@ function img_check_ok() $CRYPTSETUP repair $IMG $CS_PARAMS || fail } +function img_check_dump_ok() +{ + $CRYPTSETUP luksDump $IMG >/dev/null || fail + img_check_fail +} + function img_check_fail() { if [ $(id -u) == 0 ]; then @@ -157,43 +166,21 @@ function img_check_fail() function img_run_reenc_ok() { -local EXPECT_TIMEOUT=5 -[ -n "$VALG" ] && EXPECT_TIMEOUT=60 -# For now, we cannot run reencryption in batch mode for non-block device. Just fake the terminal here. -expect_run - >/dev/null <<EOF -proc abort {} { send_error "Timeout. "; exit 2 } -set timeout $EXPECT_TIMEOUT -eval spawn $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --disable-locks --resilience none -expect timeout abort "Are you sure? (Type 'yes' in capital letters):" -send "YES\n" -expect timeout abort eof -exit -EOF -[ $? -eq 0 ] || fail "Expect script failed." + $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS -q --disable-locks --force-offline-reencrypt --resilience none || fail +} + +function img_run_reenc_ok_data_shift() +{ + $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS -q --disable-locks --force-offline-reencrypt || fail } function img_run_reenc_fail() { -local EXPECT_TIMEOUT=5 -[ -n "$VALG" ] && EXPECT_TIMEOUT=60 -# For now, we cannot run reencryption in batch mode for non-block device. Just fake the terminal here. -expect_run - >/dev/null <<EOF -proc abort {} { send_error "Timeout. "; exit 42 } -set timeout $EXPECT_TIMEOUT -eval spawn $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --disable-locks -expect timeout abort "Are you sure? (Type 'yes' in capital letters):" -send "YES\n" -expect timeout abort eof -catch wait result -exit [lindex \$result 3] -EOF -local ret=$? -[ $ret -eq 0 ] && fail "Reencryption passed (should have failed)." -[ $ret -eq 42 ] && fail "Expect script failed." +$CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --force-offline-reencrypt --disable-locks -q 2>/dev/null && fail "Reencryption passed (should have failed)." img_hash_unchanged } -function img_check_fail_repair_ok() +function img_check_fail_repair() { if [ $(id -u) == 0 ]; then $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME 2>/dev/null && fail @@ -205,9 +192,20 @@ function img_check_fail_repair_ok() $CRYPTSETUP repair $IMG $CS_PARAMS || fail img_check_ok +} + +function img_check_fail_repair_ok() +{ + img_check_fail_repair img_run_reenc_ok } +function img_check_fail_repair_ok_data_shift() +{ + img_check_fail_repair + img_run_reenc_ok_data_shift +} + function valgrind_setup() { bin_check valgrind @@ -219,26 +217,20 @@ function valgrind_setup() function valgrind_run() { - INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" + export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" + $CRYPTSETUP_RAW "$@" } -function expect_run() -{ - export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" - expect "$@" -} +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." bin_check jq bin_check sha256sum bin_check xxd -bin_check expect export LANG=C [ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run -#while false; do - echo "[1] Reencryption with old flag is rejected" img_prepare img_update_json '.config.requirements.mandatory = ["online-reencryptx"]' @@ -253,6 +245,25 @@ img_prepare img_update_json 'del(.digests."2") | .config.requirements.mandatory = ["online-reencrypt"]' img_check_fail_repair_ok +# Simulate future version of reencrypt flag (should pass luksDump) +img_prepare +img_update_json '.config.requirements.mandatory = ["online-reencrypt-v999"]' +img_check_dump_ok + +# Multiple reencrypt requirement flags makes LUKS2 invalid +img_prepare +img_update_json '.config.requirements.mandatory = .config.requirements.mandatory + ["online-reencrypt-v999"]' +img_check_fail + +img_prepare +img_update_json '.config.requirements.mandatory = .config.requirements.mandatory + ["online-reencrypt"]' +img_check_fail + +# just regular unknown requirement +img_prepare +img_update_json '.config.requirements.mandatory = .config.requirements.mandatory + ["online-reencrypt-v3X"]' +img_check_dump_ok + # This must fail for new releases echo "[2] Old reencryption in-progress (journal)" img_prepare @@ -380,7 +391,7 @@ img_update_json ' .digests."0".segments = ["0","2"] | .digests."1".segments = ["1","3"] | .config.requirements.mandatory = ["online-reencrypt"]' -img_check_fail_repair_ok +img_check_fail_repair_ok_data_shift # # NEW metadata (with reenc digest) @@ -402,7 +413,6 @@ img_prepare '--reduce-device-size 2M' img_update_json '.keyslots."2".area.shift_size = ((.keyslots."2".area.shift_size|tonumber / 2)|tostring)' img_check_fail -#FIXME: cannot check with correct digest for now (--init-only does not store area type) img_prepare img_update_json ' .keyslots."2".area.type = "checksum" | @@ -502,5 +512,37 @@ img_update_json ' }' $CRYPTSETUP reencrypt $IMG $CS_PARAMS >/dev/null 2>&1 && fail +echo "[9] Decryption with datashift" +img_prepare_raw +$CRYPTSETUP reencrypt $CS_PARAMS --decrypt --init-only --force-offline-reencrypt --resilience checksum --header $IMG_HDR $IMG || fail +cp $IMG_HDR $IMG_HDR_BCP + +# change hash +img_json_save $IMG_HDR_BCP +img_update_json '.keyslots."1".area.hash = "sha12345"' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# change sector size +img_json_save $IMG_HDR_BCP +img_update_json '.keyslots."1".area.sector_size = 1024' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# replace with new resilience mode +img_json_save $IMG_HDR_BCP +img_update_json 'del(.keyslots."1".area.hash) | + del(.keyslots."1".sector_size) | + .keyslots."1".area.type = "datashift-journal"' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# downgrade reencryption requirement +img_json_save $IMG_HDR_BCP +img_update_json '.config.requirements.mandatory = ["online-reencrypt-v2"]' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# change datashift value +img_json_save $IMG_HDR_BCP +img_update_json '.keyslots."1".area.shift_size = (((.keyslots."1".area.shift_size | tonumber) - 4096) | tostring)' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + remove_mapping exit 0 |