diff options
author | Horia Geanta <horia.geanta@freescale.com> | 2013-12-19 10:27:35 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2013-12-20 07:06:27 -0500 |
commit | 4e6e0b272d5af0c9c4f4215248130e58d68bcf0f (patch) | |
tree | 62ce1cd056846a8556cbd87bb397fc68b7e8bd52 /drivers/crypto | |
parent | acef7b0f2b7da3cac01cd6fa5ee61e695bbfc217 (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.c | 36 |
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; |