diff options
author | Eric Biggers <ebiggers@google.com> | 2018-12-17 02:23:24 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2019-01-10 08:37:31 -0500 |
commit | dc95b5350a8f07d73d6bde3a79ef87289698451d (patch) | |
tree | 4ea06871dad4cca82d5c60e0f424048e8e0c49a1 | |
parent | ab57b33525c3221afaebd391458fa0cbcd56903d (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.c | 40 |
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 | } |