diff options
Diffstat (limited to '')
-rwxr-xr-x | tests/luks2-reencryption-test | 2207 |
1 files changed, 2207 insertions, 0 deletions
diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test new file mode 100755 index 0000000..a647a8c --- /dev/null +++ b/tests/luks2-reencryption-test @@ -0,0 +1,2207 @@ +#!/bin/bash + +#PS4='$LINENO:' +[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." +CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup + +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + +FAST_PBKDF2="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" +FAST_PBKDF_ARGON="--pbkdf-force-iterations 4 --pbkdf-memory 32 --pbkdf-parallel 1" +DEFAULT_ARGON="argon2i" + +DEV="" +OVRDEV="123reenc321" +DEVBIG="reenc2134" +DEV_NAME=reenc9768 +DEV_NAME2=reenc97682 +IMG=reenc-data +IMG_HDR=$IMG.hdr +HEADER_LUKS2_PV=blkid-luks2-pv.img +IMG_FS=xfs_512_block_size.img +KEY1=key1 +VKEY1=vkey1 +PWD1="93R4P4pIqAH8" +PWD2="1cND4319812f" +PWD3="1-9Qu5Ejfnqv" +DEV_LINK="reenc-test-link" + +FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) + +function dm_crypt_features() +{ + VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) + [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." + + VER_MAJ=$(echo $VER_STR | cut -f 1 -d.) + VER_MIN=$(echo $VER_STR | cut -f 2 -d.) + VER_PTC=$(echo $VER_STR | cut -f 3 -d.) + + [ $VER_MAJ -lt 1 ] && return + [ $VER_MAJ -gt 1 ] && { + DM_PERF_CPU=1 + DM_SECTOR_SIZE=1 + return + } + + [ $VER_MIN -lt 14 ] && return + DM_PERF_CPU=1 + if [ $VER_MIN -ge 17 ]; then + DM_SECTOR_SIZE=1 + fi +} + +function dm_delay_features() +{ + local _ver_str=$(dmsetup targets | grep delay | cut -f2 -dv) + [ -z "$_ver_str" ] && return 1 + return 0 +} + +# $1 path to scsi debug bdev +scsi_debug_teardown() { + local _tries=15; + + while [ -b "$1" -a $_tries -gt 0 ]; do + rmmod scsi_debug >/dev/null 2>&1 + if [ -b "$1" ]; then + sleep .1 + _tries=$((_tries-1)) + fi + done + + test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 +} + +function remove_mapping() +{ + [ -b /dev/mapper/$DEV_NAME ] && { + dmsetup resume $DEV_NAME + dmsetup remove --retry $DEV_NAME + } + [ -b /dev/mapper/$DEV_NAME2 ] && { + dmsetup resume $DEV_NAME2 + dmsetup remove --retry $DEV_NAME2 + } + [ -b /dev/mapper/$DEV_NAME-overlay ] && { + dmsetup resume $DEV_NAME-overlay + dmsetup remove --retry $DEV_NAME-overlay + } + [ -b /dev/mapper/$DEV_NAME-hotzone-forward ] && { + dmsetup resume $DEV_NAME-hotzone-forward + dmsetup remove --retry $DEV_NAME-hotzone-forward + } + [ -b /dev/mapper/$DEV_NAME-hotzone-backward ] && { + dmsetup resume $DEV_NAME-hotzone-backward + dmsetup remove --retry $DEV_NAME-hotzone-backward + } + [ -b /dev/mapper/$OVRDEV ] && dmsetup remove --retry $OVRDEV 2>/dev/null + [ -b /dev/mapper/$OVRDEV-err ] && dmsetup remove --retry $OVRDEV-err 2>/dev/null + [ -n "$LOOPDEV" ] && losetup -d $LOOPDEV + unset LOOPDEV + rm -f $IMG $IMG_HDR $KEY1 $VKEY1 $DEVBIG $DEV_LINK $HEADER_LUKS2_PV $IMG_FS >/dev/null 2>&1 + rmmod scsi_debug >/dev/null 2>&1 + scsi_debug_teardown $DEV +} + +function fail() +{ + local frame=0 + [ -n "$1" ] && echo "$1" + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + remove_mapping + exit 2 +} + +function skip() +{ + [ -n "$1" ] && echo "$1" + remove_mapping + exit 77 +} + +function fips_mode() +{ + [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] +} + +function add_scsi_device() { + scsi_debug_teardown $DEV + if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 + fi + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo "This kernel seems to not support proper scsi_debug module, test skipped." + exit 77 + fi + + sleep 1 + DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) + [ -b $DEV ] || fail "Cannot find $DEV." +} + +function open_crypt() # $1 pwd, $2 hdr +{ + if [ -n "$2" ] ; then + echo "$1" | $CRYPTSETUP luksOpen $DEV $DEV_NAME --header $2 || fail + elif [ -n "$1" ] ; then + echo "$1" | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail + else + $CRYPTSETUP luksOpen -d $KEY1 $DEV $DEV_NAME || fail + fi +} + +function wipe_dev_head() # $1 dev, $2 length (in MiBs) +{ + dd if=/dev/zero of=$1 bs=1M count=$2 conv=notrunc >/dev/null 2>&1 +} + +function wipe_dev() # $1 dev +{ + if [ -b $1 ] ; then + blkdiscard --zeroout $1 2>/dev/null || dd if=/dev/zero of=$1 bs=1M conv=notrunc >/dev/null 2>&1 + if [ $# -gt 2 ]; then + dd if=/dev/urandom of=$1 bs=1M seek=$2 conv=notrunc >/dev/null 2>&1 + fi + else + local size=$(stat --printf="%s" $1) + truncate -s 0 $1 + if [ $# -gt 2 ]; then + local diff=$((size-$2*1024*1024)) + echo "size: $size, diff: $diff" + truncate -s $diff $1 + # wipe_dev_head $1 $((diff/(1024*1024))) + dd if=/dev/urandom of=$1 bs=1M seek=$2 size=$((diff/(1024*1024))) conv=notrunc >/dev/null 2>&1 + else + truncate -s $size $1 + fi + fi +} + +function wipe() # $1 pass, $2 hdr +{ + open_crypt $1 $2 + wipe_dev /dev/mapper/$DEV_NAME + udevadm settle >/dev/null 2>&1 + $CRYPTSETUP luksClose $DEV_NAME || fail +} + +function prepare() # $1 dev1_siz +{ + remove_mapping + + if [ ! -e $KEY1 ]; then + dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 + fi + + if [ ! -e $VKEY1 ]; then + echo -n $'\x44\xc6\x74\x4f\x41\x4e\x50\xc0\x79\xc2\x2d\x5b\x5f\x68\x84\x17' >$VKEY1 + echo -n $'\x9c\x03\xba\xbe\x4d\x0f\x9a\x75\xb3\x90\x70\x32\x0a\xf8\xae\xc4'>>$VKEY1 + fi + + add_scsi_device $@ +} + +function preparebig() # $1 dev1_siz +{ + remove_mapping + + if [ ! -e $KEY1 ]; then + dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 + fi + + truncate -s "$1"M $DEVBIG + LOOPDEV=$(losetup -f) + losetup -f $DEVBIG || fail + DEV=$LOOPDEV +} + +function check_hash_dev() # $1 dev, $2 hash +{ + HASH=$(sha1sum $1 | cut -d' ' -f 1) + [ $HASH != "$2" ] && fail "HASH differs (expected: $2) (result $HASH)" +} + +function check_hash() # $1 pwd, $2 hash, $3 hdr +{ + open_crypt $1 $3 + check_hash_dev /dev/mapper/$DEV_NAME $2 + $CRYPTSETUP remove $DEV_NAME || fail +} + +function check_hash_dev_head() # $1 dev, $2 len, $3 hash +{ + local hash=$(dd if=$1 bs=512 count=$2 2>/dev/null | sha1sum | cut -d' ' -f1) + [ $hash != "$3" ] && fail "HASH differs (expected: $3) (result $hash)" +} + +function check_hash_head() # $1 pwd, $2 len, $3 hash, $4 hdr +{ + open_crypt $1 $4 + check_hash_dev_head /dev/mapper/$DEV_NAME $2 $3 + $CRYPTSETUP remove $DEV_NAME || fail +} + +function resize_file() # $1 dev, $2 shrink bytes +{ + local size=$(stat --printf="%s" $1) + truncate -s $(($size + $2)) $1 + losetup -c $LOOPDEV +} + +function error_writes() { # $1 dmdev, $2 data dev, $3 offset, $4 size + local _dev_size=$(blockdev --getsz /dev/mapper/$1) + local _offset=$(($3+$4)) + local _size=$((_dev_size-_offset)) + local _err=$1-err + local _table= + dmsetup create $_err --table "0 $_dev_size error" || fail + + if [ $3 -ne 0 ]; then + _table="0 $3 linear $2 0\n" + fi + + _table=$_table"$3 $4 delay $2 $3 0 /dev/mapper/$_err $3 0" + + if [ $_size -ne 0 ]; then + _table="$_table\n$_offset $_size linear $2 $_offset" + fi + + echo -e "$_table" | dmsetup load $1 || fail + dmsetup resume $1 || fail + blockdev --setra 0 /dev/mapper/$1 + blockdev --setra 0 /dev/mapper/$_err +} + +function fix_writes() { # $1 dmdev, $2 data dev + local _dev_size=$(blockdev --getsz /dev/mapper/$1) + dmsetup load $1 --table "0 $_dev_size linear $2 0" || fail + dmsetup resume $1 || fail + dmsetup remove --retry $1-err 2>/dev/null || fail +} + +function prepare_linear_dev() { + local _sizemb=$1 + shift + + if [ "$_sizemb" -gt 32 ]; then + preparebig $_sizemb + else + prepare dev_size_mb=$_sizemb $@ + fi + + dmsetup create $OVRDEV --table "0 $((_sizemb*1024*2)) linear $DEV 0" || fail + + OLD_DEV=$DEV + DEV=/dev/mapper/$OVRDEV +} + +function get_error_offsets() # $1 devsize, $2 minimal offset, $3 sector_size [512 if omitted], $4 max offset +{ + local _devsize=$(($1*1024*2)) + local _sector_size=${3:-512} + local _max_offset=${4:-$_devsize} + _sector_size=$((_sector_size/512)) + + # 8 sectors minimal size (4096) + ERRLENGTH=$((($RANDOM%56)+8)) + ERRLENGTH=$(($ERRLENGTH-($ERRLENGTH%$_sector_size))) + + ERROFFSET=$(($2+((2*$RANDOM)%($_max_offset-$2-$ERRLENGTH)))) + ERROFFSET=$(($ERROFFSET-($ERROFFSET%$_sector_size))) +} + +function reencrypt_recover() { # $1 sector size, $2 resilience, $3 digest, [$4 header] + echo -n "resilience mode: $2 ..." + local _hdr="" + test -z "$4" || _hdr="--header $4" + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 --force-offline-reencrypt -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail + fix_writes $OVRDEV $OLD_DEV + + echo $PWD1 | $CRYPTSETUP -q repair $DEV $_hdr || fail + + check_hash $PWD1 $3 $4 + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON || fail + check_hash $PWD1 $3 $4 + + echo "[OK]" +} + +function reencrypt_recover_online() { # $1 sector size, $2 resilience, $3 digest, [$4 header] + echo -n "resilience mode: $2 ..." + local _hdr="" + test -z "$4" || _hdr="--header $4" + + echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail + $CRYPTSETUP status $DEV_NAME $_hdr | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + # recovery during activation + echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail + check_hash_dev /dev/mapper/$DEV_NAME $3 + + $CRYPTSETUP luksDump ${4:-$DEV} | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + $CRYPTSETUP status $DEV_NAME $_hdr | grep -q "reencryption: in-progress" || fail + echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME $_hdr --resilience $2 --resume-only -q || fail + check_hash_dev /dev/mapper/$DEV_NAME $3 + fi + + $CRYPTSETUP close $DEV_NAME || fail + echo "[OK]" +} + +function encrypt_recover() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest + wipe_dev $DEV + check_hash_dev $DEV $5 + + echo -n "resilience mode: datashift ..." + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size $2 --sector-size $1 -q $FAST_PBKDF_ARGON --init-only >/dev/null 2>&1 || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q >/dev/null 2>&1 && fail + fix_writes $OVRDEV $OLD_DEV + + echo $PWD1 | $CRYPTSETUP -q repair $DEV || fail + + $CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + check_hash $PWD1 $3 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --sector-size $1 -q $FAST_PBKDF_ARGON || fail + fi + + check_hash_head $PWD1 $4 $3 + + echo "[OK]" +} + +function encrypt_recover_online() { # $1 sector size, $2 reduce size, $3 digest, $4 device size in sectors, $5 origin digest + wipe_dev $DEV + check_hash_dev $DEV $5 + + echo -n "resilience mode: datashift ..." + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size $2 --sector-size $1 -q $FAST_PBKDF_ARGON --init-only > /dev/null || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q >/dev/null 2>&1 && fail + $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + # recovery in activation + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + + $CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" || fail + check_hash_dev /dev/mapper/$DEV_NAME $3 + echo $PWD1 | $CRYPTSETUP reencrypt --resume-only --active-name $DEV_NAME -q || fail + fi + + $CRYPTSETUP close $DEV_NAME || fail + check_hash_head $PWD1 $4 $3 + + echo "[OK]" +} + +function encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr + wipe_dev $DEV + check_hash_dev $DEV $3 + + echo -n "resilience mode: $2 ..." + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --hotzone-size 1M --header $4 --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail + fix_writes $OVRDEV $OLD_DEV + + echo $PWD1 | $CRYPTSETUP repair $DEV --header $4 || fail + + check_hash $PWD1 $3 $4 + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $4 --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON || fail + check_hash $PWD1 $3 $4 + + [ -f $4 ] && rm -f $4 + + echo "[OK]" +} + +function encrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr + wipe_dev $DEV + check_hash_dev $DEV $3 + + echo -n "resilience mode: $2 ..." + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --hotzone-size 1M --header $4 --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON --init-only || fail + echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV --header $4 --hotzone-size 1M 2>/dev/null && fail + $CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail + check_hash_dev /dev/mapper/$DEV_NAME $3 + + $CRYPTSETUP luksDump $4 | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + $CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail + echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME --resume-only --header $4 --resilience $2 -q || fail + check_hash_dev /dev/mapper/$DEV_NAME $3 + fi + + $CRYPTSETUP close $DEV_NAME || fail + + [ -f $4 ] && rm -f $4 + + echo "[OK]" +} + +function decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest, $4 hdr + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size $1 --header $4 $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 $4 + check_hash $PWD1 $3 $4 + + echo -n "resilience mode: $2 ..." + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --hotzone-size 1M --header $4 --resilience $2 -q 2>/dev/null && fail + fix_writes $OVRDEV $OLD_DEV + + echo $PWD1 | $CRYPTSETUP repair $DEV --header $4 || fail + + $CRYPTSETUP luksDump $4 | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + check_hash $PWD1 $3 $4 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --resume-only --header $4 --resilience $2 -q || fail + fi + + check_hash_dev $DEV $3 + + [ -f $4 ] && rm -f $4 + + echo "[OK]" +} + +function decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 digest, $4 hdr + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size $1 --header $4 $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail + wipe_dev /dev/mapper/$DEV_NAME + check_hash_dev /dev/mapper/$DEV_NAME $3 + + echo -n "resilience mode: $2 ..." + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --hotzone-size 1M --header $4 --resilience $2 -q 2>/dev/null && fail + $CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + # recovery during activation + echo $PWD1 | $CRYPTSETUP open $DEV --header $4 $DEV_NAME || fail + + $CRYPTSETUP luksDump $4 | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + $CRYPTSETUP status $DEV_NAME --header $4 | grep -q "reencryption: in-progress" || fail + check_hash_dev /dev/mapper/$DEV_NAME $3 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $4 --resilience $2 -q || fail + fi + + $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail + check_hash_dev $DEV $3 + + [ -f $4 ] && rm -f $4 + + echo "[OK]" +} + +function decrypt_recover() { # $1 hash, $2 hdr, $3 dev size, $4 resilience, $5 hotzone size + local _res="" + local _maxhz="" + test -z "$4" || _res="--resilience $4" + test -z "$5" || _maxhz="--hotzone-size $5" + echo -n "[${4:-default}]" + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --header $2 --init-only $_maxhz >/dev/null || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail + fix_writes $OVRDEV $OLD_DEV + + echo $PWD1 | $CRYPTSETUP -q repair $DEV --header $2 || fail + + $CRYPTSETUP luksDump $2 | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + check_hash $PWD1 $1 $2 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 $_res -q $FAST_PBKDF_ARGON || fail + fi + + check_hash_dev_head $DEV $3 $1 + + [ -f $2 ] && rm -f $2 + + echo -n "[OK]" +} + +function decrypt_recover_online() { # $1 hash, $2 hdr, $3 dev size + local _res="" + local _maxhz="" + test -z "$4" || _res="--resilience $4" + test -z "$5" || _maxhz="--hotzone-size $5" + echo -n "[${4:-default}]" + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --header $2 $_maxhz --init-only >/dev/null 2>&1 || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail + $CRYPTSETUP status $DEV_NAME --header $2 | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + # recovery during activation + echo $PWD1 | $CRYPTSETUP open $DEV --header $2 $DEV_NAME || fail + + check_hash_dev /dev/mapper/$DEV_NAME $1 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q || fail + + $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail + check_hash_dev_head $DEV $3 $1 + + [ -f $2 ] && rm -f $2 + + echo -n "[OK]" +} + +function decrypt_recover_online_moved() { # $1 hash, $2 hdr, $3 dev size + local _res="" + local _maxhz="" + test -z "$4" || _res="--resilience $4" + test -z "$5" || _maxhz="--hotzone-size $5" + echo -n "[${4:-default}]" + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --header $2 $_maxhz $_res --init-only >/dev/null 2>&1 || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail + $CRYPTSETUP status $DEV_NAME --header $2 | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + # recovery but activation fails due to last segment recovery makes it plaintext device + echo $PWD1 | $CRYPTSETUP open $DEV --header $2 $DEV_NAME 2>/dev/null && fail + + $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail + check_hash_dev_head $DEV $3 $1 + + [ -f $2 ] && rm -f $2 + + echo -n "[OK]" +} + +# sector size (bytes) +# reenc dev size (sectors) +# reenc dev digest +# resilience +# orig size +# orig size digest +# hdr (optional) +function reencrypt_offline_fixed_size() { + local _esz=$(($1>>9)) + local _hdr="" + # round-up fixed size to megabytes + local _mbs=$((($2>>11)+1)) + test -z "$7" || _hdr="--header $7" + + if [ -z "$7" ]; then + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --offset 16384 $FAST_PBKDF_ARGON $DEV || fail + else + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $7 $FAST_PBKDF_ARGON $DEV || fail + fi + echo $PWD1 | $CRYPTSETUP open $_hdr $DEV $DEV_NAME || fail + wipe_dev_head /dev/mapper/$DEV_NAME $_mbs + $CRYPTSETUP close $DEV_NAME || fail + + # reencrypt with fixed device size + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --device-size $2s --resilience $4 --force-offline-reencrypt || fail + + check_hash_head $PWD1 $2 $3 $7 + wipe $PWD1 $7 + + # try to reencrypt device size + 1 encryption sector size + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --init-only --force-offline-reencrypt || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --device-size $(($5+_esz))s --resilience $4 2>/dev/null && fail + check_hash $PWD1 $6 $7 + + # misaligned reencryption size + if [ $_esz -gt 1 ]; then + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --device-size $(($2+_esz-1))s --resilience $4 2>/dev/null && fail + $CRYPTSETUP luksDump ${7:-$DEV} | grep -q "2: crypt" || fail + $CRYPTSETUP luksDump ${7:-$DEV} | grep -q "3: crypt" && fail + check_hash $PWD1 $6 $7 + fi +} + +# sector size (bytes) +# reenc dev size (sectors) +# reenc dev digest +# resilience +# orig size +# orig size digest +# hdr +function encrypt_offline_fixed_size() { + local _esz=$(($1>>9)) + + # reencrypt with fixed device size + wipe_dev $DEV + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 --device-size $2s --resilience $4 || fail + check_hash_head $PWD1 $2 $3 $7 + [ -f $7 ] && rm -f $7 + + # try to reencrypt device size + 1 encryption sector size + wipe_dev $DEV + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 --init-only || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --device-size $(($5+_esz))s --resilience $4 2>/dev/null && fail + check_hash $PWD1 $6 $7 + + # misaligned reencryption size + if [ $_esz -gt 1 ]; then + [ -f $7 ] && rm -f $7 + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 --init-only || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV --header $7 --device-size $(($2+_esz-1))s --resilience $4 2>/dev/null && fail + $CRYPTSETUP luksDump $7 | grep -q "2: crypt" || fail + $CRYPTSETUP luksDump $7 | grep -q "3: crypt" && fail + check_hash $PWD1 $6 $7 + fi + + [ -f $7 ] && rm -f $7 +} + +# sector size (bytes) +# reenc dev size (sectors) +# reenc dev digest +# resilience +# orig size +# orig size digest +# hdr +function decrypt_offline_fixed_size() { + local _esz=$(($1>>9)) + + # decrypt with fixed device size + echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 || fail + wipe $PWD1 $7 + echo $PWD1 | $CRYPTSETUP reencrypt --decrypt -q $DEV --header $7 --device-size $2s --resilience $4 || fail + + dmsetup load $OVRDEV --table "0 $2 linear $OLD_DEV 0" || fail + dmsetup resume $OVRDEV || fail + check_hash_dev $DEV $3 + dmsetup load $OVRDEV --table "0 $5 linear $OLD_DEV 0" || fail + dmsetup resume $OVRDEV || fail + + # try to decrypt device size + 1 encryption sector size + echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 || fail + wipe $PWD1 $7 + echo $PWD1 | $CRYPTSETUP reencrypt --decrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --init-only || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --device-size $(($5+_esz))s --resilience $4 2>/dev/null && fail + check_hash $PWD1 $6 $7 + + # misaligned reencryption size + if [ $_esz -gt 1 ]; then + echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV --header $7 --device-size $(($2+_esz-1))s --resilience $4 2>/dev/null && fail + $CRYPTSETUP luksDump $7 | grep -q "2: linear\|2: crypt" || fail + $CRYPTSETUP luksDump $7 | grep -q "3: crypt\|3: linear" && fail + check_hash $PWD1 $6 $7 + fi +} + +# sector size (bytes) +# reenc dev size (sectors) +# reenc dev digest +# resilience +# orig size +# orig size digest +# hdr (optional) +function reencrypt_online_fixed_size() { + local _esz=$(($1>>9)) + local _hdr="" + test -z "$7" || _hdr="--header $7" + + if [ -z "$_hdr" ]; then + echo $PWD1 | $CRYPTSETUP -q luksFormat --sector-size 512 --type luks2 --offset 16384 $FAST_PBKDF_ARGON $DEV || fail + else + echo $PWD1 | $CRYPTSETUP -q luksFormat --sector-size 512 --type luks2 $_hdr $FAST_PBKDF_ARGON $DEV || fail + fi + wipe $PWD1 $7 + + # reencrypt with fixed device size + echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail + echo $PWD1 | $CRYPTSETUP resize $DEV_NAME $_hdr --size $2 || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --resilience $4 || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "$2 sectors" || fail + $CRYPTSETUP close $DEV_NAME || fail + check_hash_head $PWD1 $2 $3 $7 + wipe $PWD1 $7 + + # active device != requested reencryption size + echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail + echo $PWD1 | $CRYPTSETUP resize $DEV_NAME $_hdr --size $2 || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --init-only || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --device-size $(($2-_esz))s --resilience $4 2>/dev/null && fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --device-size $2s --resilience $4 || fail + $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "$2 sectors" || fail + $CRYPTSETUP close $DEV_NAME || fail + check_hash_head $PWD1 $2 $3 $7 + + # misaligned reencryption size + if [ $_esz -gt 1 ]; then + if [ -z "$_hdr" ]; then + echo $PWD1 | $CRYPTSETUP -q luksFormat --sector-size 512 --type luks2 --offset 16384 $FAST_PBKDF_ARGON $DEV || fail + else + echo $PWD1 | $CRYPTSETUP -q luksFormat --sector-size 512 --type luks2 $_hdr $FAST_PBKDF_ARGON $DEV || fail + fi + wipe $PWD1 $7 + check_hash $PWD1 $6 $7 + + echo $PWD1 | $CRYPTSETUP open $DEV $_hdr $DEV_NAME || fail + echo $PWD1 | $CRYPTSETUP resize $DEV_NAME $_hdr --size $(($2+_esz-1)) || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --init-only || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --resilience $4 2>/dev/null && fail + $CRYPTSETUP close $DEV_NAME || fail + check_hash $PWD1 $6 $7 + fi + + [ -n "$7" -a -f "$7" ] && rm -f $7 +} + +function setup_luks2_env() { + echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c aes-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + HAVE_KEYRING=$($CRYPTSETUP status $DEV_NAME | grep "key location: keyring") + if [ -n "$HAVE_KEYRING" ]; then + HAVE_KEYRING=1 + else + HAVE_KEYRING=0 + fi + DEF_XTS_KEY=$($CRYPTSETUP status $DEV_NAME | grep "keysize:" | sed 's/\( keysize: \)\([0-9]\+\)\(.*\)/\2/') + [ -n "$DEF_XTS_KEY" ] || fail "Failed to parse xts mode key size." + $CRYPTSETUP close $DEV_NAME || fail +} + +function check_blkid() { + bin_check blkid + xz -dkf $HEADER_LUKS2_PV.xz + if ! $($CRYPTSETUP --version | grep -q "BLKID"); then + HAVE_BLKID=0 + elif $(blkid -p -n crypto_LUKS $HEADER_LUKS2_PV >/dev/null 2>&1); then + HAVE_BLKID=1 + xz -dkf $IMG_FS.xz + blkid $IMG_FS | grep -q BLOCK_SIZE && BLKID_BLOCK_SIZE_SUPPORT=1 + else + HAVE_BLKID=0 + fi +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + +function bin_check() +{ + command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." +} + +[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +fips_mode && skip "This test cannot be run in FIPS mode." +modprobe --dry-run scsi_debug >/dev/null 2>&1 || skip "This kernel seems to not support proper scsi_debug module, test skipped." +modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load" +modprobe dm-delay > /dev/null 2>&1 +dm_crypt_features + +if [ -n "$DM_SECTOR_SIZE" ]; then + TEST_SECTORS="512 4096" +else + TEST_SECTORS="512" +fi + +modinfo scsi_debug -p | grep -q opt_xferlen_exp && OPT_XFERLEN_EXP="opt_xferlen_exp=6" + +export LANG=C + +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run + +# REENCRYPTION tests + +# 28 MiBs of zeros (32MiBs - 4MiB LUKS2 header) +HASH1=4da90c0638bd7d29ce3d0ace3df5ee99706c23da +# 1 MiB of zeros +HASH2=3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3 +# 256 MiBs of zeros +HASH3=7b91dbdc56c5781edf6c8847b4aa6965566c5c75 +# 64 MiBs of zeroes +HASH4=44fac4bedde4df04b9572ac665d3ac2c5cd00c7d +# 56 MiBs of zeroes +HASH5=bcd8ce9b30a43b2dacdf479493c93e167ef60946 +# 43 MiBs of zeroes +HASH6=2cf8a5f40a2ab5373c5425d6071da480f1ce08e8 +# 31 MiBs of zeroes +HASH7=7ed56dd14d2841cf169fe503d097be04192666bd +# 60 MiBs of zeroes +HASH8=233ba936226a3ac499e67babaebd0d4aafb9761a +# 240 MiBs of zeroes (256MiBs - 16MiBs default LUKS2 header size) +HASH9=045eebed703cce308e049deb019b877f0445862f +# 16 MiBs of zeroes +HASH10=3b4417fc421cee30a9ad0fd9319220a8dae32da2 + +prepare dev_size_mb=32 +setup_luks2_env + +# Check that we can use other ciphers than AES in userspace backend. +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c twofish-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>/dev/null || skip "Cannot use Twofish cipher, test skipped" +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c serpent-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>/dev/null || skip "Cannot use Serpent cipher, test skipped." +wipe_dev $DEV + +echo "[1] Reencryption" +echo -n "[512 sector]" +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>&1 | tail -1 | grep -q "not supported" && skip " No reenryption support, test skipped." +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience none $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 128 -c aes-cbc-essiv:sha256 --resilience checksum $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +# simple test --active-name can consume absolute path to mapping +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -c aes-xts-plain64 --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +echo $PWD1 | $CRYPTSETUP reencrypt --active-name /dev/mapper/$DEV_NAME --resilience none -q || fail +XTS_KEY=$($CRYPTSETUP status $DEV_NAME | grep "keysize:" | sed 's/\( keysize: \)\([0-9]\+\)\(.*\)/\2/') +[ "$XTS_KEY" -eq "$DEF_XTS_KEY" ] || fail "xts mode has wrong key size after reencryption ($XTS_KEY != expected $DEF_XTS_KEY)" +echo $PWD1 | $CRYPTSETUP close $DEV_NAME || fail +echo -n "[OK][4096 sector]" +prepare sector_size=4096 dev_size_mb=32 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience none $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 128 -c aes-cbc-essiv:sha256 --resilience checksum $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +if [ -n "$DM_SECTOR_SIZE" ]; then + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON --sector-size 4096 || fail + check_hash $PWD1 $HASH1 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal --sector-size 2048 $FAST_PBKDF_ARGON || fail + check_hash $PWD1 $HASH1 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience none $FAST_PBKDF_ARGON --sector-size 1024 || fail + check_hash $PWD1 $HASH1 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 128 -c aes-cbc-essiv:sha256 --resilience checksum --sector-size 512 $FAST_PBKDF_ARGON || fail + check_hash $PWD1 $HASH1 +fi +echo -n "[OK][4096/512 sector]" +prepare sector_size=512 physblk_exp=3 dev_size_mb=32 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience none $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 128 -c aes-cbc-essiv:sha256 --resilience checksum $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 +echo "[OK]" + +# reencrypt minimal device size (FIXME: change data device size to single encryption sector size) +# temporary small device size is default luks2 hdr size + 1MiB +echo -n "[small device reencryption]" +prepare dev_size_mb=5 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +check_hash $PWD1 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience none $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 128 -c aes-cbc-essiv:sha256 --resilience checksum $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH2 +if [ -n "$DM_SECTOR_SIZE" ]; then + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON --sector-size 4096 --force-offline-reencrypt || fail + check_hash $PWD1 $HASH2 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal --sector-size 2048 $FAST_PBKDF_ARGON || fail + check_hash $PWD1 $HASH2 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience none $FAST_PBKDF_ARGON --sector-size 1024 || fail + check_hash $PWD1 $HASH2 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 128 -c aes-cbc-essiv:sha256 --resilience checksum --sector-size 512 $FAST_PBKDF_ARGON || fail + check_hash $PWD1 $HASH2 +fi +echo "[OK]" + +echo "[2] Encryption with data shift" +# well, movin' zeroes :-) +preparebig 64 +wipe_dev $DEV +check_hash_dev $DEV $HASH4 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --reduce-device-size 8M -q $FAST_PBKDF_ARGON || fail +check_hash_head $PWD1 $((56*1024*2)) $HASH5 +wipe_dev $DEV +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c twofish-cbc-essiv:sha256 -s 128 --reduce-device-size 21M -q $FAST_PBKDF_ARGON || fail +check_hash_head $PWD1 $((43*1024*2)) $HASH6 +wipe_dev $DEV +# offset 21504 equals 10,5MiBs, equals --reduce-device-size 21M from test above (30M is ignored here, we'll reduce it to 21M in cryptsetup anyway) +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c twofish-cbc-essiv:sha256 -s 128 --offset 21504 --reduce-device-size 30M -q $FAST_PBKDF_ARGON > /dev/null || fail +check_hash_head $PWD1 $((43*1024*2)) $HASH6 +wipe_dev $DEV +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 33M -q $FAST_PBKDF_ARGON || fail +check_hash_head $PWD1 $((31*1024*2)) $HASH7 +wipe_dev $DEV +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M -q $FAST_PBKDF_ARGON > /dev/null 2>&1 && fail +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 8M --init-only -q $FAST_PBKDF_ARGON $DEV || fail +resize_file $DEVBIG -512 +echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV 2> /dev/null && fail +resize_file $DEVBIG 512 +wipe_dev $DEV +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --offset 32760 --reduce-device-size 8M -q $FAST_PBKDF_ARGON --init-only >/dev/null 2>&1 && fail +# data offset at 21MiB +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --header $IMG_HDR --offset 43008 --reduce-device-size 21M -q $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH6 $IMG_HDR +$CRYPTSETUP luksHeaderRestore --header-backup-file $IMG_HDR $DEV -q || fail +check_hash $PWD1 $HASH6 + +# Device activation after encryption initialization +wipe_dev $DEV +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --init-only -c aes-cbc-essiv:sha256 -s 128 -S11 --reduce-device-size 8M -q $FAST_PBKDF_ARGON $DEV_NAME >/dev/null || fail +$CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH5 +echo $PWD1 | $CRYPTSETUP reencrypt --resume-only $DEV -q || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH5 + +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --reduce-device-size 8M -q $FAST_PBKDF_ARGON $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP close $DEV_NAME +check_hash_head $PWD1 $((56*1024*2)) $HASH5 + +# Device activation using key file +wipe_dev $DEV +echo -n $PWD1 > $KEY1 +$CRYPTSETUP reencrypt $DEV --encrypt --init-only -c aes-cbc-essiv:sha256 -s 128 --reduce-device-size 8M --key-file $KEY1 -q $FAST_PBKDF_ARGON $DEV_NAME >/dev/null || fail +$CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail +$CRYPTSETUP close $DEV_NAME +echo $PWD1 | $CRYPTSETUP open $DEV --test-passphrase || fail + +# Small device encryption test +preparebig 65 +# wipe only 1st MiB (final data size after encryption) +wipe_dev $DEV 1 +check_hash_dev_head $DEV 2048 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M -q $FAST_PBKDF_ARGON || fail +check_hash_head $PWD1 2048 $HASH2 + +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M --init-only -q $FAST_PBKDF_ARGON $DEV_NAME >/dev/null || fail +check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q || fail +check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 + +echo "[3] Encryption with detached header" +preparebig 256 +wipe_dev $DEV +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +wipe_dev $DEV +rm -f $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --resilience journal --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +wipe_dev $DEV +rm -f $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c twofish-cbc-essiv:sha256 -s 128 --resilience none --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +wipe_dev $DEV +rm -f $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c serpent-xts-plain --resilience checksum --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +rm -f $IMG_HDR + +# Device activation after encryption initialization +wipe_dev $DEV +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV $DEV_NAME >/dev/null || fail +$CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH3 +echo $PWD1 | $CRYPTSETUP reencrypt --resume-only --header $IMG_HDR --active-name $DEV_NAME -q || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH3 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --reduce-device-size 8M -q $FAST_PBKDF_ARGON $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP close $DEV_NAME +check_hash $PWD1 $HASH3 $IMG_HDR +rm -f $IMG_HDR + +# Device encryption with data offset set in detached header +wipe_dev $DEV +dd if=/dev/urandom of=$DEV bs=512 count=32768 >/dev/null 2>&1 +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --header $IMG_HDR --offset 32768 -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH9 $IMG_HDR +rm -f $IMG_HDR + +# Device activation using key file +wipe_dev $DEV +echo -n $PWD1 > $KEY1 +$CRYPTSETUP reencrypt $DEV --encrypt --init-only -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR --key-file $KEY1 -q $FAST_PBKDF_ARGON $DEV_NAME >/dev/null || fail +$CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail +$CRYPTSETUP close $DEV_NAME +echo $PWD1 | $CRYPTSETUP open --header $IMG_HDR $DEV --test-passphrase || fail + +# Encrypt without size reduction must not allow header device same as data device +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail +ln -s $DEV $DEV_LINK || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail +rm -f $DEV_LINK || fail + +dd if=/dev/zero of=$IMG bs=4k count=1 >/dev/null 2>&1 +echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail +ln -s $IMG $DEV_LINK || fail +echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail + +echo "[4] Reencryption with detached header" +wipe $PWD1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --resilience journal --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt -c twofish-cbc-essiv:sha256 -s 128 --resilience none --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt -c serpent-xts-plain --resilience checksum --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH3 $IMG_HDR +# trivial check for detached header misuse +dd if=/dev/zero of=$IMG bs=4k count=1 >/dev/null 2>&1 +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open $IMG $DEV_NAME --header $IMG_HDR || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME2 --header $IMG_HDR || fail +echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME --header $IMG_HDR -q || fail +# key description mismatch in active device +echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME2 --header $IMG_HDR >/dev/null 2>&1 && fail +# also check it can abort initialization in this case +$CRYPTSETUP luksDump $IMG_HDR | grep -q "online-reencrypt" && fail +$CRYPTSETUP close $DEV_NAME || fail +$CRYPTSETUP close $DEV_NAME2 || fail + +echo "[5] Decryption with detached header" +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --sector-size 512 -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --header $IMG_HDR $DEV || fail +check_hash_dev $DEV $HASH3 +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --resilience journal --header $IMG_HDR $DEV || fail +check_hash_dev $DEV $HASH3 +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c twofish-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --resilience none --header $IMG_HDR $DEV || fail +check_hash_dev $DEV $HASH3 +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c serpent-xts-plain --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --resilience checksum --header $IMG_HDR $DEV || fail +check_hash_dev $DEV $HASH3 + +# check deferred remove works as expected after decryption +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --sector-size 512 -c serpent-xts-plain --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +open_crypt $PWD1 $IMG_HDR +dmsetup create $DEV_NAME2 --table "0 1 linear /dev/mapper/$DEV_NAME 0" || fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --resilience checksum --header $IMG_HDR --active-name $DEV_NAME || fail +$CRYPTSETUP status $DEV_NAME >/dev/null || fail +dmsetup remove --retry $DEV_NAME2 +$CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail + +# check tool can block some funny user ideas +preparebig 64 +ln -s $DEV $DEV_LINK || fail +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c serpent-xts-plain -q $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $DEV -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $DEV_LINK -q 2>/dev/null && fail +open_crypt $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --active-name $DEV_NAME -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --active-name $DEV_NAME --header $DEV -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --active-name $DEV_NAME --header $DEV_LINK -q 2>/dev/null && fail +$CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail +$CRYPTSETUP close $DEV_NAME + +# yet another funny idea +rm -f $IMG_HDR +$CRYPTSETUP luksHeaderBackup --header-backup-file $IMG_HDR $DEV || fail +chmod +w $IMG_HDR || fail +command -v wipefs >/dev/null && { + wipefs -a $DEV >/dev/null 2>&1 || fail +} +open_crypt $PWD1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME --decrypt --header $IMG_HDR -q 2>/dev/null && fail +$CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail +$CRYPTSETUP close $DEV_NAME || fail + +if ! dm_delay_features; then + echo "dm-delay target is missing, skipping recovery tests." + remove_mapping + exit 0 +fi + +echo "[6] Reencryption recovery" +# (check opt-io size optimization in reencryption code does not affect recovery) +# device with opt-io size 32k +prepare_linear_dev 32 opt_blks=64 $OPT_XFERLEN_EXP +OFFSET=8192 + +echo "sector size 512->512" + +get_error_offsets 32 $OFFSET +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover 512 checksum $HASH1 +reencrypt_recover 512 journal $HASH1 + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 512->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH1 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + reencrypt_recover 4096 journal $HASH1 + + echo "sector size 4096->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 --sector-size 4096 -c aes-cbc-essiv:sha256 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH1 + reencrypt_recover 4096 journal $HASH1 +fi + +echo "[7] Reencryption recovery (online i/o error)" + +echo "sector size 512->512" + +get_error_offsets 32 $OFFSET +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover_online 512 checksum $HASH1 +reencrypt_recover_online 512 journal $HASH1 + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 512->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH1 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + reencrypt_recover_online 4096 journal $HASH1 + + echo "sector size 4096->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 --sector-size 4096 -c aes-cbc-essiv:sha256 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH1 + reencrypt_recover_online 4096 journal $HASH1 +fi + +echo "[8] Reencryption with detached header recovery" +prepare_linear_dev 31 opt_blks=64 $OPT_XFERLEN_EXP + +echo "sector size 512->512" + +get_error_offsets 31 0 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 $IMG_HDR +check_hash $PWD1 $HASH7 $IMG_HDR + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover 512 checksum $HASH7 $IMG_HDR +reencrypt_recover 512 journal $HASH7 $IMG_HDR + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 512->4096" + + get_error_offsets 31 0 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 $IMG_HDR + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH7 $IMG_HDR + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 $IMG_HDR + reencrypt_recover 4096 journal $HASH7 $IMG_HDR + + echo "sector size 4096->4096" + + get_error_offsets 31 0 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 $IMG_HDR + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH7 $IMG_HDR + reencrypt_recover 4096 journal $HASH7 $IMG_HDR +fi + +echo "[9] Reencryption with detached header recovery (online i/o error)" + +echo "sector size 512->512" + +get_error_offsets 31 0 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 $IMG_HDR + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover_online 512 checksum $HASH7 $IMG_HDR +reencrypt_recover_online 512 journal $HASH7 $IMG_HDR + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 512->4096" + + get_error_offsets 31 0 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 $IMG_HDR + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH7 $IMG_HDR + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 $IMG_HDR + reencrypt_recover_online 4096 journal $HASH7 $IMG_HDR + + echo "sector size 4096->4096" + + get_error_offsets 31 0 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 $IMG_HDR + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH7 $IMG_HDR + reencrypt_recover_online 4096 journal $HASH7 $IMG_HDR +fi + +echo "[10] Encryption recovery" +prepare_linear_dev 64 +OFFSET=$((2*1024*2)) + +echo "sector size 512" + +get_error_offsets 64 $OFFSET 512 $((62*1024*2)) + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +encrypt_recover 512 4M $HASH8 $((60*1024*2)) $HASH4 + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 4096" + + get_error_offsets 64 $OFFSET 4096 $((62*1024*2)) + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + encrypt_recover 4096 4M $HASH8 $((60*1024*2)) $HASH4 +fi + +echo "[11] Encryption recovery (online i/o error)" + +echo "sector size 512" + +get_error_offsets 64 $OFFSET 512 $((62*1024*2)) + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +encrypt_recover_online 512 4M $HASH8 $((60*1024*2)) $HASH4 + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 4096" + + get_error_offsets 64 $OFFSET 4096 $((62*1024*2)) + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + encrypt_recover_online 4096 4M $HASH8 $((60*1024*2)) $HASH4 +fi + +echo "[12] Encryption with detached header recovery" +prepare_linear_dev 31 opt_blks=64 $OPT_XFERLEN_EXP + +get_error_offsets 31 0 + +echo "sector size 512" + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +encrypt_recover_detached 512 checksum $HASH7 $IMG_HDR +encrypt_recover_detached 512 journal $HASH7 $IMG_HDR + +if [ -n "$DM_SECTOR_SIZE" ]; then + get_error_offsets 31 0 4096 + + echo "sector size 4096" + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + encrypt_recover_detached 4096 checksum $HASH7 $IMG_HDR + encrypt_recover_detached 4096 journal $HASH7 $IMG_HDR +fi + +echo "[13] Encryption with detached header recovery (online i/o error)" + +get_error_offsets 31 0 + +echo "sector size 512" + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +encrypt_recover_detached_online 512 checksum $HASH7 $IMG_HDR +encrypt_recover_detached_online 512 journal $HASH7 $IMG_HDR + +if [ -n "$DM_SECTOR_SIZE" ]; then + get_error_offsets 31 0 4096 + + echo "sector size 4096" + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + encrypt_recover_detached_online 4096 checksum $HASH7 $IMG_HDR + encrypt_recover_detached_online 4096 journal $HASH7 $IMG_HDR +fi + +echo "[14] Decryption with detached header recovery" + +echo "sector size 512" + +# TODO: What should decryption do when it finishes decryption during recovery (with open) +get_error_offsets 31 2049 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +decrypt_recover_detached 512 journal $HASH7 $IMG_HDR +decrypt_recover_detached 512 checksum $HASH7 $IMG_HDR + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 4096" + + # TODO: What should decryption do when it finishes decryption during recovery (with open) + get_error_offsets 31 2048 4096 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + decrypt_recover_detached 4096 checksum $HASH7 $IMG_HDR + decrypt_recover_detached 4096 journal $HASH7 $IMG_HDR +fi + +echo "[15] Decryption with detached header recovery (online i/o error)" + +echo "sector size 512" + +# TODO: What should decryption do when it finishes decryption during recovery (with open) +get_error_offsets 31 2049 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +decrypt_recover_detached_online 512 journal $HASH7 $IMG_HDR +decrypt_recover_detached_online 512 checksum $HASH7 $IMG_HDR + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 4096" + + # TODO: What should decryption do when it finishes decryption during recovery (with open) + get_error_offsets 31 2048 4096 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + decrypt_recover_detached_online 4096 checksum $HASH7 $IMG_HDR + decrypt_recover_detached_online 4096 journal $HASH7 $IMG_HDR +fi + +echo "[16] Offline reencryption with fixed device size." +preparebig 68 + +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size +for test_res in checksum journal none; do + echo -n "[$test_res]" + reencrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 + reencrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 + reencrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 + echo -n "[OK]" +done +echo "" +done + +echo "[17] Online reencryption with fixed device size." +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size +for test_res in checksum journal none; do + echo -n "[$test_res]" + reencrypt_online_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 + reencrypt_online_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 + reencrypt_online_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 + echo -n "[OK]" +done +echo "" +done + +echo "[18] Offline reencryption with fixed device size (detached header)." +preparebig 60 + +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size +for test_res in checksum journal none; do + echo -n "[$test_res]" + reencrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + echo -n "[OK]" +done +echo "" +done + +echo "[19] Online reencryption with fixed device size (detached header)." +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size +for test_res in checksum journal none; do + echo -n "[$test_res]" + reencrypt_online_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_online_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_online_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + echo -n "[OK]" +done +echo "" +done + +echo "[20] Offline encryption with fixed device size (detached header)." +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size +for test_res in checksum journal none; do + echo -n "[$test_res]" + encrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + encrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + encrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + echo -n "[OK]" +done +echo "" +done + +echo "[21] Offline decryption with fixed device size (detached header)." +prepare_linear_dev 60 +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size +for test_res in checksum journal none; do + echo -n "[$test_res]" + decrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + decrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + decrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + echo -n "[OK]" +done +echo "" +done + +echo "[22] Multi-keyslot device reencryption" +prepare dev_size_mb=17 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --offset 32768 $FAST_PBKDF_ARGON $DEV || fail +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF2 $DEV || fail +echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 + +echo -e "$PWD1\n$PWD2\n$PWD3" | $CRYPTSETUP reencrypt $DEV -q || fail +check_hash $PWD1 $HASH2 +check_hash $PWD2 $HASH2 +check_hash $PWD3 $HASH2 + +# check at least pbkdf type is preserved +$CRYPTSETUP luksDump $DEV | grep -e "3: luks2" -A5 | grep -q "argon2" || fail +$CRYPTSETUP luksDump $DEV | grep -e "4: luks2" -A5 | grep -q "pbkdf2" || fail +$CRYPTSETUP luksDump $DEV | grep -e "5: luks2" -A5 | grep -q "argon2" || fail + +echo $PWD1 | $CRYPTSETUP -q luksAddKey $FAST_PBKDF2 $DEV $KEY1 || fail + +# with more keyslots, specific has to be selected +$CRYPTSETUP reencrypt $DEV -d $KEY1 -q 2>/dev/null && fail +$CRYPTSETUP reencrypt $DEV -d $KEY1 -q -S0 || fail +open_crypt +check_hash_dev /dev/mapper/$DEV_NAME $HASH2 +$CRYPTSETUP close $DEV_NAME + +# there should be single keyslot now +$CRYPTSETUP reencrypt $DEV -d $KEY1 -q || fail +echo $PWD1 | $CRYPTSETUP -q luksAddKey $FAST_PBKDF2 $DEV -S1 -d $KEY1 || fail + +echo $PWD3 | $CRYPTSETUP -q luksAddKey $FAST_PBKDF2 $DEV -S2 --unbound --key-size 32 || fail +echo $PWD3 | $CRYPTSETUP -q luksAddKey $FAST_PBKDF2 $DEV -S22 --unbound --key-size 32 || fail +echo $PWD3 | $CRYPTSETUP -q luksAddKey $FAST_PBKDF2 $DEV -S23 --unbound --key-size 32 || fail + +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -S1 -q || fail +$CRYPTSETUP open --test-passphrase -d $KEY1 $DEV 2>/dev/null && fail +echo $PWD3 | $CRYPTSETUP open --test-passphrase -S2 $DEV || fail +echo $PWD3 | $CRYPTSETUP open --test-passphrase -S22 $DEV || fail +check_hash $PWD1 $HASH2 + +# fill 31 keyslots +COUNT=27 +while [ $COUNT -gt 0 ]; do + echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey $DEV -q $FAST_PBKDF_ARGON || fail + COUNT=$((COUNT-1)) +done + +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -S0 -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksKillSlot $DEV 30 || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -S0 || fail + +COUNT=14 +while [ $COUNT -gt 0 ]; do + echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey $DEV -q $FAST_PBKDF_ARGON || fail + COUNT=$((COUNT-1)) +done + +echo -e "$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1" | $CRYPTSETUP reencrypt $DEV -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksKillSlot $DEV 1 || fail +# one wrong passphrase +echo -e "$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD2" | $CRYPTSETUP reencrypt $DEV -q 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --resume-only -q 2>/dev/null && fail +echo -e "$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1\n$PWD1" | $CRYPTSETUP reencrypt $DEV -q || fail + +#test error path behaves as expected for initialization with not enough space in binary area +# create LUKS2 header with keyslots binary space for exactly 4 keyslots +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --luks2-keyslots-size $((4*258048)) -S0 -s512 --cipher aes-xts-plain64 $FAST_PBKDF_ARGON $DEV >/dev/null || fail +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -S1 $DEV -q $FAST_PBKDF_ARGON || fail +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -S2 $DEV -q $FAST_PBKDF_ARGON || fail +# there is not enough space in binary area for keyslot id 4 (replacement for id 2) +echo -e "$PWD1\n$PWD2\n$PWD2" | $CRYPTSETUP reencrypt $DEV --init-only -q 2>/dev/null && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail +# check cli removed all unbound keyslots created in-before reencryption initialization +$CRYPTSETUP luksDump $DEV | grep -q "unbound" && fail + +echo $PWD1 | $CRYPTSETUP luksKillSlot $DEV 2 || fail +# there is not enough space in binary area for reencryption keyslot +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP reencrypt $DEV --init-only -q 2>/dev/null && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail +# check cli removed all unbound keyslots created in-before reencryption initialization +$CRYPTSETUP luksDump $DEV | grep -q "unbound" && fail + +echo "[23] Reencryption with specified new volume key" +prepare dev_size_mb=32 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 256 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -S0 $FAST_PBKDF_ARGON --volume-key-file $VKEY1 -s 128 || fail +check_hash $PWD1 $HASH1 +$CRYPTSETUP luksErase -q $DEV || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_ARGON --volume-key-file $VKEY1 -s 128 $DEV || fail +check_hash $PWD1 $HASH1 + +echo "[24] Reencryption with initial cipher_null" +# aka custom encryption +prepare dev_size_mb=32 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -c aes-xts-plain64 -q $FAST_PBKDF_ARGON || fail +check_hash $PWD1 $HASH1 + +# online +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -c aes-xts-plain64 -q $FAST_PBKDF_ARGON || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH1 +if [ $HAVE_KEYRING -gt 0 ]; then + $CRYPTSETUP status $DEV_NAME | grep -q "key location: keyring" || fail +fi +$CRYPTSETUP close $DEV_NAME + +# simulate LUKS2 device with cipher_null in both keyslot and segment (it can be created only by up conversion from LUKS1) +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 -s 128 -c cipher_null-ecb --offset 8192 $FAST_PBKDF2 $DEV || fail +$CRYPTSETUP convert -q --type luks2 $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON >/dev/null || fail +check_hash $PWD1 $HASH1 +# both keyslot and segment cipher must not be null after reencryption with default params +$CRYPTSETUP luksDump $DEV | grep -q "cipher_null" && fail + +# multistep reencryption with initial cipher_null +preparebig 64 +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $DEV -c null --offset 16384 -q $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --hotzone-size 1M --resilience none -q $FAST_PBKDF_ARGON >/dev/null || fail +$CRYPTSETUP close $DEV_NAME +check_hash $PWD1 $HASH5 + +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $DEV -c null --offset 16384 -q $FAST_PBKDF_ARGON || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --hotzone-size 1M --resilience none -q $FAST_PBKDF_ARGON >/dev/null || fail +check_hash $PWD1 $HASH5 + +echo "[25] Reencryption recovery with cipher_null" +# (check opt-io size optimization in reencryption code does not affect recovery) +# device with opt-io size 32k +prepare_linear_dev 32 opt_blks=64 $OPT_XFERLEN_EXP +OFFSET=8192 + +echo "sector size 512->512" + +get_error_offsets 32 $OFFSET +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover 512 checksum $HASH1 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +reencrypt_recover 512 journal $HASH1 + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 512->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH1 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + reencrypt_recover 4096 journal $HASH1 + + echo "sector size 4096->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover 4096 checksum $HASH1 + reencrypt_recover 4096 journal $HASH1 +fi + +echo "[26] Reencryption recovery with cipher_null (online i/o error)" + +echo "sector size 512->512" + +get_error_offsets 32 $OFFSET +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 -c null --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +reencrypt_recover_online 512 checksum $HASH1 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 -c null --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +reencrypt_recover_online 512 journal $HASH1 + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo "sector size 512->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH1 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + reencrypt_recover_online 4096 journal $HASH1 + + echo "sector size 4096->4096" + + get_error_offsets 32 $OFFSET 4096 + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c null --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + reencrypt_recover_online 4096 checksum $HASH1 + reencrypt_recover_online 4096 journal $HASH1 +fi + +echo "[27] Verify test passphrase mode works with reencryption metadata" +echo $PWD1 | $CRYPTSETUP -S5 -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV || fail +echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey --unbound -s80 -S0 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --init-only $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail + +echo $PWD1 | $CRYPTSETUP -q luksFormat -S5 --header $IMG_HDR --type luks2 $FAST_PBKDF_ARGON $DEV || fail +echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey --unbound -s80 -S0 $FAST_PBKDF_ARGON $IMG_HDR || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --init-only --header $IMG_HDR $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail +rm -f $IMG_HDR +wipe_dev_head $DEV 1 + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --init-only --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail + +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 8M $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail + +echo "[28] Prevent nested encryption" +prepare_linear_dev 32 opt_blks=64 $OPT_XFERLEN_EXP + +#device already LUKS2 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --reduce-device-size 2m $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --reduce-device-size 2m $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +#type mismatch +echo $PWD1 | $CRYPTSETUP reencrypt -q --type luks1 $DEV 2>/dev/null && fail +wipe_dev $DEV + +#detached header already LUKS2 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --type luks1 --header $IMG_HDR $DEV 2>/dev/null && fail +rm -f $IMG_HDR + +#data device already in reencryption +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --init-only $FAST_PBKDF_ARGON $DEV || fail + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +#type mismatch +echo $PWD1 | $CRYPTSETUP reencrypt -q --type luks1 $DEV 2>/dev/null && fail +wipe_dev $DEV +rm -f $IMG_HDR + +#header in reencryption (type mismatch) +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail + +echo "[29] Conflicting reencryption parameters" +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 4M $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-checksum 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-journal 2> /dev/null && fail +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 16M $DEV -q $FAST_PBKDF_ARGON 2> /dev/null || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience journal 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-checksum 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-journal 2> /dev/null && fail +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --resilience datashift-checksum 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --resilience datashift-journal 2>/dev/null && fail +rm -f $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --encrypt --header $IMG_HDR --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +rm -f $IMG_HDR +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience datashift 2> /dev/null && fail +test -f $IMG_HDR && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience none 2> /dev/null && fail +test -f $IMG_HDR && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience checksum --hotzone-size 4m || fail +$CRYPTSETUP isLuks $DEV -q && fail +# $CRYPTSETUP luksDump $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience datashift 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience none 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience journal || fail +rm -f $IMG_HDR + +check_blkid +if [ "$HAVE_BLKID" -gt 0 ]; then + echo "[30] Prevent nested encryption of broken LUKS device" + rm -f $IMG_HDR + xz -dkf $HEADER_LUKS2_PV.xz + wipe_dev $DEV + + # broken header + echo $PWD1 | $CRYPTSETUP reencrypt -q --header $HEADER_LUKS2_PV $DEV $FAST_PBKDF_ARGON --encrypt --type luks2 2>/dev/null && fail + $CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail + # broken device + echo $PWD1 | $CRYPTSETUP reencrypt -q $HEADER_LUKS2_PV $FAST_PBKDF_ARGON --encrypt --force-offline-reencrypt --type luks2 --reduce-device-size 8m 2>/dev/null && fail + $CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail + # broken data device only + echo $PWD1 | $CRYPTSETUP reencrypt -q --header $IMG_HDR $HEADER_LUKS2_PV $FAST_PBKDF_ARGON --encrypt --force-offline-reencrypt --type luks2 2>/dev/null && fail + test -f $IMG_HDR && fail +fi + +if [ -n "$DM_SECTOR_SIZE" -a $HAVE_BLKID -gt 0 ]; then + echo "[31] Prevent dangerous sector size increase" + preparebig 64 + echo $PWD1 | $CRYPTSETUP luksFormat -q --sector-size 512 --type luks2 $FAST_PBKDF_ARGON $DEV || fail + + # block encryption sector size increase on offline device + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail + echo $PWD1 | $CRYPTSETUP reencrypt -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail + $CRYPTSETUP luksDump $DEV | grep -q "sector: 1024" && fail + + # --force-offline-reencrypt can bypass the constraint + echo $PWD1 | $CRYPTSETUP reencrypt --force-offline-reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV || fail + # resume must work + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV || fail + + # online with no superblock is fine + echo $PWD1 | $CRYPTSETUP open -q $DEV $DEV_NAME || fail + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 4096 $FAST_PBKDF_ARGON $DEV || fail + $CRYPTSETUP close $DEV_NAME || fail + + # sector size decrease is ok + echo $PWD1 | $CRYPTSETUP luksFormat -q --sector-size 4096 --type luks2 $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV || fail + + if [ -n "$BLKID_BLOCK_SIZE_SUPPORT" ]; then + xz -dkf $IMG_FS.xz + # encryption checks must work in offline mode + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --header $IMG_HDR $IMG_FS $FAST_PBKDF_ARGON --init-only --type luks2 2>/dev/null && fail + test -f $IMG_HDR && fail + + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --header $IMG_HDR $IMG_FS $FAST_PBKDF_ARGON --type luks2 2>/dev/null && fail + test -f $IMG_HDR && fail + + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --reduce-device-size 8m $IMG_FS $FAST_PBKDF_ARGON --init-only --type luks2 2>/dev/null && fail + $CRYPTSETUP isLuks $IMG_FS && fail + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --reduce-device-size 8m $IMG_FS $FAST_PBKDF_ARGON --type luks2 2>/dev/null && fail + $CRYPTSETUP isLuks $IMG_FS && fail + + echo $PWD1 | $CRYPTSETUP luksFormat -q --sector-size 512 --type luks2 $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open -q $DEV $DEV_NAME || fail + dd if=$IMG_FS of=/dev/mapper/$DEV_NAME bs=1M >/dev/null 2>&1 + + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 --active-name $DEV_NAME $FAST_PBKDF_ARGON 2>/dev/null && fail + $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail + echo $PWD1 | $CRYPTSETUP reencrypt -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "sector: 512" || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q --sector-size 1024 --active-name $DEV_NAME $FAST_PBKDF_ARGON 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "sector: 512" || fail + fi +fi + +echo "[32] Removal of encryption (LUKS2 legacy cryptsetup-reencrypt test)." +prepare dev_size_mb=32 +OFFSET=8192 + +# offline decryption with shift +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# online decryption with shift +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# offline decryption (separate initialization and decryption steps) +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash $PWD1 $HASH1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# online decryption with shift +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# same tests just with date size == LUKS2 header size +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +wipe $PWD1 +check_hash $PWD1 $HASH10 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash $PWD1 $HASH10 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH10 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# 1MiB data size +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 63488 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +# --hotzone-size larger than data expected to get auto corrected by library +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only --hotzone-size 4M || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +# small device (less than header size) +prepare dev_size_mb=5 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -S5 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 2048 $HASH2 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -S5 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +# initialization by --active-name parameter +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --active-name $DEV_NAME || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +# initialization and resume by --active-name parameter +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --active-name $DEV_NAME --init-only || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --active-name $DEV_NAME || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +echo "[33] Decryption with datashift recovery (error in shift area)." +prepare_linear_dev 32 +echo "sector size 512" + +# avoid error in moved segment area on purpose +# Also do not create write error in last segment because +# that would not trigger reencryption crash (read would pass) +get_error_offsets 32 $OFFSET 512 $((32-1024*2-$OFFSET)) +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +echo -n "resilience:" +decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + get_error_offsets 32 $OFFSET 4096 $((32-1024*2-$OFFSET)) + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + echo -n "resilience:" + decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) +fi +echo "" + +echo "[34] Decryption with datashift recovery (error in moved segment)." +echo "sector size 512" + +HZ_SIZE=$((3*1024*2)) + +# move injected error in moved segment area +get_error_offsets 32 0 512 $HZ_SIZE +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + +echo -n "resilience:" +for res in datashift-journal datashift-checksum; do + + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) +done + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + # move injected error in moved segment area + get_error_offsets 32 0 4096 $HZ_SIZE + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + + echo -n "resilience:" + for res in datashift-journal datashift-checksum; do + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) + done +fi +echo "" + +echo "[35] Decryption with datashift recovery (online i/o error in shift area)." +echo "sector size 512" + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME + +# avoid error in moved segment area on purpose +# Also do not create write error in last segment because +# that would not trigger reencryption crash (read would pass) +get_error_offsets 32 $OFFSET 512 $((32-1024*2-$OFFSET)) +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + +echo -n "resilience:" +decrypt_recover_online $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + get_error_offsets 32 $OFFSET 4096 $((32-1024*2-$OFFSET)) + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + wipe_dev /dev/mapper/$DEV_NAME + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + echo -n "resilience:" + decrypt_recover_online $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) +fi +echo "" + +echo "[36] Decryption with datashift recovery (online i/o error in moved segment)." +echo "sector size 512" + +# move injected error in moved segment area +get_error_offsets 32 0 512 $HZ_SIZE +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + +echo -n "resilience:" +for res in datashift-journal datashift-checksum; do + + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + wipe_dev /dev/mapper/$DEV_NAME + + decrypt_recover_online_moved $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) +done + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + get_error_offsets 32 0 4096 $HZ_SIZE + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + + echo -n "resilience:" + for res in datashift-journal datashift-checksum; do + + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + wipe_dev /dev/mapper/$DEV_NAME + + decrypt_recover_online_moved $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) + done +fi +echo "" + +echo "[37] Decryption with datashift (large data offsets)" +prepare_linear_dev 512 + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1015808 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV $((16*1024*2)) $HASH10 +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1015808 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV $((16*1024*2)) $HASH10 +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1046528 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1046528 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV 2048 $HASH2 + +remove_mapping +exit 0 |