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