| From f52b869701afb5d4126cde6a2265adc50a7a98b2 Mon Sep 17 00:00:00 2001 |
| From: Eric Biggers <ebiggers@google.com> |
| Date: Mon, 30 Dec 2019 21:19:31 -0600 |
| Subject: [PATCH] crypto: chelsio - fix writing tfm flags to wrong place |
| |
| commit bd56cea012fc2d6381e8cd3209510ce09f9de8c9 upstream. |
| |
| The chelsio crypto driver is casting 'struct crypto_aead' directly to |
| 'struct crypto_tfm', which is incorrect because the crypto_tfm isn't the |
| first field of 'struct crypto_aead'. Consequently, the calls to |
| crypto_tfm_set_flags() are modifying some other field in the struct. |
| |
| Also, the driver is setting CRYPTO_TFM_RES_BAD_KEY_LEN in |
| ->setauthsize(), not just in ->setkey(). This is incorrect since this |
| flag is for bad key lengths, not for bad authentication tag lengths. |
| |
| Fix these bugs by removing the broken crypto_tfm_set_flags() calls from |
| ->setauthsize() and by fixing them in ->setkey(). |
| |
| Fixes: 324429d74127 ("chcr: Support for Chelsio's Crypto Hardware") |
| Cc: <stable@vger.kernel.org> # v4.9+ |
| Cc: Atul Gupta <atul.gupta@chelsio.com> |
| Signed-off-by: Eric Biggers <ebiggers@google.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c |
| index 177f572b9589..c40b4f3e14aa 100644 |
| --- a/drivers/crypto/chelsio/chcr_algo.c |
| +++ b/drivers/crypto/chelsio/chcr_algo.c |
| @@ -3206,9 +3206,6 @@ static int chcr_gcm_setauthsize(struct crypto_aead *tfm, unsigned int authsize) |
| aeadctx->mayverify = VERIFY_SW; |
| break; |
| default: |
| - |
| - crypto_tfm_set_flags((struct crypto_tfm *) tfm, |
| - CRYPTO_TFM_RES_BAD_KEY_LEN); |
| return -EINVAL; |
| } |
| return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize); |
| @@ -3233,8 +3230,6 @@ static int chcr_4106_4309_setauthsize(struct crypto_aead *tfm, |
| aeadctx->mayverify = VERIFY_HW; |
| break; |
| default: |
| - crypto_tfm_set_flags((struct crypto_tfm *)tfm, |
| - CRYPTO_TFM_RES_BAD_KEY_LEN); |
| return -EINVAL; |
| } |
| return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize); |
| @@ -3275,8 +3270,6 @@ static int chcr_ccm_setauthsize(struct crypto_aead *tfm, |
| aeadctx->mayverify = VERIFY_HW; |
| break; |
| default: |
| - crypto_tfm_set_flags((struct crypto_tfm *)tfm, |
| - CRYPTO_TFM_RES_BAD_KEY_LEN); |
| return -EINVAL; |
| } |
| return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize); |
| @@ -3301,8 +3294,7 @@ static int chcr_ccm_common_setkey(struct crypto_aead *aead, |
| ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256; |
| mk_size = CHCR_KEYCTX_MAC_KEY_SIZE_256; |
| } else { |
| - crypto_tfm_set_flags((struct crypto_tfm *)aead, |
| - CRYPTO_TFM_RES_BAD_KEY_LEN); |
| + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); |
| aeadctx->enckey_len = 0; |
| return -EINVAL; |
| } |
| @@ -3340,8 +3332,7 @@ static int chcr_aead_rfc4309_setkey(struct crypto_aead *aead, const u8 *key, |
| int error; |
| |
| if (keylen < 3) { |
| - crypto_tfm_set_flags((struct crypto_tfm *)aead, |
| - CRYPTO_TFM_RES_BAD_KEY_LEN); |
| + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); |
| aeadctx->enckey_len = 0; |
| return -EINVAL; |
| } |
| @@ -3391,8 +3382,7 @@ static int chcr_gcm_setkey(struct crypto_aead *aead, const u8 *key, |
| } else if (keylen == AES_KEYSIZE_256) { |
| ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256; |
| } else { |
| - crypto_tfm_set_flags((struct crypto_tfm *)aead, |
| - CRYPTO_TFM_RES_BAD_KEY_LEN); |
| + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); |
| pr_err("GCM: Invalid key length %d\n", keylen); |
| ret = -EINVAL; |
| goto out; |
| -- |
| 2.7.4 |
| |