@@ -71,7 +71,7 @@ EXPORT_SYMBOL(fscrypt_free_bounce_page);
/*
* Generate the IV for the given logical block number within the given file.
- * For filenames encryption, lblk_num == 0.
+ * For filenames encryption, lblk_num == U64_MAX.
*
* Keep this in sync with fscrypt_limit_io_blocks(). fscrypt_limit_io_blocks()
* needs to know about any IV generation methods where the low bits of IV don't
@@ -84,6 +84,13 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
memset(iv, 0, ci->ci_mode->ivsize);
+ /*
+ * Filename encryption. For inode-based policies, filenames are
+ * encrypted as though they are lblk 0.
+ */
+ if (lblk_num == U64_MAX)
+ lblk_num = 0;
+
if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) {
WARN_ON_ONCE(lblk_num > U32_MAX);
WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX);
@@ -79,7 +79,7 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
memset(out + iname->len, 0, olen - iname->len);
/* Initialize the IV */
- fscrypt_generate_iv(&iv, 0, ci);
+ fscrypt_generate_iv(&iv, U64_MAX, ci);
/* Set up the encryption request */
req = skcipher_request_alloc(tfm, GFP_NOFS);
@@ -134,7 +134,7 @@ static int fname_decrypt(const struct inode *inode,
crypto_req_done, &wait);
/* Initialize IV */
- fscrypt_generate_iv(&iv, 0, ci);
+ fscrypt_generate_iv(&iv, U64_MAX, ci);
/* Create decryption request */
sg_init_one(&src_sg, iname->name, iname->len);
For extent-based file contents encryption, filenames will need to generate an IV based on the inode context, while file contents will need to generate an IV based on the extent context. Currently filenames and the first block of file contents both pass fscrypt_generate_iv() a block number of 0, making it hard to distinguish the two cases. To enable distinguishing these two cases for extent-based encryption, this change adjusts all callers to pass U64_MAX when requesting an IV for filename encryption, and then changes fscrypt_generate_iv() to convert U64_MAX to 0 for traditional inode-context encryption. For extent-based encryption, any block number other than U64_MAX will get an IV from the extent context, while U64_MAX will indicate falling back to inode contexts. Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me> --- fs/crypto/crypto.c | 9 ++++++++- fs/crypto/fname.c | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-)