public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] fstests: add btrfs encryption support
@ 2022-08-17 14:45 Sweet Tea Dorminy
  2022-08-17 14:45 ` [PATCH 1/2] fstests: fscrypt: enable btrfs testing Sweet Tea Dorminy
  2022-08-17 14:45 ` [PATCH 2/2] fstests: fscrypt: update tests of encryption contents for btrfs Sweet Tea Dorminy
  0 siblings, 2 replies; 4+ messages in thread
From: Sweet Tea Dorminy @ 2022-08-17 14:45 UTC (permalink / raw)
  To: fstests, linux-fscrypt, linux-btrfs, kernel-team; +Cc: Sweet Tea Dorminy

This changeset is in combination with a kernel changeset implementing
btrfs encryption, and a btrfs-progs changeset 

btrfs has several differences from other filesystems currently
integrated with fscrypt. It stores IVs on a per-file-extent basis,
rather than per-inode, using a new v2 policy to do so; and requires the
use of a v2 policy and its IV_FROM_FS policy flag. The design document
can be found at [1].

As such, this adjusts many tests to explicitly require v1 policies if
they require it, and generalizes the key handling for tests which can
work fine with v2. It duplicates two generic tests which can't easily be
generalized to work with btrfs, and adds all necessary function
invocations to implement the ciphertext-checking functions.

There are definitely additional areas which deserve testing. There are
some tests which ought be split into v1-specific and v2-specific tests
so that btrfs can work on the v2 part. A key feature for btrfs is
subvolume encryption, and tests for that should be added.
 
Necessary btrfs-progs changes are available at [2]; kernel changes
are available at [3]. Additional tests around subvolume-level encryption
will be added in the next version. 

[1]
https://lore.kernel.org/linux-btrfs/YXGyq+buM79A1S0L@relinquished.localdomain/
[2] https://lore.kernel.org/linux-btrfs/cover.1660729916.git.sweettea-kernel@dorminy.me
[3] https://lore.kernel.org/linux-btrfs/cover.1660744500.git.sweettea-kernel@dorminy.me

Sweet Tea Dorminy (2):
  fstests: fscrypt: enable btrfs testing.
  fstests: fscrypt: update tests of encryption contents for btrfs

 common/encrypt           | 184 +++++++++++++++++++++++++++++++++++++--
 common/verity            |   2 +-
 src/fscrypt-crypt-util.c |  34 +++++++-
 tests/btrfs/298          |  85 ++++++++++++++++++
 tests/btrfs/298.out      |  34 ++++++++
 tests/btrfs/299          |  68 +++++++++++++++
 tests/btrfs/299.out      |   4 +
 tests/generic/395        |   2 +-
 tests/generic/397        |   8 +-
 tests/generic/398        |  12 +--
 tests/generic/399        |   7 +-
 tests/generic/419        |   7 +-
 tests/generic/421        |   7 +-
 tests/generic/429        |   2 +-
 tests/generic/435        |   2 +-
 tests/generic/440        |   2 +-
 tests/generic/576        |   8 +-
 tests/generic/580        |   1 +
 tests/generic/581        |   1 +
 tests/generic/593        |   1 +
 tests/generic/613        |   1 +
 21 files changed, 439 insertions(+), 33 deletions(-)
 create mode 100755 tests/btrfs/298
 create mode 100644 tests/btrfs/298.out
 create mode 100755 tests/btrfs/299
 create mode 100644 tests/btrfs/299.out

-- 
2.35.1


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

* [PATCH 1/2] fstests: fscrypt: enable btrfs testing.
  2022-08-17 14:45 [PATCH 0/2] fstests: add btrfs encryption support Sweet Tea Dorminy
@ 2022-08-17 14:45 ` Sweet Tea Dorminy
  2022-08-17 14:45 ` [PATCH 2/2] fstests: fscrypt: update tests of encryption contents for btrfs Sweet Tea Dorminy
  1 sibling, 0 replies; 4+ messages in thread
From: Sweet Tea Dorminy @ 2022-08-17 14:45 UTC (permalink / raw)
  To: fstests, linux-fscrypt, linux-btrfs, kernel-team; +Cc: Sweet Tea Dorminy

btrfs' fscrypt integration has more stringent requirements than other
filesystems using fscrypt: only v2 policies are permitted, and v2
policies must use the FSCRYPT_FLAG_IV_FROM_FS flag. This makes most
existing fscrypt tests fail, as they use v1 policies.

To make at least a few pass, this adds several common pieces:
- _set_encpolicy tries to automatically add -v 2 and -f 32 for btrfs,
  if no explicit -v and -f (respectively) option is set
- _require_scratch_encryption updates default policy version for btrfs,
  and checks that only the relevant flag is set
- _scratch_mkfs_sized_encrypted can deal with btrfs

These pieces are used in tests to make most generic tests work with
btrfs, although some tests of both v1 and v2 policies still need to be
split.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 common/encrypt      | 117 +++++++++++++++++++++++++++++++++++++++++++-
 common/verity       |   2 +-
 tests/btrfs/298     |  85 ++++++++++++++++++++++++++++++++
 tests/btrfs/298.out |  34 +++++++++++++
 tests/btrfs/299     |  68 +++++++++++++++++++++++++
 tests/btrfs/299.out |   4 ++
 tests/generic/395   |   2 +-
 tests/generic/397   |   8 +--
 tests/generic/398   |  12 +++--
 tests/generic/399   |   7 +--
 tests/generic/419   |   7 +--
 tests/generic/421   |   7 +--
 tests/generic/429   |   2 +-
 tests/generic/435   |   2 +-
 tests/generic/440   |   2 +-
 tests/generic/576   |   7 +--
 tests/generic/580   |   1 +
 tests/generic/581   |   1 +
 tests/generic/593   |   1 +
 tests/generic/613   |   1 +
 20 files changed, 344 insertions(+), 26 deletions(-)
 create mode 100755 tests/btrfs/298
 create mode 100644 tests/btrfs/298.out
 create mode 100755 tests/btrfs/299
 create mode 100644 tests/btrfs/299.out

diff --git a/common/encrypt b/common/encrypt
index 8f3c46f6..b011c3e8 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -73,6 +73,10 @@ _require_encryption_policy_support()
 	local policy_version=1
 	local c
 
+	if [ "$FSTYP" = "btrfs" ]; then
+		policy_version=2
+	fi
+
 	OPTIND=2
 	while getopts "c:n:f:v:" c; do
 		case $c in
@@ -102,6 +106,12 @@ _require_encryption_policy_support()
 		_scratch_unmount
 		_scratch_mkfs_stable_inodes_encrypted &>> $seqres.full
 		_scratch_mount
