X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=crypto%2Fcipher.c;h=9a1a7316eeacf6f71befe1b149283a4350db0c56;hb=28111eb2f5087c5aa5ec3697388f6c7d354b2ad8;hp=333aab2f027717fc96672ed74662d1c25d72b2ce;hpb=a727fea99bf4b2addcd64c596735148117a7b37f;p=pandora-kernel.git diff --git a/crypto/cipher.c b/crypto/cipher.c index 333aab2f0277..9a1a7316eeac 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -16,20 +16,48 @@ #include #include #include -#include +#include #include #include "internal.h" +static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen) +{ + struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; + unsigned long alignmask = crypto_tfm_alg_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 = cia->cia_setkey(tfm, alignbuffer, keylen); + memset(alignbuffer, 0, keylen); + kfree(buffer); + return ret; + +} + static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; - + unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); + tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; return -EINVAL; - } else - return cia->cia_setkey(tfm, key, keylen); + } + + if ((unsigned long)key & alignmask) + return setkey_unaligned(tfm, key, keylen); + + return cia->cia_setkey(tfm, key, keylen); } static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *,