mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
b09ba3318e
Test that encryption nonces are unique and random, where randomness is approximated as "incompressible by the xz program". This gets indirectly tested by generic/399, but there are some gaps. It's good to test for this directly too. This test runs and passes on ext4 and f2fs. It doesn't currently run on ubifs because _get_encryption_nonce() isn't implemented for ubifs yet. (At some point I'll probably switch _get_encryption_nonce() to use FS_IOC_GET_ENCRYPTION_NONCE, which was added in Linux 5.7. But for now I'd like to keep the tests using it runnable on older kernels too.) Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
119 lines
3.7 KiB
Bash
Executable File
119 lines
3.7 KiB
Bash
Executable File
#! /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.
|
|
#
|
|
seq=`basename $0`
|
|
seqres=$RESULT_DIR/$seq
|
|
echo "QA output created by $seq"
|
|
|
|
here=`pwd`
|
|
tmp=/tmp/$$
|
|
status=1 # failure is the default!
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
_cleanup()
|
|
{
|
|
cd /
|
|
rm -f $tmp.*
|
|
}
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/encrypt
|
|
|
|
# remove previous $seqres.full before test
|
|
rm -f $seqres.full
|
|
|
|
# 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
|