Skip to content

Commit

Permalink
crypto: ccp - Add support for valid authsize values less than 16
Browse files Browse the repository at this point in the history
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: 36cf515 ("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]>
  • Loading branch information
garyrhook authored and herbertx committed Aug 2, 2019
1 parent 25e4433 commit 9f00baf
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
14 changes: 14 additions & 0 deletions drivers/crypto/ccp/ccp-crypto-aes-galois.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
26 changes: 21 additions & 5 deletions drivers/crypto/ccp/ccp-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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.
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand Down
2 changes: 2 additions & 0 deletions include/linux/ccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down

0 comments on commit 9f00baf

Please sign in to comment.