+	fi;
+
+	if [ "$FSTYP" = "btrfs" ]; then
+		if (( policy_flags & ~FSCRYPT_POLICY_FLAG_IV_FROM_FS )); then
+			_fail "Btrfs accepts policy flags of IV_FROM_FS only"
+		fi
 	fi
 
 	mkdir $dir
@@ -146,7 +156,7 @@ _require_encryption_policy_support()
 _scratch_mkfs_encrypted()
 {
 	case $FSTYP in
-	ext4|f2fs)
+	btrfs|ext4|f2fs)
 		_scratch_mkfs -O encrypt
 		;;
 	ubifs)
@@ -165,6 +175,9 @@ _scratch_mkfs_sized_encrypted()
 	ext4|f2fs)
 		MKFS_OPTIONS="$MKFS_OPTIONS -O encrypt" _scratch_mkfs_sized $*
 		;;
+	btrfs)
+		_scratch_mkfs_sized $*
+		;;
 	*)
 		_notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized_encrypted"
 		;;
@@ -225,6 +238,57 @@ _check_session_keyring()
 	fi
 }
 
+# Set up to use default-policy keys.
+_initialize_default_policy()
+{
+	if ! [ "$FSTYP" = "btrfs" ]; then
+		_init_session_keyring
+	fi
+}
+
+# Add a key with the default-policy.
+_add_default_policy_key()
+{
+	if [ "$FSTYP" = "btrfs" ]; then
+		_add_enckey $SCRATCH_MNT "$*" | awk '{print $NF}'
+	else
+		local keydesc=$(_generate_key_descriptor)
+		_add_session_encryption_key $keydesc $*
+		echo $keydesc
+	fi
+}
+
+# Unlink a default-type key
+_unlink_default_policy_key()
+{
+	if [ "$FSTYP" = "btrfs" ]; then
+		_rm_enckey $SCRATCH_MNT $*
+	else
+		_unlink_session_encryption_key $*
+	fi
+}
+
+# Revoke a default-type key
+_revoke_default_policy_key()
+{
+	if [ "$FSTYP" = "btrfs" ]; then
+		_rm_enckey $SCRATCH_MNT $*
+	else
+		_revoke_session_encryption_key $*
+	fi
+}
+
+# Give the invoking shell a new session keyring.  This makes any keys we add to
+# the session keyring scoped to the lifetime of the test script.
+_new_session_keyring()
+{
+	if [ "$FSTYP" = "btrfs" ]; then
+		_notrun "not suitable for this filesystem type: btrfs"
+	fi
+
+	$KEYCTL_PROG new_session >>$seqres.full
+}
+
 # Generate a key descriptor (16 character hex string)
 _generate_key_descriptor()
 {
@@ -357,6 +421,19 @@ _set_encpolicy()
 	local dir=$1
 	shift
 
+	if [ "$FSTYP" = "btrfs" ]; then
+		# Append -v 2 and the necessary IV_FROM_FS flag if -v or -f
+		# isn't set.
+		if ! [[ "$*" =~ -v ]]; then
+			set -- "$* -v 2"
+		fi
+
+		versionmatcher="-v 2"
+		if [[ "$*" =~ $versionmatcher ]] && ! [[ "$*" =~ -f ]]; then
+			set -- "$* -f 32"
+		fi
+	fi
+
 	$XFS_IO_PROG -c "set_encpolicy $*" "$dir"
 }
 
@@ -364,6 +441,18 @@ _user_do_set_encpolicy()
 {
 	local dir=$1
 	shift
+	if [ "$FSTYP" = "btrfs" ]; then
+		# Append -v 2 and the necessary IV_FROM_FS flag if -v or -f
+		# isn't set.
+		if ! [[ "$*" =~ -v ]]; then
+			set -- "$* -v 2"
+		fi
+
+		versionmatcher="-v 2"
+		if [[ "$*" =~ $versionmatcher ]] && ! [[ "$*" =~ -f ]]; then
+			set -- "$* -f 32"
+		fi
+	fi
 
 	_user_do "$XFS_IO_PROG -c \"set_encpolicy $*\" \"$dir\""
 }
@@ -491,6 +580,18 @@ _get_encryption_nonce()
 	local inode=$2
 
 	case $FSTYP in
+	btrfs)
+		# btrfs prints the fscrypt_context like:
+		#
+		# item 18 key (258 FSCRYPT_CTXT_ITEM 0) itemoff 15218 itemsize 40
+		#	value: 0201042000000000000000000000000000000000000000007907c9718128b82caebfa42e881b0163
+		#
+		$BTRFS_UTIL_PROG inspect-internal dump-tree $device | \
+			grep -A 1 "key ($inode FSCRYPT_CTXT_ITEM 0)" | \
+			awk '/value: [[:xdigit:]]+$/ {
+				print substr($0, length($0) - 31, 32);
+			}'
+		;;
 	ext4)
 		# Use debugfs to dump the special xattr named "c", which is the
 		# file's fscrypt_context.  This produces a line like:
@@ -539,6 +640,9 @@ _require_get_encryption_nonce_support()
 {
 	echo "Checking for _get_encryption_nonce() support for $FSTYP" >> $seqres.full
 	case $FSTYP in
+	btrfs)
+		_require_command "$BTRFS_UTIL_PROG" btrfs
+		;;
 	ext4)
 		_require_command "$DEBUGFS_PROG" debugfs
 		;;
@@ -810,6 +914,7 @@ FSCRYPT_MODE_ADIANTUM=9
 FSCRYPT_POLICY_FLAG_DIRECT_KEY=0x04
 FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64=0x08
 FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32=0x10
+FSCRYPT_POLICY_FLAG_IV_FROM_FS=0x20
 
 FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR=1
 FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER=2
@@ -853,6 +958,10 @@ _verify_ciphertext_for_encryption_policy()
 	local crypt_util_filename_args=""
 	local expected_identifier
 
+	if [ "$FSTYP" = "btrfs" ]; then
+		policy_version = 2
+	fi
+	
 	shift 2
 	for opt; do
 		case "$opt" in
@@ -888,6 +997,12 @@ _verify_ciphertext_for_encryption_policy()
 	if (( policy_version > 1 )); then
 		set_encpolicy_args+=" -v 2"
 		crypt_util_args+=" --kdf=HKDF-SHA512"
+		if [ "$FSTYP" = "btrfs" ]; then
+			if (( policy_flags & ~FSCRYPT_POLICY_FLAG_IV_FROM_FS )); then
+				_fail "Btrfs accepts policy flags of IV_FROM_FS only"
+			fi	
+			policy_flags |= FSCRYPT_POLICY_FLAG_IV_FROM_FS
+		fi
 		if (( policy_flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY )); then
 			crypt_util_args+=" --direct-key"
 		elif (( policy_flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 )); then
