aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorHoria Geanta <horia.geanta@freescale.com>2013-12-19 10:27:35 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2013-12-20 07:06:27 -0500
commit4e6e0b272d5af0c9c4f4215248130e58d68bcf0f (patch)
tree62ce1cd056846a8556cbd87bb397fc68b7e8bd52 /drivers/crypto
parentacef7b0f2b7da3cac01cd6fa5ee61e695bbfc217 (diff)
crypto: caam - simplify and harden key parsing
Use the common helper function crypto_authenc_extractkeys() for key parsing. Also fix the key buffer overflow condition: use split key pad length instead of authentication key length. Signed-off-by: Horia Geanta <horia.geanta@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/caamalg.c36
1 files changed, 13 insertions, 23 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 4cf5dec826e1..b71f2fd749df 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -467,24 +467,10 @@ static int aead_setkey(struct crypto_aead *aead,
467 static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 }; 467 static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
468 struct caam_ctx *ctx = crypto_aead_ctx(aead); 468 struct caam_ctx *ctx = crypto_aead_ctx(aead);
469 struct device *jrdev = ctx->jrdev; 469 struct device *jrdev = ctx->jrdev;
470 struct rtattr *rta = (void *)key; 470 struct crypto_authenc_keys keys;
471 struct crypto_authenc_key_param *param;
472 unsigned int authkeylen;
473 unsigned int enckeylen;
474 int ret = 0; 471 int ret = 0;
475 472
476 param = RTA_DATA(rta); 473 if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
477 enckeylen = be32_to_cpu(param->enckeylen);
478
479 key += RTA_ALIGN(rta->rta_len);
480 keylen -= RTA_ALIGN(rta->rta_len);
481
482 if (keylen < enckeylen)
483 goto badkey;
484
485 authkeylen = keylen - enckeylen;
486
487 if (keylen > CAAM_MAX_KEY_SIZE)
488 goto badkey; 474 goto badkey;
489 475
490 /* Pick class 2 key length from algorithm submask */ 476 /* Pick class 2 key length from algorithm submask */
@@ -492,25 +478,29 @@ static int aead_setkey(struct crypto_aead *aead,
492 OP_ALG_ALGSEL_SHIFT] * 2; 478 OP_ALG_ALGSEL_SHIFT] * 2;
493 ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16); 479 ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16);
494 480
481 if (ctx->split_key_pad_len + keys.enckeylen > CAAM_MAX_KEY_SIZE)
482 goto badkey;
483
495#ifdef DEBUG 484#ifdef DEBUG
496 printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n", 485 printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
497 keylen, enckeylen, authkeylen); 486 keys.authkeylen + keys.enckeylen, keys.enckeylen,
487 keys.authkeylen);
498 printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n", 488 printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n",
499 ctx->split_key_len, ctx->split_key_pad_len); 489 ctx->split_key_len, ctx->split_key_pad_len);
500 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ", 490 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
501 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 491 DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
502#endif 492#endif
503 493
504 ret = gen_split_aead_key(ctx, key, authkeylen); 494 ret = gen_split_aead_key(ctx, keys.authkey, keys.authkeylen);
505 if (ret) { 495 if (ret) {
506 goto badkey; 496 goto badkey;
507 } 497 }
508 498
509 /* postpend encryption key to auth split key */ 499 /* postpend encryption key to auth split key */
510 memcpy(ctx->key + ctx->split_key_pad_len, key + authkeylen, enckeylen); 500 memcpy(ctx->key + ctx->split_key_pad_len, keys.enckey, keys.enckeylen);
511 501
512 ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len + 502 ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len +
513 enckeylen, DMA_TO_DEVICE); 503 keys.enckeylen, DMA_TO_DEVICE);
514 if (dma_mapping_error(jrdev, ctx->key_dma)) { 504 if (dma_mapping_error(jrdev, ctx->key_dma)) {
515 dev_err(jrdev, "unable to map key i/o memory\n"); 505 dev_err(jrdev, "unable to map key i/o memory\n");
516 return -ENOMEM; 506 return -ENOMEM;
@@ -518,15 +508,15 @@ static int aead_setkey(struct crypto_aead *aead,
518#ifdef DEBUG 508#ifdef DEBUG
519 print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ", 509 print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
520 DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, 510 DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
521 ctx->split_key_pad_len + enckeylen, 1); 511 ctx->split_key_pad_len + keys.enckeylen, 1);
522#endif 512#endif
523 513
524 ctx->enckeylen = enckeylen; 514 ctx->enckeylen = keys.enckeylen;
525 515
526 ret = aead_set_sh_desc(aead); 516 ret = aead_set_sh_desc(aead);
527 if (ret) { 517 if (ret) {
528 dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len + 518 dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len +
529 enckeylen, DMA_TO_DEVICE); 519 keys.enckeylen, DMA_TO_DEVICE);
530 } 520 }
531 521
532 return ret; 522 return ret;