aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-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/michael_mic.c4
-rw-r--r--crypto/pcbc.c11
-rw-r--r--crypto/scatterwalk.c12
-rw-r--r--crypto/tcrypt.c123
-rw-r--r--crypto/xcbc.c12
17 files changed, 862 insertions, 126 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 086fcec44720..620e14cabdc6 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -16,6 +16,10 @@ config CRYPTO_ALGAPI
16 help 16 help
17 This option provides the API for cryptographic algorithms. 17 This option provides the API for cryptographic algorithms.
18 18
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/michael_mic.c b/crypto/michael_mic.c
index 094397b48849..9e917b8011b1 100644
--- a/crypto/michael_mic.c
+++ b/crypto/michael_mic.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Michael MIC (IEEE 802.11i/TKIP) keyed digest 4 * Michael MIC (IEEE 802.11i/TKIP) keyed digest
5 * 5 *
6 * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi> 6 * Copyright (c) 2004 Jouni Malinen <j@w1.fi>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -173,4 +173,4 @@ module_exit(michael_mic_exit);
173 173
174MODULE_LICENSE("GPL v2"); 174MODULE_LICENSE("GPL v2");
175MODULE_DESCRIPTION("Michael MIC"); 175MODULE_DESCRIPTION("Michael MIC");
176MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>"); 176MODULE_AUTHOR("Jouni Malinen <j@w1.fi>");
diff --git a/crypto/pcbc.c b/crypto/pcbc.c
index 5174d7fdad6e..c3ed8a1c9f46 100644
--- a/crypto/pcbc.c
+++ b/crypto/pcbc.c
@@ -279,13 +279,18 @@ static void crypto_pcbc_exit_tfm(struct crypto_tfm *tfm)
279 crypto_free_cipher(ctx->child); 279 crypto_free_cipher(ctx->child);
280} 280}
281 281
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/scatterwalk.c b/crypto/scatterwalk.c
index 35172d3f043b..81afd1790a1d 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -59,8 +59,12 @@ EXPORT_SYMBOL_GPL(scatterwalk_map);
59static void scatterwalk_pagedone(struct scatter_walk *walk, int out, 59static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
60 unsigned int more) 60 unsigned int more)
61{ 61{
62 if (out) 62 if (out) {
63 flush_dcache_page(scatterwalk_page(walk)); 63 struct page *page;
64
65 page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
66 flush_dcache_page(page);
67 }
64 68
65 if (more) { 69 if (more) {
66 walk->offset += PAGE_SIZE - 1; 70 walk->offset += PAGE_SIZE - 1;
@@ -91,6 +95,8 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
91 memcpy_dir(buf, vaddr, len_this_page, out); 95 memcpy_dir(buf, vaddr, len_this_page, out);
92 scatterwalk_unmap(vaddr, out); 96 scatterwalk_unmap(vaddr, out);
93 97
98 scatterwalk_advance(walk, len_this_page);
99
94 if (nbytes == len_this_page) 100 if (nbytes == len_this_page)
95 break; 101 break;
96 102
@@ -99,7 +105,5 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
99 105
100 scatterwalk_pagedone(walk, out, 1); 106 scatterwalk_pagedone(walk, out, 1);
101 } 107 }
102
103 scatterwalk_advance(walk, nbytes);
104} 108}
105EXPORT_SYMBOL_GPL(scatterwalk_copychunks); 109EXPORT_SYMBOL_GPL(scatterwalk_copychunks);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index f5e9da319ece..f0aed0106adb 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -57,6 +57,11 @@
57#define ENCRYPT 1 57#define ENCRYPT 1
58#define DECRYPT 0 58#define DECRYPT 0
59 59
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,
@@ -768,7 +811,7 @@ static void test_deflate(void)
768 tv = (void *)tvmem; 811 tv = (void *)tvmem;
769 812
770 tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC); 813 tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC);
771 if (tfm == NULL) { 814 if (IS_ERR(tfm)) {
772 printk("failed to load transform for deflate\n"); 815 printk("failed to load transform for deflate\n");
773 return; 816 return;
774 } 817 }
@@ -832,7 +875,7 @@ static void test_available(void)
832 875
833 while (*name) { 876 while (*name) {
834 printk("alg %s ", *name); 877 printk("alg %s ", *name);
835 printk(crypto_has_alg(*name, 0, CRYPTO_ALG_ASYNC) ? 878 printk(crypto_has_alg(*name, 0, 0) ?
836 "found\n" : "not found\n"); 879 "found\n" : "not found\n");
837 name++; 880 name++;
838 } 881 }
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 53e8ccbf0f5f..9f502b86e0ea 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -288,12 +288,18 @@ static void xcbc_exit_tfm(struct crypto_tfm *tfm)
288 crypto_free_cipher(ctx->child); 288 crypto_free_cipher(ctx->child);
289} 289}
290 290
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