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