From 4dfb761caea026f9ef4f0616f95cdb9d72bc1e39 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 6 May 2020 14:15:07 -0700 Subject: [PATCH] ANDROID: fscrypt: set dun_bytes more precisely Make fscrypt set dun_bytes to only what it actually needs, so that it can make use of inline crypto hardware in more cases. Bug: 144046242 Bug: 153512828 Change-Id: I36f90ea6b64ef51a9d58ffb069d2cba74965c239 Signed-off-by: Eric Biggers --- fs/crypto/inline_crypt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index a932c8f9ce80..aebc8ecb7caa 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -43,13 +43,20 @@ static void fscrypt_get_devices(struct super_block *sb, int num_devs, static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci) { - unsigned int dun_bytes = 8; + struct super_block *sb = ci->ci_inode->i_sb; + unsigned int flags = fscrypt_policy_flags(&ci->ci_policy); + int ino_bits = 64, lblk_bits = 64; - if (fscrypt_policy_flags(&ci->ci_policy) & - FSCRYPT_POLICY_FLAG_DIRECT_KEY) - dun_bytes += FS_KEY_DERIVATION_NONCE_SIZE; + if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) + return offsetofend(union fscrypt_iv, nonce); - return dun_bytes; + if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) + return sizeof(__le64); + + /* Default case: IVs are just the file logical block number */ + if (sb->s_cop->get_ino_and_lblk_bits) + sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits); + return DIV_ROUND_UP(lblk_bits, 8); } /* Enable inline encryption for this file if supported. */