Skip to content

Commit 8094c3c

Browse files
ebiggerstytso
authored andcommitted
fscrypt: add Adiantum support
Add support for the Adiantum encryption mode to fscrypt. Adiantum is a tweakable, length-preserving encryption mode with security provably reducible to that of XChaCha12 and AES-256, subject to a security bound. It's also a true wide-block mode, unlike XTS. See the paper "Adiantum: length-preserving encryption for entry-level processors" (https://eprint.iacr.org/2018/720.pdf) for more details. Also see commit 059c2a4 ("crypto: adiantum - add Adiantum support"). On sufficiently long messages, Adiantum's bottlenecks are XChaCha12 and the NH hash function. These algorithms are fast even on processors without dedicated crypto instructions. Adiantum makes it feasible to enable storage encryption on low-end mobile devices that lack AES instructions; currently such devices are unencrypted. On ARM Cortex-A7, on 4096-byte messages Adiantum encryption is about 4 times faster than AES-256-XTS encryption; decryption is about 5 times faster. In fscrypt, Adiantum is suitable for encrypting both file contents and names. With filenames, it fixes a known weakness: when two filenames in a directory share a common prefix of >= 16 bytes, with CTS-CBC their encrypted filenames share a common prefix too, leaking information. Adiantum does not have this problem. Since Adiantum also accepts long tweaks (IVs), it's also safe to use the master key directly for Adiantum encryption rather than deriving per-file keys, provided that the per-file nonce is included in the IVs and the master key isn't used for any other encryption mode. This configuration saves memory and improves performance. A new fscrypt policy flag is added to allow users to opt-in to this configuration. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 7beb01f commit 8094c3c

File tree

7 files changed

+468
-188
lines changed

7 files changed

+468
-188
lines changed

Documentation/filesystems/fscrypt.rst

Lines changed: 102 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -132,47 +132,28 @@ designed for this purpose be used, such as scrypt, PBKDF2, or Argon2.
132132
Per-file keys
133133
-------------
134134

135-
Master keys are not used to encrypt file contents or names directly.
136-
Instead, a unique key is derived for each encrypted file, including
137-
each regular file, directory, and symbolic link. This has several
138-
advantages:
139-
140-
- In cryptosystems, the same key material should never be used for
141-
different purposes. Using the master key as both an XTS key for
142-
contents encryption and as a CTS-CBC key for filenames encryption
143-
would violate this rule.
144-
- Per-file keys simplify the choice of IVs (Initialization Vectors)
145-
for contents encryption. Without per-file keys, to ensure IV
146-
uniqueness both the inode and logical block number would need to be
147-
encoded in the IVs. This would make it impossible to renumber
148-
inodes, which e.g. ``resize2fs`` can do when resizing an ext4
149-
filesystem. With per-file keys, it is sufficient to encode just the
150-
logical block number in the IVs.
151-
- Per-file keys strengthen the encryption of filenames, where IVs are
152-
reused out of necessity. With a unique key per directory, IV reuse
153-
is limited to within a single directory.
154-
- Per-file keys allow individual files to be securely erased simply by
155-
securely erasing their keys. (Not yet implemented.)
156-
157-
A KDF (Key Derivation Function) is used to derive per-file keys from
158-
the master key. This is done instead of wrapping a randomly-generated
159-
key for each file because it reduces the size of the encryption xattr,
160-
which for some filesystems makes the xattr more likely to fit in-line
161-
in the filesystem's inode table. With a KDF, only a 16-byte nonce is
162-
required --- long enough to make key reuse extremely unlikely. A
163-
wrapped key, on the other hand, would need to be up to 64 bytes ---
164-
the length of an AES-256-XTS key. Furthermore, currently there is no
165-
requirement to support unlocking a file with multiple alternative
166-
master keys or to support rotating master keys. Instead, the master
167-
keys may be wrapped in userspace, e.g. as done by the `fscrypt
168-
<https://github.com/google/fscrypt>`_ tool.
169-
170-
The current KDF encrypts the master key using the 16-byte nonce as an
171-
AES-128-ECB key. The output is used as the derived key. If the
172-
output is longer than needed, then it is truncated to the needed
173-
length. Truncation is the norm for directories and symlinks, since
174-
those use the CTS-CBC encryption mode which requires a key half as
175-
long as that required by the XTS encryption mode.
135+
Since each master key can protect many files, it is necessary to
136+
"tweak" the encryption of each file so that the same plaintext in two
137+
files doesn't map to the same ciphertext, or vice versa. In most
138+
cases, fscrypt does this by deriving per-file keys. When a new
139+
encrypted inode (regular file, directory, or symlink) is created,
140+
fscrypt randomly generates a 16-byte nonce and stores it in the
141+
inode's encryption xattr. Then, it uses a KDF (Key Derivation
142+
Function) to derive the file's key from the master key and nonce.
143+
144+
The Adiantum encryption mode (see `Encryption modes and usage`_) is
145+
special, since it accepts longer IVs and is suitable for both contents
146+
and filenames encryption. For it, a "direct key" option is offered
147+
where the file's nonce is included in the IVs and the master key is
148+
used for encryption directly. This improves performance; however,
149+
users must not use the same master key for any other encryption mode.
150+
151+
Below, the KDF and design considerations are described in more detail.
152+
153+
The current KDF works by encrypting the master key with AES-128-ECB,
154+
using the file's nonce as the AES key. The output is used as the
155+
derived key. If the output is longer than needed, then it is
156+
truncated to the needed length.
176157

