From: Daniel Vacek <neelx@suse.com>
To: fstests@vger.kernel.org
Cc: linux-btrfs@vger.kernel.org, linux-ext4@vger.kernel.org,
linux-xfs@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net, zlang@redhat.com,
hch@infradead.org, djwong@kernel.org,
David Sterba <dsterba@suse.com>, Daniel Vacek <neelx@suse.com>,
linux-fscrypt@vger.kernel.org
Subject: [PATCH 12/12] fscrypt-crypt-util: add support for per extent KDF
Date: Fri, 24 Jul 2026 15:33:28 +0200 [thread overview]
Message-ID: <20260724133328.1837318-13-neelx@suse.com> (raw)
In-Reply-To: <20260724133328.1837318-1-neelx@suse.com>
When deriving a key for extent, fscrypt uses different salt. Add the
support for this.
Signed-off-by: Daniel Vacek <neelx@suse.com>
---
common/encrypt | 13 +++++++++----
src/fscrypt-crypt-util.c | 12 +++++++++++-
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/common/encrypt b/common/encrypt
index 4c3fd904..2485b69a 100644
--- a/common/encrypt
+++ b/common/encrypt
@@ -836,7 +836,7 @@ _do_verify_ciphertext_for_encryption_policy()
local blocksize=$(_get_block_size $SCRATCH_MNT)
local test_contents_files=()
local test_filenames_files=()
- local i src dir dst inode blocklist \
+ local i src dir dst inode blocklist context_per_extent \
padding_flag padding dir_inode len name f nonce decrypted_name
# Create files whose encrypted contents we'll verify. For each, save
@@ -891,19 +891,24 @@ _do_verify_ciphertext_for_encryption_policy()
# Now unmount the filesystem and verify the ciphertext we just wrote.
_scratch_unmount
+ case $FSTYP in
+ btrfs) context_per_extent=--context-per-extent;;
+ *) context_per_extent=;;
+ esac
+
echo "Verifying encrypted file contents" >> $seqres.full
for f in "${test_contents_files[@]}"; do
read -r src inode blocklist <<< "$f"
nonce=$(_get_encryption_data_nonce $SCRATCH_DEV $inode)
_dump_ciphertext_blocks $SCRATCH_DEV $blocklist > $tmp.actual_contents
$crypt_contents_cmd $contents_encryption_mode $raw_key_hex \
- --file-nonce=$nonce --inode-number=$inode \
- < $src > $tmp.expected_contents
+ --file-nonce=$nonce $context_per_extent --inode-number=$inode \
+ < $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 --inode-number=$inode \
+ --decrypt --file-nonce=$nonce $context_per_extent --inode-number=$inode \
< $tmp.actual_contents > $tmp.decrypted_contents
if ! cmp $src $tmp.decrypted_contents; then
_fail "Contents decryption sanity check failed. File: $f"
diff --git a/src/fscrypt-crypt-util.c b/src/fscrypt-crypt-util.c
index f51b3669..1403edb5 100644
--- a/src/fscrypt-crypt-util.c
+++ b/src/fscrypt-crypt-util.c
@@ -75,6 +75,7 @@ static void usage(FILE *fp)
" replicate the en/decryption that is done when\n"
" the filesystem is given a hardware-wrapped key.\n"
" --file-nonce=NONCE File's nonce as a 32-character hex string\n"
+" --context-per-extent Derive the key for per extent context.\n"
" --fs-uuid=UUID The filesystem UUID as a 32-character hex string.\n"
" Required for --iv-ino-lblk-32 and\n"
" --iv-ino-lblk-64; otherwise is unused.\n"
@@ -2162,6 +2163,7 @@ struct key_and_iv_params {
bool direct_key;
bool iv_ino_lblk_64;
bool iv_ino_lblk_32;
+ bool context_per_extent;
u64 data_unit_index;
u64 inode_number;
u8 fs_uuid[UUID_SIZE];
@@ -2176,6 +2178,7 @@ struct key_and_iv_params {
#define HKDF_CONTEXT_IV_INO_LBLK_32_KEY 6
#define HKDF_CONTEXT_INODE_HASH_KEY 7
#define HKDF_CONTEXT_KEY_IDENTIFIER_FOR_HW_WRAPPED_KEY 8
+#define HKDF_CONTEXT_PER_EXTENT_ENC_KEY 9
/* 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)
@@ -2366,7 +2369,9 @@ static void derive_real_key(const struct key_and_iv_params *params,
} else {
if (!params->file_nonce_specified)
die("--kdf=HKDF-SHA512 requires --file-nonce or --iv-ino-lblk-{64,32}");
- info[infolen++] = HKDF_CONTEXT_PER_FILE_ENC_KEY;
+ info[infolen++] = params->context_per_extent?
+ HKDF_CONTEXT_PER_EXTENT_ENC_KEY:
+ HKDF_CONTEXT_PER_FILE_ENC_KEY;
memcpy(&info[infolen], params->file_nonce,
FILE_NONCE_SIZE);
infolen += FILE_NONCE_SIZE;
@@ -2481,6 +2486,7 @@ enum {
OPT_DUMP_KEY_IDENTIFIER,
OPT_ENABLE_HW_KDF,
OPT_FILE_NONCE,
+ OPT_CONTEXT_PER_EXTENT,
OPT_FS_UUID,
OPT_HELP,
OPT_INODE_NUMBER,
@@ -2500,6 +2506,7 @@ static const struct option longopts[] = {
{ "dump-key-identifier", no_argument, NULL, OPT_DUMP_KEY_IDENTIFIER },
{ "enable-hw-kdf", no_argument, NULL, OPT_ENABLE_HW_KDF },
{ "file-nonce", required_argument, NULL, OPT_FILE_NONCE },
+ { "context-per-extent", no_argument, NULL, OPT_CONTEXT_PER_EXTENT },
{ "fs-uuid", required_argument, NULL, OPT_FS_UUID },
{ "help", no_argument, NULL, OPT_HELP },
{ "inode-number", required_argument, NULL, OPT_INODE_NUMBER },
@@ -2572,6 +2579,9 @@ int main(int argc, char *argv[])
die("Invalid file nonce: %s", optarg);
params.file_nonce_specified = true;
break;
+ case OPT_CONTEXT_PER_EXTENT:
+ params.context_per_extent = true;
+ break;
case OPT_FS_UUID:
if (hex2bin(optarg, params.fs_uuid, UUID_SIZE)
!= UUID_SIZE)
--
2.53.0
next prev parent reply other threads:[~2026-07-24 13:34 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-24 13:33 [PATCH 00/12] fstests: introduce fscrypt support for btrfs Daniel Vacek
2026-07-24 13:33 ` [PATCH 01/12] common/encrypt: separate data and inode nonces Daniel Vacek
2026-07-24 13:33 ` [PATCH 02/12] common/encrypt: add btrfs to get_encryption_*nonce Daniel Vacek
2026-07-24 13:33 ` [PATCH 03/12] common/encrypt: add btrfs to get_ciphertext_filename Daniel Vacek
2026-07-24 13:33 ` [PATCH 04/12] common/encrypt: enable making a encrypted btrfs filesystem Daniel Vacek
2026-07-24 13:33 ` [PATCH 05/12] common/verity: explicitly don't allow btrfs encryption Daniel Vacek
2026-07-24 13:33 ` [PATCH 06/12] btrfs: add simple test of reflink of encrypted data Daniel Vacek
2026-07-24 13:33 ` [PATCH 07/12] btrfs: test snapshotting encrypted subvol Daniel Vacek
2026-07-24 13:33 ` [PATCH 08/12] fstests: properly test for v1 encryption policies in encrypt tests Daniel Vacek
2026-07-24 13:33 ` [PATCH 09/12] fstests: split generic/580 into two tests Daniel Vacek
2026-07-24 13:33 ` [PATCH 10/12] fstests: split generic/581 " Daniel Vacek
2026-07-24 13:33 ` [PATCH 11/12] fstests: split generic/613 " Daniel Vacek
2026-07-24 13:33 ` Daniel Vacek [this message]
2026-07-28 3:19 ` [PATCH 00/12] fstests: introduce fscrypt support for btrfs Christoph Hellwig
2026-07-28 5:44 ` Daniel Vacek
2026-07-28 5:48 ` Eric Biggers
2026-07-28 6:04 ` Christoph Hellwig
2026-07-28 6:07 ` Eric Biggers
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=20260724133328.1837318-13-neelx@suse.com \
--to=neelx@suse.com \
--cc=djwong@kernel.org \
--cc=dsterba@suse.com \
--cc=fstests@vger.kernel.org \
--cc=hch@infradead.org \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fscrypt@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=zlang@redhat.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