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