mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add trusted/encrypted keyring test (for plain format).
This commit is contained in:
@@ -16,6 +16,7 @@ TESTS = 00modules-test \
|
||||
device-test \
|
||||
keyring-test \
|
||||
keyring-compat-test \
|
||||
keyring-trusted-test \
|
||||
luks2-validation-test \
|
||||
luks2-integrity-test \
|
||||
vectors-test \
|
||||
@@ -86,6 +87,7 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \
|
||||
device-test \
|
||||
keyring-test \
|
||||
keyring-compat-test \
|
||||
keyring-trusted-test \
|
||||
integrity-compat-test \
|
||||
cryptsetup-valg-supps valg.sh valg-api.sh \
|
||||
blockwise-compat-test \
|
||||
|
||||
184
tests/keyring-trusted-test
Executable file
184
tests/keyring-trusted-test
Executable file
@@ -0,0 +1,184 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Encrypted and trusted keyring test; trusted keys can be emulated by TPM2.
|
||||
# DO NOT use this in combination with a real TPM data, it can destroy them.
|
||||
#
|
||||
# Note that if trusted or tpm kernel module is built-in, emulated TPM2 cannot
|
||||
# provide trusted keys (only encrypted keys will be tested then).
|
||||
|
||||
[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
|
||||
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
|
||||
|
||||
IMG=keyring_trusted_test.img
|
||||
MAP="trusted_test"
|
||||
KEYNAME=testxxx
|
||||
|
||||
function bin_check()
|
||||
{
|
||||
command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped."
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
clear_keys
|
||||
|
||||
[ -S $SWTPM_STATE_DIR/ctrl.sock ] && {
|
||||
# shutdown TPM via control socket
|
||||
swtpm_ioctl -s --unix $SWTPM_STATE_DIR/ctrl.sock
|
||||
sleep 1
|
||||
}
|
||||
|
||||
# if graceful shutdown was successful, pidfile should be deleted
|
||||
# if it is still present, we forcefully kill the process
|
||||
[ -f "$SWTPM_PIDFILE" ] && {
|
||||
kill -9 $(cat $SWTPM_PIDFILE) >/dev/null 2>&1
|
||||
}
|
||||
|
||||
[ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP
|
||||
|
||||
[ -n "$SWTPM_PIDFILE" ] && rm -f $SWTPM_PIDFILE >/dev/null 2>&1
|
||||
[ -n "$SWTPM_STATE_DIR" ] && rm -rf $SWTPM_STATE_DIR >/dev/null 2>&1
|
||||
rm -f $IMG >/dev/null 2>&1
|
||||
|
||||
cleanup_modules
|
||||
}
|
||||
|
||||
function cleanup_modules()
|
||||
{
|
||||
[ -n "$SKIP_MODULE_UNLOAD" ] && return
|
||||
|
||||
# This is a hack to avoid linking trusted key to another TPM.
|
||||
# Without clean load tests do not work reliably.
|
||||
modprobe -r dm-crypt 2>/dev/null
|
||||
modprobe -r encrypted-keys 2>/dev/null
|
||||
modprobe -r trusted 2>/dev/null
|
||||
modprobe -r tpm_vtpm_proxy 2>/dev/null
|
||||
modprobe -r tpm 2>/dev/null
|
||||
}
|
||||
|
||||
function fail()
|
||||
{
|
||||
echo "[FAILED]"
|
||||
[ -n "$1" ] && echo "$1"
|
||||
echo "FAILED backtrace:"
|
||||
while caller $frame; do ((frame++)); done
|
||||
cleanup
|
||||
exit 2
|
||||
}
|
||||
|
||||
function skip()
|
||||
{
|
||||
[ -n "$1" ] && echo "$1"
|
||||
cleanup
|
||||
exit 77
|
||||
}
|
||||
|
||||
function prepare_tpm()
|
||||
{
|
||||
SWTPM_STATE_DIR=$(mktemp -d /tmp/systemd_swtpm_state.XXXXXX)
|
||||
SWTPM_SEAL_KEY="$SWTPM_STATE_DIR/sealkey.ctxt"
|
||||
SWTPM_PERSISTENT_HANDLE=0x81000001
|
||||
|
||||
if [ -z "$TPM_PATH" ]; then
|
||||
bin_check swtpm
|
||||
bin_check swtpm_ioctl
|
||||
|
||||
SWTPM_PIDFILE=$(mktemp /tmp/systemd_swtpm_pid.XXXXXX)
|
||||
|
||||
cleanup_modules
|
||||
modprobe tpm_vtpm_proxy || fail "Failed to load tpm_vtpm_proxy kernel module, required for emulated TPM."
|
||||
|
||||
SWTPM_LOG=$(swtpm chardev --vtpm-proxy --tpm2 --tpmstate dir=$SWTPM_STATE_DIR -d --pid file=$SWTPM_PIDFILE --ctrl type=unixio,path=$SWTPM_STATE_DIR/ctrl.sock)
|
||||
TPM_PATH=$(echo $SWTPM_LOG | grep -Eo /dev/tpm\([0-9]\)+ | sed s/tpm/tpmrm/)
|
||||
|
||||
[ -z "$TPM_PATH" ] && fail "No TPM_PATH set and swtpm failed, test skipped."
|
||||
|
||||
echo "Virtual TPM set up at $TPM_PATH"
|
||||
|
||||
# Trusted module needs to see TPM above.
|
||||
sleep 1
|
||||
modprobe trusted 2>/dev/null || echo "Failed to load trusted keys kernel module."
|
||||
else
|
||||
SKIP_MODULE_UNLOAD=1
|
||||
echo "Preconfigured TPM set up at $TPM_PATH"
|
||||
fi
|
||||
# Create persistent store
|
||||
tpm2_createprimary -Q -T device:$TPM_PATH --hierarchy o -G rsa2048 -c $SWTPM_SEAL_KEY || fail
|
||||
tpm2_evictcontrol -Q -T device:$TPM_PATH -c $SWTPM_SEAL_KEY $SWTPM_PERSISTENT_HANDLE || fail
|
||||
}
|
||||
|
||||
function prepare_vk_keyring()
|
||||
{
|
||||
local s_desc=$(keyctl rdescribe @s | cut -d';' -f5)
|
||||
local us_desc=$(keyctl rdescribe @us | cut -d';' -f5)
|
||||
|
||||
if [ "$s_desc" = "$us_desc" -a -n "$s_desc" ]; then
|
||||
echo "Session keyring is missing, initializing new one."
|
||||
keyctl new_session > /dev/null || fail
|
||||
fi
|
||||
}
|
||||
|
||||
clear_keys()
|
||||
{
|
||||
keyctl revoke %encrypted:$KEYNAME 2>/dev/null
|
||||
keyctl revoke %user:$KEYNAME 2>/dev/null
|
||||
|
||||
if [ -n "$TRUSTED_SUPPORTED" ]; then
|
||||
keyctl revoke %trusted:$KEYNAME 2>/dev/null
|
||||
tpm2_evictcontrol -Q -T device:$TPM_PATH -C o -c $SWTPM_PERSISTENT_HANDLE 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
|
||||
bin_check keyctl
|
||||
|
||||
prepare_vk_keyring
|
||||
|
||||
# Prevent using TPM by default
|
||||
if [ -n "$RUN_KEYRING_TRUSTED_TEST" ]; then
|
||||
prepare_tpm
|
||||
# Trusted keyring key
|
||||
keyctl add trusted $KEYNAME "new 32 keyhandle=$SWTPM_PERSISTENT_HANDLE" @s >/dev/null 2>&1 && TRUSTED_SUPPORTED=1
|
||||
if [ -n "$TRUSTED_SUPPORTED" ]; then
|
||||
keyctl print %trusted:$KEYNAME >/dev/null || fail "Cannot read trusted key blob."
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Variable RUN_KEYRING_TRUSTED_TEST must be defined, TPM trusted test skipped."
|
||||
TRUSTED_SUPPORTED=
|
||||
fi
|
||||
|
||||
# Prepare encrypted key
|
||||
modprobe encrypted-keys 2>/dev/null || skip "Failed to load encrypted keys kernel module."
|
||||
|
||||
# Encrypted keyring key (encrypted with user key)
|
||||
# User key needed for encrypted key
|
||||
keyctl add -x user $KEYNAME bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a @s >/dev/null || fail "User key failed."
|
||||
keyctl print %user:$KEYNAME >/dev/null || fail "Cannot read user key."
|
||||
|
||||
keyctl add encrypted $KEYNAME "new user:$KEYNAME 32" @s >/dev/null || fail "Encrypted keys are not supported."
|
||||
keyctl print %encrypted:$KEYNAME >/dev/null || fail "Cannot read encrypted key blob."
|
||||
|
||||
dd if=/dev/zero of=$IMG bs=1M count=32 >/dev/null 2>&1
|
||||
|
||||
echo -n "Plain with trusted volume key "
|
||||
if [ -n "$TRUSTED_SUPPORTED" ]; then
|
||||
$CRYPTSETUP open --type plain $IMG $MAP --key-size=256 --cipher=aes-xts-plain64 --volume-key-keyring=%trusted:$KEYNAME || fail
|
||||
dmsetup table --showkeys $MAP | grep -q ":32:trusted:$KEYNAME" || fail
|
||||
$CRYPTSETUP status $MAP | grep -q "key location: keyring" || fail
|
||||
$CRYPTSETUP close $MAP || fail
|
||||
echo "[OK]"
|
||||
else
|
||||
echo "[N/A]"
|
||||
fi
|
||||
|
||||
echo -n "Plain with encrypted volume key "
|
||||
$CRYPTSETUP open --type plain $IMG $MAP --key-size=256 --cipher=aes-xts-plain64 --volume-key-keyring=%encrypted:$KEYNAME ||fail
|
||||
dmsetup table --showkeys $MAP | grep -q ":32:encrypted:$KEYNAME" || fail
|
||||
$CRYPTSETUP status $MAP | grep -q "key location: keyring" || fail
|
||||
$CRYPTSETUP resize $MAP --size 100 || fail
|
||||
$CRYPTSETUP status $MAP| grep "size:" | grep -q "100 sectors" || fail
|
||||
$CRYPTSETUP resize $MAP || fail
|
||||
$CRYPTSETUP close $MAP || fail
|
||||
echo "[OK]"
|
||||
|
||||
cleanup
|
||||
exit 0
|
||||
@@ -392,6 +392,14 @@ if get_option('cryptsetup')
|
||||
depends: [
|
||||
cryptsetup,
|
||||
])
|
||||
test('keyring-trusted-test',
|
||||
find_program('./keyring-trusted-test'),
|
||||
workdir: meson.current_build_dir(),
|
||||
timeout: 14400,
|
||||
is_parallel: false,
|
||||
depends: [
|
||||
cryptsetup,
|
||||
])
|
||||
test('luks2-validation-test',
|
||||
find_program('./luks2-validation-test'),
|
||||
workdir: meson.current_build_dir(),
|
||||
|
||||
Reference in New Issue
Block a user