|
19 | 19 | #include <linux/module.h> |
20 | 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 | 43 | static int setkey(struct crypto_ablkcipher *tfm, const u8 *key, |
23 | 44 | unsigned int keylen) |
24 | 45 | { |
25 | 46 | struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); |
| 47 | + unsigned long alignmask = crypto_ablkcipher_alignmask(tfm); |
26 | 48 |
|
27 | 49 | if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { |
28 | 50 | crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); |
29 | 51 | return -EINVAL; |
30 | 52 | } |
31 | 53 |
|
| 54 | + if ((unsigned long)key & alignmask) |
| 55 | + return setkey_unaligned(tfm, key, keylen); |
| 56 | + |
32 | 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 | 91 | seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); |
67 | 92 | seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); |
68 | 93 | 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); |
| 94 | + if (ablkcipher->queue) { |
| 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 | 100 | const struct crypto_type crypto_ablkcipher_type = { |
|
0 commit comments