diff --git a/common/verity b/common/verity
index cb7fa333..82a4ff90 100644
--- a/common/verity
+++ b/common/verity
@@ -178,7 +178,7 @@ _scratch_mkfs_verity()
 _scratch_mkfs_encrypted_verity()
 {
 	case $FSTYP in
-	ext4)
+	ext4|btrfs)
 		_scratch_mkfs -O encrypt,verity
 		;;
 	f2fs)
diff --git a/tests/btrfs/298 b/tests/btrfs/298
new file mode 100755
index 00000000..2b03148e
--- /dev/null
+++ b/tests/btrfs/298
@@ -0,0 +1,85 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2016 Google, Inc.  All Rights Reserved.
+#
+# FS QA Test No. 298
+#
+# Test setting and getting encryption policies. Like generic/395, but allows
+# setting encryption policy on a nonempty directory.
+#
+. ./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
+_require_xfs_io_command "get_encpolicy"
+_require_user
+
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+
+# Should be able to set an encryption policy on an empty directory
+empty_dir=$SCRATCH_MNT/empty_dir
+echo -e "\n*** Setting encryption policy on empty directory ***"
+mkdir $empty_dir
+_get_encpolicy $empty_dir |& _filter_scratch
+_set_encpolicy $empty_dir 0000111122223333
+_get_encpolicy $empty_dir | _filter_scratch
+
+# Should be able to set the same policy again, but not a different one.
+echo -e "\n*** Setting encryption policy again ***"
+_set_encpolicy $empty_dir 0000111122223333
+_get_encpolicy $empty_dir | _filter_scratch
+_set_encpolicy $empty_dir 4444555566667777 |& _filter_scratch
+_get_encpolicy $empty_dir | _filter_scratch
+
+# Should be able to set an encryption policy on a nonempty directory
+nonempty_dir=$SCRATCH_MNT/nonempty_dir
+echo -e "\n*** Setting encryption policy on nonempty directory ***"
+mkdir $nonempty_dir
+touch $nonempty_dir/file
+_set_encpolicy $nonempty_dir |& _filter_scratch
+_get_encpolicy $nonempty_dir |& _filter_scratch
+
+# Should *not* be able to set an encryption policy on a nondirectory file, even
+# an empty one.  Regression test for 002ced4be642: "fscrypto: only allow setting
+# encryption policy on directories".
+nondirectory=$SCRATCH_MNT/nondirectory
+echo -e "\n*** Setting encryption policy on nondirectory ***"
+touch $nondirectory
+_set_encpolicy $nondirectory |& _filter_scratch
+_get_encpolicy $nondirectory |& _filter_scratch
+
+# Should *not* be able to set an encryption policy on another user's directory.
+# Regression test for 163ae1c6ad62: "fscrypto: add authorization check for
+# setting encryption policy".
+unauthorized_dir=$SCRATCH_MNT/unauthorized_dir
+echo -e "\n*** Setting encryption policy on another user's directory ***"
+mkdir $unauthorized_dir
+_user_do_set_encpolicy $unauthorized_dir |& _filter_scratch
+_get_encpolicy $unauthorized_dir |& _filter_scratch
+
+# Should *not* be able to set an encryption policy on a directory on a
+# filesystem mounted readonly.  Regression test for ba63f23d69a3: "fscrypto:
+# require write access to mount to set encryption policy".  Test both a regular
+# readonly filesystem and a readonly bind mount of a read-write filesystem.
+echo -e "\n*** Setting encryption policy on readonly filesystem ***"
+mkdir $SCRATCH_MNT/ro_dir $SCRATCH_MNT/ro_bind_mnt
+_scratch_remount ro
+_set_encpolicy $SCRATCH_MNT/ro_dir |& _filter_scratch
+_get_encpolicy $SCRATCH_MNT/ro_dir |& _filter_scratch
+_scratch_remount rw
+mount --bind $SCRATCH_MNT $SCRATCH_MNT/ro_bind_mnt
+mount -o remount,ro,bind $SCRATCH_MNT/ro_bind_mnt
+_set_encpolicy $SCRATCH_MNT/ro_bind_mnt/ro_dir |& _filter_scratch
+_get_encpolicy $SCRATCH_MNT/ro_bind_mnt/ro_dir |& _filter_scratch
+umount $SCRATCH_MNT/ro_bind_mnt
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/298.out b/tests/btrfs/298.out
new file mode 100644
index 00000000..15069749
--- /dev/null
+++ b/tests/btrfs/298.out
@@ -0,0 +1,34 @@
+QA output created by 298
+
+*** Setting encryption policy on empty directory ***
+SCRATCH_MNT/empty_dir: failed to get encryption policy: No data available
+invalid key identifier: 0000111122223333
+/mnt/scratch/empty_dir: failed to get encryption policy: No data available
+
+*** Setting encryption policy again ***
+invalid key identifier: 0000111122223333
+/mnt/scratch/empty_dir: failed to get encryption policy: No data available
+invalid key identifier: 4444555566667777
+/mnt/scratch/empty_dir: failed to get encryption policy: No data available
+
+*** Setting encryption policy on nonempty directory ***
+Encryption policy for SCRATCH_MNT/nonempty_dir:
+	Policy version: 2
+	Master key identifier: 00000000000000000000000000000000
+	Contents encryption mode: 1 (AES-256-XTS)
+	Filenames encryption mode: 4 (AES-256-CTS)
+	Flags: 0x20
+
+*** Setting encryption policy on nondirectory ***
+SCRATCH_MNT/nondirectory: failed to set encryption policy: Not a directory
+SCRATCH_MNT/nondirectory: failed to get encryption policy: No data available
+
+*** Setting encryption policy on another user's directory ***
+Permission denied
+SCRATCH_MNT/unauthorized_dir: failed to get encryption policy: No data available
+
+*** Setting encryption policy on readonly filesystem ***
+SCRATCH_MNT/ro_dir: failed to set encryption policy: Read-only file system
+SCRATCH_MNT/ro_dir: failed to get encryption policy: No data available
+SCRATCH_MNT/ro_bind_mnt/ro_dir: failed to set encryption policy: Read-only file system
+SCRATCH_MNT/ro_bind_mnt/ro_dir: failed to get encryption policy: No data available
diff --git a/tests/btrfs/299 b/tests/btrfs/299
new file mode 100755
index 00000000..d9fde898
--- /dev/null
+++ b/tests/btrfs/299
@@ -0,0 +1,68 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2017 Google, Inc.  All Rights Reserved.
+#
+# FS QA Test No. 299
+#
+# Test that without the encryption key for a directory, long filenames are
+# presented in a way which avoids collisions, even though they are abbreviated
+# in order to support names up to NAME_MAX bytes.
+#
+# Regression test for:
+#	6332cd32c829 ("f2fs: check entire encrypted bigname when finding a dentry")
+#	6b06cdee81d6 ("fscrypt: avoid collisions when presenting long encrypted filenames")
+#
+# Even with these two fixes it's still possible to create intentional
+# collisions.  For now this test covers "accidental" collisions only.
+#
+# Based on generic/435.
+#
+. ./common/preamble
+_begin_fstest auto encrypt
+
+# Import common functions.
+. ./common/filter
+. ./common/encrypt
+
+# real QA test starts here
+_supported_fs generic
+_require_scratch_encryption
+_require_command "$KEYCTL_PROG" keyctl
+
+# set up an encrypted directory
+
+_initialize_default_policy
+_scratch_mkfs_encrypted &>> $seqres.full
+_scratch_mount
+mkdir $SCRATCH_MNT/edir
+raw_key=$(_generate_raw_encryption_key)
+keydesc=$(_add_default_policy_key $raw_key)
+# -f 0x2: zero-pad to 16-byte boundary (i.e. encryption block boundary)
+# -f 0x20: necessary flag for btrfs
+_set_encpolicy $SCRATCH_MNT/edir $keydesc -f 0x22
+
+# Create files with long names (> 32 bytes, long enough to trigger the use of
+# "digested" names) in the encrypted directory.
+#
+# Use 100,000 files so that we have a good chance of detecting buggy filesystems
+# that solely use a 32-bit hash to distinguish files, which f2fs was doing.
+#
+# Furthermore, make the filenames differ only in the last 16-byte encryption
+# block.  This reproduces the bug where it was not accounted for that ciphertext
+# stealing (CTS) causes the last two blocks to appear "flipped".
+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_default_policy_key $keydesc &>> $seqres.full
+_scratch_cycle_mount
+
+# Verify that every file has a unique inode number and can be removed without
+# error.  With the bug(s), some filenames incorrectly pointed to the same inode,
+# and ext4 reported a "Structure needs cleaning" error when removing files.
+find $SCRATCH_MNT/edir/ -type f | xargs stat -c %i | sort | uniq | wc -l
+rm -rf $SCRATCH_MNT/edir |& head -n 10
+stat $SCRATCH_MNT/edir |& _filter_stat |& _filter_scratch
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/299.out b/tests/btrfs/299.out
new file mode 100644
index 00000000..41d3d94a
--- /dev/null
+++ b/tests/btrfs/299.out
@@ -0,0 +1,4 @@
+QA output created by 299
+100000
+100000
+stat: cannot statx 'SCRATCH_MNT/edir': No such file or directory
diff --git a/tests/generic/395 b/tests/generic/395
index ab2ad612..f111329b 100755
--- a/tests/generic/395
+++ b/tests/generic/395
@@ -15,7 +15,7 @@ _begin_fstest auto quick encrypt
 
 # real QA test starts here
 _supported_fs generic
