When deriving a key for extent, fscrypt uses different salt. Add the support for this.
Signed-off-by: Daniel Vacek <[email protected]> --- 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
