linux-fscrypt.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements
@ 2019-08-12 17:58 Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 1/9] common/encrypt: disambiguate session encryption keys Eric Biggers
                   ` (9 more replies)
  0 siblings, 10 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

Hello,

This patchset adds xfstests for the kernel patchset
"[PATCH v8 00/20] fscrypt: key management improvements"
https://lkml.kernel.org/linux-fsdevel/20190805162521.90882-1-ebiggers@kernel.org/T/#u

These tests test the new ioctls for managing filesystem encryption keys,
and they test the new encryption policy version.

These tests depend on new xfs_io commands, for which I've sent a
separate patchset for xfsprogs.

Note: currently only ext4, f2fs, and ubifs support encryption.  But I
was told previously that since the fscrypt API is generic and may be
supported by XFS in the future, the command-line wrappers for the
fscrypt ioctls should be in xfs_io rather than in fstests directly
(https://marc.info/?l=fstests&m=147976255831951&w=2).

We'll want to wait for the kernel patches to be mainlined before merging
this, but I'm making it available now for any early feedback.

This version of the xfstests patchset can also be retrieved from tag
"fscrypt-key-mgmt-improvements_2019-08-12" of
https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/xfstests-dev.git

Eric Biggers (9):
  common/encrypt: disambiguate session encryption keys
  common/encrypt: add helper functions that wrap new xfs_io commands
  common/encrypt: support checking for v2 encryption policy support
  common/encrypt: support verifying ciphertext of v2 encryption policies
  generic: add basic test for fscrypt API additions
  generic: add test for non-root use of fscrypt API additions
  generic: verify ciphertext of v2 encryption policies with AES-256
  generic: verify ciphertext of v2 encryption policies with AES-128
  generic: verify ciphertext of v2 encryption policies with Adiantum

 common/encrypt           | 180 +++++++++++++++++++----
 src/fscrypt-crypt-util.c | 304 ++++++++++++++++++++++++++++++++++-----
 tests/ext4/024           |   2 +-
 tests/generic/397        |   4 +-
 tests/generic/398        |   8 +-
 tests/generic/399        |   4 +-
 tests/generic/419        |   4 +-
 tests/generic/421        |   4 +-
 tests/generic/429        |   8 +-
 tests/generic/435        |   4 +-
 tests/generic/440        |   8 +-
 tests/generic/800        | 127 ++++++++++++++++
 tests/generic/800.out    |  91 ++++++++++++
 tests/generic/801        | 136 ++++++++++++++++++
 tests/generic/801.out    |  62 ++++++++
 tests/generic/802        |  43 ++++++
 tests/generic/802.out    |   6 +
 tests/generic/803        |  43 ++++++
 tests/generic/803.out    |   6 +
 tests/generic/804        |  45 ++++++
 tests/generic/804.out    |  11 ++
 tests/generic/group      |   5 +
 22 files changed, 1018 insertions(+), 87 deletions(-)
 create mode 100755 tests/generic/800
 create mode 100644 tests/generic/800.out
 create mode 100755 tests/generic/801
 create mode 100644 tests/generic/801.out
 create mode 100755 tests/generic/802
 create mode 100644 tests/generic/802.out
 create mode 100755 tests/generic/803
 create mode 100644 tests/generic/803.out
 create mode 100755 tests/generic/804
 create mode 100644 tests/generic/804.out

-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 1/9] common/encrypt: disambiguate session encryption keys
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 2/9] common/encrypt: add helper functions that wrap new xfs_io commands Eric Biggers
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Rename the helper functions that add/remove keys from the session
keyring, in order to distinguish them from the helper functions I'll be
adding to add/remove keys from the new filesystem-level keyring.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 common/encrypt    | 20 ++++++++++----------
 tests/ext4/024    |  2 +-
 tests/generic/397 |  4 ++--
 tests/generic/398 |  8 ++++----
 tests/generic/399 |  4 ++--
 tests/generic/419 |  4 ++--
 tests/generic/421 |  4 ++--
 tests/generic/429 |  8 ++++----
 tests/generic/435 |  4 ++--
 tests/generic/440 |  8 ++++----
 10 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/common/encrypt b/common/encrypt
index 06a56ed9..7bbe1936 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -89,7 +89,7 @@ _require_encryption_policy_support()
 	mkdir $dir
 	_require_command "$KEYCTL_PROG" keyctl
 	_new_session_keyring
-	local keydesc=$(_generate_encryption_key)
+	local keydesc=$(_generate_session_encryption_key)
 	if _set_encpolicy $dir $keydesc $set_encpolicy_args \
 		2>&1 >>$seqres.full | egrep -q 'Invalid argument'; then
 		_notrun "kernel does not support encryption policy: '$set_encpolicy_args'"
@@ -153,7 +153,7 @@ _generate_key_descriptor()
 	echo $keydesc
 }
 
-# Generate a raw encryption key, but don't add it to the keyring yet.
+# Generate a raw encryption key, but don't add it to any keyring yet.
 _generate_raw_encryption_key()
 {
 	local raw=""
@@ -166,7 +166,7 @@ _generate_raw_encryption_key()
 
 # Add the specified raw encryption key to the session keyring, using the
 # specified key descriptor.
-_add_encryption_key()
+_add_session_encryption_key()
 {
 	local keydesc=$1
 	local raw=$2
@@ -209,26 +209,26 @@ _add_encryption_key()
 # keyctl program.  It's assumed the caller has already set up a test-scoped
 # session keyring using _new_session_keyring.
 #
-_generate_encryption_key()
+_generate_session_encryption_key()
 {
 	local keydesc=$(_generate_key_descriptor)
 	local raw=$(_generate_raw_encryption_key)
 
-	_add_encryption_key $keydesc $raw
+	_add_session_encryption_key $keydesc $raw
 
 	echo $keydesc
 }
 
 # Unlink an encryption key from the session keyring, given its key descriptor.
-_unlink_encryption_key()
+_unlink_session_encryption_key()
 {
 	local keydesc=$1
 	local keyid=$($KEYCTL_PROG search @s logon $FSTYP:$keydesc)
 	$KEYCTL_PROG unlink $keyid >>$seqres.full
 }
 
-# Revoke an encryption key from the keyring, given its key descriptor.
-_revoke_encryption_key()
+# Revoke an encryption key from the session keyring, given its key descriptor.
+_revoke_session_encryption_key()
 {
 	local keydesc=$1
 	local keyid=$($KEYCTL_PROG search @s logon $FSTYP:$keydesc)
@@ -412,7 +412,7 @@ _require_get_ciphertext_filename_support()
 		_scratch_mount
 		_new_session_keyring
 
-		local keydesc=$(_generate_encryption_key)
+		local keydesc=$(_generate_session_encryption_key)
 		local dir=$SCRATCH_MNT/test.${FUNCNAME[0]}
 		local file=$dir/$(perl -e 'print "A" x 255')
 		mkdir $dir
@@ -634,7 +634,7 @@ _verify_ciphertext_for_encryption_policy()
 	local raw_key=$(_generate_raw_encryption_key)
 	local keydesc=$(_generate_key_descriptor)
 	_new_session_keyring
-	_add_encryption_key $keydesc $raw_key
+	_add_session_encryption_key $keydesc $raw_key
 	local raw_key_hex=$(echo "$raw_key" | tr -d '\\x')
 
 	echo
diff --git a/tests/ext4/024 b/tests/ext4/024
index a86cc417..95243b70 100755
--- a/tests/ext4/024
+++ b/tests/ext4/024
@@ -53,7 +53,7 @@ _new_session_keyring
 _scratch_mkfs_encrypted &>>$seqres.full
 _scratch_mount
 mkdir $SCRATCH_MNT/edir
-keydesc=$(_generate_encryption_key)
+keydesc=$(_generate_session_encryption_key)
 _set_encpolicy $SCRATCH_MNT/edir $keydesc
 echo foo > $SCRATCH_MNT/edir/file
 inum=$(stat -c '%i' $SCRATCH_MNT/edir/file)
diff --git a/tests/generic/397 b/tests/generic/397
index a97e866b..f2e22950 100755
--- a/tests/generic/397
+++ b/tests/generic/397
@@ -45,7 +45,7 @@ _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
 mkdir $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
-keydesc=$(_generate_encryption_key)
+keydesc=$(_generate_session_encryption_key)
 _set_encpolicy $SCRATCH_MNT/edir $keydesc
 for dir in $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir; do
 	touch $dir/empty > /dev/null
@@ -92,7 +92,7 @@ filter_create_errors()
 	    -e 's/Operation not permitted/Required key not available/'
 }
 
-_unlink_encryption_key $keydesc
+_unlink_session_encryption_key $keydesc
 _scratch_cycle_mount
 
 # Check that unencrypted names aren't there
diff --git a/tests/generic/398 b/tests/generic/398
index b1af65e5..8c02bdc4 100755
--- a/tests/generic/398
+++ b/tests/generic/398
@@ -68,8 +68,8 @@ edir1=$SCRATCH_MNT/edir1
 edir2=$SCRATCH_MNT/edir2
 udir=$SCRATCH_MNT/udir
 mkdir $edir1 $edir2 $udir
-keydesc1=$(_generate_encryption_key)
-keydesc2=$(_generate_encryption_key)
+keydesc1=$(_generate_session_encryption_key)
+keydesc2=$(_generate_session_encryption_key)
 _set_encpolicy $edir1 $keydesc1
 _set_encpolicy $edir2 $keydesc2
 touch $edir1/efile1
@@ -141,8 +141,8 @@ rm $edir1/fifo $edir2/fifo $udir/fifo
 # Now test that *without* access to the encrypted key, we cannot use an exchange
 # (cross rename) operation to move a forbidden file into an encrypted directory.
 
-_unlink_encryption_key $keydesc1
-_unlink_encryption_key $keydesc2
+_unlink_session_encryption_key $keydesc1
+_unlink_session_encryption_key $keydesc2
 _scratch_cycle_mount
 efile1=$(find $edir1 -type f)
 efile2=$(find $edir2 -type f)
diff --git a/tests/generic/399 b/tests/generic/399
index dfd8d3c2..b2aaac13 100755
--- a/tests/generic/399
+++ b/tests/generic/399
@@ -61,7 +61,7 @@ dd if=/dev/zero of=$SCRATCH_DEV bs=$((1024 * 1024)) \
 _scratch_mkfs_sized_encrypted $fs_size &>> $seqres.full
 _scratch_mount
 
-keydesc=$(_generate_encryption_key)
+keydesc=$(_generate_session_encryption_key)
 mkdir $SCRATCH_MNT/encrypted_dir
 _set_encpolicy $SCRATCH_MNT/encrypted_dir $keydesc
 
@@ -127,7 +127,7 @@ done
 # memory than the '-9' preset.  The memory needed with our settings will be
 # 64 * 6.5 = 416 MB; see xz(1).
 #
-_unlink_encryption_key $keydesc
+_unlink_session_encryption_key $keydesc
 _scratch_unmount
 fs_compressed_size=$(head -c $fs_size $SCRATCH_DEV | \
 	xz --lzma2=dict=64M,mf=hc4,mode=fast,nice=16 | \
diff --git a/tests/generic/419 b/tests/generic/419
index 2f1d34c6..5b6636cd 100755
--- a/tests/generic/419
+++ b/tests/generic/419
@@ -47,11 +47,11 @@ _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
 mkdir $SCRATCH_MNT/edir
-keydesc=$(_generate_encryption_key)
+keydesc=$(_generate_session_encryption_key)
 _set_encpolicy $SCRATCH_MNT/edir $keydesc
 echo a > $SCRATCH_MNT/edir/a
 echo b > $SCRATCH_MNT/edir/b
-_unlink_encryption_key $keydesc
+_unlink_session_encryption_key $keydesc
 _scratch_cycle_mount
 
 # Note that because encrypted filenames are unpredictable, this needs to be
diff --git a/tests/generic/421 b/tests/generic/421
index c8cc2dcc..f634a431 100755
--- a/tests/generic/421
+++ b/tests/generic/421
@@ -51,7 +51,7 @@ slice=2
 # Create an encrypted file and sync its data to disk.
 rm -rf $dir
 mkdir $dir
-keydesc=$(_generate_encryption_key)
+keydesc=$(_generate_session_encryption_key)
 _set_encpolicy $dir $keydesc
 $XFS_IO_PROG -f $file -c "pwrite 0 $((nproc*slice))M" -c "fsync" > /dev/null
 
@@ -71,7 +71,7 @@ done
 sleep 1
 
 # Revoke the encryption key.
-keyid=$(_revoke_encryption_key $keydesc)
+keyid=$(_revoke_session_encryption_key $keydesc)
 
 # Now try to open the file again.  In buggy kernels this caused concurrent
 # readers to crash with a NULL pointer dereference during decryption.
diff --git a/tests/generic/429 b/tests/generic/429
index 472fdbd9..6c18c543 100755
--- a/tests/generic/429
+++ b/tests/generic/429
@@ -56,7 +56,7 @@ _new_session_keyring
 keydesc=$(_generate_key_descriptor)
 raw_key=$(_generate_raw_encryption_key)
 mkdir $SCRATCH_MNT/edir
-_add_encryption_key $keydesc $raw_key
+_add_session_encryption_key $keydesc $raw_key
 _set_encpolicy $SCRATCH_MNT/edir $keydesc
 
 # Create two files in the directory: one whose name is valid in the base64
@@ -96,7 +96,7 @@ show_directory_with_key()
 # the correct number of them are listed by readdir, and save them for later.
 echo
 echo "***** Without encryption key *****"
-_unlink_encryption_key $keydesc
+_unlink_session_encryption_key $keydesc
 _scratch_cycle_mount
 echo "--- Directory listing:"
 ciphertext_names=( $(find $SCRATCH_MNT/edir -mindepth 1 | sort) )
@@ -109,7 +109,7 @@ show_file_contents
 # stale dentries.
 echo
 echo "***** With encryption key *****"
-_add_encryption_key $keydesc $raw_key
+_add_session_encryption_key $keydesc $raw_key
 show_directory_with_key
 
 # Test for ->d_revalidate() race conditions.
@@ -127,7 +127,7 @@ echo "***** After key revocation *****"
 	exec 3<$SCRATCH_MNT/edir
 	exec 4<$SCRATCH_MNT/edir/@@@
 	exec 5<$SCRATCH_MNT/edir/abcd
-	_revoke_encryption_key $keydesc
+	_revoke_session_encryption_key $keydesc
 	show_directory_with_key
 )
 
diff --git a/tests/generic/435 b/tests/generic/435
index 073596f3..f12d2be8 100755
--- a/tests/generic/435
+++ b/tests/generic/435
@@ -50,7 +50,7 @@ _new_session_keyring
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 mkdir $SCRATCH_MNT/edir
-keydesc=$(_generate_encryption_key)
+keydesc=$(_generate_session_encryption_key)
 # -f 0x2: zero-pad to 16-byte boundary (i.e. encryption block boundary)
 _set_encpolicy $SCRATCH_MNT/edir $keydesc -f 0x2
 
@@ -66,7 +66,7 @@ _set_encpolicy $SCRATCH_MNT/edir $keydesc -f 0x2
 seq -f "$SCRATCH_MNT/edir/abcdefghijklmnopqrstuvwxyz012345%.0f" 100000 | xargs touch
 find $SCRATCH_MNT/edir/ -type f | xargs stat -c %i | sort | uniq | wc -l
 
-_unlink_encryption_key $keydesc
+_unlink_session_encryption_key $keydesc
 _scratch_cycle_mount
 
 # Verify that every file has a unique inode number and can be removed without
diff --git a/tests/generic/440 b/tests/generic/440
index 434286f4..1ec1ed48 100755
--- a/tests/generic/440
+++ b/tests/generic/440
@@ -46,7 +46,7 @@ _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 keydesc=$(_generate_key_descriptor)
 raw_key=$(_generate_raw_encryption_key)
-_add_encryption_key $keydesc $raw_key
+_add_session_encryption_key $keydesc $raw_key
 
 # Set up an encrypted directory containing a regular file, a subdirectory, and a
 # symlink.
@@ -65,7 +65,7 @@ echo
 echo "***** Parent has key, but child doesn't *****"
 exec 3< $SCRATCH_MNT/edir # pin inode with cached key in memory
 ls $SCRATCH_MNT/edir | sort
-_unlink_encryption_key $keydesc
+_unlink_session_encryption_key $keydesc
 cat $SCRATCH_MNT/edir/file |& _filter_scratch
 ls $SCRATCH_MNT/edir/subdir
 cat $SCRATCH_MNT/edir/symlink |& _filter_scratch
@@ -79,14 +79,14 @@ exec 3>&-
 # plaintext contents, even though its filename is shown in ciphertext!
 echo
 echo "***** Child has key, but parent doesn't *****"
-_add_encryption_key $keydesc $raw_key
+_add_session_encryption_key $keydesc $raw_key
 mkdir $SCRATCH_MNT/edir2
 _set_encpolicy $SCRATCH_MNT/edir2 $keydesc
 ln $SCRATCH_MNT/edir/file $SCRATCH_MNT/edir2/link
 _scratch_cycle_mount
 cat $SCRATCH_MNT/edir2/link
 exec 3< $SCRATCH_MNT/edir2/link # pin inode with cached key in memory
-_unlink_encryption_key $keydesc
+_unlink_session_encryption_key $keydesc
 stat $SCRATCH_MNT/edir/file |& _filter_scratch
 cat "$(find $SCRATCH_MNT/edir/ -type f)"
 exec 3>&-
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 2/9] common/encrypt: add helper functions that wrap new xfs_io commands
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 1/9] common/encrypt: disambiguate session encryption keys Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 3/9] common/encrypt: support checking for v2 encryption policy support Eric Biggers
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Wrap the new xfs_io commands 'add_enckey', 'rm_enckey', and
'enckey_status' with helper functions.

Also add _user_do_get_encpolicy(), so that all encryption xfs_io
commands have a _user_do() version.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 common/encrypt | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/common/encrypt b/common/encrypt
index 7bbe1936..a086e80f 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -261,6 +261,71 @@ _get_encpolicy()
 	$XFS_IO_PROG -c "get_encpolicy $*" "$file"
 }
 
+_user_do_get_encpolicy()
+{
+	local file=$1
+	shift
+
+	_user_do "$XFS_IO_PROG -c \"get_encpolicy $*\" \"$file\""
+}
+
+# Add an encryption key to the given filesystem.
+_add_enckey()
+{
+	local mnt=$1
+	local raw_key=$2
+	shift 2
+
+	echo -ne "$raw_key" | $XFS_IO_PROG -c "add_enckey $*" "$mnt"
+}
+
+_user_do_add_enckey()
+{
+	local mnt=$1
+	local raw_key=$2
+	shift 2
+
+	_user_do "echo -ne \"$raw_key\" | $XFS_IO_PROG -c \"add_enckey $*\" \"$mnt\""
+}
+
+# Remove the given encryption key from the given filesystem.
+_rm_enckey()
+{
+	local mnt=$1
+	local keyspec=$2
+	shift 2
+
+	$XFS_IO_PROG -c "rm_enckey $* $keyspec" "$mnt"
+}
+
+_user_do_rm_enckey()
+{
+	local mnt=$1
+	local keyspec=$2
+	shift 2
+
+	_user_do "$XFS_IO_PROG -c \"rm_enckey $* $keyspec\" \"$mnt\""
+}
+
+# Get the status of the given encryption key on the given filesystem.
+_enckey_status()
+{
+	local mnt=$1
+	local keyspec=$2
+	shift 2
+
+	$XFS_IO_PROG -c "enckey_status $* $keyspec" "$mnt"
+}
+
+_user_do_enckey_status()
+{
+	local mnt=$1
+	local keyspec=$2
+	shift 2
+
+	_user_do "$XFS_IO_PROG -c \"enckey_status $* $keyspec\" \"$mnt\""
+}
+
 # Retrieve the encryption nonce of the given inode as a hex string.  The nonce
 # was randomly generated by the filesystem and isn't exposed directly to
 # userspace.  But it can be read using the filesystem's debugging tools.
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 3/9] common/encrypt: support checking for v2 encryption policy support
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 1/9] common/encrypt: disambiguate session encryption keys Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 2/9] common/encrypt: add helper functions that wrap new xfs_io commands Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-09-01 12:08   ` Eryu Guan
  2019-08-12 17:58 ` [RFC PATCH 4/9] common/encrypt: support verifying ciphertext of v2 encryption policies Eric Biggers
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Allow passing '-v 2' to _require_scratch_encryption() to check for v2
encryption policy support on the scratch device, and for xfs_io support
for setting and getting v2 encryption policies.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 common/encrypt | 41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/common/encrypt b/common/encrypt
index a086e80f..fa6e2672 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -6,12 +6,13 @@
 
 #
 # _require_scratch_encryption [-c CONTENTS_MODE] [-n FILENAMES_MODE]
+#			      [-v POLICY_VERSION]
 #
 # Require encryption support on the scratch device.
 #
-# This checks for support for the default type of encryption policy (AES-256-XTS
-# and AES-256-CTS).  Options can be specified to also require support for a
-# different type of encryption policy.
+# This checks for support for the default type of encryption policy (v1 with
+# AES-256-XTS and AES-256-CTS).  Options can be specified to also require
+# support for a different type of encryption policy.
 #
 _require_scratch_encryption()
 {
@@ -68,13 +69,15 @@ _require_encryption_policy_support()
 	local mnt=$1
 	local dir=$mnt/tmpdir
 	local set_encpolicy_args=""
+	local policy_version=1
 	local c
 
 	OPTIND=2
-	while getopts "c:n:" c; do
+	while getopts "c:n:v:" c; do
 		case $c in
-		c|n)
+		c|n|v)
 			set_encpolicy_args+=" -$c $OPTARG"
+			[ $c = v ] && policy_version=$OPTARG
 			;;
 		*)
 			_fail "Unrecognized option '$c'"
@@ -87,10 +90,26 @@ _require_encryption_policy_support()
 		>> $seqres.full
 
 	mkdir $dir
-	_require_command "$KEYCTL_PROG" keyctl
-	_new_session_keyring
-	local keydesc=$(_generate_session_encryption_key)
-	if _set_encpolicy $dir $keydesc $set_encpolicy_args \
+	if (( policy_version > 1 )); then
+		_require_xfs_io_command "get_encpolicy" "-t"
+		local output=$(_get_encpolicy $dir -t)
+		if [ "$output" != "supported" ]; then
+			if [ "$output" = "unsupported" ]; then
+				_notrun "kernel does not support $FSTYP encryption v2 API"
+			fi
+			_fail "Unexpected output from 'get_encpolicy -t'"
+		fi
+		# Both the kernel and xfs_io support v2 encryption policies, and
+		# therefore also filesystem-level keys -- since that's the only
+		# way to provide keys for v2 policies.
+		local raw_key=$(_generate_raw_encryption_key)
+		local keyspec=$(_add_enckey $mnt "$raw_key" | awk '{print $NF}')
+	else
+		_require_command "$KEYCTL_PROG" keyctl
+		_new_session_keyring
+		local keyspec=$(_generate_session_encryption_key)
+	fi
+	if _set_encpolicy $dir $keyspec $set_encpolicy_args \
 		2>&1 >>$seqres.full | egrep -q 'Invalid argument'; then
 		_notrun "kernel does not support encryption policy: '$set_encpolicy_args'"
 	fi
@@ -103,7 +122,9 @@ _require_encryption_policy_support()
 	if ! echo foo > $dir/file; then
 		_notrun "encryption policy '$set_encpolicy_args' is unusable; probably missing kernel crypto API support"
 	fi
-	$KEYCTL_PROG clear @s
+	if (( policy_version <= 1 )); then
+		$KEYCTL_PROG clear @s
+	fi
 	rm -r $dir
 }
 
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 4/9] common/encrypt: support verifying ciphertext of v2 encryption policies
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
                   ` (2 preceding siblings ...)
  2019-08-12 17:58 ` [RFC PATCH 3/9] common/encrypt: support checking for v2 encryption policy support Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 5/9] generic: add basic test for fscrypt API additions Eric Biggers
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Update _verify_ciphertext_for_encryption_policy() to support v2
encryption policies.

This also required adding HKDF-SHA512 support to fscrypt-crypt-util.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 common/encrypt           |  58 ++++++--
 src/fscrypt-crypt-util.c | 304 ++++++++++++++++++++++++++++++++++-----
 2 files changed, 316 insertions(+), 46 deletions(-)

diff --git a/common/encrypt b/common/encrypt
index fa6e2672..6a3c469d 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -379,9 +379,16 @@ _get_encryption_nonce()
 		#	flags: 0x2
 		#	master_key_descriptor: 0000000000000000
 		#	nonce: EFBD18765DF6414EC0A2CD5F91297E12
+		#
+		# Also support the case where the whole xattr is printed as hex,
+		# as is the case for fscrypt_context_v2.
+		#
+		#	xattr: e_name_index:9 e_name:c e_name_len:1 e_value_size:40 e_value:
+		#	020104020000000033809BFEBE68A4AD264079B30861DD5E6B9E72D07523C58794ACF52534BAA756
+		#
 		$DUMP_F2FS_PROG -i $inode $device | awk '
 			/\<e_name:c\>/ { found = 1 }
-			/^nonce:/ && found {
+			(/^nonce:/ || /^[[:xdigit:]]+$/) && found {
 				print substr($0, length($0) - 31, 32);
 				found = 0;
 			}'
@@ -402,6 +409,11 @@ _require_get_encryption_nonce_support()
 		;;
 	f2fs)
 		_require_command "$DUMP_F2FS_PROG" dump.f2fs
+		# For fscrypt_context_v2, we actually need a f2fs-tools version
+		# that has the patch "f2fs-tools: improve xattr value printing"
+		# (https://sourceforge.net/p/linux-f2fs/mailman/message/36648640/).
+		# Otherwise the xattr is incorrectly parsed as v1.  But just let
+		# the test fail in that case, as it was an f2fs-tools bug...
 		;;
 	*)
 		_notrun "_get_encryption_nonce() isn't implemented on $FSTYP"
@@ -551,7 +563,7 @@ _do_verify_ciphertext_for_encryption_policy()
 	local filenames_encryption_mode=$2
 	local policy_flags=$3
 	local set_encpolicy_args=$4
-	local keydesc=$5
+	local keyspec=$5
 	local raw_key_hex=$6
 	local crypt_cmd="src/fscrypt-crypt-util $7"
 
@@ -573,7 +585,7 @@ _do_verify_ciphertext_for_encryption_policy()
 	done
 	dir=$SCRATCH_MNT/encdir
 	mkdir $dir
-	_set_encpolicy $dir $keydesc $set_encpolicy_args -f $policy_flags
+	_set_encpolicy $dir $keyspec $set_encpolicy_args -f $policy_flags
 	for src in $tmp.testfile_*; do
 		dst=$dir/${src##*.}
 		cp $src $dst
@@ -593,7 +605,7 @@ _do_verify_ciphertext_for_encryption_policy()
 		dir=$SCRATCH_MNT/encdir.pad$padding
 		mkdir $dir
 		dir_inode=$(stat -c %i $dir)
-		_set_encpolicy $dir $keydesc $set_encpolicy_args \
+		_set_encpolicy $dir $keyspec $set_encpolicy_args \
 			-f $((policy_flags | padding_flag))
 		for len in 1 3 15 16 17 32 100 254 255; do
 			name=$(tr -d -C a-zA-Z0-9 < /dev/urandom | head -c $len)
@@ -667,12 +679,14 @@ _fscrypt_mode_name_to_num()
 # policy of the specified type is used.
 #
 # The first two parameters are the contents and filenames encryption modes to
-# test.  Optionally, also specify 'direct' to test the DIRECT_KEY flag.
+# test.  Optionally, also specify 'direct' to test the DIRECT_KEY flag, and/or
+# 'v2' to test v2 policies.
 _verify_ciphertext_for_encryption_policy()
 {
 	local contents_encryption_mode=$1
 	local filenames_encryption_mode=$2
 	local opt
+	local policy_version=1
 	local policy_flags=0
 	local set_encpolicy_args=""
 	local crypt_util_args=""
@@ -680,6 +694,9 @@ _verify_ciphertext_for_encryption_policy()
 	shift 2
 	for opt; do
 		case "$opt" in
+		v2)
+			policy_version=2
+			;;
 		direct)
 			if [ $contents_encryption_mode != \
 			     $filenames_encryption_mode ]; then
@@ -698,10 +715,18 @@ _verify_ciphertext_for_encryption_policy()
 	set_encpolicy_args+=" -c $contents_mode_num"
 	set_encpolicy_args+=" -n $filenames_mode_num"
 
-	if (( policy_flags & 0x04 )); then
-		crypt_util_args+=" --kdf=none"
+	if (( policy_version > 1 )); then
+		set_encpolicy_args+=" -v 2"
+		crypt_util_args+=" --kdf=HKDF-SHA512"
+		if (( policy_flags & 0x04 )); then
+			crypt_util_args+=" --mode-num=$contents_mode_num"
+		fi
 	else
-		crypt_util_args+=" --kdf=AES-128-ECB"
+		if (( policy_flags & 0x04 )); then
+			crypt_util_args+=" --kdf=none"
+		else
+			crypt_util_args+=" --kdf=AES-128-ECB"
+		fi
 	fi
 	set_encpolicy_args=${set_encpolicy_args# }
 
@@ -710,7 +735,9 @@ _verify_ciphertext_for_encryption_policy()
 	_require_xfs_io_command "fiemap"
 	_require_get_encryption_nonce_support
 	_require_get_ciphertext_filename_support
-	_require_command "$KEYCTL_PROG" keyctl
+	if (( policy_version == 1 )); then
+		_require_command "$KEYCTL_PROG" keyctl
+	fi
 
 	echo "Creating encryption-capable filesystem" >> $seqres.full
 	_scratch_mkfs_encrypted &>> $seqres.full
@@ -718,9 +745,14 @@ _verify_ciphertext_for_encryption_policy()
 
 	echo "Generating encryption key" >> $seqres.full
 	local raw_key=$(_generate_raw_encryption_key)
-	local keydesc=$(_generate_key_descriptor)
-	_new_session_keyring
-	_add_session_encryption_key $keydesc $raw_key
+	if (( policy_version > 1 )); then
+		local keyspec=$(_add_enckey $SCRATCH_MNT "$raw_key" \
+				| awk '{print $NF}')
+	else
+		local keyspec=$(_generate_key_descriptor)
+		_new_session_keyring
+		_add_session_encryption_key $keyspec $raw_key
+	fi
 	local raw_key_hex=$(echo "$raw_key" | tr -d '\\x')
 
 	echo
@@ -734,7 +766,7 @@ _verify_ciphertext_for_encryption_policy()
 		"$filenames_encryption_mode" \
 		"$policy_flags" \
 		"$set_encpolicy_args" \
-		"$keydesc" \
+		"$keyspec" \
 		"$raw_key_hex" \
 		"$crypt_util_args"
 }
diff --git a/src/fscrypt-crypt-util.c b/src/fscrypt-crypt-util.c
index 81574a55..f5fd8386 100644
--- a/src/fscrypt-crypt-util.c
+++ b/src/fscrypt-crypt-util.c
@@ -12,11 +12,11 @@
  *
  * All algorithms are implemented in portable C code to avoid depending on
  * libcrypto (OpenSSL), and because some fscrypt-supported algorithms aren't
- * available in libcrypto anyway (e.g. Adiantum).  For simplicity, all crypto
- * code here tries to follow the mathematical definitions directly, without
- * optimizing for performance or worrying about following security best
- * practices such as mitigating side-channel attacks.  So, only use this program
- * for testing!
+ * available in libcrypto anyway (e.g. Adiantum), or are only supported in
+ * recent versions (e.g. HKDF-SHA512).  For simplicity, all crypto code here
+ * tries to follow the mathematical definitions directly, without optimizing for
+ * performance or worrying about following security best practices such as
+ * mitigating side-channel attacks.  So, only use this program for testing!
  */
 
 #include <asm/byteorder.h>
@@ -63,8 +63,9 @@ static void usage(FILE *fp)
 "  --decrypt                   Decrypt instead of encrypt\n"
 "  --file-nonce=NONCE          File's nonce as a 32-character hex string\n"
 "  --help                      Show this help\n"
-"  --kdf=KDF                   Key derivation function to use: AES-128-ECB\n"
-"                                or none.  Default: none\n"
+"  --kdf=KDF                   Key derivation function to use: AES-128-ECB,\n"
+"                                HKDF-SHA512, or none.  Default: none\n"
+"  --mode-num=NUM              Derive per-mode key using mode number NUM\n"
 "  --padding=PADDING           If last block is partial, zero-pad it to next\n"
 "                                PADDING-byte boundary.  Default: BLOCK_SIZE\n"
 	, fp);
@@ -134,6 +135,11 @@ static inline u32 ror32(u32 v, int n)
 	return (v >> n) | (v << (32 - n));
 }
 
+static inline u64 ror64(u64 v, int n)
+{
+	return (v >> n) | (v << (64 - n));
+}
+
 static inline void xor(u8 *res, const u8 *a, const u8 *b, size_t count)
 {
 	while (count--)
@@ -586,7 +592,7 @@ static void test_aes(void)
 #endif /* ENABLE_ALG_TESTS */
 
 /*----------------------------------------------------------------------------*
- *                                  SHA-256                                   *
+ *                            SHA-512 and SHA-256                             *
  *----------------------------------------------------------------------------*/
 
 /*
@@ -594,35 +600,104 @@ static void test_aes(void)
  *	https://csrc.nist.gov/csrc/media/publications/fips/180/2/archive/2002-08-01/documents/fips180-2withchangenotice.pdf
  */
 
+#define SHA512_DIGEST_SIZE	64
+#define SHA512_BLOCK_SIZE	128
+
 #define SHA256_DIGEST_SIZE	32
 #define SHA256_BLOCK_SIZE	64
 
 #define Ch(x, y, z)	(((x) & (y)) ^ (~(x) & (z)))
 #define Maj(x, y, z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#define Sigma512_0(x)	(ror64((x), 28) ^ ror64((x), 34) ^ ror64((x), 39))
+#define Sigma512_1(x)	(ror64((x), 14) ^ ror64((x), 18) ^ ror64((x), 41))
+#define sigma512_0(x)	(ror64((x),  1) ^ ror64((x),  8) ^ ((x) >> 7))
+#define sigma512_1(x)	(ror64((x), 19) ^ ror64((x), 61) ^ ((x) >> 6))
+
 #define Sigma256_0(x)	(ror32((x),  2) ^ ror32((x), 13) ^ ror32((x), 22))
 #define Sigma256_1(x)	(ror32((x),  6) ^ ror32((x), 11) ^ ror32((x), 25))
 #define sigma256_0(x)	(ror32((x),  7) ^ ror32((x), 18) ^ ((x) >>  3))
 #define sigma256_1(x)	(ror32((x), 17) ^ ror32((x), 19) ^ ((x) >> 10))
 
-static const u32 sha256_iv[8] = {
-	0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
-	0x1f83d9ab, 0x5be0cd19,
+static const u64 sha512_iv[8] = {
+	0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
+	0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
+	0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
 };
 
-static const u32 sha256_round_constants[64] = {
-	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
-	0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
-	0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
-	0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
-	0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
-	0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+static const u64 sha512_round_constants[80] = {
+	0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
+	0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
+	0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
+	0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+	0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
+	0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
+	0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
+	0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+	0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
+	0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+	0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
+	0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
+	0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
+	0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
+	0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
+	0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
+	0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
+	0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
+	0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
+	0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+	0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
+	0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
+	0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
+	0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
+	0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
+	0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
+	0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
 };
 
+/* Compute the SHA-512 digest of the given buffer */
+static void sha512(const u8 *in, size_t inlen, u8 out[SHA512_DIGEST_SIZE])
+{
+	const size_t msglen = ROUND_UP(inlen + 17, SHA512_BLOCK_SIZE);
+	u8 * const msg = xmalloc(msglen);
+	u64 H[8];
+	int i;
+
+	/* super naive way of handling the padding */
+	memcpy(msg, in, inlen);
+	memset(&msg[inlen], 0, msglen - inlen);
+	msg[inlen] = 0x80;
+	put_unaligned_be64((u64)inlen * 8, &msg[msglen - sizeof(__be64)]);
+	in = msg;
+
+	memcpy(H, sha512_iv, sizeof(H));
+	do {
+		u64 a = H[0], b = H[1], c = H[2], d = H[3],
+		    e = H[4], f = H[5], g = H[6], h = H[7];
+		u64 W[80];
+
+		for (i = 0; i < 16; i++)
+			W[i] = get_unaligned_be64(&in[i * sizeof(__be64)]);
+		for (; i < ARRAY_SIZE(W); i++)
+			W[i] = sigma512_1(W[i - 2]) + W[i - 7] +
+			       sigma512_0(W[i - 15]) + W[i - 16];
+		for (i = 0; i < ARRAY_SIZE(W); i++) {
+			u64 T1 = h + Sigma512_1(e) + Ch(e, f, g) +
+				 sha512_round_constants[i] + W[i];
+			u64 T2 = Sigma512_0(a) + Maj(a, b, c);
+
+			h = g; g = f; f = e; e = d + T1;
+			d = c; c = b; b = a; a = T1 + T2;
+		}
+		H[0] += a; H[1] += b; H[2] += c; H[3] += d;
+		H[4] += e; H[5] += f; H[6] += g; H[7] += h;
+	} while ((in += SHA512_BLOCK_SIZE) != &msg[msglen]);
+
+	for (i = 0; i < ARRAY_SIZE(H); i++)
+		put_unaligned_be64(H[i], &out[i * sizeof(__be64)]);
+	free(msg);
+}
+
 /* Compute the SHA-256 digest of the given buffer */
 static void sha256(const u8 *in, size_t inlen, u8 out[SHA256_DIGEST_SIZE])
 {
@@ -638,7 +713,8 @@ static void sha256(const u8 *in, size_t inlen, u8 out[SHA256_DIGEST_SIZE])
 	put_unaligned_be64((u64)inlen * 8, &msg[msglen - sizeof(__be64)]);
 	in = msg;
 
-	memcpy(H, sha256_iv, sizeof(H));
+	for (i = 0; i < ARRAY_SIZE(H); i++)
+		H[i] = (u32)(sha512_iv[i] >> 32);
 	do {
 		u32 a = H[0], b = H[1], c = H[2], d = H[3],
 		    e = H[4], f = H[5], g = H[6], h = H[7];
@@ -651,7 +727,7 @@ static void sha256(const u8 *in, size_t inlen, u8 out[SHA256_DIGEST_SIZE])
 			       sigma256_0(W[i - 15]) + W[i - 16];
 		for (i = 0; i < ARRAY_SIZE(W); i++) {
 			u32 T1 = h + Sigma256_1(e) + Ch(e, f, g) +
-				 sha256_round_constants[i] + W[i];
+				 (u32)(sha512_round_constants[i] >> 32) + W[i];
 			u32 T2 = Sigma256_0(a) + Maj(a, b, c);
 
 			h = g; g = f; f = e; e = d + T1;
@@ -674,8 +750,8 @@ static void test_sha2(void)
 
 	while (num_tests--) {
 		u8 in[4096];
-		u8 digest[SHA256_DIGEST_SIZE];
-		u8 ref_digest[SHA256_DIGEST_SIZE];
+		u8 digest[SHA512_DIGEST_SIZE];
+		u8 ref_digest[SHA512_DIGEST_SIZE];
 		const size_t inlen = rand() % (1 + sizeof(in));
 
 		rand_bytes(in, inlen);
@@ -683,6 +759,124 @@ static void test_sha2(void)
 		sha256(in, inlen, digest);
 		SHA256(in, inlen, ref_digest);
 		ASSERT(memcmp(digest, ref_digest, SHA256_DIGEST_SIZE) == 0);
+
+		sha512(in, inlen, digest);
+		SHA512(in, inlen, ref_digest);
+		ASSERT(memcmp(digest, ref_digest, SHA512_DIGEST_SIZE) == 0);
+	}
+}
+#endif /* ENABLE_ALG_TESTS */
+
+/*----------------------------------------------------------------------------*
+ *                            HKDF implementation                             *
+ *----------------------------------------------------------------------------*/
+
+static void hmac_sha512(const u8 *key, size_t keylen, const u8 *msg,
+			size_t msglen, u8 mac[SHA512_DIGEST_SIZE])
+{
+	u8 *ibuf = xmalloc(SHA512_BLOCK_SIZE + msglen);
+	u8 obuf[SHA512_BLOCK_SIZE + SHA512_DIGEST_SIZE];
+
+	ASSERT(keylen <= SHA512_BLOCK_SIZE); /* keylen > bs not implemented */
+
+	memset(ibuf, 0x36, SHA512_BLOCK_SIZE);
+	xor(ibuf, ibuf, key, keylen);
+	memcpy(&ibuf[SHA512_BLOCK_SIZE], msg, msglen);
+
+	memset(obuf, 0x5c, SHA512_BLOCK_SIZE);
+	xor(obuf, obuf, key, keylen);
+	sha512(ibuf, SHA512_BLOCK_SIZE + msglen, &obuf[SHA512_BLOCK_SIZE]);
+	sha512(obuf, sizeof(obuf), mac);
+
+	free(ibuf);
+}
+
+static void hkdf_sha512(const u8 *ikm, size_t ikmlen,
+			const u8 *salt, size_t saltlen,
+			const u8 *info, size_t infolen,
+			u8 *output, size_t outlen)
+{
+	static const u8 default_salt[SHA512_DIGEST_SIZE];
+	u8 prk[SHA512_DIGEST_SIZE]; /* pseudorandom key */
+	u8 *buf = xmalloc(1 + infolen + SHA512_DIGEST_SIZE);
+	u8 counter = 1;
+	size_t i;
+
+	if (saltlen == 0) {
+		salt = default_salt;
+		saltlen = sizeof(default_salt);
+	}
+
+	/* HKDF-Extract */
+	ASSERT(ikmlen > 0);
+	hmac_sha512(salt, saltlen, ikm, ikmlen, prk);
+
+	/* HKDF-Expand */
+	for (i = 0; i < outlen; i += SHA512_DIGEST_SIZE) {
+		u8 *p = buf;
+		u8 tmp[SHA512_DIGEST_SIZE];
+
+		ASSERT(counter != 0);
+		if (i > 0) {
+			memcpy(p, &output[i - SHA512_DIGEST_SIZE],
+			       SHA512_DIGEST_SIZE);
+			p += SHA512_DIGEST_SIZE;
+		}
+		memcpy(p, info, infolen);
+		p += infolen;
+		*p++ = counter++;
+		hmac_sha512(prk, sizeof(prk), buf, p - buf, tmp);
+		memcpy(&output[i], tmp, MIN(sizeof(tmp), outlen - i));
+	}
+	free(buf);
+}
+
+#ifdef ENABLE_ALG_TESTS
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+static void openssl_hkdf_sha512(const u8 *ikm, size_t ikmlen,
+				const u8 *salt, size_t saltlen,
+				const u8 *info, size_t infolen,
+				u8 *output, size_t outlen)
+{
+	EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
+	size_t actual_outlen = outlen;
+
+	ASSERT(pctx != NULL);
+	ASSERT(EVP_PKEY_derive_init(pctx) > 0);
+	ASSERT(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha512()) > 0);
+	ASSERT(EVP_PKEY_CTX_set1_hkdf_key(pctx, ikm, ikmlen) > 0);
+	ASSERT(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) > 0);
+	ASSERT(EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) > 0);
+	ASSERT(EVP_PKEY_derive(pctx, output, &actual_outlen) > 0);
+	ASSERT(actual_outlen == outlen);
+	EVP_PKEY_CTX_free(pctx);
+}
+
+static void test_hkdf_sha512(void)
+{
+	unsigned long num_tests = NUM_ALG_TEST_ITERATIONS;
+
+	while (num_tests--) {
+		u8 ikm[SHA512_DIGEST_SIZE];
+		u8 salt[SHA512_DIGEST_SIZE];
+		u8 info[128];
+		u8 actual_output[512];
+		u8 expected_output[sizeof(actual_output)];
+		size_t ikmlen = 1 + (rand() % sizeof(ikm));
+		size_t saltlen = rand() % (1 + sizeof(salt));
+		size_t infolen = rand() % (1 + sizeof(info));
+		size_t outlen = rand() % (1 + sizeof(actual_output));
+
+		rand_bytes(ikm, ikmlen);
+		rand_bytes(salt, saltlen);
+		rand_bytes(info, infolen);
+
+		hkdf_sha512(ikm, ikmlen, salt, saltlen, info, infolen,
+			    actual_output, outlen);
+		openssl_hkdf_sha512(ikm, ikmlen, salt, saltlen, info, infolen,
+				    expected_output, outlen);
+		ASSERT(memcmp(actual_output, expected_output, outlen) == 0);
 	}
 }
 #endif /* ENABLE_ALG_TESTS */
@@ -1476,6 +1670,7 @@ static void crypt_loop(const struct fscrypt_cipher *cipher, const u8 *key,
 enum kdf_algorithm {
 	KDF_NONE,
 	KDF_AES_128_ECB,
+	KDF_HKDF_SHA512,
 };
 
 static enum kdf_algorithm parse_kdf_algorithm(const char *arg)
@@ -1484,21 +1679,36 @@ static enum kdf_algorithm parse_kdf_algorithm(const char *arg)
 		return KDF_NONE;
 	if (strcmp(arg, "AES-128-ECB") == 0)
 		return KDF_AES_128_ECB;
+	if (strcmp(arg, "HKDF-SHA512") == 0)
+		return KDF_HKDF_SHA512;
 	die("Unknown KDF: %s", arg);
 }
 
+static u8 parse_mode_number(const char *arg)
+{
+	char *tmp;
+	long num = strtol(arg, &tmp, 10);
+
+	if (num <= 0 || *tmp || (u8)num != num)
+		die("Invalid mode number: %s", arg);
+	return num;
+}
+
 /*
  * Get the key and starting IV with which the encryption will actually be done.
- * If a KDF was specified, a subkey is derived from the master key and file
- * nonce.  Otherwise, the master key is used directly.
+ * If a KDF was specified, a subkey is derived from the master key and the mode
+ * number or file nonce.  Otherwise, the master key is used directly.
  */
 static void get_key_and_iv(const u8 *master_key, size_t master_key_size,
 			   enum kdf_algorithm kdf,
-			   const u8 nonce[FILE_NONCE_SIZE],
+			   u8 mode_num, const u8 nonce[FILE_NONCE_SIZE],
 			   u8 *real_key, size_t real_key_size,
 			   struct fscrypt_iv *iv)
 {
+	bool nonce_in_iv = false;
 	struct aes_key aes_key;
+	u8 info[8 + 1 + FILE_NONCE_SIZE] = "fscrypt";
+	size_t infolen = 8;
 	size_t i;
 
 	ASSERT(real_key_size <= master_key_size);
@@ -1507,22 +1717,43 @@ static void get_key_and_iv(const u8 *master_key, size_t master_key_size,
 
 	switch (kdf) {
 	case KDF_NONE:
+		if (mode_num != 0)
+			die("--mode-num isn't supported with --kdf=none");
 		memcpy(real_key, master_key, real_key_size);
-		if (nonce != NULL)
-			memcpy(&iv->bytes[8], nonce, FILE_NONCE_SIZE);
+		nonce_in_iv = true;
 		break;
 	case KDF_AES_128_ECB:
 		if (nonce == NULL)
 			die("--file-nonce is required with --kdf=AES-128-ECB");
+		if (mode_num != 0)
+			die("--mode-num isn't supported with --kdf=AES-128-ECB");
 		STATIC_ASSERT(FILE_NONCE_SIZE == AES_128_KEY_SIZE);
 		ASSERT(real_key_size % AES_BLOCK_SIZE == 0);
 		aes_setkey(&aes_key, nonce, AES_128_KEY_SIZE);
 		for (i = 0; i < real_key_size; i += AES_BLOCK_SIZE)
 			aes_encrypt(&aes_key, &master_key[i], &real_key[i]);
 		break;
+	case KDF_HKDF_SHA512:
+		if (mode_num != 0) {
+			info[infolen++] = 3; /* HKDF_CONTEXT_PER_MODE_KEY */
+			info[infolen++] = mode_num;
+			nonce_in_iv = true;
+		} else if (nonce != NULL) {
+			info[infolen++] = 2; /* HKDF_CONTEXT_PER_FILE_KEY */
+			memcpy(&info[infolen], nonce, FILE_NONCE_SIZE);
+			infolen += FILE_NONCE_SIZE;
+		} else {
+			die("With --kdf=HKDF-SHA512, at least one of --file-nonce and --mode-num must be specified");
+		}
+		hkdf_sha512(master_key, master_key_size, NULL, 0,
+			    info, infolen, real_key, real_key_size);
+		break;
 	default:
 		ASSERT(0);
 	}
+
+	if (nonce_in_iv && nonce != NULL)
+		memcpy(&iv->bytes[8], nonce, FILE_NONCE_SIZE);
 }
 
 enum {
@@ -1531,6 +1762,7 @@ enum {
 	OPT_FILE_NONCE,
 	OPT_HELP,
 	OPT_KDF,
+	OPT_MODE_NUM,
 	OPT_PADDING,
 };
 
@@ -1540,6 +1772,7 @@ static const struct option longopts[] = {
 	{ "file-nonce",      required_argument, NULL, OPT_FILE_NONCE },
 	{ "help",            no_argument,       NULL, OPT_HELP },
 	{ "kdf",             required_argument, NULL, OPT_KDF },
+	{ "mode-num",        required_argument, NULL, OPT_MODE_NUM },
 	{ "padding",         required_argument, NULL, OPT_PADDING },
 	{ NULL, 0, NULL, 0 },
 };
@@ -1551,6 +1784,7 @@ int main(int argc, char *argv[])
 	u8 _file_nonce[FILE_NONCE_SIZE];
 	u8 *file_nonce = NULL;
 	enum kdf_algorithm kdf = KDF_NONE;
+	u8 mode_num = 0;
 	size_t padding = 0;
 	const struct fscrypt_cipher *cipher;
 	u8 master_key[MAX_KEY_SIZE];
@@ -1565,6 +1799,7 @@ int main(int argc, char *argv[])
 #ifdef ENABLE_ALG_TESTS
 	test_aes();
 	test_sha2();
+	test_hkdf_sha512();
 	test_aes_256_xts();
 	test_aes_256_cts_cbc();
 	test_adiantum();
@@ -1592,6 +1827,9 @@ int main(int argc, char *argv[])
 		case OPT_KDF:
 			kdf = parse_kdf_algorithm(optarg);
 			break;
+		case OPT_MODE_NUM:
+			mode_num = parse_mode_number(optarg);
+			break;
 		case OPT_PADDING:
 			padding = strtoul(optarg, &tmp, 10);
 			if (padding <= 0 || *tmp || !is_power_of_2(padding) ||
@@ -1625,7 +1863,7 @@ int main(int argc, char *argv[])
 	if (master_key_size < cipher->keysize)
 		die("Master key is too short for cipher %s", cipher->name);
 
-	get_key_and_iv(master_key, master_key_size, kdf, file_nonce,
+	get_key_and_iv(master_key, master_key_size, kdf, mode_num, file_nonce,
 		       real_key, cipher->keysize, &iv);
 
 	crypt_loop(cipher, real_key, &iv, decrypting, block_size, padding);
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 5/9] generic: add basic test for fscrypt API additions
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
                   ` (3 preceding siblings ...)
  2019-08-12 17:58 ` [RFC PATCH 4/9] common/encrypt: support verifying ciphertext of v2 encryption policies Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 6/9] generic: add test for non-root use of " Eric Biggers
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Add a basic test of fscrypt filesystem-level encryption keyring and v2
encryption policies.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 tests/generic/800     | 127 ++++++++++++++++++++++++++++++++++++++++++
 tests/generic/800.out |  91 ++++++++++++++++++++++++++++++
 tests/generic/group   |   1 +
 3 files changed, 219 insertions(+)
 create mode 100755 tests/generic/800
 create mode 100644 tests/generic/800.out

diff --git a/tests/generic/800 b/tests/generic/800
new file mode 100755
index 00000000..de71b7ff
--- /dev/null
+++ b/tests/generic/800
@@ -0,0 +1,127 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2019 Google LLC
+#
+# FS QA Test generic/800
+#
+# Basic test of fscrypt filesystem-level encryption keyring
+# and v2 encryption policies.
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+echo
+
+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
+_supported_os Linux
+_require_scratch_encryption -v 2
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+test_with_policy_version()
+{
+	local vers=$1
+	local raw_key=""
+	local i
+
+	for i in {1..64}; do
+		raw_key+="\\x$(printf "%02x" $i)"
+	done
+
+	if (( vers == 1 )); then
+		# Key descriptor: arbitrary value
+		local keyspec="0000111122223333"
+		local add_enckey_args="-d $keyspec"
+	else
+		# Key identifier:
+		# HKDF-SHA512(key=raw_key, salt="", info="fscrypt\0\x01")
+		local keyspec="69b2f6edeee720cce0577937eb8a6751"
+		local add_enckey_args=""
+	fi
+
+	mkdir $dir
+	echo "# Setting v$vers encryption policy"
+	_set_encpolicy $dir $keyspec
+	echo "# Getting v$vers encryption policy"
+	_get_encpolicy $dir | _filter_scratch
+	if (( vers == 1 )); then
+		echo "# Getting v1 encryption policy using old ioctl"
+		_get_encpolicy $dir -1 | _filter_scratch
+	fi
+	echo "# Trying to create file without key added yet"
+	$XFS_IO_PROG -f $dir/file |& _filter_scratch
+	echo "# Getting encryption key status"
+	_enckey_status $SCRATCH_MNT $keyspec
+	echo "# Adding encryption key"
+	_add_enckey $SCRATCH_MNT "$raw_key" $add_enckey_args
+	echo "# Creating encrypted file"
+	echo contents > $dir/file
+	echo "# Getting encryption key status"
+	_enckey_status $SCRATCH_MNT $keyspec
+	echo "# Removing encryption key"
+	_rm_enckey $SCRATCH_MNT $keyspec
+	echo "# Getting encryption key status"
+	_enckey_status $SCRATCH_MNT $keyspec
+	echo "# Verifying that the encrypted directory was \"locked\""
+	cat $dir/file |& _filter_scratch
+	cat "$(find $dir -type f)" |& _filter_scratch | cut -d ' ' -f3-
+
+	# Test removing key with a file open.
+	echo "# Re-adding encryption key"
+	_add_enckey $SCRATCH_MNT "$raw_key" $add_enckey_args
+	echo "# Creating another encrypted file"
+	echo foo > $dir/file2
+	echo "# Removing key while an encrypted file is open"
+	exec 3< $dir/file
+	_rm_enckey $SCRATCH_MNT $keyspec
+	echo "# Non-open file should have been evicted"
+	cat $dir/file2 |& _filter_scratch
+	echo "# Open file shouldn't have been evicted"
+	cat $dir/file
+	echo "# Key should be in \"incompletely removed\" state"
+	_enckey_status $SCRATCH_MNT $keyspec
+	echo "# Closing file and removing key for real now"
+	exec 3<&-
+	_rm_enckey $SCRATCH_MNT $keyspec
+	cat $dir/file |& _filter_scratch
+
+	echo "# Cleaning up"
+	rm -r $dir
+	_scratch_cycle_mount	# Clear all keys
+	echo
+}
+
+dir=$SCRATCH_MNT/dir
+
+test_with_policy_version 1
+
+test_with_policy_version 2
+
+echo "# Trying to remove absent key"
+_rm_enckey $SCRATCH_MNT abcdabcdabcdabcd
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/800.out b/tests/generic/800.out
new file mode 100644
index 00000000..a4027e2a
--- /dev/null
+++ b/tests/generic/800.out
@@ -0,0 +1,91 @@
+QA output created by 800
+
+# Setting v1 encryption policy
+# Getting v1 encryption policy
+Encryption policy for SCRATCH_MNT/dir:
+	Policy version: 0
+	Master key descriptor: 0000111122223333
+	Contents encryption mode: 1 (AES-256-XTS)
+	Filenames encryption mode: 4 (AES-256-CTS)
+	Flags: 0x02
+# Getting v1 encryption policy using old ioctl
+Encryption policy for SCRATCH_MNT/dir:
+	Policy version: 0
+	Master key descriptor: 0000111122223333
+	Contents encryption mode: 1 (AES-256-XTS)
+	Filenames encryption mode: 4 (AES-256-CTS)
+	Flags: 0x02
+# Trying to create file without key added yet
+SCRATCH_MNT/dir/file: Required key not available
+# Getting encryption key status
+Absent
+# Adding encryption key
+Added encryption key with descriptor 0000111122223333
+# Creating encrypted file
+# Getting encryption key status
+Present
+# Removing encryption key
+Removed encryption key with descriptor 0000111122223333
+# Getting encryption key status
+Absent
+# Verifying that the encrypted directory was "locked"
+cat: SCRATCH_MNT/dir/file: No such file or directory
+Required key not available
+# Re-adding encryption key
+Added encryption key with descriptor 0000111122223333
+# Creating another encrypted file
+# Removing key while an encrypted file is open
+Removed encryption key with descriptor 0000111122223333, but files still busy
+# Non-open file should have been evicted
+cat: SCRATCH_MNT/dir/file2: Required key not available
+# Open file shouldn't have been evicted
+contents
+# Key should be in "incompletely removed" state
+Incompletely removed
+# Closing file and removing key for real now
+Removed encryption key with descriptor 0000111122223333
+cat: SCRATCH_MNT/dir/file: No such file or directory
+# Cleaning up
+
+# Setting v2 encryption policy
+# Getting v2 encryption policy
+Encryption policy for SCRATCH_MNT/dir:
+	Policy version: 2
+	Master key identifier: 69b2f6edeee720cce0577937eb8a6751
+	Contents encryption mode: 1 (AES-256-XTS)
+	Filenames encryption mode: 4 (AES-256-CTS)
+	Flags: 0x02
+# Trying to create file without key added yet
+SCRATCH_MNT/dir/file: Required key not available
+# Getting encryption key status
+Absent
+# Adding encryption key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Creating encrypted file
+# Getting encryption key status
+Present (user_count=1, added_by_self)
+# Removing encryption key
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting encryption key status
+Absent
+# Verifying that the encrypted directory was "locked"
+cat: SCRATCH_MNT/dir/file: No such file or directory
+Required key not available
+# Re-adding encryption key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Creating another encrypted file
+# Removing key while an encrypted file is open
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751, but files still busy
+# Non-open file should have been evicted
+cat: SCRATCH_MNT/dir/file2: Required key not available
+# Open file shouldn't have been evicted
+contents
+# Key should be in "incompletely removed" state
+Incompletely removed
+# Closing file and removing key for real now
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+cat: SCRATCH_MNT/dir/file: No such file or directory
+# Cleaning up
+
+# Trying to remove absent key
+Error removing encryption key: Required key not available
diff --git a/tests/generic/group b/tests/generic/group
index 2e4a6f79..5be46357 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -568,3 +568,4 @@
 563 auto quick
 564 auto quick copy_range
 565 auto quick copy_range
+800 auto quick encrypt
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 6/9] generic: add test for non-root use of fscrypt API additions
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
                   ` (4 preceding siblings ...)
  2019-08-12 17:58 ` [RFC PATCH 5/9] generic: add basic test for fscrypt API additions Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 7/9] generic: verify ciphertext of v2 encryption policies with AES-256 Eric Biggers
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Test non-root use of thte fscrypt filesystem-level encryption keyring
and v2 encryption policies.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 tests/generic/801     | 136 ++++++++++++++++++++++++++++++++++++++++++
 tests/generic/801.out |  62 +++++++++++++++++++
 tests/generic/group   |   1 +
 3 files changed, 199 insertions(+)
 create mode 100755 tests/generic/801
 create mode 100644 tests/generic/801.out

diff --git a/tests/generic/801 b/tests/generic/801
new file mode 100755
index 00000000..dc306315
--- /dev/null
+++ b/tests/generic/801
@@ -0,0 +1,136 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2019 Google LLC
+#
+# FS QA Test generic/801
+#
+# Test non-root use of fscrypt filesystem-level encryption keyring
+# and v2 encryption policies.
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+echo
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+orig_maxkeys=$(</proc/sys/kernel/keys/maxkeys)
+maxkeys=5
+echo $maxkeys > /proc/sys/kernel/keys/maxkeys
+
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+	echo $orig_maxkeys > /proc/sys/kernel/keys/maxkeys
+}
+
+# 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
+_supported_os Linux
+_require_user
+_require_scratch_encryption -v 2
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+dir=$SCRATCH_MNT/dir
+
+raw_key=""
+for i in `seq 64`; do
+	raw_key+="\\x$(printf "%02x" $i)"
+done
+keydesc="0000111122223333"
+keyid="69b2f6edeee720cce0577937eb8a6751"
+chmod 777 $SCRATCH_MNT
+
+_user_do "mkdir $dir"
+
+echo "# Setting v1 policy as regular user (should succeed)"
+_user_do_set_encpolicy $dir $keydesc
+
+echo "# Getting v1 policy as regular user (should succeed)"
+_user_do_get_encpolicy $dir | _filter_scratch
+
+echo "# Adding v1 policy key as regular user (should fail with EACCES)"
+_user_do_add_enckey $SCRATCH_MNT "$raw_key" -d $keydesc
+
+rm -rf $dir
+echo
+_user_do "mkdir $dir"
+
+echo "# Setting v2 policy as regular user without key already added (should fail with ENOKEY)"
+_user_do_set_encpolicy $dir $keyid |& _filter_scratch
+
+echo "# Adding v2 policy key as regular user (should succeed)"
+_user_do_add_enckey $SCRATCH_MNT "$raw_key"
+
+echo "# Setting v2 policy as regular user with key added (should succeed)"
+_user_do_set_encpolicy $dir $keyid
+
+echo "# Getting v2 policy as regular user (should succeed)"
+_user_do_get_encpolicy $dir | _filter_scratch
+
+echo "# Creating encrypted file as regular user (should succeed)"
+_user_do "echo contents > $dir/file"
+
+echo "# Removing v2 policy key as regular user (should succeed)"
+_user_do_rm_enckey $SCRATCH_MNT $keyid
+
+_scratch_cycle_mount	# Clear all keys
+
+echo
+echo "# Testing user key quota"
+for i in `seq $((maxkeys + 1))`; do
+	rand_raw_key=$(_generate_raw_encryption_key)
+	_user_do_add_enckey $SCRATCH_MNT "$rand_raw_key" \
+	    | sed 's/ with identifier .*$//'
+done
+
+rm -rf $dir
+echo
+_user_do "mkdir $dir"
+_scratch_cycle_mount	# Clear all keys
+
+# Test multiple users adding the same key.
+echo "# Adding key as root"
+_add_enckey $SCRATCH_MNT "$raw_key"
+echo "# Getting key status as regular user"
+_user_do_enckey_status $SCRATCH_MNT $keyid
+echo "# Removing key only added by another user (should fail with ENOKEY)"
+_user_do_rm_enckey $SCRATCH_MNT $keyid
+echo "# Setting v2 encryption policy with key only added by another user (should fail with ENOKEY)"
+_user_do_set_encpolicy $dir $keyid |& _filter_scratch
+echo "# Adding second user of key"
+_user_do_add_enckey $SCRATCH_MNT "$raw_key"
+echo "# Getting key status as regular user"
+_user_do_enckey_status $SCRATCH_MNT $keyid
+echo "# Setting v2 encryption policy as regular user"
+_user_do_set_encpolicy $dir $keyid
+echo "# Removing this user's claim to the key"
+_user_do_rm_enckey $SCRATCH_MNT $keyid
+echo "# Getting key status as regular user"
+_user_do_enckey_status $SCRATCH_MNT $keyid
+echo "# Adding back second user of key"
+_user_do_add_enckey $SCRATCH_MNT "$raw_key"
+echo "# Remove key for \"all users\", as regular user (should fail with EACCES)"
+_user_do_rm_enckey $SCRATCH_MNT $keyid -a |& _filter_scratch
+_enckey_status $SCRATCH_MNT $keyid
+echo "# Remove key for \"all users\", as root"
+_rm_enckey $SCRATCH_MNT $keyid -a
+_enckey_status $SCRATCH_MNT $keyid
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/801.out b/tests/generic/801.out
new file mode 100644
index 00000000..b5b6cec8
--- /dev/null
+++ b/tests/generic/801.out
@@ -0,0 +1,62 @@
+QA output created by 801
+
+# Setting v1 policy as regular user (should succeed)
+# Getting v1 policy as regular user (should succeed)
+Encryption policy for SCRATCH_MNT/dir:
+	Policy version: 0
+	Master key descriptor: 0000111122223333
+	Contents encryption mode: 1 (AES-256-XTS)
+	Filenames encryption mode: 4 (AES-256-CTS)
+	Flags: 0x02
+# Adding v1 policy key as regular user (should fail with EACCES)
+Permission denied
+
+# Setting v2 policy as regular user without key already added (should fail with ENOKEY)
+SCRATCH_MNT/dir: failed to set encryption policy: Required key not available
+# Adding v2 policy key as regular user (should succeed)
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Setting v2 policy as regular user with key added (should succeed)
+# Getting v2 policy as regular user (should succeed)
+Encryption policy for SCRATCH_MNT/dir:
+	Policy version: 2
+	Master key identifier: 69b2f6edeee720cce0577937eb8a6751
+	Contents encryption mode: 1 (AES-256-XTS)
+	Filenames encryption mode: 4 (AES-256-CTS)
+	Flags: 0x02
+# Creating encrypted file as regular user (should succeed)
+# Removing v2 policy key as regular user (should succeed)
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+
+# Testing user key quota
+Added encryption key
+Added encryption key
+Added encryption key
+Added encryption key
+Added encryption key
+Error adding encryption key: Disk quota exceeded
+
+# Adding key as root
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting key status as regular user
+Present (user_count=1)
+# Removing key only added by another user (should fail with ENOKEY)
+Error removing encryption key: Required key not available
+# Setting v2 encryption policy with key only added by another user (should fail with ENOKEY)
+SCRATCH_MNT/dir: failed to set encryption policy: Required key not available
+# Adding second user of key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting key status as regular user
+Present (user_count=2, added_by_self)
+# Setting v2 encryption policy as regular user
+# Removing this user's claim to the key
+Removed user's claim to encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Getting key status as regular user
+Present (user_count=1)
+# Adding back second user of key
+Added encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+# Remove key for "all users", as regular user (should fail with EACCES)
+Permission denied
+Present (user_count=2, added_by_self)
+# Remove key for "all users", as root
+Removed encryption key with identifier 69b2f6edeee720cce0577937eb8a6751
+Absent
diff --git a/tests/generic/group b/tests/generic/group
index 5be46357..4bc4772a 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -569,3 +569,4 @@
 564 auto quick copy_range
 565 auto quick copy_range
 800 auto quick encrypt
+801 auto quick encrypt
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 7/9] generic: verify ciphertext of v2 encryption policies with AES-256
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
                   ` (5 preceding siblings ...)
  2019-08-12 17:58 ` [RFC PATCH 6/9] generic: add test for non-root use of " Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 8/9] generic: verify ciphertext of v2 encryption policies with AES-128 Eric Biggers
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Verify ciphertext for v2 encryption policies that use AES-256-XTS to
encrypt file contents and AES-256-CTS-CBC to encrypt file names.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 tests/generic/802     | 43 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/802.out |  6 ++++++
 tests/generic/group   |  1 +
 3 files changed, 50 insertions(+)
 create mode 100755 tests/generic/802
 create mode 100644 tests/generic/802.out

diff --git a/tests/generic/802 b/tests/generic/802
new file mode 100755
index 00000000..457260b2
--- /dev/null
+++ b/tests/generic/802
@@ -0,0 +1,43 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2019 Google LLC
+#
+# FS QA Test generic/802
+#
+# Verify ciphertext for v2 encryption policies that use AES-256-XTS to encrypt
+# file contents and AES-256-CTS-CBC to encrypt file names.
+#
+# This is the same as generic/548, except using v2 policies.
+#
+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
+_supported_os Linux
+
+_verify_ciphertext_for_encryption_policy AES-256-XTS AES-256-CTS-CBC v2
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/802.out b/tests/generic/802.out
new file mode 100644
index 00000000..c0930809
--- /dev/null
+++ b/tests/generic/802.out
@@ -0,0 +1,6 @@
+QA output created by 802
+
+Verifying ciphertext with parameters:
+	contents_encryption_mode: AES-256-XTS
+	filenames_encryption_mode: AES-256-CTS-CBC
+	options: v2
diff --git a/tests/generic/group b/tests/generic/group
index 4bc4772a..29c9af30 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -570,3 +570,4 @@
 565 auto quick copy_range
 800 auto quick encrypt
 801 auto quick encrypt
+802 auto quick encrypt
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 8/9] generic: verify ciphertext of v2 encryption policies with AES-128
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
                   ` (6 preceding siblings ...)
  2019-08-12 17:58 ` [RFC PATCH 7/9] generic: verify ciphertext of v2 encryption policies with AES-256 Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-08-12 17:58 ` [RFC PATCH 9/9] generic: verify ciphertext of v2 encryption policies with Adiantum Eric Biggers
  2019-09-01 12:29 ` [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eryu Guan
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Verify ciphertext for v2 encryption policies that use AES-128-CBC-ESSIV
to encrypt file contents and AES-128-CTS-CBC to encrypt file names.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 tests/generic/803     | 43 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/803.out |  6 ++++++
 tests/generic/group   |  1 +
 3 files changed, 50 insertions(+)
 create mode 100755 tests/generic/803
 create mode 100644 tests/generic/803.out

diff --git a/tests/generic/803 b/tests/generic/803
new file mode 100755
index 00000000..c12daeff
--- /dev/null
+++ b/tests/generic/803
@@ -0,0 +1,43 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2019 Google LLC
+#
+# FS QA Test generic/803
+#
+# Verify ciphertext for v2 encryption policies that use AES-128-CBC-ESSIV to
+# encrypt file contents and AES-128-CTS-CBC to encrypt file names.
+#
+# This is the same as generic/549, except using v2 policies.
+#
+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
+_supported_os Linux
+
+_verify_ciphertext_for_encryption_policy AES-128-CBC-ESSIV AES-128-CTS-CBC v2
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/803.out b/tests/generic/803.out
new file mode 100644
index 00000000..f4051d27
--- /dev/null
+++ b/tests/generic/803.out
@@ -0,0 +1,6 @@
+QA output created by 803
+
+Verifying ciphertext with parameters:
+	contents_encryption_mode: AES-128-CBC-ESSIV
+	filenames_encryption_mode: AES-128-CTS-CBC
+	options: v2
diff --git a/tests/generic/group b/tests/generic/group
index 29c9af30..6deae98f 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -571,3 +571,4 @@
 800 auto quick encrypt
 801 auto quick encrypt
 802 auto quick encrypt
+803 auto quick encrypt
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RFC PATCH 9/9] generic: verify ciphertext of v2 encryption policies with Adiantum
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
                   ` (7 preceding siblings ...)
  2019-08-12 17:58 ` [RFC PATCH 8/9] generic: verify ciphertext of v2 encryption policies with AES-128 Eric Biggers
@ 2019-08-12 17:58 ` Eric Biggers
  2019-09-01 12:29 ` [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eryu Guan
  9 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2019-08-12 17:58 UTC (permalink / raw)
  To: fstests; +Cc: linux-fscrypt

From: Eric Biggers <ebiggers@google.com>

Verify ciphertext for v2 encryption policies that use Adiantum to
encrypt file contents and file names.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 tests/generic/804     | 45 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/804.out | 11 +++++++++++
 tests/generic/group   |  1 +
 3 files changed, 57 insertions(+)
 create mode 100755 tests/generic/804
 create mode 100644 tests/generic/804.out

diff --git a/tests/generic/804 b/tests/generic/804
new file mode 100755
index 00000000..72e7b025
--- /dev/null
+++ b/tests/generic/804
@@ -0,0 +1,45 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2019 Google LLC
+#
+# FS QA Test generic/804
+#
+# Verify ciphertext for v2 encryption policies that use Adiantum to encrypt file
+# contents and file names.
+#
+# This is the same as generic/550, except using v2 policies.
+#
+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
+_supported_os Linux
+
+# Test both with and without the DIRECT_KEY flag.
+_verify_ciphertext_for_encryption_policy Adiantum Adiantum v2
+_verify_ciphertext_for_encryption_policy Adiantum Adiantum v2 direct
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/804.out b/tests/generic/804.out
new file mode 100644
index 00000000..726376b2
--- /dev/null
+++ b/tests/generic/804.out
@@ -0,0 +1,11 @@
+QA output created by 804
+
+Verifying ciphertext with parameters:
+	contents_encryption_mode: Adiantum
+	filenames_encryption_mode: Adiantum
+	options: v2
+
+Verifying ciphertext with parameters:
+	contents_encryption_mode: Adiantum
+	filenames_encryption_mode: Adiantum
+	options: v2 direct
diff --git a/tests/generic/group b/tests/generic/group
index 6deae98f..c73ad0d9 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -572,3 +572,4 @@
 801 auto quick encrypt
 802 auto quick encrypt
 803 auto quick encrypt
+804 auto quick encrypt
-- 
2.23.0.rc1.153.gdeed80330f-goog

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 3/9] common/encrypt: support checking for v2 encryption policy support
  2019-08-12 17:58 ` [RFC PATCH 3/9] common/encrypt: support checking for v2 encryption policy support Eric Biggers
