aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/Kconfig6
-rw-r--r--crypto/ablkcipher.c31
-rw-r--r--crypto/algapi.c4
-rw-r--r--crypto/api.c2
-rw-r--r--crypto/blkcipher.c25
-rw-r--r--crypto/cipher.c33
-rw-r--r--crypto/hash.c38
7 files changed, 125 insertions, 14 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 07090e9f9bcf..3d1a1e27944f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -12,9 +12,7 @@ source "crypto/async_tx/Kconfig"
12# 12#
13# Cryptographic API Configuration 13# Cryptographic API Configuration
14# 14#
15menu "Cryptographic options" 15menuconfig CRYPTO
16
17config CRYPTO
18 bool "Cryptographic API" 16 bool "Cryptographic API"
19 help 17 help
20 This option provides the core Cryptographic API. 18 This option provides the core Cryptographic API.
@@ -473,5 +471,3 @@ config CRYPTO_TEST
473source "drivers/crypto/Kconfig" 471source "drivers/crypto/Kconfig"
474 472
475endif # if CRYPTO 473endif # if CRYPTO
476
477endmenu
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 9348ddd84a56..1c166b47b4cc 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -19,16 +19,41 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/seq_file.h> 20#include <linux/seq_file.h>
21 21
22static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen)
23{
24 struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
25 unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
26 int ret;
27 u8 *buffer, *alignbuffer;
28 unsigned long absize;
29
30 absize = keylen + alignmask;
31 buffer = kmalloc(absize, GFP_ATOMIC);
32 if (!buffer)
33 return -ENOMEM;
34
35 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
36 memcpy(alignbuffer, key, keylen);
37 ret = cipher->setkey(tfm, alignbuffer, keylen);
38 memset(alignbuffer, 0, absize);
39 kfree(buffer);
40 return ret;
41}
42
22static int setkey(struct crypto_ablkcipher *tfm, const u8 *key, 43static int setkey(struct crypto_ablkcipher *tfm, const u8 *key,
23 unsigned int keylen) 44 unsigned int keylen)
24{ 45{
25 struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); 46 struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
47 unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
26 48
27 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { 49 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
28 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 50 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
29 return -EINVAL; 51 return -EINVAL;
30 } 52 }
31 53
54 if ((unsigned long)key & alignmask)
55 return setkey_unaligned(tfm, key, keylen);
56
32 return cipher->setkey(tfm, key, keylen); 57 return cipher->setkey(tfm, key, keylen);
33} 58}
34 59
@@ -66,8 +91,10 @@ static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
66 seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); 91 seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize);
67 seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); 92 seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize);
68 seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize); 93 seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize);
69 seq_printf(m, "qlen : %u\n", ablkcipher->queue->qlen); 94 if (ablkcipher->queue) {
70 seq_printf(m, "max qlen : %u\n", ablkcipher->queue->max_qlen); 95 seq_printf(m, "qlen : %u\n", ablkcipher->queue->qlen);
96 seq_printf(m, "max qlen : %u\n", ablkcipher->queue->max_qlen);
97 }
71} 98}
72 99
73const struct crypto_type crypto_ablkcipher_type = { 100const struct crypto_type crypto_ablkcipher_type = {
diff --git a/crypto/algapi.c b/crypto/algapi.c
index f137a432061f..38aa9e994703 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -34,7 +34,7 @@ void crypto_larval_error(const char *name, u32 type, u32 mask)
34 if (alg) { 34 if (alg) {
35 if (crypto_is_larval(alg)) { 35 if (crypto_is_larval(alg)) {
36 struct crypto_larval *larval = (void *)alg; 36 struct crypto_larval *larval = (void *)alg;
37 complete(&larval->completion); 37 complete_all(&larval->completion);
38 } 38 }
39 crypto_mod_put(alg); 39 crypto_mod_put(alg);
40 } 40 }
@@ -164,7 +164,7 @@ static int __crypto_register_alg(struct crypto_alg *alg,
164 continue; 164 continue;
165 165
166 larval->adult = alg; 166 larval->adult = alg;
167 complete(&larval->completion); 167 complete_all(&larval->completion);
168 continue; 168 continue;
169 } 169 }
170 170
diff --git a/crypto/api.c b/crypto/api.c
index 33734fd9198f..4ccc5af6c265 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -144,7 +144,7 @@ static void crypto_larval_kill(struct crypto_alg *alg)
144 down_write(&crypto_alg_sem); 144 down_write(&crypto_alg_sem);
145 list_del(&alg->cra_list); 145 list_del(&alg->cra_list);
146 up_write(&crypto_alg_sem); 146 up_write(&crypto_alg_sem);
147 complete(&larval->completion); 147 complete_all(&larval->completion);
148 crypto_alg_put(alg); 148 crypto_alg_put(alg);
149} 149}
150 150
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 8edf40c835a7..40a3dcff15bb 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -336,16 +336,41 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc,
336 return blkcipher_walk_next(desc, walk); 336 return blkcipher_walk_next(desc, walk);
337} 337}
338 338
339static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
340{
341 struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher;
342 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
343 int ret;
344 u8 *buffer, *alignbuffer;
345 unsigned long absize;
346
347 absize = keylen + alignmask;
348 buffer = kmalloc(absize, GFP_ATOMIC);
349 if (!buffer)
350 return -ENOMEM;
351
352 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
353 memcpy(alignbuffer, key, keylen);
354 ret = cipher->setkey(tfm, alignbuffer, keylen);
355 memset(alignbuffer, 0, absize);
356 kfree(buffer);
357 return ret;
358}
359
339static int setkey(struct crypto_tfm *tfm, const u8 *key, 360static int setkey(struct crypto_tfm *tfm, const u8 *key,
340 unsigned int keylen) 361 unsigned int keylen)
341{ 362{
342 struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher; 363 struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher;
364 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
343 365
344 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { 366 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
345 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 367 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
346 return -EINVAL; 368 return -EINVAL;
347 } 369 }
348 370
371 if ((unsigned long)key & alignmask)
372 return setkey_unaligned(tfm, key, keylen);
373
349 return cipher->setkey(tfm, key, keylen); 374 return cipher->setkey(tfm, key, keylen);
350} 375}
351 376
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 333aab2f0277..0b2650c2014b 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -20,16 +20,43 @@
20#include <linux/string.h> 20#include <linux/string.h>
21#include "internal.h" 21#include "internal.h"
22 22
23static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
24{
25 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
26 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
27 int ret;
28 u8 *buffer, *alignbuffer;
29 unsigned long absize;
30
31 absize = keylen + alignmask;
32 buffer = kmalloc(absize, GFP_ATOMIC);
33 if (!buffer)
34 return -ENOMEM;
35
36 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
37 memcpy(alignbuffer, key, keylen);
38 ret = cia->cia_setkey(tfm, alignbuffer, keylen);
39 memset(alignbuffer, 0, absize);
40 kfree(buffer);
41 return ret;
42
43}
44
23static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) 45static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
24{ 46{
25 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; 47 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
26 48 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
49
27 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; 50 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
28 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { 51 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
29 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 52 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
30 return -EINVAL; 53 return -EINVAL;
31 } else 54 }
32 return cia->cia_setkey(tfm, key, keylen); 55
56 if ((unsigned long)key & alignmask)
57 return setkey_unaligned(tfm, key, keylen);
58
59 return cia->cia_setkey(tfm, key, keylen);
33} 60}
34 61
35static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *, 62static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *,
diff --git a/crypto/hash.c b/crypto/hash.c
index 4ccd22deef39..4d75ca7b57b2 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -22,6 +22,42 @@ static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type,
22 return alg->cra_ctxsize; 22 return alg->cra_ctxsize;
23} 23}
24 24
25static int hash_setkey_unaligned(struct crypto_hash *crt, const u8 *key,
26 unsigned int keylen)
27{
28 struct crypto_tfm *tfm = crypto_hash_tfm(crt);
29 struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
30 unsigned long alignmask = crypto_hash_alignmask(crt);
31 int ret;
32 u8 *buffer, *alignbuffer;
33 unsigned long absize;
34
35 absize = keylen + alignmask;
36 buffer = kmalloc(absize, GFP_ATOMIC);
37 if (!buffer)
38 return -ENOMEM;
39
40 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
41 memcpy(alignbuffer, key, keylen);
42 ret = alg->setkey(crt, alignbuffer, keylen);
43 memset(alignbuffer, 0, absize);
44 kfree(buffer);
45 return ret;
46}
47
48static int hash_setkey(struct crypto_hash *crt, const u8 *key,
49 unsigned int keylen)
50{
51 struct crypto_tfm *tfm = crypto_hash_tfm(crt);
52 struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
53 unsigned long alignmask = crypto_hash_alignmask(crt);
54
55 if ((unsigned long)key & alignmask)
56 return hash_setkey_unaligned(crt, key, keylen);
57
58 return alg->setkey(crt, key, keylen);
59}
60
25static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) 61static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
26{ 62{
27 struct hash_tfm *crt = &tfm->crt_hash; 63 struct hash_tfm *crt = &tfm->crt_hash;
@@ -34,7 +70,7 @@ static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
34 crt->update = alg->update; 70 crt->update = alg->update;
35 crt->final = alg->final; 71 crt->final = alg->final;
36 crt->digest = alg->digest; 72 crt->digest = alg->digest;
37 crt->setkey = alg->setkey; 73 crt->setkey = hash_setkey;
38 crt->digestsize = alg->digestsize; 74 crt->digestsize = alg->digestsize;
39 75
40 return 0; 76 return 0;