Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * Scatterlist Cryptographic API.
4 : : *
5 : : * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
6 : : * Copyright (c) 2002 David S. Miller (davem@redhat.com)
7 : : * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
8 : : *
9 : : * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
10 : : * and Nettle, by Niels Möller.
11 : : */
12 : :
13 : : #include <linux/err.h>
14 : : #include <linux/errno.h>
15 : : #include <linux/kernel.h>
16 : : #include <linux/kmod.h>
17 : : #include <linux/module.h>
18 : : #include <linux/param.h>
19 : : #include <linux/sched/signal.h>
20 : : #include <linux/slab.h>
21 : : #include <linux/string.h>
22 : : #include <linux/completion.h>
23 : : #include "internal.h"
24 : :
25 : : LIST_HEAD(crypto_alg_list);
26 : : EXPORT_SYMBOL_GPL(crypto_alg_list);
27 : : DECLARE_RWSEM(crypto_alg_sem);
28 : : EXPORT_SYMBOL_GPL(crypto_alg_sem);
29 : :
30 : : BLOCKING_NOTIFIER_HEAD(crypto_chain);
31 : : EXPORT_SYMBOL_GPL(crypto_chain);
32 : :
33 : : static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
34 : :
35 : 735 : struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
36 : : {
37 [ + - ]: 735 : return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL;
38 : : }
39 : : EXPORT_SYMBOL_GPL(crypto_mod_get);
40 : :
41 : 672 : void crypto_mod_put(struct crypto_alg *alg)
42 : : {
43 : 672 : struct module *module = alg->cra_module;
44 : :
45 : 21 : crypto_alg_put(alg);
46 : 672 : module_put(module);
47 : 525 : }
48 : : EXPORT_SYMBOL_GPL(crypto_mod_put);
49 : :
50 : 21 : static inline int crypto_is_test_larval(struct crypto_larval *larval)
51 : : {
52 : 21 : return larval->alg.cra_driver_name[0];
53 : : }
54 : :
55 : 273 : static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
56 : : u32 mask)
57 : : {
58 : 273 : struct crypto_alg *q, *alg = NULL;
59 : 273 : int best = -2;
60 : :
61 [ + + ]: 6699 : list_for_each_entry(q, &crypto_alg_list, cra_list) {
62 : 6426 : int exact, fuzzy;
63 : :
64 [ - + ]: 6426 : if (crypto_is_moribund(q))
65 : 0 : continue;
66 : :
67 [ + + ]: 6426 : if ((q->cra_flags ^ type) & mask)
68 : 5271 : continue;
69 : :
70 [ - + ]: 1155 : if (crypto_is_larval(q) &&
71 [ # # ]: 0 : !crypto_is_test_larval((struct crypto_larval *)q) &&
72 [ # # ]: 0 : ((struct crypto_larval *)q)->mask != mask)
73 : 0 : continue;
74 : :
75 : 1155 : exact = !strcmp(q->cra_driver_name, name);
76 : 1155 : fuzzy = !strcmp(q->cra_name, name);
77 [ + - + + : 1155 : if (!exact && !(fuzzy && q->cra_priority > best))
- + ]
78 : 987 : continue;
79 : :
80 [ - + ]: 168 : if (unlikely(!crypto_mod_get(q)))
81 : 0 : continue;
82 : :
83 : 168 : best = q->cra_priority;
84 [ - + ]: 168 : if (alg)
85 : 0 : crypto_mod_put(alg);
86 : 168 : alg = q;
87 : :
88 [ + - ]: 168 : if (exact)
89 : : break;
90 : : }
91 : :
92 : 273 : return alg;
93 : : }
94 : :
95 : 525 : static void crypto_larval_destroy(struct crypto_alg *alg)
96 : : {
97 : 525 : struct crypto_larval *larval = (void *)alg;
98 : :
99 [ - + ]: 525 : BUG_ON(!crypto_is_larval(alg));
100 [ + - + - ]: 1050 : if (!IS_ERR_OR_NULL(larval->adult))
101 : 525 : crypto_mod_put(larval->adult);
102 : 525 : kfree(larval);
103 : 525 : }
104 : :
105 : 525 : struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask)
106 : : {
107 : 525 : struct crypto_larval *larval;
108 : :
109 : 525 : larval = kzalloc(sizeof(*larval), GFP_KERNEL);
110 [ + - ]: 525 : if (!larval)
111 : : return ERR_PTR(-ENOMEM);
112 : :
113 : 525 : larval->mask = mask;
114 : 525 : larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type;
115 : 525 : larval->alg.cra_priority = -1;
116 : 525 : larval->alg.cra_destroy = crypto_larval_destroy;
117 : :
118 : 525 : strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
119 : 525 : init_completion(&larval->completion);
120 : :
121 : 525 : return larval;
122 : : }
123 : : EXPORT_SYMBOL_GPL(crypto_larval_alloc);
124 : :
125 : 21 : static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
126 : : u32 mask)
127 : : {
128 : 21 : struct crypto_alg *alg;
129 : 21 : struct crypto_larval *larval;
130 : :
131 : 21 : larval = crypto_larval_alloc(name, type, mask);
132 [ + - ]: 21 : if (IS_ERR(larval))
133 : : return ERR_CAST(larval);
134 : :
135 : 21 : refcount_set(&larval->alg.cra_refcnt, 2);
136 : :
137 : 21 : down_write(&crypto_alg_sem);
138 : 21 : alg = __crypto_alg_lookup(name, type, mask);
139 [ + - ]: 21 : if (!alg) {
140 : 21 : alg = &larval->alg;
141 : 21 : list_add(&alg->cra_list, &crypto_alg_list);
142 : : }
143 : 21 : up_write(&crypto_alg_sem);
144 : :
145 [ - + ]: 21 : if (alg != &larval->alg) {
146 : 0 : kfree(larval);
147 [ # # ]: 0 : if (crypto_is_larval(alg))
148 : 0 : alg = crypto_larval_wait(alg);
149 : : }
150 : :
151 : : return alg;
152 : : }
153 : :
154 : 525 : void crypto_larval_kill(struct crypto_alg *alg)
155 : : {
156 : 525 : struct crypto_larval *larval = (void *)alg;
157 : :
158 : 525 : down_write(&crypto_alg_sem);
159 : 525 : list_del(&alg->cra_list);
160 : 525 : up_write(&crypto_alg_sem);
161 : 525 : complete_all(&larval->completion);
162 : 525 : crypto_alg_put(alg);
163 : 525 : }
164 : : EXPORT_SYMBOL_GPL(crypto_larval_kill);
165 : :
166 : 21 : static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
167 : : {
168 : 21 : struct crypto_larval *larval = (void *)alg;
169 : 21 : long timeout;
170 : :
171 : 21 : timeout = wait_for_completion_killable_timeout(
172 : : &larval->completion, 60 * HZ);
173 : :
174 : 21 : alg = larval->adult;
175 [ + - ]: 21 : if (timeout < 0)
176 : : alg = ERR_PTR(-EINTR);
177 [ + - ]: 21 : else if (!timeout)
178 : : alg = ERR_PTR(-ETIMEDOUT);
179 [ + - ]: 21 : else if (!alg)
180 : : alg = ERR_PTR(-ENOENT);
181 [ + - ]: 21 : else if (IS_ERR(alg))
182 : : ;
183 [ - + ]: 21 : else if (crypto_is_test_larval(larval) &&
184 [ # # ]: 0 : !(alg->cra_flags & CRYPTO_ALG_TESTED))
185 : : alg = ERR_PTR(-EAGAIN);
186 [ - + ]: 21 : else if (!crypto_mod_get(alg))
187 : 0 : alg = ERR_PTR(-EAGAIN);
188 : 21 : crypto_mod_put(&larval->alg);
189 : :
190 : 21 : return alg;
191 : : }
192 : :
193 : 210 : static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
194 : : u32 mask)
195 : : {
196 : 210 : struct crypto_alg *alg;
197 : 210 : u32 test = 0;
198 : :
199 [ + - ]: 210 : if (!((type | mask) & CRYPTO_ALG_TESTED))
200 : 210 : test |= CRYPTO_ALG_TESTED;
201 : :
202 : 210 : down_read(&crypto_alg_sem);
203 : 210 : alg = __crypto_alg_lookup(name, type | test, mask | test);
204 [ + + ]: 210 : if (!alg && test) {
205 : 42 : alg = __crypto_alg_lookup(name, type, mask);
206 [ - + - - ]: 42 : if (alg && !crypto_is_larval(alg)) {
207 : : /* Test failed */
208 : 0 : crypto_mod_put(alg);
209 : 0 : alg = ERR_PTR(-ELIBBAD);
210 : : }
211 : : }
212 : 210 : up_read(&crypto_alg_sem);
213 : :
214 : 210 : return alg;
215 : : }
216 : :
217 : 189 : static struct crypto_alg *crypto_larval_lookup(const char *name, u32 type,
218 : : u32 mask)
219 : : {
220 : 189 : struct crypto_alg *alg;
221 : :
222 [ + - ]: 189 : if (!name)
223 : : return ERR_PTR(-ENOENT);
224 : :
225 : 189 : type &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
226 : 189 : mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
227 : :
228 : 189 : alg = crypto_alg_lookup(name, type, mask);
229 [ + + + - ]: 189 : if (!alg && !(mask & CRYPTO_NOLOAD)) {
230 : 21 : request_module("crypto-%s", name);
231 : :
232 [ + - ]: 21 : if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask &
233 : : CRYPTO_ALG_NEED_FALLBACK))
234 : 21 : request_module("crypto-%s-all", name);
235 : :
236 : 21 : alg = crypto_alg_lookup(name, type, mask);
237 : : }
238 : :
239 [ + + + + : 357 : if (!IS_ERR_OR_NULL(alg) && crypto_is_larval(alg))
- + ]
240 : 0 : alg = crypto_larval_wait(alg);
241 [ + + ]: 189 : else if (!alg)
242 : 21 : alg = crypto_larval_add(name, type, mask);
243 : :
244 : : return alg;
245 : : }
246 : :
247 : 1029 : int crypto_probing_notify(unsigned long val, void *v)
248 : : {
249 : 1029 : int ok;
250 : :
251 : 1029 : ok = blocking_notifier_call_chain(&crypto_chain, val, v);
252 [ + + ]: 1029 : if (ok == NOTIFY_DONE) {
253 : 504 : request_module("cryptomgr");
254 : 504 : ok = blocking_notifier_call_chain(&crypto_chain, val, v);
255 : : }
256 : :
257 : 1029 : return ok;
258 : : }
259 : : EXPORT_SYMBOL_GPL(crypto_probing_notify);
260 : :
261 : 189 : struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
262 : : {
263 : 189 : struct crypto_alg *alg;
264 : 189 : struct crypto_alg *larval;
265 : 189 : int ok;
266 : :
267 : : /*
268 : : * If the internal flag is set for a cipher, require a caller to
269 : : * to invoke the cipher with the internal flag to use that cipher.
270 : : * Also, if a caller wants to allocate a cipher that may or may
271 : : * not be an internal cipher, use type | CRYPTO_ALG_INTERNAL and
272 : : * !(mask & CRYPTO_ALG_INTERNAL).
273 : : */
274 [ + - ]: 189 : if (!((type | mask) & CRYPTO_ALG_INTERNAL))
275 : 189 : mask |= CRYPTO_ALG_INTERNAL;
276 : :
277 : 189 : larval = crypto_larval_lookup(name, type, mask);
278 [ + - + + ]: 189 : if (IS_ERR(larval) || !crypto_is_larval(larval))
279 : : return larval;
280 : :
281 : 21 : ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval);
282 : :
283 [ + - ]: 21 : if (ok == NOTIFY_STOP)
284 : 21 : alg = crypto_larval_wait(larval);
285 : : else {
286 : 0 : crypto_mod_put(larval);
287 : 0 : alg = ERR_PTR(-ENOENT);
288 : : }
289 : 21 : crypto_larval_kill(larval);
290 : 21 : return alg;
291 : : }
292 : : EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup);
293 : :
294 : 0 : static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
295 : : {
296 : 0 : const struct crypto_type *type_obj = tfm->__crt_alg->cra_type;
297 : :
298 : 0 : if (type_obj)
299 : 0 : return type_obj->init(tfm, type, mask);
300 : : return 0;
301 : : }
302 : :
303 : 105 : static void crypto_exit_ops(struct crypto_tfm *tfm)
304 : : {
305 : 105 : const struct crypto_type *type = tfm->__crt_alg->cra_type;
306 : :
307 [ + + - - : 105 : if (type && tfm->exit)
- - ]
308 : 42 : tfm->exit(tfm);
309 : : }
310 : :
311 : 0 : static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask)
312 : : {
313 : 0 : const struct crypto_type *type_obj = alg->cra_type;
314 : 0 : unsigned int len;
315 : :
316 [ # # ]: 0 : len = alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1);
317 [ # # ]: 0 : if (type_obj)
318 : 0 : return len + type_obj->ctxsize(alg, type, mask);
319 : :
320 [ # # # ]: 0 : switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
321 : 0 : default:
322 : 0 : BUG();
323 : :
324 : 0 : case CRYPTO_ALG_TYPE_CIPHER:
325 : 0 : len += crypto_cipher_ctxsize(alg);
326 : 0 : break;
327 : :
328 : 0 : case CRYPTO_ALG_TYPE_COMPRESS:
329 : 0 : len += crypto_compress_ctxsize(alg);
330 : 0 : break;
331 : : }
332 : :
333 : : return len;
334 : : }
335 : :
336 : 0 : static void crypto_shoot_alg(struct crypto_alg *alg)
337 : : {
338 : 0 : down_write(&crypto_alg_sem);
339 : 0 : alg->cra_flags |= CRYPTO_ALG_DYING;
340 : 0 : up_write(&crypto_alg_sem);
341 : 0 : }
342 : :
343 : 0 : struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
344 : : u32 mask)
345 : : {
346 : 0 : struct crypto_tfm *tfm = NULL;
347 : 0 : unsigned int tfm_size;
348 : 0 : int err = -ENOMEM;
349 : :
350 : 0 : tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, type, mask);
351 : 0 : tfm = kzalloc(tfm_size, GFP_KERNEL);
352 [ # # ]: 0 : if (tfm == NULL)
353 : 0 : goto out_err;
354 : :
355 : 0 : tfm->__crt_alg = alg;
356 : :
357 [ # # ]: 0 : err = crypto_init_ops(tfm, type, mask);
358 [ # # ]: 0 : if (err)
359 : 0 : goto out_free_tfm;
360 : :
361 [ # # # # : 0 : if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm)))
# # ]
362 : 0 : goto cra_init_failed;
363 : :
364 : 0 : goto out;
365 : :
366 : : cra_init_failed:
367 [ # # ]: 0 : crypto_exit_ops(tfm);
368 : 0 : out_free_tfm:
369 [ # # ]: 0 : if (err == -EAGAIN)
370 : 0 : crypto_shoot_alg(alg);
371 : 0 : kfree(tfm);
372 : 0 : out_err:
373 : 0 : tfm = ERR_PTR(err);
374 : 0 : out:
375 : 0 : return tfm;
376 : : }
377 : : EXPORT_SYMBOL_GPL(__crypto_alloc_tfm);
378 : :
379 : : /*
380 : : * crypto_alloc_base - Locate algorithm and allocate transform
381 : : * @alg_name: Name of algorithm
382 : : * @type: Type of algorithm
383 : : * @mask: Mask for type comparison
384 : : *
385 : : * This function should not be used by new algorithm types.
386 : : * Please use crypto_alloc_tfm instead.
387 : : *
388 : : * crypto_alloc_base() will first attempt to locate an already loaded
389 : : * algorithm. If that fails and the kernel supports dynamically loadable
390 : : * modules, it will then attempt to load a module of the same name or
391 : : * alias. If that fails it will send a query to any loaded crypto manager
392 : : * to construct an algorithm on the fly. A refcount is grabbed on the
393 : : * algorithm which is then associated with the new transform.
394 : : *
395 : : * The returned transform is of a non-determinate type. Most people
396 : : * should use one of the more specific allocation functions such as
397 : : * crypto_alloc_skcipher().
398 : : *
399 : : * In case of error the return value is an error pointer.
400 : : */
401 : 0 : struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
402 : : {
403 : 0 : struct crypto_tfm *tfm;
404 : 0 : int err;
405 : :
406 : 0 : for (;;) {
407 : 0 : struct crypto_alg *alg;
408 : :
409 : 0 : alg = crypto_alg_mod_lookup(alg_name, type, mask);
410 [ # # ]: 0 : if (IS_ERR(alg)) {
411 : 0 : err = PTR_ERR(alg);
412 : 0 : goto err;
413 : : }
414 : :
415 : 0 : tfm = __crypto_alloc_tfm(alg, type, mask);
416 [ # # ]: 0 : if (!IS_ERR(tfm))
417 : 0 : return tfm;
418 : :
419 : 0 : crypto_mod_put(alg);
420 : 0 : err = PTR_ERR(tfm);
421 : :
422 : 0 : err:
423 [ # # ]: 0 : if (err != -EAGAIN)
424 : : break;
425 [ # # ]: 0 : if (fatal_signal_pending(current)) {
426 : : err = -EINTR;
427 : : break;
428 : : }
429 : : }
430 : :
431 : 0 : return ERR_PTR(err);
432 : : }
433 : : EXPORT_SYMBOL_GPL(crypto_alloc_base);
434 : :
435 : 189 : void *crypto_create_tfm(struct crypto_alg *alg,
436 : : const struct crypto_type *frontend)
437 : : {
438 : 189 : char *mem;
439 : 189 : struct crypto_tfm *tfm = NULL;
440 : 189 : unsigned int tfmsize;
441 : 189 : unsigned int total;
442 : 189 : int err = -ENOMEM;
443 : :
444 : 189 : tfmsize = frontend->tfmsize;
445 : 189 : total = tfmsize + sizeof(*tfm) + frontend->extsize(alg);
446 : :
447 : 189 : mem = kzalloc(total, GFP_KERNEL);
448 [ - + ]: 189 : if (mem == NULL)
449 : 0 : goto out_err;
450 : :
451 : 189 : tfm = (struct crypto_tfm *)(mem + tfmsize);
452 : 189 : tfm->__crt_alg = alg;
453 : :
454 : 189 : err = frontend->init_tfm(tfm);
455 [ - + ]: 189 : if (err)
456 : 0 : goto out_free_tfm;
457 : :
458 [ + + + + : 189 : if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm)))
- + ]
459 : 0 : goto cra_init_failed;
460 : :
461 : 189 : goto out;
462 : :
463 : : cra_init_failed:
464 [ # # ]: 0 : crypto_exit_ops(tfm);
465 : 0 : out_free_tfm:
466 [ # # ]: 0 : if (err == -EAGAIN)
467 : 0 : crypto_shoot_alg(alg);
468 : 0 : kfree(mem);
469 : 0 : out_err:
470 : 0 : mem = ERR_PTR(err);
471 : 189 : out:
472 : 189 : return mem;
473 : : }
474 : : EXPORT_SYMBOL_GPL(crypto_create_tfm);
475 : :
476 : 189 : struct crypto_alg *crypto_find_alg(const char *alg_name,
477 : : const struct crypto_type *frontend,
478 : : u32 type, u32 mask)
479 : : {
480 [ + - ]: 21 : if (frontend) {
481 : 189 : type &= frontend->maskclear;
482 : 189 : mask &= frontend->maskclear;
483 : 189 : type |= frontend->type;
484 : 189 : mask |= frontend->maskset;
485 : : }
486 : :
487 : 189 : return crypto_alg_mod_lookup(alg_name, type, mask);
488 : : }
489 : : EXPORT_SYMBOL_GPL(crypto_find_alg);
490 : :
491 : : /*
492 : : * crypto_alloc_tfm - Locate algorithm and allocate transform
493 : : * @alg_name: Name of algorithm
494 : : * @frontend: Frontend algorithm type
495 : : * @type: Type of algorithm
496 : : * @mask: Mask for type comparison
497 : : *
498 : : * crypto_alloc_tfm() will first attempt to locate an already loaded
499 : : * algorithm. If that fails and the kernel supports dynamically loadable
500 : : * modules, it will then attempt to load a module of the same name or
501 : : * alias. If that fails it will send a query to any loaded crypto manager
502 : : * to construct an algorithm on the fly. A refcount is grabbed on the
503 : : * algorithm which is then associated with the new transform.
504 : : *
505 : : * The returned transform is of a non-determinate type. Most people
506 : : * should use one of the more specific allocation functions such as
507 : : * crypto_alloc_skcipher().
508 : : *
509 : : * In case of error the return value is an error pointer.
510 : : */
511 : 168 : void *crypto_alloc_tfm(const char *alg_name,
512 : : const struct crypto_type *frontend, u32 type, u32 mask)
513 : : {
514 : 168 : void *tfm;
515 : 168 : int err;
516 : :
517 : 168 : for (;;) {
518 : 168 : struct crypto_alg *alg;
519 : :
520 [ + - ]: 168 : alg = crypto_find_alg(alg_name, frontend, type, mask);
521 [ - + ]: 168 : if (IS_ERR(alg)) {
522 : 0 : err = PTR_ERR(alg);
523 : 0 : goto err;
524 : : }
525 : :
526 : 168 : tfm = crypto_create_tfm(alg, frontend);
527 [ + - ]: 168 : if (!IS_ERR(tfm))
528 : 168 : return tfm;
529 : :
530 : 0 : crypto_mod_put(alg);
531 : 0 : err = PTR_ERR(tfm);
532 : :
533 : 0 : err:
534 [ # # ]: 0 : if (err != -EAGAIN)
535 : : break;
536 [ # # ]: 0 : if (fatal_signal_pending(current)) {
537 : : err = -EINTR;
538 : : break;
539 : : }
540 : : }
541 : :
542 : 0 : return ERR_PTR(err);
543 : : }
544 : : EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
545 : :
546 : : /*
547 : : * crypto_destroy_tfm - Free crypto transform
548 : : * @mem: Start of tfm slab
549 : : * @tfm: Transform to free
550 : : *
551 : : * This function frees up the transform and any associated resources,
552 : : * then drops the refcount on the associated algorithm.
553 : : */
554 : 105 : void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
555 : : {
556 : 105 : struct crypto_alg *alg;
557 : :
558 [ + - ]: 105 : if (unlikely(!mem))
559 : : return;
560 : :
561 : 105 : alg = tfm->__crt_alg;
562 : :
563 [ + + - + ]: 105 : if (!tfm->exit && alg->cra_exit)
564 : 0 : alg->cra_exit(tfm);
565 [ + - ]: 105 : crypto_exit_ops(tfm);
566 : 105 : crypto_mod_put(alg);
567 : 105 : kzfree(mem);
568 : : }
569 : : EXPORT_SYMBOL_GPL(crypto_destroy_tfm);
570 : :
571 : 0 : int crypto_has_alg(const char *name, u32 type, u32 mask)
572 : : {
573 : 0 : int ret = 0;
574 : 0 : struct crypto_alg *alg = crypto_alg_mod_lookup(name, type, mask);
575 : :
576 [ # # ]: 0 : if (!IS_ERR(alg)) {
577 : 0 : crypto_mod_put(alg);
578 : 0 : ret = 1;
579 : : }
580 : :
581 : 0 : return ret;
582 : : }
583 : : EXPORT_SYMBOL_GPL(crypto_has_alg);
584 : :
585 : 0 : void crypto_req_done(struct crypto_async_request *req, int err)
586 : : {
587 : 0 : struct crypto_wait *wait = req->data;
588 : :
589 [ # # ]: 0 : if (err == -EINPROGRESS)
590 : : return;
591 : :
592 : 0 : wait->err = err;
593 : 0 : complete(&wait->completion);
594 : : }
595 : : EXPORT_SYMBOL_GPL(crypto_req_done);
596 : :
597 : : MODULE_DESCRIPTION("Cryptographic core API");
598 : : MODULE_LICENSE("GPL");
599 : : MODULE_SOFTDEP("pre: cryptomgr");
|