public inbox for fstests@vger.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: fstests@vger.kernel.org
Cc: linux-fscrypt@vger.kernel.org,
	Bartosz Golaszewski <brgl@bgdev.pl>,
	Gaurav Kashyap <quic_gaurkash@quicinc.com>
Subject: [PATCH v2 2/3] common/encrypt: support hardware-wrapped key testing
Date: Thu, 12 Dec 2024 21:28:38 -0800	[thread overview]
Message-ID: <20241213052840.314921-3-ebiggers@kernel.org> (raw)
In-Reply-To: <20241213052840.314921-1-ebiggers@kernel.org>

From: Eric Biggers <ebiggers@google.com>

To support testing the kernel's support for hardware-wrapped inline
encryption keys, update _verify_ciphertext_for_encryption_policy() to
support a hw_wrapped_key option.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 common/config  |  1 +
 common/encrypt | 80 +++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/common/config b/common/config
index fcff0660..091405b3 100644
--- a/common/config
+++ b/common/config
@@ -233,10 +233,11 @@ export BLKZONE_PROG="$(type -P blkzone)"
 export GZIP_PROG="$(type -P gzip)"
 export BTRFS_IMAGE_PROG="$(type -P btrfs-image)"
 export BTRFS_MAP_LOGICAL_PROG=$(type -P btrfs-map-logical)
 export PARTED_PROG="$(type -P parted)"
 export XFS_PROPERTY_PROG="$(type -P xfs_property)"
+export FSCRYPTCTL_PROG="$(type -P fscryptctl)"
 
 # use 'udevadm settle' or 'udevsettle' to wait for lv to be settled.
 # newer systems have udevadm command but older systems like RHEL5 don't.
 # But if neither one is available, just set it to "sleep 1" to wait for lv to
 # be settled
diff --git a/common/encrypt b/common/encrypt
index d90a566a..1caca767 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -150,10 +150,46 @@ _require_encryption_policy_support()
 		$KEYCTL_PROG clear $TEST_KEYRING_ID
 	fi
 	rm -r $dir
 }
 
+# Require that the scratch filesystem accepts the "inlinecrypt" mount option.
+#
+# This does not check whether the scratch block device has any specific inline
+# encryption capabilities.
+_require_scratch_inlinecrypt()
+{
+	_require_scratch
+	_scratch_mkfs &>> $seqres.full
+	if ! _try_scratch_mount -o inlinecrypt &>> $seqres.full; then
+		_notrun "filesystem doesn't support -o inlinecrypt"
+	fi
+}
+
+# Require that the given block device supports hardware-wrapped inline
+# encryption keys, and require that a command-line tool that supports
+# importing/generating/preparing them is available.
+_require_hw_wrapped_key_support()
+{
+	local dev=$1
+
+	echo "Checking for HW-wrapped key support on $dev" >> $seqres.full
+	local sysfs_dir=$(_sysfs_dev $dev)
+	if [ ! -e $sysfs_dir/queue ]; then
+		sysfs_dir=$sysfs_dir/..
+	fi
+	if [ ! -e $sysfs_dir/queue/crypto/hw_wrapped_keys ]; then
+		_notrun "$dev doesn't support hardware-wrapped inline encryption keys"
+	fi
+
+	echo "Checking for fscryptctl support for HW-wrapped keys" >> $seqres.full
+	_require_command "$FSCRYPTCTL_PROG" fscryptctl
+	if ! "$FSCRYPTCTL_PROG" --help | grep -q "import_hw_wrapped_key"; then
+		_notrun "fscryptctl too old; doesn't support hardware-wrapped inline encryption keys"
+	fi
+}
+
 _scratch_mkfs_encrypted()
 {
 	case $FSTYP in
 	ext4|f2fs)
 		_scratch_mkfs -O encrypt
@@ -249,18 +285,21 @@ _generate_key_descriptor()
 }
 
 # Generate a raw encryption key, but don't add it to any keyring yet.
 _generate_raw_encryption_key()
 {
+	local size=${1:-64}
 	local raw=""
 	local i
-	for ((i = 0; i < 64; i++)); do
+	for ((i = 0; i < $size; i++)); do
 		raw="${raw}\\x$(printf "%02x" $(( $RANDOM % 256 )))"
 	done
 	echo $raw
 }
 
+RAW_HW_KEY_SIZE=32
+
 # Serialize an integer into a CPU-endian bytestring of the given length, and
 # print it as a string where each byte is hex-escaped.  For example,
 # `_num_to_hex 1000 4` == "\xe8\x03\x00\x00" if the CPU is little endian.
 _num_to_hex()
 {
@@ -405,10 +444,25 @@ _add_enckey()
 	shift 2
 
 	echo -ne "$raw_key" | $XFS_IO_PROG -c "add_enckey $*" "$mnt"
 }
 
