fscrypt: split up FS_CRYPTO_BLOCK_SIZE

FS_CRYPTO_BLOCK_SIZE is neither the filesystem block size nor the
granularity of encryption.  Rather, it defines two logically separate
constraints that both arise from the block size of the AES cipher:

- The alignment required for the lengths of file contents blocks
- The minimum input/output length for the filenames encryption modes

Since there are way too many things called the "block size", and the
connection with the AES block size is not easily understood, split
FS_CRYPTO_BLOCK_SIZE into two constants FSCRYPT_CONTENTS_ALIGNMENT and
FSCRYPT_FNAME_MIN_MSG_LEN that more clearly describe what they are.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Link: https://lore.kernel.org/r/20220405010914.18519-1-ebiggers@kernel.org
This commit is contained in:
Eric Biggers 2022-04-04 18:09:14 -07:00
parent ce522ba9ef
commit 63cec1389e
4 changed files with 26 additions and 9 deletions

View File

@ -113,7 +113,7 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
if (WARN_ON_ONCE(len <= 0)) if (WARN_ON_ONCE(len <= 0))
return -EINVAL; return -EINVAL;
if (WARN_ON_ONCE(len % FS_CRYPTO_BLOCK_SIZE != 0)) if (WARN_ON_ONCE(len % FSCRYPT_CONTENTS_ALIGNMENT != 0))
return -EINVAL; return -EINVAL;
fscrypt_generate_iv(&iv, lblk_num, ci); fscrypt_generate_iv(&iv, lblk_num, ci);
@ -213,8 +213,8 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks);
* fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place * fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place
* @inode: The inode to which this block belongs * @inode: The inode to which this block belongs
* @page: The page containing the block to encrypt * @page: The page containing the block to encrypt
* @len: Size of block to encrypt. Doesn't need to be a multiple of the * @len: Size of block to encrypt. This must be a multiple of
* fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE. * FSCRYPT_CONTENTS_ALIGNMENT.
* @offs: Byte offset within @page at which the block to encrypt begins * @offs: Byte offset within @page at which the block to encrypt begins
* @lblk_num: Filesystem logical block number of the block, i.e. the 0-based * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
* number of the block within the file * number of the block within the file
@ -283,8 +283,8 @@ EXPORT_SYMBOL(fscrypt_decrypt_pagecache_blocks);
* fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place * fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place
* @inode: The inode to which this block belongs * @inode: The inode to which this block belongs
* @page: The page containing the block to decrypt * @page: The page containing the block to decrypt
* @len: Size of block to decrypt. Doesn't need to be a multiple of the * @len: Size of block to decrypt. This must be a multiple of
* fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE. * FSCRYPT_CONTENTS_ALIGNMENT.
* @offs: Byte offset within @page at which the block to decrypt begins * @offs: Byte offset within @page at which the block to decrypt begins
* @lblk_num: Filesystem logical block number of the block, i.e. the 0-based * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
* number of the block within the file * number of the block within the file

View File

@ -18,6 +18,13 @@
#include <crypto/skcipher.h> #include <crypto/skcipher.h>
#include "fscrypt_private.h" #include "fscrypt_private.h"
/*
* The minimum message length (input and output length), in bytes, for all
* filenames encryption modes. Filenames shorter than this will be zero-padded
* before being encrypted.
*/
#define FSCRYPT_FNAME_MIN_MSG_LEN 16
/* /*
* struct fscrypt_nokey_name - identifier for directory entry when key is absent * struct fscrypt_nokey_name - identifier for directory entry when key is absent
* *
@ -267,7 +274,7 @@ bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
if (orig_len > max_len) if (orig_len > max_len)
return false; return false;
encrypted_len = max(orig_len, (u32)FS_CRYPTO_BLOCK_SIZE); encrypted_len = max_t(u32, orig_len, FSCRYPT_FNAME_MIN_MSG_LEN);
encrypted_len = round_up(encrypted_len, padding); encrypted_len = round_up(encrypted_len, padding);
*encrypted_len_ret = min(encrypted_len, max_len); *encrypted_len_ret = min(encrypted_len, max_len);
return true; return true;
@ -350,7 +357,7 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
return 0; return 0;
} }
if (iname->len < FS_CRYPTO_BLOCK_SIZE) if (iname->len < FSCRYPT_FNAME_MIN_MSG_LEN)
return -EUCLEAN; return -EUCLEAN;
if (fscrypt_has_encryption_key(inode)) if (fscrypt_has_encryption_key(inode))

View File

@ -132,7 +132,7 @@
#define WORST_COMPR_FACTOR 2 #define WORST_COMPR_FACTOR 2
#ifdef CONFIG_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
#define UBIFS_CIPHER_BLOCK_SIZE FS_CRYPTO_BLOCK_SIZE #define UBIFS_CIPHER_BLOCK_SIZE FSCRYPT_CONTENTS_ALIGNMENT
#else #else
#define UBIFS_CIPHER_BLOCK_SIZE 0 #define UBIFS_CIPHER_BLOCK_SIZE 0
#endif #endif

View File

@ -18,7 +18,17 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <uapi/linux/fscrypt.h> #include <uapi/linux/fscrypt.h>
#define FS_CRYPTO_BLOCK_SIZE 16 /*
* The lengths of all file contents blocks must be divisible by this value.
* This is needed to ensure that all contents encryption modes will work, as
* some of the supported modes don't support arbitrarily byte-aligned messages.
*
* Since the needed alignment is 16 bytes, most filesystems will meet this
* requirement naturally, as typical block sizes are powers of 2. However, if a
* filesystem can generate arbitrarily byte-aligned block lengths (e.g., via
* compression), then it will need to pad to this alignment before encryption.
*/
#define FSCRYPT_CONTENTS_ALIGNMENT 16
union fscrypt_policy; union fscrypt_policy;
struct fscrypt_info; struct fscrypt_info;