Files
cryptsetup/tests/reencryption-compat-test2
Milan Broz aa1551c6e8 Introduce CRYPT_SLOT_UNBOUND keyslot status for LUKS2.
A keyslot not bound to any segment can store any key for any purpose.

To easily check slot status, new enum value is introduced.
This status is valid only for LUKS2, so the functions are backward compatible
with LUKS1.
2018-04-19 22:28:13 +02:00

414 lines
14 KiB
Bash
Executable File

#!/bin/bash
CRYPTSETUP=../cryptsetup
REENC=../cryptsetup-reencrypt
FAST_PBKDF_ARGON="--pbkdf-force-iterations 4 --pbkdf-memory 32 --pbkdf-parallel 1"
DEFAULT_ARGON="argon2i"
DEV_NAME=reenc9768
DEV_NAME2=reenc1273
IMG=reenc-data
IMG_HDR=$IMG.hdr
ORIG_IMG=reenc-data-orig
KEY1=key1
PWD1="93R4P4pIqAH8"
PWD2="1cND4319812f"
PWD3="1-9Qu5Ejfnqv"
MNT_DIR=./mnt_luks
START_DIR=$(pwd)
function dm_crypt_features()
{
local VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
[ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
local VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
local VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
[ $VER_MAJ -lt 1 ] && return
[ $VER_MAJ -eq 1 -a $VER_MIN -lt 11 ] && return
ALLOW_DISCARDS=--allow-discards
[ $VER_MAJ -eq 1 -a $VER_MIN -lt 14 ] && return
PERF_CPU=--perf-same_cpu_crypt
}
function del_scsi_device()
{
rmmod scsi_debug 2>/dev/null
sleep 2
}
function remove_mapping()
{
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 >/dev/null 2>&1
umount $MNT_DIR > /dev/null 2>&1
rmdir $MNT_DIR > /dev/null 2>&1
del_scsi_device
}
function fail()
{
[ -n "$1" ] && echo "$1"
echo "FAILED at line $(caller)"
cd $START_DIR
remove_mapping
exit 2
}
function skip()
{
[ -n "$1" ] && echo "$1"
exit 77
}
function add_scsi_device() {
del_scsi_device
modprobe scsi_debug $@
if [ $? -ne 0 ] ; then
echo "This kernel seems to not support proper scsi_debug module, test skipped."
exit 77
fi
sleep 2
SCSI_DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
[ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV."
}
function open_crypt() # $1 pwd, $2 hdr
{
if [ -n "$2" ] ; then
echo "$1" | $CRYPTSETUP luksOpen $IMG $DEV_NAME --header $2 || fail
elif [ -n "$1" ] ; then
echo "$1" | $CRYPTSETUP luksOpen $IMG $DEV_NAME || fail
else
$CRYPTSETUP luksOpen -d $KEY1 $IMG $DEV_NAME || fail
fi
}
function wipe_dev() # $1 dev
{
dd if=/dev/zero of=$1 bs=256k conv=notrunc >/dev/null 2>&1
}
function wipe() # $1 pass
{
open_crypt $1
wipe_dev /dev/mapper/$DEV_NAME
udevadm settle >/dev/null 2>&1
$CRYPTSETUP luksClose $DEV_NAME || fail
}
function prepare() # $1 dev1_siz
{
remove_mapping
dd if=/dev/zero of=$IMG bs=1k count=$1 >/dev/null 2>&1
if [ ! -e $KEY1 ]; then
dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1
fi
}
function check_hash_dev() # $1 dev, $2 hash
{
HASH=$(sha256sum $1 | cut -d' ' -f 1)
[ $HASH != "$2" ] && fail "HASH differs ($HASH)"
}
function check_hash() # $1 pwd, $2 hash, $hdr
{
open_crypt $1 $3
check_hash_dev /dev/mapper/$DEV_NAME $2
$CRYPTSETUP remove $DEV_NAME || fail
}
function backup_orig()
{
sync
cp $IMG $ORIG_IMG
}
function rollback()
{
sync
cp $ORIG_IMG $IMG
}
function check_slot() #space separeted list of active key slots
{
local _out=$($CRYPTSETUP luksDump $IMG | grep -e ": luks2" | sed -e 's/[[:space:]]*\([0-9]\+\):.*/\1/g')
local _req
local _hdr
local _j
for _i in $*; do
_j=$((_i))
_req="$_req $_j"
done
for _i in $_out; do
_j=$((_i))
_hdr="$_hdr $_j"
done
test "$_req" = "$_hdr"
}
function simple_scsi_reenc()
{
echo -n "$1"
echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_ARGON $SCSI_DEV || fail
echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail
HASH=$(sha256sum /dev/mapper/$DEV_NAME | cut -d' ' -f 1)
$CRYPTSETUP luksClose $DEV_NAME || fail
echo $PWD1 | $REENC -q $FAST_PBKDF_ARGON $SCSI_DEV || fail
echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail
check_hash_dev /dev/mapper/$DEV_NAME $HASH
$CRYPTSETUP luksClose $DEV_NAME || fail
}
function mount_and_test() {
test -d $MNT_DIR || mkdir -p $MNT_DIR
mount $@ $MNT_DIR 2>/dev/null || {
echo -n "failed to mount [SKIP]"
return 0
}
rm $MNT_DIR/* 2>/dev/null
cd $MNT_DIR
echo $PWD2 | $START_DIR/$REENC $START_DIR/$IMG -q --use-fsync --use-directio --write-log $FAST_PBKDF_ARGON || return 1
cd $START_DIR
umount $MNT_DIR
echo -n [OK]
}
function test_logging_tmpfs() {
echo -n "[tmpfs]"
mount_and_test -t tmpfs none -o size=$[25*1024*1024] || return 1
echo
}
function test_logging() {
echo -n "$1:"
for img in $(ls img_fs*img.bz2) ; do
wipefs -a $SCSI_DEV > /dev/null
echo -n "[${img%.img.bz2}]"
bzip2 -d -c $img | dd of=$SCSI_DEV bs=4k >/dev/null 2>&1
mount_and_test $SCSI_DEV || return 1
done
echo
}
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
[ ! -x "$REENC" ] && skip "Cannot find $REENC, test skipped."
which wipefs >/dev/null || skip "Cannot find wipefs, test skipped."
# REENCRYPTION tests
HASH4=2daeb1f36095b44b318410b3f4e8b5d989dcc7bb023d1426c492dab0a3053e74
HASH5=bb9f8df61474d25e71fa00722318cd387396ca1736605e1248821cc0de3d3af8
HASH6=4d9cbaf3aa0935a8c113f139691b3daf9c94c8d6c278aedc8eec66a4b9f6c8ae
echo "[1] Reencryption"
prepare 8192
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-plain $FAST_PBKDF_ARGON --align-payload 4096 $IMG || fail
wipe $PWD1
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q -s 256 $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q -s 256 -c aes-xts-plain64 -h sha256 $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q --use-directio $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q --master-key-file /dev/urandom $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q -s 512 --master-key-file /dev/urandom $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail
echo "[2] Reencryption with data shift"
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c aes-cbc-essiv:sha256 -s 128 $FAST_PBKDF_ARGON --align-payload 2048 $IMG || fail
wipe $PWD1
echo $PWD1 | $REENC $IMG -q -s 256 --reduce-device-size 1024S $FAST_PBKDF_ARGON || fail
check_hash $PWD1 $HASH6
echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_ARGON || fail
check_hash $PWD1 $HASH6
$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail
echo "[3] Reencryption with keyfile"
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -d $KEY1 -c aes-cbc-essiv:sha256 -s 128 $FAST_PBKDF_ARGON --align-payload 4096 $IMG || fail
wipe
check_hash "" $HASH5
echo $PWD1 | $CRYPTSETUP -q luksAddKey -d $KEY1 $IMG $FAST_PBKDF_ARGON || fail
$REENC $IMG -d $KEY1 $FAST_PBKDF_ARGON -q 2>/dev/null && fail
$REENC $IMG -d $KEY1 -S 0 $FAST_PBKDF_ARGON -q || fail
check_hash "" $HASH5
check_slot 0 || fail "Only keyslot 0 expected to be enabled"
$REENC $IMG -d $KEY1 $FAST_PBKDF_ARGON -q || fail
$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail
# FIXME echo $PWD1 | $REENC ...
echo "[4] Encryption of not yet encrypted device"
# well, movin' zeroes :-)
OFFSET=8192 # default LUKS2 header size
prepare 8192
check_hash_dev $IMG $HASH4
echo $PWD1 | $REENC --type luks2 $IMG -c aes-cbc-essiv:sha256 -s 128 --new --reduce-device-size "$OFFSET"S -q $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail
echo "[5] Reencryption using specific keyslot"
echo $PWD2 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 1 $IMG || fail
echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 2 $IMG || fail
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 3 $IMG || fail
echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 4 $IMG || fail
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 5 $IMG || fail
echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 6 $IMG || fail
echo -e "$PWD2\n$PWD3" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 22 $IMG || fail
backup_orig
echo $PWD2 | $REENC $FAST_PBKDF_ARGON -S 0 -q $IMG || fail
check_slot 0 || fail "Only keyslot 0 expected to be enabled"
wipe $PWD2
rollback
echo $PWD1 | $REENC $FAST_PBKDF_ARGON -S 1 -q $IMG || fail
check_slot 1 || fail "Only keyslot 1 expected to be enabled"
wipe $PWD1
rollback
echo $PWD2 | $REENC $FAST_PBKDF_ARGON -S 6 -q $IMG || fail
check_slot 6 || fail "Only keyslot 6 expected to be enabled"
wipe $PWD2
rollback
echo $PWD3 | $REENC $FAST_PBKDF_ARGON -S 22 -q $IMG || fail
check_slot 22 || fail "Only keyslot 22 expected to be enabled"
wipe $PWD3
rollback
echo "[6] Reencryption using all active keyslots"
echo -e "$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD3" | $REENC -q $IMG $FAST_PBKDF_ARGON || fail
check_slot 0 1 2 3 4 5 6 22 || fail "All keyslots expected to be enabled"
echo "[7] Reencryption of block devices with different block size"
add_scsi_device sector_size=512 dev_size_mb=8
simple_scsi_reenc "[512 sector]"
add_scsi_device sector_size=4096 dev_size_mb=8
simple_scsi_reenc "[4096 sector]"
add_scsi_device sector_size=512 physblk_exp=3 dev_size_mb=8
simple_scsi_reenc "[4096/512 sector]"
echo "[OK]"
echo "[8] Header only reencryption (hash and iteration time)"
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
wipe $PWD1
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf pbkdf2 --pbkdf-force-iterations 999 2>/dev/null && fail
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf-force-iterations 3 2>/dev/null && fail
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf-force-iterations 4 --pbkdf-memory 31 2>/dev/null && fail
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --hash sha512
check_hash $PWD1 $HASH5
[ "$($CRYPTSETUP luksDump $IMG | grep -A4 -m1 "0: luks2" | grep PBKDF: | sed -e 's/[[:space:]]\+PBKDF:\ \+//g')" = "pbkdf2" ] || fail
[ "$($CRYPTSETUP luksDump $IMG | grep -A5 -m1 "0: luks2" | grep Hash: | sed -e 's/[[:space:]]\+Hash:\ \+//g')" = "sha512" ] || fail
echo $PWD1 | $REENC $IMG -q --keep-key $FAST_PBKDF_ARGON
check_hash $PWD1 $HASH5
[ "$($CRYPTSETUP luksDump $IMG | grep -A4 -m1 "0: luks2" | grep PBKDF: | sed -e 's/[[:space:]]\+PBKDF:\ \+//g')" = $DEFAULT_ARGON ] || fail
[ "$($CRYPTSETUP luksDump $IMG | grep -A5 -m1 "0: luks2" | grep "Time cost" | sed -e 's/[[:space:]]\+Time\ cost:\ \+//g')" -eq 4 ] || fail
[ "$($CRYPTSETUP luksDump $IMG | grep -A6 -m1 "0: luks2" | grep Memory | sed -e 's/[[[:space:]]\+Memory:\ \+//g')" -eq 32 ] || fail
[ "$($CRYPTSETUP luksDump $IMG | grep -A7 -m1 "0: luks2" | grep Threads | sed -e 's/[[[:space:]]\+Threads:\ \+//g')" -eq 1 ] || fail
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey -S21 $FAST_PBKDF_ARGON $IMG || fail
echo $PWD2 | $REENC -S21 -q --keep-key --pbkdf pbkdf2 --pbkdf-force-iterations 1000 $IMG || fail
check_hash $PWD2 $HASH5
check_slot 21 || fail "Only keyslot 21 expected to be enabled"
$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail
echo "[9] Test log I/Os on various underlaying block devices"
echo $PWD2 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
add_scsi_device sector_size=512 dev_size_mb=32
test_logging "[512 sector]" || fail
add_scsi_device sector_size=4096 dev_size_mb=32
test_logging "[4096 sector]" || fail
add_scsi_device sector_size=512 dev_size_mb=32 physblk_exp=3
test_logging "[4096/512 sector]" || fail
test_logging_tmpfs || fail
echo "[10] Removal of encryption"
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
wipe $PWD1
check_hash $PWD1 $HASH5
echo $PWD1 | $REENC $IMG -q --decrypt
check_hash_dev $IMG $HASH4
echo "[11] Reencryption with tokens"
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
wipe $PWD1
check_hash $PWD1 $HASH5
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey -S23 $FAST_PBKDF_ARGON $IMG || fail
echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey -S1 $FAST_PBKDF_ARGON $IMG || fail
echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey -S3 $FAST_PBKDF_ARGON $IMG || fai
$CRYPTSETUP token add --key-description key-name0 --key-slot 23 --token-id 0 $IMG
$CRYPTSETUP token add --key-description key-name2 --key-slot 1 --token-id 2 $IMG
$CRYPTSETUP token add --key-description key-name31 --token-id 31 $IMG
echo $PWD1 | $CRYPTSETUP -q luksKillSlot $IMG 3 || fail
echo $PWD2 | $REENC $FAST_PBKDF_ARGON -S 23 -q $IMG || fail
$CRYPTSETUP luksDump $IMG | grep "0: luks2-keyring" >/dev/null || fail
[ "$($CRYPTSETUP luksDump $IMG | grep -A2 -m1 "0: luks2-keyring" | grep Keyslot: | sed -e 's/[[[:space:]]\+Keyslot:\ \+//g')" -eq 23 ] || fail
$CRYPTSETUP luksDump $IMG | grep "2: luks2-keyring" >/dev/null || fail
$CRYPTSETUP luksDump $IMG | grep "31: luks2-keyring" >/dev/null || fail
[ "$($CRYPTSETUP luksDump $IMG | grep -A2 -m1 "31: luks2-keyring" | grep Keyslot: | sed -e 's/[[[:space:]]\+Keyslot:\ \+//g')" -eq 23 ] || fail
echo "[12] Reencryption with persistent flags"
dm_crypt_features
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
wipe $PWD1
check_hash $PWD1 $HASH5
echo $PWD1 | $CRYPTSETUP open $IMG $DEV_NAME $ALLOW_DISCARDS $PERF_CPU --persistent || fail
$CRYPTSETUP close $DEV_NAME || fail
echo $PWD1 | $REENC $FAST_PBKDF_ARGON -q $IMG || fail
if [ -n "$PERF_CPU" ]; then
$CRYPTSETUP luksDump $IMG | grep -m1 Flags: | grep same-cpu-crypt > /dev/null || fail
fi
if [ -n "$ALLOW_DISCARDS" ]; then
$CRYPTSETUP luksDump $IMG | grep -m1 Flags: | grep allow-discards > /dev/null || fail
fi
echo "[13] Detached header - adding encryption/reencryption/decryption"
prepare 8192
check_hash_dev $IMG $HASH4
echo $PWD1 | $REENC --type luks2 $IMG -q $FAST_PBKDF --header $IMG_HDR --new
check_hash $PWD1 $HASH4 $IMG_HDR
echo $PWD1 | $REENC $IMG -q $FAST_PBKDF --header $IMG_HDR
check_hash $PWD1 $HASH4 $IMG_HDR
echo $PWD1 | $REENC $IMG -q --header $IMG_HDR --decrypt
check_hash_dev $IMG $HASH4
# existing header of zero size
cat /dev/null >$IMG_HDR
echo $PWD1 | $REENC --type luks2 $IMG -q $FAST_PBKDF --header $IMG_HDR --new
check_hash $PWD1 $HASH4 $IMG_HDR
$CRYPTSETUP isLuks $IMG && fail
$CRYPTSETUP isLuks $IMG_HDR || fail
$CRYPTSETUP luksDump $IMG_HDR | grep -q "0: luks2" || fail
echo "[14] Reencryption with unbound keyslot"
prepare 8192
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG || fail
echo $PWD2 | $CRYPTSETUP -q luksAddKey -S 3 --unbound --key-size 64 $FAST_PBKDF_ARGON $IMG || fail
wipe $PWD1
check_hash $PWD1 $HASH5
$CRYPTSETUP luksDump $IMG | grep -q "3: luks2 (unbound)" || fail
echo $PWD2 | $REENC $IMG -q $FAST_PBKDF 2>/dev/null && fail
echo -e "$PWD1\n$PWD2" | $REENC $IMG -q $FAST_PBKDF || fail
$CRYPTSETUP luksDump $IMG | grep -q "3: luks2 (unbound)" || fail
remove_mapping
exit 0