summaryrefslogtreecommitdiffstats
path: root/tests/keyring-test
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xtests/keyring-test238
1 files changed, 238 insertions, 0 deletions
diff --git a/tests/keyring-test b/tests/keyring-test
new file mode 100755
index 0000000..3ed3aff
--- /dev/null
+++ b/tests/keyring-test
@@ -0,0 +1,238 @@
+#!/bin/bash
+
+DEV_ZERO="dmtst-zero"
+DEV_CRYPT="dmtst-crypt"
+
+CIPHER="aes-xts-plain64"
+
+TEST_KEYRING_NAME="keyringtest_keyring"
+
+USER_KEY_32_OK="dmtst:ukey_32_ok"
+USER_KEY_32_WRONG="dmtst:ukey_32_wrong_size"
+
+LOGON_KEY_32_OK="dmtst:lkey_32_ok"
+LOGON_KEY_32_WRONG="dmtst:lkey_32_wrong_size"
+
+PAYLOAD_32="bb21158c733229347bd4e681891e213d"
+PAYLOAD_31="bb21158c733229347bd4e681891e213"
+
+HEXKEY_32="bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
+HEXKEY_32_BAD="bb21158c733229347bd4e68189XXXX3d94c685be6a5b84818afe7a78a6de7a1a"
+HEXKEY_31="bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a"
+
+function remove_mapping()
+{
+ [ -b /dev/mapper/$DEV_CRYPT ] && dmsetup remove --retry $DEV_CRYPT
+ [ -b /dev/mapper/$DEV_ZERO ] && dmsetup remove --retry $DEV_ZERO
+
+ # unlink whole test keyring
+ [ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
+}
+
+function skip()
+{
+ [ -n "$1" ] && echo "$1"
+ remove_mapping
+ exit 77
+}
+
+function fail()
+{
+ [ -n "$1" ] && echo "$1"
+ echo "FAILED backtrace:"
+ while caller $frame; do ((frame++)); done
+ remove_mapping
+ exit 2
+}
+
+# $1 type
+# $2 description
+# $3 payload
+# $4 keyring
+function load_key()
+{
+ keyctl add $@ >/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.)
+
+ [ $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 user test_key test_data "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped."
+}
+
+[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
+which dmsetup >/dev/null 2>&1 || skip "Cannot find dmsetup, test skipped"
+which keyctl >/dev/null 2>&1 || skip "Cannot find keyctl, test skipped"
+modprobe dm-crypt || fail "dm-crypt failed to load"
+dm_crypt_keyring_support || skip "dm-crypt doesn't support kernel keyring, test skipped."
+
+test_and_prepare_keyring
+
+load_key logon $LOGON_KEY_32_OK $PAYLOAD_32 "$TEST_KEYRING" || fail "Cannot load 32 byte logon key type"
+load_key user $USER_KEY_32_OK $PAYLOAD_32 "$TEST_KEYRING" || fail "Cannot load 32 byte user key type"
+load_key logon $LOGON_KEY_32_WRONG $PAYLOAD_31 "$TEST_KEYRING" || fail "Cannot load 31 byte logon key type"
+load_key user $USER_KEY_32_WRONG $PAYLOAD_31 "$TEST_KEYRING" || fail "Cannot load 31 byte user key type"
+
+dmsetup create $DEV_ZERO --table "0 100 zero" || fail
+
+echo "[1] Valid keyring keys"
+
+# load logon type kernel key
+KEY=":32:logon:$LOGON_KEY_32_OK"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $KEY 0 /dev/mapper/$DEV_ZERO 0" || fail
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER $KEY 0" || fail
+dmsetup remove --retry $DEV_CRYPT || fail
+
+# load user type kernel key
+KEY=":32:user:$USER_KEY_32_OK"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $KEY 0 /dev/mapper/$DEV_ZERO 0" || fail
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER $KEY 0" || fail
+dmsetup remove --retry $DEV_CRYPT || fail
+
+# load logon type kernel key...
+KEY=":32:logon:$LOGON_KEY_32_OK"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $KEY 0 /dev/mapper/$DEV_ZERO 0" || fail
+dmsetup suspend $DEV_CRYPT || fail
+dmsetup message $DEV_CRYPT 0 "key wipe" || fail
+# ...replace the key with hexkey...
+dmsetup message $DEV_CRYPT 0 "key set $HEXKEY_32" || fail
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER $HEXKEY_32 0" || fail
+dmsetup resume $DEV_CRYPT || fail
+dmsetup suspend $DEV_CRYPT || fail
+# ...and replace it again with user type kernel key...
+dmsetup message $DEV_CRYPT 0 "key set :32:user:$USER_KEY_32_OK" || fail
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER :32:user:$USER_KEY_32_OK 0" || fail
+dmsetup message $DEV_CRYPT 0 "key set $HEXKEY_32" || fail
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER $HEXKEY_32 0" || fail
+dmsetup resume $DEV_CRYPT || fail
+dmsetup remove --retry $DEV_CRYPT || fail
+
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $HEXKEY_32 0 /dev/mapper/$DEV_ZERO 0" || fail
+dmsetup suspend $DEV_CRYPT || fail
+dmsetup message $DEV_CRYPT 0 "key wipe" || fail
+dmsetup message $DEV_CRYPT 0 "key set :32:user:$USER_KEY_32_OK" || fail
+dmsetup resume $DEV_CRYPT || fail
+dmsetup suspend $DEV_CRYPT || fail
+dmsetup message $DEV_CRYPT 0 "key set :32:logon:$LOGON_KEY_32_OK" || fail
+dmsetup resume $DEV_CRYPT || fail
+dmsetup remove --retry $DEV_CRYPT || fail
+
+echo "[2] message ioctl"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $HEXKEY_32 0 /dev/mapper/$DEV_ZERO 0" || fail
+dmsetup suspend $DEV_CRYPT || fail
+dmsetup message $DEV_CRYPT 0 "key set :32:logon:$LOGON_KEY_32_WRONG" 2> /dev/null && fail
+# old key should be intact and valid
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER $HEXKEY_32 0" || fail
+dmsetup resume $DEV_CRYPT || fail
+dmsetup suspend $DEV_CRYPT || fail
+# now the key gets destroyed by invalid input
+dmsetup message $DEV_CRYPT 0 "key set $HEXKEY_32_BAD" 2> /dev/null && fail
+dmsetup resume $DEV_CRYPT 2> /dev/null && fail
+# hmm... see the output. don't like it
+# dmsetup table --showkeys $DEV_CRYPT
+
+dmsetup message $DEV_CRYPT 0 "key set :32:user:$USER_KEY_32_OK" || fail
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER :32:user:$USER_KEY_32_OK 0" || fail
+dmsetup message $DEV_CRYPT 0 "key set :31:logon:$LOGON_KEY_32_OK" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set :" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set ::::" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set :0:logon:$LOGON_KEY_32_OK" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set :32" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set :32:" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set :32:logon" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set :32:logo" 2> /dev/null && fail
+dmsetup message $DEV_CRYPT 0 "key set :32:logon:" 2> /dev/null && fail
+dmsetup table --showkeys $DEV_CRYPT | grep -q "crypt $CIPHER :32:user:$USER_KEY_32_OK 0" || fail
+dmsetup message $DEV_CRYPT 0 "key set :32:user:$USER_KEY_32_OK" || fail
+dmsetup resume $DEV_CRYPT || fail
+dmsetup remove --retry $DEV_CRYPT || fail
+
+echo "[3] bOrked keys"
+# declare the key having 32 bytes but load key which has in fact 31 bytes only
+KEY=":32:logon:$LOGON_KEY_32_WRONG"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $KEY 0 /dev/mapper/$DEV_ZERO 0" 2> /dev/null && fail "dm-crypt accepted wrong key size"
+
+# declare the key having 31 bytes (incompatible with cipher) and load key with 32 bytes in real
+KEY=":31:logon:$LOGON_KEY_32_WRONG"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $KEY 0 /dev/mapper/$DEV_ZERO 0" 2> /dev/null && fail "dm-crypt accepted wrong key size"
+
+# declare the key being user type but try to load logon one
+KEY=":32:user:$LOGON_KEY_32"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $KEY 0 /dev/mapper/$DEV_ZERO 0" 2> /dev/null && fail "dm-crypt accepted key description for invalid key type"
+
+# now the other way
+KEY=":32:logon:$USER_KEY_32"
+dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $KEY 0 /dev/mapper/$DEV_ZERO 0" 2> /dev/null && fail "dm-crypt accepted key description for invalid key type"
+
+BORKED_KEYS=":\ 32:logon:$LOGON_KEY_32_OK
+: 32:logon:$LOGON_KEY_32_OK
+:+32:logon:$LOGON_KEY_32_OK
+:-32:logon:$LOGON_KEY_32_OK
+:32 :logon:$LOGON_KEY_32_OK
+:32\ :logon:$LOGON_KEY_32_OK
+:32_:logon:$LOGON_KEY_32_OK
+:32+:logon:$LOGON_KEY_32_OK
+:30+2:logon:$LOGON_KEY_32_OK
+:32+0:logon:$LOGON_KEY_32_OK
+:32: logon:$LOGON_KEY_32_OK
+:32:\ logon:$LOGON_KEY_32_OK
+:32:logonA:$LOGON_KEY_32_OK
+:32:logo:$LOGON_KEY_32_OK
+:32:llogon:$LOGON_KEY_32_OK
+:32xlogon:$LOGON_KEY_32_OK
+:32logon:$LOGON_KEY_32_OK
+:32:logonx$LOGON_KEY_32_OK
+:32:logon$LOGON_KEY_32_OK
+: 32:user:$USER_KEY_32_OK
+:\ 32:user:$USER_KEY_32_OK
+:+32:user:$USER_KEY_32_OK
+:-32:user:$USER_KEY_32_OK
+:32 :user:$USER_KEY_32_OK
+:32\ :user:$USER_KEY_32_OK
+:32_:user:$USER_KEY_32_OK
+:32+:user:$USER_KEY_32_OK
+:30+2:user:$USER_KEY_32_OK
+:32+0:user:$USER_KEY_32_OK
+:32: user:$USER_KEY_32_OK
+:32:\ user:$USER_KEY_32_OK
+:32:userA:$USER_KEY_32_OK
+:32:use:$USER_KEY_32_OK
+:32:uuser:$USER_KEY_32_OK
+:32xuser:$USER_KEY_32_OK
+:32user:$USER_KEY_32_OK
+:32:userx$USER_KEY_32_OK
+:32:user$USER_KEY_32_OK
+:32:userlogon:$USER_KEY_32_OK
+:32:userlogon:$LOGON_KEY_32_OK
+:32:logonuser:$USER_KEY_32_OK
+:32:logonuser:$LOGON_KEY_32_OK
+:32:logon:user:$USER_KEY_32_OK
+:32:logon:user:$LOGON_KEY_32_OK
+:32:user:logon:$USER_KEY_32_OK
+:32:user:logon:$LOGON_KEY_32_OK"
+
+# TODO: add tests with whitespace in key description (not possible with current libdevmapper)
+
+IFS="
+"
+
+for key in $BORKED_KEYS; do
+ dmsetup create $DEV_CRYPT --table "0 100 crypt $CIPHER $key 0 /dev/mapper/$DEV_ZERO 0" 2> /dev/null && fail "dm-crypt accepted seriously borked key string"
+done
+
+remove_mapping