Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fscrypt: Don't use asynchronous CryptoAPI algorithms

Now that fscrypt's incomplete support for non-inline crypto engines has
been removed, and none of the CPU-based algorithms have the
CRYPTO_ALG_ASYNC flag set anymore, there is no need to accommodate
asynchronous algorithms. Therefore, explicitly allocate only
synchronous algorithms. Then, remove the code that handled waiting for
asynchronous en/decryption operations to complete.

This commit should *not* be backported to kernels that lack commit
0ba6ec5b2972 ("crypto: x86/aes - stop using the SIMD helper"), as then
it would disable the use of the optimized AES code on x86.

Link: https://lore.kernel.org/r/20250710060754.637098-2-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>

+18 -21
+3 -4
fs/crypto/crypto.c
··· 115 115 { 116 116 union fscrypt_iv iv; 117 117 struct skcipher_request *req = NULL; 118 - DECLARE_CRYPTO_WAIT(wait); 119 118 struct scatterlist dst, src; 120 119 struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; 121 120 int res = 0; ··· 132 133 133 134 skcipher_request_set_callback( 134 135 req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 135 - crypto_req_done, &wait); 136 + NULL, NULL); 136 137 137 138 sg_init_table(&dst, 1); 138 139 sg_set_page(&dst, dest_page, len, offs); ··· 140 141 sg_set_page(&src, src_page, len, offs); 141 142 skcipher_request_set_crypt(req, &src, &dst, len, &iv); 142 143 if (rw == FS_DECRYPT) 143 - res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); 144 + res = crypto_skcipher_decrypt(req); 144 145 else 145 - res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 146 + res = crypto_skcipher_encrypt(req); 146 147 skcipher_request_free(req); 147 148 if (res) { 148 149 fscrypt_err(ci->ci_inode,
+8 -10
fs/crypto/fname.c
··· 95 95 u8 *out, unsigned int olen) 96 96 { 97 97 struct skcipher_request *req = NULL; 98 - DECLARE_CRYPTO_WAIT(wait); 99 98 const struct fscrypt_inode_info *ci = inode->i_crypt_info; 100 99 struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; 101 100 union fscrypt_iv iv; ··· 117 118 req = skcipher_request_alloc(tfm, GFP_NOFS); 118 119 if (!req) 119 120 return -ENOMEM; 120 - skcipher_request_set_callback(req, 121 - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 122 - crypto_req_done, &wait); 121 + skcipher_request_set_callback( 122 + req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 123 + NULL, NULL); 123 124 sg_init_one(&sg, out, olen); 124 125 skcipher_request_set_crypt(req, &sg, &sg, olen, &iv); 125 126 126 127 /* Do the encryption */ 127 - res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 128 + res = crypto_skcipher_encrypt(req); 128 129 skcipher_request_free(req); 129 130 if (res < 0) { 130 131 fscrypt_err(inode, "Filename encryption failed: %d", res); ··· 150 151 struct fscrypt_str *oname) 151 152 { 152 153 struct skcipher_request *req = NULL; 153 - DECLARE_CRYPTO_WAIT(wait); 154 154 struct scatterlist src_sg, dst_sg; 155 155 const struct fscrypt_inode_info *ci = inode->i_crypt_info; 156 156 struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; ··· 160 162 req = skcipher_request_alloc(tfm, GFP_NOFS); 161 163 if (!req) 162 164 return -ENOMEM; 163 - skcipher_request_set_callback(req, 164 - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 165 - crypto_req_done, &wait); 165 + skcipher_request_set_callback( 166 + req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 167 + NULL, NULL); 166 168 167 169 /* Initialize IV */ 168 170 fscrypt_generate_iv(&iv, 0, ci); ··· 171 173 sg_init_one(&src_sg, iname->name, iname->len); 172 174 sg_init_one(&dst_sg, oname->name, oname->len); 173 175 skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, &iv); 174 - res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); 176 + res = crypto_skcipher_decrypt(req); 175 177 skcipher_request_free(req); 176 178 if (res < 0) { 177 179 fscrypt_err(inode, "Filename decryption failed: %d", res);
+3 -2
fs/crypto/fscrypt_private.h
··· 59 59 * Note that fscrypt also supports inline crypto engines. Those don't use the 60 60 * Crypto API and work much better than the old-style (non-inline) engines. 61 61 */ 62 - #define FSCRYPT_CRYPTOAPI_MASK \ 63 - (CRYPTO_ALG_ALLOCATES_MEMORY | CRYPTO_ALG_KERN_DRIVER_ONLY) 62 + #define FSCRYPT_CRYPTOAPI_MASK \ 63 + (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | \ 64 + CRYPTO_ALG_KERN_DRIVER_ONLY) 64 65 65 66 #define FSCRYPT_CONTEXT_V1 1 66 67 #define FSCRYPT_CONTEXT_V2 2
+4 -5
fs/crypto/keysetup_v1.c
··· 50 50 { 51 51 int res = 0; 52 52 struct skcipher_request *req = NULL; 53 - DECLARE_CRYPTO_WAIT(wait); 54 53 struct scatterlist src_sg, dst_sg; 55 54 struct crypto_skcipher *tfm = 56 55 crypto_alloc_skcipher("ecb(aes)", 0, FSCRYPT_CRYPTOAPI_MASK); ··· 65 66 res = -ENOMEM; 66 67 goto out; 67 68 } 68 - skcipher_request_set_callback(req, 69 - CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 70 - crypto_req_done, &wait); 69 + skcipher_request_set_callback( 70 + req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 71 + NULL, NULL); 71 72 res = crypto_skcipher_setkey(tfm, nonce, FSCRYPT_FILE_NONCE_SIZE); 72 73 if (res < 0) 73 74 goto out; ··· 76 77 sg_init_one(&dst_sg, derived_key, derived_keysize); 77 78 skcipher_request_set_crypt(req, &src_sg, &dst_sg, derived_keysize, 78 79 NULL); 79 - res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 80 + res = crypto_skcipher_encrypt(req); 80 81 out: 81 82 skcipher_request_free(req); 82 83 crypto_free_skcipher(tfm);