diff options
Diffstat (limited to 'drivers/crypto/ccp/ccp-ops.c')
| -rw-r--r-- | drivers/crypto/ccp/ccp-ops.c | 89 | 
1 files changed, 56 insertions, 33 deletions
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c index c69ed4bae2eb..c8da8eb160da 100644 --- a/drivers/crypto/ccp/ccp-ops.c +++ b/drivers/crypto/ccp/ccp-ops.c @@ -10,7 +10,6 @@  #include <linux/module.h>  #include <linux/kernel.h> -#include <linux/pci.h>  #include <linux/interrupt.h>  #include <crypto/scatterwalk.h>  #include <crypto/des.h> @@ -150,14 +149,13 @@ static int ccp_init_dm_workarea(struct ccp_dm_workarea *wa,  	if (len <= CCP_DMAPOOL_MAX_SIZE) {  		wa->dma_pool = cmd_q->dma_pool; -		wa->address = dma_pool_alloc(wa->dma_pool, GFP_KERNEL, +		wa->address = dma_pool_zalloc(wa->dma_pool, GFP_KERNEL,  					     &wa->dma.address);  		if (!wa->address)  			return -ENOMEM;  		wa->dma.length = CCP_DMAPOOL_MAX_SIZE; -		memset(wa->address, 0, CCP_DMAPOOL_MAX_SIZE);  	} else {  		wa->address = kzalloc(len, GFP_KERNEL);  		if (!wa->address) @@ -455,8 +453,8 @@ static int ccp_copy_from_sb(struct ccp_cmd_queue *cmd_q,  	return ccp_copy_to_from_sb(cmd_q, wa, jobid, sb, byte_swap, true);  } -static int ccp_run_aes_cmac_cmd(struct ccp_cmd_queue *cmd_q, -				struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_aes_cmac_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_aes_engine *aes = &cmd->u.aes;  	struct ccp_dm_workarea key, ctx; @@ -611,8 +609,8 @@ e_key:  	return ret;  } -static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, -			       struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_aes_engine *aes = &cmd->u.aes;  	struct ccp_dm_workarea key, ctx, final_wa, tag; @@ -622,6 +620,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,  	unsigned long long *final;  	unsigned int dm_offset; +	unsigned int authsize;  	unsigned int jobid;  	unsigned int ilen;  	bool in_place = true; /* Default value */ @@ -643,6 +642,21 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,  	if (!aes->key) /* Gotta have a key SGL */  		return -EINVAL; +	/* Zero defaults to 16 bytes, the maximum size */ +	authsize = aes->authsize ? aes->authsize : AES_BLOCK_SIZE; +	switch (authsize) { +	case 16: +	case 15: +	case 14: +	case 13: +	case 12: +	case 8: +	case 4: +		break; +	default: +		return -EINVAL; +	} +  	/* First, decompose the source buffer into AAD & PT,  	 * and the destination buffer into AAD, CT & tag, or  	 * the input into CT & tag. @@ -657,7 +671,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,  		p_tag = scatterwalk_ffwd(sg_tag, p_outp, ilen);  	} else {  		/* Input length for decryption includes tag */ -		ilen = aes->src_len - AES_BLOCK_SIZE; +		ilen = aes->src_len - authsize;  		p_tag = scatterwalk_ffwd(sg_tag, p_inp, ilen);  	} @@ -766,8 +780,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,  		while (src.sg_wa.bytes_left) {  			ccp_prepare_data(&src, &dst, &op, AES_BLOCK_SIZE, true);  			if (!src.sg_wa.bytes_left) { -				unsigned int nbytes = aes->src_len -						      % AES_BLOCK_SIZE; +				unsigned int nbytes = ilen % AES_BLOCK_SIZE;  				if (nbytes) {  					op.eom = 1; @@ -839,19 +852,19 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q,  	if (aes->action == CCP_AES_ACTION_ENCRYPT) {  		/* Put the ciphered tag after the ciphertext. */ -		ccp_get_dm_area(&final_wa, 0, p_tag, 0, AES_BLOCK_SIZE); +		ccp_get_dm_area(&final_wa, 0, p_tag, 0, authsize);  	} else {  		/* Does this ciphered tag match the input? */ -		ret = ccp_init_dm_workarea(&tag, cmd_q, AES_BLOCK_SIZE, +		ret = ccp_init_dm_workarea(&tag, cmd_q, authsize,  					   DMA_BIDIRECTIONAL);  		if (ret)  			goto e_tag; -		ret = ccp_set_dm_area(&tag, 0, p_tag, 0, AES_BLOCK_SIZE); +		ret = ccp_set_dm_area(&tag, 0, p_tag, 0, authsize);  		if (ret)  			goto e_tag;  		ret = crypto_memneq(tag.address, final_wa.address, -				    AES_BLOCK_SIZE) ? -EBADMSG : 0; +				    authsize) ? -EBADMSG : 0;  		ccp_dm_free(&tag);  	} @@ -859,11 +872,11 @@ e_tag:  	ccp_dm_free(&final_wa);  e_dst: -	if (aes->src_len && !in_place) +	if (ilen > 0 && !in_place)  		ccp_free_data(&dst, cmd_q);  e_src: -	if (aes->src_len) +	if (ilen > 0)  		ccp_free_data(&src, cmd_q);  e_aad: @@ -879,7 +892,8 @@ e_key:  	return ret;  } -static int ccp_run_aes_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_aes_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_aes_engine *aes = &cmd->u.aes;  	struct ccp_dm_workarea key, ctx; @@ -889,12 +903,6 @@ static int ccp_run_aes_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  	bool in_place = false;  	int ret; -	if (aes->mode == CCP_AES_MODE_CMAC) -		return ccp_run_aes_cmac_cmd(cmd_q, cmd); - -	if (aes->mode == CCP_AES_MODE_GCM) -		return ccp_run_aes_gcm_cmd(cmd_q, cmd); -  	if (!((aes->key_len == AES_KEYSIZE_128) ||  	      (aes->key_len == AES_KEYSIZE_192) ||  	      (aes->key_len == AES_KEYSIZE_256))) @@ -1061,8 +1069,8 @@ e_key:  	return ret;  } -static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q, -			       struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_xts_aes_engine *xts = &cmd->u.xts;  	struct ccp_dm_workarea key, ctx; @@ -1261,7 +1269,8 @@ e_key:  	return ret;  } -static int ccp_run_des3_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_des3_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_des3_engine *des3 = &cmd->u.des3; @@ -1457,7 +1466,8 @@ e_key:  	return ret;  } -static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_sha_engine *sha = &cmd->u.sha;  	struct ccp_dm_workarea ctx; @@ -1801,7 +1811,8 @@ e_ctx:  	return ret;  } -static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_rsa_engine *rsa = &cmd->u.rsa;  	struct ccp_dm_workarea exp, src, dst; @@ -1932,8 +1943,8 @@ e_sb:  	return ret;  } -static int ccp_run_passthru_cmd(struct ccp_cmd_queue *cmd_q, -				struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_passthru_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_passthru_engine *pt = &cmd->u.passthru;  	struct ccp_dm_workarea mask; @@ -2064,7 +2075,8 @@ e_mask:  	return ret;  } -static int ccp_run_passthru_nomap_cmd(struct ccp_cmd_queue *cmd_q, +static noinline_for_stack int +ccp_run_passthru_nomap_cmd(struct ccp_cmd_queue *cmd_q,  				      struct ccp_cmd *cmd)  {  	struct ccp_passthru_nomap_engine *pt = &cmd->u.passthru_nomap; @@ -2405,7 +2417,8 @@ e_src:  	return ret;  } -static int ccp_run_ecc_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) +static noinline_for_stack int +ccp_run_ecc_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  {  	struct ccp_ecc_engine *ecc = &cmd->u.ecc; @@ -2442,7 +2455,17 @@ int ccp_run_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)  	switch (cmd->engine) {  	case CCP_ENGINE_AES: -		ret = ccp_run_aes_cmd(cmd_q, cmd); +		switch (cmd->u.aes.mode) { +		case CCP_AES_MODE_CMAC: +			ret = ccp_run_aes_cmac_cmd(cmd_q, cmd); +			break; +		case CCP_AES_MODE_GCM: +			ret = ccp_run_aes_gcm_cmd(cmd_q, cmd); +			break; +		default: +			ret = ccp_run_aes_cmd(cmd_q, cmd); +			break; +		}  		break;  	case CCP_ENGINE_XTS_AES_128:  		ret = ccp_run_xts_aes_cmd(cmd_q, cmd);  | 
