diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/Kconfig | 13 | ||||
-rw-r--r-- | crypto/Makefile | 2 | ||||
-rw-r--r-- | crypto/ablkcipher.c | 83 | ||||
-rw-r--r-- | crypto/algapi.c | 169 | ||||
-rw-r--r-- | crypto/blkcipher.c | 72 | ||||
-rw-r--r-- | crypto/cbc.c | 11 | ||||
-rw-r--r-- | crypto/cryptd.c | 375 | ||||
-rw-r--r-- | crypto/cryptomgr.c | 66 | ||||
-rw-r--r-- | crypto/ecb.c | 11 | ||||
-rw-r--r-- | crypto/hash.c | 2 | ||||
-rw-r--r-- | crypto/hmac.c | 11 | ||||
-rw-r--r-- | crypto/lrw.c | 11 | ||||
-rw-r--r-- | crypto/michael_mic.c | 4 | ||||
-rw-r--r-- | crypto/pcbc.c | 11 | ||||
-rw-r--r-- | crypto/scatterwalk.c | 12 | ||||
-rw-r--r-- | crypto/tcrypt.c | 123 | ||||
-rw-r--r-- | crypto/xcbc.c | 12 |
17 files changed, 862 insertions, 126 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 086fcec44720..620e14cabdc6 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -16,6 +16,10 @@ config CRYPTO_ALGAPI | |||
16 | help | 16 | help |
17 | This option provides the API for cryptographic algorithms. | 17 | This option provides the API for cryptographic algorithms. |
18 | 18 | ||
19 | config CRYPTO_ABLKCIPHER | ||
20 | tristate | ||
21 | select CRYPTO_BLKCIPHER | ||
22 | |||
19 | config CRYPTO_BLKCIPHER | 23 | config CRYPTO_BLKCIPHER |
20 | tristate | 24 | tristate |
21 | select CRYPTO_ALGAPI | 25 | select CRYPTO_ALGAPI |
@@ -171,6 +175,15 @@ config CRYPTO_LRW | |||
171 | The first 128, 192 or 256 bits in the key are used for AES and the | 175 | The first 128, 192 or 256 bits in the key are used for AES and the |
172 | rest is used to tie each cipher block to its logical position. | 176 | rest is used to tie each cipher block to its logical position. |
173 | 177 | ||
178 | config CRYPTO_CRYPTD | ||
179 | tristate "Software async crypto daemon" | ||
180 | select CRYPTO_ABLKCIPHER | ||
181 | select CRYPTO_MANAGER | ||
182 | help | ||
183 | This is a generic software asynchronous crypto daemon that | ||
184 | converts an arbitrary synchronous software crypto algorithm | ||
185 | into an asynchronous algorithm that executes in a kernel thread. | ||
186 | |||
174 | config CRYPTO_DES | 187 | config CRYPTO_DES |
175 | tristate "DES and Triple DES EDE cipher algorithms" | 188 | tristate "DES and Triple DES EDE cipher algorithms" |
176 | select CRYPTO_ALGAPI | 189 | select CRYPTO_ALGAPI |
diff --git a/crypto/Makefile b/crypto/Makefile index 12f93f578171..cce46a1c9dc7 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
@@ -8,6 +8,7 @@ crypto_algapi-$(CONFIG_PROC_FS) += proc.o | |||
8 | crypto_algapi-objs := algapi.o $(crypto_algapi-y) | 8 | crypto_algapi-objs := algapi.o $(crypto_algapi-y) |
9 | obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o | 9 | obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o |
10 | 10 | ||
11 | obj-$(CONFIG_CRYPTO_ABLKCIPHER) += ablkcipher.o | ||
11 | obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o | 12 | obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o |
12 | 13 | ||
13 | crypto_hash-objs := hash.o | 14 | crypto_hash-objs := hash.o |
@@ -29,6 +30,7 @@ obj-$(CONFIG_CRYPTO_ECB) += ecb.o | |||
29 | obj-$(CONFIG_CRYPTO_CBC) += cbc.o | 30 | obj-$(CONFIG_CRYPTO_CBC) += cbc.o |
30 | obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o | 31 | obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o |
31 | obj-$(CONFIG_CRYPTO_LRW) += lrw.o | 32 | obj-$(CONFIG_CRYPTO_LRW) += lrw.o |
33 | obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o | ||
32 | obj-$(CONFIG_CRYPTO_DES) += des.o | 34 | obj-$(CONFIG_CRYPTO_DES) += des.o |
33 | obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o | 35 | obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o |
34 | obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o | 36 | obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o |
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c new file mode 100644 index 000000000000..9348ddd84a56 --- /dev/null +++ b/crypto/ablkcipher.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Asynchronous block chaining cipher operations. | ||
3 | * | ||
4 | * This is the asynchronous version of blkcipher.c indicating completion | ||
5 | * via a callback. | ||
6 | * | ||
7 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the Free | ||
11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
12 | * any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <crypto/algapi.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/seq_file.h> | ||
21 | |||
22 | static int setkey(struct crypto_ablkcipher *tfm, const u8 *key, | ||
23 | unsigned int keylen) | ||
24 | { | ||
25 | struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); | ||
26 | |||
27 | if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { | ||
28 | crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
29 | return -EINVAL; | ||
30 | } | ||
31 | |||
32 | return cipher->setkey(tfm, key, keylen); | ||
33 | } | ||
34 | |||
35 | static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type, | ||
36 | u32 mask) | ||
37 | { | ||
38 | return alg->cra_ctxsize; | ||
39 | } | ||
40 | |||
41 | static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, | ||
42 | u32 mask) | ||
43 | { | ||
44 | struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher; | ||
45 | struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher; | ||
46 | |||
47 | if (alg->ivsize > PAGE_SIZE / 8) | ||
48 | return -EINVAL; | ||
49 | |||
50 | crt->setkey = setkey; | ||
51 | crt->encrypt = alg->encrypt; | ||
52 | crt->decrypt = alg->decrypt; | ||
53 | crt->ivsize = alg->ivsize; | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) | ||
59 | __attribute__ ((unused)); | ||
60 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) | ||
61 | { | ||
62 | struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher; | ||
63 | |||
64 | seq_printf(m, "type : ablkcipher\n"); | ||
65 | seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); | ||
66 | seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); | ||
67 | seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); | ||
68 | seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize); | ||
69 | seq_printf(m, "qlen : %u\n", ablkcipher->queue->qlen); | ||
70 | seq_printf(m, "max qlen : %u\n", ablkcipher->queue->max_qlen); | ||
71 | } | ||
72 | |||
73 | const struct crypto_type crypto_ablkcipher_type = { | ||
74 | .ctxsize = crypto_ablkcipher_ctxsize, | ||
75 | .init = crypto_init_ablkcipher_ops, | ||
76 | #ifdef CONFIG_PROC_FS | ||
77 | .show = crypto_ablkcipher_show, | ||
78 | #endif | ||
79 | }; | ||
80 | EXPORT_SYMBOL_GPL(crypto_ablkcipher_type); | ||
81 | |||
82 | MODULE_LICENSE("GPL"); | ||
83 | MODULE_DESCRIPTION("Asynchronous block chaining cipher type"); | ||
diff --git a/crypto/algapi.c b/crypto/algapi.c index f7d2185b2c8f..f137a432061f 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c | |||
@@ -84,36 +84,47 @@ static void crypto_destroy_instance(struct crypto_alg *alg) | |||
84 | crypto_tmpl_put(tmpl); | 84 | crypto_tmpl_put(tmpl); |
85 | } | 85 | } |
86 | 86 | ||
87 | static void crypto_remove_spawns(struct list_head *spawns, | 87 | static void crypto_remove_spawn(struct crypto_spawn *spawn, |
88 | struct list_head *list) | 88 | struct list_head *list, |
89 | struct list_head *secondary_spawns) | ||
89 | { | 90 | { |
90 | struct crypto_spawn *spawn, *n; | 91 | struct crypto_instance *inst = spawn->inst; |
92 | struct crypto_template *tmpl = inst->tmpl; | ||
91 | 93 | ||
92 | list_for_each_entry_safe(spawn, n, spawns, list) { | 94 | list_del_init(&spawn->list); |
93 | struct crypto_instance *inst = spawn->inst; | 95 | spawn->alg = NULL; |
94 | struct crypto_template *tmpl = inst->tmpl; | ||
95 | 96 | ||
96 | list_del_init(&spawn->list); | 97 | if (crypto_is_dead(&inst->alg)) |
97 | spawn->alg = NULL; | 98 | return; |
98 | 99 | ||
99 | if (crypto_is_dead(&inst->alg)) | 100 | inst->alg.cra_flags |= CRYPTO_ALG_DEAD; |
100 | continue; | 101 | if (!tmpl || !crypto_tmpl_get(tmpl)) |
102 | return; | ||
101 | 103 | ||
102 | inst->alg.cra_flags |= CRYPTO_ALG_DEAD; | 104 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg); |
103 | if (!tmpl || !crypto_tmpl_get(tmpl)) | 105 | list_move(&inst->alg.cra_list, list); |
106 | hlist_del(&inst->list); | ||
107 | inst->alg.cra_destroy = crypto_destroy_instance; | ||
108 | |||
109 | list_splice(&inst->alg.cra_users, secondary_spawns); | ||
110 | } | ||
111 | |||
112 | static void crypto_remove_spawns(struct list_head *spawns, | ||
113 | struct list_head *list, u32 new_type) | ||
114 | { | ||
115 | struct crypto_spawn *spawn, *n; | ||
116 | LIST_HEAD(secondary_spawns); | ||
117 | |||
118 | list_for_each_entry_safe(spawn, n, spawns, list) { | ||
119 | if ((spawn->alg->cra_flags ^ new_type) & spawn->mask) | ||
104 | continue; | 120 | continue; |
105 | 121 | ||
106 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, &inst->alg); | 122 | crypto_remove_spawn(spawn, list, &secondary_spawns); |
107 | list_move(&inst->alg.cra_list, list); | 123 | } |
108 | hlist_del(&inst->list); | ||
109 | inst->alg.cra_destroy = crypto_destroy_instance; | ||
110 | 124 | ||
111 | if (!list_empty(&inst->alg.cra_users)) { | 125 | while (!list_empty(&secondary_spawns)) { |
112 | if (&n->list == spawns) | 126 | list_for_each_entry_safe(spawn, n, &secondary_spawns, list) |
113 | n = list_entry(inst->alg.cra_users.next, | 127 | crypto_remove_spawn(spawn, list, &secondary_spawns); |
114 | typeof(*n), list); | ||
115 | __list_splice(&inst->alg.cra_users, spawns->prev); | ||
116 | } | ||
117 | } | 128 | } |
118 | } | 129 | } |
119 | 130 | ||
@@ -164,7 +175,7 @@ static int __crypto_register_alg(struct crypto_alg *alg, | |||
164 | q->cra_priority > alg->cra_priority) | 175 | q->cra_priority > alg->cra_priority) |
165 | continue; | 176 | continue; |
166 | 177 | ||
167 | crypto_remove_spawns(&q->cra_users, list); | 178 | crypto_remove_spawns(&q->cra_users, list, alg->cra_flags); |
168 | } | 179 | } |
169 | 180 | ||
170 | list_add(&alg->cra_list, &crypto_alg_list); | 181 | list_add(&alg->cra_list, &crypto_alg_list); |
@@ -214,7 +225,7 @@ static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list) | |||
214 | 225 | ||
215 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg); | 226 | crypto_notify(CRYPTO_MSG_ALG_UNREGISTER, alg); |
216 | list_del_init(&alg->cra_list); | 227 | list_del_init(&alg->cra_list); |
217 | crypto_remove_spawns(&alg->cra_users, list); | 228 | crypto_remove_spawns(&alg->cra_users, list, alg->cra_flags); |
218 | 229 | ||
219 | return 0; | 230 | return 0; |
220 | } | 231 | } |
@@ -351,11 +362,12 @@ err: | |||
351 | EXPORT_SYMBOL_GPL(crypto_register_instance); | 362 | EXPORT_SYMBOL_GPL(crypto_register_instance); |
352 | 363 | ||
353 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, | 364 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, |
354 | struct crypto_instance *inst) | 365 | struct crypto_instance *inst, u32 mask) |
355 | { | 366 | { |
356 | int err = -EAGAIN; | 367 | int err = -EAGAIN; |
357 | 368 | ||
358 | spawn->inst = inst; | 369 | spawn->inst = inst; |
370 | spawn->mask = mask; | ||
359 | 371 | ||
360 | down_write(&crypto_alg_sem); | 372 | down_write(&crypto_alg_sem); |
361 | if (!crypto_is_moribund(alg)) { | 373 | if (!crypto_is_moribund(alg)) { |
@@ -425,15 +437,45 @@ int crypto_unregister_notifier(struct notifier_block *nb) | |||
425 | } | 437 | } |
426 | EXPORT_SYMBOL_GPL(crypto_unregister_notifier); | 438 | EXPORT_SYMBOL_GPL(crypto_unregister_notifier); |
427 | 439 | ||
428 | struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, | 440 | struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb) |
429 | u32 type, u32 mask) | 441 | { |
442 | struct rtattr *rta = tb[CRYPTOA_TYPE - 1]; | ||
443 | struct crypto_attr_type *algt; | ||
444 | |||
445 | if (!rta) | ||
446 | return ERR_PTR(-ENOENT); | ||
447 | if (RTA_PAYLOAD(rta) < sizeof(*algt)) | ||
448 | return ERR_PTR(-EINVAL); | ||
449 | |||
450 | algt = RTA_DATA(rta); | ||
451 | |||
452 | return algt; | ||
453 | } | ||
454 | EXPORT_SYMBOL_GPL(crypto_get_attr_type); | ||
455 | |||
456 | int crypto_check_attr_type(struct rtattr **tb, u32 type) | ||
430 | { | 457 | { |
431 | struct rtattr *rta = param; | 458 | struct crypto_attr_type *algt; |
459 | |||
460 | algt = crypto_get_attr_type(tb); | ||
461 | if (IS_ERR(algt)) | ||
462 | return PTR_ERR(algt); | ||
463 | |||
464 | if ((algt->type ^ type) & algt->mask) | ||
465 | return -EINVAL; | ||
466 | |||
467 | return 0; | ||
468 | } | ||
469 | EXPORT_SYMBOL_GPL(crypto_check_attr_type); | ||
470 | |||
471 | struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask) | ||
472 | { | ||
473 | struct rtattr *rta = tb[CRYPTOA_ALG - 1]; | ||
432 | struct crypto_attr_alg *alga; | 474 | struct crypto_attr_alg *alga; |
433 | 475 | ||
434 | if (!RTA_OK(rta, len)) | 476 | if (!rta) |
435 | return ERR_PTR(-EBADR); | 477 | return ERR_PTR(-ENOENT); |
436 | if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga)) | 478 | if (RTA_PAYLOAD(rta) < sizeof(*alga)) |
437 | return ERR_PTR(-EINVAL); | 479 | return ERR_PTR(-EINVAL); |
438 | 480 | ||
439 | alga = RTA_DATA(rta); | 481 | alga = RTA_DATA(rta); |
@@ -464,7 +506,8 @@ struct crypto_instance *crypto_alloc_instance(const char *name, | |||
464 | goto err_free_inst; | 506 | goto err_free_inst; |
465 | 507 | ||
466 | spawn = crypto_instance_ctx(inst); | 508 | spawn = crypto_instance_ctx(inst); |
467 | err = crypto_init_spawn(spawn, alg, inst); | 509 | err = crypto_init_spawn(spawn, alg, inst, |
510 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | ||
468 | 511 | ||
469 | if (err) | 512 | if (err) |
470 | goto err_free_inst; | 513 | goto err_free_inst; |
@@ -477,6 +520,68 @@ err_free_inst: | |||
477 | } | 520 | } |
478 | EXPORT_SYMBOL_GPL(crypto_alloc_instance); | 521 | EXPORT_SYMBOL_GPL(crypto_alloc_instance); |
479 | 522 | ||
523 | void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen) | ||
524 | { | ||
525 | INIT_LIST_HEAD(&queue->list); | ||
526 | queue->backlog = &queue->list; | ||
527 | queue->qlen = 0; | ||
528 | queue->max_qlen = max_qlen; | ||
529 | } | ||
530 | EXPORT_SYMBOL_GPL(crypto_init_queue); | ||
531 | |||
532 | int crypto_enqueue_request(struct crypto_queue *queue, | ||
533 | struct crypto_async_request *request) | ||
534 | { | ||
535 | int err = -EINPROGRESS; | ||
536 | |||
537 | if (unlikely(queue->qlen >= queue->max_qlen)) { | ||
538 | err = -EBUSY; | ||
539 | if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) | ||
540 | goto out; | ||
541 | if (queue->backlog == &queue->list) | ||
542 | queue->backlog = &request->list; | ||
543 | } | ||
544 | |||
545 | queue->qlen++; | ||
546 | list_add_tail(&request->list, &queue->list); | ||
547 | |||
548 | out: | ||
549 | return err; | ||
550 | } | ||
551 | EXPORT_SYMBOL_GPL(crypto_enqueue_request); | ||
552 | |||
553 | struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue) | ||
554 | { | ||
555 | struct list_head *request; | ||
556 | |||
557 | if (unlikely(!queue->qlen)) | ||
558 | return NULL; | ||
559 | |||
560 | queue->qlen--; | ||
561 | |||
562 | if (queue->backlog != &queue->list) | ||
563 | queue->backlog = queue->backlog->next; | ||
564 | |||
565 | request = queue->list.next; | ||
566 | list_del(request); | ||
567 | |||
568 | return list_entry(request, struct crypto_async_request, list); | ||
569 | } | ||
570 | EXPORT_SYMBOL_GPL(crypto_dequeue_request); | ||
571 | |||
572 | int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm) | ||
573 | { | ||
574 | struct crypto_async_request *req; | ||
575 | |||
576 | list_for_each_entry(req, &queue->list, list) { | ||
577 | if (req->tfm == tfm) | ||
578 | return 1; | ||
579 | } | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | EXPORT_SYMBOL_GPL(crypto_tfm_in_queue); | ||
584 | |||
480 | static int __init crypto_algapi_init(void) | 585 | static int __init crypto_algapi_init(void) |
481 | { | 586 | { |
482 | crypto_init_proc(); | 587 | crypto_init_proc(); |
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index b5befe8c3a96..8edf40c835a7 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
@@ -349,13 +349,48 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, | |||
349 | return cipher->setkey(tfm, key, keylen); | 349 | return cipher->setkey(tfm, key, keylen); |
350 | } | 350 | } |
351 | 351 | ||
352 | static int async_setkey(struct crypto_ablkcipher *tfm, const u8 *key, | ||
353 | unsigned int keylen) | ||
354 | { | ||
355 | return setkey(crypto_ablkcipher_tfm(tfm), key, keylen); | ||
356 | } | ||
357 | |||
358 | static int async_encrypt(struct ablkcipher_request *req) | ||
359 | { | ||
360 | struct crypto_tfm *tfm = req->base.tfm; | ||
361 | struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; | ||
362 | struct blkcipher_desc desc = { | ||
363 | .tfm = __crypto_blkcipher_cast(tfm), | ||
364 | .info = req->info, | ||
365 | .flags = req->base.flags, | ||
366 | }; | ||
367 | |||
368 | |||
369 | return alg->encrypt(&desc, req->dst, req->src, req->nbytes); | ||
370 | } | ||
371 | |||
372 | static int async_decrypt(struct ablkcipher_request *req) | ||
373 | { | ||
374 | struct crypto_tfm *tfm = req->base.tfm; | ||
375 | struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; | ||
376 | struct blkcipher_desc desc = { | ||
377 | .tfm = __crypto_blkcipher_cast(tfm), | ||
378 | .info = req->info, | ||
379 | .flags = req->base.flags, | ||
380 | }; | ||
381 | |||
382 | return alg->decrypt(&desc, req->dst, req->src, req->nbytes); | ||
383 | } | ||
384 | |||
352 | static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, | 385 | static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, |
353 | u32 mask) | 386 | u32 mask) |
354 | { | 387 | { |
355 | struct blkcipher_alg *cipher = &alg->cra_blkcipher; | 388 | struct blkcipher_alg *cipher = &alg->cra_blkcipher; |
356 | unsigned int len = alg->cra_ctxsize; | 389 | unsigned int len = alg->cra_ctxsize; |
357 | 390 | ||
358 | if (cipher->ivsize) { | 391 | type ^= CRYPTO_ALG_ASYNC; |
392 | mask &= CRYPTO_ALG_ASYNC; | ||
393 | if ((type & mask) && cipher->ivsize) { | ||
359 | len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1); | 394 | len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1); |
360 | len += cipher->ivsize; | 395 | len += cipher->ivsize; |
361 | } | 396 | } |
@@ -363,16 +398,26 @@ static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, | |||
363 | return len; | 398 | return len; |
364 | } | 399 | } |
365 | 400 | ||
366 | static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | 401 | static int crypto_init_blkcipher_ops_async(struct crypto_tfm *tfm) |
402 | { | ||
403 | struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher; | ||
404 | struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; | ||
405 | |||
406 | crt->setkey = async_setkey; | ||
407 | crt->encrypt = async_encrypt; | ||
408 | crt->decrypt = async_decrypt; | ||
409 | crt->ivsize = alg->ivsize; | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static int crypto_init_blkcipher_ops_sync(struct crypto_tfm *tfm) | ||
367 | { | 415 | { |
368 | struct blkcipher_tfm *crt = &tfm->crt_blkcipher; | 416 | struct blkcipher_tfm *crt = &tfm->crt_blkcipher; |
369 | struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; | 417 | struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; |
370 | unsigned long align = crypto_tfm_alg_alignmask(tfm) + 1; | 418 | unsigned long align = crypto_tfm_alg_alignmask(tfm) + 1; |
371 | unsigned long addr; | 419 | unsigned long addr; |
372 | 420 | ||
373 | if (alg->ivsize > PAGE_SIZE / 8) | ||
374 | return -EINVAL; | ||
375 | |||
376 | crt->setkey = setkey; | 421 | crt->setkey = setkey; |
377 | crt->encrypt = alg->encrypt; | 422 | crt->encrypt = alg->encrypt; |
378 | crt->decrypt = alg->decrypt; | 423 | crt->decrypt = alg->decrypt; |
@@ -385,8 +430,23 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
385 | return 0; | 430 | return 0; |
386 | } | 431 | } |
387 | 432 | ||
433 | static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | ||
434 | { | ||
435 | struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; | ||
436 | |||
437 | if (alg->ivsize > PAGE_SIZE / 8) | ||
438 | return -EINVAL; | ||
439 | |||
440 | type ^= CRYPTO_ALG_ASYNC; | ||
441 | mask &= CRYPTO_ALG_ASYNC; | ||
442 | if (type & mask) | ||
443 | return crypto_init_blkcipher_ops_sync(tfm); | ||
444 | else | ||
445 | return crypto_init_blkcipher_ops_async(tfm); | ||
446 | } | ||
447 | |||
388 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 448 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
389 | __attribute_used__; | 449 | __attribute__ ((unused)); |
390 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 450 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
391 | { | 451 | { |
392 | seq_printf(m, "type : blkcipher\n"); | 452 | seq_printf(m, "type : blkcipher\n"); |
diff --git a/crypto/cbc.c b/crypto/cbc.c index 136fea7e7000..1f2649e13b42 100644 --- a/crypto/cbc.c +++ b/crypto/cbc.c | |||
@@ -275,13 +275,18 @@ static void crypto_cbc_exit_tfm(struct crypto_tfm *tfm) | |||
275 | crypto_free_cipher(ctx->child); | 275 | crypto_free_cipher(ctx->child); |
276 | } | 276 | } |
277 | 277 | ||
278 | static struct crypto_instance *crypto_cbc_alloc(void *param, unsigned int len) | 278 | static struct crypto_instance *crypto_cbc_alloc(struct rtattr **tb) |
279 | { | 279 | { |
280 | struct crypto_instance *inst; | 280 | struct crypto_instance *inst; |
281 | struct crypto_alg *alg; | 281 | struct crypto_alg *alg; |
282 | int err; | ||
283 | |||
284 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); | ||
285 | if (err) | ||
286 | return ERR_PTR(err); | ||
282 | 287 | ||
283 | alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, | 288 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, |
284 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | 289 | CRYPTO_ALG_TYPE_MASK); |
285 | if (IS_ERR(alg)) | 290 | if (IS_ERR(alg)) |
286 | return ERR_PTR(PTR_ERR(alg)); | 291 | return ERR_PTR(PTR_ERR(alg)); |
287 | 292 | ||
diff --git a/crypto/cryptd.c b/crypto/cryptd.c new file mode 100644 index 000000000000..3ff4e1f0f032 --- /dev/null +++ b/crypto/cryptd.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | * Software async crypto daemon. | ||
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 <crypto/algapi.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/kthread.h> | ||
18 | #include <linux/list.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/scatterlist.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | |||
26 | #define CRYPTD_MAX_QLEN 100 | ||
27 | |||
28 | struct cryptd_state { | ||
29 | spinlock_t lock; | ||
30 | struct mutex mutex; | ||
31 | struct crypto_queue queue; | ||
32 | struct task_struct *task; | ||
33 | }; | ||
34 | |||
35 | struct cryptd_instance_ctx { | ||
36 | struct crypto_spawn spawn; | ||
37 | struct cryptd_state *state; | ||
38 | }; | ||
39 | |||
40 | struct cryptd_blkcipher_ctx { | ||
41 | struct crypto_blkcipher *child; | ||
42 | }; | ||
43 | |||
44 | struct cryptd_blkcipher_request_ctx { | ||
45 | crypto_completion_t complete; | ||
46 | }; | ||
47 | |||
48 | |||
49 | static inline struct cryptd_state *cryptd_get_state(struct crypto_tfm *tfm) | ||
50 | { | ||
51 | struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); | ||
52 | struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst); | ||
53 | return ictx->state; | ||
54 | } | ||
55 | |||
56 | static int cryptd_blkcipher_setkey(struct crypto_ablkcipher *parent, | ||
57 | const u8 *key, unsigned int keylen) | ||
58 | { | ||
59 | struct cryptd_blkcipher_ctx *ctx = crypto_ablkcipher_ctx(parent); | ||
60 | struct crypto_blkcipher *child = ctx->child; | ||
61 | int err; | ||
62 | |||
63 | crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); | ||
64 | crypto_blkcipher_set_flags(child, crypto_ablkcipher_get_flags(parent) & | ||
65 | CRYPTO_TFM_REQ_MASK); | ||
66 | err = crypto_blkcipher_setkey(child, key, keylen); | ||
67 | crypto_ablkcipher_set_flags(parent, crypto_blkcipher_get_flags(child) & | ||
68 | CRYPTO_TFM_RES_MASK); | ||
69 | return err; | ||
70 | } | ||
71 | |||
72 | static void cryptd_blkcipher_crypt(struct ablkcipher_request *req, | ||
73 | struct crypto_blkcipher *child, | ||
74 | int err, | ||
75 | int (*crypt)(struct blkcipher_desc *desc, | ||
76 | struct scatterlist *dst, | ||
77 | struct scatterlist *src, | ||
78 | unsigned int len)) | ||
79 | { | ||
80 | struct cryptd_blkcipher_request_ctx *rctx; | ||
81 | struct blkcipher_desc desc; | ||
82 | |||
83 | rctx = ablkcipher_request_ctx(req); | ||
84 | |||
85 | if (unlikely(err == -EINPROGRESS)) { | ||
86 | rctx->complete(&req->base, err); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | desc.tfm = child; | ||
91 | desc.info = req->info; | ||
92 | desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
93 | |||
94 | err = crypt(&desc, req->dst, req->src, req->nbytes); | ||
95 | |||
96 | req->base.complete = rctx->complete; | ||
97 | |||
98 | local_bh_disable(); | ||
99 | req->base.complete(&req->base, err); | ||
100 | local_bh_enable(); | ||
101 | } | ||
102 | |||
103 | static void cryptd_blkcipher_encrypt(struct crypto_async_request *req, int err) | ||
104 | { | ||
105 | struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(req->tfm); | ||
106 | struct crypto_blkcipher *child = ctx->child; | ||
107 | |||
108 | cryptd_blkcipher_crypt(ablkcipher_request_cast(req), child, err, | ||
109 | crypto_blkcipher_crt(child)->encrypt); | ||
110 | } | ||
111 | |||
112 | static void cryptd_blkcipher_decrypt(struct crypto_async_request *req, int err) | ||
113 | { | ||
114 | struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(req->tfm); | ||
115 | struct crypto_blkcipher *child = ctx->child; | ||
116 | |||
117 | cryptd_blkcipher_crypt(ablkcipher_request_cast(req), child, err, | ||
118 | crypto_blkcipher_crt(child)->decrypt); | ||
119 | } | ||
120 | |||
121 | static int cryptd_blkcipher_enqueue(struct ablkcipher_request *req, | ||
122 | crypto_completion_t complete) | ||
123 | { | ||
124 | struct cryptd_blkcipher_request_ctx *rctx = ablkcipher_request_ctx(req); | ||
125 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
126 | struct cryptd_state *state = | ||
127 | cryptd_get_state(crypto_ablkcipher_tfm(tfm)); | ||
128 | int err; | ||
129 | |||
130 | rctx->complete = req->base.complete; | ||
131 | req->base.complete = complete; | ||
132 | |||
133 | spin_lock_bh(&state->lock); | ||
134 | err = ablkcipher_enqueue_request(crypto_ablkcipher_alg(tfm), req); | ||
135 | spin_unlock_bh(&state->lock); | ||
136 | |||
137 | wake_up_process(state->task); | ||
138 | return err; | ||
139 | } | ||
140 | |||
141 | static int cryptd_blkcipher_encrypt_enqueue(struct ablkcipher_request *req) | ||
142 | { | ||
143 | return cryptd_blkcipher_enqueue(req, cryptd_blkcipher_encrypt); | ||
144 | } | ||
145 | |||
146 | static int cryptd_blkcipher_decrypt_enqueue(struct ablkcipher_request *req) | ||
147 | { | ||
148 | return cryptd_blkcipher_enqueue(req, cryptd_blkcipher_decrypt); | ||
149 | } | ||
150 | |||
151 | static int cryptd_blkcipher_init_tfm(struct crypto_tfm *tfm) | ||
152 | { | ||
153 | struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); | ||
154 | struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst); | ||
155 | struct crypto_spawn *spawn = &ictx->spawn; | ||
156 | struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(tfm); | ||
157 | struct crypto_blkcipher *cipher; | ||
158 | |||
159 | cipher = crypto_spawn_blkcipher(spawn); | ||
160 | if (IS_ERR(cipher)) | ||
161 | return PTR_ERR(cipher); | ||
162 | |||
163 | ctx->child = cipher; | ||
164 | tfm->crt_ablkcipher.reqsize = | ||
165 | sizeof(struct cryptd_blkcipher_request_ctx); | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm) | ||
170 | { | ||
171 | struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(tfm); | ||
172 | struct cryptd_state *state = cryptd_get_state(tfm); | ||
173 | int active; | ||
174 | |||
175 | mutex_lock(&state->mutex); | ||
176 | active = ablkcipher_tfm_in_queue(__crypto_ablkcipher_cast(tfm)); | ||
177 | mutex_unlock(&state->mutex); | ||
178 | |||
179 | BUG_ON(active); | ||
180 | |||
181 | crypto_free_blkcipher(ctx->child); | ||
182 | } | ||
183 | |||
184 | static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, | ||
185 | struct cryptd_state *state) | ||
186 | { | ||
187 | struct crypto_instance *inst; | ||
188 | struct cryptd_instance_ctx *ctx; | ||
189 | int err; | ||
190 | |||
191 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); | ||
192 | if (IS_ERR(inst)) | ||
193 | goto out; | ||
194 | |||
195 | err = -ENAMETOOLONG; | ||
196 | if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, | ||
197 | "cryptd(%s)", alg->cra_driver_name) >= CRYPTO_MAX_ALG_NAME) | ||
198 | goto out_free_inst; | ||
199 | |||
200 | ctx = crypto_instance_ctx(inst); | ||
201 | err = crypto_init_spawn(&ctx->spawn, alg, inst, | ||
202 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | ||
203 | if (err) | ||
204 | goto out_free_inst; | ||
205 | |||
206 | ctx->state = state; | ||
207 | |||
208 | memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); | ||
209 | |||
210 | inst->alg.cra_priority = alg->cra_priority + 50; | ||
211 | inst->alg.cra_blocksize = alg->cra_blocksize; | ||
212 | inst->alg.cra_alignmask = alg->cra_alignmask; | ||
213 | |||
214 | out: | ||
215 | return inst; | ||
216 | |||
217 | out_free_inst: | ||
218 | kfree(inst); | ||
219 | inst = ERR_PTR(err); | ||
220 | goto out; | ||
221 | } | ||
222 | |||
223 | static struct crypto_instance *cryptd_alloc_blkcipher( | ||
224 | struct rtattr **tb, struct cryptd_state *state) | ||
225 | { | ||
226 | struct crypto_instance *inst; | ||
227 | struct crypto_alg *alg; | ||
228 | |||
229 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_BLKCIPHER, | ||
230 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | ||
231 | if (IS_ERR(alg)) | ||
232 | return ERR_PTR(PTR_ERR(alg)); | ||
233 | |||
234 | inst = cryptd_alloc_instance(alg, state); | ||
235 | if (IS_ERR(inst)) | ||
236 | goto out_put_alg; | ||
237 | |||
238 | inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_ASYNC; | ||
239 | inst->alg.cra_type = &crypto_ablkcipher_type; | ||
240 | |||
241 | inst->alg.cra_ablkcipher.ivsize = alg->cra_blkcipher.ivsize; | ||
242 | inst->alg.cra_ablkcipher.min_keysize = alg->cra_blkcipher.min_keysize; | ||
243 | inst->alg.cra_ablkcipher.max_keysize = alg->cra_blkcipher.max_keysize; | ||
244 | |||
245 | inst->alg.cra_ctxsize = sizeof(struct cryptd_blkcipher_ctx); | ||
246 | |||
247 | inst->alg.cra_init = cryptd_blkcipher_init_tfm; | ||
248 | inst->alg.cra_exit = cryptd_blkcipher_exit_tfm; | ||
249 | |||
250 | inst->alg.cra_ablkcipher.setkey = cryptd_blkcipher_setkey; | ||
251 | inst->alg.cra_ablkcipher.encrypt = cryptd_blkcipher_encrypt_enqueue; | ||
252 | inst->alg.cra_ablkcipher.decrypt = cryptd_blkcipher_decrypt_enqueue; | ||
253 | |||
254 | inst->alg.cra_ablkcipher.queue = &state->queue; | ||
255 | |||
256 | out_put_alg: | ||
257 | crypto_mod_put(alg); | ||
258 | return inst; | ||
259 | } | ||
260 | |||
261 | static struct cryptd_state state; | ||
262 | |||
263 | static struct crypto_instance *cryptd_alloc(struct rtattr **tb) | ||
264 | { | ||
265 | struct crypto_attr_type *algt; | ||
266 | |||
267 | algt = crypto_get_attr_type(tb); | ||
268 | if (IS_ERR(algt)) | ||
269 | return ERR_PTR(PTR_ERR(algt)); | ||
270 | |||
271 | switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) { | ||
272 | case CRYPTO_ALG_TYPE_BLKCIPHER: | ||
273 | return cryptd_alloc_blkcipher(tb, &state); | ||
274 | } | ||
275 | |||
276 | return ERR_PTR(-EINVAL); | ||
277 | } | ||
278 | |||
279 | static void cryptd_free(struct crypto_instance *inst) | ||
280 | { | ||
281 | struct cryptd_instance_ctx *ctx = crypto_instance_ctx(inst); | ||
282 | |||
283 | crypto_drop_spawn(&ctx->spawn); | ||
284 | kfree(inst); | ||
285 | } | ||
286 | |||
287 | static struct crypto_template cryptd_tmpl = { | ||
288 | .name = "cryptd", | ||
289 | .alloc = cryptd_alloc, | ||
290 | .free = cryptd_free, | ||
291 | .module = THIS_MODULE, | ||
292 | }; | ||
293 | |||
294 | static inline int cryptd_create_thread(struct cryptd_state *state, | ||
295 | int (*fn)(void *data), const char *name) | ||
296 | { | ||
297 | spin_lock_init(&state->lock); | ||
298 | mutex_init(&state->mutex); | ||
299 | crypto_init_queue(&state->queue, CRYPTD_MAX_QLEN); | ||
300 | |||
301 | state->task = kthread_create(fn, state, name); | ||
302 | if (IS_ERR(state->task)) | ||
303 | return PTR_ERR(state->task); | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static inline void cryptd_stop_thread(struct cryptd_state *state) | ||
309 | { | ||
310 | BUG_ON(state->queue.qlen); | ||
311 | kthread_stop(state->task); | ||
312 | } | ||
313 | |||
314 | static int cryptd_thread(void *data) | ||
315 | { | ||
316 | struct cryptd_state *state = data; | ||
317 | int stop; | ||
318 | |||
319 | do { | ||
320 | struct crypto_async_request *req, *backlog; | ||
321 | |||
322 | mutex_lock(&state->mutex); | ||
323 | __set_current_state(TASK_INTERRUPTIBLE); | ||
324 | |||
325 | spin_lock_bh(&state->lock); | ||
326 | backlog = crypto_get_backlog(&state->queue); | ||
327 | req = crypto_dequeue_request(&state->queue); | ||
328 | spin_unlock_bh(&state->lock); | ||
329 | |||
330 | stop = kthread_should_stop(); | ||
331 | |||
332 | if (stop || req) { | ||
333 | __set_current_state(TASK_RUNNING); | ||
334 | if (req) { | ||
335 | if (backlog) | ||
336 | backlog->complete(backlog, | ||
337 | -EINPROGRESS); | ||
338 | req->complete(req, 0); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | mutex_unlock(&state->mutex); | ||
343 | |||
344 | schedule(); | ||
345 | } while (!stop); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int __init cryptd_init(void) | ||
351 | { | ||
352 | int err; | ||
353 | |||
354 | err = cryptd_create_thread(&state, cryptd_thread, "cryptd"); | ||
355 | if (err) | ||
356 | return err; | ||
357 | |||
358 | err = crypto_register_template(&cryptd_tmpl); | ||
359 | if (err) | ||
360 | kthread_stop(state.task); | ||
361 | |||
362 | return err; | ||
363 | } | ||
364 | |||
365 | static void __exit cryptd_exit(void) | ||
366 | { | ||
367 | cryptd_stop_thread(&state); | ||
368 | crypto_unregister_template(&cryptd_tmpl); | ||
369 | } | ||
370 | |||
371 | module_init(cryptd_init); | ||
372 | module_exit(cryptd_exit); | ||
373 | |||
374 | MODULE_LICENSE("GPL"); | ||
375 | MODULE_DESCRIPTION("Software async crypto daemon"); | ||
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c index 2ebffb84f1d9..6958ea83ee44 100644 --- a/crypto/cryptomgr.c +++ b/crypto/cryptomgr.c | |||
@@ -14,17 +14,24 @@ | |||
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/kthread.h> | ||
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
18 | #include <linux/notifier.h> | 19 | #include <linux/notifier.h> |
19 | #include <linux/rtnetlink.h> | 20 | #include <linux/rtnetlink.h> |
20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
21 | #include <linux/string.h> | 22 | #include <linux/string.h> |
22 | #include <linux/workqueue.h> | ||
23 | 23 | ||
24 | #include "internal.h" | 24 | #include "internal.h" |
25 | 25 | ||
26 | struct cryptomgr_param { | 26 | struct cryptomgr_param { |
27 | struct work_struct work; | 27 | struct task_struct *thread; |
28 | |||
29 | struct rtattr *tb[CRYPTOA_MAX]; | ||
30 | |||
31 | struct { | ||
32 | struct rtattr attr; | ||
33 | struct crypto_attr_type data; | ||
34 | } type; | ||
28 | 35 | ||
29 | struct { | 36 | struct { |
30 | struct rtattr attr; | 37 | struct rtattr attr; |
@@ -32,18 +39,15 @@ struct cryptomgr_param { | |||
32 | } alg; | 39 | } alg; |
33 | 40 | ||
34 | struct { | 41 | struct { |
35 | u32 type; | ||
36 | u32 mask; | ||
37 | char name[CRYPTO_MAX_ALG_NAME]; | 42 | char name[CRYPTO_MAX_ALG_NAME]; |
38 | } larval; | 43 | } larval; |
39 | 44 | ||
40 | char template[CRYPTO_MAX_ALG_NAME]; | 45 | char template[CRYPTO_MAX_ALG_NAME]; |
41 | }; | 46 | }; |
42 | 47 | ||
43 | static void cryptomgr_probe(struct work_struct *work) | 48 | static int cryptomgr_probe(void *data) |
44 | { | 49 | { |
45 | struct cryptomgr_param *param = | 50 | struct cryptomgr_param *param = data; |
46 | container_of(work, struct cryptomgr_param, work); | ||
47 | struct crypto_template *tmpl; | 51 | struct crypto_template *tmpl; |
48 | struct crypto_instance *inst; | 52 | struct crypto_instance *inst; |
49 | int err; | 53 | int err; |
@@ -53,7 +57,7 @@ static void cryptomgr_probe(struct work_struct *work) | |||
53 | goto err; | 57 | goto err; |
54 | 58 | ||
55 | do { | 59 | do { |
56 | inst = tmpl->alloc(¶m->alg, sizeof(param->alg)); | 60 | inst = tmpl->alloc(param->tb); |
57 | if (IS_ERR(inst)) | 61 | if (IS_ERR(inst)) |
58 | err = PTR_ERR(inst); | 62 | err = PTR_ERR(inst); |
59 | else if ((err = crypto_register_instance(tmpl, inst))) | 63 | else if ((err = crypto_register_instance(tmpl, inst))) |
@@ -67,11 +71,11 @@ static void cryptomgr_probe(struct work_struct *work) | |||
67 | 71 | ||
68 | out: | 72 | out: |
69 | kfree(param); | 73 | kfree(param); |
70 | return; | 74 | module_put_and_exit(0); |
71 | 75 | ||
72 | err: | 76 | err: |
73 | crypto_larval_error(param->larval.name, param->larval.type, | 77 | crypto_larval_error(param->larval.name, param->type.data.type, |
74 | param->larval.mask); | 78 | param->type.data.mask); |
75 | goto out; | 79 | goto out; |
76 | } | 80 | } |
77 | 81 | ||
@@ -82,10 +86,13 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) | |||
82 | const char *p; | 86 | const char *p; |
83 | unsigned int len; | 87 | unsigned int len; |
84 | 88 | ||
85 | param = kmalloc(sizeof(*param), GFP_KERNEL); | 89 | if (!try_module_get(THIS_MODULE)) |
86 | if (!param) | ||
87 | goto err; | 90 | goto err; |
88 | 91 | ||
92 | param = kzalloc(sizeof(*param), GFP_KERNEL); | ||
93 | if (!param) | ||
94 | goto err_put_module; | ||
95 | |||
89 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) | 96 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) |
90 | ; | 97 | ; |
91 | 98 | ||
@@ -94,32 +101,45 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) | |||
94 | goto err_free_param; | 101 | goto err_free_param; |
95 | 102 | ||
96 | memcpy(param->template, name, len); | 103 | memcpy(param->template, name, len); |
97 | param->template[len] = 0; | ||
98 | 104 | ||
99 | name = p + 1; | 105 | name = p + 1; |
100 | for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) | 106 | len = 0; |
101 | ; | 107 | for (p = name; *p; p++) { |
108 | for (; isalnum(*p) || *p == '-' || *p == '_' || *p == '('; p++) | ||
109 | ; | ||
102 | 110 | ||
103 | len = p - name; | 111 | if (*p != ')') |
104 | if (!len || *p != ')' || p[1]) | 112 | goto err_free_param; |
113 | |||
114 | len = p - name; | ||
115 | } | ||
116 | |||
117 | if (!len || name[len + 1]) | ||
105 | goto err_free_param; | 118 | goto err_free_param; |
106 | 119 | ||
120 | param->type.attr.rta_len = sizeof(param->type); | ||
121 | param->type.attr.rta_type = CRYPTOA_TYPE; | ||
122 | param->type.data.type = larval->alg.cra_flags; | ||
123 | param->type.data.mask = larval->mask; | ||
124 | param->tb[CRYPTOA_TYPE - 1] = ¶m->type.attr; | ||
125 | |||
107 | param->alg.attr.rta_len = sizeof(param->alg); | 126 | param->alg.attr.rta_len = sizeof(param->alg); |
108 | param->alg.attr.rta_type = CRYPTOA_ALG; | 127 | param->alg.attr.rta_type = CRYPTOA_ALG; |
109 | memcpy(param->alg.data.name, name, len); | 128 | memcpy(param->alg.data.name, name, len); |
110 | param->alg.data.name[len] = 0; | 129 | param->tb[CRYPTOA_ALG - 1] = ¶m->alg.attr; |
111 | 130 | ||
112 | memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); | 131 | memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); |
113 | param->larval.type = larval->alg.cra_flags; | ||
114 | param->larval.mask = larval->mask; | ||
115 | 132 | ||
116 | INIT_WORK(¶m->work, cryptomgr_probe); | 133 | param->thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); |
117 | schedule_work(¶m->work); | 134 | if (IS_ERR(param->thread)) |
135 | goto err_free_param; | ||
118 | 136 | ||
119 | return NOTIFY_STOP; | 137 | return NOTIFY_STOP; |
120 | 138 | ||
121 | err_free_param: | 139 | err_free_param: |
122 | kfree(param); | 140 | kfree(param); |
141 | err_put_module: | ||
142 | module_put(THIS_MODULE); | ||
123 | err: | 143 | err: |
124 | return NOTIFY_OK; | 144 | return NOTIFY_OK; |
125 | } | 145 | } |
diff --git a/crypto/ecb.c b/crypto/ecb.c index 839a0aed8c22..6310387a872c 100644 --- a/crypto/ecb.c +++ b/crypto/ecb.c | |||
@@ -115,13 +115,18 @@ static void crypto_ecb_exit_tfm(struct crypto_tfm *tfm) | |||
115 | crypto_free_cipher(ctx->child); | 115 | crypto_free_cipher(ctx->child); |
116 | } | 116 | } |
117 | 117 | ||
118 | static struct crypto_instance *crypto_ecb_alloc(void *param, unsigned int len) | 118 | static struct crypto_instance *crypto_ecb_alloc(struct rtattr **tb) |
119 | { | 119 | { |
120 | struct crypto_instance *inst; | 120 | struct crypto_instance *inst; |
121 | struct crypto_alg *alg; | 121 | struct crypto_alg *alg; |
122 | int err; | ||
123 | |||
124 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); | ||
125 | if (err) | ||
126 | return ERR_PTR(err); | ||
122 | 127 | ||
123 | alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, | 128 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, |
124 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | 129 | CRYPTO_ALG_TYPE_MASK); |
125 | if (IS_ERR(alg)) | 130 | if (IS_ERR(alg)) |
126 | return ERR_PTR(PTR_ERR(alg)); | 131 | return ERR_PTR(PTR_ERR(alg)); |
127 | 132 | ||
diff --git a/crypto/hash.c b/crypto/hash.c index 12c4514f3478..4ccd22deef39 100644 --- a/crypto/hash.c +++ b/crypto/hash.c | |||
@@ -41,7 +41,7 @@ static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
41 | } | 41 | } |
42 | 42 | ||
43 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | 43 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) |
44 | __attribute_used__; | 44 | __attribute__ ((unused)); |
45 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) | 45 | static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) |
46 | { | 46 | { |
47 | seq_printf(m, "type : hash\n"); | 47 | seq_printf(m, "type : hash\n"); |
diff --git a/crypto/hmac.c b/crypto/hmac.c index 44187c5ee593..8802fb6dd5a6 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c | |||
@@ -197,13 +197,18 @@ static void hmac_free(struct crypto_instance *inst) | |||
197 | kfree(inst); | 197 | kfree(inst); |
198 | } | 198 | } |
199 | 199 | ||
200 | static struct crypto_instance *hmac_alloc(void *param, unsigned int len) | 200 | static struct crypto_instance *hmac_alloc(struct rtattr **tb) |
201 | { | 201 | { |
202 | struct crypto_instance *inst; | 202 | struct crypto_instance *inst; |
203 | struct crypto_alg *alg; | 203 | struct crypto_alg *alg; |
204 | int err; | ||
205 | |||
206 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH); | ||
207 | if (err) | ||
208 | return ERR_PTR(err); | ||
204 | 209 | ||
205 | alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_HASH, | 210 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_HASH, |
206 | CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC); | 211 | CRYPTO_ALG_TYPE_HASH_MASK); |
207 | if (IS_ERR(alg)) | 212 | if (IS_ERR(alg)) |
208 | return ERR_PTR(PTR_ERR(alg)); | 213 | return ERR_PTR(PTR_ERR(alg)); |
209 | 214 | ||
diff --git a/crypto/lrw.c b/crypto/lrw.c index b4105080ac7a..621095db28b3 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c | |||
@@ -228,13 +228,18 @@ static void exit_tfm(struct crypto_tfm *tfm) | |||
228 | crypto_free_cipher(ctx->child); | 228 | crypto_free_cipher(ctx->child); |
229 | } | 229 | } |
230 | 230 | ||
231 | static struct crypto_instance *alloc(void *param, unsigned int len) | 231 | static struct crypto_instance *alloc(struct rtattr **tb) |
232 | { | 232 | { |
233 | struct crypto_instance *inst; | 233 | struct crypto_instance *inst; |
234 | struct crypto_alg *alg; | 234 | struct crypto_alg *alg; |
235 | int err; | ||
236 | |||
237 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); | ||
238 | if (err) | ||
239 | return ERR_PTR(err); | ||
235 | 240 | ||
236 | alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, | 241 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, |
237 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | 242 | CRYPTO_ALG_TYPE_MASK); |
238 | if (IS_ERR(alg)) | 243 | if (IS_ERR(alg)) |
239 | return ERR_PTR(PTR_ERR(alg)); | 244 | return ERR_PTR(PTR_ERR(alg)); |
240 | 245 | ||
diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c index 094397b48849..9e917b8011b1 100644 --- a/crypto/michael_mic.c +++ b/crypto/michael_mic.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Michael MIC (IEEE 802.11i/TKIP) keyed digest | 4 | * Michael MIC (IEEE 802.11i/TKIP) keyed digest |
5 | * | 5 | * |
6 | * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi> | 6 | * Copyright (c) 2004 Jouni Malinen <j@w1.fi> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -173,4 +173,4 @@ module_exit(michael_mic_exit); | |||
173 | 173 | ||
174 | MODULE_LICENSE("GPL v2"); | 174 | MODULE_LICENSE("GPL v2"); |
175 | MODULE_DESCRIPTION("Michael MIC"); | 175 | MODULE_DESCRIPTION("Michael MIC"); |
176 | MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>"); | 176 | MODULE_AUTHOR("Jouni Malinen <j@w1.fi>"); |
diff --git a/crypto/pcbc.c b/crypto/pcbc.c index 5174d7fdad6e..c3ed8a1c9f46 100644 --- a/crypto/pcbc.c +++ b/crypto/pcbc.c | |||
@@ -279,13 +279,18 @@ static void crypto_pcbc_exit_tfm(struct crypto_tfm *tfm) | |||
279 | crypto_free_cipher(ctx->child); | 279 | crypto_free_cipher(ctx->child); |
280 | } | 280 | } |
281 | 281 | ||
282 | static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len) | 282 | static struct crypto_instance *crypto_pcbc_alloc(struct rtattr **tb) |
283 | { | 283 | { |
284 | struct crypto_instance *inst; | 284 | struct crypto_instance *inst; |
285 | struct crypto_alg *alg; | 285 | struct crypto_alg *alg; |
286 | int err; | ||
287 | |||
288 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); | ||
289 | if (err) | ||
290 | return ERR_PTR(err); | ||
286 | 291 | ||
287 | alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, | 292 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, |
288 | CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); | 293 | CRYPTO_ALG_TYPE_MASK); |
289 | if (IS_ERR(alg)) | 294 | if (IS_ERR(alg)) |
290 | return ERR_PTR(PTR_ERR(alg)); | 295 | return ERR_PTR(PTR_ERR(alg)); |
291 | 296 | ||
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 35172d3f043b..81afd1790a1d 100644 --- a/crypto/scatterwalk.c +++ b/crypto/scatterwalk.c | |||
@@ -59,8 +59,12 @@ EXPORT_SYMBOL_GPL(scatterwalk_map); | |||
59 | static void scatterwalk_pagedone(struct scatter_walk *walk, int out, | 59 | static void scatterwalk_pagedone(struct scatter_walk *walk, int out, |
60 | unsigned int more) | 60 | unsigned int more) |
61 | { | 61 | { |
62 | if (out) | 62 | if (out) { |
63 | flush_dcache_page(scatterwalk_page(walk)); | 63 | struct page *page; |
64 | |||
65 | page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT); | ||
66 | flush_dcache_page(page); | ||
67 | } | ||
64 | 68 | ||
65 | if (more) { | 69 | if (more) { |
66 | walk->offset += PAGE_SIZE - 1; | 70 | walk->offset += PAGE_SIZE - 1; |
@@ -91,6 +95,8 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk, | |||
91 | memcpy_dir(buf, vaddr, len_this_page, out); | 95 | memcpy_dir(buf, vaddr, len_this_page, out); |
92 | scatterwalk_unmap(vaddr, out); | 96 | scatterwalk_unmap(vaddr, out); |
93 | 97 | ||
98 | scatterwalk_advance(walk, len_this_page); | ||
99 | |||
94 | if (nbytes == len_this_page) | 100 | if (nbytes == len_this_page) |
95 | break; | 101 | break; |
96 | 102 | ||
@@ -99,7 +105,5 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk, | |||
99 | 105 | ||
100 | scatterwalk_pagedone(walk, out, 1); | 106 | scatterwalk_pagedone(walk, out, 1); |
101 | } | 107 | } |
102 | |||
103 | scatterwalk_advance(walk, nbytes); | ||
104 | } | 108 | } |
105 | EXPORT_SYMBOL_GPL(scatterwalk_copychunks); | 109 | EXPORT_SYMBOL_GPL(scatterwalk_copychunks); |
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index f5e9da319ece..f0aed0106adb 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c | |||
@@ -57,6 +57,11 @@ | |||
57 | #define ENCRYPT 1 | 57 | #define ENCRYPT 1 |
58 | #define DECRYPT 0 | 58 | #define DECRYPT 0 |
59 | 59 | ||
60 | struct tcrypt_result { | ||
61 | struct completion completion; | ||
62 | int err; | ||
63 | }; | ||
64 | |||
60 | static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; | 65 | static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; |
61 | 66 | ||
62 | /* | 67 | /* |
@@ -84,6 +89,17 @@ static void hexdump(unsigned char *buf, unsigned int len) | |||
84 | printk("\n"); | 89 | printk("\n"); |
85 | } | 90 | } |
86 | 91 | ||
92 | static void tcrypt_complete(struct crypto_async_request *req, int err) | ||
93 | { | ||
94 | struct tcrypt_result *res = req->data; | ||
95 | |||
96 | if (err == -EINPROGRESS) | ||
97 | return; | ||
98 | |||
99 | res->err = err; | ||
100 | complete(&res->completion); | ||
101 | } | ||
102 | |||
87 | static void test_hash(char *algo, struct hash_testvec *template, | 103 | static void test_hash(char *algo, struct hash_testvec *template, |
88 | unsigned int tcount) | 104 | unsigned int tcount) |
89 | { | 105 | { |
@@ -203,15 +219,14 @@ static void test_cipher(char *algo, int enc, | |||
203 | { | 219 | { |
204 | unsigned int ret, i, j, k, temp; | 220 | unsigned int ret, i, j, k, temp; |
205 | unsigned int tsize; | 221 | unsigned int tsize; |
206 | unsigned int iv_len; | ||
207 | unsigned int len; | ||
208 | char *q; | 222 | char *q; |
209 | struct crypto_blkcipher *tfm; | 223 | struct crypto_ablkcipher *tfm; |
210 | char *key; | 224 | char *key; |
211 | struct cipher_testvec *cipher_tv; | 225 | struct cipher_testvec *cipher_tv; |
212 | struct blkcipher_desc desc; | 226 | struct ablkcipher_request *req; |
213 | struct scatterlist sg[8]; | 227 | struct scatterlist sg[8]; |
214 | const char *e; | 228 | const char *e; |
229 | struct tcrypt_result result; | ||
215 | 230 | ||
216 | if (enc == ENCRYPT) | 231 | if (enc == ENCRYPT) |
217 | e = "encryption"; | 232 | e = "encryption"; |
@@ -232,15 +247,24 @@ static void test_cipher(char *algo, int enc, | |||
232 | memcpy(tvmem, template, tsize); | 247 | memcpy(tvmem, template, tsize); |
233 | cipher_tv = (void *)tvmem; | 248 | cipher_tv = (void *)tvmem; |
234 | 249 | ||
235 | tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC); | 250 | init_completion(&result.completion); |
251 | |||
252 | tfm = crypto_alloc_ablkcipher(algo, 0, 0); | ||
236 | 253 | ||
237 | if (IS_ERR(tfm)) { | 254 | if (IS_ERR(tfm)) { |
238 | printk("failed to load transform for %s: %ld\n", algo, | 255 | printk("failed to load transform for %s: %ld\n", algo, |
239 | PTR_ERR(tfm)); | 256 | PTR_ERR(tfm)); |
240 | return; | 257 | return; |
241 | } | 258 | } |
242 | desc.tfm = tfm; | 259 | |
243 | desc.flags = 0; | 260 | req = ablkcipher_request_alloc(tfm, GFP_KERNEL); |
261 | if (!req) { | ||
262 | printk("failed to allocate request for %s\n", algo); | ||
263 | goto out; | ||
264 | } | ||
265 | |||
266 | ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
267 | tcrypt_complete, &result); | ||
244 | 268 | ||
245 | j = 0; | 269 | j = 0; |
246 | for (i = 0; i < tcount; i++) { | 270 | for (i = 0; i < tcount; i++) { |
@@ -249,17 +273,17 @@ static void test_cipher(char *algo, int enc, | |||
249 | printk("test %u (%d bit key):\n", | 273 | printk("test %u (%d bit key):\n", |
250 | j, cipher_tv[i].klen * 8); | 274 | j, cipher_tv[i].klen * 8); |
251 | 275 | ||
252 | crypto_blkcipher_clear_flags(tfm, ~0); | 276 | crypto_ablkcipher_clear_flags(tfm, ~0); |
253 | if (cipher_tv[i].wk) | 277 | if (cipher_tv[i].wk) |
254 | crypto_blkcipher_set_flags( | 278 | crypto_ablkcipher_set_flags( |
255 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); | 279 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
256 | key = cipher_tv[i].key; | 280 | key = cipher_tv[i].key; |
257 | 281 | ||
258 | ret = crypto_blkcipher_setkey(tfm, key, | 282 | ret = crypto_ablkcipher_setkey(tfm, key, |
259 | cipher_tv[i].klen); | 283 | cipher_tv[i].klen); |
260 | if (ret) { | 284 | if (ret) { |
261 | printk("setkey() failed flags=%x\n", | 285 | printk("setkey() failed flags=%x\n", |
262 | crypto_blkcipher_get_flags(tfm)); | 286 | crypto_ablkcipher_get_flags(tfm)); |
263 | 287 | ||
264 | if (!cipher_tv[i].fail) | 288 | if (!cipher_tv[i].fail) |
265 | goto out; | 289 | goto out; |
@@ -268,19 +292,28 @@ static void test_cipher(char *algo, int enc, | |||
268 | sg_set_buf(&sg[0], cipher_tv[i].input, | 292 | sg_set_buf(&sg[0], cipher_tv[i].input, |
269 | cipher_tv[i].ilen); | 293 | cipher_tv[i].ilen); |
270 | 294 | ||
271 | iv_len = crypto_blkcipher_ivsize(tfm); | 295 | ablkcipher_request_set_crypt(req, sg, sg, |
272 | if (iv_len) | 296 | cipher_tv[i].ilen, |
273 | crypto_blkcipher_set_iv(tfm, cipher_tv[i].iv, | 297 | cipher_tv[i].iv); |
274 | iv_len); | ||
275 | 298 | ||
276 | len = cipher_tv[i].ilen; | ||
277 | ret = enc ? | 299 | ret = enc ? |
278 | crypto_blkcipher_encrypt(&desc, sg, sg, len) : | 300 | crypto_ablkcipher_encrypt(req) : |
279 | crypto_blkcipher_decrypt(&desc, sg, sg, len); | 301 | crypto_ablkcipher_decrypt(req); |
280 | 302 | ||
281 | if (ret) { | 303 | switch (ret) { |
282 | printk("%s () failed flags=%x\n", e, | 304 | case 0: |
283 | desc.flags); | 305 | break; |
306 | case -EINPROGRESS: | ||
307 | case -EBUSY: | ||
308 | ret = wait_for_completion_interruptible( | ||
309 | &result.completion); | ||
310 | if (!ret && !((ret = result.err))) { | ||
311 | INIT_COMPLETION(result.completion); | ||
312 | break; | ||
313 | } | ||
314 | /* fall through */ | ||
315 | default: | ||
316 | printk("%s () failed err=%d\n", e, -ret); | ||
284 | goto out; | 317 | goto out; |
285 | } | 318 | } |
286 | 319 | ||
@@ -303,17 +336,17 @@ static void test_cipher(char *algo, int enc, | |||
303 | printk("test %u (%d bit key):\n", | 336 | printk("test %u (%d bit key):\n", |
304 | j, cipher_tv[i].klen * 8); | 337 | j, cipher_tv[i].klen * 8); |
305 | 338 | ||
306 | crypto_blkcipher_clear_flags(tfm, ~0); | 339 | crypto_ablkcipher_clear_flags(tfm, ~0); |
307 | if (cipher_tv[i].wk) | 340 | if (cipher_tv[i].wk) |
308 | crypto_blkcipher_set_flags( | 341 | crypto_ablkcipher_set_flags( |
309 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); | 342 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
310 | key = cipher_tv[i].key; | 343 | key = cipher_tv[i].key; |
311 | 344 | ||
312 | ret = crypto_blkcipher_setkey(tfm, key, | 345 | ret = crypto_ablkcipher_setkey(tfm, key, |
313 | cipher_tv[i].klen); | 346 | cipher_tv[i].klen); |
314 | if (ret) { | 347 | if (ret) { |
315 | printk("setkey() failed flags=%x\n", | 348 | printk("setkey() failed flags=%x\n", |
316 | crypto_blkcipher_get_flags(tfm)); | 349 | crypto_ablkcipher_get_flags(tfm)); |
317 | 350 | ||
318 | if (!cipher_tv[i].fail) | 351 | if (!cipher_tv[i].fail) |
319 | goto out; | 352 | goto out; |
@@ -329,19 +362,28 @@ static void test_cipher(char *algo, int enc, | |||
329 | cipher_tv[i].tap[k]); | 362 | cipher_tv[i].tap[k]); |
330 | } | 363 | } |
331 | 364 | ||
332 | iv_len = crypto_blkcipher_ivsize(tfm); | 365 | ablkcipher_request_set_crypt(req, sg, sg, |
333 | if (iv_len) | 366 | cipher_tv[i].ilen, |
334 | crypto_blkcipher_set_iv(tfm, cipher_tv[i].iv, | 367 | cipher_tv[i].iv); |
335 | iv_len); | ||
336 | 368 | ||
337 | len = cipher_tv[i].ilen; | ||
338 | ret = enc ? | 369 | ret = enc ? |
339 | crypto_blkcipher_encrypt(&desc, sg, sg, len) : | 370 | crypto_ablkcipher_encrypt(req) : |
340 | crypto_blkcipher_decrypt(&desc, sg, sg, len); | 371 | crypto_ablkcipher_decrypt(req); |
341 | 372 | ||
342 | if (ret) { | 373 | switch (ret) { |
343 | printk("%s () failed flags=%x\n", e, | 374 | case 0: |
344 | desc.flags); | 375 | break; |
376 | case -EINPROGRESS: | ||
377 | case -EBUSY: | ||
378 | ret = wait_for_completion_interruptible( | ||
379 | &result.completion); | ||
380 | if (!ret && !((ret = result.err))) { | ||
381 | INIT_COMPLETION(result.completion); | ||
382 | break; | ||
383 | } | ||
384 | /* fall through */ | ||
385 | default: | ||
386 | printk("%s () failed err=%d\n", e, -ret); | ||
345 | goto out; | 387 | goto out; |
346 | } | 388 | } |
347 | 389 | ||
@@ -360,7 +402,8 @@ static void test_cipher(char *algo, int enc, | |||
360 | } | 402 | } |
361 | 403 | ||
362 | out: | 404 | out: |
363 | crypto_free_blkcipher(tfm); | 405 | crypto_free_ablkcipher(tfm); |
406 | ablkcipher_request_free(req); | ||
364 | } | 407 | } |
365 | 408 | ||
366 | static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, | 409 | static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, |
@@ -768,7 +811,7 @@ static void test_deflate(void) | |||
768 | tv = (void *)tvmem; | 811 | tv = (void *)tvmem; |
769 | 812 | ||
770 | tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC); | 813 | tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC); |
771 | if (tfm == NULL) { | 814 | if (IS_ERR(tfm)) { |
772 | printk("failed to load transform for deflate\n"); | 815 | printk("failed to load transform for deflate\n"); |
773 | return; | 816 | return; |
774 | } | 817 | } |
@@ -832,7 +875,7 @@ static void test_available(void) | |||
832 | 875 | ||
833 | while (*name) { | 876 | while (*name) { |
834 | printk("alg %s ", *name); | 877 | printk("alg %s ", *name); |
835 | printk(crypto_has_alg(*name, 0, CRYPTO_ALG_ASYNC) ? | 878 | printk(crypto_has_alg(*name, 0, 0) ? |
836 | "found\n" : "not found\n"); | 879 | "found\n" : "not found\n"); |
837 | name++; | 880 | name++; |
838 | } | 881 | } |
diff --git a/crypto/xcbc.c b/crypto/xcbc.c index 53e8ccbf0f5f..9f502b86e0ea 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c | |||
@@ -288,12 +288,18 @@ static void xcbc_exit_tfm(struct crypto_tfm *tfm) | |||
288 | crypto_free_cipher(ctx->child); | 288 | crypto_free_cipher(ctx->child); |
289 | } | 289 | } |
290 | 290 | ||
291 | static struct crypto_instance *xcbc_alloc(void *param, unsigned int len) | 291 | static struct crypto_instance *xcbc_alloc(struct rtattr **tb) |
292 | { | 292 | { |
293 | struct crypto_instance *inst; | 293 | struct crypto_instance *inst; |
294 | struct crypto_alg *alg; | 294 | struct crypto_alg *alg; |
295 | alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, | 295 | int err; |
296 | CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC); | 296 | |
297 | err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH); | ||
298 | if (err) | ||
299 | return ERR_PTR(err); | ||
300 | |||
301 | alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, | ||
302 | CRYPTO_ALG_TYPE_MASK); | ||
297 | if (IS_ERR(alg)) | 303 | if (IS_ERR(alg)) |
298 | return ERR_PTR(PTR_ERR(alg)); | 304 | return ERR_PTR(PTR_ERR(alg)); |
299 | 305 | ||