-_require_scratch_encryption
+_require_scratch_encryption -v 1
 _require_xfs_io_command "get_encpolicy"
 _require_user
 
diff --git a/tests/generic/397 b/tests/generic/397
index 6c03f274..e3c5e401 100755
--- a/tests/generic/397
+++ b/tests/generic/397
@@ -23,13 +23,14 @@ _require_symlinks
 _require_scratch_encryption
 _require_command "$KEYCTL_PROG" keyctl
 
-_init_session_keyring
+_initialize_default_policy
 
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
 mkdir $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
-keydesc=$(_generate_session_encryption_key)
+raw_key=$(_generate_raw_encryption_key)
+keydesc=$(_add_default_policy_key $raw_key)
 _set_encpolicy $SCRATCH_MNT/edir $keydesc
 for dir in $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir; do
 	touch $dir/empty > /dev/null
@@ -47,6 +48,7 @@ done
 diff -r $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
 # Cycle mount and diff again
 _scratch_cycle_mount
+_add_default_policy_key $raw_key &>> $seqres.full
 diff -r $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
 
 #
@@ -63,7 +65,7 @@ diff -r $SCRATCH_MNT/edir $SCRATCH_MNT/ref_dir
 # instead of a random one.  The same applies to symlink targets.
 #
 
-_unlink_session_encryption_key $keydesc
+_unlink_default_policy_key $keydesc &>> $seqres.full
 _scratch_cycle_mount
 
 # Check that unencrypted names aren't there
diff --git a/tests/generic/398 b/tests/generic/398
index e2cbad54..b3108b15 100755
--- a/tests/generic/398
+++ b/tests/generic/398
@@ -24,7 +24,7 @@ _supported_fs generic
 _require_scratch_encryption
 _require_renameat2 exchange
 
-_init_session_keyring
+_initialize_default_policy
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
@@ -34,8 +34,10 @@ edir1=$SCRATCH_MNT/edir1
 edir2=$SCRATCH_MNT/edir2
 udir=$SCRATCH_MNT/udir
 mkdir $edir1 $edir2 $udir
-keydesc1=$(_generate_session_encryption_key)
-keydesc2=$(_generate_session_encryption_key)
+raw_key1=$(_generate_raw_encryption_key)
+raw_key2=$(_generate_raw_encryption_key)
+keydesc1=$(_add_default_policy_key $raw_key1)
+keydesc2=$(_add_default_policy_key $raw_key2)
 _set_encpolicy $edir1 $keydesc1
 _set_encpolicy $edir2 $keydesc2
 touch $edir1/efile1
@@ -101,8 +103,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_session_encryption_key $keydesc1
-_unlink_session_encryption_key $keydesc2
+_unlink_default_policy_key $keydesc1 &>> $seqres.full
+_unlink_default_policy_key $keydesc2 &>> $seqres.full
 _scratch_cycle_mount
 efile1=$(find $edir1 -type f)
 efile2=$(find $edir2 -type f)
diff --git a/tests/generic/399 b/tests/generic/399
index a5aa7107..e3c77872 100755
--- a/tests/generic/399
+++ b/tests/generic/399
@@ -30,7 +30,7 @@ _require_symlinks
 _require_command "$XZ_PROG" xz
 _require_command "$KEYCTL_PROG" keyctl
 
-_init_session_keyring
+_initialize_default_policy
 
 #
 # Set up a small filesystem containing an encrypted directory.  64 MB is enough
