mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2026-01-07 07:55:31 +01:00
System FIPS mode check is no longer dependent on /etc/system-fips file. The change should be compatible with older distributions since we now depend on crypto backend internal routine. This commit affects only FIPS enabled systems (with FIPS enabled builds). In case this causes any regression in current distributions feel free to drop the patch. For reference see https://bugzilla.redhat.com/show_bug.cgi?id=2080516
235 lines
8.8 KiB
Bash
Executable File
235 lines
8.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
CIPHER_XTS_PLAIN="aes-xts-plain64"
|
|
CIPHER_CBC_ESSIV="aes-cbc-essiv:sha256"
|
|
CIPHER_CBC_TCW="serpent-cbc-tcw"
|
|
# TODO: mode with LMK
|
|
|
|
TEST_KEYRING_NAME="keyringtest_keyring"
|
|
|
|
LOGON_KEY_16_OK="dmtst:lkey_16"
|
|
LOGON_KEY_32_OK="dmtst:lkey_32"
|
|
LOGON_KEY_64_OK="dmtst:lkey_64"
|
|
|
|
HEXKEY_16="be21aa8c733229347bd4e681891e213d";
|
|
HEXKEY_32="bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
|
|
HEXKEY_64="34f95b96abff946b64f1339ff8653cc77c38697c93b797a496f3786e86eed7781850d5112bbae17d209b8310a8f3a034f1cd297667bc0cd1438fad28d87ef6a1"
|
|
|
|
DEVSIZEMB=16
|
|
DEVSECTORS=$((DEVSIZEMB*1024*1024/512))
|
|
NAME=testcryptdev
|
|
CHKS_DMCRYPT=vk_in_dmcrypt.chk
|
|
CHKS_KEYRING=vk_in_keyring.chk
|
|
|
|
PWD="aaa"
|
|
|
|
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
|
|
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
|
|
|
|
CRYPTSETUP_VALGRIND=../.libs/cryptsetup
|
|
CRYPTSETUP_LIB_VALGRIND=../.libs
|
|
|
|
FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
|
|
|
|
function remove_mapping()
|
|
{
|
|
[ -b /dev/mapper/$NAME ] && dmsetup remove --retry $NAME
|
|
|
|
# unlink whole test keyring
|
|
[ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
|
|
|
|
rmmod scsi_debug >/dev/null 2>&1
|
|
|
|
rm -f $CHKS_DMCRYPT $CHKS_KEYRING
|
|
}
|
|
|
|
function skip()
|
|
{
|
|
[ -n "$1" ] && echo "$1"
|
|
remove_mapping
|
|
exit 77
|
|
}
|
|
|
|
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 fail()
|
|
{
|
|
[ -n "$1" ] && echo "$1"
|
|
echo "FAILED backtrace:"
|
|
while caller $frame; do ((frame++)); done
|
|
remove_mapping
|
|
exit 2
|
|
}
|
|
|
|
# $1 hexbyte key
|
|
# $2 type
|
|
# $3 description
|
|
# $4 keyring
|
|
function load_key()
|
|
{
|
|
local tmp="$1"
|
|
shift
|
|
echo -n "$tmp" | xxd -r -p | keyctl padd $@ >/dev/null
|
|
}
|
|
|
|
function dm_crypt_keyring_support()
|
|
{
|
|
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.)
|
|
|
|
# run the test with dm-crypt v1.15.0+ on purpose
|
|
# the fix is in dm-crypt v1.18.1+
|
|
[ $VER_MAJ -gt 1 ] && return 0
|
|
[ $VER_MAJ -lt 1 ] && return 1
|
|
[ $VER_MIN -ge 15 ]
|
|
}
|
|
|
|
function test_and_prepare_keyring() {
|
|
keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped"
|
|
TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null)
|
|
test -n "$TEST_KEYRING" || skip "Failed to create keyring in user keyring"
|
|
keyctl search "@s" keyring "$TEST_KEYRING" > /dev/null 2>&1 || keyctl link "@u" "@s" > /dev/null 2>&1
|
|
load_key "$HEXKEY_16" user test_key "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped."
|
|
}
|
|
|
|
function fips_mode()
|
|
{
|
|
[ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ]
|
|
}
|
|
|
|
add_device() {
|
|
rmmod scsi_debug >/dev/null 2>&1
|
|
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 2
|
|
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
|
|
|
|
DEV="/dev/$DEV"
|
|
[ -b $DEV ] || fail "Cannot find $DEV."
|
|
}
|
|
|
|
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
|
|
[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run
|
|
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
|
|
command -v dmsetup >/dev/null || skip "Cannot find dmsetup, test skipped"
|
|
command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped"
|
|
command -v xxd >/dev/null || skip "Cannot find xxd, test skipped"
|
|
command -v sha256sum >/dev/null || skip "Cannot find sha256sum, test skipped"
|
|
modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load"
|
|
dm_crypt_keyring_support || skip "dm-crypt doesn't support kernel keyring, test skipped."
|
|
|
|
test_and_prepare_keyring
|
|
|
|
add_device dev_size_mb=$DEVSIZEMB
|
|
|
|
dd if=/dev/urandom of=$DEV bs=1M count=$DEVSIZEMB oflag=direct > /dev/null 2>&1 || fail
|
|
|
|
#test aes cipher with xts mode, plain IV
|
|
echo -n "Testing $CIPHER_XTS_PLAIN..."
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
load_key "$HEXKEY_32" logon $LOGON_KEY_32_OK "$TEST_KEYRING" || fail "Cannot load 32 byte logon key type"
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN :32:logon:$LOGON_KEY_32_OK 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
|
|
# same test using message
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail
|
|
dmsetup suspend $NAME || fail
|
|
dmsetup message $NAME 0 key wipe || fail
|
|
dmsetup message $NAME 0 "key set :32:logon:$LOGON_KEY_32_OK" || fail
|
|
dmsetup resume $NAME || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
|
|
echo "OK"
|
|
|
|
#test aes cipher, xts mode, essiv IV
|
|
echo -n "Testing $CIPHER_CBC_ESSIV..."
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
load_key "$HEXKEY_16" logon $LOGON_KEY_16_OK "$TEST_KEYRING" || fail "Cannot load 16 byte logon key type"
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV :16:logon:$LOGON_KEY_16_OK 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
|
|
# same test using message
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail
|
|
dmsetup suspend $NAME || fail
|
|
dmsetup message $NAME 0 key wipe || fail
|
|
dmsetup message $NAME 0 "key set :16:logon:$LOGON_KEY_16_OK" || fail
|
|
dmsetup resume $NAME || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
|
|
echo "OK"
|
|
|
|
#test serpent cipher, cbc mode, tcw IV
|
|
fips_mode || {
|
|
echo -n "Testing $CIPHER_CBC_TCW..."
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
load_key "$HEXKEY_64" logon $LOGON_KEY_64_OK "$TEST_KEYRING" || fail "Cannot load 16 byte logon key type"
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW :64:logon:$LOGON_KEY_64_OK 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksum mismatch (corruption)"
|
|
# same test using message
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail
|
|
dmsetup suspend $NAME || fail
|
|
dmsetup message $NAME 0 key wipe || fail
|
|
dmsetup message $NAME 0 "key set :64:logon:$LOGON_KEY_64_OK" || fail
|
|
dmsetup resume $NAME || fail
|
|
sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
|
|
dmsetup remove --retry $NAME || fail
|
|
diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
|
|
echo "OK"
|
|
}
|
|
|
|
echo -n "Test LUKS2 key refresh..."
|
|
echo $PWD | $CRYPTSETUP luksFormat --type luks2 --luks2-metadata-size 16k --luks2-keyslots-size 4064k --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --force-password $DEV || fail
|
|
echo $PWD | $CRYPTSETUP open $DEV $NAME || fail
|
|
$CRYPTSETUP status $NAME | grep -q -i "location:.*keyring" || skip "LUKS2 can't use keyring. Test skipped."
|
|
dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha256sum > $CHKS_KEYRING || fail
|
|
echo $PWD | $CRYPTSETUP refresh $NAME --disable-keyring || fail
|
|
$CRYPTSETUP status $NAME | grep -q -i "location:.*keyring" && fail "Key is still in keyring"
|
|
dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha256sum > $CHKS_DMCRYPT || fail
|
|
diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksum mismatch (corruption)"
|
|
echo "OK"
|
|
|
|
remove_mapping
|