Skip to content

Commit 283564a

Browse files
committed
Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux
Pull fscrypt updates from Eric Biggers: "Simplify how fscrypt uses the crypto API, resulting in some significant performance improvements: - Drop the incomplete and problematic support for asynchronous algorithms. These drivers are bug-prone, and it turns out they are actually much slower than the CPU-based code as well. - Allocate crypto requests on the stack instead of the heap. This improves encryption and decryption performance, especially for filenames. This also eliminates a point of failure during I/O" * tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux: ceph: Remove gfp_t argument from ceph_fscrypt_encrypt_*() fscrypt: Remove gfp_t argument from fscrypt_encrypt_block_inplace() fscrypt: Remove gfp_t argument from fscrypt_crypt_data_unit() fscrypt: Switch to sync_skcipher and on-stack requests fscrypt: Drop FORBID_WEAK_KEYS flag for AES-ECB fscrypt: Don't use asynchronous CryptoAPI algorithms fscrypt: Don't use problematic non-inline crypto engines fscrypt: Drop obsolete recommendation to enable optimized SHA-512 fscrypt: Explicitly include <linux/export.h>
2 parents 4b65b85 + fa65058 commit 283564a

18 files changed

Lines changed: 146 additions & 182 deletions

File tree

Documentation/filesystems/fscrypt.rst

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,8 @@ However, these ioctls have some limitations:
147147
were wiped. To partially solve this, you can add init_on_free=1 to
148148
your kernel command line. However, this has a performance cost.
149149

150-
- Secret keys might still exist in CPU registers, in crypto
151-
accelerator hardware (if used by the crypto API to implement any of
152-
the algorithms), or in other places not explicitly considered here.
150+
- Secret keys might still exist in CPU registers or in other places
151+
not explicitly considered here.
153152

154153
Full system compromise
155154
~~~~~~~~~~~~~~~~~~~~~~
@@ -406,9 +405,12 @@ the work is done by XChaCha12, which is much faster than AES when AES
406405
acceleration is unavailable. For more information about Adiantum, see
407406
`the Adiantum paper <https://eprint.iacr.org/2018/720.pdf>`_.
408407

409-
The (AES-128-CBC-ESSIV, AES-128-CBC-CTS) pair exists only to support
410-
systems whose only form of AES acceleration is an off-CPU crypto
411-
accelerator such as CAAM or CESA that does not support XTS.
408+
The (AES-128-CBC-ESSIV, AES-128-CBC-CTS) pair was added to try to
409+
provide a more efficient option for systems that lack AES instructions
410+
in the CPU but do have a non-inline crypto engine such as CAAM or CESA
411+
that supports AES-CBC (and not AES-XTS). This is deprecated. It has
412+
been shown that just doing AES on the CPU is actually faster.
413+
Moreover, Adiantum is faster still and is recommended on such systems.
412414

413415
The remaining mode pairs are the "national pride ciphers":
414416

@@ -468,14 +470,6 @@ API, but the filenames mode still does.
468470
- Recommended:
469471
- AES-CBC acceleration
470472

471-
fscrypt also uses HMAC-SHA512 for key derivation, so enabling SHA-512
472-
acceleration is recommended:
473-
474-
- SHA-512
475-
- Recommended:
476-
- arm64: CONFIG_CRYPTO_SHA512_ARM64_CE
477-
- x86: CONFIG_CRYPTO_SHA512_SSSE3
478-
479473
Contents encryption
480474
-------------------
481475

@@ -1326,22 +1320,13 @@ this by validating all top-level encryption policies prior to access.
13261320
Inline encryption support
13271321
=========================
13281322

