From: Eric Biggers <ebiggers@xxxxxxxxxx> Calling CBC with ciphertext stealing "CBC-CTS" seems to be more common than calling it "CTS-CBC". E.g., CBC-CTS is used by OpenSSL, Crypto++, RFC3962, and RFC6803. The NIST SP800-38A addendum uses CBC-CS1, CBC-CS2, and CBC-CS3, distinguishing between different CTS conventions but similarly putting the CBC part first. In the interest of avoiding any idiosyncratic terminology, update the fscrypt documentation and the fscrypt_mode "friendly names" to align with the more common convention. Changing the "friendly names" only affects some log messages. The actual mode constants in the API are unchanged; those call it simply "CTS". Add a note to the documentation that clarifies that "CBC" and "CTS" in the API really mean CBC-ESSIV and CBC-CTS, respectively. Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx> --- Documentation/filesystems/fscrypt.rst | 27 +++++++++++++++------------ fs/crypto/keysetup.c | 6 +++--- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index e86b886b64d0e..04eaab01314bc 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -331,90 +331,93 @@ Encryption modes and usage fscrypt allows one encryption mode to be specified for file contents and one encryption mode to be specified for filenames. Different directory trees are permitted to use different encryption modes. Supported modes --------------- Currently, the following pairs of encryption modes are supported: -- AES-256-XTS for contents and AES-256-CTS-CBC for filenames +- AES-256-XTS for contents and AES-256-CBC-CTS for filenames - AES-256-XTS for contents and AES-256-HCTR2 for filenames - Adiantum for both contents and filenames -- AES-128-CBC-ESSIV for contents and AES-128-CTS-CBC for filenames -- SM4-XTS for contents and SM4-CTS-CBC for filenames +- AES-128-CBC-ESSIV for contents and AES-128-CBC-CTS for filenames +- SM4-XTS for contents and SM4-CBC-CTS for filenames + +Note: in the API, "CBC" means CBC-ESSIV, and "CTS" means CBC-CTS. +So, for example, FSCRYPT_MODE_AES_256_CTS means AES-256-CBC-CTS. Authenticated encryption modes are not currently supported because of the difficulty of dealing with ciphertext expansion. Therefore, contents encryption uses a block cipher in `XTS mode <https://en.wikipedia.org/wiki/Disk_encryption_theory#XTS>`_ or `CBC-ESSIV mode <https://en.wikipedia.org/wiki/Disk_encryption_theory#Encrypted_salt-sector_initialization_vector_(ESSIV)>`_, or a wide-block cipher. Filenames encryption uses a -block cipher in `CTS-CBC mode +block cipher in `CBC-CTS mode <https://en.wikipedia.org/wiki/Ciphertext_stealing>`_ or a wide-block cipher. -The (AES-256-XTS, AES-256-CTS-CBC) pair is the recommended default. +The (AES-256-XTS, AES-256-CBC-CTS) pair is the recommended default. It is also the only option that is *guaranteed* to always be supported if the kernel supports fscrypt at all; see `Kernel config options`_. The (AES-256-XTS, AES-256-HCTR2) pair is also a good choice that upgrades the filenames encryption to use a wide-block cipher. (A *wide-block cipher*, also called a tweakable super-pseudorandom permutation, has the property that changing one bit scrambles the entire result.) As described in `Filenames encryption`_, a wide-block -cipher is the ideal mode for the problem domain, though CTS-CBC is the +cipher is the ideal mode for the problem domain, though CBC-CTS is the "least bad" choice among the alternatives. For more information about HCTR2, see `the HCTR2 paper <https://eprint.iacr.org/2021/1441.pdf>`_. Adiantum is recommended on systems where AES is too slow due to lack of hardware acceleration for AES. Adiantum is a wide-block cipher that uses XChaCha12 and AES-256 as its underlying components. Most of the work is done by XChaCha12, which is much faster than AES when AES acceleration is unavailable. For more information about Adiantum, see `the Adiantum paper <https://eprint.iacr.org/2018/720.pdf>`_. -The (AES-128-CBC-ESSIV, AES-128-CTS-CBC) pair exists only to support +The (AES-128-CBC-ESSIV, AES-128-CBC-CTS) pair exists only to support systems whose only form of AES acceleration is an off-CPU crypto accelerator such as CAAM or CESA that does not support XTS. The remaining mode pairs are the "national pride ciphers": -- (SM4-XTS, SM4-CTS-CBC) +- (SM4-XTS, SM4-CBC-CTS) Generally speaking, these ciphers aren't "bad" per se, but they receive limited security review compared to the usual choices such as AES and ChaCha. They also don't bring much new to the table. It is suggested to only use these ciphers where their use is mandated. Kernel config options --------------------- Enabling fscrypt support (CONFIG_FS_ENCRYPTION) automatically pulls in only the basic support from the crypto API needed to use AES-256-XTS -and AES-256-CTS-CBC encryption. For optimal performance, it is +and AES-256-CBC-CTS encryption. For optimal performance, it is strongly recommended to also enable any available platform-specific kconfig options that provide acceleration for the algorithm(s) you wish to use. Support for any "non-default" encryption modes typically requires extra kconfig options as well. Below, some relevant options are listed by encryption mode. Note, acceleration options not listed below may be available for your platform; refer to the kconfig menus. File contents encryption can also be configured to use inline encryption hardware instead of the kernel crypto API (see `Inline encryption support`_); in that case, the file contents mode doesn't need to supported in the kernel crypto API, but the filenames mode still does. -- AES-256-XTS and AES-256-CTS-CBC +- AES-256-XTS and AES-256-CBC-CTS - Recommended: - arm64: CONFIG_CRYPTO_AES_ARM64_CE_BLK - x86: CONFIG_CRYPTO_AES_NI_INTEL - AES-256-HCTR2 - Mandatory: - CONFIG_CRYPTO_HCTR2 - Recommended: - arm64: CONFIG_CRYPTO_AES_ARM64_CE_BLK - arm64: CONFIG_CRYPTO_POLYVAL_ARM64_CE @@ -426,21 +429,21 @@ API, but the filenames mode still does. - CONFIG_CRYPTO_ADIANTUM - Recommended: - arm32: CONFIG_CRYPTO_CHACHA20_NEON - arm32: CONFIG_CRYPTO_NHPOLY1305_NEON - arm64: CONFIG_CRYPTO_CHACHA20_NEON - arm64: CONFIG_CRYPTO_NHPOLY1305_NEON - x86: CONFIG_CRYPTO_CHACHA20_X86_64 - x86: CONFIG_CRYPTO_NHPOLY1305_SSE2 - x86: CONFIG_CRYPTO_NHPOLY1305_AVX2 -- AES-128-CBC-ESSIV and AES-128-CTS-CBC: +- AES-128-CBC-ESSIV and AES-128-CBC-CTS: - Mandatory: - CONFIG_CRYPTO_ESSIV - CONFIG_CRYPTO_SHA256 or another SHA-256 implementation - Recommended: - AES-CBC acceleration fscrypt also uses HMAC-SHA512 for key derivation, so enabling SHA-512 acceleration is recommended: - SHA-512 @@ -514,21 +517,21 @@ Filenames encryption For filenames, each full filename is encrypted at once. Because of the requirements to retain support for efficient directory lookups and filenames of up to 255 bytes, the same IV is used for every filename in a directory. However, each encrypted directory still uses a unique key, or alternatively has the file's nonce (for `DIRECT_KEY policies`_) or inode number (for `IV_INO_LBLK_64 policies`_) included in the IVs. Thus, IV reuse is limited to within a single directory. -With CTS-CBC, the IV reuse means that when the plaintext filenames share a +With CBC-CTS, the IV reuse means that when the plaintext filenames share a common prefix at least as long as the cipher block size (16 bytes for AES), the corresponding encrypted filenames will also share a common prefix. This is undesirable. Adiantum and HCTR2 do not have this weakness, as they are wide-block encryption modes. All supported filenames encryption modes accept any plaintext length >= 16 bytes; cipher block alignment is not required. However, filenames shorter than 16 bytes are NUL-padded to 16 bytes before being encrypted. In addition, to reduce leakage of filename lengths via their ciphertexts, all filenames are NUL-padded to the next 4, 8, diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 9a0a40c81bf29..b4fe01ea4bd4c 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -16,51 +16,51 @@ struct fscrypt_mode fscrypt_modes[] = { [FSCRYPT_MODE_AES_256_XTS] = { .friendly_name = "AES-256-XTS", .cipher_str = "xts(aes)", .keysize = 64, .security_strength = 32, .ivsize = 16, .blk_crypto_mode = BLK_ENCRYPTION_MODE_AES_256_XTS, }, [FSCRYPT_MODE_AES_256_CTS] = { - .friendly_name = "AES-256-CTS-CBC", + .friendly_name = "AES-256-CBC-CTS", .cipher_str = "cts(cbc(aes))", .keysize = 32, .security_strength = 32, .ivsize = 16, }, [FSCRYPT_MODE_AES_128_CBC] = { .friendly_name = "AES-128-CBC-ESSIV", .cipher_str = "essiv(cbc(aes),sha256)", .keysize = 16, .security_strength = 16, .ivsize = 16, .blk_crypto_mode = BLK_ENCRYPTION_MODE_AES_128_CBC_ESSIV, }, [FSCRYPT_MODE_AES_128_CTS] = { - .friendly_name = "AES-128-CTS-CBC", + .friendly_name = "AES-128-CBC-CTS", .cipher_str = "cts(cbc(aes))", .keysize = 16, .security_strength = 16, .ivsize = 16, }, [FSCRYPT_MODE_SM4_XTS] = { .friendly_name = "SM4-XTS", .cipher_str = "xts(sm4)", .keysize = 32, .security_strength = 16, .ivsize = 16, .blk_crypto_mode = BLK_ENCRYPTION_MODE_SM4_XTS, }, [FSCRYPT_MODE_SM4_CTS] = { - .friendly_name = "SM4-CTS-CBC", + .friendly_name = "SM4-CBC-CTS", .cipher_str = "cts(cbc(sm4))", .keysize = 16, .security_strength = 16, .ivsize = 16, }, [FSCRYPT_MODE_ADIANTUM] = { .friendly_name = "Adiantum", .cipher_str = "adiantum(xchacha12,aes)", .keysize = 32, .security_strength = 32, base-commit: d3a7bd4200762d11c33ebe7e2c47c5813ddc65b4 -- 2.43.2
![]() |