diff options
Diffstat (limited to 'drivers/crypto/bcm/cipher.c')
| -rw-r--r-- | drivers/crypto/bcm/cipher.c | 44 |
1 files changed, 13 insertions, 31 deletions
diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c index c9393ffb70ed..5567cbda2798 100644 --- a/drivers/crypto/bcm/cipher.c +++ b/drivers/crypto/bcm/cipher.c | |||
| @@ -2845,44 +2845,28 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, | |||
| 2845 | struct spu_hw *spu = &iproc_priv.spu; | 2845 | struct spu_hw *spu = &iproc_priv.spu; |
| 2846 | struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher); | 2846 | struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher); |
| 2847 | struct crypto_tfm *tfm = crypto_aead_tfm(cipher); | 2847 | struct crypto_tfm *tfm = crypto_aead_tfm(cipher); |
| 2848 | struct rtattr *rta = (void *)key; | 2848 | struct crypto_authenc_keys keys; |
| 2849 | struct crypto_authenc_key_param *param; | 2849 | int ret; |
| 2850 | const u8 *origkey = key; | ||
| 2851 | const unsigned int origkeylen = keylen; | ||
| 2852 | |||
| 2853 | int ret = 0; | ||
| 2854 | 2850 | ||
| 2855 | flow_log("%s() aead:%p key:%p keylen:%u\n", __func__, cipher, key, | 2851 | flow_log("%s() aead:%p key:%p keylen:%u\n", __func__, cipher, key, |
| 2856 | keylen); | 2852 | keylen); |
| 2857 | flow_dump(" key: ", key, keylen); | 2853 | flow_dump(" key: ", key, keylen); |
| 2858 | 2854 | ||
| 2859 | if (!RTA_OK(rta, keylen)) | 2855 | ret = crypto_authenc_extractkeys(&keys, key, keylen); |
| 2860 | goto badkey; | 2856 | if (ret) |
| 2861 | if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) | ||
| 2862 | goto badkey; | ||
| 2863 | if (RTA_PAYLOAD(rta) < sizeof(*param)) | ||
| 2864 | goto badkey; | 2857 | goto badkey; |
| 2865 | 2858 | ||
| 2866 | param = RTA_DATA(rta); | 2859 | if (keys.enckeylen > MAX_KEY_SIZE || |
| 2867 | ctx->enckeylen = be32_to_cpu(param->enckeylen); | 2860 | keys.authkeylen > MAX_KEY_SIZE) |
| 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) | ||
| 2875 | goto badkey; | 2861 | goto badkey; |
| 2876 | 2862 | ||
| 2877 | ctx->authkeylen = keylen - ctx->enckeylen; | 2863 | ctx->enckeylen = keys.enckeylen; |
| 2878 | 2864 | ctx->authkeylen = keys.authkeylen; | |
| 2879 | if (ctx->authkeylen > MAX_KEY_SIZE) | ||
| 2880 | goto badkey; | ||
| 2881 | 2865 | ||
| 2882 | memcpy(ctx->enckey, key + ctx->authkeylen, ctx->enckeylen); | 2866 | memcpy(ctx->enckey, keys.enckey, keys.enckeylen); |
| 2883 | /* May end up padding auth key. So make sure it's zeroed. */ | 2867 | /* May end up padding auth key. So make sure it's zeroed. */ |
| 2884 | memset(ctx->authkey, 0, sizeof(ctx->authkey)); | 2868 | memset(ctx->authkey, 0, sizeof(ctx->authkey)); |
| 2885 | memcpy(ctx->authkey, key, ctx->authkeylen); | 2869 | memcpy(ctx->authkey, keys.authkey, keys.authkeylen); |
| 2886 | 2870 | ||
| 2887 | switch (ctx->alg->cipher_info.alg) { | 2871 | switch (ctx->alg->cipher_info.alg) { |
| 2888 | case CIPHER_ALG_DES: | 2872 | case CIPHER_ALG_DES: |
| @@ -2890,7 +2874,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, | |||
| 2890 | u32 tmp[DES_EXPKEY_WORDS]; | 2874 | u32 tmp[DES_EXPKEY_WORDS]; |
| 2891 | u32 flags = CRYPTO_TFM_RES_WEAK_KEY; | 2875 | u32 flags = CRYPTO_TFM_RES_WEAK_KEY; |
| 2892 | 2876 | ||
| 2893 | if (des_ekey(tmp, key) == 0) { | 2877 | if (des_ekey(tmp, keys.enckey) == 0) { |
| 2894 | if (crypto_aead_get_flags(cipher) & | 2878 | if (crypto_aead_get_flags(cipher) & |
| 2895 | CRYPTO_TFM_REQ_WEAK_KEY) { | 2879 | CRYPTO_TFM_REQ_WEAK_KEY) { |
| 2896 | crypto_aead_set_flags(cipher, flags); | 2880 | crypto_aead_set_flags(cipher, flags); |
| @@ -2905,7 +2889,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, | |||
| 2905 | break; | 2889 | break; |
| 2906 | case CIPHER_ALG_3DES: | 2890 | case CIPHER_ALG_3DES: |
| 2907 | if (ctx->enckeylen == (DES_KEY_SIZE * 3)) { | 2891 | if (ctx->enckeylen == (DES_KEY_SIZE * 3)) { |
| 2908 | const u32 *K = (const u32 *)key; | 2892 | const u32 *K = (const u32 *)keys.enckey; |
| 2909 | u32 flags = CRYPTO_TFM_RES_BAD_KEY_SCHED; | 2893 | u32 flags = CRYPTO_TFM_RES_BAD_KEY_SCHED; |
| 2910 | 2894 | ||
| 2911 | if (!((K[0] ^ K[2]) | (K[1] ^ K[3])) || | 2895 | if (!((K[0] ^ K[2]) | (K[1] ^ K[3])) || |
| @@ -2956,9 +2940,7 @@ static int aead_authenc_setkey(struct crypto_aead *cipher, | |||
| 2956 | ctx->fallback_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; | 2940 | ctx->fallback_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; |
| 2957 | ctx->fallback_cipher->base.crt_flags |= | 2941 | ctx->fallback_cipher->base.crt_flags |= |
| 2958 | tfm->crt_flags & CRYPTO_TFM_REQ_MASK; | 2942 | tfm->crt_flags & CRYPTO_TFM_REQ_MASK; |
| 2959 | ret = | 2943 | ret = crypto_aead_setkey(ctx->fallback_cipher, key, keylen); |
| 2960 | crypto_aead_setkey(ctx->fallback_cipher, origkey, | ||
| 2961 | origkeylen); | ||
| 2962 | if (ret) { | 2944 | if (ret) { |
| 2963 | flow_log(" fallback setkey() returned:%d\n", ret); | 2945 | flow_log(" fallback setkey() returned:%d\n", ret); |
| 2964 | tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; | 2946 | tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; |
