mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
fscrypt updates for 5.16
Some cleanups for fs/crypto/: - Allow 256-bit master keys with AES-256-XTS - Improve documentation and comments - Remove unneeded field fscrypt_operations::max_namelen -----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCYX8U4hQcZWJpZ2dlcnNA Z29vZ2xlLmNvbQAKCRDzXCl4vpKOKyXYAP0d7BNuKsMyw6qlzLMxbaO5wdTg2HaD 04ApVeHM6qp7IQEA/Ve2Mr+BcPOZ7E6io8haZtXs0MrRMYeessKWcWMCdQ0= =2WNZ -----END PGP SIGNATURE----- Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt Pull fscrypt updates from Eric Biggers: "Some cleanups for fs/crypto/: - Allow 256-bit master keys with AES-256-XTS - Improve documentation and comments - Remove unneeded field fscrypt_operations::max_namelen" * tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt: fscrypt: improve a few comments fscrypt: allow 256-bit master keys with AES-256-XTS fscrypt: improve documentation for inline encryption fscrypt: clean up comments in bio.c fscrypt: remove fscrypt_operations::max_namelen
This commit is contained in:
commit
cd3e8ea847
@ -1,5 +1,7 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. _inline_encryption:
|
||||
|
||||
=================
|
||||
Inline Encryption
|
||||
=================
|
||||
|
@ -77,11 +77,11 @@ Side-channel attacks
|
||||
|
||||
fscrypt is only resistant to side-channel attacks, such as timing or
|
||||
electromagnetic attacks, to the extent that the underlying Linux
|
||||
Cryptographic API algorithms are. If a vulnerable algorithm is used,
|
||||
such as a table-based implementation of AES, it may be possible for an
|
||||
attacker to mount a side channel attack against the online system.
|
||||
Side channel attacks may also be mounted against applications
|
||||
consuming decrypted data.
|
||||
Cryptographic API algorithms or inline encryption hardware are. If a
|
||||
vulnerable algorithm is used, such as a table-based implementation of
|
||||
AES, it may be possible for an attacker to mount a side channel attack
|
||||
against the online system. Side channel attacks may also be mounted
|
||||
against applications consuming decrypted data.
|
||||
|
||||
Unauthorized file access
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -176,11 +176,11 @@ Master Keys
|
||||
|
||||
Each encrypted directory tree is protected by a *master key*. Master
|
||||
keys can be up to 64 bytes long, and must be at least as long as the
|
||||
greater of the key length needed by the contents and filenames
|
||||
encryption modes being used. For example, if AES-256-XTS is used for
|
||||
contents encryption, the master key must be 64 bytes (512 bits). Note
|
||||
that the XTS mode is defined to require a key twice as long as that
|
||||
required by the underlying block cipher.
|
||||
greater of the security strength of the contents and filenames
|
||||
encryption modes being used. For example, if any AES-256 mode is
|
||||
used, the master key must be at least 256 bits, i.e. 32 bytes. A
|
||||
stricter requirement applies if the key is used by a v1 encryption
|
||||
policy and AES-256-XTS is used; such keys must be 64 bytes.
|
||||
|
||||
To "unlock" an encrypted directory tree, userspace must provide the
|
||||
appropriate master key. There can be any number of master keys, each
|
||||
@ -1135,6 +1135,50 @@ where applications may later write sensitive data. It is recommended
|
||||
that systems implementing a form of "verified boot" take advantage of
|
||||
this by validating all top-level encryption policies prior to access.
|
||||
|
||||
Inline encryption support
|
||||
=========================
|
||||
|
||||
By default, fscrypt uses the kernel crypto API for all cryptographic
|
||||
operations (other than HKDF, which fscrypt partially implements
|
||||
itself). The kernel crypto API supports hardware crypto accelerators,
|
||||
but only ones that work in the traditional way where all inputs and
|
||||
outputs (e.g. plaintexts and ciphertexts) are in memory. fscrypt can
|
||||
take advantage of such hardware, but the traditional acceleration
|
||||
model isn't particularly efficient and fscrypt hasn't been optimized
|
||||
for it.
|
||||
|
||||
Instead, many newer systems (especially mobile SoCs) have *inline
|
||||
encryption hardware* that can encrypt/decrypt data while it is on its
|
||||
way to/from the storage device. Linux supports inline encryption
|
||||
through a set of extensions to the block layer called *blk-crypto*.
|
||||
blk-crypto allows filesystems to attach encryption contexts to bios
|
||||
(I/O requests) to specify how the data will be encrypted or decrypted
|
||||
in-line. For more information about blk-crypto, see
|
||||
:ref:`Documentation/block/inline-encryption.rst <inline_encryption>`.
|
||||
|
||||
On supported filesystems (currently ext4 and f2fs), fscrypt can use
|
||||
blk-crypto instead of the kernel crypto API to encrypt/decrypt file
|
||||
contents. To enable this, set CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y in
|
||||
the kernel configuration, and specify the "inlinecrypt" mount option
|
||||
when mounting the filesystem.
|
||||
|
||||
Note that the "inlinecrypt" mount option just specifies to use inline
|
||||
encryption when possible; it doesn't force its use. fscrypt will
|
||||
still fall back to using the kernel crypto API on files where the
|
||||
inline encryption hardware doesn't have the needed crypto capabilities
|
||||
(e.g. support for the needed encryption algorithm and data unit size)
|
||||
and where blk-crypto-fallback is unusable. (For blk-crypto-fallback
|
||||
to be usable, it must be enabled in the kernel configuration with
|
||||
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y.)
|
||||
|
||||
Currently fscrypt always uses the filesystem block size (which is
|
||||
usually 4096 bytes) as the data unit size. Therefore, it can only use
|
||||
inline encryption hardware that supports that data unit size.
|
||||
|
||||
Inline encryption doesn't affect the ciphertext or other aspects of
|
||||
the on-disk format, so users may freely switch back and forth between
|
||||
using "inlinecrypt" and not using "inlinecrypt".
|
||||
|
||||
Implementation details
|
||||
======================
|
||||
|
||||
@ -1184,6 +1228,13 @@ keys`_ and `DIRECT_KEY policies`_.
|
||||
Data path changes
|
||||
-----------------
|
||||
|
||||
When inline encryption is used, filesystems just need to associate
|
||||
encryption contexts with bios to specify how the block layer or the
|
||||
inline encryption hardware will encrypt/decrypt the file contents.
|
||||
|
||||
When inline encryption isn't used, filesystems must encrypt/decrypt
|
||||
the file contents themselves, as described below:
|
||||
|
||||
For the read path (->readpage()) of regular files, filesystems can
|
||||
read the ciphertext into the page cache and decrypt it in-place. The
|
||||
page lock must be held until decryption has finished, to prevent the
|
||||
@ -1197,18 +1248,6 @@ buffer. Some filesystems, such as UBIFS, already use temporary
|
||||
buffers regardless of encryption. Other filesystems, such as ext4 and
|
||||
F2FS, have to allocate bounce pages specially for encryption.
|
||||
|
||||
Fscrypt is also able to use inline encryption hardware instead of the
|
||||
kernel crypto API for en/decryption of file contents. When possible,
|
||||
and if directed to do so (by specifying the 'inlinecrypt' mount option
|
||||
for an ext4/F2FS filesystem), it adds encryption contexts to bios and
|
||||
uses blk-crypto to perform the en/decryption instead of making use of
|
||||
the above read/write path changes. Of course, even if directed to
|
||||
make use of inline encryption, fscrypt will only be able to do so if
|
||||
either hardware inline encryption support is available for the
|
||||
selected encryption algorithm or CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK
|
||||
is selected. If neither is the case, fscrypt will fall back to using
|
||||
the above mentioned read/write path changes for en/decryption.
|
||||
|
||||
Filename hashing and encoding
|
||||
-----------------------------
|
||||
|
||||
|
@ -1,23 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* This contains encryption functions for per-file encryption.
|
||||
* Utility functions for file contents encryption/decryption on
|
||||
* block device-based filesystems.
|
||||
*
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
* Copyright (C) 2015, Motorola Mobility
|
||||
*
|
||||
* Written by Michael Halcrow, 2014.
|
||||
*
|
||||
* Filename encryption additions
|
||||
* Uday Savagaonkar, 2014
|
||||
* Encryption policy handling additions
|
||||
* Ildar Muslukhov, 2014
|
||||
* Add fscrypt_pullback_bio_page()
|
||||
* Jaegeuk Kim, 2015.
|
||||
*
|
||||
* This has not yet undergone a rigorous security audit.
|
||||
*
|
||||
* The usage of AES-XTS should conform to recommendations in NIST
|
||||
* Special Publication 800-38E and IEEE P1619/D16.
|
||||
*/
|
||||
|
||||
#include <linux/pagemap.h>
|
||||
@ -26,6 +13,21 @@
|
||||
#include <linux/namei.h>
|
||||
#include "fscrypt_private.h"
|
||||
|
||||
/**
|
||||
* fscrypt_decrypt_bio() - decrypt the contents of a bio
|
||||
* @bio: the bio to decrypt
|
||||
*
|
||||
* Decrypt the contents of a "read" bio following successful completion of the
|
||||
* underlying disk read. The bio must be reading a whole number of blocks of an
|
||||
* encrypted file directly into the page cache. If the bio is reading the
|
||||
* ciphertext into bounce pages instead of the page cache (for example, because
|
||||
* the file is also compressed, so decompression is required after decryption),
|
||||
* then this function isn't applicable. This function may sleep, so it must be
|
||||
* called from a workqueue rather than from the bio's bi_end_io callback.
|
||||
*
|
||||
* This function sets PG_error on any pages that contain any blocks that failed
|
||||
* to be decrypted. The filesystem must not mark such pages uptodate.
|
||||
*/
|
||||
void fscrypt_decrypt_bio(struct bio *bio)
|
||||
{
|
||||
struct bio_vec *bv;
|
||||
|
@ -429,8 +429,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
|
||||
|
||||
if (fscrypt_has_encryption_key(dir)) {
|
||||
if (!fscrypt_fname_encrypted_size(&dir->i_crypt_info->ci_policy,
|
||||
iname->len,
|
||||
dir->i_sb->s_cop->max_namelen,
|
||||
iname->len, NAME_MAX,
|
||||
&fname->crypto_buf.len))
|
||||
return -ENAMETOOLONG;
|
||||
fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,
|
||||
|
@ -20,6 +20,11 @@
|
||||
|
||||
#define FSCRYPT_FILE_NONCE_SIZE 16
|
||||
|
||||
/*
|
||||
* Minimum size of an fscrypt master key. Note: a longer key will be required
|
||||
* if ciphers with a 256-bit security strength are used. This is just the
|
||||
* absolute minimum, which applies when only 128-bit encryption is used.
|
||||
*/
|
||||
#define FSCRYPT_MIN_KEY_SIZE 16
|
||||
|
||||
#define FSCRYPT_CONTEXT_V1 1
|
||||
@ -413,7 +418,11 @@ struct fscrypt_master_key_secret {
|
||||
*/
|
||||
struct fscrypt_hkdf hkdf;
|
||||
|
||||
/* Size of the raw key in bytes. Set even if ->raw isn't set. */
|
||||
/*
|
||||
* Size of the raw key in bytes. This remains set even if ->raw was
|
||||
* zeroized due to no longer being needed. I.e. we still remember the
|
||||
* size of the key even if we don't need to remember the key itself.
|
||||
*/
|
||||
u32 size;
|
||||
|
||||
/* For v1 policy keys: the raw key. Wiped for v2 policy keys. */
|
||||
@ -549,8 +558,9 @@ int __init fscrypt_init_keyring(void);
|
||||
struct fscrypt_mode {
|
||||
const char *friendly_name;
|
||||
const char *cipher_str;
|
||||
int keysize;
|
||||
int ivsize;
|
||||
int keysize; /* key size in bytes */
|
||||
int security_strength; /* security strength in bytes */
|
||||
int ivsize; /* IV size in bytes */
|
||||
int logged_impl_name;
|
||||
enum blk_crypto_mode_num blk_crypto_mode;
|
||||
};
|
||||
|
@ -16,9 +16,14 @@
|
||||
|
||||
/*
|
||||
* HKDF supports any unkeyed cryptographic hash algorithm, but fscrypt uses
|
||||
* SHA-512 because it is reasonably secure and efficient; and since it produces
|
||||
* a 64-byte digest, deriving an AES-256-XTS key preserves all 64 bytes of
|
||||
* entropy from the master key and requires only one iteration of HKDF-Expand.
|
||||
* SHA-512 because it is well-established, secure, and reasonably efficient.
|
||||
*
|
||||
* HKDF-SHA256 was also considered, as its 256-bit security strength would be
|
||||
* sufficient here. A 512-bit security strength is "nice to have", though.
|
||||
* Also, on 64-bit CPUs, SHA-512 is usually just as fast as SHA-256. In the
|
||||
* common case of deriving an AES-256-XTS key (512 bits), that can result in
|
||||
* HKDF-SHA512 being much faster than HKDF-SHA256, as the longer digest size of
|
||||
* SHA-512 causes HKDF-Expand to only need to do one iteration rather than two.
|
||||
*/
|
||||
#define HKDF_HMAC_ALG "hmac(sha512)"
|
||||
#define HKDF_HASHLEN SHA512_DIGEST_SIZE
|
||||
|
@ -19,6 +19,7 @@ struct fscrypt_mode fscrypt_modes[] = {
|
||||
.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,
|
||||
},
|
||||
@ -26,12 +27,14 @@ struct fscrypt_mode fscrypt_modes[] = {
|
||||
.friendly_name = "AES-256-CTS-CBC",
|
||||
.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,
|
||||
},
|
||||
@ -39,12 +42,14 @@ struct fscrypt_mode fscrypt_modes[] = {
|
||||
.friendly_name = "AES-128-CTS-CBC",
|
||||
.cipher_str = "cts(cbc(aes))",
|
||||
.keysize = 16,
|
||||
.security_strength = 16,
|
||||
.ivsize = 16,
|
||||
},
|
||||
[FSCRYPT_MODE_ADIANTUM] = {
|
||||
.friendly_name = "Adiantum",
|
||||
.cipher_str = "adiantum(xchacha12,aes)",
|
||||
.keysize = 32,
|
||||
.security_strength = 32,
|
||||
.ivsize = 32,
|
||||
.blk_crypto_mode = BLK_ENCRYPTION_MODE_ADIANTUM,
|
||||
},
|
||||
@ -117,8 +122,9 @@ err_free_tfm:
|
||||
|
||||
/*
|
||||
* Prepare the crypto transform object or blk-crypto key in @prep_key, given the
|
||||
* raw key, encryption mode, and flag indicating which encryption implementation
|
||||
* (fs-layer or blk-crypto) will be used.
|
||||
* raw key, encryption mode (@ci->ci_mode), flag indicating which encryption
|
||||
* implementation (fs-layer or blk-crypto) will be used (@ci->ci_inlinecrypt),
|
||||
* and IV generation method (@ci->ci_policy.flags).
|
||||
*/
|
||||
int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key,
|
||||
const u8 *raw_key, const struct fscrypt_info *ci)
|
||||
@ -357,6 +363,45 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the size of the given master key (@mk) is appropriate for the
|
||||
* encryption settings which a particular file will use (@ci).
|
||||
*
|
||||
* If the file uses a v1 encryption policy, then the master key must be at least
|
||||
* as long as the derived key, as this is a requirement of the v1 KDF.
|
||||
*
|
||||
* Otherwise, the KDF can accept any size key, so we enforce a slightly looser
|
||||
* requirement: we require that the size of the master key be at least the
|
||||
* maximum security strength of any algorithm whose key will be derived from it
|
||||
* (but in practice we only need to consider @ci->ci_mode, since any other
|
||||
* possible subkeys such as DIRHASH and INODE_HASH will never increase the
|
||||
* required key size over @ci->ci_mode). This allows AES-256-XTS keys to be
|
||||
* derived from a 256-bit master key, which is cryptographically sufficient,
|
||||
* rather than requiring a 512-bit master key which is unnecessarily long. (We
|
||||
* still allow 512-bit master keys if the user chooses to use them, though.)
|
||||
*/
|
||||
static bool fscrypt_valid_master_key_size(const struct fscrypt_master_key *mk,
|
||||
const struct fscrypt_info *ci)
|
||||
{
|
||||
unsigned int min_keysize;
|
||||
|
||||
if (ci->ci_policy.version == FSCRYPT_POLICY_V1)
|
||||
min_keysize = ci->ci_mode->keysize;
|
||||
else
|
||||
min_keysize = ci->ci_mode->security_strength;
|
||||
|
||||
if (mk->mk_secret.size < min_keysize) {
|
||||
fscrypt_warn(NULL,
|
||||
"key with %s %*phN is too short (got %u bytes, need %u+ bytes)",
|
||||
master_key_spec_type(&mk->mk_spec),
|
||||
master_key_spec_len(&mk->mk_spec),
|
||||
(u8 *)&mk->mk_spec.u,
|
||||
mk->mk_secret.size, min_keysize);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the master key, then set up the inode's actual encryption key.
|
||||
*
|
||||
@ -422,18 +467,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
|
||||
goto out_release_key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Require that the master key be at least as long as the derived key.
|
||||
* Otherwise, the derived key cannot possibly contain as much entropy as
|
||||
* that required by the encryption mode it will be used for. For v1
|
||||
* policies it's also required for the KDF to work at all.
|
||||
*/
|
||||
if (mk->mk_secret.size < ci->ci_mode->keysize) {
|
||||
fscrypt_warn(NULL,
|
||||
"key with %s %*phN is too short (got %u bytes, need %u+ bytes)",
|
||||
master_key_spec_type(&mk_spec),
|
||||
master_key_spec_len(&mk_spec), (u8 *)&mk_spec.u,
|
||||
mk->mk_secret.size, ci->ci_mode->keysize);
|
||||
if (!fscrypt_valid_master_key_size(mk, ci)) {
|
||||
err = -ENOKEY;
|
||||
goto out_release_key;
|
||||
}
|
||||
|
@ -1572,7 +1572,6 @@ static const struct fscrypt_operations ext4_cryptops = {
|
||||
.set_context = ext4_set_context,
|
||||
.get_dummy_policy = ext4_get_dummy_policy,
|
||||
.empty_dir = ext4_empty_dir,
|
||||
.max_namelen = EXT4_NAME_LEN,
|
||||
.has_stable_inodes = ext4_has_stable_inodes,
|
||||
.get_ino_and_lblk_bits = ext4_get_ino_and_lblk_bits,
|
||||
};
|
||||
|
@ -2976,7 +2976,6 @@ static const struct fscrypt_operations f2fs_cryptops = {
|
||||
.set_context = f2fs_set_context,
|
||||
.get_dummy_policy = f2fs_get_dummy_policy,
|
||||
.empty_dir = f2fs_empty_dir,
|
||||
.max_namelen = F2FS_NAME_LEN,
|
||||
.has_stable_inodes = f2fs_has_stable_inodes,
|
||||
.get_ino_and_lblk_bits = f2fs_get_ino_and_lblk_bits,
|
||||
.get_num_devices = f2fs_get_num_devices,
|
||||
|
@ -82,5 +82,4 @@ const struct fscrypt_operations ubifs_crypt_operations = {
|
||||
.get_context = ubifs_crypt_get_context,
|
||||
.set_context = ubifs_crypt_set_context,
|
||||
.empty_dir = ubifs_crypt_empty_dir,
|
||||
.max_namelen = UBIFS_MAX_NLEN,
|
||||
};
|
||||
|
@ -118,9 +118,6 @@ struct fscrypt_operations {
|
||||
*/
|
||||
bool (*empty_dir)(struct inode *inode);
|
||||
|
||||
/* The filesystem's maximum ciphertext filename length, in bytes */
|
||||
unsigned int max_namelen;
|
||||
|
||||
/*
|
||||
* Check whether the filesystem's inode numbers and UUID are stable,
|
||||
* meaning that they will never be changed even by offline operations
|
||||
|
Loading…
Reference in New Issue
Block a user