aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:01:17 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:01:17 -0400
commit6adae5d9e69743aede91b274224751811f7174f1 (patch)
tree5ad15959313fbf4b7a37a36e40b04ca718b1e423
parent253f04e78ded827c30f9582489773ebe2adc8924 (diff)
parentf6259deacfd55607ae57cff422d3bc7694ea14e7 (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/Kconfig13
-rw-r--r--crypto/Makefile2
-rw-r--r--crypto/ablkcipher.c83
-rw-r--r--crypto/algapi.c169
-rw-r--r--crypto/blkcipher.c72
-rw-r--r--crypto/cbc.c11
-rw-r--r--crypto/cryptd.c375
-rw-r--r--crypto/cryptomgr.c66
-rw-r--r--crypto/ecb.c11
-rw-r--r--crypto/hash.c2
-rw-r--r--crypto/hmac.c11
-rw-r--r--crypto/lrw.c11
-rw-r--r--crypto/pcbc.c11
-rw-r--r--crypto/tcrypt.c121
-rw-r--r--crypto/xcbc.c12
-rw-r--r--drivers/crypto/Kconfig16
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/padlock.c58
-rw-r--r--include/crypto/algapi.h84
-rw-r--r--include/linux/crypto.h236
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
19config CRYPTO_ABLKCIPHER
20 tristate
21 select CRYPTO_BLKCIPHER
22
19config CRYPTO_BLKCIPHER 23config 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
178config 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
174config CRYPTO_DES 187config 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
8crypto_algapi-objs := algapi.o $(crypto_algapi-y) 8crypto_algapi-objs := algapi.o $(crypto_algapi-y)
9obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o 9obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o
10 10
11obj-$(CONFIG_CRYPTO_ABLKCIPHER) += ablkcipher.o
11obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o 12obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o
12 13
13crypto_hash-objs := hash.o 14crypto_hash-objs := hash.o
@@ -29,6 +30,7 @@ obj-$(CONFIG_CRYPTO_ECB) += ecb.o
29obj-$(CONFIG_CRYPTO_CBC) += cbc.o 30obj-$(CONFIG_CRYPTO_CBC) += cbc.o
30obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o 31obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o
31obj-$(CONFIG_CRYPTO_LRW) += lrw.o 32obj-$(CONFIG_CRYPTO_LRW) += lrw.o
33obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
32obj-$(CONFIG_CRYPTO_DES) += des.o 34obj-$(CONFIG_CRYPTO_DES) += des.o
33obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o 35obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
34obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o 36obj-$(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
22static 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
35static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type,
36 u32 mask)
37{
38 return alg->cra_ctxsize;
39}
40
41static 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
58static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
59 __attribute__ ((unused));
60static 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
73const 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};
80EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
81
82MODULE_LICENSE("GPL");
83MODULE_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
87static void crypto_remove_spawns(struct list_head *spawns, 87static 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
112static 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:
351EXPORT_SYMBOL_GPL(crypto_register_instance); 362EXPORT_SYMBOL_GPL(crypto_register_instance);
352 363
353int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, 364int 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}
426EXPORT_SYMBOL_GPL(crypto_unregister_notifier); 438EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
427 439
428struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, 440struct 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}
454EXPORT_SYMBOL_GPL(crypto_get_attr_type);
455
456int 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}
469EXPORT_SYMBOL_GPL(crypto_check_attr_type);
470
471struct 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}
478EXPORT_SYMBOL_GPL(crypto_alloc_instance); 521EXPORT_SYMBOL_GPL(crypto_alloc_instance);
479 522
523void 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}
530EXPORT_SYMBOL_GPL(crypto_init_queue);
531
532int 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
548out:
549 return err;
550}
551EXPORT_SYMBOL_GPL(crypto_enqueue_request);
552
553struct 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}
570EXPORT_SYMBOL_GPL(crypto_dequeue_request);
571
572int 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}
583EXPORT_SYMBOL_GPL(crypto_tfm_in_queue);
584
480static int __init crypto_algapi_init(void) 585static 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
352static 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
358static 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
372static 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
352static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, 385static 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
366static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) 401static 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
414static 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
433static 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
388static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) 448static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
389 __attribute_used__; 449 __attribute__ ((unused));
390static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) 450static 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
278static struct crypto_instance *crypto_cbc_alloc(void *param, unsigned int len) 278static 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
28struct cryptd_state {
29 spinlock_t lock;
30 struct mutex mutex;
31 struct crypto_queue queue;
32 struct task_struct *task;
33};
34
35struct cryptd_instance_ctx {
36 struct crypto_spawn spawn;
37 struct cryptd_state *state;
38};
39
40struct cryptd_blkcipher_ctx {
41 struct crypto_blkcipher *child;
42};
43
44struct cryptd_blkcipher_request_ctx {
45 crypto_completion_t complete;
46};
47
48
49static 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
56static 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
72static 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
103static 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
112static 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
121static 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
141static int cryptd_blkcipher_encrypt_enqueue(struct ablkcipher_request *req)
142{
143 return cryptd_blkcipher_enqueue(req, cryptd_blkcipher_encrypt);
144}
145
146static int cryptd_blkcipher_decrypt_enqueue(struct ablkcipher_request *req)
147{
148 return cryptd_blkcipher_enqueue(req, cryptd_blkcipher_decrypt);
149}
150
151static 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
169static 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
184static 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
214out:
215 return inst;
216
217out_free_inst:
218 kfree(inst);
219 inst = ERR_PTR(err);
220 goto out;
221}
222
223static 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
256out_put_alg:
257 crypto_mod_put(alg);
258 return inst;
259}
260
261static struct cryptd_state state;
262
263static 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
279static 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
287static struct crypto_template cryptd_tmpl = {
288 .name = "cryptd",
289 .alloc = cryptd_alloc,
290 .free = cryptd_free,
291 .module = THIS_MODULE,
292};
293
294static 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
308static inline void cryptd_stop_thread(struct cryptd_state *state)
309{
310 BUG_ON(state->queue.qlen);
311 kthread_stop(state->task);
312}
313
314static 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
350static 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
365static void __exit cryptd_exit(void)
366{
367 cryptd_stop_thread(&state);
368 crypto_unregister_template(&cryptd_tmpl);
369}
370
371module_init(cryptd_init);
372module_exit(cryptd_exit);
373
374MODULE_LICENSE("GPL");
375MODULE_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
26struct cryptomgr_param { 26struct 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
43static void cryptomgr_probe(struct work_struct *work) 48static 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(&param->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
68out: 72out:
69 kfree(param); 73 kfree(param);
70 return; 74 module_put_and_exit(0);
71 75
72err: 76err:
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] = &param->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] = &param->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(&param->work, cryptomgr_probe); 133 param->thread = kthread_run(cryptomgr_probe, param, "cryptomgr");
117 schedule_work(&param->work); 134 if (IS_ERR(param->thread))
135 goto err_free_param;
118 136
119 return NOTIFY_STOP; 137 return NOTIFY_STOP;
120 138
121err_free_param: 139err_free_param:
122 kfree(param); 140 kfree(param);
141err_put_module:
142 module_put(THIS_MODULE);
123err: 143err:
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
118static struct crypto_instance *crypto_ecb_alloc(void *param, unsigned int len) 118static 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
43static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) 43static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
44 __attribute_used__; 44 __attribute__ ((unused));
45static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg) 45static 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
200static struct crypto_instance *hmac_alloc(void *param, unsigned int len) 200static 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
231static struct crypto_instance *alloc(void *param, unsigned int len) 231static 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
282static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len) 282static 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
60struct tcrypt_result {
61 struct completion completion;
62 int err;
63};
64
60static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; 65static 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
92static 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
87static void test_hash(char *algo, struct hash_testvec *template, 103static 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
362out: 404out:
363 crypto_free_blkcipher(tfm); 405 crypto_free_ablkcipher(tfm);
406 ablkcipher_request_free(req);
364} 407}
365 408
366static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, 409static 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
291static struct crypto_instance *xcbc_alloc(void *param, unsigned int len) 291static 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 @@
1menu "Hardware crypto devices" 1menu "Hardware crypto devices"
2 2
3config CRYPTO_DEV_PADLOCK 3config 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
27config CRYPTO_DEV_PADLOCK_AES 17config 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
56config CRYPTO_DEV_GEODE 46config 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 @@
1obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o
2obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o 1obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
3obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o 2obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o
4obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o 3obj-$(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
25static 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
48static void __exit padlock_fini(void)
49{
50}
51
52module_init(padlock_init);
53module_exit(padlock_fini);
54
55MODULE_DESCRIPTION("Load all configured PadLock algorithms.");
56MODULE_LICENSE("GPL");
57MODULE_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
17struct module; 19struct module;
20struct rtattr;
18struct seq_file; 21struct seq_file;
19 22
20struct crypto_type { 23struct 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
57struct 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
53struct scatter_walk { 65struct scatter_walk {
@@ -81,6 +93,7 @@ struct blkcipher_walk {
81 int flags; 93 int flags;
82}; 94};
83 95
96extern const struct crypto_type crypto_ablkcipher_type;
84extern const struct crypto_type crypto_blkcipher_type; 97extern const struct crypto_type crypto_blkcipher_type;
85extern const struct crypto_type crypto_hash_type; 98extern const struct crypto_type crypto_hash_type;
86 99
@@ -91,16 +104,23 @@ void crypto_unregister_template(struct crypto_template *tmpl);
91struct crypto_template *crypto_lookup_template(const char *name); 104struct crypto_template *crypto_lookup_template(const char *name);
92 105
93int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, 106int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
94 struct crypto_instance *inst); 107 struct crypto_instance *inst, u32 mask);
95void crypto_drop_spawn(struct crypto_spawn *spawn); 108void crypto_drop_spawn(struct crypto_spawn *spawn);
96struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, 109struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
97 u32 mask); 110 u32 mask);
98 111
99struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, 112struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb);
100 u32 type, u32 mask); 113int crypto_check_attr_type(struct rtattr **tb, u32 type);
114struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask);
101struct crypto_instance *crypto_alloc_instance(const char *name, 115struct crypto_instance *crypto_alloc_instance(const char *name,
102 struct crypto_alg *alg); 116 struct crypto_alg *alg);
103 117
118void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen);
119int crypto_enqueue_request(struct crypto_queue *queue,
120 struct crypto_async_request *request);
121struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue);
122int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm);
123
104int blkcipher_walk_done(struct blkcipher_desc *desc, 124int blkcipher_walk_done(struct blkcipher_desc *desc,
105 struct blkcipher_walk *walk, int err); 125 struct blkcipher_walk *walk, int err);
106int blkcipher_walk_virt(struct blkcipher_desc *desc, 126int 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
141static 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
121static inline void *crypto_instance_ctx(struct crypto_instance *inst) 147static inline void *crypto_instance_ctx(struct crypto_instance *inst)
122{ 148{
123 return inst->__ctx; 149 return inst->__ctx;
124} 150}
125 151
152static 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
158static inline void *crypto_ablkcipher_ctx(struct crypto_ablkcipher *tfm)
159{
160 return crypto_tfm_ctx(&tfm->base);
161}
162
163static 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
126static inline void *crypto_blkcipher_ctx(struct crypto_blkcipher *tfm) 172static 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
219static 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
226static 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
232static 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
238static inline void *ablkcipher_request_ctx(struct ablkcipher_request *req)
239{
240 return req->__ctx;
241}
242
243static 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
90struct scatterlist; 91struct scatterlist;
92struct crypto_ablkcipher;
93struct crypto_async_request;
91struct crypto_blkcipher; 94struct crypto_blkcipher;
92struct crypto_hash; 95struct crypto_hash;
96struct crypto_queue;
93struct crypto_tfm; 97struct crypto_tfm;
94struct crypto_type; 98struct crypto_type;
95 99
100typedef void (*crypto_completion_t)(struct crypto_async_request *req, int err);
101
102struct 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
111struct 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
96struct blkcipher_desc { 124struct 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 */
147struct 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
119struct blkcipher_alg { 160struct 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
278struct 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
235struct blkcipher_tfm { 287struct 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
368struct crypto_ablkcipher {
369 struct crypto_tfm base;
370};
371
314struct crypto_blkcipher { 372struct crypto_blkcipher {
315 struct crypto_tfm base; 373 struct crypto_tfm base;
316}; 374};
@@ -330,12 +388,21 @@ struct crypto_hash {
330enum { 388enum {
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
335struct crypto_attr_alg { 397struct crypto_attr_alg {
336 char name[CRYPTO_MAX_ALG_NAME]; 398 char name[CRYPTO_MAX_ALG_NAME];
337}; 399};
338 400
401struct 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 */
481static inline struct crypto_ablkcipher *__crypto_ablkcipher_cast(
482 struct crypto_tfm *tfm)
483{
484 return (struct crypto_ablkcipher *)tfm;
485}
486
487static 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
498static inline struct crypto_tfm *crypto_ablkcipher_tfm(
499 struct crypto_ablkcipher *tfm)
500{
501 return &tfm->base;
502}
503
504static inline void crypto_free_ablkcipher(struct crypto_ablkcipher *tfm)
505{
506 crypto_free_tfm(crypto_ablkcipher_tfm(tfm));
507}
508
509static 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
519static inline struct ablkcipher_tfm *crypto_ablkcipher_crt(
520 struct crypto_ablkcipher *tfm)
521{
522 return &crypto_ablkcipher_tfm(tfm)->crt_ablkcipher;
523}
524
525static inline unsigned int crypto_ablkcipher_ivsize(
526 struct crypto_ablkcipher *tfm)
527{
528 return crypto_ablkcipher_crt(tfm)->ivsize;
529}
530
531static inline unsigned int crypto_ablkcipher_blocksize(
532 struct crypto_ablkcipher *tfm)
533{
534 return crypto_tfm_alg_blocksize(crypto_ablkcipher_tfm(tfm));
535}
536
537static inline unsigned int crypto_ablkcipher_alignmask(
538 struct crypto_ablkcipher *tfm)
539{
540 return crypto_tfm_alg_alignmask(crypto_ablkcipher_tfm(tfm));
541}
542
543static inline u32 crypto_ablkcipher_get_flags(struct crypto_ablkcipher *tfm)
544{
545 return crypto_tfm_get_flags(crypto_ablkcipher_tfm(tfm));
546}
547
548static 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
554static 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
560static 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
566static inline struct crypto_ablkcipher *crypto_ablkcipher_reqtfm(
567 struct ablkcipher_request *req)
568{
569 return __crypto_ablkcipher_cast(req->base.tfm);
570}
571
572static 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
579static 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
586static inline int crypto_ablkcipher_reqsize(struct crypto_ablkcipher *tfm)
587{
588 return crypto_ablkcipher_crt(tfm)->reqsize;
589}
590
591static 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
597static 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
603static 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
617static inline void ablkcipher_request_free(struct ablkcipher_request *req)
618{
619 kfree(req);
620}
621
622static 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
631static 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
414static inline struct crypto_blkcipher *__crypto_blkcipher_cast( 642static 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(
427static inline struct crypto_blkcipher *crypto_alloc_blkcipher( 655static 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
448static inline int crypto_has_blkcipher(const char *alg_name, u32 type, u32 mask) 676static 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}