diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2006-08-06 07:23:26 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2006-09-20 21:17:13 -0400 |
commit | 2825982d9d66ebba4b532a07391dfbb357f71c5f (patch) | |
tree | 3789b26b593d081ff8eedc7e528c2b9b49a94dc2 /crypto/algapi.c | |
parent | 4cc7720cd165273b08a72b4193146dffee58e34b (diff) |
[CRYPTO] api: Added event notification
This patch adds a notifier chain for algorithm/template registration events.
This will be used to register compound algorithms such as cbc(aes). In
future this will also be passed onto user-space through netlink.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'crypto/algapi.c')
-rw-r--r-- | crypto/algapi.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c index 232b37d81613..f0df85fc1f50 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c | |||
@@ -21,6 +21,24 @@ | |||
21 | 21 | ||
22 | static LIST_HEAD(crypto_template_list); | 22 | static LIST_HEAD(crypto_template_list); |
23 | 23 | ||
24 | void crypto_larval_error(const char *name) | ||
25 | { | ||
26 | struct crypto_alg *alg; | ||
27 | |||
28 | down_read(&crypto_alg_sem); | ||
29 | alg = __crypto_alg_lookup(name); | ||
30 | up_read(&crypto_alg_sem); | ||
31 | |||
32 | if (alg) { | ||
33 | if (crypto_is_larval(alg)) { | ||
34 | struct crypto_larval *larval = (void *)alg; | ||
35 | complete(&larval->completion); | ||
36 | } | ||
37 | crypto_mod_put(alg); | ||
38 | } | ||
39 | } | ||
40 | EXPORT_SYMBOL_GPL(crypto_larval_error); | ||
41 | |||
24 | static inline int crypto_set_driver_name(struct crypto_alg *alg) | 42 | static inline int crypto_set_driver_name(struct crypto_alg *alg) |
25 | { | 43 | { |
26 | static const char suffix[] = "-generic"; | 44 | static const char suffix[] = "-generic"; |
@@ -60,14 +78,27 @@ static int __crypto_register_alg(struct crypto_alg *alg) | |||
60 | struct crypto_alg *q; | 78 | struct crypto_alg *q; |
61 | int ret = -EEXIST; | 79 | int ret = -EEXIST; |
62 | 80 | ||
81 | atomic_set(&alg->cra_refcnt, 1); | ||
63 | list_for_each_entry(q, &crypto_alg_list, cra_list) { | 82 | list_for_each_entry(q, &crypto_alg_list, cra_list) { |
64 | if (q == alg) | 83 | if (q == alg) |
65 | goto out; | 84 | goto out; |
85 | if (crypto_is_larval(q) && | ||
86 | (!strcmp(alg->cra_name, q->cra_name) || | ||
87 | !strcmp(alg->cra_driver_name, q->cra_name))) { | ||
88 | struct crypto_larval *larval = (void *)q; | ||
89 | |||
90 | if (!crypto_mod_get(alg)) | ||
91 | continue; | ||
92 | larval->adult = alg; | ||
93 | complete(&larval->completion); | ||
94 | } | ||
66 | } | 95 | } |
67 | 96 | ||
68 | list_add(&alg->cra_list, &crypto_alg_list); | 97 | list_add(&alg->cra_list, &crypto_alg_list); |
69 | atomic_set(&alg->cra_refcnt, 1); | 98 | |
99 | crypto_notify(CRYPTO_MSG_ALG_REGISTER, alg); | ||
70 | ret = 0; | 100 | ret = 0; |
101 | |||
71 | out: | 102 | out: |
72 | return ret; | 103 | return ret; |
73 | } | 104 | } |
@@ -97,6 +128,7 @@ int crypto_unregister_alg(struct crypto_alg *alg) | |||
97 | list_del_init(&alg->cra_list); | 128 | list_del_init(&alg->cra_list); |
98 | ret = 0; | 129 | ret = 0; |
99 | } | 130 | } |
131 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg); | ||
100 | up_write(&crypto_alg_sem); | 132 | up_write(&crypto_alg_sem); |
101 | 133 | ||
102 | if (ret) | 134 | if (ret) |
@@ -123,6 +155,7 @@ int crypto_register_template(struct crypto_template *tmpl) | |||
123 | } | 155 | } |
124 | 156 | ||
125 | list_add(&tmpl->list, &crypto_template_list); | 157 | list_add(&tmpl->list, &crypto_template_list); |
158 | crypto_notify(CRYPTO_MSG_TMPL_REGISTER, tmpl); | ||
126 | err = 0; | 159 | err = 0; |
127 | out: | 160 | out: |
128 | up_write(&crypto_alg_sem); | 161 | up_write(&crypto_alg_sem); |
@@ -145,8 +178,11 @@ void crypto_unregister_template(struct crypto_template *tmpl) | |||
145 | hlist_for_each_entry(inst, p, list, list) { | 178 | hlist_for_each_entry(inst, p, list, list) { |
146 | BUG_ON(list_empty(&inst->alg.cra_list)); | 179 | BUG_ON(list_empty(&inst->alg.cra_list)); |
147 | list_del_init(&inst->alg.cra_list); | 180 | list_del_init(&inst->alg.cra_list); |
181 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg); | ||
148 | } | 182 | } |
149 | 183 | ||
184 | crypto_notify(CRYPTO_MSG_TMPL_UNREGISTER, tmpl); | ||
185 | |||
150 | up_write(&crypto_alg_sem); | 186 | up_write(&crypto_alg_sem); |
151 | 187 | ||
152 | hlist_for_each_entry_safe(inst, p, n, list, list) { | 188 | hlist_for_each_entry_safe(inst, p, n, list, list) { |
@@ -212,6 +248,18 @@ err: | |||
212 | } | 248 | } |
213 | EXPORT_SYMBOL_GPL(crypto_register_instance); | 249 | EXPORT_SYMBOL_GPL(crypto_register_instance); |
214 | 250 | ||
251 | int crypto_register_notifier(struct notifier_block *nb) | ||
252 | { | ||
253 | return blocking_notifier_chain_register(&crypto_chain, nb); | ||
254 | } | ||
255 | EXPORT_SYMBOL_GPL(crypto_register_notifier); | ||
256 | |||
257 | int crypto_unregister_notifier(struct notifier_block *nb) | ||
258 | { | ||
259 | return blocking_notifier_chain_unregister(&crypto_chain, nb); | ||
260 | } | ||
261 | EXPORT_SYMBOL_GPL(crypto_unregister_notifier); | ||
262 | |||
215 | static int __init crypto_algapi_init(void) | 263 | static int __init crypto_algapi_init(void) |
216 | { | 264 | { |
217 | crypto_init_proc(); | 265 | crypto_init_proc(); |