]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
crypto: aspeed/hash - Add fallback
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 13 May 2025 06:04:06 +0000 (14:04 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 13 Jun 2025 09:26:15 +0000 (17:26 +0800)
If a hash request fails due to a DMA mapping error, or if it is too
large to fit in the the driver buffer, use a fallback to do the hash
rather than failing.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/aspeed/aspeed-hace-hash.c

index d7c7f867d6e1636c3adb9e33434f911daf7466ed..3bfb7db96c40edd8935967b5bcca18de83cea797 100644 (file)
@@ -420,6 +420,32 @@ static int aspeed_hace_hash_handle_queue(struct aspeed_hace_dev *hace_dev,
                        hace_dev->crypt_engine_hash, req);
 }
 
+static noinline int aspeed_ahash_fallback(struct ahash_request *req)
+{
+       struct aspeed_sham_reqctx *rctx = ahash_request_ctx(req);
+       HASH_FBREQ_ON_STACK(fbreq, req);
+       u8 *state = rctx->buffer;
+       struct scatterlist sg[2];
+       struct scatterlist *ssg;
+       int ret;
+
+       ssg = scatterwalk_ffwd(sg, req->src, rctx->offset);
+       ahash_request_set_crypt(fbreq, ssg, req->result,
+                               rctx->total - rctx->offset);
+
+       ret = aspeed_sham_export(req, state) ?:
+             crypto_ahash_import_core(fbreq, state);
+
+       if (rctx->flags & SHA_FLAGS_FINUP)
+               ret = ret ?: crypto_ahash_finup(fbreq);
+       else
+               ret = ret ?: crypto_ahash_update(fbreq);
+                            crypto_ahash_export_core(fbreq, state) ?:
+                            aspeed_sham_import(req, state);
+       HASH_REQUEST_ZERO(fbreq);
+       return ret;
+}
+
 static int aspeed_ahash_do_request(struct crypto_engine *engine, void *areq)
 {
        struct ahash_request *req = ahash_request_cast(areq);
@@ -434,7 +460,7 @@ static int aspeed_ahash_do_request(struct crypto_engine *engine, void *areq)
 
        ret = aspeed_ahash_req_update(hace_dev);
        if (ret != -EINPROGRESS)
-               return ret;
+               return aspeed_ahash_fallback(req);
 
        return 0;
 }