Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Cryptographic API for algorithms (i.e., low-level API).
4 : *
5 : * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
6 : */
7 :
8 : #include <crypto/algapi.h>
9 : #include <linux/err.h>
10 : #include <linux/errno.h>
11 : #include <linux/fips.h>
12 : #include <linux/init.h>
13 : #include <linux/kernel.h>
14 : #include <linux/list.h>
15 : #include <linux/module.h>
16 : #include <linux/rtnetlink.h>
17 : #include <linux/slab.h>
18 : #include <linux/string.h>
19 :
20 : #include "internal.h"
21 :
22 : static LIST_HEAD(crypto_template_list);
23 :
24 10 : static inline void crypto_check_module_sig(struct module *mod)
25 : {
26 10 : if (fips_enabled && mod && !module_sig_ok(mod))
27 : panic("Module %s signature verification failed in FIPS mode\n",
28 : module_name(mod));
29 : }
30 :
31 10 : static int crypto_check_alg(struct crypto_alg *alg)
32 : {
33 10 : crypto_check_module_sig(alg->cra_module);
34 :
35 10 : if (!alg->cra_name[0] || !alg->cra_driver_name[0])
36 : return -EINVAL;
37 :
38 10 : if (alg->cra_alignmask & (alg->cra_alignmask + 1))
39 : return -EINVAL;
40 :
41 : /* General maximums for all algs. */
42 10 : if (alg->cra_alignmask > MAX_ALGAPI_ALIGNMASK)
43 : return -EINVAL;
44 :
45 10 : if (alg->cra_blocksize > MAX_ALGAPI_BLOCKSIZE)
46 : return -EINVAL;
47 :
48 : /* Lower maximums for specific alg types. */
49 10 : if (!alg->cra_type && (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
50 : CRYPTO_ALG_TYPE_CIPHER) {
51 2 : if (alg->cra_alignmask > MAX_CIPHER_ALIGNMASK)
52 : return -EINVAL;
53 :
54 2 : if (alg->cra_blocksize > MAX_CIPHER_BLOCKSIZE)
55 : return -EINVAL;
56 : }
57 :
58 10 : if (alg->cra_priority < 0)
59 : return -EINVAL;
60 :
61 10 : refcount_set(&alg->cra_refcnt, 1);
62 :
63 10 : return 0;
64 : }
65 :
66 0 : static void crypto_free_instance(struct crypto_instance *inst)
67 : {
68 0 : inst->alg.cra_type->free(inst);
69 : }
70 :
71 0 : static void crypto_destroy_instance(struct crypto_alg *alg)
72 : {
73 0 : struct crypto_instance *inst = (void *)alg;
74 0 : struct crypto_template *tmpl = inst->tmpl;
75 :
76 0 : crypto_free_instance(inst);
77 0 : crypto_tmpl_put(tmpl);
78 0 : }
79 :
80 : /*
81 : * This function adds a spawn to the list secondary_spawns which
82 : * will be used at the end of crypto_remove_spawns to unregister
83 : * instances, unless the spawn happens to be one that is depended
84 : * on by the new algorithm (nalg in crypto_remove_spawns).
85 : *
86 : * This function is also responsible for resurrecting any algorithms
87 : * in the dependency chain of nalg by unsetting n->dead.
88 : */
89 1 : static struct list_head *crypto_more_spawns(struct crypto_alg *alg,
90 : struct list_head *stack,
91 : struct list_head *top,
92 : struct list_head *secondary_spawns)
93 : {
94 1 : struct crypto_spawn *spawn, *n;
95 :
96 1 : spawn = list_first_entry_or_null(stack, struct crypto_spawn, list);
97 0 : if (!spawn)
98 : return NULL;
99 :
100 0 : n = list_prev_entry(spawn, list);
101 0 : list_move(&spawn->list, secondary_spawns);
102 :
103 0 : if (list_is_last(&n->list, stack))
104 : return top;
105 :
106 0 : n = list_next_entry(n, list);
107 0 : if (!spawn->dead)
108 0 : n->dead = false;
109 :
110 0 : return &n->inst->alg.cra_users;
111 : }
112 :
113 0 : static void crypto_remove_instance(struct crypto_instance *inst,
114 : struct list_head *list)
115 : {
116 0 : struct crypto_template *tmpl = inst->tmpl;
117 :
118 0 : if (crypto_is_dead(&inst->alg))
119 : return;
120 :
121 0 : inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
122 :
123 0 : if (!tmpl || !crypto_tmpl_get(tmpl))
124 : return;
125 :
126 0 : list_move(&inst->alg.cra_list, list);
127 0 : hlist_del(&inst->list);
128 0 : inst->alg.cra_destroy = crypto_destroy_instance;
129 :
130 0 : BUG_ON(!list_empty(&inst->alg.cra_users));
131 : }
132 :
133 : /*
134 : * Given an algorithm alg, remove all algorithms that depend on it
135 : * through spawns. If nalg is not null, then exempt any algorithms
136 : * that is depended on by nalg. This is useful when nalg itself
137 : * depends on alg.
138 : */
139 1 : void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
140 : struct crypto_alg *nalg)
141 : {
142 1 : u32 new_type = (nalg ?: alg)->cra_flags;
143 1 : struct crypto_spawn *spawn, *n;
144 1 : LIST_HEAD(secondary_spawns);
145 1 : struct list_head *spawns;
146 1 : LIST_HEAD(stack);
147 1 : LIST_HEAD(top);
148 :
149 1 : spawns = &alg->cra_users;
150 1 : list_for_each_entry_safe(spawn, n, spawns, list) {
151 0 : if ((spawn->alg->cra_flags ^ new_type) & spawn->mask)
152 0 : continue;
153 :
154 0 : list_move(&spawn->list, &top);
155 : }
156 :
157 : /*
158 : * Perform a depth-first walk starting from alg through
159 : * the cra_users tree. The list stack records the path
160 : * from alg to the current spawn.
161 : */
162 : spawns = ⊤
163 : do {
164 1 : while (!list_empty(spawns)) {
165 0 : struct crypto_instance *inst;
166 :
167 0 : spawn = list_first_entry(spawns, struct crypto_spawn,
168 : list);
169 0 : inst = spawn->inst;
170 :
171 0 : list_move(&spawn->list, &stack);
172 0 : spawn->dead = !spawn->registered || &inst->alg != nalg;
173 :
174 0 : if (!spawn->registered)
175 : break;
176 :
177 0 : BUG_ON(&inst->alg == alg);
178 :
179 0 : if (&inst->alg == nalg)
180 : break;
181 :
182 0 : spawns = &inst->alg.cra_users;
183 :
184 : /*
185 : * Even if spawn->registered is true, the
186 : * instance itself may still be unregistered.
187 : * This is because it may have failed during
188 : * registration. Therefore we still need to
189 : * make the following test.
190 : *
191 : * We may encounter an unregistered instance here, since
192 : * an instance's spawns are set up prior to the instance
193 : * being registered. An unregistered instance will have
194 : * NULL ->cra_users.next, since ->cra_users isn't
195 : * properly initialized until registration. But an
196 : * unregistered instance cannot have any users, so treat
197 : * it the same as ->cra_users being empty.
198 : */
199 0 : if (spawns->next == NULL)
200 : break;
201 : }
202 1 : } while ((spawns = crypto_more_spawns(alg, &stack, &top,
203 1 : &secondary_spawns)));
204 :
205 : /*
206 : * Remove all instances that are marked as dead. Also
207 : * complete the resurrection of the others by moving them
208 : * back to the cra_users list.
209 : */
210 1 : list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
211 0 : if (!spawn->dead)
212 0 : list_move(&spawn->list, &spawn->alg->cra_users);
213 0 : else if (spawn->registered)
214 0 : crypto_remove_instance(spawn->inst, list);
215 : }
216 1 : }
217 : EXPORT_SYMBOL_GPL(crypto_remove_spawns);
218 :
219 10 : static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
220 : {
221 10 : struct crypto_alg *q;
222 10 : struct crypto_larval *larval;
223 10 : int ret = -EAGAIN;
224 :
225 10 : if (crypto_is_dead(alg))
226 0 : goto err;
227 :
228 10 : INIT_LIST_HEAD(&alg->cra_users);
229 :
230 : /* No cheating! */
231 10 : alg->cra_flags &= ~CRYPTO_ALG_TESTED;
232 :
233 10 : ret = -EEXIST;
234 :
235 55 : list_for_each_entry(q, &crypto_alg_list, cra_list) {
236 45 : if (q == alg)
237 0 : goto err;
238 :
239 45 : if (crypto_is_moribund(q))
240 0 : continue;
241 :
242 45 : if (crypto_is_larval(q)) {
243 0 : if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
244 0 : goto err;
245 0 : continue;
246 : }
247 :
248 45 : if (!strcmp(q->cra_driver_name, alg->cra_name) ||
249 45 : !strcmp(q->cra_name, alg->cra_driver_name))
250 0 : goto err;
251 : }
252 :
253 10 : larval = crypto_larval_alloc(alg->cra_name,
254 : alg->cra_flags | CRYPTO_ALG_TESTED, 0);
255 10 : if (IS_ERR(larval))
256 0 : goto out;
257 :
258 10 : ret = -ENOENT;
259 10 : larval->adult = crypto_mod_get(alg);
260 10 : if (!larval->adult)
261 0 : goto free_larval;
262 :
263 10 : refcount_set(&larval->alg.cra_refcnt, 1);
264 10 : memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
265 : CRYPTO_MAX_ALG_NAME);
266 10 : larval->alg.cra_priority = alg->cra_priority;
267 :
268 10 : list_add(&alg->cra_list, &crypto_alg_list);
269 10 : list_add(&larval->alg.cra_list, &crypto_alg_list);
270 :
271 10 : crypto_stats_init(alg);
272 :
273 10 : out:
274 10 : return larval;
275 :
276 0 : free_larval:
277 0 : kfree(larval);
278 0 : err:
279 0 : larval = ERR_PTR(ret);
280 0 : goto out;
281 : }
282 :
283 10 : void crypto_alg_tested(const char *name, int err)
284 : {
285 10 : struct crypto_larval *test;
286 10 : struct crypto_alg *alg;
287 10 : struct crypto_alg *q;
288 10 : LIST_HEAD(list);
289 10 : bool best;
290 :
291 10 : down_write(&crypto_alg_sem);
292 10 : list_for_each_entry(q, &crypto_alg_list, cra_list) {
293 10 : if (crypto_is_moribund(q) || !crypto_is_larval(q))
294 0 : continue;
295 :
296 10 : test = (struct crypto_larval *)q;
297 :
298 10 : if (!strcmp(q->cra_driver_name, name))
299 10 : goto found;
300 : }
301 :
302 0 : pr_err("alg: Unexpected test result for %s: %d\n", name, err);
303 0 : goto unlock;
304 :
305 10 : found:
306 10 : q->cra_flags |= CRYPTO_ALG_DEAD;
307 10 : alg = test->adult;
308 10 : if (err || list_empty(&alg->cra_list))
309 0 : goto complete;
310 :
311 10 : alg->cra_flags |= CRYPTO_ALG_TESTED;
312 :
313 : /* Only satisfy larval waiters if we are the best. */
314 10 : best = true;
315 75 : list_for_each_entry(q, &crypto_alg_list, cra_list) {
316 65 : if (crypto_is_moribund(q) || !crypto_is_larval(q))
317 65 : continue;
318 :
319 0 : if (strcmp(alg->cra_name, q->cra_name))
320 0 : continue;
321 :
322 0 : if (q->cra_priority > alg->cra_priority) {
323 : best = false;
324 : break;
325 : }
326 : }
327 :
328 75 : list_for_each_entry(q, &crypto_alg_list, cra_list) {
329 65 : if (q == alg)
330 10 : continue;
331 :
332 55 : if (crypto_is_moribund(q))
333 10 : continue;
334 :
335 45 : if (crypto_is_larval(q)) {
336 0 : struct crypto_larval *larval = (void *)q;
337 :
338 : /*
339 : * Check to see if either our generic name or
340 : * specific name can satisfy the name requested
341 : * by the larval entry q.
342 : */
343 0 : if (strcmp(alg->cra_name, q->cra_name) &&
344 0 : strcmp(alg->cra_driver_name, q->cra_name))
345 0 : continue;
346 :
347 0 : if (larval->adult)
348 0 : continue;
349 0 : if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
350 0 : continue;
351 :
352 0 : if (best && crypto_mod_get(alg))
353 0 : larval->adult = alg;
354 : else
355 0 : larval->adult = ERR_PTR(-EAGAIN);
356 :
357 0 : continue;
358 : }
359 :
360 45 : if (strcmp(alg->cra_name, q->cra_name))
361 44 : continue;
362 :
363 1 : if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
364 1 : q->cra_priority > alg->cra_priority)
365 0 : continue;
366 :
367 1 : crypto_remove_spawns(q, &list, alg);
368 : }
369 :
370 10 : complete:
371 10 : complete_all(&test->completion);
372 :
373 10 : unlock:
374 10 : up_write(&crypto_alg_sem);
375 :
376 10 : crypto_remove_final(&list);
377 10 : }
378 : EXPORT_SYMBOL_GPL(crypto_alg_tested);
379 :
380 10 : void crypto_remove_final(struct list_head *list)
381 : {
382 10 : struct crypto_alg *alg;
383 10 : struct crypto_alg *n;
384 :
385 10 : list_for_each_entry_safe(alg, n, list, cra_list) {
386 0 : list_del_init(&alg->cra_list);
387 0 : crypto_alg_put(alg);
388 : }
389 10 : }
390 : EXPORT_SYMBOL_GPL(crypto_remove_final);
391 :
392 10 : static void crypto_wait_for_test(struct crypto_larval *larval)
393 : {
394 10 : int err;
395 :
396 10 : err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
397 10 : if (err != NOTIFY_STOP) {
398 10 : if (WARN_ON(err != NOTIFY_DONE))
399 0 : goto out;
400 10 : crypto_alg_tested(larval->alg.cra_driver_name, 0);
401 : }
402 :
403 10 : err = wait_for_completion_killable(&larval->completion);
404 10 : WARN_ON(err);
405 10 : if (!err)
406 10 : crypto_notify(CRYPTO_MSG_ALG_LOADED, larval);
407 :
408 0 : out:
409 10 : crypto_larval_kill(&larval->alg);
410 10 : }
411 :
412 10 : int crypto_register_alg(struct crypto_alg *alg)
413 : {
414 10 : struct crypto_larval *larval;
415 10 : int err;
416 :
417 10 : alg->cra_flags &= ~CRYPTO_ALG_DEAD;
418 10 : err = crypto_check_alg(alg);
419 10 : if (err)
420 : return err;
421 :
422 10 : down_write(&crypto_alg_sem);
423 10 : larval = __crypto_register_alg(alg);
424 10 : up_write(&crypto_alg_sem);
425 :
426 10 : if (IS_ERR(larval))
427 0 : return PTR_ERR(larval);
428 :
429 10 : crypto_wait_for_test(larval);
430 10 : return 0;
431 : }
432 : EXPORT_SYMBOL_GPL(crypto_register_alg);
433 :
434 0 : static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)
435 : {
436 0 : if (unlikely(list_empty(&alg->cra_list)))
437 : return -ENOENT;
438 :
439 0 : alg->cra_flags |= CRYPTO_ALG_DEAD;
440 :
441 0 : list_del_init(&alg->cra_list);
442 0 : crypto_remove_spawns(alg, list, NULL);
443 :
444 0 : return 0;
445 : }
446 :
447 0 : void crypto_unregister_alg(struct crypto_alg *alg)
448 : {
449 0 : int ret;
450 0 : LIST_HEAD(list);
451 :
452 0 : down_write(&crypto_alg_sem);
453 0 : ret = crypto_remove_alg(alg, &list);
454 0 : up_write(&crypto_alg_sem);
455 :
456 0 : if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name))
457 0 : return;
458 :
459 0 : BUG_ON(refcount_read(&alg->cra_refcnt) != 1);
460 0 : if (alg->cra_destroy)
461 0 : alg->cra_destroy(alg);
462 :
463 0 : crypto_remove_final(&list);
464 : }
465 : EXPORT_SYMBOL_GPL(crypto_unregister_alg);
466 :
467 1 : int crypto_register_algs(struct crypto_alg *algs, int count)
468 : {
469 1 : int i, ret;
470 :
471 3 : for (i = 0; i < count; i++) {
472 2 : ret = crypto_register_alg(&algs[i]);
473 2 : if (ret)
474 0 : goto err;
475 : }
476 :
477 : return 0;
478 :
479 0 : err:
480 0 : for (--i; i >= 0; --i)
481 0 : crypto_unregister_alg(&algs[i]);
482 :
483 : return ret;
484 : }
485 : EXPORT_SYMBOL_GPL(crypto_register_algs);
486 :
487 0 : void crypto_unregister_algs(struct crypto_alg *algs, int count)
488 : {
489 0 : int i;
490 :
491 0 : for (i = 0; i < count; i++)
492 0 : crypto_unregister_alg(&algs[i]);
493 0 : }
494 : EXPORT_SYMBOL_GPL(crypto_unregister_algs);
495 :
496 0 : int crypto_register_template(struct crypto_template *tmpl)
497 : {
498 0 : struct crypto_template *q;
499 0 : int err = -EEXIST;
500 :
501 0 : down_write(&crypto_alg_sem);
502 :
503 0 : crypto_check_module_sig(tmpl->module);
504 :
505 0 : list_for_each_entry(q, &crypto_template_list, list) {
506 0 : if (q == tmpl)
507 0 : goto out;
508 : }
509 :
510 0 : list_add(&tmpl->list, &crypto_template_list);
511 0 : err = 0;
512 0 : out:
513 0 : up_write(&crypto_alg_sem);
514 0 : return err;
515 : }
516 : EXPORT_SYMBOL_GPL(crypto_register_template);
517 :
518 0 : int crypto_register_templates(struct crypto_template *tmpls, int count)
519 : {
520 0 : int i, err;
521 :
522 0 : for (i = 0; i < count; i++) {
523 0 : err = crypto_register_template(&tmpls[i]);
524 0 : if (err)
525 0 : goto out;
526 : }
527 : return 0;
528 :
529 0 : out:
530 0 : for (--i; i >= 0; --i)
531 0 : crypto_unregister_template(&tmpls[i]);
532 : return err;
533 : }
534 : EXPORT_SYMBOL_GPL(crypto_register_templates);
535 :
536 0 : void crypto_unregister_template(struct crypto_template *tmpl)
537 : {
538 0 : struct crypto_instance *inst;
539 0 : struct hlist_node *n;
540 0 : struct hlist_head *list;
541 0 : LIST_HEAD(users);
542 :
543 0 : down_write(&crypto_alg_sem);
544 :
545 0 : BUG_ON(list_empty(&tmpl->list));
546 0 : list_del_init(&tmpl->list);
547 :
548 0 : list = &tmpl->instances;
549 0 : hlist_for_each_entry(inst, list, list) {
550 0 : int err = crypto_remove_alg(&inst->alg, &users);
551 :
552 0 : BUG_ON(err);
553 : }
554 :
555 0 : up_write(&crypto_alg_sem);
556 :
557 0 : hlist_for_each_entry_safe(inst, n, list, list) {
558 0 : BUG_ON(refcount_read(&inst->alg.cra_refcnt) != 1);
559 0 : crypto_free_instance(inst);
560 : }
561 0 : crypto_remove_final(&users);
562 0 : }
563 : EXPORT_SYMBOL_GPL(crypto_unregister_template);
564 :
565 0 : void crypto_unregister_templates(struct crypto_template *tmpls, int count)
566 : {
567 0 : int i;
568 :
569 0 : for (i = count - 1; i >= 0; --i)
570 0 : crypto_unregister_template(&tmpls[i]);
571 0 : }
572 : EXPORT_SYMBOL_GPL(crypto_unregister_templates);
573 :
574 0 : static struct crypto_template *__crypto_lookup_template(const char *name)
575 : {
576 0 : struct crypto_template *q, *tmpl = NULL;
577 :
578 0 : down_read(&crypto_alg_sem);
579 0 : list_for_each_entry(q, &crypto_template_list, list) {
580 0 : if (strcmp(q->name, name))
581 0 : continue;
582 0 : if (unlikely(!crypto_tmpl_get(q)))
583 : continue;
584 :
585 : tmpl = q;
586 : break;
587 : }
588 0 : up_read(&crypto_alg_sem);
589 :
590 0 : return tmpl;
591 : }
592 :
593 0 : struct crypto_template *crypto_lookup_template(const char *name)
594 : {
595 0 : return try_then_request_module(__crypto_lookup_template(name),
596 : "crypto-%s", name);
597 : }
598 : EXPORT_SYMBOL_GPL(crypto_lookup_template);
599 :
600 0 : int crypto_register_instance(struct crypto_template *tmpl,
601 : struct crypto_instance *inst)
602 : {
603 0 : struct crypto_larval *larval;
604 0 : struct crypto_spawn *spawn;
605 0 : int err;
606 :
607 0 : err = crypto_check_alg(&inst->alg);
608 0 : if (err)
609 : return err;
610 :
611 0 : inst->alg.cra_module = tmpl->module;
612 0 : inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
613 :
614 0 : down_write(&crypto_alg_sem);
615 :
616 0 : larval = ERR_PTR(-EAGAIN);
617 0 : for (spawn = inst->spawns; spawn;) {
618 0 : struct crypto_spawn *next;
619 :
620 0 : if (spawn->dead)
621 0 : goto unlock;
622 :
623 0 : next = spawn->next;
624 0 : spawn->inst = inst;
625 0 : spawn->registered = true;
626 :
627 0 : crypto_mod_put(spawn->alg);
628 :
629 0 : spawn = next;
630 : }
631 :
632 0 : larval = __crypto_register_alg(&inst->alg);
633 0 : if (IS_ERR(larval))
634 0 : goto unlock;
635 :
636 0 : hlist_add_head(&inst->list, &tmpl->instances);
637 0 : inst->tmpl = tmpl;
638 :
639 0 : unlock:
640 0 : up_write(&crypto_alg_sem);
641 :
642 0 : err = PTR_ERR(larval);
643 0 : if (IS_ERR(larval))
644 0 : goto err;
645 :
646 0 : crypto_wait_for_test(larval);
647 0 : err = 0;
648 :
649 : err:
650 : return err;
651 : }
652 : EXPORT_SYMBOL_GPL(crypto_register_instance);
653 :
654 0 : void crypto_unregister_instance(struct crypto_instance *inst)
655 : {
656 0 : LIST_HEAD(list);
657 :
658 0 : down_write(&crypto_alg_sem);
659 :
660 0 : crypto_remove_spawns(&inst->alg, &list, NULL);
661 0 : crypto_remove_instance(inst, &list);
662 :
663 0 : up_write(&crypto_alg_sem);
664 :
665 0 : crypto_remove_final(&list);
666 0 : }
667 : EXPORT_SYMBOL_GPL(crypto_unregister_instance);
668 :
669 0 : int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
670 : const char *name, u32 type, u32 mask)
671 : {
672 0 : struct crypto_alg *alg;
673 0 : int err = -EAGAIN;
674 :
675 0 : if (WARN_ON_ONCE(inst == NULL))
676 : return -EINVAL;
677 :
678 : /* Allow the result of crypto_attr_alg_name() to be passed directly */
679 0 : if (IS_ERR(name))
680 0 : return PTR_ERR(name);
681 :
682 0 : alg = crypto_find_alg(name, spawn->frontend, type, mask);
683 0 : if (IS_ERR(alg))
684 0 : return PTR_ERR(alg);
685 :
686 0 : down_write(&crypto_alg_sem);
687 0 : if (!crypto_is_moribund(alg)) {
688 0 : list_add(&spawn->list, &alg->cra_users);
689 0 : spawn->alg = alg;
690 0 : spawn->mask = mask;
691 0 : spawn->next = inst->spawns;
692 0 : inst->spawns = spawn;
693 0 : inst->alg.cra_flags |=
694 0 : (alg->cra_flags & CRYPTO_ALG_INHERITED_FLAGS);
695 0 : err = 0;
696 : }
697 0 : up_write(&crypto_alg_sem);
698 0 : if (err)
699 0 : crypto_mod_put(alg);
700 : return err;
701 : }
702 : EXPORT_SYMBOL_GPL(crypto_grab_spawn);
703 :
704 0 : void crypto_drop_spawn(struct crypto_spawn *spawn)
705 : {
706 0 : if (!spawn->alg) /* not yet initialized? */
707 : return;
708 :
709 0 : down_write(&crypto_alg_sem);
710 0 : if (!spawn->dead)
711 0 : list_del(&spawn->list);
712 0 : up_write(&crypto_alg_sem);
713 :
714 0 : if (!spawn->registered)
715 0 : crypto_mod_put(spawn->alg);
716 : }
717 : EXPORT_SYMBOL_GPL(crypto_drop_spawn);
718 :
719 0 : static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
720 : {
721 0 : struct crypto_alg *alg = ERR_PTR(-EAGAIN);
722 0 : struct crypto_alg *target;
723 0 : bool shoot = false;
724 :
725 0 : down_read(&crypto_alg_sem);
726 0 : if (!spawn->dead) {
727 0 : alg = spawn->alg;
728 0 : if (!crypto_mod_get(alg)) {
729 0 : target = crypto_alg_get(alg);
730 0 : shoot = true;
731 0 : alg = ERR_PTR(-EAGAIN);
732 : }
733 : }
734 0 : up_read(&crypto_alg_sem);
735 :
736 0 : if (shoot) {
737 0 : crypto_shoot_alg(target);
738 0 : crypto_alg_put(target);
739 : }
740 :
741 0 : return alg;
742 : }
743 :
744 0 : struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
745 : u32 mask)
746 : {
747 0 : struct crypto_alg *alg;
748 0 : struct crypto_tfm *tfm;
749 :
750 0 : alg = crypto_spawn_alg(spawn);
751 0 : if (IS_ERR(alg))
752 0 : return ERR_CAST(alg);
753 :
754 0 : tfm = ERR_PTR(-EINVAL);
755 0 : if (unlikely((alg->cra_flags ^ type) & mask))
756 0 : goto out_put_alg;
757 :
758 0 : tfm = __crypto_alloc_tfm(alg, type, mask);
759 0 : if (IS_ERR(tfm))
760 0 : goto out_put_alg;
761 :
762 : return tfm;
763 :
764 0 : out_put_alg:
765 0 : crypto_mod_put(alg);
766 0 : return tfm;
767 : }
768 : EXPORT_SYMBOL_GPL(crypto_spawn_tfm);
769 :
770 0 : void *crypto_spawn_tfm2(struct crypto_spawn *spawn)
771 : {
772 0 : struct crypto_alg *alg;
773 0 : struct crypto_tfm *tfm;
774 :
775 0 : alg = crypto_spawn_alg(spawn);
776 0 : if (IS_ERR(alg))
777 0 : return ERR_CAST(alg);
778 :
779 0 : tfm = crypto_create_tfm(alg, spawn->frontend);
780 0 : if (IS_ERR(tfm))
781 0 : goto out_put_alg;
782 :
783 : return tfm;
784 :
785 0 : out_put_alg:
786 0 : crypto_mod_put(alg);
787 0 : return tfm;
788 : }
789 : EXPORT_SYMBOL_GPL(crypto_spawn_tfm2);
790 :
791 0 : int crypto_register_notifier(struct notifier_block *nb)
792 : {
793 0 : return blocking_notifier_chain_register(&crypto_chain, nb);
794 : }
795 : EXPORT_SYMBOL_GPL(crypto_register_notifier);
796 :
797 0 : int crypto_unregister_notifier(struct notifier_block *nb)
798 : {
799 0 : return blocking_notifier_chain_unregister(&crypto_chain, nb);
800 : }
801 : EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
802 :
803 0 : struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
804 : {
805 0 : struct rtattr *rta = tb[0];
806 0 : struct crypto_attr_type *algt;
807 :
808 0 : if (!rta)
809 0 : return ERR_PTR(-ENOENT);
810 0 : if (RTA_PAYLOAD(rta) < sizeof(*algt))
811 0 : return ERR_PTR(-EINVAL);
812 0 : if (rta->rta_type != CRYPTOA_TYPE)
813 0 : return ERR_PTR(-EINVAL);
814 :
815 0 : algt = RTA_DATA(rta);
816 :
817 0 : return algt;
818 : }
819 : EXPORT_SYMBOL_GPL(crypto_get_attr_type);
820 :
821 : /**
822 : * crypto_check_attr_type() - check algorithm type and compute inherited mask
823 : * @tb: the template parameters
824 : * @type: the algorithm type the template would be instantiated as
825 : * @mask_ret: (output) the mask that should be passed to crypto_grab_*()
826 : * to restrict the flags of any inner algorithms
827 : *
828 : * Validate that the algorithm type the user requested is compatible with the
829 : * one the template would actually be instantiated as. E.g., if the user is
830 : * doing crypto_alloc_shash("cbc(aes)", ...), this would return an error because
831 : * the "cbc" template creates an "skcipher" algorithm, not an "shash" algorithm.
832 : *
833 : * Also compute the mask to use to restrict the flags of any inner algorithms.
834 : *
835 : * Return: 0 on success; -errno on failure
836 : */
837 0 : int crypto_check_attr_type(struct rtattr **tb, u32 type, u32 *mask_ret)
838 : {
839 0 : struct crypto_attr_type *algt;
840 :
841 0 : algt = crypto_get_attr_type(tb);
842 0 : if (IS_ERR(algt))
843 0 : return PTR_ERR(algt);
844 :
845 0 : if ((algt->type ^ type) & algt->mask)
846 : return -EINVAL;
847 :
848 0 : *mask_ret = crypto_algt_inherited_mask(algt);
849 0 : return 0;
850 : }
851 : EXPORT_SYMBOL_GPL(crypto_check_attr_type);
852 :
853 0 : const char *crypto_attr_alg_name(struct rtattr *rta)
854 : {
855 0 : struct crypto_attr_alg *alga;
856 :
857 0 : if (!rta)
858 0 : return ERR_PTR(-ENOENT);
859 0 : if (RTA_PAYLOAD(rta) < sizeof(*alga))
860 0 : return ERR_PTR(-EINVAL);
861 0 : if (rta->rta_type != CRYPTOA_ALG)
862 0 : return ERR_PTR(-EINVAL);
863 :
864 0 : alga = RTA_DATA(rta);
865 0 : alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
866 :
867 0 : return alga->name;
868 : }
869 : EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
870 :
871 0 : int crypto_attr_u32(struct rtattr *rta, u32 *num)
872 : {
873 0 : struct crypto_attr_u32 *nu32;
874 :
875 0 : if (!rta)
876 : return -ENOENT;
877 0 : if (RTA_PAYLOAD(rta) < sizeof(*nu32))
878 : return -EINVAL;
879 0 : if (rta->rta_type != CRYPTOA_U32)
880 : return -EINVAL;
881 :
882 0 : nu32 = RTA_DATA(rta);
883 0 : *num = nu32->num;
884 :
885 0 : return 0;
886 : }
887 : EXPORT_SYMBOL_GPL(crypto_attr_u32);
888 :
889 0 : int crypto_inst_setname(struct crypto_instance *inst, const char *name,
890 : struct crypto_alg *alg)
891 : {
892 0 : if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name,
893 0 : alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
894 : return -ENAMETOOLONG;
895 :
896 0 : if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
897 0 : name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
898 0 : return -ENAMETOOLONG;
899 :
900 : return 0;
901 : }
902 : EXPORT_SYMBOL_GPL(crypto_inst_setname);
903 :
904 0 : void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen)
905 : {
906 0 : INIT_LIST_HEAD(&queue->list);
907 0 : queue->backlog = &queue->list;
908 0 : queue->qlen = 0;
909 0 : queue->max_qlen = max_qlen;
910 0 : }
911 : EXPORT_SYMBOL_GPL(crypto_init_queue);
912 :
913 0 : int crypto_enqueue_request(struct crypto_queue *queue,
914 : struct crypto_async_request *request)
915 : {
916 0 : int err = -EINPROGRESS;
917 :
918 0 : if (unlikely(queue->qlen >= queue->max_qlen)) {
919 0 : if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
920 0 : err = -ENOSPC;
921 0 : goto out;
922 : }
923 0 : err = -EBUSY;
924 0 : if (queue->backlog == &queue->list)
925 0 : queue->backlog = &request->list;
926 : }
927 :
928 0 : queue->qlen++;
929 0 : list_add_tail(&request->list, &queue->list);
930 :
931 0 : out:
932 0 : return err;
933 : }
934 : EXPORT_SYMBOL_GPL(crypto_enqueue_request);
935 :
936 0 : void crypto_enqueue_request_head(struct crypto_queue *queue,
937 : struct crypto_async_request *request)
938 : {
939 0 : queue->qlen++;
940 0 : list_add(&request->list, &queue->list);
941 0 : }
942 : EXPORT_SYMBOL_GPL(crypto_enqueue_request_head);
943 :
944 0 : struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
945 : {
946 0 : struct list_head *request;
947 :
948 0 : if (unlikely(!queue->qlen))
949 : return NULL;
950 :
951 0 : queue->qlen--;
952 :
953 0 : if (queue->backlog != &queue->list)
954 0 : queue->backlog = queue->backlog->next;
955 :
956 0 : request = queue->list.next;
957 0 : list_del(request);
958 :
959 0 : return list_entry(request, struct crypto_async_request, list);
960 : }
961 : EXPORT_SYMBOL_GPL(crypto_dequeue_request);
962 :
963 0 : static inline void crypto_inc_byte(u8 *a, unsigned int size)
964 : {
965 0 : u8 *b = (a + size);
966 0 : u8 c;
967 :
968 0 : for (; size; size--) {
969 0 : c = *--b + 1;
970 0 : *b = c;
971 0 : if (c)
972 : break;
973 : }
974 0 : }
975 :
976 0 : void crypto_inc(u8 *a, unsigned int size)
977 : {
978 0 : __be32 *b = (__be32 *)(a + size);
979 0 : u32 c;
980 :
981 0 : if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
982 : IS_ALIGNED((unsigned long)b, __alignof__(*b)))
983 0 : for (; size >= 4; size -= 4) {
984 0 : c = be32_to_cpu(*--b) + 1;
985 0 : *b = cpu_to_be32(c);
986 0 : if (likely(c))
987 : return;
988 : }
989 :
990 0 : crypto_inc_byte(a, size);
991 : }
992 : EXPORT_SYMBOL_GPL(crypto_inc);
993 :
994 0 : void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
995 : {
996 0 : int relalign = 0;
997 :
998 0 : if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
999 : int size = sizeof(unsigned long);
1000 : int d = (((unsigned long)dst ^ (unsigned long)src1) |
1001 : ((unsigned long)dst ^ (unsigned long)src2)) &
1002 : (size - 1);
1003 :
1004 : relalign = d ? 1 << __ffs(d) : size;
1005 :
1006 : /*
1007 : * If we care about alignment, process as many bytes as
1008 : * needed to advance dst and src to values whose alignments
1009 : * equal their relative alignment. This will allow us to
1010 : * process the remainder of the input using optimal strides.
1011 : */
1012 : while (((unsigned long)dst & (relalign - 1)) && len > 0) {
1013 : *dst++ = *src1++ ^ *src2++;
1014 : len--;
1015 : }
1016 : }
1017 :
1018 0 : while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
1019 0 : *(u64 *)dst = *(u64 *)src1 ^ *(u64 *)src2;
1020 0 : dst += 8;
1021 0 : src1 += 8;
1022 0 : src2 += 8;
1023 0 : len -= 8;
1024 : }
1025 :
1026 0 : while (len >= 4 && !(relalign & 3)) {
1027 0 : *(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
1028 0 : dst += 4;
1029 0 : src1 += 4;
1030 0 : src2 += 4;
1031 0 : len -= 4;
1032 : }
1033 :
1034 0 : while (len >= 2 && !(relalign & 1)) {
1035 0 : *(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
1036 0 : dst += 2;
1037 0 : src1 += 2;
1038 0 : src2 += 2;
1039 0 : len -= 2;
1040 : }
1041 :
1042 0 : while (len--)
1043 0 : *dst++ = *src1++ ^ *src2++;
1044 0 : }
1045 : EXPORT_SYMBOL_GPL(__crypto_xor);
1046 :
1047 2 : unsigned int crypto_alg_extsize(struct crypto_alg *alg)
1048 : {
1049 2 : return alg->cra_ctxsize +
1050 2 : (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
1051 : }
1052 : EXPORT_SYMBOL_GPL(crypto_alg_extsize);
1053 :
1054 0 : int crypto_type_has_alg(const char *name, const struct crypto_type *frontend,
1055 : u32 type, u32 mask)
1056 : {
1057 0 : int ret = 0;
1058 0 : struct crypto_alg *alg = crypto_find_alg(name, frontend, type, mask);
1059 :
1060 0 : if (!IS_ERR(alg)) {
1061 0 : crypto_mod_put(alg);
1062 0 : ret = 1;
1063 : }
1064 :
1065 0 : return ret;
1066 : }
1067 : EXPORT_SYMBOL_GPL(crypto_type_has_alg);
1068 :
1069 : #ifdef CONFIG_CRYPTO_STATS
1070 : void crypto_stats_init(struct crypto_alg *alg)
1071 : {
1072 : memset(&alg->stats, 0, sizeof(alg->stats));
1073 : }
1074 : EXPORT_SYMBOL_GPL(crypto_stats_init);
1075 :
1076 : void crypto_stats_get(struct crypto_alg *alg)
1077 : {
1078 : crypto_alg_get(alg);
1079 : }
1080 : EXPORT_SYMBOL_GPL(crypto_stats_get);
1081 :
1082 : void crypto_stats_aead_encrypt(unsigned int cryptlen, struct crypto_alg *alg,
1083 : int ret)
1084 : {
1085 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1086 : atomic64_inc(&alg->stats.aead.err_cnt);
1087 : } else {
1088 : atomic64_inc(&alg->stats.aead.encrypt_cnt);
1089 : atomic64_add(cryptlen, &alg->stats.aead.encrypt_tlen);
1090 : }
1091 : crypto_alg_put(alg);
1092 : }
1093 : EXPORT_SYMBOL_GPL(crypto_stats_aead_encrypt);
1094 :
1095 : void crypto_stats_aead_decrypt(unsigned int cryptlen, struct crypto_alg *alg,
1096 : int ret)
1097 : {
1098 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1099 : atomic64_inc(&alg->stats.aead.err_cnt);
1100 : } else {
1101 : atomic64_inc(&alg->stats.aead.decrypt_cnt);
1102 : atomic64_add(cryptlen, &alg->stats.aead.decrypt_tlen);
1103 : }
1104 : crypto_alg_put(alg);
1105 : }
1106 : EXPORT_SYMBOL_GPL(crypto_stats_aead_decrypt);
1107 :
1108 : void crypto_stats_akcipher_encrypt(unsigned int src_len, int ret,
1109 : struct crypto_alg *alg)
1110 : {
1111 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1112 : atomic64_inc(&alg->stats.akcipher.err_cnt);
1113 : } else {
1114 : atomic64_inc(&alg->stats.akcipher.encrypt_cnt);
1115 : atomic64_add(src_len, &alg->stats.akcipher.encrypt_tlen);
1116 : }
1117 : crypto_alg_put(alg);
1118 : }
1119 : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_encrypt);
1120 :
1121 : void crypto_stats_akcipher_decrypt(unsigned int src_len, int ret,
1122 : struct crypto_alg *alg)
1123 : {
1124 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1125 : atomic64_inc(&alg->stats.akcipher.err_cnt);
1126 : } else {
1127 : atomic64_inc(&alg->stats.akcipher.decrypt_cnt);
1128 : atomic64_add(src_len, &alg->stats.akcipher.decrypt_tlen);
1129 : }
1130 : crypto_alg_put(alg);
1131 : }
1132 : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_decrypt);
1133 :
1134 : void crypto_stats_akcipher_sign(int ret, struct crypto_alg *alg)
1135 : {
1136 : if (ret && ret != -EINPROGRESS && ret != -EBUSY)
1137 : atomic64_inc(&alg->stats.akcipher.err_cnt);
1138 : else
1139 : atomic64_inc(&alg->stats.akcipher.sign_cnt);
1140 : crypto_alg_put(alg);
1141 : }
1142 : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_sign);
1143 :
1144 : void crypto_stats_akcipher_verify(int ret, struct crypto_alg *alg)
1145 : {
1146 : if (ret && ret != -EINPROGRESS && ret != -EBUSY)
1147 : atomic64_inc(&alg->stats.akcipher.err_cnt);
1148 : else
1149 : atomic64_inc(&alg->stats.akcipher.verify_cnt);
1150 : crypto_alg_put(alg);
1151 : }
1152 : EXPORT_SYMBOL_GPL(crypto_stats_akcipher_verify);
1153 :
1154 : void crypto_stats_compress(unsigned int slen, int ret, struct crypto_alg *alg)
1155 : {
1156 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1157 : atomic64_inc(&alg->stats.compress.err_cnt);
1158 : } else {
1159 : atomic64_inc(&alg->stats.compress.compress_cnt);
1160 : atomic64_add(slen, &alg->stats.compress.compress_tlen);
1161 : }
1162 : crypto_alg_put(alg);
1163 : }
1164 : EXPORT_SYMBOL_GPL(crypto_stats_compress);
1165 :
1166 : void crypto_stats_decompress(unsigned int slen, int ret, struct crypto_alg *alg)
1167 : {
1168 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1169 : atomic64_inc(&alg->stats.compress.err_cnt);
1170 : } else {
1171 : atomic64_inc(&alg->stats.compress.decompress_cnt);
1172 : atomic64_add(slen, &alg->stats.compress.decompress_tlen);
1173 : }
1174 : crypto_alg_put(alg);
1175 : }
1176 : EXPORT_SYMBOL_GPL(crypto_stats_decompress);
1177 :
1178 : void crypto_stats_ahash_update(unsigned int nbytes, int ret,
1179 : struct crypto_alg *alg)
1180 : {
1181 : if (ret && ret != -EINPROGRESS && ret != -EBUSY)
1182 : atomic64_inc(&alg->stats.hash.err_cnt);
1183 : else
1184 : atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
1185 : crypto_alg_put(alg);
1186 : }
1187 : EXPORT_SYMBOL_GPL(crypto_stats_ahash_update);
1188 :
1189 : void crypto_stats_ahash_final(unsigned int nbytes, int ret,
1190 : struct crypto_alg *alg)
1191 : {
1192 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1193 : atomic64_inc(&alg->stats.hash.err_cnt);
1194 : } else {
1195 : atomic64_inc(&alg->stats.hash.hash_cnt);
1196 : atomic64_add(nbytes, &alg->stats.hash.hash_tlen);
1197 : }
1198 : crypto_alg_put(alg);
1199 : }
1200 : EXPORT_SYMBOL_GPL(crypto_stats_ahash_final);
1201 :
1202 : void crypto_stats_kpp_set_secret(struct crypto_alg *alg, int ret)
1203 : {
1204 : if (ret)
1205 : atomic64_inc(&alg->stats.kpp.err_cnt);
1206 : else
1207 : atomic64_inc(&alg->stats.kpp.setsecret_cnt);
1208 : crypto_alg_put(alg);
1209 : }
1210 : EXPORT_SYMBOL_GPL(crypto_stats_kpp_set_secret);
1211 :
1212 : void crypto_stats_kpp_generate_public_key(struct crypto_alg *alg, int ret)
1213 : {
1214 : if (ret)
1215 : atomic64_inc(&alg->stats.kpp.err_cnt);
1216 : else
1217 : atomic64_inc(&alg->stats.kpp.generate_public_key_cnt);
1218 : crypto_alg_put(alg);
1219 : }
1220 : EXPORT_SYMBOL_GPL(crypto_stats_kpp_generate_public_key);
1221 :
1222 : void crypto_stats_kpp_compute_shared_secret(struct crypto_alg *alg, int ret)
1223 : {
1224 : if (ret)
1225 : atomic64_inc(&alg->stats.kpp.err_cnt);
1226 : else
1227 : atomic64_inc(&alg->stats.kpp.compute_shared_secret_cnt);
1228 : crypto_alg_put(alg);
1229 : }
1230 : EXPORT_SYMBOL_GPL(crypto_stats_kpp_compute_shared_secret);
1231 :
1232 : void crypto_stats_rng_seed(struct crypto_alg *alg, int ret)
1233 : {
1234 : if (ret && ret != -EINPROGRESS && ret != -EBUSY)
1235 : atomic64_inc(&alg->stats.rng.err_cnt);
1236 : else
1237 : atomic64_inc(&alg->stats.rng.seed_cnt);
1238 : crypto_alg_put(alg);
1239 : }
1240 : EXPORT_SYMBOL_GPL(crypto_stats_rng_seed);
1241 :
1242 : void crypto_stats_rng_generate(struct crypto_alg *alg, unsigned int dlen,
1243 : int ret)
1244 : {
1245 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1246 : atomic64_inc(&alg->stats.rng.err_cnt);
1247 : } else {
1248 : atomic64_inc(&alg->stats.rng.generate_cnt);
1249 : atomic64_add(dlen, &alg->stats.rng.generate_tlen);
1250 : }
1251 : crypto_alg_put(alg);
1252 : }
1253 : EXPORT_SYMBOL_GPL(crypto_stats_rng_generate);
1254 :
1255 : void crypto_stats_skcipher_encrypt(unsigned int cryptlen, int ret,
1256 : struct crypto_alg *alg)
1257 : {
1258 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1259 : atomic64_inc(&alg->stats.cipher.err_cnt);
1260 : } else {
1261 : atomic64_inc(&alg->stats.cipher.encrypt_cnt);
1262 : atomic64_add(cryptlen, &alg->stats.cipher.encrypt_tlen);
1263 : }
1264 : crypto_alg_put(alg);
1265 : }
1266 : EXPORT_SYMBOL_GPL(crypto_stats_skcipher_encrypt);
1267 :
1268 : void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret,
1269 : struct crypto_alg *alg)
1270 : {
1271 : if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
1272 : atomic64_inc(&alg->stats.cipher.err_cnt);
1273 : } else {
1274 : atomic64_inc(&alg->stats.cipher.decrypt_cnt);
1275 : atomic64_add(cryptlen, &alg->stats.cipher.decrypt_tlen);
1276 : }
1277 : crypto_alg_put(alg);
1278 : }
1279 : EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt);
1280 : #endif
1281 :
1282 1 : static int __init crypto_algapi_init(void)
1283 : {
1284 1 : crypto_init_proc();
1285 1 : return 0;
1286 : }
1287 :
1288 0 : static void __exit crypto_algapi_exit(void)
1289 : {
1290 0 : crypto_exit_proc();
1291 0 : }
1292 :
1293 : module_init(crypto_algapi_init);
1294 : module_exit(crypto_algapi_exit);
1295 :
1296 : MODULE_LICENSE("GPL");
1297 : MODULE_DESCRIPTION("Cryptographic algorithms API");
|