From: Eric Biggers <ebiggers@kernel.org>
To: fstests@vger.kernel.org
Cc: linux-fscrypt@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net,
Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <yuchao0@huawei.com>,
Daeho Jeong <daeho43@gmail.com>
Subject: [PATCH 2/5] fscrypt-crypt-util: fix IV incrementing for --iv-ino-lblk-32
Date: Wed, 30 Sep 2020 17:25:04 -0700 [thread overview]
Message-ID: <20201001002508.328866-3-ebiggers@kernel.org> (raw)
In-Reply-To: <20201001002508.328866-1-ebiggers@kernel.org>
From: Eric Biggers <ebiggers@google.com>
fscrypt-crypt-util treats the "block number" part of the IV as 64-bit
when incrementing it. That's wrong for --iv-ino-lblk-32 and
--iv-ino-lblk-64, as in those cases the block number should be 32-bit.
Fix this by using the correct length for the block number.
For --iv-ino-lblk-64 this doesn't actually matter, since in that case
the block number starts at 0 and never exceeds UINT32_MAX.
But for --iv-ino-lblk-32, the hashed inode number gets added to the
original block number to produce the IV block number, which can later
wrap around from UINT32_MAX to 0. As a result, this change fixes
generic/602, though since the wraparound case isn't specifically tested
currently, the chance of failure was extremely small.
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
src/fscrypt-crypt-util.c | 54 ++++++++++++++++++++++++++++------------
1 file changed, 38 insertions(+), 16 deletions(-)
diff --git a/src/fscrypt-crypt-util.c b/src/fscrypt-crypt-util.c
index d9189346..5c065116 100644
--- a/src/fscrypt-crypt-util.c
+++ b/src/fscrypt-crypt-util.c
@@ -1692,16 +1692,32 @@ static const struct fscrypt_cipher *find_fscrypt_cipher(const char *name)
return NULL;
}
-struct fscrypt_iv {
- union {
- __le64 block_num;
- u8 bytes[32];
+union fscrypt_iv {
+ /* usual IV format */
+ struct {
+ /* logical block number within the file */
+ __le64 block_number;
+
+ /* per-file nonce; only set in DIRECT_KEY mode */
+ u8 nonce[FILE_NONCE_SIZE];
+ };
+ /* IV format for IV_INO_LBLK_* modes */
+ struct {
+ /*
+ * IV_INO_LBLK_64: logical block number within the file
+ * IV_INO_LBLK_32: hashed inode number + logical block number
+ * within the file, mod 2^32
+ */
+ __le32 block_number32;
+
+ /* IV_INO_LBLK_64: inode number */
+ __le32 inode_number;
};
};
static void crypt_loop(const struct fscrypt_cipher *cipher, const u8 *key,
- struct fscrypt_iv *iv, bool decrypting,
- size_t block_size, size_t padding)
+ union fscrypt_iv *iv, bool decrypting,
+ size_t block_size, size_t padding, bool is_bnum_32bit)
{
u8 *buf = xmalloc(block_size);
size_t res;
@@ -1718,13 +1734,18 @@ static void crypt_loop(const struct fscrypt_cipher *cipher, const u8 *key,
memset(&buf[res], 0, crypt_len - res);
if (decrypting)
- cipher->decrypt(key, iv->bytes, buf, buf, crypt_len);
+ cipher->decrypt(key, (u8 *)iv, buf, buf, crypt_len);
else
- cipher->encrypt(key, iv->bytes, buf, buf, crypt_len);
+ cipher->encrypt(key, (u8 *)iv, buf, buf, crypt_len);
full_write(STDOUT_FILENO, buf, crypt_len);
- iv->block_num = cpu_to_le64(le64_to_cpu(iv->block_num) + 1);
+ if (is_bnum_32bit)
+ iv->block_number32 = cpu_to_le32(
+ le32_to_cpu(iv->block_number32) + 1);
+ else
+ iv->block_number = cpu_to_le64(
+ le64_to_cpu(iv->block_number) + 1);
}
free(buf);
}
@@ -1806,7 +1827,7 @@ static u32 hash_inode_number(const struct key_and_iv_params *params)
*/
static void get_key_and_iv(const struct key_and_iv_params *params,
u8 *real_key, size_t real_key_size,
- struct fscrypt_iv *iv)
+ union fscrypt_iv *iv)
{
bool file_nonce_in_iv = false;
struct aes_key aes_key;
@@ -1860,14 +1881,14 @@ static void get_key_and_iv(const struct key_and_iv_params *params,
info[infolen++] = params->mode_num;
memcpy(&info[infolen], params->fs_uuid, UUID_SIZE);
infolen += UUID_SIZE;
- put_unaligned_le32(params->inode_number, &iv->bytes[4]);
+ iv->inode_number = cpu_to_le32(params->inode_number);
} else if (params->iv_ino_lblk_32) {
info[infolen++] = HKDF_CONTEXT_IV_INO_LBLK_32_KEY;
info[infolen++] = params->mode_num;
memcpy(&info[infolen], params->fs_uuid, UUID_SIZE);
infolen += UUID_SIZE;
- put_unaligned_le32(hash_inode_number(params),
- iv->bytes);
+ iv->block_number32 =
+ cpu_to_le32(hash_inode_number(params));
} else if (params->mode_num != 0) {
info[infolen++] = HKDF_CONTEXT_DIRECT_KEY;
info[infolen++] = params->mode_num;
@@ -1888,7 +1909,7 @@ static void get_key_and_iv(const struct key_and_iv_params *params,
}
if (file_nonce_in_iv && params->file_nonce_specified)
- memcpy(&iv->bytes[8], params->file_nonce, FILE_NONCE_SIZE);
+ memcpy(iv->nonce, params->file_nonce, FILE_NONCE_SIZE);
}
enum {
@@ -1928,7 +1949,7 @@ int main(int argc, char *argv[])
size_t padding = 0;
const struct fscrypt_cipher *cipher;
u8 real_key[MAX_KEY_SIZE];
- struct fscrypt_iv iv;
+ union fscrypt_iv iv;
char *tmp;
int c;
@@ -2025,6 +2046,7 @@ int main(int argc, char *argv[])
get_key_and_iv(¶ms, real_key, cipher->keysize, &iv);
- crypt_loop(cipher, real_key, &iv, decrypting, block_size, padding);
+ crypt_loop(cipher, real_key, &iv, decrypting, block_size, padding,
+ params.iv_ino_lblk_64 || params.iv_ino_lblk_32);
return 0;
}
--
2.28.0
next prev parent reply other threads:[~2020-10-01 0:25 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-01 0:25 [PATCH 0/5] xfstests: test f2fs compression+encryption Eric Biggers
2020-10-01 0:25 ` [PATCH 1/5] fscrypt-crypt-util: clean up parsing --block-size and --inode-number Eric Biggers
2020-10-01 0:25 ` Eric Biggers [this message]
2020-10-01 0:25 ` [PATCH 3/5] fscrypt-crypt-util: add --block-number option Eric Biggers
2020-10-01 0:25 ` [PATCH 4/5] common/f2fs: add _require_scratch_f2fs_compression() Eric Biggers
2020-10-01 0:25 ` [PATCH 5/5] f2fs: verify ciphertext of compressed+encrypted file Eric Biggers
2020-10-07 3:48 ` [PATCH 0/5] xfstests: test f2fs compression+encryption Eric Biggers
2020-10-07 4:27 ` [f2fs-dev] " Daeho Jeong
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=20201001002508.328866-3-ebiggers@kernel.org \
--to=ebiggers@kernel.org \
--cc=daeho43@gmail.com \
--cc=fstests@vger.kernel.org \
--cc=jaegeuk@kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fscrypt@vger.kernel.org \
--cc=yuchao0@huawei.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