mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-26 08:51:13 +00:00
80 lines
2.6 KiB
Diff
80 lines
2.6 KiB
Diff
|
From 31f796293b6c38126a466414c565827b9cfdbe39 Mon Sep 17 00:00:00 2001
|
||
|
From: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||
|
Date: Wed, 20 Nov 2019 21:39:11 -0300
|
||
|
Subject: [PATCH] crypto: qce - save a sg table slot for result buf
|
||
|
|
||
|
When ctr-aes-qce is used for gcm-mode, an extra sg entry for the
|
||
|
authentication tag is present, causing trouble when the qce driver
|
||
|
prepares the dst-results eg table for dma.
|
||
|
|
||
|
It computes the number of entries needed with sg_nents_for_len, leaving
|
||
|
out the tag entry. Then it creates a sg table with that number plus
|
||
|
one, used to store a "result" sg.
|
||
|
|
||
|
When copying the sg table, it does not limit the number of entries
|
||
|
copied, so tha extra slot is filled with the authentication tag sg.
|
||
|
When the driver tries to add the result sg, the list is full, and it
|
||
|
returns EINVAL.
|
||
|
|
||
|
By limiting the number of sg entries copied to the dest table, the slot
|
||
|
for the result buffer is guaranteed to be unused.
|
||
|
|
||
|
Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||
|
|
||
|
--- a/drivers/crypto/qce/dma.c
|
||
|
+++ b/drivers/crypto/qce/dma.c
|
||
|
@@ -55,7 +55,8 @@ void qce_dma_release(struct qce_dma_data
|
||
|
}
|
||
|
|
||
|
struct scatterlist *
|
||
|
-qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl)
|
||
|
+qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl,
|
||
|
+ int max_ents)
|
||
|
{
|
||
|
struct scatterlist *sg = sgt->sgl, *sg_last = NULL;
|
||
|
|
||
|
@@ -68,12 +69,13 @@ qce_sgtable_add(struct sg_table *sgt, st
|
||
|
if (!sg)
|
||
|
return ERR_PTR(-EINVAL);
|
||
|
|
||
|
- while (new_sgl && sg) {
|
||
|
+ while (new_sgl && sg && max_ents) {
|
||
|
sg_set_page(sg, sg_page(new_sgl), new_sgl->length,
|
||
|
new_sgl->offset);
|
||
|
sg_last = sg;
|
||
|
sg = sg_next(sg);
|
||
|
new_sgl = sg_next(new_sgl);
|
||
|
+ max_ents--;
|
||
|
}
|
||
|
|
||
|
return sg_last;
|
||
|
--- a/drivers/crypto/qce/dma.h
|
||
|
+++ b/drivers/crypto/qce/dma.h
|
||
|
@@ -50,6 +50,7 @@ int qce_dma_prep_sgs(struct qce_dma_data
|
||
|
void qce_dma_issue_pending(struct qce_dma_data *dma);
|
||
|
int qce_dma_terminate_all(struct qce_dma_data *dma);
|
||
|
struct scatterlist *
|
||
|
-qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add);
|
||
|
+qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add,
|
||
|
+ int max_ents);
|
||
|
|
||
|
#endif /* _DMA_H_ */
|
||
|
--- a/drivers/crypto/qce/skcipher.c
|
||
|
+++ b/drivers/crypto/qce/skcipher.c
|
||
|
@@ -103,13 +103,13 @@ qce_skcipher_async_req_handle(struct cry
|
||
|
|
||
|
sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
|
||
|
|
||
|
- sg = qce_sgtable_add(&rctx->dst_tbl, req->dst);
|
||
|
+ sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, rctx->dst_nents - 1);
|
||
|
if (IS_ERR(sg)) {
|
||
|
ret = PTR_ERR(sg);
|
||
|
goto error_free;
|
||
|
}
|
||
|
|
||
|
- sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg);
|
||
|
+ sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg, 1);
|
||
|
if (IS_ERR(sg)) {
|
||
|
ret = PTR_ERR(sg);
|
||
|
goto error_free;
|