@@ -45,7 +45,8 @@ dd if=/dev/zero of=$SCRATCH_DEV bs=$((1024 * 1024)) \
 _scratch_mkfs_sized_encrypted $fs_size &>> $seqres.full
 _scratch_mount
 
-keydesc=$(_generate_session_encryption_key)
+raw_key=$(_generate_raw_encryption_key)
+keydesc=$(_add_default_policy_key $raw_key)
 mkdir $SCRATCH_MNT/encrypted_dir
 _set_encpolicy $SCRATCH_MNT/encrypted_dir $keydesc
 
@@ -111,7 +112,7 @@ done
 # memory than the '-9' preset.  The memory needed with our settings will be
 # 64 * 6.5 = 416 MB; see xz(1).
 #
-_unlink_session_encryption_key $keydesc
+_unlink_default_policy_key $keydesc &>> $seqres.full
 _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 5d56d64f..f5fd9ea9 100755
--- a/tests/generic/419
+++ b/tests/generic/419
@@ -24,17 +24,18 @@ _require_scratch_encryption
 _require_command "$KEYCTL_PROG" keyctl
 _require_renameat2 exchange
 
-_init_session_keyring
+_initialize_default_policy
 
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
 mkdir $SCRATCH_MNT/edir
-keydesc=$(_generate_session_encryption_key)
+raw_key=$(_generate_raw_encryption_key)
+keydesc=$(_add_default_policy_key $raw_key)
 _set_encpolicy $SCRATCH_MNT/edir $keydesc
 echo a > $SCRATCH_MNT/edir/a
 echo b > $SCRATCH_MNT/edir/b
-_unlink_session_encryption_key $keydesc
+_unlink_default_policy_key $keydesc &>> $seqres.full
 _scratch_cycle_mount
 
 # Note that because no-key filenames are unpredictable, this needs to be written
diff --git a/tests/generic/421 b/tests/generic/421
index 0c4fa8e3..de8594fa 100755
--- a/tests/generic/421
+++ b/tests/generic/421
@@ -20,7 +20,7 @@ _supported_fs generic
 _require_scratch_encryption
 _require_command "$KEYCTL_PROG" keyctl
 
-_init_session_keyring
+_initialize_default_policy
 _scratch_mkfs_encrypted &>> $seqres.full
 _scratch_mount
 
@@ -34,7 +34,8 @@ slice=2
 # Create an encrypted file and sync its data to disk.
 rm -rf $dir
 mkdir $dir
-keydesc=$(_generate_session_encryption_key)
+raw_key=$(_generate_raw_encryption_key)
+keydesc=$(_add_default_policy_key $raw_key)
 _set_encpolicy $dir $keydesc
 $XFS_IO_PROG -f $file -c "pwrite 0 $((nproc*slice))M" -c "fsync" > /dev/null
 
@@ -54,7 +55,7 @@ done
 sleep 1
 
 # Revoke the encryption key.
-keyid=$(_revoke_session_encryption_key $keydesc)
+keyid=$(_revoke_default_policy_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 2cf12316..776eee71 100755
--- a/tests/generic/429
+++ b/tests/generic/429
@@ -28,7 +28,7 @@ _begin_fstest auto encrypt
 
 # real QA test starts here
 _supported_fs generic
-_require_scratch_encryption
+_require_scratch_encryption -v 1
 _require_command "$KEYCTL_PROG" keyctl
 _require_test_program "t_encrypted_d_revalidate"
 
diff --git a/tests/generic/435 b/tests/generic/435
index bb1cbb62..b0b9cd83 100755
--- a/tests/generic/435
+++ b/tests/generic/435
@@ -24,7 +24,7 @@ _begin_fstest auto encrypt
 
 # real QA test starts here
 _supported_fs generic
-_require_scratch_encryption
+_require_scratch_encryption -v 1
 _require_command "$KEYCTL_PROG" keyctl
 
 # set up an encrypted directory
diff --git a/tests/generic/440 b/tests/generic/440
index 5850a8fe..ca7c55b1 100755
--- a/tests/generic/440
+++ b/tests/generic/440
@@ -20,7 +20,7 @@ _begin_fstest auto quick encrypt
 
 # real QA test starts here
 _supported_fs generic
-_require_scratch_encryption
+_require_scratch_encryption -v 1
 _require_symlinks
 _require_command "$KEYCTL_PROG" keyctl
 
diff --git a/tests/generic/576 b/tests/generic/576
index c8862de2..7a368a8d 100755
--- a/tests/generic/576
+++ b/tests/generic/576
@@ -26,7 +26,7 @@ _cleanup()
 # real QA test starts here
 _supported_fs generic
 _require_scratch_verity
-_require_scratch_encryption
+_require_scratch_encryption -v 1
 _require_command "$KEYCTL_PROG" keyctl
 _require_fsverity_corruption
 _disable_fsverity_signatures
@@ -39,8 +39,9 @@ edir=$SCRATCH_MNT/edir
 fsv_file=$edir/file.fsv
 
 # Set up an encrypted directory.
-_init_session_keyring
-keydesc=$(_generate_session_encryption_key)
+_initialize_default_policy
+raw_key=$(_generate_raw_encryption_key)
+keydesc=$(_add_default_policy_key $raw_key)
 mkdir $edir
 _set_encpolicy $edir $keydesc
 
diff --git a/tests/generic/580 b/tests/generic/580
index 73f32ff9..f9928d33 100755
--- a/tests/generic/580
+++ b/tests/generic/580
@@ -18,6 +18,7 @@ echo
 
 # real QA test starts here
 _supported_fs generic
+_require_scratch_encryption -v 1
 _require_scratch_encryption -v 2
 
 _scratch_mkfs_encrypted &>> $seqres.full
diff --git a/tests/generic/581 b/tests/generic/581
index cabc7e1c..78cc0fa8 100755
--- a/tests/generic/581
+++ b/tests/generic/581
@@ -31,6 +31,7 @@ _cleanup()
 # real QA test starts here
 _supported_fs generic
 _require_user
+_require_scratch_encryption -v 1
 _require_scratch_encryption -v 2
 
 _scratch_mkfs_encrypted &>> $seqres.full
diff --git a/tests/generic/593 b/tests/generic/593
index 2dda5d76..7907236c 100755
--- a/tests/generic/593
+++ b/tests/generic/593
@@ -17,6 +17,7 @@ _begin_fstest auto quick encrypt
 
 # real QA test starts here
 _supported_fs generic
+_require_scratch_encryption -v 1
 _require_scratch_encryption -v 2
 _require_command "$KEYCTL_PROG" keyctl
 
diff --git a/tests/generic/613 b/tests/generic/613
index 4cf5ccc6..ffd5f8a9 100755
--- a/tests/generic/613
+++ b/tests/generic/613
@@ -22,6 +22,7 @@ _begin_fstest auto quick encrypt
 
 # real QA test starts here
 _supported_fs generic
+_require_scratch_encryption -v 1
 _require_scratch_encryption -v 2
 _require_get_encryption_nonce_support
 _require_command "$XZ_PROG" xz
-- 
2.35.1


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

* [PATCH 2/2] fstests: fscrypt: update tests of encryption contents for btrfs
  2022-08-17 14:45 [PATCH 0/2] fstests: add btrfs encryption support Sweet Tea Dorminy
  2022-08-17 14:45 ` [PATCH 1/2] fstests: fscrypt: enable btrfs testing Sweet Tea Dorminy
@ 2022-08-17 14:45 ` Sweet Tea Dorminy
  1 sibling, 0 replies; 4+ messages in thread
From: Sweet Tea Dorminy @ 2022-08-17 14:45 UTC (permalink / raw)
  To: fstests, linux-fscrypt, linux-btrfs, kernel-team; +Cc: Sweet Tea Dorminy

As btrfs has a new encryption policy, and requires a particular set of
policy flags, both the tests to verify contents and filename encryption,
and the tool to verify against, need updates to use the new policy for
btrfs. This change updates the tool with the new fscrypt policy
behavior; updates the test functions to extract per-extent IVs, assuming
there is only one extent per inode; and updates the test functions to
use btrfs's dump-tree as necessary to extract information.

It is somewhat fragile to assume that the contents always fit within one
extent, but no test yet uses large enough files for this to be an issue.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 common/encrypt           | 75 +++++++++++++++++++++++++++++++++++-----
 src/fscrypt-crypt-util.c | 34 ++++++++++++++++--
 tests/generic/576        |  1 +
 3 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/common/encrypt b/common/encrypt
index b011c3e8..ce6ebdf9 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -110,7 +110,7 @@ _require_encryption_policy_support()
 
 	if [ "$FSTYP" = "btrfs" ]; then
 		if (( policy_flags & ~FSCRYPT_POLICY_FLAG_IV_FROM_FS )); then
-			_fail "Btrfs accepts policy flags of IV_FROM_FS only"
+			_notrun "Btrfs accepts policy flags of IV_FROM_FS only"
 		fi
 	fi
 
@@ -635,6 +635,40 @@ _get_encryption_nonce()
 	esac
 }
 
