ea88c21011aea82637fc53739e618f55cdcb05f4
[platform/upstream/cryptsetup.git] / tests / keyring-compat-test
1 #!/bin/bash
2
3 CIPHER_XTS_PLAIN="aes-xts-plain64"
4 CIPHER_CBC_ESSIV="aes-cbc-essiv:sha256"
5 CIPHER_CBC_TCW="serpent-cbc-tcw"
6 # TODO: mode with LMK
7
8 TEST_KEYRING_NAME="keyringtest_keyring"
9
10 LOGON_KEY_16_OK="dmtst:lkey_16"
11 LOGON_KEY_32_OK="dmtst:lkey_32"
12 LOGON_KEY_64_OK="dmtst:lkey_64"
13
14 HEXKEY_16="be21aa8c733229347bd4e681891e213d";
15 HEXKEY_32="bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
16 HEXKEY_64="34f95b96abff946b64f1339ff8653cc77c38697c93b797a496f3786e86eed7781850d5112bbae17d209b8310a8f3a034f1cd297667bc0cd1438fad28d87ef6a1"
17
18 DEVSIZEMB=16
19 DEVSECTORS=$((DEVSIZEMB*1024*1024/512))
20 NAME=testcryptdev
21 CHKS_DMCRYPT=vk_in_dmcrypt.chk
22 CHKS_KEYRING=vk_in_keyring.chk
23
24 PWD="aaablabl"
25
26 [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
27 CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
28
29 CRYPTSETUP_VALGRIND=../.libs/cryptsetup
30 CRYPTSETUP_LIB_VALGRIND=../.libs
31
32 FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null)
33
34 function remove_mapping()
35 {
36         [ -b /dev/mapper/$NAME ] && dmsetup remove --retry $NAME
37
38         # unlink whole test keyring
39         [ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
40
41         rmmod scsi_debug >/dev/null 2>&1
42
43         rm -f $CHKS_DMCRYPT $CHKS_KEYRING
44 }
45
46 function skip()
47 {
48         [ -n "$1" ] && echo "$1"
49         remove_mapping
50         exit 77
51 }
52
53 function valgrind_setup()
54 {
55         command -v valgrind >/dev/null || fail "Cannot find valgrind."
56         [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
57         export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
58 }
59
60 function valgrind_run()
61 {
62         INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@"
63 }
64
65 function fail()
66 {
67         [ -n "$1" ] && echo "$1"
68         echo "FAILED backtrace:"
69         while caller $frame; do ((frame++)); done
70         remove_mapping
71         exit 2
72 }
73
74 # $1 hexbyte key
75 # $2 type
76 # $3 description
77 # $4 keyring
78 function load_key()
79 {
80         local tmp="$1"
81         shift
82         echo -n "$tmp" | xxd -r -p | keyctl padd $@ >/dev/null
83 }
84
85 function dm_crypt_keyring_support()
86 {
87         VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
88         [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
89
90         VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
91         VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
92
93         # run the test with dm-crypt v1.15.0+ on purpose
94         # the fix is in dm-crypt v1.18.1+
95         [ $VER_MAJ -gt 1 ] && return 0
96         [ $VER_MAJ -lt 1 ] && return 1
97         [ $VER_MIN -ge 15 ]
98 }
99
100 function test_and_prepare_keyring() {
101         keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped"
102         TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null)
103         test -n "$TEST_KEYRING" || skip "Failed to create keyring in user keyring"
104         keyctl search "@s" keyring "$TEST_KEYRING" > /dev/null 2>&1 || keyctl link "@u" "@s" > /dev/null 2>&1
105         load_key "$HEXKEY_16" user test_key "$TEST_KEYRING" || skip "Kernel keyring service is useless on this system, test skipped."
106 }
107
108 function fips_mode()
109 {
110         [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ]
111 }
112
113 add_device() {
114         rmmod scsi_debug >/dev/null 2>&1
115         if [ -d /sys/module/scsi_debug ] ; then
116                 echo "Cannot use scsi_debug module (in use or compiled-in), test skipped."
117                 exit 77
118         fi
119
120         modprobe scsi_debug $@ delay=0 >/dev/null 2>&1
121         if [ $? -ne 0 ] ; then
122                 echo "This kernel seems to not support proper scsi_debug module, test skipped."
123                 exit 77
124         fi
125
126         sleep 2
127         DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
128
129         DEV="/dev/$DEV"
130         [ -b $DEV ] || fail "Cannot find $DEV."
131 }
132
133 [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
134 [ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run
135 [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
136 command -v dmsetup >/dev/null || skip "Cannot find dmsetup, test skipped"
137 command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped"
138 command -v xxd >/dev/null || skip "Cannot find xxd, test skipped"
139 command -v sha256sum >/dev/null || skip "Cannot find sha256sum, test skipped"
140 modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load"
141 dm_crypt_keyring_support || skip "dm-crypt doesn't support kernel keyring, test skipped."
142
143 test_and_prepare_keyring
144
145 add_device dev_size_mb=$DEVSIZEMB
146
147 dd if=/dev/urandom of=$DEV bs=1M count=$DEVSIZEMB oflag=direct > /dev/null 2>&1 || fail
148
149 #test aes cipher with xts mode, plain IV
150 echo -n "Testing $CIPHER_XTS_PLAIN..."
151 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail
152 sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
153 dmsetup remove --retry $NAME || fail
154 load_key "$HEXKEY_32" logon  $LOGON_KEY_32_OK "$TEST_KEYRING" || fail "Cannot load 32 byte logon key type"
155 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN :32:logon:$LOGON_KEY_32_OK 0 $DEV 0" || fail
156 sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
157 dmsetup remove --retry $NAME || fail
158 diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
159 # same test using message
160 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail
161 sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
162 dmsetup remove --retry $NAME || fail
163 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail
164 dmsetup suspend $NAME || fail
165 dmsetup message $NAME 0 key wipe || fail
166 dmsetup message $NAME 0 "key set :32:logon:$LOGON_KEY_32_OK" || fail
167 dmsetup resume $NAME || fail
168 sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
169 dmsetup remove --retry $NAME || fail
170 diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
171 echo "OK"
172
173 #test aes cipher, xts mode, essiv IV
174 echo -n "Testing $CIPHER_CBC_ESSIV..."
175 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail
176 sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
177 dmsetup remove --retry $NAME || fail
178 load_key "$HEXKEY_16" logon  $LOGON_KEY_16_OK "$TEST_KEYRING" || fail "Cannot load 16 byte logon key type"
179 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV :16:logon:$LOGON_KEY_16_OK 0 $DEV 0" || fail
180 sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
181 dmsetup remove --retry $NAME || fail
182 diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
183 # same test using message
184 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail
185 sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
186 dmsetup remove --retry $NAME || fail
187 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail
188 dmsetup suspend $NAME || fail
189 dmsetup message $NAME 0 key wipe || fail
190 dmsetup message $NAME 0 "key set :16:logon:$LOGON_KEY_16_OK" || fail
191 dmsetup resume $NAME || fail
192 sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
193 dmsetup remove --retry $NAME || fail
194 diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
195 echo "OK"
196
197 #test serpent cipher, cbc mode, tcw IV
198 fips_mode || {
199 echo -n "Testing $CIPHER_CBC_TCW..."
200 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail
201 sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
202 dmsetup remove --retry $NAME || fail
203 load_key "$HEXKEY_64" logon  $LOGON_KEY_64_OK "$TEST_KEYRING" || fail "Cannot load 16 byte logon key type"
204 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW :64:logon:$LOGON_KEY_64_OK 0 $DEV 0" || fail
205 sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
206 dmsetup remove --retry $NAME || fail
207 diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksum mismatch (corruption)"
208 # same test using message
209 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail
210 sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail
211 dmsetup remove --retry $NAME || fail
212 dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail
213 dmsetup suspend $NAME || fail
214 dmsetup message $NAME 0 key wipe || fail
215 dmsetup message $NAME 0 "key set :64:logon:$LOGON_KEY_64_OK" || fail
216 dmsetup resume $NAME || fail
217 sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail
218 dmsetup remove --retry $NAME || fail
219 diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)"
220 echo "OK"
221 }
222
223 echo -n "Test LUKS2 key refresh..."
224 echo $PWD | $CRYPTSETUP luksFormat --type luks2 --luks2-metadata-size 16k --luks2-keyslots-size 4064k --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --force-password $DEV || fail
225 echo $PWD | $CRYPTSETUP open $DEV $NAME || fail
226 $CRYPTSETUP status $NAME | grep -q -i "location:.*keyring" || skip "LUKS2 can't use keyring. Test skipped."
227 dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha256sum > $CHKS_KEYRING || fail
228 echo $PWD | $CRYPTSETUP refresh $NAME --disable-keyring || fail
229 $CRYPTSETUP status $NAME | grep -q -i "location:.*keyring" && fail "Key is still in keyring"
230 dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha256sum > $CHKS_DMCRYPT || fail
231 diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksum mismatch (corruption)"
232 echo "OK"
233
234 remove_mapping