summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/api.c4
-rw-r--r--crypto/internal.h6
2 files changed, 10 insertions, 0 deletions
diff --git a/crypto/api.c b/crypto/api.c
index e67cc63368ed..f509d73fa682 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -408,6 +408,7 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
goto out_err;
tfm->__crt_alg = alg;
+ refcount_set(&tfm->refcnt, 1);
err = crypto_init_ops(tfm, type, mask);
if (err)
@@ -507,6 +508,7 @@ void *crypto_create_tfm_node(struct crypto_alg *alg,
tfm = (struct crypto_tfm *)(mem + tfmsize);
tfm->__crt_alg = alg;
tfm->node = node;
+ refcount_set(&tfm->refcnt, 1);
err = frontend->init_tfm(tfm);
if (err)
@@ -619,6 +621,8 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
if (IS_ERR_OR_NULL(mem))
return;
+ if (!refcount_dec_and_test(&tfm->refcnt))
+ return;
alg = tfm->__crt_alg;
if (!tfm->exit && alg->cra_exit)
diff --git a/crypto/internal.h b/crypto/internal.h
index f84dfe6491e5..5eee009ee494 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -10,6 +10,7 @@
#include <crypto/algapi.h>
#include <linux/completion.h>
+#include <linux/err.h>
#include <linux/jump_label.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -186,5 +187,10 @@ static inline int crypto_is_test_larval(struct crypto_larval *larval)
return larval->alg.cra_driver_name[0];
}
+static inline struct crypto_tfm *crypto_tfm_get(struct crypto_tfm *tfm)
+{
+ return refcount_inc_not_zero(&tfm->refcnt) ? tfm : ERR_PTR(-EOVERFLOW);
+}
+
#endif /* _CRYPTO_INTERNAL_H */