+# Retrieve the encryption IV of the first file extent in an inode as a hex
+# string.  The IV was randomly generated by the filesystem, in the case of
+# btrfs, and isn't exposed directly to userspace.  But it can be read using
+# the filesystem's debugging tools.
+_get_encryption_iv()
+{
+	local device=$1
+	local inode=$2
+
+	case $FSTYP in
+	btrfs)
+		# btrfs prints the file extents (for simple unshared
+		# inodes) like:
+		#         item 21 key ($inode EXTENT_DATA 0) itemoff 2534 itemsize 69
+		#                generation 7 type 1 (regular)
+                #		 extent data disk byte 5304320 nr 1048576
+                #		 extent data offset 0 nr 1048576 ram 1048576
+                #		 extent compression 0 (none)
+                #		 extent encryption 81 (1, 16: IV 77d05501da7c23920f9ca00872f0bbc3)
+
+		#
+		$BTRFS_UTIL_PROG inspect-internal dump-tree $device | \
+			grep -A 5 "key ($inode EXTENT_DATA 0)" | \
+			awk '/ IV [[:xdigit:]]+)/ {
+				match($0, /IV ([[:xdigit:]]+)\)/,a);
+				print a[1];
+			}'
+		;;
+	*)
+		_fail "_get_encryption_iv() isn't implemented on $FSTYP"
+		;;
+	esac
+}
+
 # Require support for _get_encryption_nonce()
 _require_get_encryption_nonce_support()
 {
@@ -669,6 +703,19 @@ _get_ciphertext_filename()
 	local dir_inode=$3
 
 	case $FSTYP in
+	btrfs)
+		# Extract the filename from the inode_ref object, similar to:
+		# item 24 key (259 INODE_REF 257) itemoff 14826 itemsize 26
+		# 	index 3 namelen 16 name: J\xf7\x15tD\x8eL\xae/\x98\x9f\x09\xc1\xb6\x09>
+		#
+		$BTRFS_UTIL_PROG inspect-internal dump-tree $device | \
+			grep -A 1 "key ($inode INODE_REF " | tail -n 1 | \
+			perl -ne '
+				s/.*?name: //;
+				chomp;
+				s/\\x([[:xdigit:]]{2})/chr hex $1/eg;
+				print;'
+		;;
 	ext4)
 		# Extract the filename from the debugfs output line like:
 		#
@@ -806,6 +853,7 @@ _do_verify_ciphertext_for_encryption_policy()
 	local raw_key_hex=$6
 	local crypt_contents_cmd="$here/src/fscrypt-crypt-util $7"
 	local crypt_filename_cmd="$here/src/fscrypt-crypt-util $8"
+	local use_iv=$9
 
 	local blocksize=$(_get_block_size $SCRATCH_MNT)
 	local test_contents_files=()
@@ -860,18 +908,24 @@ _do_verify_ciphertext_for_encryption_policy()
 
 	echo "Verifying encrypted file contents" >> $seqres.full
 	for f in "${test_contents_files[@]}"; do
+		local iv_arg=""
 		read -r src inode blocklist <<< "$f"
 		nonce=$(_get_encryption_nonce $SCRATCH_DEV $inode)
 		_dump_ciphertext_blocks $SCRATCH_DEV $blocklist > $tmp.actual_contents
+		if [ -n "$use_iv" ]; then
+			local iv_hex=$(_get_encryption_iv $SCRATCH_DEV $inode)
+			iv_arg=" --iv=$iv_hex"
+		fi
+			
 		$crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
 			--file-nonce=$nonce --block-size=$blocksize \
-			--inode-number=$inode < $src > $tmp.expected_contents
+			--inode-number=$inode $iv_arg < $src > $tmp.expected_contents
 		if ! cmp $tmp.expected_contents $tmp.actual_contents; then
 			_fail "Expected encrypted contents != actual encrypted contents.  File: $f"
 		fi
 		$crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
 			--decrypt --file-nonce=$nonce --block-size=$blocksize \
-			--inode-number=$inode \
+			--inode-number=$inode $iv_arg \
 			< $tmp.actual_contents > $tmp.decrypted_contents
 		if ! cmp $src $tmp.decrypted_contents; then
 			_fail "Contents decryption sanity check failed.  File: $f"
