Commit ab57b335 authored by Eric Biggers's avatar Eric Biggers Committed by Herbert Xu

crypto: bcm - convert to use crypto_authenc_extractkeys()

Convert the bcm crypto driver to use crypto_authenc_extractkeys() so
that it picks up the fix for broken validation of rtattr::rta_len.

This also fixes the DES weak key check to actually be done on the right
key. (It was checking the authentication key, not the encryption key...)

Fixes: 9d12ba86 ("crypto: brcm - Add Broadcom SPU driver")
Cc: <stable@vger.kernel.org> # v4.11+
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 8f9c4693
...@@ -692,6 +692,7 @@ config CRYPTO_DEV_BCM_SPU ...@@ -692,6 +692,7 @@ config CRYPTO_DEV_BCM_SPU
depends on ARCH_BCM_IPROC depends on ARCH_BCM_IPROC
depends on MAILBOX depends on MAILBOX
default m default m
select CRYPTO_AUTHENC
select CRYPTO_DES select CRYPTO_DES
select CRYPTO_MD5 select CRYPTO_MD5
select CRYPTO_SHA1 select CRYPTO_SHA1
......
...@@ -2845,44 +2845,28 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, ...@@ -2845,44 +2845,28 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,
struct spu_hw *spu = &iproc_priv.spu; struct spu_hw *spu = &iproc_priv.spu;
struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher); struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);
struct crypto_tfm *tfm = crypto_aead_tfm(cipher); struct crypto_tfm *tfm = crypto_aead_tfm(cipher);
struct rtattr *rta = (void *)key; struct crypto_authenc_keys keys;
struct crypto_authenc_key_param *param; int ret;
const u8 *origkey = key;
const unsigned int origkeylen = keylen;
int ret = 0;
flow_log("%s() aead:%p key:%p keylen:%u\n", __func__, cipher, key, flow_log("%s() aead:%p key:%p keylen:%u\n", __func__, cipher, key,
keylen); keylen);
flow_dump(" key: ", key, keylen); flow_dump(" key: ", key, keylen);
if (!RTA_OK(rta, keylen)) ret = crypto_authenc_extractkeys(&keys, key, keylen);
goto badkey; if (ret)
if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
goto badkey;
if (RTA_PAYLOAD(rta) < sizeof(*param))
goto badkey; goto badkey;
param = RTA_DATA(rta); if (keys.enckeylen > MAX_KEY_SIZE ||
ctx->enckeylen = be32_to_cpu(param->enckeylen); keys.authkeylen > MAX_KEY_SIZE)
key += RTA_ALIGN(rta->rta_len);
keylen -= RTA_ALIGN(rta->rta_len);
if (keylen < ctx->enckeylen)
goto badkey;
if (ctx->enckeylen > MAX_KEY_SIZE)
goto badkey; goto badkey;
ctx->authkeylen = keylen - ctx->enckeylen; ctx->enckeylen = keys.enckeylen;
ctx->authkeylen = keys.authkeylen;
if (ctx->authkeylen > MAX_KEY_SIZE)
goto badkey;
memcpy(ctx->enckey, key + ctx->authkeylen, ctx->enckeylen); memcpy(ctx->enckey, keys.enckey, keys.enckeylen);
/* May end up padding auth key. So make sure it's zeroed. */ /* May end up padding auth key. So make sure it's zeroed. */
memset(ctx->authkey, 0, sizeof(ctx->authkey)); memset(ctx->authkey, 0, sizeof(ctx->authkey));
memcpy(ctx->authkey, key, ctx->authkeylen); memcpy(ctx->authkey, keys.authkey, keys.authkeylen);
switch (ctx->alg->cipher_info.alg) { switch (ctx->alg->cipher_info.alg) {
case CIPHER_ALG_DES: case CIPHER_ALG_DES:
...@@ -2890,7 +2874,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, ...@@ -2890,7 +2874,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,
u32 tmp[DES_EXPKEY_WORDS]; u32 tmp[DES_EXPKEY_WORDS];
u32 flags = CRYPTO_TFM_RES_WEAK_KEY; u32 flags = CRYPTO_TFM_RES_WEAK_KEY;
if (des_ekey(tmp, key) == 0) { if (des_ekey(tmp, keys.enckey) == 0) {
if (crypto_aead_get_flags(cipher) & if (crypto_aead_get_flags(cipher) &
CRYPTO_TFM_REQ_WEAK_KEY) { CRYPTO_TFM_REQ_WEAK_KEY) {
crypto_aead_set_flags(cipher, flags); crypto_aead_set_flags(cipher, flags);
...@@ -2905,7 +2889,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, ...@@ -2905,7 +2889,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,
break; break;
case CIPHER_ALG_3DES: case CIPHER_ALG_3DES:
if (ctx->enckeylen == (DES_KEY_SIZE * 3)) { if (ctx->enckeylen == (DES_KEY_SIZE * 3)) {
const u32 *K = (const u32 *)key; const u32 *K = (const u32 *)keys.enckey;
u32 flags = CRYPTO_TFM_RES_BAD_KEY_SCHED; u32 flags = CRYPTO_TFM_RES_BAD_KEY_SCHED;
if (!((K[0] ^ K[2]) | (K[1] ^ K[3])) || if (!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
...@@ -2956,9 +2940,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, ...@@ -2956,9 +2940,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,
ctx->fallback_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; ctx->fallback_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
ctx->fallback_cipher->base.crt_flags |= ctx->fallback_cipher->base.crt_flags |=
tfm->crt_flags & CRYPTO_TFM_REQ_MASK; tfm->crt_flags & CRYPTO_TFM_REQ_MASK;
ret = ret = crypto_aead_setkey(ctx->fallback_cipher, key, keylen);
crypto_aead_setkey(ctx->fallback_cipher, origkey,
origkeylen);
if (ret) { if (ret) {
flow_log(" fallback setkey() returned:%d\n", ret); flow_log(" fallback setkey() returned:%d\n", ret);
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment