From ca7c39385ce1a7b44894a4b225a4608624e90730 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Sat, 19 May 2007 19:51:21 +1000 Subject: [CRYPTO] api: Handle unaligned keys in setkey setkey() in {cipher,blkcipher,ablkcipher,hash}.c does not respect the requested alignment by the algorithm. This patch fixes it. The extra memory is allocated by kmalloc() with GFP_ATOMIC flag. Signed-off-by: Sebastian Siewior Signed-off-by: Herbert Xu --- crypto/ablkcipher.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'crypto/ablkcipher.c') diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 9348ddd84a56..d45fa16dff81 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c @@ -19,16 +19,41 @@ #include #include +static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen) +{ + struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); + unsigned long alignmask = crypto_ablkcipher_alignmask(tfm); + int ret; + u8 *buffer, *alignbuffer; + unsigned long absize; + + absize = keylen + alignmask; + buffer = kmalloc(absize, GFP_ATOMIC); + if (!buffer) + return -ENOMEM; + + alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + memcpy(alignbuffer, key, keylen); + ret = cipher->setkey(tfm, alignbuffer, keylen); + memset(alignbuffer, 0, absize); + kfree(buffer); + return ret; +} + static int setkey(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen) { struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); + unsigned long alignmask = crypto_ablkcipher_alignmask(tfm); if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } + if ((unsigned long)key & alignmask) + return setkey_unaligned(tfm, key, keylen); + return cipher->setkey(tfm, key, keylen); } -- cgit v1.2.3-59-g8ed1b