mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
crypto: ccp - Add support for valid authsize values less than 16
commit 9f00baf74e4b6f79a3a3dfab44fb7bb2e797b551 upstream. 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: <stable@vger.kernel.org> Signed-off-by: Gary R Hook <gary.hook@amd.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e95468f233
commit
cd31e7c5d5
@ -63,6 +63,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;
|
||||
}
|
||||
|
||||
@ -109,6 +122,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;
|
||||
|
@ -625,6 +625,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 */
|
||||
@ -646,6 +647,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.
|
||||
@ -660,7 +676,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);
|
||||
}
|
||||
|
||||
@ -841,19 +857,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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user