summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2025-04-23 17:22:31 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2025-04-28 19:40:54 +0800
commit2cfe41630a1a4f24d46825aa9656a51a38fb7f7d (patch)
tree83c10c5937f5fc7e788ef1a37de2353b975d4b21
parent19da081a28c95fe9b03ce952a2bf4a6f6bf5112c (diff)
crypto: hash - Fix clone error handling
Do not copy the exit function in crypto_clone_tfm as it should only be set after init_tfm or clone_tfm has succeeded. Move the setting into crypto_clone_ahash and crypto_clone_shash instead. Also clone the fb if necessary. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/ahash.c19
-rw-r--r--crypto/api.c2
-rw-r--r--crypto/shash.c3
3 files changed, 21 insertions, 3 deletions
diff --git a/crypto/ahash.c b/crypto/ahash.c
index 9b813f7b9177..cc9885d5cfd2 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -877,6 +877,7 @@ struct crypto_ahash *crypto_clone_ahash(struct crypto_ahash *hash)
{
struct hash_alg_common *halg = crypto_hash_alg_common(hash);
struct crypto_tfm *tfm = crypto_ahash_tfm(hash);
+ struct crypto_ahash *fb = NULL;
struct crypto_ahash *nhash;
struct ahash_alg *alg;
int err;
@@ -906,22 +907,36 @@ struct crypto_ahash *crypto_clone_ahash(struct crypto_ahash *hash)
err = PTR_ERR(shash);
goto out_free_nhash;
}
+ crypto_ahash_tfm(nhash)->exit = crypto_exit_ahash_using_shash;
nhash->using_shash = true;
*nctx = shash;
return nhash;
}
+ if (ahash_is_async(hash)) {
+ fb = crypto_clone_ahash(crypto_ahash_fb(hash));
+ err = PTR_ERR(fb);
+ if (IS_ERR(fb))
+ goto out_free_nhash;
+
+ crypto_ahash_tfm(nhash)->fb = crypto_ahash_tfm(fb);
+ }
+
err = -ENOSYS;
alg = crypto_ahash_alg(hash);
if (!alg->clone_tfm)
- goto out_free_nhash;
+ goto out_free_fb;
err = alg->clone_tfm(nhash, hash);
if (err)
- goto out_free_nhash;
+ goto out_free_fb;
+
+ crypto_ahash_tfm(nhash)->exit = crypto_ahash_exit_tfm;
return nhash;
+out_free_fb:
+ crypto_free_ahash(fb);
out_free_nhash:
crypto_free_ahash(nhash);
return ERR_PTR(err);
diff --git a/crypto/api.c b/crypto/api.c
index 172e82f79c69..5cd5ec105bb1 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -570,7 +570,7 @@ void *crypto_clone_tfm(const struct crypto_type *frontend,
tfm = (struct crypto_tfm *)(mem + frontend->tfmsize);
tfm->crt_flags = otfm->crt_flags;
- tfm->exit = otfm->exit;
+ tfm->fb = tfm;
out:
return mem;
diff --git a/crypto/shash.c b/crypto/shash.c
index b6c79a4a044a..c4a724e55d7a 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -413,6 +413,9 @@ struct crypto_shash *crypto_clone_shash(struct crypto_shash *hash)
}
}
+ if (alg->exit_tfm)
+ crypto_shash_tfm(nhash)->exit = crypto_shash_exit_tfm;
+
return nhash;
}
EXPORT_SYMBOL_GPL(crypto_clone_shash);