177158
Note: this KDF meets the primary security requirement, which is to
178159
produce unique derived keys that preserve the entropy of the master
@@ -181,6 +162,20 @@ However, it is nonstandard and has some problems such as being
181162
reversible, so it is generally considered to be a mistake! It may be
182163
replaced with HKDF or another more standard KDF in the future.
183164

165+
Key derivation was chosen over key wrapping because wrapped keys would
166+
require larger xattrs which would be less likely to fit in-line in the
167+
filesystem's inode table, and there didn't appear to be any
168+
significant advantages to key wrapping. In particular, currently
169+
there is no requirement to support unlocking a file with multiple
170+
alternative master keys or to support rotating master keys. Instead,
171+
the master keys may be wrapped in userspace, e.g. as is done by the
172+
`fscrypt <https://github.com/google/fscrypt>`_ tool.
173+
174+
Including the inode number in the IVs was considered. However, it was
175+
rejected as it would have prevented ext4 filesystems from being
176+
resized, and by itself still wouldn't have been sufficient to prevent
177+
the same key from being directly reused for both XTS and CTS-CBC.
178+
184179
Encryption modes and usage
185180
==========================
186181

@@ -191,54 +186,80 @@ Currently, the following pairs of encryption modes are supported:
191186

192187
- AES-256-XTS for contents and AES-256-CTS-CBC for filenames
193188
- AES-128-CBC for contents and AES-128-CTS-CBC for filenames
189+
- Adiantum for both contents and filenames
190+
191+
If unsure, you should use the (AES-256-XTS, AES-256-CTS-CBC) pair.
194192

195-
It is strongly recommended to use AES-256-XTS for contents encryption.
196193
AES-128-CBC was added only for low-powered embedded devices with
197194
crypto accelerators such as CAAM or CESA that do not support XTS.
198195

