diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-04 21:01:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-04 21:01:17 -0400 |
commit | 6adae5d9e69743aede91b274224751811f7174f1 (patch) | |
tree | 5ad15959313fbf4b7a37a36e40b04ca718b1e423 | |
parent | 253f04e78ded827c30f9582489773ebe2adc8924 (diff) | |
parent | f6259deacfd55607ae57cff422d3bc7694ea14e7 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6:
[CRYPTO] padlock: Remove pointless padlock module
[CRYPTO] api: Add ablkcipher_request_set_tfm
[CRYPTO] cryptd: Add software async crypto daemon
[CRYPTO] api: Do not remove users unless new algorithm matches
[CRYPTO] cryptomgr: Fix parsing of nested templates
[CRYPTO] api: Add async blkcipher type
[CRYPTO] templates: Pass type/mask when creating instances
[CRYPTO] tcrypt: Use async blkcipher interface
[CRYPTO] api: Add async block cipher interface
[CRYPTO] api: Proc functions should be marked as unused
-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/pcbc.c | 11 | ||||
-rw-r--r-- | crypto/tcrypt.c | 121 | ||||
-rw-r--r-- | crypto/xcbc.c | 12 | ||||
-rw-r--r-- | drivers/crypto/Kconfig | 16 | ||||
-rw-r--r-- | drivers/crypto/Makefile | 1 | ||||
-rw-r--r-- | drivers/crypto/padlock.c | 58 | ||||
-rw-r--r-- | include/crypto/algapi.h | 84 | ||||
-rw-r--r-- | include/linux/crypto.h | 236 |
20 files changed, 1166 insertions, 199 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/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/tcrypt.c b/crypto/tcrypt.c index 8eaa5aa210b0..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, |
@@ -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 | ||
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index ff8c4beaace4..f21fe66c9eef 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
@@ -1,10 +1,10 @@ | |||
1 | menu "Hardware crypto devices" | 1 | menu "Hardware crypto devices" |
2 | 2 | ||
3 | config CRYPTO_DEV_PADLOCK | 3 | config CRYPTO_DEV_PADLOCK |
4 | tristate "Support for VIA PadLock ACE" | 4 | bool "Support for VIA PadLock ACE" |
5 | depends on X86_32 | 5 | depends on X86_32 |
6 | select CRYPTO_ALGAPI | 6 | select CRYPTO_ALGAPI |
7 | default m | 7 | default y |
8 | help | 8 | help |
9 | Some VIA processors come with an integrated crypto engine | 9 | Some VIA processors come with an integrated crypto engine |
10 | (so called VIA PadLock ACE, Advanced Cryptography Engine) | 10 | (so called VIA PadLock ACE, Advanced Cryptography Engine) |
@@ -14,16 +14,6 @@ config CRYPTO_DEV_PADLOCK | |||
14 | The instructions are used only when the CPU supports them. | 14 | The instructions are used only when the CPU supports them. |
15 | Otherwise software encryption is used. | 15 | Otherwise software encryption is used. |
16 | 16 | ||
17 | Selecting M for this option will compile a helper module | ||
18 | padlock.ko that should autoload all below configured | ||
19 | algorithms. Don't worry if your hardware does not support | ||
20 | some or all of them. In such case padlock.ko will | ||
21 | simply write a single line into the kernel log informing | ||
22 | about its failure but everything will keep working fine. | ||
23 | |||
24 | If you are unsure, say M. The compiled module will be | ||
25 | called padlock.ko | ||
26 | |||
27 | config CRYPTO_DEV_PADLOCK_AES | 17 | config CRYPTO_DEV_PADLOCK_AES |
28 | tristate "PadLock driver for AES algorithm" | 18 | tristate "PadLock driver for AES algorithm" |
29 | depends on CRYPTO_DEV_PADLOCK | 19 | depends on CRYPTO_DEV_PADLOCK |
@@ -55,7 +45,7 @@ source "arch/s390/crypto/Kconfig" | |||
55 | 45 | ||
56 | config CRYPTO_DEV_GEODE | 46 | config CRYPTO_DEV_GEODE |
57 | tristate "Support for the Geode LX AES engine" | 47 | tristate "Support for the Geode LX AES engine" |
58 | depends on CRYPTO && X86_32 && PCI | 48 | depends on X86_32 && PCI |
59 | select CRYPTO_ALGAPI | 49 | select CRYPTO_ALGAPI |
60 | select CRYPTO_BLKCIPHER | 50 | select CRYPTO_BLKCIPHER |
61 | default m | 51 | default m |
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 6059cf869414..d070030f7d7e 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o | ||
2 | obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o | 1 | obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o |
3 | obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o | 2 | obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o |
4 | obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o | 3 | obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o |
diff --git a/drivers/crypto/padlock.c b/drivers/crypto/padlock.c deleted file mode 100644 index d6d7dd5bb98c..000000000000 --- a/drivers/crypto/padlock.c +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * Support for VIA PadLock hardware crypto engine. | ||
5 | * | ||
6 | * Copyright (c) 2006 Michal Ludvig <michal@logix.cz> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/crypto.h> | ||
19 | #include <linux/cryptohash.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/scatterlist.h> | ||
23 | #include "padlock.h" | ||
24 | |||
25 | static int __init padlock_init(void) | ||
26 | { | ||
27 | int success = 0; | ||
28 | |||
29 | if (crypto_has_cipher("aes-padlock", 0, 0)) | ||
30 | success++; | ||
31 | |||
32 | if (crypto_has_hash("sha1-padlock", 0, 0)) | ||
33 | success++; | ||
34 | |||
35 | if (crypto_has_hash("sha256-padlock", 0, 0)) | ||
36 | success++; | ||
37 | |||
38 | if (!success) { | ||
39 | printk(KERN_WARNING PFX "No VIA PadLock drivers have been loaded.\n"); | ||
40 | return -ENODEV; | ||
41 | } | ||
42 | |||
43 | printk(KERN_NOTICE PFX "%d drivers are available.\n", success); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static void __exit padlock_fini(void) | ||
49 | { | ||
50 | } | ||
51 | |||
52 | module_init(padlock_init); | ||
53 | module_exit(padlock_fini); | ||
54 | |||
55 | MODULE_DESCRIPTION("Load all configured PadLock algorithms."); | ||
56 | MODULE_LICENSE("GPL"); | ||
57 | MODULE_AUTHOR("Michal Ludvig"); | ||
58 | |||
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 4e05e93ff681..b2b1e6efd812 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h | |||
@@ -13,8 +13,11 @@ | |||
13 | #define _CRYPTO_ALGAPI_H | 13 | #define _CRYPTO_ALGAPI_H |
14 | 14 | ||
15 | #include <linux/crypto.h> | 15 | #include <linux/crypto.h> |
16 | #include <linux/list.h> | ||
17 | #include <linux/kernel.h> | ||
16 | 18 | ||
17 | struct module; | 19 | struct module; |
20 | struct rtattr; | ||
18 | struct seq_file; | 21 | struct seq_file; |
19 | 22 | ||
20 | struct crypto_type { | 23 | struct crypto_type { |
@@ -38,7 +41,7 @@ struct crypto_template { | |||
38 | struct hlist_head instances; | 41 | struct hlist_head instances; |
39 | struct module *module; | 42 | struct module *module; |
40 | 43 | ||
41 | struct crypto_instance *(*alloc)(void *param, unsigned int len); | 44 | struct crypto_instance *(*alloc)(struct rtattr **tb); |
42 | void (*free)(struct crypto_instance *inst); | 45 | void (*free)(struct crypto_instance *inst); |
43 | 46 | ||
44 | char name[CRYPTO_MAX_ALG_NAME]; | 47 | char name[CRYPTO_MAX_ALG_NAME]; |
@@ -48,6 +51,15 @@ struct crypto_spawn { | |||
48 | struct list_head list; | 51 | struct list_head list; |
49 | struct crypto_alg *alg; | 52 | struct crypto_alg *alg; |
50 | struct crypto_instance *inst; | 53 | struct crypto_instance *inst; |
54 | u32 mask; | ||
55 | }; | ||
56 | |||
57 | struct crypto_queue { | ||
58 | struct list_head list; | ||
59 | struct list_head *backlog; | ||
60 | |||
61 | unsigned int qlen; | ||
62 | unsigned int max_qlen; | ||
51 | }; | 63 | }; |
52 | 64 | ||
53 | struct scatter_walk { | 65 | struct scatter_walk { |
@@ -81,6 +93,7 @@ struct blkcipher_walk { | |||
81 | int flags; | 93 | int flags; |
82 | }; | 94 | }; |
83 | 95 | ||
96 | extern const struct crypto_type crypto_ablkcipher_type; | ||
84 | extern const struct crypto_type crypto_blkcipher_type; | 97 | extern const struct crypto_type crypto_blkcipher_type; |
85 | extern const struct crypto_type crypto_hash_type; | 98 | extern const struct crypto_type crypto_hash_type; |
86 | 99 | ||
@@ -91,16 +104,23 @@ void crypto_unregister_template(struct crypto_template *tmpl); | |||
91 | struct crypto_template *crypto_lookup_template(const char *name); | 104 | struct crypto_template *crypto_lookup_template(const char *name); |
92 | 105 | ||
93 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, | 106 | int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, |
94 | struct crypto_instance *inst); | 107 | struct crypto_instance *inst, u32 mask); |
95 | void crypto_drop_spawn(struct crypto_spawn *spawn); | 108 | void crypto_drop_spawn(struct crypto_spawn *spawn); |
96 | struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, | 109 | struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, |
97 | u32 mask); | 110 | u32 mask); |
98 | 111 | ||
99 | struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, | 112 | struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb); |
100 | u32 type, u32 mask); | 113 | int crypto_check_attr_type(struct rtattr **tb, u32 type); |
114 | struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask); | ||
101 | struct crypto_instance *crypto_alloc_instance(const char *name, | 115 | struct crypto_instance *crypto_alloc_instance(const char *name, |
102 | struct crypto_alg *alg); | 116 | struct crypto_alg *alg); |
103 | 117 | ||
118 | void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen); | ||
119 | int crypto_enqueue_request(struct crypto_queue *queue, | ||
120 | struct crypto_async_request *request); | ||
121 | struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue); | ||
122 | int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm); | ||
123 | |||
104 | int blkcipher_walk_done(struct blkcipher_desc *desc, | 124 | int blkcipher_walk_done(struct blkcipher_desc *desc, |
105 | struct blkcipher_walk *walk, int err); | 125 | struct blkcipher_walk *walk, int err); |
106 | int blkcipher_walk_virt(struct blkcipher_desc *desc, | 126 | int blkcipher_walk_virt(struct blkcipher_desc *desc, |
@@ -118,11 +138,37 @@ static inline void *crypto_tfm_ctx_aligned(struct crypto_tfm *tfm) | |||
118 | return (void *)ALIGN(addr, align); | 138 | return (void *)ALIGN(addr, align); |
119 | } | 139 | } |
120 | 140 | ||
141 | static inline struct crypto_instance *crypto_tfm_alg_instance( | ||
142 | struct crypto_tfm *tfm) | ||
143 | { | ||
144 | return container_of(tfm->__crt_alg, struct crypto_instance, alg); | ||
145 | } | ||
146 | |||
121 | static inline void *crypto_instance_ctx(struct crypto_instance *inst) | 147 | static inline void *crypto_instance_ctx(struct crypto_instance *inst) |
122 | { | 148 | { |
123 | return inst->__ctx; | 149 | return inst->__ctx; |
124 | } | 150 | } |
125 | 151 | ||
152 | static inline struct ablkcipher_alg *crypto_ablkcipher_alg( | ||
153 | struct crypto_ablkcipher *tfm) | ||
154 | { | ||
155 | return &crypto_ablkcipher_tfm(tfm)->__crt_alg->cra_ablkcipher; | ||
156 | } | ||
157 | |||
158 | static inline void *crypto_ablkcipher_ctx(struct crypto_ablkcipher *tfm) | ||
159 | { | ||
160 | return crypto_tfm_ctx(&tfm->base); | ||
161 | } | ||
162 | |||
163 | static inline struct crypto_blkcipher *crypto_spawn_blkcipher( | ||
164 | struct crypto_spawn *spawn) | ||
165 | { | ||
166 | u32 type = CRYPTO_ALG_TYPE_BLKCIPHER; | ||
167 | u32 mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC; | ||
168 | |||
169 | return __crypto_blkcipher_cast(crypto_spawn_tfm(spawn, type, mask)); | ||
170 | } | ||
171 | |||
126 | static inline void *crypto_blkcipher_ctx(struct crypto_blkcipher *tfm) | 172 | static inline void *crypto_blkcipher_ctx(struct crypto_blkcipher *tfm) |
127 | { | 173 | { |
128 | return crypto_tfm_ctx(&tfm->base); | 174 | return crypto_tfm_ctx(&tfm->base); |
@@ -170,5 +216,35 @@ static inline void blkcipher_walk_init(struct blkcipher_walk *walk, | |||
170 | walk->total = nbytes; | 216 | walk->total = nbytes; |
171 | } | 217 | } |
172 | 218 | ||
219 | static inline struct crypto_async_request *crypto_get_backlog( | ||
220 | struct crypto_queue *queue) | ||
221 | { | ||
222 | return queue->backlog == &queue->list ? NULL : | ||
223 | container_of(queue->backlog, struct crypto_async_request, list); | ||
224 | } | ||
225 | |||
226 | static inline int ablkcipher_enqueue_request(struct ablkcipher_alg *alg, | ||
227 | struct ablkcipher_request *request) | ||
228 | { | ||
229 | return crypto_enqueue_request(alg->queue, &request->base); | ||
230 | } | ||
231 | |||
232 | static inline struct ablkcipher_request *ablkcipher_dequeue_request( | ||
233 | struct ablkcipher_alg *alg) | ||
234 | { | ||
235 | return ablkcipher_request_cast(crypto_dequeue_request(alg->queue)); | ||
236 | } | ||
237 | |||
238 | static inline void *ablkcipher_request_ctx(struct ablkcipher_request *req) | ||
239 | { | ||
240 | return req->__ctx; | ||
241 | } | ||
242 | |||
243 | static inline int ablkcipher_tfm_in_queue(struct crypto_ablkcipher *tfm) | ||
244 | { | ||
245 | return crypto_tfm_in_queue(crypto_ablkcipher_alg(tfm)->queue, | ||
246 | crypto_ablkcipher_tfm(tfm)); | ||
247 | } | ||
248 | |||
173 | #endif /* _CRYPTO_ALGAPI_H */ | 249 | #endif /* _CRYPTO_ALGAPI_H */ |
174 | 250 | ||
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 779aa78ee643..0de7e2ace822 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
@@ -56,6 +56,7 @@ | |||
56 | 56 | ||
57 | #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 | 57 | #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 |
58 | #define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200 | 58 | #define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200 |
59 | #define CRYPTO_TFM_REQ_MAY_BACKLOG 0x00000400 | ||
59 | #define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 | 60 | #define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 |
60 | #define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 | 61 | #define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 |
61 | #define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 | 62 | #define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 |
@@ -88,11 +89,38 @@ | |||
88 | #endif | 89 | #endif |
89 | 90 | ||
90 | struct scatterlist; | 91 | struct scatterlist; |
92 | struct crypto_ablkcipher; | ||
93 | struct crypto_async_request; | ||
91 | struct crypto_blkcipher; | 94 | struct crypto_blkcipher; |
92 | struct crypto_hash; | 95 | struct crypto_hash; |
96 | struct crypto_queue; | ||
93 | struct crypto_tfm; | 97 | struct crypto_tfm; |
94 | struct crypto_type; | 98 | struct crypto_type; |
95 | 99 | ||
100 | typedef void (*crypto_completion_t)(struct crypto_async_request *req, int err); | ||
101 | |||
102 | struct crypto_async_request { | ||
103 | struct list_head list; | ||
104 | crypto_completion_t complete; | ||
105 | void *data; | ||
106 | struct crypto_tfm *tfm; | ||
107 | |||
108 | u32 flags; | ||
109 | }; | ||
110 | |||
111 | struct ablkcipher_request { | ||
112 | struct crypto_async_request base; | ||
113 | |||
114 | unsigned int nbytes; | ||
115 | |||
116 | void *info; | ||
117 | |||
118 | struct scatterlist *src; | ||
119 | struct scatterlist *dst; | ||
120 | |||
121 | void *__ctx[] CRYPTO_MINALIGN_ATTR; | ||
122 | }; | ||
123 | |||
96 | struct blkcipher_desc { | 124 | struct blkcipher_desc { |
97 | struct crypto_blkcipher *tfm; | 125 | struct crypto_blkcipher *tfm; |
98 | void *info; | 126 | void *info; |
@@ -116,6 +144,19 @@ struct hash_desc { | |||
116 | * Algorithms: modular crypto algorithm implementations, managed | 144 | * Algorithms: modular crypto algorithm implementations, managed |
117 | * via crypto_register_alg() and crypto_unregister_alg(). | 145 | * via crypto_register_alg() and crypto_unregister_alg(). |
118 | */ | 146 | */ |
147 | struct ablkcipher_alg { | ||
148 | int (*setkey)(struct crypto_ablkcipher *tfm, const u8 *key, | ||
149 | unsigned int keylen); | ||
150 | int (*encrypt)(struct ablkcipher_request *req); | ||
151 | int (*decrypt)(struct ablkcipher_request *req); | ||
152 | |||
153 | struct crypto_queue *queue; | ||
154 | |||
155 | unsigned int min_keysize; | ||
156 | unsigned int max_keysize; | ||
157 | unsigned int ivsize; | ||
158 | }; | ||
159 | |||
119 | struct blkcipher_alg { | 160 | struct blkcipher_alg { |
120 | int (*setkey)(struct crypto_tfm *tfm, const u8 *key, | 161 | int (*setkey)(struct crypto_tfm *tfm, const u8 *key, |
121 | unsigned int keylen); | 162 | unsigned int keylen); |
@@ -170,6 +211,7 @@ struct compress_alg { | |||
170 | unsigned int slen, u8 *dst, unsigned int *dlen); | 211 | unsigned int slen, u8 *dst, unsigned int *dlen); |
171 | }; | 212 | }; |
172 | 213 | ||
214 | #define cra_ablkcipher cra_u.ablkcipher | ||
173 | #define cra_blkcipher cra_u.blkcipher | 215 | #define cra_blkcipher cra_u.blkcipher |
174 | #define cra_cipher cra_u.cipher | 216 | #define cra_cipher cra_u.cipher |
175 | #define cra_digest cra_u.digest | 217 | #define cra_digest cra_u.digest |
@@ -194,6 +236,7 @@ struct crypto_alg { | |||
194 | const struct crypto_type *cra_type; | 236 | const struct crypto_type *cra_type; |
195 | 237 | ||
196 | union { | 238 | union { |
239 | struct ablkcipher_alg ablkcipher; | ||
197 | struct blkcipher_alg blkcipher; | 240 | struct blkcipher_alg blkcipher; |
198 | struct cipher_alg cipher; | 241 | struct cipher_alg cipher; |
199 | struct digest_alg digest; | 242 | struct digest_alg digest; |
@@ -232,6 +275,15 @@ static inline int crypto_has_alg(const char *name, u32 type, u32 mask) | |||
232 | * crypto_free_*(), as well as the various helpers below. | 275 | * crypto_free_*(), as well as the various helpers below. |
233 | */ | 276 | */ |
234 | 277 | ||
278 | struct ablkcipher_tfm { | ||
279 | int (*setkey)(struct crypto_ablkcipher *tfm, const u8 *key, | ||
280 | unsigned int keylen); | ||
281 | int (*encrypt)(struct ablkcipher_request *req); | ||
282 | int (*decrypt)(struct ablkcipher_request *req); | ||
283 | unsigned int ivsize; | ||
284 | unsigned int reqsize; | ||
285 | }; | ||
286 | |||
235 | struct blkcipher_tfm { | 287 | struct blkcipher_tfm { |
236 | void *iv; | 288 | void *iv; |
237 | int (*setkey)(struct crypto_tfm *tfm, const u8 *key, | 289 | int (*setkey)(struct crypto_tfm *tfm, const u8 *key, |
@@ -290,6 +342,7 @@ struct compress_tfm { | |||
290 | u8 *dst, unsigned int *dlen); | 342 | u8 *dst, unsigned int *dlen); |
291 | }; | 343 | }; |
292 | 344 | ||
345 | #define crt_ablkcipher crt_u.ablkcipher | ||
293 | #define crt_blkcipher crt_u.blkcipher | 346 | #define crt_blkcipher crt_u.blkcipher |
294 | #define crt_cipher crt_u.cipher | 347 | #define crt_cipher crt_u.cipher |
295 | #define crt_hash crt_u.hash | 348 | #define crt_hash crt_u.hash |
@@ -300,6 +353,7 @@ struct crypto_tfm { | |||
300 | u32 crt_flags; | 353 | u32 crt_flags; |
301 | 354 | ||
302 | union { | 355 | union { |
356 | struct ablkcipher_tfm ablkcipher; | ||
303 | struct blkcipher_tfm blkcipher; | 357 | struct blkcipher_tfm blkcipher; |
304 | struct cipher_tfm cipher; | 358 | struct cipher_tfm cipher; |
305 | struct hash_tfm hash; | 359 | struct hash_tfm hash; |
@@ -311,6 +365,10 @@ struct crypto_tfm { | |||
311 | void *__crt_ctx[] CRYPTO_MINALIGN_ATTR; | 365 | void *__crt_ctx[] CRYPTO_MINALIGN_ATTR; |
312 | }; | 366 | }; |
313 | 367 | ||
368 | struct crypto_ablkcipher { | ||
369 | struct crypto_tfm base; | ||
370 | }; | ||
371 | |||
314 | struct crypto_blkcipher { | 372 | struct crypto_blkcipher { |
315 | struct crypto_tfm base; | 373 | struct crypto_tfm base; |
316 | }; | 374 | }; |
@@ -330,12 +388,21 @@ struct crypto_hash { | |||
330 | enum { | 388 | enum { |
331 | CRYPTOA_UNSPEC, | 389 | CRYPTOA_UNSPEC, |
332 | CRYPTOA_ALG, | 390 | CRYPTOA_ALG, |
391 | CRYPTOA_TYPE, | ||
392 | __CRYPTOA_MAX, | ||
333 | }; | 393 | }; |
334 | 394 | ||
395 | #define CRYPTOA_MAX (__CRYPTOA_MAX - 1) | ||
396 | |||
335 | struct crypto_attr_alg { | 397 | struct crypto_attr_alg { |
336 | char name[CRYPTO_MAX_ALG_NAME]; | 398 | char name[CRYPTO_MAX_ALG_NAME]; |
337 | }; | 399 | }; |
338 | 400 | ||
401 | struct crypto_attr_type { | ||
402 | u32 type; | ||
403 | u32 mask; | ||
404 | }; | ||
405 | |||
339 | /* | 406 | /* |
340 | * Transform user interface. | 407 | * Transform user interface. |
341 | */ | 408 | */ |
@@ -411,6 +478,167 @@ static inline unsigned int crypto_tfm_ctx_alignment(void) | |||
411 | /* | 478 | /* |
412 | * API wrappers. | 479 | * API wrappers. |
413 | */ | 480 | */ |
481 | static inline struct crypto_ablkcipher *__crypto_ablkcipher_cast( | ||
482 | struct crypto_tfm *tfm) | ||
483 | { | ||
484 | return (struct crypto_ablkcipher *)tfm; | ||
485 | } | ||
486 | |||
487 | static inline struct crypto_ablkcipher *crypto_alloc_ablkcipher( | ||
488 | const char *alg_name, u32 type, u32 mask) | ||
489 | { | ||
490 | type &= ~CRYPTO_ALG_TYPE_MASK; | ||
491 | type |= CRYPTO_ALG_TYPE_BLKCIPHER; | ||
492 | mask |= CRYPTO_ALG_TYPE_MASK; | ||
493 | |||
494 | return __crypto_ablkcipher_cast( | ||
495 | crypto_alloc_base(alg_name, type, mask)); | ||
496 | } | ||
497 | |||
498 | static inline struct crypto_tfm *crypto_ablkcipher_tfm( | ||
499 | struct crypto_ablkcipher *tfm) | ||
500 | { | ||
501 | return &tfm->base; | ||
502 | } | ||
503 | |||
504 | static inline void crypto_free_ablkcipher(struct crypto_ablkcipher *tfm) | ||
505 | { | ||
506 | crypto_free_tfm(crypto_ablkcipher_tfm(tfm)); | ||
507 | } | ||
508 | |||
509 | static inline int crypto_has_ablkcipher(const char *alg_name, u32 type, | ||
510 | u32 mask) | ||
511 | { | ||
512 | type &= ~CRYPTO_ALG_TYPE_MASK; | ||
513 | type |= CRYPTO_ALG_TYPE_BLKCIPHER; | ||
514 | mask |= CRYPTO_ALG_TYPE_MASK; | ||
515 | |||
516 | return crypto_has_alg(alg_name, type, mask); | ||
517 | } | ||
518 | |||
519 | static inline struct ablkcipher_tfm *crypto_ablkcipher_crt( | ||
520 | struct crypto_ablkcipher *tfm) | ||
521 | { | ||
522 | return &crypto_ablkcipher_tfm(tfm)->crt_ablkcipher; | ||
523 | } | ||
524 | |||
525 | static inline unsigned int crypto_ablkcipher_ivsize( | ||
526 | struct crypto_ablkcipher *tfm) | ||
527 | { | ||
528 | return crypto_ablkcipher_crt(tfm)->ivsize; | ||
529 | } | ||
530 | |||
531 | static inline unsigned int crypto_ablkcipher_blocksize( | ||
532 | struct crypto_ablkcipher *tfm) | ||
533 | { | ||
534 | return crypto_tfm_alg_blocksize(crypto_ablkcipher_tfm(tfm)); | ||
535 | } | ||
536 | |||
537 | static inline unsigned int crypto_ablkcipher_alignmask( | ||
538 | struct crypto_ablkcipher *tfm) | ||
539 | { | ||
540 | return crypto_tfm_alg_alignmask(crypto_ablkcipher_tfm(tfm)); | ||
541 | } | ||
542 | |||
543 | static inline u32 crypto_ablkcipher_get_flags(struct crypto_ablkcipher *tfm) | ||
544 | { | ||
545 | return crypto_tfm_get_flags(crypto_ablkcipher_tfm(tfm)); | ||
546 | } | ||
547 | |||
548 | static inline void crypto_ablkcipher_set_flags(struct crypto_ablkcipher *tfm, | ||
549 | u32 flags) | ||
550 | { | ||
551 | crypto_tfm_set_flags(crypto_ablkcipher_tfm(tfm), flags); | ||
552 | } | ||
553 | |||
554 | static inline void crypto_ablkcipher_clear_flags(struct crypto_ablkcipher *tfm, | ||
555 | u32 flags) | ||
556 | { | ||
557 | crypto_tfm_clear_flags(crypto_ablkcipher_tfm(tfm), flags); | ||
558 | } | ||
559 | |||
560 | static inline int crypto_ablkcipher_setkey(struct crypto_ablkcipher *tfm, | ||
561 | const u8 *key, unsigned int keylen) | ||
562 | { | ||
563 | return crypto_ablkcipher_crt(tfm)->setkey(tfm, key, keylen); | ||
564 | } | ||
565 | |||
566 | static inline struct crypto_ablkcipher *crypto_ablkcipher_reqtfm( | ||
567 | struct ablkcipher_request *req) | ||
568 | { | ||
569 | return __crypto_ablkcipher_cast(req->base.tfm); | ||
570 | } | ||
571 | |||
572 | static inline int crypto_ablkcipher_encrypt(struct ablkcipher_request *req) | ||
573 | { | ||
574 | struct ablkcipher_tfm *crt = | ||
575 | crypto_ablkcipher_crt(crypto_ablkcipher_reqtfm(req)); | ||
576 | return crt->encrypt(req); | ||
577 | } | ||
578 | |||
579 | static inline int crypto_ablkcipher_decrypt(struct ablkcipher_request *req) | ||
580 | { | ||
581 | struct ablkcipher_tfm *crt = | ||
582 | crypto_ablkcipher_crt(crypto_ablkcipher_reqtfm(req)); | ||
583 | return crt->decrypt(req); | ||
584 | } | ||
585 | |||
586 | static inline int crypto_ablkcipher_reqsize(struct crypto_ablkcipher *tfm) | ||
587 | { | ||
588 | return crypto_ablkcipher_crt(tfm)->reqsize; | ||
589 | } | ||
590 | |||
591 | static inline void ablkcipher_request_set_tfm( | ||
592 | struct ablkcipher_request *req, struct crypto_ablkcipher *tfm) | ||
593 | { | ||
594 | req->base.tfm = crypto_ablkcipher_tfm(tfm); | ||
595 | } | ||
596 | |||
597 | static inline struct ablkcipher_request *ablkcipher_request_cast( | ||
598 | struct crypto_async_request *req) | ||
599 | { | ||
600 | return container_of(req, struct ablkcipher_request, base); | ||
601 | } | ||
602 | |||
603 | static inline struct ablkcipher_request *ablkcipher_request_alloc( | ||
604 | struct crypto_ablkcipher *tfm, gfp_t gfp) | ||
605 | { | ||
606 | struct ablkcipher_request *req; | ||
607 | |||
608 | req = kmalloc(sizeof(struct ablkcipher_request) + | ||
609 | crypto_ablkcipher_reqsize(tfm), gfp); | ||
610 | |||
611 | if (likely(req)) | ||
612 | ablkcipher_request_set_tfm(req, tfm); | ||
613 | |||
614 | return req; | ||
615 | } | ||
616 | |||
617 | static inline void ablkcipher_request_free(struct ablkcipher_request *req) | ||
618 | { | ||
619 | kfree(req); | ||
620 | } | ||
621 | |||
622 | static inline void ablkcipher_request_set_callback( | ||
623 | struct ablkcipher_request *req, | ||
624 | u32 flags, crypto_completion_t complete, void *data) | ||
625 | { | ||
626 | req->base.complete = complete; | ||
627 | req->base.data = data; | ||
628 | req->base.flags = flags; | ||
629 | } | ||
630 | |||
631 | static inline void ablkcipher_request_set_crypt( | ||
632 | struct ablkcipher_request *req, | ||
633 | struct scatterlist *src, struct scatterlist *dst, | ||
634 | unsigned int nbytes, void *iv) | ||
635 | { | ||
636 | req->src = src; | ||
637 | req->dst = dst; | ||
638 | req->nbytes = nbytes; | ||
639 | req->info = iv; | ||
640 | } | ||
641 | |||
414 | static inline struct crypto_blkcipher *__crypto_blkcipher_cast( | 642 | static inline struct crypto_blkcipher *__crypto_blkcipher_cast( |
415 | struct crypto_tfm *tfm) | 643 | struct crypto_tfm *tfm) |
416 | { | 644 | { |
@@ -427,9 +655,9 @@ static inline struct crypto_blkcipher *crypto_blkcipher_cast( | |||
427 | static inline struct crypto_blkcipher *crypto_alloc_blkcipher( | 655 | static inline struct crypto_blkcipher *crypto_alloc_blkcipher( |
428 | const char *alg_name, u32 type, u32 mask) | 656 | const char *alg_name, u32 type, u32 mask) |
429 | { | 657 | { |
430 | type &= ~CRYPTO_ALG_TYPE_MASK; | 658 | type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); |
431 | type |= CRYPTO_ALG_TYPE_BLKCIPHER; | 659 | type |= CRYPTO_ALG_TYPE_BLKCIPHER; |
432 | mask |= CRYPTO_ALG_TYPE_MASK; | 660 | mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC; |
433 | 661 | ||
434 | return __crypto_blkcipher_cast(crypto_alloc_base(alg_name, type, mask)); | 662 | return __crypto_blkcipher_cast(crypto_alloc_base(alg_name, type, mask)); |
435 | } | 663 | } |
@@ -447,9 +675,9 @@ static inline void crypto_free_blkcipher(struct crypto_blkcipher *tfm) | |||
447 | 675 | ||
448 | static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask) | 676 | static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask) |
449 | { | 677 | { |
450 | type &= ~CRYPTO_ALG_TYPE_MASK; | 678 | type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); |
451 | type |= CRYPTO_ALG_TYPE_BLKCIPHER; | 679 | type |= CRYPTO_ALG_TYPE_BLKCIPHER; |
452 | mask |= CRYPTO_ALG_TYPE_MASK; | 680 | mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC; |
453 | 681 | ||
454 | return crypto_has_alg(alg_name, type, mask); | 682 | return crypto_has_alg(alg_name, type, mask); |
455 | } | 683 | } |