Hi Would it be possible to export the function crypto_ahash_stack_req_ok, so that I could know up-front whether having a request on the stack will succeed or not?
Perhaps the function crypto_ahash_stack_req_ok could take "struct crypto_ahash *" argument rather than "struct ahash_request, *" so that I would know in advance whether it makes sense to try to build the request on the stack or not. Mikulas On Tue, 9 Sep 2025, Herbert Xu wrote: > 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 <[email protected]> > --- > 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..33b2a19169f1 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 >
