summaryrefslogtreecommitdiffstats
path: root/crypto/shash.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/shash.c')
-rw-r--r--crypto/shash.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/crypto/shash.c b/crypto/shash.c
index 7989258a46b4..8042bb0df9c0 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -385,15 +385,41 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
return 0;
}
+static void crypto_shash_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_shash *hash = __crypto_shash_cast(tfm);
+ struct shash_alg *alg = crypto_shash_alg(hash);
+
+ alg->exit_tfm(hash);
+}
+
static int crypto_shash_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_shash *hash = __crypto_shash_cast(tfm);
struct shash_alg *alg = crypto_shash_alg(hash);
+ int err;
hash->descsize = alg->descsize;
shash_set_needkey(hash, alg);
+ if (alg->exit_tfm)
+ tfm->exit = crypto_shash_exit_tfm;
+
+ if (!alg->init_tfm)
+ return 0;
+
+ err = alg->init_tfm(hash);
+ if (err)
+ return err;
+
+ /* ->init_tfm() may have increased the descsize. */
+ if (WARN_ON_ONCE(hash->descsize > HASH_MAX_DESCSIZE)) {
+ if (alg->exit_tfm)
+ alg->exit_tfm(hash);
+ return -EINVAL;
+ }
+
return 0;
}