1329-
By default, fscrypt uses the kernel crypto API for all cryptographic
1330-
operations (other than HKDF, which fscrypt partially implements
1331-
itself). The kernel crypto API supports hardware crypto accelerators,
1332-
but only ones that work in the traditional way where all inputs and
1333-
outputs (e.g. plaintexts and ciphertexts) are in memory. fscrypt can
1334-
take advantage of such hardware, but the traditional acceleration
1335-
model isn't particularly efficient and fscrypt hasn't been optimized
1336-
for it.
1337-
1338-
Instead, many newer systems (especially mobile SoCs) have *inline
1339-
encryption hardware* that can encrypt/decrypt data while it is on its
1340-
way to/from the storage device. Linux supports inline encryption
1341-
through a set of extensions to the block layer called *blk-crypto*.
1342-
blk-crypto allows filesystems to attach encryption contexts to bios
1343-
(I/O requests) to specify how the data will be encrypted or decrypted
1344-
in-line. For more information about blk-crypto, see
1323+
Many newer systems (especially mobile SoCs) have *inline encryption
1324+
hardware* that can encrypt/decrypt data while it is on its way to/from
1325+
the storage device. Linux supports inline encryption through a set of
1326+
extensions to the block layer called *blk-crypto*. blk-crypto allows
1327+
filesystems to attach encryption contexts to bios (I/O requests) to
1328+
specify how the data will be encrypted or decrypted in-line. For more
1329+
information about blk-crypto, see
13451330
:ref:`Documentation/block/inline-encryption.rst <inline_encryption>`.
13461331

13471332
On supported filesystems (currently ext4 and f2fs), fscrypt can use

fs/ceph/crypto.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -488,15 +488,13 @@ int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode,
488488

489489
int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode,
490490
struct page *page, unsigned int len,
491-
unsigned int offs, u64 lblk_num,
492-
gfp_t gfp_flags)
491+
unsigned int offs, u64 lblk_num)
493492
{
494493
struct ceph_client *cl = ceph_inode_to_client(inode);
495494

496495
doutc(cl, "%p %llx.%llx len %u offs %u blk %llu\n", inode,
497496
ceph_vinop(inode), len, offs, lblk_num);
498-
return fscrypt_encrypt_block_inplace(inode, page, len, offs, lblk_num,
499-
gfp_flags);
497+
return fscrypt_encrypt_block_inplace(inode, page, len, offs, lblk_num);
500498
}
501499

502500
/**
@@ -614,17 +612,16 @@ int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page,
614612
* @page: pointer to page array
615613
* @off: offset into the file that the data starts
616614
* @len: max length to encrypt
617-
* @gfp: gfp flags to use for allocation
618615
*
619-
* Decrypt an array of cleartext pages and return the amount of
616+
* Encrypt an array of cleartext pages and return the amount of
620617
* data encrypted. Any data in the page prior to the start of the
621618
* first complete block in the read is ignored. Any incomplete
622619
* crypto blocks at the end of the array are ignored.
623620
*
624621
* Returns the length of the encrypted data or a negative errno.
625622
*/
626623
int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off,
627-
int len, gfp_t gfp)
624+
int len)
628625
{
629626
int i, num_blocks;
630627
u64 baseblk = off >> CEPH_FSCRYPT_BLOCK_SHIFT;
@@ -645,7 +642,7 @@ int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off,
645642

646643
fret = ceph_fscrypt_encrypt_block_inplace(inode, page[pgidx],
647644
CEPH_FSCRYPT_BLOCK_SIZE, pgoffs,
648-
baseblk + i, gfp);
645+
baseblk + i);
649646
if (fret < 0) {
650647
if (ret == 0)
651648
ret = fret;

fs/ceph/crypto.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,14 @@ int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode,
152152
unsigned int offs, u64 lblk_num);
153153
int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode,
154154
struct page *page, unsigned int len,
155-
unsigned int offs, u64 lblk_num,
156-
gfp_t gfp_flags);
155+
unsigned int offs, u64 lblk_num);
157156
int ceph_fscrypt_decrypt_pages(struct inode *inode, struct page **page,
158157
u64 off, int len);
159158
int ceph_fscrypt_decrypt_extents(struct inode *inode, struct page **page,
160159
u64 off, struct ceph_sparse_extent *map,
161160
u32 ext_cnt);
162161
int ceph_fscrypt_encrypt_pages(struct inode *inode, struct page **page, u64 off,
163-
int len, gfp_t gfp);
162+
int len);
164163

