aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-12-17 02:23:24 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2019-01-10 08:37:31 -0500
commitdc95b5350a8f07d73d6bde3a79ef87289698451d (patch)
tree4ea06871dad4cca82d5c60e0f424048e8e0c49a1
parentab57b33525c3221afaebd391458fa0cbcd56903d (diff)
crypto: ccree - convert to use crypto_authenc_extractkeys()
Convert the ccree crypto driver to use crypto_authenc_extractkeys() so that it picks up the fix for broken validation of rtattr::rta_len. Fixes: ff27e85a85bb ("crypto: ccree - add AEAD support") Cc: <stable@vger.kernel.org> # v4.17+ Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/ccree/cc_aead.c40
1 files changed, 19 insertions, 21 deletions
diff --git a/drivers/crypto/ccree/cc_aead.c b/drivers/crypto/ccree/cc_aead.c
index f2643cda45db..a3527c00b29a 100644
--- a/drivers/crypto/ccree/cc_aead.c
+++ b/drivers/crypto/ccree/cc_aead.c
@@ -549,13 +549,12 @@ static int cc_aead_setkey(struct crypto_aead *tfm, const u8 *key,
549 unsigned int keylen) 549 unsigned int keylen)
550{ 550{
551 struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); 551 struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm);
552 struct rtattr *rta = (struct rtattr *)key;
553 struct cc_crypto_req cc_req = {}; 552 struct cc_crypto_req cc_req = {};
554 struct crypto_authenc_key_param *param;
555 struct cc_hw_desc desc[MAX_AEAD_SETKEY_SEQ]; 553 struct cc_hw_desc desc[MAX_AEAD_SETKEY_SEQ];
556 int rc = -EINVAL;
557 unsigned int seq_len = 0; 554 unsigned int seq_len = 0;
558 struct device *dev = drvdata_to_dev(ctx->drvdata); 555 struct device *dev = drvdata_to_dev(ctx->drvdata);
556 const u8 *enckey, *authkey;
557 int rc;
559 558
560 dev_dbg(dev, "Setting key in context @%p for %s. key=%p keylen=%u\n", 559 dev_dbg(dev, "Setting key in context @%p for %s. key=%p keylen=%u\n",
561 ctx, crypto_tfm_alg_name(crypto_aead_tfm(tfm)), key, keylen); 560 ctx, crypto_tfm_alg_name(crypto_aead_tfm(tfm)), key, keylen);
@@ -563,35 +562,33 @@ static int cc_aead_setkey(struct crypto_aead *tfm, const u8 *key,
563 /* STAT_PHASE_0: Init and sanity checks */ 562 /* STAT_PHASE_0: Init and sanity checks */
564 563
565 if (ctx->auth_mode != DRV_HASH_NULL) { /* authenc() alg. */ 564 if (ctx->auth_mode != DRV_HASH_NULL) { /* authenc() alg. */
566 if (!RTA_OK(rta, keylen)) 565 struct crypto_authenc_keys keys;
567 goto badkey; 566
568 if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) 567 rc = crypto_authenc_extractkeys(&keys, key, keylen);
569 goto badkey; 568 if (rc)
570 if (RTA_PAYLOAD(rta) < sizeof(*param))
571 goto badkey;
572 param = RTA_DATA(rta);
573 ctx->enc_keylen = be32_to_cpu(param->enckeylen);
574 key += RTA_ALIGN(rta->rta_len);
575 keylen -= RTA_ALIGN(rta->rta_len);
576 if (keylen < ctx->enc_keylen)
577 goto badkey; 569 goto badkey;
578 ctx->auth_keylen = keylen - ctx->enc_keylen; 570 enckey = keys.enckey;
571 authkey = keys.authkey;
572 ctx->enc_keylen = keys.enckeylen;
573 ctx->auth_keylen = keys.authkeylen;
579 574
580 if (ctx->cipher_mode == DRV_CIPHER_CTR) { 575 if (ctx->cipher_mode == DRV_CIPHER_CTR) {
581 /* the nonce is stored in bytes at end of key */ 576 /* the nonce is stored in bytes at end of key */
577 rc = -EINVAL;
582 if (ctx->enc_keylen < 578 if (ctx->enc_keylen <
583 (AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE)) 579 (AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE))
584 goto badkey; 580 goto badkey;
585 /* Copy nonce from last 4 bytes in CTR key to 581 /* Copy nonce from last 4 bytes in CTR key to
586 * first 4 bytes in CTR IV 582 * first 4 bytes in CTR IV
587 */ 583 */
588 memcpy(ctx->ctr_nonce, key + ctx->auth_keylen + 584 memcpy(ctx->ctr_nonce, enckey + ctx->enc_keylen -
589 ctx->enc_keylen - CTR_RFC3686_NONCE_SIZE, 585 CTR_RFC3686_NONCE_SIZE, CTR_RFC3686_NONCE_SIZE);
590 CTR_RFC3686_NONCE_SIZE);
591 /* Set CTR key size */ 586 /* Set CTR key size */
592 ctx->enc_keylen -= CTR_RFC3686_NONCE_SIZE; 587 ctx->enc_keylen -= CTR_RFC3686_NONCE_SIZE;
593 } 588 }
594 } else { /* non-authenc - has just one key */ 589 } else { /* non-authenc - has just one key */
590 enckey = key;
591 authkey = NULL;
595 ctx->enc_keylen = keylen; 592 ctx->enc_keylen = keylen;
596 ctx->auth_keylen = 0; 593 ctx->auth_keylen = 0;
597 } 594 }
@@ -603,13 +600,14 @@ static int cc_aead_setkey(struct crypto_aead *tfm, const u8 *key,
603 /* STAT_PHASE_1: Copy key to ctx */ 600 /* STAT_PHASE_1: Copy key to ctx */
604 601
605 /* Get key material */ 602 /* Get key material */
606 memcpy(ctx->enckey, key + ctx->auth_keylen, ctx->enc_keylen); 603 memcpy(ctx->enckey, enckey, ctx->enc_keylen);
607 if (ctx->enc_keylen == 24) 604 if (ctx->enc_keylen == 24)
608 memset(ctx->enckey + 24, 0, CC_AES_KEY_SIZE_MAX - 24); 605 memset(ctx->enckey + 24, 0, CC_AES_KEY_SIZE_MAX - 24);
609 if (ctx->auth_mode == DRV_HASH_XCBC_MAC) { 606 if (ctx->auth_mode == DRV_HASH_XCBC_MAC) {
610 memcpy(ctx->auth_state.xcbc.xcbc_keys, key, ctx->auth_keylen); 607 memcpy(ctx->auth_state.xcbc.xcbc_keys, authkey,
608 ctx->auth_keylen);
611 } else if (ctx->auth_mode != DRV_HASH_NULL) { /* HMAC */ 609 } else if (ctx->auth_mode != DRV_HASH_NULL) { /* HMAC */
612 rc = cc_get_plain_hmac_key(tfm, key, ctx->auth_keylen); 610 rc = cc_get_plain_hmac_key(tfm, authkey, ctx->auth_keylen);
613 if (rc) 611 if (rc)
614 goto badkey; 612 goto badkey;
615 } 613 }