[PATCH v2 20/30] crypto: sa2ul - handle transform initialization failures

From: Manorit Chawdhry

Date: Wed Nov 04 2026 - 00:52:08 EST


Stop initialization when security-context or fallback allocation fails,
and propagate hash setup errors instead of exposing a partial transform.

Unwind acquired fallback transforms and security contexts in reverse
order. Release the hash context on fallback allocation failure, and use
the hash teardown path when command-label setup fails.

Fixes: 7694b6ca649f ("crypto: sa2ul - Add crypto driver")
Fixes: 2dc53d004745 ("crypto: sa2ul - add sha1/sha256/sha512 support")
Fixes: d2c8ac187fc9 ("crypto: sa2ul - Add AEAD algorithm support")
Signed-off-by: Manorit Chawdhry <m-chawdhry@xxxxxx>
---
drivers/crypto/sa2ul.c | 70 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 50 insertions(+), 20 deletions(-)

diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
index 36f1d13dfe91..ead12f77ff67 100644
--- a/drivers/crypto/sa2ul.c
+++ b/drivers/crypto/sa2ul.c
@@ -771,16 +771,14 @@ static int sa_cipher_cra_init(struct crypto_skcipher *tfm)
if (ret)
return ret;
ret = sa_init_ctx_info(&ctx->dec, data);
- if (ret) {
- sa_free_ctx_info(&ctx->enc, data);
- return ret;
- }
+ if (ret)
+ goto ctx_dec_err;

child = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
-
if (IS_ERR(child)) {
dev_err(sa_k3_dev, "Error allocating fallback algo %s\n", name);
- return PTR_ERR(child);
+ ret = PTR_ERR(child);
+ goto alloc_err;
}

ctx->fallback.skcipher = child;
@@ -791,6 +789,11 @@ static int sa_cipher_cra_init(struct crypto_skcipher *tfm)
__func__, tfm, ctx->enc.sc_id, &ctx->enc.sc_phys,
ctx->dec.sc_id, &ctx->dec.sc_phys);
return 0;
+alloc_err:
+ sa_free_ctx_info(&ctx->dec, data);
+ctx_dec_err:
+ sa_free_ctx_info(&ctx->enc, data);
+ return ret;
}

static int sa_cipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
@@ -1407,7 +1410,9 @@ static int sa_sha_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
if (IS_ERR(ctx->fallback.ahash)) {
dev_err(ctx->dev_data->dev,
"Could not load fallback driver\n");
- return PTR_ERR(ctx->fallback.ahash);
+ ret = PTR_ERR(ctx->fallback.ahash);
+ ctx->fallback.ahash = NULL;
+ goto err_free_ctx;
}
}

@@ -1420,8 +1425,14 @@ static int sa_sha_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base)
crypto_ahash_reqsize(ctx->fallback.ahash));

return 0;
+
+err_free_ctx:
+ sa_free_ctx_info(&ctx->enc, data);
+ return ret;
}

+static void sa_sha_cra_exit(struct crypto_tfm *tfm);
+
static int sa_sha_init(struct ahash_request *req)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
@@ -1494,45 +1505,60 @@ static int sa_sha1_cra_init(struct crypto_tfm *tfm)
{
struct algo_data ad = { 0 };
struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+ int ret = 0;

- sa_sha_cra_init_alg(tfm, "sha1");
+ ret = sa_sha_cra_init_alg(tfm, "sha1");
+ if (ret)
+ return ret;

ad.hash_size = SHA1_DIGEST_SIZE;
ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA1;

- sa_sha_setup(ctx, &ad);
+ ret = sa_sha_setup(ctx, &ad);
+ if (ret)
+ sa_sha_cra_exit(tfm);

- return 0;
+ return ret;
}

static int sa_sha256_cra_init(struct crypto_tfm *tfm)
{
struct algo_data ad = { 0 };
struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+ int ret = 0;

- sa_sha_cra_init_alg(tfm, "sha256");
+ ret = sa_sha_cra_init_alg(tfm, "sha256");
+ if (ret)
+ return ret;

ad.hash_size = SHA256_DIGEST_SIZE;
ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA256;

- sa_sha_setup(ctx, &ad);
+ ret = sa_sha_setup(ctx, &ad);
+ if (ret)
+ sa_sha_cra_exit(tfm);

- return 0;
+ return ret;
}

static int sa_sha512_cra_init(struct crypto_tfm *tfm)
{
struct algo_data ad = { 0 };
struct sa_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+ int ret = 0;

- sa_sha_cra_init_alg(tfm, "sha512");
+ ret = sa_sha_cra_init_alg(tfm, "sha512");
+ if (ret)
+ return ret;

ad.hash_size = SHA512_DIGEST_SIZE;
ad.auth_ctrl = SA_AUTH_SW_CTRL_SHA512;

- sa_sha_setup(ctx, &ad);
+ ret = sa_sha_setup(ctx, &ad);
+ if (ret)
+ sa_sha_cra_exit(tfm);

- return 0;
+ return ret;
}

static void sa_sha_cra_exit(struct crypto_tfm *tfm)
@@ -1544,10 +1570,10 @@ static void sa_sha_cra_exit(struct crypto_tfm *tfm)
__func__, tfm, ctx->enc.sc_id, &ctx->enc.sc_phys,
ctx->dec.sc_id, &ctx->dec.sc_phys);

+ crypto_free_ahash(ctx->fallback.ahash);
+
if (crypto_tfm_alg_type(tfm) == CRYPTO_ALG_TYPE_AHASH)
sa_free_ctx_info(&ctx->enc, data);
-
- crypto_free_ahash(ctx->fallback.ahash);
}

static void sa_aead_dma_in_callback(void *data)
@@ -1612,12 +1638,12 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *fallback)

ret = sa_init_ctx_info(&ctx->enc, data);
if (ret)
- return ret;
+ goto err_free_fallback;

ret = sa_init_ctx_info(&ctx->dec, data);
if (ret) {
sa_free_ctx_info(&ctx->enc, data);
- return ret;
+ goto err_free_fallback;
}

dev_dbg(sa_k3_dev, "%s(0x%p) sc-ids(0x%x(0x%pad), 0x%x(0x%pad))\n",
@@ -1625,6 +1651,10 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *fallback)
ctx->dec.sc_id, &ctx->dec.sc_phys);

return ret;
+
+err_free_fallback:
+ crypto_free_aead(ctx->fallback.aead);
+ return ret;
}

static int sa_cra_init_aead_sha1(struct crypto_aead *tfm)

--
2.43.0