Skip to content

Commit ab57b33

Browse files
ebiggersherbertx
authored andcommitted
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: 9d12ba8 ("crypto: brcm - Add Broadcom SPU driver") Cc: <stable@vger.kernel.org> # v4.11+ Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 8f9c469 commit ab57b33

File tree

2 files changed

+14
-31
lines changed

2 files changed

+14
-31
lines changed

drivers/crypto/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ config CRYPTO_DEV_BCM_SPU
692692
depends on ARCH_BCM_IPROC
693693
depends on MAILBOX
694694
default m
695+
select CRYPTO_AUTHENC
695696
select CRYPTO_DES
696697
select CRYPTO_MD5
697698
select CRYPTO_SHA1

drivers/crypto/bcm/cipher.c

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,52 +2845,36 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,
28452845
struct spu_hw *spu = &iproc_priv.spu;
28462846
struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher);
28472847
struct crypto_tfm *tfm = crypto_aead_tfm(cipher);
2848-
struct rtattr *rta = (void *)key;
2849-
struct crypto_authenc_key_param *param;
2850-
const u8 *origkey = key;
2851-
const unsigned int origkeylen = keylen;
2852-
2853-
int ret = 0;
2848+
struct crypto_authenc_keys keys;
2849+
int ret;
28542850

28552851
flow_log("%s() aead:%p key:%p keylen:%u\n", __func__, cipher, key,
28562852
keylen);
28572853
flow_dump(" key: ", key, keylen);
28582854

2859-
if (!RTA_OK(rta, keylen))
2860-
goto badkey;
2861-
if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
2862-
goto badkey;
2863-
if (RTA_PAYLOAD(rta) < sizeof(*param))
2855+
ret = crypto_authenc_extractkeys(&keys, key, keylen);
2856+
if (ret)
28642857
goto badkey;
28652858

2866-
param = RTA_DATA(rta);
2867-
ctx->enckeylen = be32_to_cpu(param->enckeylen);
2868-
2869-
key += RTA_ALIGN(rta->rta_len);
2870-
keylen -= RTA_ALIGN(rta->rta_len);
2871-
2872-
if (keylen < ctx->enckeylen)
2873-
goto badkey;
2874-
if (ctx->enckeylen > MAX_KEY_SIZE)
2859+
if (keys.enckeylen > MAX_KEY_SIZE ||
2860+
keys.authkeylen > MAX_KEY_SIZE)
28752861
goto badkey;
28762862

2877-
ctx->authkeylen = keylen - ctx->enckeylen;
2878-
2879-
if (ctx->authkeylen > MAX_KEY_SIZE)
2880-
goto badkey;
2863+
ctx->enckeylen = keys.enckeylen;
2864+
ctx->authkeylen = keys.authkeylen;
28812865

2882-
memcpy(ctx->enckey, key + ctx->authkeylen, ctx->enckeylen);
2866+
memcpy(ctx->enckey, keys.enckey, keys.enckeylen);
28832867
/* May end up padding auth key. So make sure it's zeroed. */
28842868
memset(ctx->authkey, 0, sizeof(ctx->authkey));
2885-
memcpy(ctx->authkey, key, ctx->authkeylen);
2869+
memcpy(ctx->authkey, keys.authkey, keys.authkeylen);
28862870

28872871
switch (ctx->alg->cipher_info.alg) {
28882872
case CIPHER_ALG_DES:
28892873
if (ctx->enckeylen == DES_KEY_SIZE) {
28902874
u32 tmp[DES_EXPKEY_WORDS];
28912875
u32 flags = CRYPTO_TFM_RES_WEAK_KEY;
28922876

2893-
if (des_ekey(tmp, key) == 0) {
2877+
if (des_ekey(tmp, keys.enckey) == 0) {
28942878
if (crypto_aead_get_flags(cipher) &
28952879
CRYPTO_TFM_REQ_WEAK_KEY) {
28962880
crypto_aead_set_flags(cipher, flags);
@@ -2905,7 +2889,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,
29052889
break;
29062890
case CIPHER_ALG_3DES:
29072891
if (ctx->enckeylen == (DES_KEY_SIZE * 3)) {
2908-
const u32 *K = (const u32 *)key;
2892+
const u32 *K = (const u32 *)keys.enckey;
29092893
u32 flags = CRYPTO_TFM_RES_BAD_KEY_SCHED;
29102894

29112895
if (!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
@@ -2956,9 +2940,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,
29562940
ctx->fallback_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
29572941
ctx->fallback_cipher->base.crt_flags |=
29582942
tfm->crt_flags & CRYPTO_TFM_REQ_MASK;
2959-
ret =
2960-
crypto_aead_setkey(ctx->fallback_cipher, origkey,
2961-
origkeylen);
2943+
ret = crypto_aead_setkey(ctx->fallback_cipher, key, keylen);
29622944
if (ret) {
29632945
flow_log(" fallback setkey() returned:%d\n", ret);
29642946
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;

0 commit comments

Comments
 (0)