@@ -957,9 +1011,10 @@ _verify_ciphertext_for_encryption_policy()
 	local crypt_util_contents_args=""
 	local crypt_util_filename_args=""
 	local expected_identifier
+	local use_iv=""
 
 	if [ "$FSTYP" = "btrfs" ]; then
-		policy_version = 2
+		policy_version=2
 	fi
 	
 	shift 2
@@ -999,9 +1054,9 @@ _verify_ciphertext_for_encryption_policy()
 		crypt_util_args+=" --kdf=HKDF-SHA512"
 		if [ "$FSTYP" = "btrfs" ]; then
 			if (( policy_flags & ~FSCRYPT_POLICY_FLAG_IV_FROM_FS )); then
-				_fail "Btrfs accepts policy flags of IV_FROM_FS only"
+				_notrun "Btrfs accepts policy flags of IV_FROM_FS only"
 			fi	
-			policy_flags |= FSCRYPT_POLICY_FLAG_IV_FROM_FS
+			(( policy_flags |= FSCRYPT_POLICY_FLAG_IV_FROM_FS ))
 		fi
 		if (( policy_flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY )); then
 			crypt_util_args+=" --direct-key"
@@ -1009,6 +1064,9 @@ _verify_ciphertext_for_encryption_policy()
 			crypt_util_args+=" --iv-ino-lblk-64"
 		elif (( policy_flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 )); then
 			crypt_util_args+=" --iv-ino-lblk-32"
+		elif (( policy_flags & FSCRYPT_POLICY_FLAG_IV_FROM_FS )); then
+			crypt_util_args+=" --iv-from-fs"
+			use_iv=1
 		fi
 	else
 		if (( policy_flags & ~FSCRYPT_POLICY_FLAG_DIRECT_KEY )); then
@@ -1026,7 +1084,7 @@ _verify_ciphertext_for_encryption_policy()
 	_require_test_program "fscrypt-crypt-util"
 	_require_xfs_io_command "fiemap"
 	_require_get_encryption_nonce_support
-	_require_get_ciphertext_filename_support
+	#_require_get_ciphertext_filename_support
 	if (( policy_version == 1 )); then
 		_require_command "$KEYCTL_PROG" keyctl
 	fi
@@ -1094,7 +1152,8 @@ EOF
 		"$keyspec" \
 		"$raw_key_hex" \
 		"$crypt_util_contents_args" \
-		"$crypt_util_filename_args"
+		"$crypt_util_filename_args" \
+		"$use_iv"
 }
 
 # Replace no-key filenames in the given directory with "NOKEY_NAME".
diff --git a/src/fscrypt-crypt-util.c b/src/fscrypt-crypt-util.c
index ffb9534d..6f4f8190 100644
--- a/src/fscrypt-crypt-util.c
+++ b/src/fscrypt-crypt-util.c
@@ -76,10 +76,14 @@ static void usage(FILE *fp)
 "  --inode-number=INUM         The file's inode number.  Required for\n"
 "                                --iv-ino-lblk-32 and --iv-ino-lblk-64;\n"
 "                                otherwise is unused.\n"
+"  --iv=IV                     For the IV-from-FS format, the starting IV for\n"
+"                                the file\n"
 "  --iv-ino-lblk-32            Similar to --iv-ino-lblk-64, but selects the\n"
 "                                32-bit variant.\n"
 "  --iv-ino-lblk-64            Use the format where the IVs include the inode\n"
 "                                number and the same key is shared across files.\n"
+"  --iv-from-fs                Use the format where the IV is specifically\n"
+"                                supplied by the filesystem\n"
 "  --kdf=KDF                   Key derivation function to use: AES-128-ECB,\n"
 "                                HKDF-SHA512, or none.  Default: none\n"
 "  --mode-num=NUM              The encryption mode number.  This may be required\n"
