diff mbox series

[11/12] fstests: split generic/613 into two tests

Message ID 227ac42377705dcd416558f8415965ecba3a17df.1696969376.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series fstests: fscrypt test updates | expand

Commit Message

Josef Bacik Oct. 10, 2023, 8:26 p.m. UTC
generic/613 tests v1 and v2 policies, but btrfs can only support v2
policies.  Split this into two different tests, 613 which will only test
v1 policies, and then 735 which will test v2 policies.

The 735 test will also add checks for the per-extent nonces to validate
they're all sufficiently random.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 tests/generic/613     |  20 ++------
 tests/generic/613.out |   5 +-
 tests/generic/735     | 117 ++++++++++++++++++++++++++++++++++++++++++
 tests/generic/735.out |  14 +++++
 4 files changed, 138 insertions(+), 18 deletions(-)
 create mode 100644 tests/generic/735
 create mode 100644 tests/generic/735.out
diff mbox series

Patch

diff --git a/tests/generic/613 b/tests/generic/613
index 47c60e9c..96b81a96 100755
--- a/tests/generic/613
+++ b/tests/generic/613
@@ -22,22 +22,21 @@  _begin_fstest auto quick encrypt
 
 # real QA test starts here
 _supported_fs generic
-_require_scratch_encryption -v 2
+_require_scratch_encryption
 _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"
+echo -e "\n# Adding encryption 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.
+# long time.  Test using the v1 encryption policy, 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
@@ -45,20 +44,11 @@  for i in {1..50}; do
 	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
 
diff --git a/tests/generic/613.out b/tests/generic/613.out
index 203a64f2..4a218d03 100644
--- a/tests/generic/613.out
+++ b/tests/generic/613.out
@@ -1,7 +1,6 @@ 
 QA output created by 613
 
-# Adding encryption keys
-Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Adding encryption key
 Added encryption key with descriptor 0000111122223333
 
 # Creating encrypted files and directories
@@ -12,5 +11,5 @@  Added encryption key with descriptor 0000111122223333
 Listing non-unique nonces:
 
 # Verifying randomness of nonces
-Uncompressed size is 3200 bytes
+Uncompressed size is 1600 bytes
 Nonces are incompressible, as expected
diff --git a/tests/generic/735 b/tests/generic/735
new file mode 100644
index 00000000..c901be1f
--- /dev/null
+++ b/tests/generic/735
@@ -0,0 +1,117 @@ 
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2023 Meta
+#
+# FS QA Test No. 735
+#
+# A variation of generic/613 that only tests v2, and checks data nonces for any
+# file system that supporst per-extent encryption.
+#
+# 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
+
+_check_nonce()
+{
+	local nonce=$1
+
+	if (( ${#nonce} != 32 )) || [ -n "$(echo "$nonce" | tr -d 0-9a-fA-F)" ]
+	then
+		_fail "Expected nonce for inode $inode to be 16 bytes (32 hex characters), but got \"$nonce\""
+	fi
+}
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+echo -e "\n# Adding encryption key"
+_add_enckey $SCRATCH_MNT "$TEST_RAW_KEY"
+
+# 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 the v2 encryption policy, 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/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/v2_policy_dir_1/$i
+	$XFS_IO_PROG -f -c "pwrite 0 1m" $file > /dev/null
+	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
+	inode_nonce=$(_get_encryption_file_nonce $SCRATCH_DEV $inode)
+	_check_nonce $inode_nonce
+	
+	echo $inode_nonce >> $tmp.nonces_hex
+	echo -ne "$(echo $inode_nonce | sed 's/[0-9a-fA-F]\{2\}/\\x\0/g')" \
+		>> $tmp.nonces_bin
+
+	data_nonce=$(_get_encryption_data_nonce $SCRATCH_DEV $inode)
+
+	# If the inode is empty we won't have a data nonce
+	[ "$data_nonce" = "" ] && continue
+
+	# If the inode nonce and data nonce are the same continue
+	[ "$inode_nonce" = "$data_nonce" ] && continue
+
+	_check_nonce $data_nonce
+	
+	echo $data_nonce >> $tmp.nonces_hex
+	echo -ne "$(echo $data_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" >> $seqres.full
+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
diff --git a/tests/generic/735.out b/tests/generic/735.out
new file mode 100644
index 00000000..bf73118b
--- /dev/null
+++ b/tests/generic/735.out
@@ -0,0 +1,14 @@ 
+QA output created by 735
+
+# Adding encryption key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+
+# Creating encrypted files and directories
+
+# Getting encryption nonces from inodes
+
+# Verifying uniqueness of nonces
+Listing non-unique nonces:
+
+# Verifying randomness of nonces
+Nonces are incompressible, as expected