196+
Adiantum is a (primarily) stream cipher-based mode that is fast even
197+
on CPUs without dedicated crypto instructions. It's also a true
198+
wide-block mode, unlike XTS. It can also eliminate the need to derive
199+
per-file keys. However, it depends on the security of two primitives,
200+
XChaCha12 and AES-256, rather than just one. See the paper
201+
"Adiantum: length-preserving encryption for entry-level processors"
202+
(https://eprint.iacr.org/2018/720.pdf) for more details. To use
203+
Adiantum, CONFIG_CRYPTO_ADIANTUM must be enabled. Also, fast
204+
implementations of ChaCha and NHPoly1305 should be enabled, e.g.
205+
CONFIG_CRYPTO_CHACHA20_NEON and CONFIG_CRYPTO_NHPOLY1305_NEON for ARM.
206+
199207
New encryption modes can be added relatively easily, without changes
200208
to individual filesystems. However, authenticated encryption (AE)
201209
modes are not currently supported because of the difficulty of dealing
202210
with ciphertext expansion.
203211

212+
Contents encryption
213+
-------------------
214+
204215
For file contents, each filesystem block is encrypted independently.
205216
Currently, only the case where the filesystem block size is equal to
206-
the system's page size (usually 4096 bytes) is supported. With the
207-
XTS mode of operation (recommended), the logical block number within
208-
the file is used as the IV. With the CBC mode of operation (not
209-
recommended), ESSIV is used; specifically, the IV for CBC is the
210-
logical block number encrypted with AES-256, where the AES-256 key is
211-
the SHA-256 hash of the inode's data encryption key.
212-
213-
For filenames, the full filename is encrypted at once. Because of the
214-
requirements to retain support for efficient directory lookups and
215-
filenames of up to 255 bytes, a constant initialization vector (IV) is
216-
used. However, each encrypted directory uses a unique key, which
217-
limits IV reuse to within a single directory. Note that IV reuse in
218-
the context of CTS-CBC encryption means that when the original
219-
filenames share a common prefix at least as long as the cipher block
220-
size (16 bytes for AES), the corresponding encrypted filenames will
221-
also share a common prefix. This is undesirable; it may be fixed in
222-
the future by switching to an encryption mode that is a strong
223-
pseudorandom permutation on arbitrary-length messages, e.g. the HEH
224-
(Hash-Encrypt-Hash) mode.
225-
226-
Since filenames are encrypted with the CTS-CBC mode of operation, the
227-
plaintext and ciphertext filenames need not be multiples of the AES
228-
block size, i.e. 16 bytes. However, the minimum size that can be
229-
encrypted is 16 bytes, so shorter filenames are NUL-padded to 16 bytes
230-
before being encrypted. In addition, to reduce leakage of filename
231-
lengths via their ciphertexts, all filenames are NUL-padded to the
232-
next 4, 8, 16, or 32-byte boundary (configurable). 32 is recommended
233-
since this provides the best confidentiality, at the cost of making
234-
directory entries consume slightly more space. Note that since NUL
235-
(``\0``) is not otherwise a valid character in filenames, the padding
236-
will never produce duplicate plaintexts.
217+
the system's page size (usually 4096 bytes) is supported.
218+
219+
Each block's IV is set to the logical block number within the file as
220+
a little endian number, except that:
221+
222+
- With CBC mode encryption, ESSIV is also used. Specifically, each IV
223+
is encrypted with AES-256 where the AES-256 key is the SHA-256 hash
224+
of the file's data encryption key.
225+
226+
- In the "direct key" configuration (FS_POLICY_FLAG_DIRECT_KEY set in
227+
the fscrypt_policy), the file's nonce is also appended to the IV.
228+
Currently this is only allowed with the Adiantum encryption mode.
229+
230+
Filenames encryption
231+
--------------------
232+
233+
For filenames, each full filename is encrypted at once. Because of
234+
the requirements to retain support for efficient directory lookups and
235+
filenames of up to 255 bytes, the same IV is used for every filename
236+
in a directory.
237+
238+
However, each encrypted directory still uses a unique key; or
239+
alternatively (for the "direct key" configuration) has the file's
240+
nonce included in the IVs. Thus, IV reuse is limited to within a
241+
single directory.
242+
243+
With CTS-CBC, the IV reuse means that when the plaintext filenames
244+
share a common prefix at least as long as the cipher block size (16
245+
bytes for AES), the corresponding encrypted filenames will also share
246+
a common prefix. This is undesirable. Adiantum does not have this
247+
weakness, as it is a wide-block encryption mode.
248+
249+
All supported filenames encryption modes accept any plaintext length
250+
>= 16 bytes; cipher block alignment is not required. However,
251+
filenames shorter than 16 bytes are NUL-padded to 16 bytes before
252+
being encrypted. In addition, to reduce leakage of filename lengths
253+
via their ciphertexts, all filenames are NUL-padded to the next 4, 8,
254+
16, or 32-byte boundary (configurable). 32 is recommended since this
255+
provides the best confidentiality, at the cost of making directory
256+
entries consume slightly more space. Note that since NUL (``\0``) is
257+
not otherwise a valid character in filenames, the padding will never
258+
produce duplicate plaintexts.
237259

238260
Symbolic link targets are considered a type of filename and are
239-
encrypted in the same way as filenames in directory entries. Each
240-
symlink also uses a unique key; hence, the hardcoded IV is not a
241-
problem for symlinks.
261+
encrypted in the same way as filenames in directory entries, except
262+
that IV reuse is not a problem as each symlink has its own inode.
242263

243264
User API
244265
========
@@ -272,9 +293,13 @@ This structure must be initialized as follows:
272293
and FS_ENCRYPTION_MODE_AES_256_CTS (4) for
273294
``filenames_encryption_mode``.
274295

275-
- ``flags`` must be set to a value from ``<linux/fs.h>`` which
296+
- ``flags`` must contain a value from ``<linux/fs.h>`` which
276297
identifies the amount of NUL-padding to use when encrypting
277298
filenames. If unsure, use FS_POLICY_FLAGS_PAD_32 (0x3).
299+
In addition, if the chosen encryption modes are both
300+
FS_ENCRYPTION_MODE_ADIANTUM, this can contain
301+
FS_POLICY_FLAG_DIRECT_KEY to specify that the master key should be
302+
used directly, without key derivation.
278303

279304
- ``master_key_descriptor`` specifies how to find the master key in
280305
the keyring; see `Adding keys`_. It is up to userspace to choose a

fs/crypto/crypto.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,25 @@ struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags)
133133
}
134134
EXPORT_SYMBOL(fscrypt_get_ctx);
135135

