diff options
Diffstat (limited to 'drivers/crypto/bcm/cipher.c')
| -rw-r--r-- | drivers/crypto/bcm/cipher.c | 92 | 
1 files changed, 30 insertions, 62 deletions
diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c index 869602fcfd96..f85356a48e7e 100644 --- a/drivers/crypto/bcm/cipher.c +++ b/drivers/crypto/bcm/cipher.c @@ -24,7 +24,7 @@  #include <crypto/aead.h>  #include <crypto/internal/aead.h>  #include <crypto/aes.h> -#include <crypto/des.h> +#include <crypto/internal/des.h>  #include <crypto/hmac.h>  #include <crypto/sha.h>  #include <crypto/md5.h> @@ -1802,24 +1802,13 @@ static int des_setkey(struct crypto_ablkcipher *cipher, const u8 *key,  		      unsigned int keylen)  {  	struct iproc_ctx_s *ctx = crypto_ablkcipher_ctx(cipher); -	u32 tmp[DES_EXPKEY_WORDS]; - -	if (keylen == DES_KEY_SIZE) { -		if (des_ekey(tmp, key) == 0) { -			if (crypto_ablkcipher_get_flags(cipher) & -			    CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) { -				u32 flags = CRYPTO_TFM_RES_WEAK_KEY; +	int err; -				crypto_ablkcipher_set_flags(cipher, flags); -				return -EINVAL; -			} -		} +	err = verify_ablkcipher_des_key(cipher, key); +	if (err) +		return err; -		ctx->cipher_type = CIPHER_TYPE_DES; -	} else { -		crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); -		return -EINVAL; -	} +	ctx->cipher_type = CIPHER_TYPE_DES;  	return 0;  } @@ -1827,23 +1816,13 @@ static int threedes_setkey(struct crypto_ablkcipher *cipher, const u8 *key,  			   unsigned int keylen)  {  	struct iproc_ctx_s *ctx = crypto_ablkcipher_ctx(cipher); +	int err; -	if (keylen == (DES_KEY_SIZE * 3)) { -		u32 flags; -		int ret; - -		flags = crypto_ablkcipher_get_flags(cipher); -		ret = __des3_verify_key(&flags, key); -		if (unlikely(ret)) { -			crypto_ablkcipher_set_flags(cipher, flags); -			return ret; -		} +	err = verify_ablkcipher_des3_key(cipher, key); +	if (err) +		return err; -		ctx->cipher_type = CIPHER_TYPE_3DES; -	} else { -		crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); -		return -EINVAL; -	} +	ctx->cipher_type = CIPHER_TYPE_3DES;  	return 0;  } @@ -2629,6 +2608,19 @@ static int aead_need_fallback(struct aead_request *req)  		return 1;  	} +	/* +	 * RFC4106 and RFC4543 cannot handle the case where AAD is other than +	 * 16 or 20 bytes long. So use fallback in this case. +	 */ +	if (ctx->cipher.mode == CIPHER_MODE_GCM && +	    ctx->cipher.alg == CIPHER_ALG_AES && +	    rctx->iv_ctr_len == GCM_RFC4106_IV_SIZE && +	    req->assoclen != 16 && req->assoclen != 20) { +		flow_log("RFC4106/RFC4543 needs fallback for assoclen" +			 " other than 16 or 20 bytes\n"); +		return 1; +	} +  	payload_len = req->cryptlen;  	if (spu->spu_type == SPU_TYPE_SPUM)  		payload_len += req->assoclen; @@ -2855,40 +2847,16 @@ static int aead_authenc_setkey(struct crypto_aead *cipher,  	switch (ctx->alg->cipher_info.alg) {  	case CIPHER_ALG_DES: -		if (ctx->enckeylen == DES_KEY_SIZE) { -			u32 tmp[DES_EXPKEY_WORDS]; -			u32 flags = CRYPTO_TFM_RES_WEAK_KEY; - -			if (des_ekey(tmp, keys.enckey) == 0) { -				if (crypto_aead_get_flags(cipher) & -				    CRYPTO_TFM_REQ_FORBID_WEAK_KEYS) { -					crypto_aead_set_flags(cipher, flags); -					return -EINVAL; -				} -			} +		if (verify_aead_des_key(cipher, keys.enckey, keys.enckeylen)) +			return -EINVAL; -			ctx->cipher_type = CIPHER_TYPE_DES; -		} else { -			goto badkey; -		} +		ctx->cipher_type = CIPHER_TYPE_DES;  		break;  	case CIPHER_ALG_3DES: -		if (ctx->enckeylen == (DES_KEY_SIZE * 3)) { -			u32 flags; - -			flags = crypto_aead_get_flags(cipher); -			ret = __des3_verify_key(&flags, keys.enckey); -			if (unlikely(ret)) { -				crypto_aead_set_flags(cipher, flags); -				return ret; -			} - -			ctx->cipher_type = CIPHER_TYPE_3DES; -		} else { -			crypto_aead_set_flags(cipher, -					      CRYPTO_TFM_RES_BAD_KEY_LEN); +		if (verify_aead_des3_key(cipher, keys.enckey, keys.enckeylen))  			return -EINVAL; -		} + +		ctx->cipher_type = CIPHER_TYPE_3DES;  		break;  	case CIPHER_ALG_AES:  		switch (ctx->enckeylen) {  |