Skip to content

Commit

Permalink
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/herbert/crypto-2.6

Pull crypto fix from Herbert Xu:
 "This fixes a regression in the skcipher interface that allows bogus
  key parameters to hit underlying implementations which can cause
  crashes"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: skcipher - Add missing API setkey checks
  • Loading branch information
torvalds committed May 23, 2017
2 parents fadd2ce + 9933e11 commit fde8e33
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion crypto/skcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,44 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
return 0;
}

static int skcipher_setkey_unaligned(struct crypto_skcipher *tfm,
const u8 *key, unsigned int keylen)
{
unsigned long alignmask = crypto_skcipher_alignmask(tfm);
struct skcipher_alg *cipher = crypto_skcipher_alg(tfm);
u8 *buffer, *alignbuffer;
unsigned long absize;
int ret;

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);
kzfree(buffer);
return ret;
}

static int skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keylen)
{
struct skcipher_alg *cipher = crypto_skcipher_alg(tfm);
unsigned long alignmask = crypto_skcipher_alignmask(tfm);

if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}

if ((unsigned long)key & alignmask)
return skcipher_setkey_unaligned(tfm, key, keylen);

return cipher->setkey(tfm, key, keylen);
}

static void crypto_skcipher_exit_tfm(struct crypto_tfm *tfm)
{
struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
Expand All @@ -784,7 +822,7 @@ static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
tfm->__crt_alg->cra_type == &crypto_givcipher_type)
return crypto_init_skcipher_ops_ablkcipher(tfm);

skcipher->setkey = alg->setkey;
skcipher->setkey = skcipher_setkey;
skcipher->encrypt = alg->encrypt;
skcipher->decrypt = alg->decrypt;
skcipher->ivsize = alg->ivsize;
Expand Down

0 comments on commit fde8e33

Please sign in to comment.