136+
void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
137+
const struct fscrypt_info *ci)
138+
{
139+
memset(iv, 0, ci->ci_mode->ivsize);
140+
iv->lblk_num = cpu_to_le64(lblk_num);
141+
142+
if (ci->ci_flags & FS_POLICY_FLAG_DIRECT_KEY)
143+
memcpy(iv->nonce, ci->ci_nonce, FS_KEY_DERIVATION_NONCE_SIZE);
144+
145+
if (ci->ci_essiv_tfm != NULL)
146+
crypto_cipher_encrypt_one(ci->ci_essiv_tfm, iv->raw, iv->raw);
147+
}
148+
136149
int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
137150
u64 lblk_num, struct page *src_page,
138151
struct page *dest_page, unsigned int len,
139152
unsigned int offs, gfp_t gfp_flags)
140153
{
141-
struct {
142-
__le64 index;
143-
u8 padding[FS_IV_SIZE - sizeof(__le64)];
144-
} iv;
154+
union fscrypt_iv iv;
145155
struct skcipher_request *req = NULL;
146156
DECLARE_CRYPTO_WAIT(wait);
147157
struct scatterlist dst, src;
@@ -151,15 +161,7 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw,
151161

152162
BUG_ON(len == 0);
153163

154-
BUILD_BUG_ON(sizeof(iv) != FS_IV_SIZE);
155-
BUILD_BUG_ON(AES_BLOCK_SIZE != FS_IV_SIZE);
156-
iv.index = cpu_to_le64(lblk_num);
157-
memset(iv.padding, 0, sizeof(iv.padding));
158-
159-
if (ci->ci_essiv_tfm != NULL) {
160-
crypto_cipher_encrypt_one(ci->ci_essiv_tfm, (u8 *)&iv,
161-
(u8 *)&iv);
162-
}
164+
fscrypt_generate_iv(&iv, lblk_num, ci);
163165

164166
req = skcipher_request_alloc(tfm, gfp_flags);
165167
if (!req)

fs/crypto/fname.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ int fname_encrypt(struct inode *inode, const struct qstr *iname,
4040
{
4141
struct skcipher_request *req = NULL;
4242
DECLARE_CRYPTO_WAIT(wait);
43-
struct crypto_skcipher *tfm = inode->i_crypt_info->ci_ctfm;
44-
int res = 0;
45-
char iv[FS_CRYPTO_BLOCK_SIZE];
43+
struct fscrypt_info *ci = inode->i_crypt_info;
44+
struct crypto_skcipher *tfm = ci->ci_ctfm;
45+
union fscrypt_iv iv;
4646
struct scatterlist sg;
47+
int res;
4748

4849
/*
4950
* Copy the filename to the output buffer for encrypting in-place and
@@ -55,7 +56,7 @@ int fname_encrypt(struct inode *inode, const struct qstr *iname,
5556
memset(out + iname->len, 0, olen - iname->len);
5657

5758
/* Initialize the IV */
58-
memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
59+
fscrypt_generate_iv(&iv, 0, ci);
5960

6061
/* Set up the encryption request */
6162
req = skcipher_request_alloc(tfm, GFP_NOFS);
@@ -65,7 +66,7 @@ int fname_encrypt(struct inode *inode, const struct qstr *iname,
6566
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
6667
crypto_req_done, &wait);
6768
sg_init_one(&sg, out, olen);
68-
skcipher_request_set_crypt(req, &sg, &sg, olen, iv);
69+
skcipher_request_set_crypt(req, &sg, &sg, olen, &iv);
6970

7071
/* Do the encryption */
7172
res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
@@ -94,9 +95,10 @@ static int fname_decrypt(struct inode *inode,
9495
struct skcipher_request *req = NULL;
9596
DECLARE_CRYPTO_WAIT(wait);
9697
struct scatterlist src_sg, dst_sg;
97-
struct crypto_skcipher *tfm = inode->i_crypt_info->ci_ctfm;
98-
int res = 0;
99-
char iv[FS_CRYPTO_BLOCK_SIZE];
98+
struct fscrypt_info *ci = inode->i_crypt_info;
99+
struct crypto_skcipher *tfm = ci->ci_ctfm;
100+
union fscrypt_iv iv;
101+
int res;
100102

101103
/* Allocate request */
102104
req = skcipher_request_alloc(tfm, GFP_NOFS);
@@ -107,12 +109,12 @@ static int fname_decrypt(struct inode *inode,
107109
crypto_req_done, &wait);
108110

109111
/* Initialize IV */
110-
memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
112+
fscrypt_generate_iv(&iv, 0, ci);
111113

112114
/* Create decryption request */
113115
sg_init_one(&src_sg, iname->name, iname->len);
114116
sg_init_one(&dst_sg, oname->name, oname->len);
115-
skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
117+
skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, &iv);
116118
res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
117119
skcipher_request_free(req);
118120
if (res < 0) {

0 commit comments

Comments
 (0)