+# Create a hardware-wrapped key from the given raw key using the given block
+# device, add it to the given filesystem, and print the resulting key
+# identifier.
+_add_hw_wrapped_key()
+{
+	local dev=$1
+	local mnt=$2
+	local raw_key=$3
+
+	echo -ne "$raw_key" | \
+		$FSCRYPTCTL_PROG import_hw_wrapped_key "$dev" | \
+		$FSCRYPTCTL_PROG prepare_hw_wrapped_key "$dev" | \
+		$FSCRYPTCTL_PROG add_key --hw-wrapped-key "$mnt"
+}
+
 _user_do_add_enckey()
 {
 	local mnt=$1
 	local raw_key=$2
 	shift 2
@@ -851,19 +905,21 @@ _fscrypt_mode_name_to_num()
 #	'v2':			test a v2 encryption policy
 #	'direct':		test the DIRECT_KEY policy flag
 #	'iv_ino_lblk_64':	test the IV_INO_LBLK_64 policy flag
 #	'iv_ino_lblk_32':	test the IV_INO_LBLK_32 policy flag
 #	'log2_dusize=N':        test the log2_data_unit_size field
+#	'hw_wrapped_key':	use a hardware-wrapped inline encryption key
 #
 _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 log2_dusize=0
+	local hw_wrapped_key=false
 	local set_encpolicy_args=""
 	local crypt_util_args=""
 	local crypt_util_contents_args=""
 	local crypt_util_filename_args=""
 	local expected_identifier
@@ -888,10 +944,15 @@ _verify_ciphertext_for_encryption_policy()
 			(( policy_flags |= FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 ))
 			;;
 		log2_dusize=*)
 			log2_dusize=$(echo "$opt" | sed 's/^log2_dusize=//')
 			;;
+		hw_wrapped_key)
+			hw_wrapped_key=true
+			crypt_util_args+=" --enable-hw-kdf"
+			crypt_util_contents_args+=" --use-inlinecrypt-key"
+			;;
 		*)
 			_fail "Unknown option '$opt' passed to ${FUNCNAME[0]}"
 			;;
 		esac
 	done
@@ -927,10 +988,13 @@ _verify_ciphertext_for_encryption_policy()
 		fi
 	fi
 	set_encpolicy_args=${set_encpolicy_args# }
 
 	_require_scratch_encryption $set_encpolicy_args -f $policy_flags
+	if $hw_wrapped_key; then
+		_require_hw_wrapped_key_support $SCRATCH_DEV
+	fi
 	_require_test_program "fscrypt-crypt-util"
 	_require_xfs_io_command "fiemap"
 	_require_get_encryption_nonce_support
 	_require_get_ciphertext_filename_support
 	if (( policy_version == 1 )); then
@@ -956,15 +1020,23 @@ _verify_ciphertext_for_encryption_policy()
 
 	crypt_util_contents_args+="$crypt_util_args"
 	crypt_util_filename_args+="$crypt_util_args"
 
 	echo "Generating encryption key" >> $seqres.full
-	local raw_key=$(_generate_raw_encryption_key)
 	if (( policy_version > 1 )); then
-		local keyspec=$(_add_enckey $SCRATCH_MNT "$raw_key" \
-				| awk '{print $NF}')
+		if $hw_wrapped_key; then
+			local raw_key=$(_generate_raw_encryption_key \
+					$RAW_HW_KEY_SIZE)
+			local keyspec=$(_add_hw_wrapped_key $SCRATCH_DEV \
+					$SCRATCH_MNT "$raw_key")
+		else
+			local raw_key=$(_generate_raw_encryption_key)
+			local keyspec=$(_add_enckey $SCRATCH_MNT "$raw_key" | \
+					awk '{print $NF}')
+		fi
 	else
+		local raw_key=$(_generate_raw_encryption_key)
 		local keyspec=$(_generate_key_descriptor)
 		_init_session_keyring
 		_add_session_encryption_key $keyspec $raw_key
 	fi
 	local raw_key_hex=$(echo "$raw_key" | tr -d '\\x')
-- 
2.47.1


  parent reply	other threads:[~2024-12-13  5:28 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-13  5:28 [PATCH v2 0/3] xfstests: test the fscrypt hardware-wrapped key support Eric Biggers
2024-12-13  5:28 ` [PATCH v2 1/3] fscrypt-crypt-util: add hardware KDF support Eric Biggers
2024-12-13  5:28 ` Eric Biggers [this message]
2024-12-13  5:28 ` [PATCH v2 3/3] generic: verify ciphertext with hardware-wrapped keys Eric Biggers
2025-01-07 13:59 ` [PATCH v2 0/3] xfstests: test the fscrypt hardware-wrapped key support Zorro Lang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241213052840.314921-3-ebiggers@kernel.org \
    --to=ebiggers@kernel.org \
    --cc=brgl@bgdev.pl \
    --cc=fstests@vger.kernel.org \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=quic_gaurkash@quicinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox