diff options
author | Mark Johnston <markj@FreeBSD.org> | 2021-04-21 18:50:48 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2021-04-21 19:11:58 +0000 |
commit | d74d1284386aa37e6ec8ffa7739c51b3fa54fcb3 (patch) | |
tree | 1b847980fcdadeb24f604b47466ce314f8e998b6 /sys/dev/safexcel/safexcel.c | |
parent | bd2cb05d24907e37029f252086aaef70d91c92ff (diff) | |
download | src-d74d1284386aa37e6ec8ffa7739c51b3fa54fcb3.tar.gz src-d74d1284386aa37e6ec8ffa7739c51b3fa54fcb3.zip |
safexcel: Fix the SHA-HMAC digest computation when AAD is present
The driver would fail to include the AAD in the input stream, resulting
in incorrect digests for requests combining SHA-HMAC with AES-CBC or
-CTR. Ensure that the AAD is included in the processor's input stream,
and fix the corresponding instruction sequence to include the AAD as
input to the digest computation.
This is a direct commit to stable/12 since the bug was introduced while
merging there and is not present in later branches.
Diffstat (limited to 'sys/dev/safexcel/safexcel.c')
-rw-r--r-- | sys/dev/safexcel/safexcel.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/sys/dev/safexcel/safexcel.c b/sys/dev/safexcel/safexcel.c index 0d209513ebdb..8c9094da9138 100644 --- a/sys/dev/safexcel/safexcel.c +++ b/sys/dev/safexcel/safexcel.c @@ -1590,16 +1590,27 @@ safexcel_instr_eta(struct safexcel_request *req, struct safexcel_instr *instr, start = instr; - /* Encrypt any data left in the request. */ + /* Insert the AAD into the input stream. */ instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION; - instr->length = req->enc->crd_len; - instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH; + instr->length = req->mac->crd_len - req->enc->crd_len; + instr->status = req->enc->crd_len == 0 ? + SAFEXCEL_INSTR_STATUS_LAST_HASH : 0; instr->instructions = SAFEXCEL_INSTR_INS_LAST | - SAFEXCEL_INSTR_DEST_CRYPTO | - SAFEXCEL_INSTR_DEST_HASH | - SAFEXCEL_INSTR_DEST_OUTPUT; + SAFEXCEL_INSTR_DEST_HASH; instr++; + /* Encrypt any data left in the request. */ + if (req->enc->crd_len > 0) { + instr->opcode = SAFEXCEL_INSTR_OPCODE_DIRECTION; + instr->length = req->enc->crd_len; + instr->status = SAFEXCEL_INSTR_STATUS_LAST_HASH; + instr->instructions = SAFEXCEL_INSTR_INS_LAST | + SAFEXCEL_INSTR_DEST_CRYPTO | + SAFEXCEL_INSTR_DEST_HASH | + SAFEXCEL_INSTR_DEST_OUTPUT; + instr++; + } + /* * Compute the digest, or extract it and place it in the output stream. */ @@ -2029,16 +2040,30 @@ safexcel_create_chain_cb(void *arg, bus_dma_segment_t *segs, int nseg, * consumers place the digest first in the input buffer, in which case * we have to create an extra descriptor. * + * Note that for encrypt-then-auth algorithms, mac->crd_len corresponds + * to the sum of the lengths of the AAD and payload, while for GCM and + * CCM it is the length of the AAD. + * * As an optimization, unmodified data is not passed to the output * stream. */ sglist_reset(ring->cmd_data); sglist_reset(ring->res_data); - if (req->mac != NULL && (req->enc == NULL || - req->enc->crd_alg == CRYPTO_AES_NIST_GCM_16 || - req->enc->crd_alg == CRYPTO_AES_CCM_16)) { - safexcel_append_segs(segs, nseg, ring->cmd_data, - req->mac->crd_skip, req->mac->crd_len); + if (req->mac != NULL) { + if (req->enc == NULL || + req->enc->crd_alg == CRYPTO_AES_NIST_GCM_16 || + req->enc->crd_alg == CRYPTO_AES_CCM_16) { + safexcel_append_segs(segs, nseg, ring->cmd_data, + req->mac->crd_skip, req->mac->crd_len); + } else { + if (req->mac->crd_len < req->enc->crd_len) { + req->error = EINVAL; + return; + } + safexcel_append_segs(segs, nseg, ring->cmd_data, + req->mac->crd_skip, + req->mac->crd_len - req->enc->crd_len); + } } if (req->enc != NULL) { safexcel_append_segs(segs, nseg, ring->cmd_data, |