generic: test for creating duplicate filenames in encrypted dir
[xfstests-dev.git] / tests / generic / 613
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright 2020 Google LLC
4 #
5 # FS QA Test No. 613
6 #
7 # Test that encryption nonces are unique and random, where randomness is
8 # approximated as "incompressible by the xz program".
9 #
10 # An encryption nonce is the 16-byte value that the filesystem generates for
11 # each encrypted file.  These nonces must be unique in order to cause different
12 # files to be encrypted differently, which is an important security property.
13 # In practice, they need to be random to achieve that; and it's easy enough to
14 # test for both uniqueness and randomness, so we test for both.
15 #
16 seq=`basename $0`
17 seqres=$RESULT_DIR/$seq
18 echo "QA output created by $seq"
19
20 here=`pwd`
21 tmp=/tmp/$$
22 status=1        # failure is the default!
23 trap "_cleanup; exit \$status" 0 1 2 3 15
24
25 _cleanup()
26 {
27         cd /
28         rm -f $tmp.*
29 }
30
31 # get standard environment, filters and checks
32 . ./common/rc
33 . ./common/filter
34 . ./common/encrypt
35
36 # remove previous $seqres.full before test
37 rm -f $seqres.full
38
39 # real QA test starts here
40 _supported_fs generic
41 _require_scratch_encryption -v 2
42 _require_get_encryption_nonce_support
43 _require_command "$XZ_PROG" xz
44
45 _scratch_mkfs_encrypted &>> $seqres.full
46 _scratch_mount
47
48 echo -e "\n# Adding encryption keys"
49 _add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
50 _add_enckey $SCRATCH_MNT "$TEST_RAW_KEY" -d $TEST_KEY_DESCRIPTOR
51
52 # Create a bunch of encrypted files and directories -- enough for the uniqueness
53 # and randomness tests to be meaningful, but not so many that this test takes a
54 # long time.  Test using both v1 and v2 encryption policies, and for each of
55 # those test the case of an encryption policy that is assigned to an empty
56 # directory as well as the case of a file created in an encrypted directory.
57 echo -e "\n# Creating encrypted files and directories"
58 inodes=()
59 for i in {1..50}; do
60         dir=$SCRATCH_MNT/v1_policy_dir_$i
61         mkdir $dir
62         inodes+=("$(stat -c %i $dir)")
63         _set_encpolicy $dir $TEST_KEY_DESCRIPTOR
64
65         dir=$SCRATCH_MNT/v2_policy_dir_$i
66         mkdir $dir
67         inodes+=("$(stat -c %i $dir)")
68         _set_encpolicy $dir $TEST_KEY_IDENTIFIER
69 done
70 for i in {1..50}; do
71         file=$SCRATCH_MNT/v1_policy_dir_1/$i
72         touch $file
73         inodes+=("$(stat -c %i $file)")
74
75         file=$SCRATCH_MNT/v2_policy_dir_1/$i
76         touch $file
77         inodes+=("$(stat -c %i $file)")
78 done
79 _scratch_unmount
80
81 # Build files that contain all the nonces.  nonces_hex contains them in hex, one
82 # per line.  nonces_bin contains them in binary, all concatenated.
83 echo -e "\n# Getting encryption nonces from inodes"
84 echo -n > $tmp.nonces_hex
85 echo -n > $tmp.nonces_bin
86 for inode in "${inodes[@]}"; do
87         nonce=$(_get_encryption_nonce $SCRATCH_DEV $inode)
88         if (( ${#nonce} != 32 )) || [ -n "$(echo "$nonce" | tr -d 0-9a-fA-F)" ]
89         then
90                 _fail "Expected nonce to be 16 bytes (32 hex characters), but got \"$nonce\""
91         fi
92         echo $nonce >> $tmp.nonces_hex
93         echo -ne "$(echo $nonce | sed 's/[0-9a-fA-F]\{2\}/\\x\0/g')" \
94                 >> $tmp.nonces_bin
95 done
96
97 # Verify the uniqueness and randomness of the nonces.  In theory randomness
98 # implies uniqueness here, but it's easy enough to explicitly test for both.
99
100 echo -e "\n# Verifying uniqueness of nonces"
101 echo "Listing non-unique nonces:"
102 sort < $tmp.nonces_hex | uniq -d
103
104 echo -e "\n# Verifying randomness of nonces"
105 uncompressed_size=$(stat -c %s $tmp.nonces_bin)
106 echo "Uncompressed size is $uncompressed_size bytes"
107 compressed_size=$($XZ_PROG -c < $tmp.nonces_bin | wc -c)
108 echo "Compressed size is $compressed_size bytes" >> $seqres.full
109 # The xz format has 60 bytes of overhead.  Go a bit lower to avoid flakiness.
110 if (( compressed_size >= uncompressed_size + 55 )); then
111         echo "Nonces are incompressible, as expected"
112 else
113         _fail "Nonces are compressible (non-random); compressed $uncompressed_size => $compressed_size bytes!"
114 fi
115
116 # success, all done
117 status=0
118 exit