aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq40xx/patches-5.4/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq40xx/patches-5.4/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch')
-rw-r--r--target/linux/ipq40xx/patches-5.4/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch85
1 files changed, 85 insertions, 0 deletions
diff --git a/target/linux/ipq40xx/patches-5.4/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch b/target/linux/ipq40xx/patches-5.4/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch
new file mode 100644
index 0000000000..2385d483f2
--- /dev/null
+++ b/target/linux/ipq40xx/patches-5.4/043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch
@@ -0,0 +1,85 @@
+From 3ee50c896d712dc2fc8f34c2cd1918d035e74045 Mon Sep 17 00:00:00 2001
+From: Eneas U de Queiroz <cotequeiroz@gmail.com>
+Date: Fri, 20 Dec 2019 16:02:15 -0300
+Subject: [PATCH 04/11] 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 sg 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 buffer.
+
+When copying the sg table, there's no limit to the number of entries
+copied, so the 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>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/qce/dma.c | 6 ++++--
+ drivers/crypto/qce/dma.h | 3 ++-
+ drivers/crypto/qce/skcipher.c | 4 ++--
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/qce/dma.c
++++ b/drivers/crypto/qce/dma.c
+@@ -47,7 +47,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;
+
+@@ -60,12 +61,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
+@@ -42,6 +42,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
+@@ -95,13 +95,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;