Imported Upstream version 2.6.1
[platform/upstream/cryptsetup.git] / tests / luks2-reencryption-mangle-test
index 8f308f5..5aa62e4 100755 (executable)
@@ -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