aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--include/linux/crypto.h20
8 files changed, 125 insertions, 34 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;
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 0de7e2ace822..357e8cfedc37 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -295,28 +295,8 @@ struct blkcipher_tfm {
295}; 295};
296 296
297struct cipher_tfm { 297struct cipher_tfm {
298 void *cit_iv;
299 unsigned int cit_ivsize;
300 u32 cit_mode;
301 int (*cit_setkey)(struct crypto_tfm *tfm, 298 int (*cit_setkey)(struct crypto_tfm *tfm,
302 const u8 *key, unsigned int keylen); 299 const u8 *key, unsigned int keylen);
303 int (*cit_encrypt)(struct crypto_tfm *tfm,
304 struct scatterlist *dst,
305 struct scatterlist *src,
306 unsigned int nbytes);
307 int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
308 struct scatterlist *dst,
309 struct scatterlist *src,
310 unsigned int nbytes, u8 *iv);
311 int (*cit_decrypt)(struct crypto_tfm *tfm,
312 struct scatterlist *dst,
313 struct scatterlist *src,
314 unsigned int nbytes);
315 int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
316 struct scatterlist *dst,
317 struct scatterlist *src,
318 unsigned int nbytes, u8 *iv);
319 void (*cit_xor_block)(u8 *dst, const u8 *src);
320 void (*cit_encrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); 300 void (*cit_encrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
321 void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); 301 void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
322}; 302};