[PATCH v2 04/20] fscrypt: allow fscrypt_generate_iv() to distinguish filenames

Sweet Tea Dorminy
2022-09-06T00:35:52Z

With the introduction of extent-based file content encryption, filenames
and file contents might no longer use the same IV generation scheme, and
so should not upass the same logical block number to
fscrypt_generate_iv(). In preparation, start passing U64_MAX as the
block number for filename IV generation, and make fscrypt_generate_iv()
translate this to 0 if extent-based encryption is not being used.

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(-)

diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index e78be66bbf01..7fe5979fbea2 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -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);
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index 3bdece33e14d..16b64e0589e4 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -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);
--
2.35.1