1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 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"
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
}
skip()
{
[ -n "$1" ] && echo "$1"
remove_mapping
exit 77
}
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
load_key()
{
keyctl add $@ >/dev/null
}
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 ]
}
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."
command -v dmsetup >/dev/null || skip "Cannot find dmsetup, test skipped"
command -v keyctl >/dev/null || skip "Cannot find keyctl, 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
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
|