crypto: ccp - Add support for valid authsize values less than 16
PATCH 1/1 crypto: ccp - Add support for valid authsize values less than 16
AES GCM encryption allows for authsize values of 4, 8, and 12-16 bytes. Validate the requested authsize, and retain it to save in the request context.
Fixes 36cf515b9bbe2 ("crypto: ccp - Enable support for AES GCM on v5 CCPs")
Cc <[email protected]>
Signed-off-by Gary R Hook <[email protected]>
Signed-off-by Herbert Xu <[email protected]>
--- drivers/crypto/ccp/ccp-crypto-aes-galois.c | 14 ++++++++++++ drivers/crypto/ccp/ccp-ops.c | 26 +++++++++++++++++----- include/linux/ccp.h | 2 ++ 3 files changed, 37 insertions(+), 5 deletions(-)
drivers/crypto/ccp/ccp-crypto-aes-galois.c +14 -0
@@ -58,6 +58,19 @@ static int ccp_aes_gcm_setkey(struct crypto_aead *tfm, const u8 *key,static int ccp_aes_gcm_setauthsize (struct crypto_aead *tfm,unsigned int authsize) { +switch (authsize) { +case 16 : +case 15 : +case 14 : +case 13 : +case 12 : +case 8 : +case 4 : +break ; +default : +return -EINVAL ; + } +return 0 ; }
@@ -104,6 +117,7 @@ static int ccp_aes_gcm_crypt(struct aead_request *req, bool encrypt)memset (&rctx->cmd,0 ,sizeof (rctx->cmd));INIT_LIST_HEAD (&rctx->cmd.entry); rctx->cmd.engine =CCP_ENGINE_AES ; + rctx->cmd.u.aes.authsize =crypto_aead_authsize (tfm); rctx->cmd.u.aes.type = ctx->u.aes.type; rctx->cmd.u.aes.mode = ctx->u.aes.mode; rctx->cmd.u.aes.action = encrypt;
drivers/crypto/ccp/ccp-ops.c +21 -5
@@ -622,6 +622,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 +644,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 +673,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); }
@@ -839,19 +855,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); }
include/linux/ccp.h +2 -0
@@ -173,6 +173,8 @@ struct ccp_aes_engine {enum ccp_aes_mode mode;enum ccp_aes_action action; +u32 authsize; +struct scatterlist *key;u32 key_len;/* In bytes */
Signature · 1 line
2.17.1