As it stands stack requests are forbidden for async algorithms because of the inability to perform DMA on stack memory. However, some async algorithms do not perform DMA and are able to handle stack requests. Allow such uses by addnig a new type bit CRYPTO_AHASH_ALG_STACK_REQ. When it is set on the algorithm stack requests will be allowed even if the algorithm is asynchronous. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> --- crypto/ahash.c | 22 ++++++++++++++++++---- include/crypto/internal/hash.h | 3 +++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/crypto/ahash.c b/crypto/ahash.c index a227793d2c5b..5ea72eb2ea91 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -49,6 +49,20 @@ static inline bool crypto_ahash_need_fallback(struct crypto_ahash *tfm) CRYPTO_ALG_NEED_FALLBACK; } +static inline bool crypto_ahash_stack_req_ok(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + + if (!ahash_req_on_stack(req)) + return true; + + if (!ahash_is_async(tfm)) + return true; + + return crypto_ahash_alg(tfm)->halg.base.cra_flags & + CRYPTO_AHASH_ALG_STACK_REQ; +} + static inline void ahash_op_done(void *data, int err, int (*finish)(struct ahash_request *, int)) { @@ -376,7 +390,7 @@ int crypto_ahash_init(struct ahash_request *req) return crypto_shash_init(prepare_shash_desc(req, tfm)); if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) return -ENOKEY; - if (ahash_req_on_stack(req) && ahash_is_async(tfm)) + if (crypto_ahash_stack_req_ok(req)) return -EAGAIN; if (crypto_ahash_block_only(tfm)) { u8 *buf = ahash_request_ctx(req); @@ -451,7 +465,7 @@ int crypto_ahash_update(struct ahash_request *req) if (likely(tfm->using_shash)) return shash_ahash_update(req, ahash_request_ctx(req)); - if (ahash_req_on_stack(req) && ahash_is_async(tfm)) + if (crypto_ahash_stack_req_ok(req)) return -EAGAIN; if (!crypto_ahash_block_only(tfm)) return ahash_do_req_chain(req, &crypto_ahash_alg(tfm)->update); @@ -531,7 +545,7 @@ int crypto_ahash_finup(struct ahash_request *req) if (likely(tfm->using_shash)) return shash_ahash_finup(req, ahash_request_ctx(req)); - if (ahash_req_on_stack(req) && ahash_is_async(tfm)) + if (crypto_ahash_stack_req_ok(req)) return -EAGAIN; if (!crypto_ahash_alg(tfm)->finup) return ahash_def_finup(req); @@ -569,7 +583,7 @@ int crypto_ahash_digest(struct ahash_request *req) if (likely(tfm->using_shash)) return shash_ahash_digest(req, prepare_shash_desc(req, tfm)); - if (ahash_req_on_stack(req) && ahash_is_async(tfm)) + if (crypto_ahash_stack_req_ok(req)) return -EAGAIN; if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) return -ENOKEY; diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h index 6ec5f2f37ccb..79899d36032b 100644 --- a/include/crypto/internal/hash.h +++ b/include/crypto/internal/hash.h @@ -23,6 +23,9 @@ /* This bit is set by the Crypto API if export_core is not supported. */ #define CRYPTO_AHASH_ALG_NO_EXPORT_CORE 0x08000000 +/* This bit is set by the Crypto API if stack requests are supported. */ +#define CRYPTO_AHASH_ALG_STACK_REQ 0x10000000 + #define HASH_FBREQ_ON_STACK(name, req) \ char __##name##_req[sizeof(struct ahash_request) + \ MAX_SYNC_HASH_REQSIZE] CRYPTO_MINALIGN_ATTR; \ -- 2.39.5