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
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.