aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/cipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/cipher.c')
-rw-r--r--crypto/cipher.c33
1 files changed, 30 insertions, 3 deletions
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 *,