@@ -1794,8 +1798,11 @@ struct key_and_iv_params {
 	u8 file_nonce[FILE_NONCE_SIZE];
 	bool file_nonce_specified;
 	bool direct_key;
+	u8 iv[MAX_IV_SIZE];
+	bool iv_set;
 	bool iv_ino_lblk_64;
 	bool iv_ino_lblk_32;
+	bool iv_from_fs;
 	u64 block_number;
 	u64 inode_number;
 	u8 fs_uuid[UUID_SIZE];
@@ -1809,6 +1816,7 @@ struct key_and_iv_params {
 #define HKDF_CONTEXT_DIRHASH_KEY	5
 #define HKDF_CONTEXT_IV_INO_LBLK_32_KEY	6
 #define HKDF_CONTEXT_INODE_HASH_KEY	7
+#define HKDF_CONTEXT_IV_FROM_FS		8
 
 /* Hash the file's inode number using SipHash keyed by a derived key */
 static u32 hash_inode_number(const struct key_and_iv_params *params)
@@ -1881,9 +1889,10 @@ static void derive_real_key(const struct key_and_iv_params *params,
 			info[infolen++] = params->mode_num;
 			memcpy(&info[infolen], params->fs_uuid, UUID_SIZE);
 			infolen += UUID_SIZE;
-		} else {
-			if (!params->file_nonce_specified)
-				die("--kdf=HKDF-SHA512 requires --file-nonce or --iv-ino-lblk-{64,32}");
+		} else if (params->iv_from_fs) {
+			info[infolen++] = HKDF_CONTEXT_IV_FROM_FS;
+			info[infolen++] = params->mode_num;
+		} else if (params->file_nonce_specified) {
 			info[infolen++] = HKDF_CONTEXT_PER_FILE_ENC_KEY;
 			memcpy(&info[infolen], params->file_nonce,
 			       FILE_NONCE_SIZE);
@@ -1906,6 +1915,10 @@ static void generate_iv(const struct key_and_iv_params *params,
 			die("--direct-key requires --file-nonce");
 		iv->block_number = cpu_to_le64(params->block_number);
 		memcpy(iv->nonce, params->file_nonce, FILE_NONCE_SIZE);
+	} else if (params->iv_from_fs) {
+		memcpy(iv->nonce, params->file_nonce, FILE_NONCE_SIZE);
+		if (params->iv_set)
+			memcpy(iv->bytes, params->iv, MAX_IV_SIZE);
 	} else if (params->iv_ino_lblk_64) {
 		if (params->block_number > UINT32_MAX)
 			die("iv-ino-lblk-64 can't use --block-number > UINT32_MAX");
@@ -1987,8 +2000,10 @@ enum {
 	OPT_FS_UUID,
 	OPT_HELP,
 	OPT_INODE_NUMBER,
+	OPT_IV,
 	OPT_IV_INO_LBLK_32,
 	OPT_IV_INO_LBLK_64,
+	OPT_IV_FROM_FS,
 	OPT_KDF,
 	OPT_MODE_NUM,
 	OPT_PADDING,
@@ -2004,8 +2019,10 @@ static const struct option longopts[] = {
 	{ "fs-uuid",         required_argument, NULL, OPT_FS_UUID },
 	{ "help",            no_argument,       NULL, OPT_HELP },
 	{ "inode-number",    required_argument, NULL, OPT_INODE_NUMBER },
+	{ "iv",              required_argument, NULL, OPT_IV },
 	{ "iv-ino-lblk-32",  no_argument,       NULL, OPT_IV_INO_LBLK_32 },
 	{ "iv-ino-lblk-64",  no_argument,       NULL, OPT_IV_INO_LBLK_64 },
+	{ "iv-from-fs",      no_argument,       NULL, OPT_IV_FROM_FS },
 	{ "kdf",             required_argument, NULL, OPT_KDF },
 	{ "mode-num",        required_argument, NULL, OPT_MODE_NUM },
 	{ "padding",         required_argument, NULL, OPT_PADDING },
@@ -2082,12 +2099,23 @@ int main(int argc, char *argv[])
 			if (params.inode_number <= 0 || *tmp || errno)
 				die("Invalid inode number: %s", optarg);
 			break;
+		case OPT_IV:
+			int iv_len = hex2bin(optarg, params.iv, MAX_IV_SIZE);
+			if ((iv_len != AES_BLOCK_SIZE) &&
+			    (iv_len != ADIANTUM_IV_SIZE))
+				die("Invalid iv length: %d (must be %u or %u)",
+				    iv_len, AES_BLOCK_SIZE, ADIANTUM_IV_SIZE);
+			params.iv_set = true;
+			break;
 		case OPT_IV_INO_LBLK_32:
 			params.iv_ino_lblk_32 = true;
 			break;
 		case OPT_IV_INO_LBLK_64:
 			params.iv_ino_lblk_64 = true;
 			break;
+		case OPT_IV_FROM_FS:
+			params.iv_from_fs = true;
+			break;
 		case OPT_KDF:
 			params.kdf = parse_kdf_algorithm(optarg);
 			break;
diff --git a/tests/generic/576 b/tests/generic/576
index 7a368a8d..060d5ac8 100755
--- a/tests/generic/576
+++ b/tests/generic/576
@@ -61,6 +61,7 @@ cmp $fsv_orig_file $fsv_file && echo "Files matched"
 
 # Just in case, try again after a mount cycle to empty the page cache.
 _scratch_cycle_mount
+_add_default_policy_key $raw_key &>> $seqres.full
 cmp $fsv_orig_file $fsv_file && echo "Files matched"
 
 # Corrupt some bytes as a sanity check that fs-verity is really working.
-- 
2.35.1


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

* [PATCH 0/2] fstests: add btrfs encryption support
@ 2022-09-06  0:31 Sweet Tea Dorminy
  0 siblings, 0 replies; 4+ messages in thread
From: Sweet Tea Dorminy @ 2022-09-06  0:31 UTC (permalink / raw)
  To: fstests, linux-fscrypt, linux-btrfs, kernel-team; +Cc: Sweet Tea Dorminy

btrfs has several differences from other filesystems currently
integrated with fscrypt. It uses a newly proposed extent context object;
only works with direct key policies; and allows partially encrypted
directories. The design document can be found at [1].

As such, this splits a couple of tests and filters encryption policy
printing to account for different filesystems' different default
policies.

Tests for subvolume encryption, a key feature for btrfs, are not yet complete.
 
Necessary btrfs-progs changes are available at [2]; kernel changes
are available at [3]. 

[1]
https://lore.kernel.org/linux-btrfs/YXGyq+buM79A1S0L@relinquished.localdomain/
[2] https://lore.kernel.org/linux-btrfs/cover.1662420176.git.sweettea-kernel@dorminy.me
[3] https://lore.kernel.org/linux-btrfs/cover.1662417859.git.sweettea-kernel@dorminy.me

Changelog:

v2:
 - Mostly rewrote and simplified the changes, as btrfs no longer requires
   a separate new encryption policy.
 - Added a filter function to account for different default encryption
   policies.
 - Split Adiantum tests, as only the direct-key variant works with
   btrfs.
 - https://lore.kernel.org/linux-btrfs/cover.1662417905.git.sweettea-kernel@dorminy.me

v1: 
 - https://lore.kernel.org/linux-btrfs/cover.1660729861.git.sweettea-kernel@dorminy.me

Sweet Tea Dorminy (2):
  fstests: fscrypt: enable btrfs testing.
  fstests: fscrypt: update tests of encryption contents for btrfs

 common/encrypt           | 141 +++++++++++++++++++++++++++++++++++++--
 common/verity            |   2 +-
 src/fscrypt-crypt-util.c |  18 ++++-
 tests/btrfs/298          |  85 +++++++++++++++++++++++
 tests/btrfs/298.out      |  47 +++++++++++++
 tests/generic/395        |  10 ++-
 tests/generic/395.out    |  18 ++---
 tests/generic/435        |  10 ++-
 tests/generic/550        |   2 -
 tests/generic/550.out    |   5 --
 tests/generic/576        |   3 +-
 tests/generic/576.out    |   6 +-
 tests/generic/580        |   5 +-
 tests/generic/580.out    |  18 ++---
 tests/generic/581        |   4 +-
 tests/generic/581.out    |  12 ++--
 tests/generic/584        |   2 -
 tests/generic/584.out    |   5 --
 tests/generic/720        |  26 ++++++++
 tests/generic/720.out    |   6 ++
 tests/generic/721        |  26 ++++++++
 tests/generic/721.out    |   6 ++
 22 files changed, 398 insertions(+), 59 deletions(-)
 create mode 100755 tests/btrfs/298
 create mode 100644 tests/btrfs/298.out
 create mode 100755 tests/generic/720
 create mode 100644 tests/generic/720.out
 create mode 100755 tests/generic/721
 create mode 100644 tests/generic/721.out

-- 
2.35.1


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

end of thread, other threads:[~2022-09-06  0:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-17 14:45 [PATCH 0/2] fstests: add btrfs encryption support Sweet Tea Dorminy
2022-08-17 14:45 ` [PATCH 1/2] fstests: fscrypt: enable btrfs testing Sweet Tea Dorminy
2022-08-17 14:45 ` [PATCH 2/2] fstests: fscrypt: update tests of encryption contents for btrfs Sweet Tea Dorminy
  -- strict thread matches above, loose matches on Subject: below --
2022-09-06  0:31 [PATCH 0/2] fstests: add btrfs encryption support Sweet Tea Dorminy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox