]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: xilinx - Avoid submitting fallback requests to engine
authorHarsh Jain <h.jain@amd.com>
Sat, 20 Dec 2025 15:58:59 +0000 (21:28 +0530)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 23 Jan 2026 05:48:43 +0000 (13:48 +0800)
Don't enqueue requests which are supposed to fallback to s/w crypto.

Signed-off-by: Harsh Jain <h.jain@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/xilinx/zynqmp-aes-gcm.c

index 3b346a1c9f7e4829a427f920a0c00930982bff10..b8574e144f486b4391e2ef9880775d1402326bf0 100644 (file)
@@ -204,31 +204,9 @@ static int zynqmp_handle_aes_req(struct crypto_engine *engine,
 {
        struct aead_request *areq =
                                container_of(req, struct aead_request, base);
-       struct crypto_aead *aead = crypto_aead_reqtfm(req);
-       struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead);
-       struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(areq);
-       struct aead_request *subreq = aead_request_ctx(req);
-       int need_fallback;
        int err;
 
-       need_fallback = zynqmp_fallback_check(tfm_ctx, areq);
-
-       if (need_fallback) {
-               aead_request_set_tfm(subreq, tfm_ctx->fbk_cipher);
-
-               aead_request_set_callback(subreq, areq->base.flags,
-                                         NULL, NULL);
-               aead_request_set_crypt(subreq, areq->src, areq->dst,
-                                      areq->cryptlen, areq->iv);
-               aead_request_set_ad(subreq, areq->assoclen);
-               if (rq_ctx->op == ZYNQMP_AES_ENCRYPT)
-                       err = crypto_aead_encrypt(subreq);
-               else
-                       err = crypto_aead_decrypt(subreq);
-       } else {
-               err = zynqmp_aes_aead_cipher(areq);
-       }
-
+       err = zynqmp_aes_aead_cipher(areq);
        local_bh_disable();
        crypto_finalize_aead_request(engine, areq, err);
        local_bh_enable();
@@ -279,28 +257,58 @@ static int zynqmp_aes_aead_setauthsize(struct crypto_aead *aead,
        return crypto_aead_setauthsize(tfm_ctx->fbk_cipher, authsize);
 }
 
+static int xilinx_aes_fallback_crypt(struct aead_request *req, bool encrypt)
+{
+       struct aead_request *subreq = aead_request_ctx(req);
+       struct crypto_aead *aead = crypto_aead_reqtfm(req);
+       struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead);
+
+       aead_request_set_tfm(subreq, tfm_ctx->fbk_cipher);
+       aead_request_set_callback(subreq, req->base.flags, NULL, NULL);
+       aead_request_set_crypt(subreq, req->src, req->dst,
+                              req->cryptlen, req->iv);
+       aead_request_set_ad(subreq, req->assoclen);
+
+       return encrypt ? crypto_aead_encrypt(subreq) : crypto_aead_decrypt(subreq);
+}
+
 static int zynqmp_aes_aead_encrypt(struct aead_request *req)
 {
-       struct zynqmp_aead_drv_ctx *drv_ctx;
+       struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req);
        struct crypto_aead *aead = crypto_aead_reqtfm(req);
+       struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead);
        struct aead_alg *alg = crypto_aead_alg(aead);
-       struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req);
+       struct zynqmp_aead_drv_ctx *drv_ctx;
+       int err;
 
        rq_ctx->op = ZYNQMP_AES_ENCRYPT;
        drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, aead.base);
+       err = zynqmp_fallback_check(tfm_ctx, req);
+       if (err && tfm_ctx->keysrc != ZYNQMP_AES_KUP_KEY)
+               return -EOPNOTSUPP;
+
+       if (err)
+               return xilinx_aes_fallback_crypt(req, true);
 
        return crypto_transfer_aead_request_to_engine(drv_ctx->engine, req);
 }
 
 static int zynqmp_aes_aead_decrypt(struct aead_request *req)
 {
-       struct zynqmp_aead_drv_ctx *drv_ctx;
+       struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req);
        struct crypto_aead *aead = crypto_aead_reqtfm(req);
+       struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead);
        struct aead_alg *alg = crypto_aead_alg(aead);
-       struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req);
+       struct zynqmp_aead_drv_ctx *drv_ctx;
+       int err;
 
        rq_ctx->op = ZYNQMP_AES_DECRYPT;
        drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, aead.base);
+       err = zynqmp_fallback_check(tfm_ctx, req);
+       if (err && tfm_ctx->keysrc != ZYNQMP_AES_KUP_KEY)
+               return -EOPNOTSUPP;
+       if (err)
+               return xilinx_aes_fallback_crypt(req, false);
 
        return crypto_transfer_aead_request_to_engine(drv_ctx->engine, req);
 }