api.c (c51b6c8102a82239163c8c04e404c7cc2857b4be) api.c (73d3864a4823abda19ebc4387b6ddcbf416e3a77)
1/*
2 * Scatterlist Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
6 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
7 *
8 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>

--- 41 unchanged lines hidden (view full) ---

50{
51 struct module *module = alg->cra_module;
52
53 crypto_alg_put(alg);
54 module_put(module);
55}
56EXPORT_SYMBOL_GPL(crypto_mod_put);
57
1/*
2 * Scatterlist Cryptographic API.
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
6 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
7 *
8 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>

--- 41 unchanged lines hidden (view full) ---

50{
51 struct module *module = alg->cra_module;
52
53 crypto_alg_put(alg);
54 module_put(module);
55}
56EXPORT_SYMBOL_GPL(crypto_mod_put);
57
58static inline int crypto_is_test_larval(struct crypto_larval *larval)
59{
60 return larval->alg.cra_driver_name[0];
61}
62
58static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
59 u32 mask)
60{
61 struct crypto_alg *q, *alg = NULL;
62 int best = -2;
63
64 list_for_each_entry(q, &crypto_alg_list, cra_list) {
65 int exact, fuzzy;
66
67 if (crypto_is_moribund(q))
68 continue;
69
70 if ((q->cra_flags ^ type) & mask)
71 continue;
72
73 if (crypto_is_larval(q) &&
63static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
64 u32 mask)
65{
66 struct crypto_alg *q, *alg = NULL;
67 int best = -2;
68
69 list_for_each_entry(q, &crypto_alg_list, cra_list) {
70 int exact, fuzzy;
71
72 if (crypto_is_moribund(q))
73 continue;
74
75 if ((q->cra_flags ^ type) & mask)
76 continue;
77
78 if (crypto_is_larval(q) &&
79 !crypto_is_test_larval((struct crypto_larval *)q) &&
74 ((struct crypto_larval *)q)->mask != mask)
75 continue;
76
77 exact = !strcmp(q->cra_driver_name, name);
78 fuzzy = !strcmp(q->cra_name, name);
79 if (!exact && !(fuzzy && q->cra_priority > best))
80 continue;
81

--- 17 unchanged lines hidden (view full) ---

99 struct crypto_larval *larval = (void *)alg;
100
101 BUG_ON(!crypto_is_larval(alg));
102 if (larval->adult)
103 crypto_mod_put(larval->adult);
104 kfree(larval);
105}
106
80 ((struct crypto_larval *)q)->mask != mask)
81 continue;
82
83 exact = !strcmp(q->cra_driver_name, name);
84 fuzzy = !strcmp(q->cra_name, name);
85 if (!exact && !(fuzzy && q->cra_priority > best))
86 continue;
87

--- 17 unchanged lines hidden (view full) ---

105 struct crypto_larval *larval = (void *)alg;
106
107 BUG_ON(!crypto_is_larval(alg));
108 if (larval->adult)
109 crypto_mod_put(larval->adult);
110 kfree(larval);
111}
112
107static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
108 u32 mask)
113struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask)
109{
114{
110 struct crypto_alg *alg;
111 struct crypto_larval *larval;
112
113 larval = kzalloc(sizeof(*larval), GFP_KERNEL);
114 if (!larval)
115 return ERR_PTR(-ENOMEM);
116
117 larval->mask = mask;
118 larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type;
119 larval->alg.cra_priority = -1;
120 larval->alg.cra_destroy = crypto_larval_destroy;
121
115 struct crypto_larval *larval;
116
117 larval = kzalloc(sizeof(*larval), GFP_KERNEL);
118 if (!larval)
119 return ERR_PTR(-ENOMEM);
120
121 larval->mask = mask;
122 larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type;
123 larval->alg.cra_priority = -1;
124 larval->alg.cra_destroy = crypto_larval_destroy;
125
122 atomic_set(&larval->alg.cra_refcnt, 2);
123 strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
124 init_completion(&larval->completion);
125
126 strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
127 init_completion(&larval->completion);
128
129 return larval;
130}
131EXPORT_SYMBOL_GPL(crypto_larval_alloc);
132
133static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
134 u32 mask)
135{
136 struct crypto_alg *alg;
137 struct crypto_larval *larval;
138
139 larval = crypto_larval_alloc(name, type, mask);
140 if (IS_ERR(larval))
141 return ERR_CAST(larval);
142
143 atomic_set(&larval->alg.cra_refcnt, 2);
144
126 down_write(&crypto_alg_sem);
127 alg = __crypto_alg_lookup(name, type, mask);
128 if (!alg) {
129 alg = &larval->alg;
130 list_add(&alg->cra_list, &crypto_alg_list);
131 }
132 up_write(&crypto_alg_sem);
133

--- 13 unchanged lines hidden (view full) ---

147 complete_all(&larval->completion);
148 crypto_alg_put(alg);
149}
150EXPORT_SYMBOL_GPL(crypto_larval_kill);
151
152static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
153{
154 struct crypto_larval *larval = (void *)alg;
145 down_write(&crypto_alg_sem);
146 alg = __crypto_alg_lookup(name, type, mask);
147 if (!alg) {
148 alg = &larval->alg;
149 list_add(&alg->cra_list, &crypto_alg_list);
150 }
151 up_write(&crypto_alg_sem);
152

--- 13 unchanged lines hidden (view full) ---

166 complete_all(&larval->completion);
167 crypto_alg_put(alg);
168}
169EXPORT_SYMBOL_GPL(crypto_larval_kill);
170
171static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
172{
173 struct crypto_larval *larval = (void *)alg;
174 long timeout;
155
175
156 wait_for_completion_interruptible_timeout(&larval->completion, 60 * HZ);
176 timeout = wait_for_completion_interruptible_timeout(
177 &larval->completion, 60 * HZ);
178
157 alg = larval->adult;
179 alg = larval->adult;
158 if (alg) {
159 if (!crypto_mod_get(alg))
160 alg = ERR_PTR(-EAGAIN);
161 } else
180 if (timeout < 0)
181 alg = ERR_PTR(-EINTR);
182 else if (!timeout)
183 alg = ERR_PTR(-ETIMEDOUT);
184 else if (!alg)
162 alg = ERR_PTR(-ENOENT);
185 alg = ERR_PTR(-ENOENT);
186 else if (crypto_is_test_larval(larval) &&
187 !(alg->cra_flags & CRYPTO_ALG_TESTED))
188 alg = ERR_PTR(-EAGAIN);
189 else if (!crypto_mod_get(alg))
190 alg = ERR_PTR(-EAGAIN);
163 crypto_mod_put(&larval->alg);
164
165 return alg;
166}
167
168struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask)
169{
170 struct crypto_alg *alg;

--- 16 unchanged lines hidden (view full) ---

187 mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
188 type &= mask;
189
190 alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
191 name);
192 if (alg)
193 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
194
191 crypto_mod_put(&larval->alg);
192
193 return alg;
194}
195
196struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask)
197{
198 struct crypto_alg *alg;

--- 16 unchanged lines hidden (view full) ---

215 mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
216 type &= mask;
217
218 alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
219 name);
220 if (alg)
221 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
222
195 return crypto_larval_alloc(name, type, mask);
223 return crypto_larval_add(name, type, mask);
196}
197EXPORT_SYMBOL_GPL(crypto_larval_lookup);
198
224}
225EXPORT_SYMBOL_GPL(crypto_larval_lookup);
226
227int crypto_probing_notify(unsigned long val, void *v)
228{
229 int ok;
230
231 ok = blocking_notifier_call_chain(&crypto_chain, val, v);
232 if (ok == NOTIFY_DONE) {
233 request_module("cryptomgr");
234 ok = blocking_notifier_call_chain(&crypto_chain, val, v);
235 }
236
237 return ok;
238}
239EXPORT_SYMBOL_GPL(crypto_probing_notify);
240
199struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
200{
201 struct crypto_alg *alg;
202 struct crypto_alg *larval;
203 int ok;
204
241struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
242{
243 struct crypto_alg *alg;
244 struct crypto_alg *larval;
245 int ok;
246
247 if (!(mask & CRYPTO_ALG_TESTED)) {
248 type |= CRYPTO_ALG_TESTED;
249 mask |= CRYPTO_ALG_TESTED;
250 }
251
205 larval = crypto_larval_lookup(name, type, mask);
206 if (IS_ERR(larval) || !crypto_is_larval(larval))
207 return larval;
208
252 larval = crypto_larval_lookup(name, type, mask);
253 if (IS_ERR(larval) || !crypto_is_larval(larval))
254 return larval;
255
209 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
210 if (ok == NOTIFY_DONE) {
211 request_module("cryptomgr");
212 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
213 }
256 ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval);
214
215 if (ok == NOTIFY_STOP)
216 alg = crypto_larval_wait(larval);
217 else {
218 crypto_mod_put(larval);
219 alg = ERR_PTR(-ENOENT);
220 }
221 crypto_larval_kill(larval);

--- 233 unchanged lines hidden ---
257
258 if (ok == NOTIFY_STOP)
259 alg = crypto_larval_wait(larval);
260 else {
261 crypto_mod_put(larval);
262 alg = ERR_PTR(-ENOENT);
263 }
264 crypto_larval_kill(larval);

--- 233 unchanged lines hidden ---