165164
static inline struct page *ceph_fscrypt_pagecache_page(struct page *page)
166165
{
@@ -236,8 +235,7 @@ static inline int ceph_fscrypt_decrypt_block_inplace(const struct inode *inode,
236235

237236
static inline int ceph_fscrypt_encrypt_block_inplace(const struct inode *inode,
238237
struct page *page, unsigned int len,
239-
unsigned int offs, u64 lblk_num,
240-
gfp_t gfp_flags)
238+
unsigned int offs, u64 lblk_num)
241239
{
242240
return 0;
243241
}
@@ -259,7 +257,7 @@ static inline int ceph_fscrypt_decrypt_extents(struct inode *inode,
259257

260258
static inline int ceph_fscrypt_encrypt_pages(struct inode *inode,
261259
struct page **page, u64 off,
262-
int len, gfp_t gfp)
260+
int len)
263261
{
264262
return 0;
265263
}

fs/ceph/file.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,8 +1992,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
19921992

19931993
if (IS_ENCRYPTED(inode)) {
19941994
ret = ceph_fscrypt_encrypt_pages(inode, pages,
1995-
write_pos, write_len,
1996-
GFP_KERNEL);
1995+
write_pos, write_len);
19971996
if (ret < 0) {
19981997
doutc(cl, "encryption failed with %d\n", ret);
19991998
ceph_release_page_vector(pages, num_pages);

fs/ceph/inode.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,8 +2436,7 @@ static int fill_fscrypt_truncate(struct inode *inode,
24362436
/* encrypt the last block */
24372437
ret = ceph_fscrypt_encrypt_block_inplace(inode, page,
24382438
CEPH_FSCRYPT_BLOCK_SIZE,
2439-
0, block,
2440-
GFP_KERNEL);
2439+
0, block);
24412440
if (ret)
24422441
goto out;
24432442
}

fs/crypto/bio.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
* Copyright (C) 2015, Motorola Mobility
88
*/
99

10-
#include <linux/pagemap.h>
11-
#include <linux/module.h>
1210
#include <linux/bio.h>
11+
#include <linux/export.h>
12+
#include <linux/module.h>
1313
#include <linux/namei.h>
14+
#include <linux/pagemap.h>
15+
1416
#include "fscrypt_private.h"
1517

1618
/**
@@ -165,8 +167,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
165167
do {
166168
err = fscrypt_crypt_data_unit(ci, FS_ENCRYPT, du_index,
167169
ZERO_PAGE(0), pages[i],
168-
du_size, offset,
169-
GFP_NOFS);
170+
du_size, offset);
170171
if (err)
171172
goto out;
172173
du_index++;

fs/crypto/crypto.c

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
* Special Publication 800-38E and IEEE P1619/D16.
2121
*/
2222

23-
#include <linux/pagemap.h>
23+
#include <crypto/skcipher.h>
24+
#include <linux/export.h>
2425
#include <linux/mempool.h>
2526
#include <linux/module.h>
26-
#include <linux/scatterlist.h>
27+
#include <linux/pagemap.h>
2728
#include <linux/ratelimit.h>
28-
#include <crypto/skcipher.h>
29+
#include <linux/scatterlist.h>
30+
2931
#include "fscrypt_private.h"
3032

3133
static unsigned int num_prealloc_crypto_pages = 32;
@@ -108,15 +110,13 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 index,
108110
int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci,
109111
fscrypt_direction_t rw, u64 index,
110112
struct page *src_page, struct page *dest_page,
111-
unsigned int len, unsigned int offs,
112-
gfp_t gfp_flags)
113+
unsigned int len, unsigned int offs)
113114
{
115+
struct crypto_sync_skcipher *tfm = ci->ci_enc_key.tfm;
116+
SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
114117
union fscrypt_iv iv;
115-
struct skcipher_request *req = NULL;
116-
DECLARE_CRYPTO_WAIT(wait);
117118
struct scatterlist dst, src;
118-
struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
119-
int res = 0;
119+
int err;
120120

121121
if (WARN_ON_ONCE(len <= 0))
122122
return -EINVAL;
@@ -125,31 +125,23 @@ int fscrypt_crypt_data_unit(const struct fscrypt_inode_info *ci,
125125

126126
fscrypt_generate_iv(&iv, index, ci);
127127

128-
req = skcipher_request_alloc(tfm, gfp_flags);
129-
if (!req)
130-
return -ENOMEM;
131-
132128
skcipher_request_set_callback(
133129
req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
134-
crypto_req_done, &wait);
135-
130+
NULL, NULL);
136131
sg_init_table(&dst, 1);
137132
sg_set_page(&dst, dest_page, len, offs);
138133
sg_init_table(&src, 1);
139134
sg_set_page(&src, src_page, len, offs);
140135
skcipher_request_set_crypt(req, &src, &dst, len, &iv);
141136
if (rw == FS_DECRYPT)
142-
res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
137+
err = crypto_skcipher_decrypt(req);
143138
else
144-
res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
145-
skcipher_request_free(req);
146-
if (res) {
139+
err = crypto_skcipher_encrypt(req);
140+
if (err)
147141
fscrypt_err(ci->ci_inode,
148142
"%scryption failed for data unit %llu: %d",
149-
(rw == FS_DECRYPT ? "De" : "En"), index, res);
150-
return res;
151-
}
152-
return 0;
143+
(rw == FS_DECRYPT ? "De" : "En"), index, err);
144+
return err;
153145
}
154146