@ 2019-09-01 12:08   ` Eryu Guan
  0 siblings, 0 replies; 12+ messages in thread
From: Eryu Guan @ 2019-09-01 12:08 UTC (permalink / raw)
  To: Eric Biggers; +Cc: fstests, linux-fscrypt

On Mon, Aug 12, 2019 at 10:58:03AM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Allow passing '-v 2' to _require_scratch_encryption() to check for v2
> encryption policy support on the scratch device, and for xfs_io support
> for setting and getting v2 encryption policies.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>
> ---
>  common/encrypt | 41 +++++++++++++++++++++++++++++++----------
>  1 file changed, 31 insertions(+), 10 deletions(-)
> 
> diff --git a/common/encrypt b/common/encrypt
> index a086e80f..fa6e2672 100644
> --- a/common/encrypt
> +++ b/common/encrypt
> @@ -6,12 +6,13 @@
>  
>  #
>  # _require_scratch_encryption [-c CONTENTS_MODE] [-n FILENAMES_MODE]
> +#			      [-v POLICY_VERSION]
>  #
>  # Require encryption support on the scratch device.
>  #
> -# This checks for support for the default type of encryption policy (AES-256-XTS
> -# and AES-256-CTS).  Options can be specified to also require support for a
> -# different type of encryption policy.
> +# This checks for support for the default type of encryption policy (v1 with
> +# AES-256-XTS and AES-256-CTS).  Options can be specified to also require
> +# support for a different type of encryption policy.
>  #
>  _require_scratch_encryption()
>  {
> @@ -68,13 +69,15 @@ _require_encryption_policy_support()
>  	local mnt=$1
>  	local dir=$mnt/tmpdir
>  	local set_encpolicy_args=""
> +	local policy_version=1
>  	local c
>  
>  	OPTIND=2
> -	while getopts "c:n:" c; do
> +	while getopts "c:n:v:" c; do
>  		case $c in
> -		c|n)
> +		c|n|v)
>  			set_encpolicy_args+=" -$c $OPTARG"
> +			[ $c = v ] && policy_version=$OPTARG

Why not checking 'v' in a separate case?

>  			;;
>  		*)
>  			_fail "Unrecognized option '$c'"
> @@ -87,10 +90,26 @@ _require_encryption_policy_support()
>  		>> $seqres.full
>  
>  	mkdir $dir
> -	_require_command "$KEYCTL_PROG" keyctl
> -	_new_session_keyring
> -	local keydesc=$(_generate_session_encryption_key)
> -	if _set_encpolicy $dir $keydesc $set_encpolicy_args \
> +	if (( policy_version > 1 )); then
> +		_require_xfs_io_command "get_encpolicy" "-t"
> +		local output=$(_get_encpolicy $dir -t)
> +		if [ "$output" != "supported" ]; then
> +			if [ "$output" = "unsupported" ]; then
> +				_notrun "kernel does not support $FSTYP encryption v2 API"
> +			fi
> +			_fail "Unexpected output from 'get_encpolicy -t'"

Print $output in the _fail message as well?

Thanks,
Eryu

> +		fi
> +		# Both the kernel and xfs_io support v2 encryption policies, and
> +		# therefore also filesystem-level keys -- since that's the only
> +		# way to provide keys for v2 policies.
> +		local raw_key=$(_generate_raw_encryption_key)
> +		local keyspec=$(_add_enckey $mnt "$raw_key" | awk '{print $NF}')
> +	else
> +		_require_command "$KEYCTL_PROG" keyctl
> +		_new_session_keyring
> +		local keyspec=$(_generate_session_encryption_key)
> +	fi
> +	if _set_encpolicy $dir $keyspec $set_encpolicy_args \
>  		2>&1 >>$seqres.full | egrep -q 'Invalid argument'; then
>  		_notrun "kernel does not support encryption policy: '$set_encpolicy_args'"
>  	fi
> @@ -103,7 +122,9 @@ _require_encryption_policy_support()
>  	if ! echo foo > $dir/file; then
>  		_notrun "encryption policy '$set_encpolicy_args' is unusable; probably missing kernel crypto API support"
>  	fi
> -	$KEYCTL_PROG clear @s
> +	if (( policy_version <= 1 )); then
> +		$KEYCTL_PROG clear @s
> +	fi
>  	rm -r $dir
>  }
>  
> -- 
> 2.23.0.rc1.153.gdeed80330f-goog
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements
  2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
                   ` (8 preceding siblings ...)
  2019-08-12 17:58 ` [RFC PATCH 9/9] generic: verify ciphertext of v2 encryption policies with Adiantum Eric Biggers
@ 2019-09-01 12:29 ` Eryu Guan
  9 siblings, 0 replies; 12+ messages in thread
