diff options
Diffstat (limited to 'crypto/algapi.c')
-rw-r--r-- | crypto/algapi.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c index c3cf1a69a47..9d4a9fe913f 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -22,8 +22,6 @@ #include "internal.h" -static void crypto_remove_final(struct list_head *list); - static LIST_HEAD(crypto_template_list); void crypto_larval_error(const char *name, u32 type, u32 mask) @@ -129,9 +127,8 @@ static void crypto_remove_spawn(struct crypto_spawn *spawn, BUG_ON(!list_empty(&inst->alg.cra_users)); } -static void crypto_remove_spawns(struct crypto_alg *alg, - struct list_head *list, - struct crypto_alg *nalg) +void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, + struct crypto_alg *nalg) { u32 new_type = (nalg ?: alg)->cra_flags; struct crypto_spawn *spawn, *n; @@ -177,6 +174,7 @@ static void crypto_remove_spawns(struct crypto_alg *alg, crypto_remove_spawn(spawn, list); } } +EXPORT_SYMBOL_GPL(crypto_remove_spawns); static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg) { @@ -321,7 +319,7 @@ unlock: } EXPORT_SYMBOL_GPL(crypto_alg_tested); -static void crypto_remove_final(struct list_head *list) +void crypto_remove_final(struct list_head *list) { struct crypto_alg *alg; struct crypto_alg *n; @@ -331,6 +329,7 @@ static void crypto_remove_final(struct list_head *list) crypto_alg_put(alg); } } +EXPORT_SYMBOL_GPL(crypto_remove_final); static void crypto_wait_for_test(struct crypto_larval *larval) { @@ -493,6 +492,7 @@ int crypto_register_instance(struct crypto_template *tmpl, goto err; inst->alg.cra_module = tmpl->module; + inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE; down_write(&crypto_alg_sem); @@ -518,6 +518,35 @@ err: } EXPORT_SYMBOL_GPL(crypto_register_instance); +int crypto_unregister_instance(struct crypto_alg *alg) +{ + int err; + struct crypto_instance *inst = (void *)alg; + struct crypto_template *tmpl = inst->tmpl; + LIST_HEAD(users); + + if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE)) + return -EINVAL; + + BUG_ON(atomic_read(&alg->cra_refcnt) != 1); + + down_write(&crypto_alg_sem); + + hlist_del_init(&inst->list); + err = crypto_remove_alg(alg, &users); + + up_write(&crypto_alg_sem); + + if (err) + return err; + + tmpl->free(inst); + crypto_remove_final(&users); + + return 0; +} +EXPORT_SYMBOL_GPL(crypto_unregister_instance); + int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, struct crypto_instance *inst, u32 mask) { |