diff options
Diffstat (limited to 'crypto/ablkcipher.c')
| -rw-r--r-- | crypto/ablkcipher.c | 31 |
1 files changed, 29 insertions, 2 deletions
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 | ||
| 22 | static 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 | |||
| 22 | static int setkey(struct crypto_ablkcipher *tfm, const u8 *key, | 43 | static 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 | ||
| 73 | const struct crypto_type crypto_ablkcipher_type = { | 100 | const struct crypto_type crypto_ablkcipher_type = { |
