|
|
@@ -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);
|
|
|
}
|
|
|
|
|
|
@@ -842,19 +858,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);
|
|
|
}
|
|
|
|