Makefile: Add security compiling option (RELRO, SC, and FORTIFY)
[platform/upstream/cryptsetup.git] / tests / verity-compat-test
1 #!/bin/bash
2
3 [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
4 VERITYSETUP=$CRYPTSETUP_PATH/veritysetup
5 VERITYSETUP_VALGRIND=../.libs/veritysetup
6 VERITYSETUP_LIB_VALGRIND=../.libs
7
8 DEV_NAME=verity3273
9 DEV_NAME2=verity3273x
10 DEV_OUT="$DEV_NAME.out"
11 IMG=verity-data
12 IMG_HASH=verity-hash
13 IMG_TMP=tst-dev
14 FEC_DEV=tst_fec123
15 # If we need deterministic image creation
16 DEV_SALT=9e7457222290f1bac0d42ad2de2d602a87bb871c22ab70ca040bad450578a436
17 DEV_UUID=a60c98d2-ae9b-4865-bfcb-b4e3ace11033
18
19 function remove_mapping()
20 {
21         [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 >/dev/null 2>&1
22         [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME >/dev/null 2>&1
23         [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
24         rm -f $IMG $IMG.roothash $IMG_HASH $DEV_OUT $FEC_DEV $IMG_TMP >/dev/null 2>&1
25         LOOPDEV1=""
26         LOOPDEV2=""
27 }
28
29 function fail()
30 {
31         [ -n "$1" ] && echo "$1"
32         echo "FAILED backtrace:"
33         while caller $frame; do ((frame++)); done
34         [ -f $DEV_OUT ] && cat $DEV_OUT
35         remove_mapping
36         exit 2
37 }
38
39 function skip()
40 {
41         [ -n "$1" ] && echo "$1"
42         exit 77
43 }
44
45 function prepare() # $1 dev1_siz [$2 dev2_size]
46 {
47         remove_mapping
48
49         dd if=/dev/zero of=$IMG bs=1k count=$1 >/dev/null 2>&1
50         LOOPDEV1=$(losetup -f 2>/dev/null)
51         [ -z "$LOOPDEV1" ] && fail "No free loop device"
52         losetup $LOOPDEV1 $IMG
53
54         [ -z "$2" ] && return
55         LOOPDEV2=$IMG_HASH
56 }
57
58 function wipe()
59 {
60         dd if=/dev/zero of=$LOOPDEV1 bs=256k >/dev/null 2>&1
61         rm -f $IMG_HASH $DEV_OUT >/dev/null 2>&1
62 }
63
64 function check_exists()
65 {
66         [ -b /dev/mapper/$DEV_NAME ] || fail
67 }
68
69 function check_version() # MAJ MIN
70 {
71         VER_STR=$(dmsetup targets | grep verity | cut -f 3 -dv)
72         [ -z "$VER_STR" ] && fail "Failed to parse dm-verity version."
73
74         VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
75         VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
76
77         test $VER_MAJ -gt $1 && return 0
78         test $VER_MIN -ge $2 && return 0
79         return 1
80 }
81
82 function compare_out() # $1 what, $2 expected
83 {
84         OPT=$(grep -v "^#" $DEV_OUT | grep -i "$1" | sed -e s/.*\:\ // )
85         [ -z "$OPT" ] && fail
86         [ $OPT != $2 ] && fail "$1 differs ($2)"
87 }
88
89 function check_root_hash_fail()
90 {
91         echo -n "Root hash check "
92         ROOT_HASH=$($VERITYSETUP format $IMG $IMG_HASH --fec-device $FEC_DEV --fec-roots 2 -h sha256 | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ")
93         ROOT_HASH_BAD=abcdef0000000000000000000000000000000000000000000000000000000000
94
95         $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH || fail
96         $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH_BAD >/dev/null 2>&1 && fail
97         $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH_BAD --fec-device $FEC_DEV --fec-roots 2 >/dev/null 2>&1 && fail
98
99         $VERITYSETUP open $IMG $DEV_NAME $IMG_HASH $ROOT_HASH || fail
100         check_exists
101         dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=4096 count=1 >/dev/null 2>&1
102         dmsetup status $DEV_NAME | grep "verity V" >/dev/null || fail
103         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
104
105         $VERITYSETUP open $IMG $DEV_NAME $IMG_HASH $ROOT_HASH_BAD >/dev/null 2>&1 || fail
106         check_exists
107         dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=4096 count=1 >/dev/null 2>&1
108         dmsetup status $DEV_NAME | grep "verity C" >/dev/null || fail
109         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
110
111         echo "[OK]"
112 }
113
114 function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 offset]
115 {
116         local FORMAT_PARAMS
117         local VERIFY_PARAMS
118         local ROOT_HASH
119
120         if [ -z "$LOOPDEV2" ] ; then
121                 BLOCKS=$(($6 / $1))
122                 DEV_PARAMS="$LOOPDEV1 $LOOPDEV1 \
123                            --hash-offset $6 \
124                            --data-blocks=$BLOCKS --debug"
125         else
126                 DEV_PARAMS="$LOOPDEV1 $LOOPDEV2"
127         fi
128
129         for root_hash_as_file in yes no; do
130         for sb in yes no; do
131         FORMAT_PARAMS="--format=$4 --data-block-size=$1 --hash-block-size=$1 --hash=$5 --salt=$3"
132         if [ $sb == yes ] ; then
133                 VERIFY_PARAMS=""
134         else
135                 FORMAT_PARAMS="$FORMAT_PARAMS --no-superblock"
136                 VERIFY_PARAMS=$FORMAT_PARAMS
137         fi
138         if [ $root_hash_as_file == yes ] ; then
139                 echo -n $2 > $IMG.roothash
140                 FORMAT_PARAMS="$FORMAT_PARAMS --root-hash-file=$IMG.roothash"
141                 VERIFY_PARAMS="$VERIFY_PARAMS --root-hash-file=$IMG.roothash"
142                 ROOT_HASH=""
143         else
144                 ROOT_HASH="$2"
145         fi
146
147         for fail in data hash; do
148         wipe
149         echo -n "V$4(sb=$sb root_hash_as_file=$root_hash_as_file) $5 block size $1: "
150         $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >$DEV_OUT
151         if [ $? -ne 0 ] ; then
152                 if [[ $1 =~ "sha2" ]] ; then
153                         fail "Cannot format device."
154                 fi
155                 return
156         fi
157
158         echo -n "[root hash]"
159         compare_out "root hash" $2
160         compare_out "salt" "$3"
161
162         $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || fail
163         echo -n "[verify]"
164
165         $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH  >>$DEV_OUT 2>&1 || fail
166         check_exists
167         echo -n "[activate]"
168
169         dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=$1 2>/dev/null
170         dmsetup status $DEV_NAME | grep "verity V" >/dev/null || fail
171         echo -n "[in-kernel verify]"
172
173         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
174
175         case $fail in
176         data)
177                 dd if=/dev/urandom of=$LOOPDEV1 bs=1 seek=3456 count=8 conv=notrunc 2>/dev/null
178                 TXT="data_dev"
179                 ;;
180         hash)
181                 if [ -z "$LOOPDEV2" ] ; then
182                         dd if=/dev/urandom of=$LOOPDEV1 bs=1 seek=$((8193 + $4)) count=8 conv=notrunc 2>/dev/null
183                 else
184                         dd if=/dev/urandom of=$LOOPDEV2 bs=1 seek=8193 count=8 conv=notrunc 2>/dev/null
185                 fi
186                 TXT="hash_dev"
187                 ;;
188         esac
189
190         $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 && \
191                 fail "userspace check for $TXT corruption"
192         $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || \
193                 fail "activation"
194         dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=$1 2>/dev/null
195         dmsetup status $DEV_NAME | grep "verity V" >/dev/null && \
196                 fail "in-kernel check for $TXT corruption"
197         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail "deactivation"
198         echo "[$TXT corruption]"
199         done
200         done
201         done
202 }
203
204 function corrupt_device() # $1 device, $2 device_size(in bytes), $3 #{corrupted_bytes}
205 {
206         # Repeatable magic corruption :-)
207         CORRUPT=$3
208         RANDOM=43
209         while [ "$CORRUPT" -gt 0 ]; do
210                 SEEK=$RANDOM
211                 while [ $SEEK -ge $2 ] ; do SEEK=$RANDOM; done
212                 echo -n -e "\x55" | dd of=$1 bs=1 count=1 seek=$SEEK conv=notrunc > /dev/null 2>&1
213                 CORRUPT=$(($CORRUPT - 1))
214         done
215 }
216
217 # $1 data_device, $2 hash_device, $3 fec_device, $4 data/hash_block_size(in bytes),
218 # $5 data_size(in blocks), $6 device_size(in blocks), $7 hash_offset(in bytes),
219 # $8 fec_offset(in bytes), $9 fec_roots, ${10} corrupted_bytes, [${11} superblock(y/n), ${12} salt]
220 function check_fec()
221 {
222         INDEX=25
223         dd if=/dev/zero of=$1 bs=$4 count=$6 > /dev/null 2>&1
224
225         echo -n "Block_size: $4, Data_size: $(($4 * $5))B, FEC_roots: $9, Corrupted_bytes: ${10} "
226
227         PARAMS=" --data-block-size=$4 --hash-block-size=$4 "
228         if [ "$5" -ne "$6" ]; then
229                 PARAMS="$PARAMS --data-blocks=$5"
230         fi
231
232         if [ "$7" -ne 0 ]; then
233                 PARAMS="$PARAMS --hash-offset=$7"
234         fi
235
236         if [ "$8" -ne 0 ]; then
237                 PARAMS="$PARAMS --fec-offset=$8"
238         fi
239
240         if [ "${11}" == "n" ]; then
241                 INDEX=24
242                 echo -n "[no-superblock]"
243                 PARAMS="$PARAMS --no-superblock --salt=${12}"
244         elif [ -n "${12}" ]; then
245                 PARAMS="$PARAMS --salt=${12}"
246         fi
247
248         if [[ "$1" == "$2" && "$1" == "$3" ]]; then
249                 echo -n "[one_device_test]"
250                 dd if=/dev/zero of=$IMG_TMP bs=$4 count=$5  > /dev/null 2>&1
251                 HASH_ORIG=$(sha256sum $IMG_TMP | cut -d' ' -f 1)
252         else
253                 HASH_ORIG=$(sha256sum $1 | cut -d' ' -f 1)
254         fi
255
256         ROOT_HASH=$($VERITYSETUP format $1 $2 --fec-device=$3 $PARAMS | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ")
257
258         corrupt_device $1 $(($5 * $4)) ${10}
259
260         $VERITYSETUP create $DEV_NAME $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS > /dev/null 2>&1
261         if [ "$?" -ne "0" ] ; then
262                 echo "[N/A, test skipped]"
263                 return 3
264         fi
265
266         udevadm settle > /dev/null 2>&1
267
268         dd if=/dev/mapper/$DEV_NAME of=$IMG_TMP > /dev/null 2>&1
269         HASH_REPAIRED=$(sha256sum $IMG_TMP | cut -d' ' -f 1)
270
271         $VERITYSETUP close $DEV_NAME
272
273         if [ "$HASH_ORIG" != "$HASH_REPAIRED" ]; then
274                 echo -n "[kernel correction failed]"
275                 $VERITYSETUP verify $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS >/dev/null 2>&1 && fail "Userspace verify should fail"
276                 echo -n "[userspace verify failed]"
277                 RET=1
278         else
279                 echo -n "[repaired in kernel]"
280                 $VERITYSETUP verify $1 $2 $ROOT_HASH --fec-device=$3 $PARAMS >/dev/null 2>&1 || fail "Userspace verify failed"
281                 echo "[userspace verify][OK]"
282                 RET=0
283         fi
284         rm $1 $2 $3 $IMG_TMP > /dev/null 2>&1
285         return $RET
286 }
287
288 function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI option, $7 status option
289 {
290         DEV_PARAMS="$LOOPDEV1 $LOOPDEV2"
291         FORMAT_PARAMS="--format=$4 --data-block-size=$1 --hash-block-size=$1 --hash=$5 --salt=$3"
292
293         echo -n "Option $6 "
294         $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >/dev/null 2>&1 || fail
295         $VERITYSETUP create $DEV_NAME $DEV_PARAMS $2 $6 >/dev/null 2>&1 || fail
296         check_exists
297         $VERITYSETUP status $DEV_NAME 2>/dev/null | grep flags | grep -q $7 || fail
298         dmsetup table $DEV_NAME 2>/dev/null | grep -q $7 || fail
299         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
300         echo "[OK]"
301 }
302
303 function valgrind_setup()
304 {
305         command -v valgrind >/dev/null || fail "Cannot find valgrind."
306         [ ! -f $VERITYSETUP_VALGRIND ] && fail "Unable to get location of veritysetup executable."
307         export LD_LIBRARY_PATH="$VERITYSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
308 }
309
310 function valgrind_run()
311 {
312         INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${VERITYSETUP_VALGRIND} "$@"
313 }
314
315 function checkOffsetBug() # $1 size, $2 hash-offset, $3 data-blocks
316 {
317         echo -n "Size :: $1 B | Hash-offset :: $2 blocks | Data-blocks :: $3 "
318         dd if=/dev/zero of=$IMG bs=1 count=0 seek=$1 >/dev/null 2>&1
319         $VERITYSETUP --data-blocks=$3 --hash-offset=$2 format $IMG $IMG >/dev/null 2>&1 || fail "Test [hash-offset greater than 2G] failed"
320         echo "[OK]"
321         remove_mapping
322 }
323
324 function checkOverlapBug() # $1 size, $2 hash-offset, $3 data-blocks, $4 block_size, $5 fec_offset
325 {
326         echo -n "Device-size :: $1 B | "
327         [ $# -ge 3 ] && echo -n "Data-blocks :: $3 blocks| "
328         [ $# -lt 3 ] && echo -n "Data-blocks :: whole device | "
329         [ $# -ge 4 ] && echo -n "Block-size :: $4 B | "
330         [ $# -lt 4 ] && echo -n "Block-size :: 4096 B | "
331         echo -n "Hash-offset :: $2 B | "
332
333         dd if=/dev/zero of=$IMG bs=1 count=0 seek=$1 >/dev/null 2>&1
334         if [ -z $3 ] ; then
335                 # veritysetup must fail
336                 $VERITYSETUP --hash-offset=$2 format $IMG $IMG >/dev/null 2>&1 && fail "Test [overlap with option \"--data-blocks\" not entered] failed"
337         else
338                 $VERITYSETUP --data-block-size=$4 --hash-block-size=$4 --data-blocks=$3 --hash-offset=$2 format $IMG $IMG >/dev/null 2>&1
339                 RET=$?
340                 [ "$3" -gt "$(($2 / $4))" ] && [ "$RET" -eq "0" ] && fail "Test [overlap - hash-offset in data area] failed"
341         fi
342
343         if [ $# -eq 5 ] ; then
344                 echo -n "FEC-offset :: $5 B | "
345                 PARAMS="--data-block-size=$4 --hash-block-size=$4 --data-blocks=$3 --fec-device=$IMG --fec-offset=$5"
346
347                 # test data-fec area overlap
348                 $VERITYSETUP format $IMG $IMG_HASH $PARAMS >/dev/null 2>&1
349                 RET=$?
350                 [ "$(($3*$4))" -gt "$5" ] && [ "$RET" -eq "0" ] && fail "Test [data/fec area overlap] failed"
351
352                 HASH_SIZE=$(stat --printf="%s" $IMG_HASH)
353
354                 # test hash-fec area overlap
355                 $VERITYSETUP format $IMG $IMG $PARAMS --hash-offset=$2 >/dev/null 2>&1
356                 RET=$?
357                 [ "$(($2 + $HASH_SIZE))" -gt "$5" ] && [ "$RET" -eq "0" ] && fail "Test [hash/fec area overlap] failed"
358         fi
359
360         echo "[OK]"
361         remove_mapping
362 }
363
364 # $1 size, $2 block size, $3 roots, $4 hash offset, $5 fec offset,
365 # $6 one dev(1 - one device, 2 - one device for data and hash, one device for fec data, 3 - three separate devices),
366 # $7 #{corrupted bytes}
367 function checkUserSpaceRepair()
368 {
369         BS=512
370         COUNT=50000
371         dd if=/dev/zero of=$IMG bs=$BS count=$COUNT >/dev/null 2>&1
372         PARAMS="--data-block-size=$2 --hash-block-size=$2 --fec-roots=$3"
373         [ "$1" -gt 0 ] && PARAMS="$PARAMS --data-blocks=$1" && BS=$2 && COUNT=$1
374
375         # different parameters for different number of devices
376         [ "$6" -eq 1 ] && HASH_DEV=$IMG && FEC=$IMG && PARAMS="$PARAMS --hash-offset=$4 --fec-offset=$5" && echo -n "[One device]"
377         [ "$6" -eq 2 ] && HASH_DEV=$IMG && FEC=$FEC_DEV && PARAMS="$PARAMS --hash-offset=$4" && echo -n "[Two separate data/hash and fec devices]"
378         [ "$6" -eq 3 ] && HASH_DEV=$IMG_HASH && FEC=$FEC_DEV && echo -n "[Three separate devices]"
379
380         echo -n "[nroots::$3]"
381
382         ROOT_HASH=$($VERITYSETUP format $IMG $HASH_DEV --fec-device $FEC $PARAMS --salt=$DEV_SALT --uuid=$DEV_UUID | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ")
383
384         echo -n "[Errors can be corrected]"
385         corrupt_device $IMG $(($BS*$COUNT)) $7
386         $VERITYSETUP verify $IMG $HASH_DEV $ROOT_HASH --fec-device=$FEC $PARAMS >/dev/null 2>&1
387         RET=$?
388         [ "$RET" -ne 0 ] && fail "Device can be corrected, but it wasn't."
389         echo -n "[OK]"
390
391         echo -n "[Errors cannot be corrected]"
392         dd if=/dev/urandom of=$IMG bs=$BS count=$COUNT conv=notrunc >/dev/null 2>&1
393         $VERITYSETUP verify $IMG $HASH_DEV $ROOT_HASH --fec-device=$FEC $PARAMS >/dev/null 2>&1
394         RET=$?
395         [ "$RET" -eq 0 ] && fail "Device cannot be correct, but it didn't fail."
396         echo "[OK]"
397 }
398
399 function check_concurrent() # $1 hash
400 {
401         DEV_PARAMS="$LOOPDEV1 $LOOPDEV2"
402
403         # First check that with two sequential opens, we are returning the expected -EEXIST
404         $VERITYSETUP format $DEV_PARAMS >/dev/null 2>&1 || fail
405         $VERITYSETUP create $DEV_NAME $DEV_PARAMS $1 >/dev/null 2>&1 || fail
406         check_exists
407         $VERITYSETUP create $DEV_NAME $DEV_PARAMS $1 2>&1 >/dev/null | grep -q "Device $DEV_NAME already exists" || fail
408         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
409
410         # Then do two concurrent opens, and check that libdevmapper did not return -EINVAL, which is
411         # not gracefully recoverable. Either could fail depending on scheduling, so just check that
412         # the libdevmapper error does not appear in either of the outputs.
413         cat /dev/null >$DEV_OUT
414         $VERITYSETUP create -v $DEV_NAME $DEV_PARAMS $1 >>$DEV_OUT 2>&1 &
415         $VERITYSETUP create -v $DEV_NAME $DEV_PARAMS $1 >>$DEV_OUT 2>&1 &
416         wait
417         grep -q "Command failed with code .* (wrong or missing parameters)" $DEV_OUT && fail
418         check_exists
419         rm $DEV_OUT
420         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail
421
422         echo "[OK]"
423 }
424
425 export LANG=C
426 [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
427 [ ! -x "$VERITYSETUP" ] && skip "Cannot find $VERITYSETUP, test skipped."
428
429 [ -n "$VALG" ] && valgrind_setup && VERITYSETUP=valgrind_run
430 modprobe dm-verity >/dev/null 2>&1
431 dmsetup targets | grep verity >/dev/null 2>&1 || skip "Cannot find dm-verity target, test skipped."
432
433 # VERITYSETUP tests
434
435 SALT=e48da609055204e89ae53b655ca2216dd983cf3cb829f34f63a297d106d53e2d
436
437 echo "Verity tests [separate devices]"
438 prepare 8192 1024
439 check_root_hash_fail
440
441 check_root_hash  512 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 $SALT 1 sha256
442 check_root_hash 1024 54d92778750495d1f80832b486ebd007617d746271511bbf0e295e143da2b3df $SALT 1 sha256
443 check_root_hash 4096 e522df0f97da4febb882ac40f30b37dc0b444bf6df418929463fa25280f09d5c $SALT 1 sha256
444 # version 0
445 check_root_hash 4096 cbbf4ebd004ef65e29b935bb635a39cf754d677f3fa10b0126da725bbdf10f7d $SALT 0 sha256
446 # no salt
447 check_root_hash 4096 ef29c902d87350f1da4bfa536e16cebc162a909bf89abe448b81ec500d4fb9bf - 1 sha256
448 # sha1
449 check_root_hash 1024 d0e9163ca8844aaa2e88fe5265a8c5d9ee494a99 $SALT 1 sha1
450 check_root_hash 1024 73509e8e868be6b8ac939817a98a3d35121413b2 dadada 1 sha1
451
452 echo "Verity tests [one device offset]"
453 prepare $((8192 + 1024))
454 check_root_hash  512 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 $SALT 1 sha256 8388608
455 check_root_hash 1024 54d92778750495d1f80832b486ebd007617d746271511bbf0e295e143da2b3df $SALT 1 sha256 8388608
456 check_root_hash 4096 e522df0f97da4febb882ac40f30b37dc0b444bf6df418929463fa25280f09d5c $SALT 1 sha256 8388608
457 # version 0
458 check_root_hash 4096 cbbf4ebd004ef65e29b935bb635a39cf754d677f3fa10b0126da725bbdf10f7d $SALT 0 sha256 8388608
459 # no salt
460 check_root_hash 4096 ef29c902d87350f1da4bfa536e16cebc162a909bf89abe448b81ec500d4fb9bf - 1 sha256 8388608
461 # sha1
462 check_root_hash 1024 d0e9163ca8844aaa2e88fe5265a8c5d9ee494a99 $SALT 1 sha1 8388608
463 check_root_hash 1024 73509e8e868be6b8ac939817a98a3d35121413b2 dadada 1 sha1 8388608
464
465 if check_version 1 3; then
466         echo "Verity data corruption options test."
467         SALT=e48da609055204e89ae53b655ca2216dd983cf3cb829f34f63a297d106d53e2d
468         HASH=9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174
469         prepare 8192 1024
470         check_option 512 $HASH $SALT 1 sha256 "--ignore-corruption" "ignore_corruption"
471         check_option 512 $HASH $SALT 1 sha256 "--restart-on-corruption" "restart_on_corruption"
472         check_option 512 $HASH $SALT 1 sha256 "--ignore-zero-blocks" "ignore_zero_blocks"
473         check_option 512 $HASH $SALT 1 sha256 "--ignore-corruption --ignore-zero-blocks" "ignore_corruption"
474         if check_version 1 4; then
475                 check_option 512 $HASH $SALT 1 sha256 "--check-at-most-once" "check_at_most_once"
476         fi
477         if check_version 1 7; then
478                 check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption"
479         fi
480
481         if check_version 1 9; then
482                 echo "Verity data performance options test."
483                 check_option 512 $HASH $SALT 1 sha256 "--use-tasklets" "try_verify_in_tasklet"
484         fi
485 fi
486
487 echo "Veritysetup [hash-offset bigger than 2G works] "
488 checkOffsetBug 3000000000 2499997696 256
489 checkOffsetBug 10000000000 8000000000 128
490
491 echo "Veritysetup [overlap-detection] "
492 checkOverlapBug 2097152 1433600
493 checkOverlapBug 2097152 1433600 350 4096
494 checkOverlapBug 2097152 1228800 350 4096 # data-hash overlap
495 checkOverlapBug 2097152 0 350 4096 1228800 # data-fec overlap
496 checkOverlapBug 10240000 256000 400 512 256512 # hash-fec overlap
497
498 if check_version 1 3; then
499         echo "Veritysetup [FEC tests]"
500         for INDEX in  {1..4}; do
501           # in the first iteration check if we can use FEC (it can be compiled-out)
502           (check_fec $IMG $IMG $IMG 4096 30 150 163840 409600 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) )
503           RET=$?
504           [ "$RET" -eq "3" ] && break
505           [ "$RET" -eq "0" ] || fail "FEC repair failed"
506
507           (check_fec $IMG $IMG $IMG 512  500 50000 2457600 4915200 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'n' $SALT) || fail "FEC repair failed"
508           (check_fec $IMG $IMG $IMG 512  500 50000 2457600 4915200 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'y' $SALT) || fail "FEC repair failed"
509           (check_fec $IMG $IMG $IMG 4096  64 6250  4194304 8388608 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'n' $SALT) || fail "FEC repair failed"
510           (check_fec $IMG $IMG $IMG 4096  64 6250  4194304 8388608 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'y' $SALT) || fail "FEC repair failed"
511
512           (check_fec $IMG $IMG_HASH $FEC_DEV 4096 30 30 0 0 $(($RANDOM % 23 + 2)) $(($INDEX * 4)) 'n' $SALT) || fail "FEC repair failed"
513           (check_fec $IMG $IMG_HASH $FEC_DEV 4096 35 35 0 0 $(($RANDOM % 23 + 2)) $(($INDEX * 4))) || fail "FEC repair failed"
514           (check_fec $IMG $IMG_HASH $FEC_DEV 512 2000 2000 0 0 $(($RANDOM % 23 + 2)) $(($INDEX * 4))) || fail "FEC repair failed"
515           (check_fec $IMG $IMG_HASH $FEC_DEV 1024 2000 2000 0 0 $(($RANDOM % 23 + 2)) $(($INDEX * 4))) || fail "FEC repair failed"
516           # this test should fail
517           (check_fec $IMG $IMG_HASH $FEC_DEV 4096 30 30 0 0 $(($RANDOM % 23 + 2)) $(($RANDOM % 200 + 200))) && fail "FEC repair must fail"
518           echo "[OK]"
519         done
520 fi
521
522 echo "Correction in userspace: "
523 # checkUserSpaceRepair <#blocks> <block_size> <roots> <hash_offset> <fec_offset> <#devices> <#corrupted bytes>
524 checkUserSpaceRepair -1  512  2 0       0       3 100
525 checkUserSpaceRepair 400 512  2 256000  0       2 50
526 checkUserSpaceRepair 500 512  2 2457600  4915200  1 1
527 checkUserSpaceRepair -1  4096 2 0       0       3 10
528 checkUserSpaceRepair 400 4096 2 2048000 0       2 1
529 checkUserSpaceRepair 500 4096 2 2457600 4915200 1 2
530
531 echo -n "Verity concurrent opening tests:"
532 prepare 8192 1024
533 check_concurrent 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174
534
535 echo -n "Deferred removal of device:"
536 prepare 8192 1024
537 $VERITYSETUP format $LOOPDEV1 $IMG_HASH --format=1 --data-block-size=512 --hash-block-size=512 --hash=sha256 --salt=$SALT >/dev/null 2>&1 || fail "Cannot format device."
538 $VERITYSETUP open $LOOPDEV1 $DEV_NAME $DEV $IMG_HASH 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 || fail "Cannot activate device."
539 dmsetup create $DEV_NAME2 --table "0 8 linear /dev/mapper/$DEV_NAME 0"
540 [ ! -b /dev/mapper/$DEV_NAME2 ] && fail
541 $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 && fail
542 $VERITYSETUP status $DEV_NAME >/dev/null 2>&1 || fail
543 $VERITYSETUP close --deferred $DEV_NAME >/dev/null 2>&1
544 if [ $? -eq 0 ] ; then
545         dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" || fail
546         $VERITYSETUP close --cancel-deferred $DEV_NAME >/dev/null 2>&1
547         dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" >/dev/null 2>&1 && fail
548         $VERITYSETUP close --deferred $DEV_NAME >/dev/null 2>&1
549         dmsetup remove $DEV_NAME2 || fail
550         $VERITYSETUP status $DEV_NAME >/dev/null 2>&1 && fail
551         echo "[OK]"
552 else
553         dmsetup remove $DEV_NAME2 >/dev/null 2>&1
554         $VERITYSETUP close $DEV_NAME >/dev/null 2>&1
555         echo "[N/A]"
556 fi
557
558 remove_mapping
559 exit 0