crypto: bcm - convert to use crypto_authenc_extractkeys()
commitab57b33525
upstream. 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:9d12ba86f8
("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
d196d2fdc0
Коммит
7c5f00e898
|
@ -679,6 +679,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
|
||||||
|
|
|
@ -2846,44 +2846,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)
|
memcpy(ctx->enckey, keys.enckey, keys.enckeylen);
|
||||||
goto badkey;
|
|
||||||
|
|
||||||
memcpy(ctx->enckey, key + ctx->authkeylen, ctx->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:
|
||||||
|
@ -2891,7 +2875,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);
|
||||||
|
@ -2906,7 +2890,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])) ||
|
||||||
|
@ -2957,9 +2941,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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче