aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-04-21 18:50:48 +0000
committerMark Johnston <markj@FreeBSD.org>2021-04-21 19:11:58 +0000
commitd74d1284386aa37e6ec8ffa7739c51b3fa54fcb3 (patch)
tree1b847980fcdadeb24f604b47466ce314f8e998b6
parentbd2cb05d24907e37029f252086aaef70d91c92ff (diff)
downloadsrc-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.
-rw-r--r--sys/dev/safexcel/safexcel.c47
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,