]> git.karo-electronics.de Git - karo-tx-linux.git/blob - crypto/algapi.c
Merge remote-tracking branch 'fscache/fscache'
[karo-tx-linux.git] / crypto / algapi.c
1 /*
2  * Cryptographic API for algorithms (i.e., low-level API).
3  *
4  * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  *
11  */
12
13 #include <linux/err.h>
14 #include <linux/errno.h>
15 #include <linux/fips.h>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/list.h>
19 #include <linux/module.h>
20 #include <linux/rtnetlink.h>
21 #include <linux/slab.h>
22 #include <linux/string.h>
23
24 #include "internal.h"
25
26 static LIST_HEAD(crypto_template_list);
27
28 static inline int crypto_set_driver_name(struct crypto_alg *alg)
29 {
30         static const char suffix[] = "-generic";
31         char *driver_name = alg->cra_driver_name;
32         int len;
33
34         if (*driver_name)
35                 return 0;
36
37         len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
38         if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
39                 return -ENAMETOOLONG;
40
41         memcpy(driver_name + len, suffix, sizeof(suffix));
42         return 0;
43 }
44
45 static inline void crypto_check_module_sig(struct module *mod)
46 {
47         if (fips_enabled && mod && !module_sig_ok(mod))
48                 panic("Module %s signature verification failed in FIPS mode\n",
49                       module_name(mod));
50 }
51
52 static int crypto_check_alg(struct crypto_alg *alg)
53 {
54         crypto_check_module_sig(alg->cra_module);
55
56         if (alg->cra_alignmask & (alg->cra_alignmask + 1))
57                 return -EINVAL;
58
59         if (alg->cra_blocksize > PAGE_SIZE / 8)
60                 return -EINVAL;
61
62         if (alg->cra_priority < 0)
63                 return -EINVAL;
64
65         atomic_set(&alg->cra_refcnt, 1);
66
67         return crypto_set_driver_name(alg);
68 }
69
70 static void crypto_free_instance(struct crypto_instance *inst)
71 {
72         if (!inst->alg.cra_type->free) {
73                 inst->tmpl->free(inst);
74                 return;
75         }
76
77         inst->alg.cra_type->free(inst);
78 }
79
80 static void crypto_destroy_instance(struct crypto_alg *alg)
81 {
82         struct crypto_instance *inst = (void *)alg;
83         struct crypto_template *tmpl = inst->tmpl;
84
85         crypto_free_instance(inst);
86         crypto_tmpl_put(tmpl);
87 }
88
89 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         struct crypto_spawn *spawn, *n;
95
96         spawn = list_first_entry_or_null(stack, struct crypto_spawn, list);
97         if (!spawn)
98                 return NULL;
99
100         n = list_next_entry(spawn, list);
101
102         if (spawn->alg && &n->list != stack && !n->alg)
103                 n->alg = (n->list.next == stack) ? alg :
104                          &list_next_entry(n, list)->inst->alg;
105
106         list_move(&spawn->list, secondary_spawns);
107
108         return &n->list == stack ? top : &n->inst->alg.cra_users;
109 }
110
111 static void crypto_remove_instance(struct crypto_instance *inst,
112                                    struct list_head *list)
113 {
114         struct crypto_template *tmpl = inst->tmpl;
115
116         if (crypto_is_dead(&inst->alg))
117                 return;
118
119         inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
120         if (hlist_unhashed(&inst->list))
121                 return;
122
123         if (!tmpl || !crypto_tmpl_get(tmpl))
124                 return;
125
126         crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg);
127         list_move(&inst->alg.cra_list, list);
128         hlist_del(&inst->list);
129         inst->alg.cra_destroy = crypto_destroy_instance;
130
131         BUG_ON(!list_empty(&inst->alg.cra_users));
132 }
133
134 void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
135                           struct crypto_alg *nalg)
136 {
137         u32 new_type = (nalg ?: alg)->cra_flags;
138         struct crypto_spawn *spawn, *n;
139         LIST_HEAD(secondary_spawns);
140         struct list_head *spawns;
141         LIST_HEAD(stack);
142         LIST_HEAD(top);
143
144         spawns = &alg->cra_users;
145         list_for_each_entry_safe(spawn, n, spawns, list) {
146                 if ((spawn->alg->cra_flags ^ new_type) & spawn->mask)
147                         continue;
148
149                 list_move(&spawn->list, &top);
150         }
151
152         spawns = &top;
153         do {
154                 while (!list_empty(spawns)) {
155                         struct crypto_instance *inst;
156
157                         spawn = list_first_entry(spawns, struct crypto_spawn,
158                                                  list);
159                         inst = spawn->inst;
160
161                         BUG_ON(&inst->alg == alg);
162
163                         list_move(&spawn->list, &stack);
164
165                         if (&inst->alg == nalg)
166                                 break;
167
168                         spawn->alg = NULL;
169                         spawns = &inst->alg.cra_users;
170                 }
171         } while ((spawns = crypto_more_spawns(alg, &stack, &top,
172                                               &secondary_spawns)));
173
174         list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
175                 if (spawn->alg)
176                         list_move(&spawn->list, &spawn->alg->cra_users);
177                 else
178                         crypto_remove_instance(spawn->inst, list);
179         }
180 }
181 EXPORT_SYMBOL_GPL(crypto_remove_spawns);
182
183 static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
184 {
185         struct crypto_alg *q;
186         struct crypto_larval *larval;
187         int ret = -EAGAIN;
188
189         if (crypto_is_dead(alg))
190                 goto err;
191
192         INIT_LIST_HEAD(&alg->cra_users);
193
194         /* No cheating! */
195         alg->cra_flags &= ~CRYPTO_ALG_TESTED;
196
197         ret = -EEXIST;
198
199         list_for_each_entry(q, &crypto_alg_list, cra_list) {
200                 if (q == alg)
201                         goto err;
202
203                 if (crypto_is_moribund(q))
204                         continue;
205
206                 if (crypto_is_larval(q)) {
207                         if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
208                                 goto err;
209                         continue;
210                 }
211
212                 if (!strcmp(q->cra_driver_name, alg->cra_name) ||
213                     !strcmp(q->cra_name, alg->cra_driver_name))
214                         goto err;
215         }
216
217         larval = crypto_larval_alloc(alg->cra_name,
218                                      alg->cra_flags | CRYPTO_ALG_TESTED, 0);
219         if (IS_ERR(larval))
220                 goto out;
221
222         ret = -ENOENT;
223         larval->adult = crypto_mod_get(alg);
224         if (!larval->adult)
225                 goto free_larval;
226
227         atomic_set(&larval->alg.cra_refcnt, 1);
228         memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
229                CRYPTO_MAX_ALG_NAME);
230         larval->alg.cra_priority = alg->cra_priority;
231
232         list_add(&alg->cra_list, &crypto_alg_list);
233         list_add(&larval->alg.cra_list, &crypto_alg_list);
234
235 out:
236         return larval;
237
238 free_larval:
239         kfree(larval);
240 err:
241         larval = ERR_PTR(ret);
242         goto out;
243 }
244
245 void crypto_alg_tested(const char *name, int err)
246 {
247         struct crypto_larval *test;
248         struct crypto_alg *alg;
249         struct crypto_alg *q;
250         LIST_HEAD(list);
251
252         down_write(&crypto_alg_sem);
253         list_for_each_entry(q, &crypto_alg_list, cra_list) {
254                 if (crypto_is_moribund(q) || !crypto_is_larval(q))
255                         continue;
256
257                 test = (struct crypto_larval *)q;
258
259                 if (!strcmp(q->cra_driver_name, name))
260                         goto found;
261         }
262
263         printk(KERN_ERR "alg: Unexpected test result for %s: %d\n", name, err);
264         goto unlock;
265
266 found:
267         q->cra_flags |= CRYPTO_ALG_DEAD;
268         alg = test->adult;
269         if (err || list_empty(&alg->cra_list))
270                 goto complete;
271
272         alg->cra_flags |= CRYPTO_ALG_TESTED;
273
274         list_for_each_entry(q, &crypto_alg_list, cra_list) {
275                 if (q == alg)
276                         continue;
277
278                 if (crypto_is_moribund(q))
279                         continue;
280
281                 if (crypto_is_larval(q)) {
282                         struct crypto_larval *larval = (void *)q;
283
284                         /*
285                          * Check to see if either our generic name or
286                          * specific name can satisfy the name requested
287                          * by the larval entry q.
288                          */
289                         if (strcmp(alg->cra_name, q->cra_name) &&
290                             strcmp(alg->cra_driver_name, q->cra_name))
291                                 continue;
292
293                         if (larval->adult)
294                                 continue;
295                         if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
296                                 continue;
297                         if (!crypto_mod_get(alg))
298                                 continue;
299
300                         larval->adult = alg;
301                         continue;
302                 }
303
304                 if (strcmp(alg->cra_name, q->cra_name))
305                         continue;
306
307                 if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
308                     q->cra_priority > alg->cra_priority)
309                         continue;
310
311                 crypto_remove_spawns(q, &list, alg);
312         }
313
314 complete:
315         complete_all(&test->completion);
316
317 unlock:
318         up_write(&crypto_alg_sem);
319
320         crypto_remove_final(&list);
321 }
322 EXPORT_SYMBOL_GPL(crypto_alg_tested);
323
324 void crypto_remove_final(struct list_head *list)
325 {
326         struct crypto_alg *alg;
327         struct crypto_alg *n;
328
329         list_for_each_entry_safe(alg, n, list, cra_list) {
330                 list_del_init(&alg->cra_list);
331                 crypto_alg_put(alg);
332         }
333 }
334 EXPORT_SYMBOL_GPL(crypto_remove_final);
335
336 static void crypto_wait_for_test(struct crypto_larval *larval)
337 {
338         int err;
339
340         err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
341         if (err != NOTIFY_STOP) {
342                 if (WARN_ON(err != NOTIFY_DONE))
343                         goto out;
344                 crypto_alg_tested(larval->alg.cra_driver_name, 0);
345         }
346
347         err = wait_for_completion_killable(&larval->completion);
348         WARN_ON(err);
349
350 out:
351         crypto_larval_kill(&larval->alg);
352 }
353
354 int crypto_register_alg(struct crypto_alg *alg)
355 {
356         struct crypto_larval *larval;
357         int err;
358
359         err = crypto_check_alg(alg);
360         if (err)
361                 return err;
362
363         down_write(&crypto_alg_sem);
364         larval = __crypto_register_alg(alg);
365         up_write(&crypto_alg_sem);
366
367         if (IS_ERR(larval))
368                 return PTR_ERR(larval);
369
370         crypto_wait_for_test(larval);
371         return 0;
372 }
373 EXPORT_SYMBOL_GPL(crypto_register_alg);
374
375 static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)
376 {
377         if (unlikely(list_empty(&alg->cra_list)))
378                 return -ENOENT;
379
380         alg->cra_flags |= CRYPTO_ALG_DEAD;
381
382         crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg);
383         list_del_init(&alg->cra_list);
384         crypto_remove_spawns(alg, list, NULL);
385
386         return 0;
387 }
388
389 int crypto_unregister_alg(struct crypto_alg *alg)
390 {
391         int ret;
392         LIST_HEAD(list);
393
394         down_write(&crypto_alg_sem);
395         ret = crypto_remove_alg(alg, &list);
396         up_write(&crypto_alg_sem);
397
398         if (ret)
399                 return ret;
400
401         BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
402         if (alg->cra_destroy)
403                 alg->cra_destroy(alg);
404
405         crypto_remove_final(&list);
406         return 0;
407 }
408 EXPORT_SYMBOL_GPL(crypto_unregister_alg);
409
410 int crypto_register_algs(struct crypto_alg *algs, int count)
411 {
412         int i, ret;
413
414         for (i = 0; i < count; i++) {
415                 ret = crypto_register_alg(&algs[i]);
416                 if (ret)
417                         goto err;
418         }
419
420         return 0;
421
422 err:
423         for (--i; i >= 0; --i)
424                 crypto_unregister_alg(&algs[i]);
425
426         return ret;
427 }
428 EXPORT_SYMBOL_GPL(crypto_register_algs);
429
430 int crypto_unregister_algs(struct crypto_alg *algs, int count)
431 {
432         int i, ret;
433
434         for (i = 0; i < count; i++) {
435                 ret = crypto_unregister_alg(&algs[i]);
436                 if (ret)
437                         pr_err("Failed to unregister %s %s: %d\n",
438                                algs[i].cra_driver_name, algs[i].cra_name, ret);
439         }
440
441         return 0;
442 }
443 EXPORT_SYMBOL_GPL(crypto_unregister_algs);
444
445 int crypto_register_template(struct crypto_template *tmpl)
446 {
447         struct crypto_template *q;
448         int err = -EEXIST;
449
450         down_write(&crypto_alg_sem);
451
452         crypto_check_module_sig(tmpl->module);
453
454         list_for_each_entry(q, &crypto_template_list, list) {
455                 if (q == tmpl)
456                         goto out;
457         }
458
459         list_add(&tmpl->list, &crypto_template_list);
460         crypto_notify(CRYPTO_MSG_TMPL_REGISTER, tmpl);
461         err = 0;
462 out:
463         up_write(&crypto_alg_sem);
464         return err;
465 }
466 EXPORT_SYMBOL_GPL(crypto_register_template);
467
468 void crypto_unregister_template(struct crypto_template *tmpl)
469 {
470         struct crypto_instance *inst;
471         struct hlist_node *n;
472         struct hlist_head *list;
473         LIST_HEAD(users);
474
475         down_write(&crypto_alg_sem);
476
477         BUG_ON(list_empty(&tmpl->list));
478         list_del_init(&tmpl->list);
479
480         list = &tmpl->instances;
481         hlist_for_each_entry(inst, list, list) {
482                 int err = crypto_remove_alg(&inst->alg, &users);
483
484                 BUG_ON(err);
485         }
486
487         crypto_notify(CRYPTO_MSG_TMPL_UNREGISTER, tmpl);
488
489         up_write(&crypto_alg_sem);
490
491         hlist_for_each_entry_safe(inst, n, list, list) {
492                 BUG_ON(atomic_read(&inst->alg.cra_refcnt) != 1);
493                 crypto_free_instance(inst);
494         }
495         crypto_remove_final(&users);
496 }
497 EXPORT_SYMBOL_GPL(crypto_unregister_template);
498
499 static struct crypto_template *__crypto_lookup_template(const char *name)
500 {
501         struct crypto_template *q, *tmpl = NULL;
502
503         down_read(&crypto_alg_sem);
504         list_for_each_entry(q, &crypto_template_list, list) {
505                 if (strcmp(q->name, name))
506                         continue;
507                 if (unlikely(!crypto_tmpl_get(q)))
508                         continue;
509
510                 tmpl = q;
511                 break;
512         }
513         up_read(&crypto_alg_sem);
514
515         return tmpl;
516 }
517
518 struct crypto_template *crypto_lookup_template(const char *name)
519 {
520         return try_then_request_module(__crypto_lookup_template(name),
521                                        "crypto-%s", name);
522 }
523 EXPORT_SYMBOL_GPL(crypto_lookup_template);
524
525 int crypto_register_instance(struct crypto_template *tmpl,
526                              struct crypto_instance *inst)
527 {
528         struct crypto_larval *larval;
529         int err;
530
531         err = crypto_check_alg(&inst->alg);
532         if (err)
533                 return err;
534
535         inst->alg.cra_module = tmpl->module;
536         inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
537
538         if (unlikely(!crypto_mod_get(&inst->alg)))
539                 return -EAGAIN;
540
541         down_write(&crypto_alg_sem);
542
543         larval = __crypto_register_alg(&inst->alg);
544         if (IS_ERR(larval))
545                 goto unlock;
546
547         hlist_add_head(&inst->list, &tmpl->instances);
548         inst->tmpl = tmpl;
549
550 unlock:
551         up_write(&crypto_alg_sem);
552
553         err = PTR_ERR(larval);
554         if (IS_ERR(larval))
555                 goto err;
556
557         crypto_wait_for_test(larval);
558
559         /* Remove instance if test failed */
560         if (!(inst->alg.cra_flags & CRYPTO_ALG_TESTED))
561                 crypto_unregister_instance(inst);
562         err = 0;
563
564 err:
565         crypto_mod_put(&inst->alg);
566         return err;
567 }
568 EXPORT_SYMBOL_GPL(crypto_register_instance);
569
570 int crypto_unregister_instance(struct crypto_instance *inst)
571 {
572         LIST_HEAD(list);
573
574         down_write(&crypto_alg_sem);
575
576         crypto_remove_spawns(&inst->alg, &list, NULL);
577         crypto_remove_instance(inst, &list);
578
579         up_write(&crypto_alg_sem);
580
581         crypto_remove_final(&list);
582
583         return 0;
584 }
585 EXPORT_SYMBOL_GPL(crypto_unregister_instance);
586
587 int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
588                       struct crypto_instance *inst, u32 mask)
589 {
590         int err = -EAGAIN;
591
592         spawn->inst = inst;
593         spawn->mask = mask;
594
595         down_write(&crypto_alg_sem);
596         if (!crypto_is_moribund(alg)) {
597                 list_add(&spawn->list, &alg->cra_users);
598                 spawn->alg = alg;
599                 err = 0;
600         }
601         up_write(&crypto_alg_sem);
602
603         return err;
604 }
605 EXPORT_SYMBOL_GPL(crypto_init_spawn);
606
607 int crypto_init_spawn2(struct crypto_spawn *spawn, struct crypto_alg *alg,
608                        struct crypto_instance *inst,
609                        const struct crypto_type *frontend)
610 {
611         int err = -EINVAL;
612
613         if ((alg->cra_flags ^ frontend->type) & frontend->maskset)
614                 goto out;
615
616         spawn->frontend = frontend;
617         err = crypto_init_spawn(spawn, alg, inst, frontend->maskset);
618
619 out:
620         return err;
621 }
622 EXPORT_SYMBOL_GPL(crypto_init_spawn2);
623
624 int crypto_grab_spawn(struct crypto_spawn *spawn, const char *name,
625                       u32 type, u32 mask)
626 {
627         struct crypto_alg *alg;
628         int err;
629
630         alg = crypto_find_alg(name, spawn->frontend, type, mask);
631         if (IS_ERR(alg))
632                 return PTR_ERR(alg);
633
634         err = crypto_init_spawn(spawn, alg, spawn->inst, mask);
635         crypto_mod_put(alg);
636         return err;
637 }
638 EXPORT_SYMBOL_GPL(crypto_grab_spawn);
639
640 void crypto_drop_spawn(struct crypto_spawn *spawn)
641 {
642         if (!spawn->alg)
643                 return;
644
645         down_write(&crypto_alg_sem);
646         list_del(&spawn->list);
647         up_write(&crypto_alg_sem);
648 }
649 EXPORT_SYMBOL_GPL(crypto_drop_spawn);
650
651 static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
652 {
653         struct crypto_alg *alg;
654         struct crypto_alg *alg2;
655
656         down_read(&crypto_alg_sem);
657         alg = spawn->alg;
658         alg2 = alg;
659         if (alg2)
660                 alg2 = crypto_mod_get(alg2);
661         up_read(&crypto_alg_sem);
662
663         if (!alg2) {
664                 if (alg)
665                         crypto_shoot_alg(alg);
666                 return ERR_PTR(-EAGAIN);
667         }
668
669         return alg;
670 }
671
672 struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
673                                     u32 mask)
674 {
675         struct crypto_alg *alg;
676         struct crypto_tfm *tfm;
677
678         alg = crypto_spawn_alg(spawn);
679         if (IS_ERR(alg))
680                 return ERR_CAST(alg);
681
682         tfm = ERR_PTR(-EINVAL);
683         if (unlikely((alg->cra_flags ^ type) & mask))
684                 goto out_put_alg;
685
686         tfm = __crypto_alloc_tfm(alg, type, mask);
687         if (IS_ERR(tfm))
688                 goto out_put_alg;
689
690         return tfm;
691
692 out_put_alg:
693         crypto_mod_put(alg);
694         return tfm;
695 }
696 EXPORT_SYMBOL_GPL(crypto_spawn_tfm);
697
698 void *crypto_spawn_tfm2(struct crypto_spawn *spawn)
699 {
700         struct crypto_alg *alg;
701         struct crypto_tfm *tfm;
702
703         alg = crypto_spawn_alg(spawn);
704         if (IS_ERR(alg))
705                 return ERR_CAST(alg);
706
707         tfm = crypto_create_tfm(alg, spawn->frontend);
708         if (IS_ERR(tfm))
709                 goto out_put_alg;
710
711         return tfm;
712
713 out_put_alg:
714         crypto_mod_put(alg);
715         return tfm;
716 }
717 EXPORT_SYMBOL_GPL(crypto_spawn_tfm2);
718
719 int crypto_register_notifier(struct notifier_block *nb)
720 {
721         return blocking_notifier_chain_register(&crypto_chain, nb);
722 }
723 EXPORT_SYMBOL_GPL(crypto_register_notifier);
724
725 int crypto_unregister_notifier(struct notifier_block *nb)
726 {
727         return blocking_notifier_chain_unregister(&crypto_chain, nb);
728 }
729 EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
730
731 struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
732 {
733         struct rtattr *rta = tb[0];
734         struct crypto_attr_type *algt;
735
736         if (!rta)
737                 return ERR_PTR(-ENOENT);
738         if (RTA_PAYLOAD(rta) < sizeof(*algt))
739                 return ERR_PTR(-EINVAL);
740         if (rta->rta_type != CRYPTOA_TYPE)
741                 return ERR_PTR(-EINVAL);
742
743         algt = RTA_DATA(rta);
744
745         return algt;
746 }
747 EXPORT_SYMBOL_GPL(crypto_get_attr_type);
748
749 int crypto_check_attr_type(struct rtattr **tb, u32 type)
750 {
751         struct crypto_attr_type *algt;
752
753         algt = crypto_get_attr_type(tb);
754         if (IS_ERR(algt))
755                 return PTR_ERR(algt);
756
757         if ((algt->type ^ type) & algt->mask)
758                 return -EINVAL;
759
760         return 0;
761 }
762 EXPORT_SYMBOL_GPL(crypto_check_attr_type);
763
764 const char *crypto_attr_alg_name(struct rtattr *rta)
765 {
766         struct crypto_attr_alg *alga;
767
768         if (!rta)
769                 return ERR_PTR(-ENOENT);
770         if (RTA_PAYLOAD(rta) < sizeof(*alga))
771                 return ERR_PTR(-EINVAL);
772         if (rta->rta_type != CRYPTOA_ALG)
773                 return ERR_PTR(-EINVAL);
774
775         alga = RTA_DATA(rta);
776         alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
777
778         return alga->name;
779 }
780 EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
781
782 struct crypto_alg *crypto_attr_alg2(struct rtattr *rta,
783                                     const struct crypto_type *frontend,
784                                     u32 type, u32 mask)
785 {
786         const char *name;
787
788         name = crypto_attr_alg_name(rta);
789         if (IS_ERR(name))
790                 return ERR_CAST(name);
791
792         return crypto_find_alg(name, frontend, type, mask);
793 }
794 EXPORT_SYMBOL_GPL(crypto_attr_alg2);
795
796 int crypto_attr_u32(struct rtattr *rta, u32 *num)
797 {
798         struct crypto_attr_u32 *nu32;
799
800         if (!rta)
801                 return -ENOENT;
802         if (RTA_PAYLOAD(rta) < sizeof(*nu32))
803                 return -EINVAL;
804         if (rta->rta_type != CRYPTOA_U32)
805                 return -EINVAL;
806
807         nu32 = RTA_DATA(rta);
808         *num = nu32->num;
809
810         return 0;
811 }
812 EXPORT_SYMBOL_GPL(crypto_attr_u32);
813
814 void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg,
815                              unsigned int head)
816 {
817         struct crypto_instance *inst;
818         char *p;
819         int err;
820
821         p = kzalloc(head + sizeof(*inst) + sizeof(struct crypto_spawn),
822                     GFP_KERNEL);
823         if (!p)
824                 return ERR_PTR(-ENOMEM);
825
826         inst = (void *)(p + head);
827
828         err = -ENAMETOOLONG;
829         if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s(%s)", name,
830                      alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
831                 goto err_free_inst;
832
833         if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
834                      name, alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
835                 goto err_free_inst;
836
837         return p;
838
839 err_free_inst:
840         kfree(p);
841         return ERR_PTR(err);
842 }
843 EXPORT_SYMBOL_GPL(crypto_alloc_instance2);
844
845 struct crypto_instance *crypto_alloc_instance(const char *name,
846                                               struct crypto_alg *alg)
847 {
848         struct crypto_instance *inst;
849         struct crypto_spawn *spawn;
850         int err;
851
852         inst = crypto_alloc_instance2(name, alg, 0);
853         if (IS_ERR(inst))
854                 goto out;
855
856         spawn = crypto_instance_ctx(inst);
857         err = crypto_init_spawn(spawn, alg, inst,
858                                 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC);
859
860         if (err)
861                 goto err_free_inst;
862
863         return inst;
864
865 err_free_inst:
866         kfree(inst);
867         inst = ERR_PTR(err);
868
869 out:
870         return inst;
871 }
872 EXPORT_SYMBOL_GPL(crypto_alloc_instance);
873
874 void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen)
875 {
876         INIT_LIST_HEAD(&queue->list);
877         queue->backlog = &queue->list;
878         queue->qlen = 0;
879         queue->max_qlen = max_qlen;
880 }
881 EXPORT_SYMBOL_GPL(crypto_init_queue);
882
883 int crypto_enqueue_request(struct crypto_queue *queue,
884                            struct crypto_async_request *request)
885 {
886         int err = -EINPROGRESS;
887
888         if (unlikely(queue->qlen >= queue->max_qlen)) {
889                 err = -EBUSY;
890                 if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
891                         goto out;
892                 if (queue->backlog == &queue->list)
893                         queue->backlog = &request->list;
894         }
895
896         queue->qlen++;
897         list_add_tail(&request->list, &queue->list);
898
899 out:
900         return err;
901 }
902 EXPORT_SYMBOL_GPL(crypto_enqueue_request);
903
904 struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
905 {
906         struct list_head *request;
907
908         if (unlikely(!queue->qlen))
909                 return NULL;
910
911         queue->qlen--;
912
913         if (queue->backlog != &queue->list)
914                 queue->backlog = queue->backlog->next;
915
916         request = queue->list.next;
917         list_del(request);
918
919         return list_entry(request, struct crypto_async_request, list);
920 }
921 EXPORT_SYMBOL_GPL(crypto_dequeue_request);
922
923 int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm)
924 {
925         struct crypto_async_request *req;
926
927         list_for_each_entry(req, &queue->list, list) {
928                 if (req->tfm == tfm)
929                         return 1;
930         }
931
932         return 0;
933 }
934 EXPORT_SYMBOL_GPL(crypto_tfm_in_queue);
935
936 static inline void crypto_inc_byte(u8 *a, unsigned int size)
937 {
938         u8 *b = (a + size);
939         u8 c;
940
941         for (; size; size--) {
942                 c = *--b + 1;
943                 *b = c;
944                 if (c)
945                         break;
946         }
947 }
948
949 void crypto_inc(u8 *a, unsigned int size)
950 {
951         __be32 *b = (__be32 *)(a + size);
952         u32 c;
953
954         for (; size >= 4; size -= 4) {
955                 c = be32_to_cpu(*--b) + 1;
956                 *b = cpu_to_be32(c);
957                 if (c)
958                         return;
959         }
960
961         crypto_inc_byte(a, size);
962 }
963 EXPORT_SYMBOL_GPL(crypto_inc);
964
965 static inline void crypto_xor_byte(u8 *a, const u8 *b, unsigned int size)
966 {
967         for (; size; size--)
968                 *a++ ^= *b++;
969 }
970
971 void crypto_xor(u8 *dst, const u8 *src, unsigned int size)
972 {
973         u32 *a = (u32 *)dst;
974         u32 *b = (u32 *)src;
975
976         for (; size >= 4; size -= 4)
977                 *a++ ^= *b++;
978
979         crypto_xor_byte((u8 *)a, (u8 *)b, size);
980 }
981 EXPORT_SYMBOL_GPL(crypto_xor);
982
983 unsigned int crypto_alg_extsize(struct crypto_alg *alg)
984 {
985         return alg->cra_ctxsize +
986                (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
987 }
988 EXPORT_SYMBOL_GPL(crypto_alg_extsize);
989
990 static int __init crypto_algapi_init(void)
991 {
992         crypto_init_proc();
993         return 0;
994 }
995
996 static void __exit crypto_algapi_exit(void)
997 {
998         crypto_exit_proc();
999 }
1000
1001 module_init(crypto_algapi_init);
1002 module_exit(crypto_algapi_exit);
1003
1004 MODULE_LICENSE("GPL");
1005 MODULE_DESCRIPTION("Cryptographic algorithms API");