Merge branch 'upstream' into tizen
[platform/upstream/cryptsetup.git] / tests / device-test
1 #!/bin/bash
2
3 [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
4 CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
5 MNT_DIR="./mnt_luks"
6 DEV_NAME="dummy"
7 DEV_NAME2="ymmud"
8 PWD1="93R4P4pIqAH8"
9 PWD2="mymJeD8ivEhE"
10 FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
11 SKIP_COUNT=0
12
13 CRYPTSETUP_VALGRIND=../.libs/cryptsetup
14 CRYPTSETUP_LIB_VALGRIND=../.libs
15
16 cleanup() {
17         [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME
18         udevadm settle >/dev/null 2>&1
19         if [ -d "$MNT_DIR" ] ; then
20                 umount -f $MNT_DIR 2>/dev/null
21                 rmdir $MNT_DIR 2>/dev/null
22         fi
23         rmmod scsi_debug >/dev/null 2>&1
24 }
25
26 fail()
27 {
28         [ -n "$1" ] && echo "FAIL $1"
29         echo "FAILED backtrace:"
30         while caller $frame; do ((frame++)); done
31         cleanup
32         exit 100
33 }
34
35 skip()
36 {
37         echo "TEST SKIPPED: $1"
38         cleanup
39         exit 77
40 }
41
42 function valgrind_setup()
43 {
44         command -v valgrind >/dev/null || fail "Cannot find valgrind."
45         [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
46         export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
47 }
48
49 function valgrind_run()
50 {
51         INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@"
52 }
53
54 add_device() {
55         rmmod scsi_debug >/dev/null 2>&1
56         [ -d /sys/module/scsi_debug ] && skip "Cannot use scsi_debug module (in use or compiled-in)."
57
58         modprobe scsi_debug $@ delay=0 >/dev/null 2>&1
59         [ $? -ne 0 ] && skip "This kernel seems to not support proper scsi_debug module."
60
61         sleep 1
62         SCSI_DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
63
64         [ -b "/dev/$SCSI_DEV" ] || fail "Cannot find $SCSI_DEV."
65 }
66
67 add_image()
68 {
69         dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1
70 }
71
72 function dm_crypt_features()
73 {
74         modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load"
75         VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
76         [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
77
78         VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
79         VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
80         VER_PTC=$(echo $VER_STR | cut -f 3 -d.)
81
82         [ $VER_MAJ -lt 1 ] && return
83         [ $VER_MAJ -gt 1 ] && {
84                 DM_PERF_CPU=1
85                 DM_SECTOR_SIZE=1
86                 test -d /proc/sys/kernel/keys && DM_KEYRING=1
87                 return
88         }
89
90         [ $VER_MIN -lt 14 ] && return
91         DM_PERF_CPU=1
92         if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then
93                 DM_SECTOR_SIZE=1
94         fi
95         if [ $VER_MIN -gt 18 -o \( $VER_MIN -eq 18 -a $VER_PTC -ge 1 \) ]; then
96                  test -d /proc/sys/kernel/keys && DM_KEYRING=1
97         fi
98
99         [ $VER_MIN -lt 22 ] && return
100         DM_PERF_NO_WORKQUEUE=1
101 }
102
103 function dm_crypt_keyring_support()
104 {
105         VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
106         [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
107
108         VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
109         VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
110
111         # run the test with dm-crypt v1.15.0+ on purpose
112         # the fix is in dm-crypt v1.18.1+
113         [ $VER_MAJ -gt 1 ] && return 0
114         [ $VER_MAJ -lt 1 ] && return 1
115         [ $VER_MIN -ge 15 ]
116 }
117
118 format() # format
119 {
120         add_image
121
122         echo $PWD1 | $CRYPTSETUP luksFormat --type $1 $DEV -q  $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256
123         [ $? -ne 0 ] && fail "Format failed."
124
125         # test some operation, just in case
126         echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV -i1 --new-key-slot 1
127         [ $? -ne 0 ] && fail "Keyslot add failed."
128
129         $CRYPTSETUP -q luksKillSlot $DEV 1
130         [ $? -ne 0 ] && fail "Keyslot removal failed."
131 }
132
133 check_sector_size() # $1 expected sector size
134 {
135         $CRYPTSETUP status $DEV_NAME | grep "sector size" | grep -q $1 || fail
136         if [ $S -gt 512 ]; then
137                 dmsetup table $DEV_NAME | grep -q "sector_size:$1" || fail
138         fi
139 }
140
141 check_io()
142 {
143         dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M count=32 iflag=direct 2>/dev/null || fail
144         dd if=/dev/zero of=/dev/mapper/$DEV_NAME bs=1M count=32 oflag=direct 2>/dev/null || fail
145 }
146
147 [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
148 [ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run
149 if [ $(id -u) != 0 ]; then
150         skip "You must be root to run this test, test skipped."
151 fi
152
153 dm_crypt_features
154
155 [ ! -d $MNT_DIR ] && mkdir $MNT_DIR
156
157 echo "[1] Using tmpfs for image"
158 DEV="$MNT_DIR/test.img"
159 mount -t tmpfs none $MNT_DIR || skip "Mounting tmpfs not available."
160
161 add_image
162 echo "[2] Kernel dmcrypt performance options"
163 if [ -z "$DM_PERF_CPU" ]; then
164         echo "TEST SKIPPED: dmcrypt options not available"
165         SKIP_COUNT=$((SKIP_COUNT+1))
166 else
167         echo -n "PLAIN: same_cpu_crypt submit_from_cpus "
168         echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
169         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
170         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
171         check_io
172         $CRYPTSETUP close $DEV_NAME || fail
173         echo -n "allow_discards "
174         echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
175         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
176         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
177         check_io
178         $CRYPTSETUP close $DEV_NAME || fail
179         echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME || fail
180         echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
181         # Hash affects volume key for plain device. Check we can detect it
182         echo -e "$PWD1" | $CRYPTSETUP refresh -q $DEV_NAME --hash sha512 --perf-same_cpu_crypt --allow-discards 2>/dev/null && fail
183         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
184         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
185         echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME --allow-discards || fail
186         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
187         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
188         echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME || fail
189         $CRYPTSETUP status $DEV_NAME | grep -q discards && fail
190         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
191         echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 $DEV $DEV_NAME2 2>/dev/null && fail
192         if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then
193                 echo -n "no_read_workqueue no_write_workqueue"
194                 echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue || fail
195                 $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail
196                 $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
197                 check_io
198         fi
199         $CRYPTSETUP close $DEV_NAME || fail
200         echo
201
202         format luks1
203         echo -n "LUKS: same_cpu_crypt submit_from_cpus "
204         echo -e "$PWD1" | $CRYPTSETUP open --type luks1 $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
205         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
206         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
207         $CRYPTSETUP close $DEV_NAME || fail
208         echo -n "allow_discards "
209         echo -e "$PWD1" | $CRYPTSETUP open --type luks1 $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
210         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
211         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
212         $CRYPTSETUP close $DEV_NAME || fail
213         echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail
214         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME --allow-discards || fail
215         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
216         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
217         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME --allow-discards --perf-same_cpu_crypt || fail
218         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
219         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
220         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME || fail
221         $CRYPTSETUP status $DEV_NAME | grep -q discards && fail
222         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
223         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME2 2>/dev/null && fail
224         if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then
225                 echo -n "no_read_workqueue no_write_workqueue"
226                 echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME  --perf-no_read_workqueue --perf-no_write_workqueue || fail
227                 $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail
228                 $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
229         fi
230         $CRYPTSETUP close $DEV_NAME || fail
231         echo
232
233         format luks2
234         echo -n "LUKS2: same_cpu_crypt submit_from_cpus "
235         echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus --persistent || fail
236         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
237         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
238         $CRYPTSETUP close $DEV_NAME || fail
239         # Stored in metadata
240         echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail
241         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
242         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
243         $CRYPTSETUP close $DEV_NAME || fail
244         echo -n "allow_discards [persistent flags] "
245         echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards --persistent || fail
246         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
247         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
248         $CRYPTSETUP close $DEV_NAME || fail
249         echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail
250         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
251         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
252         $CRYPTSETUP close $DEV_NAME || fail
253
254         echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME --persistent || fail
255         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
256         $CRYPTSETUP status $DEV_NAME | grep -q discards && fail
257         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus --persistent || fail
258         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
259         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
260         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME || fail
261         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
262         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
263         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards --persistent || fail
264         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
265         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
266         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV_NAME || fail
267         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
268         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
269         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-submit_from_crypt_cpus || fail
270         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
271         $CRYPTSETUP status $DEV_NAME | grep -q discards || fail
272         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
273         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME || fail
274         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus && fail
275         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --persistent || fail
276         $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt && fail
277         $CRYPTSETUP status $DEV_NAME | grep -q discards && fail
278         $CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus && fail
279         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --disable-keyring || fail
280         $CRYPTSETUP status $DEV_NAME | grep -q keyring && fail
281         if [ -n "$DM_KEYRING" ]; then
282                 echo -n "keyring "
283                 echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME || fail
284                 $CRYPTSETUP status $DEV_NAME | grep -q keyring || fail
285         fi
286         if [ -n "$DM_PERF_NO_WORKQUEUE" ]; then
287                 echo -n "no_read_workqueue no_write_workqueue"
288                 echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME --perf-no_read_workqueue --perf-no_write_workqueue --persistent || fail
289                 $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail
290                 $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
291                 $CRYPTSETUP close $DEV_NAME || fail
292                 echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail
293                 $CRYPTSETUP status $DEV_NAME | grep -q no_read_workqueue || fail
294                 $CRYPTSETUP status $DEV_NAME | grep -q no_write_workqueue || fail
295         fi
296         echo -e "$PWD1" | $CRYPTSETUP refresh $DEV $DEV_NAME2 2>/dev/null && fail
297         $CRYPTSETUP close $DEV_NAME || fail
298         echo
299 fi
300
301 echo "[3] Kernel dmcrypt sector size options"
302 echo -e "$PWD1" | $CRYPTSETUP open --type plain --hash sha256 $DEV $DEV_NAME --sector-size 4096 >/dev/null 2>&1
303 ret=$?
304 [ -z "$DM_SECTOR_SIZE" -a $ret -eq 0 ] && fail "cryptsetup activated device with --sector-size option on incompatible kernel!"
305 if [ $ret -ne 0 ] ; then
306         SKIP_COUNT=$((SKIP_COUNT+1))
307         if [ $SKIP_COUNT -ge 2 ]; then
308                 skip "dmcrypt sector-size option not available"
309         fi
310         echo "TEST SKIPPED: dmcrypt sector-size option not available"
311 else
312         $CRYPTSETUP close $DEV_NAME || fail
313
314         echo -n "PLAIN sector size:"
315         echo -e "$PWD1" | $CRYPTSETUP open --type plain --hash sha256 $DEV $DEV_NAME --sector-size 1234 >/dev/null 2>&1 && fail
316         for S in 512 1024 2048 4096; do
317                 echo -n "[$S]"
318                 echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --sector-size $S || fail
319                 check_sector_size $S
320                 $CRYPTSETUP close $DEV_NAME || fail
321         done
322
323         echo -e "$PWD1" | $CRYPTSETUP open --type plain --hash sha256 $DEV $DEV_NAME --iv-large-sectors >/dev/null 2>&1 && fail
324         for S in 1024 2048 4096; do
325                 echo -n "[$S/IV]"
326                 echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --sector-size $S --iv-large-sectors || fail
327                 check_sector_size $S
328                 dmsetup table $DEV_NAME | grep -q "iv_large_sectors" || fail
329                 $CRYPTSETUP close $DEV_NAME || fail
330         done
331         echo
332
333         echo -n "LUKS2 sector size:"
334         echo -e "$PWD1" | $CRYPTSETUP luksFormat --type luks2 -$DEV --sector-size 1234 >/dev/null 2>&1 && fail
335         for S in 512 1024 2048 4096; do
336                 echo -n "[$S]"
337                 echo -e "$PWD1" | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force-iterations 1000 $DEV --sector-size $S || fail
338                 echo -e "$PWD1" | $CRYPTSETUP open $DEV $DEV_NAME || fail
339                 check_sector_size $S
340                 $CRYPTSETUP close $DEV_NAME || fail
341         done
342         echo
343 fi
344
345 echo "[4] Disappeared device test:"
346 KEY="00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
347 for F in LUKS1 LUKS2 BITLK TCRYPT; do
348         add_device dev_size_mb=1 sector_size=512 num_tgts=1 lbpu=1
349         echo -n "$F"
350         # Fake CRYPT UUID to force code to parse type-specific path
351         dmsetup create $DEV_NAME --uuid CRYPT-$F-$DEV_NAME --table "0 1024 crypt aes-xts-plain64 $KEY 16 /dev/$SCSI_DEV 16"
352         $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail
353         echo 1 > /sys/block/$SCSI_DEV/device/delete
354         udevadm settle >/dev/null 2>&1
355         $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail
356         dmsetup remove $DEV_NAME --retry || fail
357         rmmod scsi_debug >/dev/null 2>&1
358         echo -n "[OK] "
359 done
360 echo
361
362 cleanup
363 exit 0