From: Eryu Guan @ 2019-09-01 12:29 UTC (permalink / raw)
  To: Eric Biggers; +Cc: fstests, linux-fscrypt

On Mon, Aug 12, 2019 at 10:58:00AM -0700, Eric Biggers wrote:
> Hello,
> 
> This patchset adds xfstests for the kernel patchset
> "[PATCH v8 00/20] fscrypt: key management improvements"
> https://lkml.kernel.org/linux-fsdevel/20190805162521.90882-1-ebiggers@kernel.org/T/#u
> 
> These tests test the new ioctls for managing filesystem encryption keys,
> and they test the new encryption policy version.
> 
> These tests depend on new xfs_io commands, for which I've sent a
> separate patchset for xfsprogs.
> 
> Note: currently only ext4, f2fs, and ubifs support encryption.  But I
> was told previously that since the fscrypt API is generic and may be
> supported by XFS in the future, the command-line wrappers for the
> fscrypt ioctls should be in xfs_io rather than in fstests directly
> (https://marc.info/?l=fstests&m=147976255831951&w=2).
> 
> We'll want to wait for the kernel patches to be mainlined before merging
> this, but I'm making it available now for any early feedback.
> 
> This version of the xfstests patchset can also be retrieved from tag
> "fscrypt-key-mgmt-improvements_2019-08-12" of
> https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/xfstests-dev.git

Sorry for getting so long to review this patchset. The patches all look
in a good shape to me, thanks a lot! Please see the reply to patch "3/9"
for the only minor issues I noticed.

But it'd be really helpful if other fscrypt folks could help review the
new tests!

Thanks,
Eryu

> 
> Eric Biggers (9):
>   common/encrypt: disambiguate session encryption keys
>   common/encrypt: add helper functions that wrap new xfs_io commands
>   common/encrypt: support checking for v2 encryption policy support
>   common/encrypt: support verifying ciphertext of v2 encryption policies
>   generic: add basic test for fscrypt API additions
>   generic: add test for non-root use of fscrypt API additions
>   generic: verify ciphertext of v2 encryption policies with AES-256
>   generic: verify ciphertext of v2 encryption policies with AES-128
>   generic: verify ciphertext of v2 encryption policies with Adiantum
> 
>  common/encrypt           | 180 +++++++++++++++++++----
>  src/fscrypt-crypt-util.c | 304 ++++++++++++++++++++++++++++++++++-----
>  tests/ext4/024           |   2 +-
>  tests/generic/397        |   4 +-
>  tests/generic/398        |   8 +-
>  tests/generic/399        |   4 +-
>  tests/generic/419        |   4 +-
>  tests/generic/421        |   4 +-
>  tests/generic/429        |   8 +-
>  tests/generic/435        |   4 +-
>  tests/generic/440        |   8 +-
>  tests/generic/800        | 127 ++++++++++++++++
>  tests/generic/800.out    |  91 ++++++++++++
>  tests/generic/801        | 136 ++++++++++++++++++
>  tests/generic/801.out    |  62 ++++++++
>  tests/generic/802        |  43 ++++++
>  tests/generic/802.out    |   6 +
>  tests/generic/803        |  43 ++++++
>  tests/generic/803.out    |   6 +
>  tests/generic/804        |  45 ++++++
>  tests/generic/804.out    |  11 ++
>  tests/generic/group      |   5 +
>  22 files changed, 1018 insertions(+), 87 deletions(-)
>  create mode 100755 tests/generic/800
>  create mode 100644 tests/generic/800.out
>  create mode 100755 tests/generic/801
>  create mode 100644 tests/generic/801.out
>  create mode 100755 tests/generic/802
>  create mode 100644 tests/generic/802.out
>  create mode 100755 tests/generic/803
>  create mode 100644 tests/generic/803.out
>  create mode 100755 tests/generic/804
>  create mode 100644 tests/generic/804.out
> 
> -- 
> 2.23.0.rc1.153.gdeed80330f-goog
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-09-01 12:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-12 17:58 [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 1/9] common/encrypt: disambiguate session encryption keys Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 2/9] common/encrypt: add helper functions that wrap new xfs_io commands Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 3/9] common/encrypt: support checking for v2 encryption policy support Eric Biggers
2019-09-01 12:08   ` Eryu Guan
2019-08-12 17:58 ` [RFC PATCH 4/9] common/encrypt: support verifying ciphertext of v2 encryption policies Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 5/9] generic: add basic test for fscrypt API additions Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 6/9] generic: add test for non-root use of " Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 7/9] generic: verify ciphertext of v2 encryption policies with AES-256 Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 8/9] generic: verify ciphertext of v2 encryption policies with AES-128 Eric Biggers
2019-08-12 17:58 ` [RFC PATCH 9/9] generic: verify ciphertext of v2 encryption policies with Adiantum Eric Biggers
2019-09-01 12:29 ` [RFC PATCH 0/9] xfstests: add tests for fscrypt key management improvements Eryu Guan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).