155147
/**
@@ -204,7 +196,7 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct folio *folio,
204196
for (i = offs; i < offs + len; i += du_size, index++) {
205197
err = fscrypt_crypt_data_unit(ci, FS_ENCRYPT, index,
206198
&folio->page, ciphertext_page,
207-
du_size, i, gfp_flags);
199+
du_size, i);
208200
if (err) {
209201
fscrypt_free_bounce_page(ciphertext_page);
210202
return ERR_PTR(err);
@@ -225,7 +217,6 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks);
225217
* @offs: Byte offset within @page at which the block to encrypt begins
226218
* @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
227219
* number of the block within the file
228-
* @gfp_flags: Memory allocation flags
229220
*
230221
* Encrypt a possibly-compressed filesystem block that is located in an
231222
* arbitrary page, not necessarily in the original pagecache page. The @inode
@@ -237,13 +228,12 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks);
237228
*/
238229
int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page,
239230
unsigned int len, unsigned int offs,
240-
u64 lblk_num, gfp_t gfp_flags)
231+
u64 lblk_num)
241232
{
242233
if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
243234
return -EOPNOTSUPP;
244235
return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_ENCRYPT,
245-
lblk_num, page, page, len, offs,
246-
gfp_flags);
236+
lblk_num, page, page, len, offs);
247237
}
248238
EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
249239

@@ -283,8 +273,7 @@ int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len,
283273
struct page *page = folio_page(folio, i >> PAGE_SHIFT);
284274

285275
err = fscrypt_crypt_data_unit(ci, FS_DECRYPT, index, page,
286-
page, du_size, i & ~PAGE_MASK,
287-
GFP_NOFS);
276+
page, du_size, i & ~PAGE_MASK);
288277
if (err)
289278
return err;
290279
}
@@ -317,8 +306,7 @@ int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
317306
if (WARN_ON_ONCE(inode->i_sb->s_cop->supports_subblock_data_units))
318307
return -EOPNOTSUPP;
319308
return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_DECRYPT,
320-
lblk_num, page, page, len, offs,
321-
GFP_NOFS);
309+
lblk_num, page, page, len, offs);
322310
}
323311
EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
324312

0 commit comments

Comments
 (0)