ipq40xx: qce - add fixes for AES ciphers
[openwrt/staging/dedeckeh.git] / target / linux / ipq40xx / patches-4.19 / 043-crypto-qce-save-a-sg-table-slot-for-result-buf.patch
1 From 31f796293b6c38126a466414c565827b9cfdbe39 Mon Sep 17 00:00:00 2001
2 From: Eneas U de Queiroz <cotequeiroz@gmail.com>
3 Date: Wed, 20 Nov 2019 21:39:11 -0300
4 Subject: [PATCH] crypto: qce - save a sg table slot for result buf
5
6 When ctr-aes-qce is used for gcm-mode, an extra sg entry for the
7 authentication tag is present, causing trouble when the qce driver
8 prepares the dst-results eg table for dma.
9
10 It computes the number of entries needed with sg_nents_for_len, leaving
11 out the tag entry. Then it creates a sg table with that number plus
12 one, used to store a "result" sg.
13
14 When copying the sg table, it does not limit the number of entries
15 copied, so tha extra slot is filled with the authentication tag sg.
16 When the driver tries to add the result sg, the list is full, and it
17 returns EINVAL.
18
19 By limiting the number of sg entries copied to the dest table, the slot
20 for the result buffer is guaranteed to be unused.
21
22 Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
23
24 --- a/drivers/crypto/qce/dma.c
25 +++ b/drivers/crypto/qce/dma.c
26 @@ -55,7 +55,8 @@ void qce_dma_release(struct qce_dma_data
27 }
28
29 struct scatterlist *
30 -qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl)
31 +qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl,
32 + int max_ents)
33 {
34 struct scatterlist *sg = sgt->sgl, *sg_last = NULL;
35
36 @@ -68,12 +69,13 @@ qce_sgtable_add(struct sg_table *sgt, st
37 if (!sg)
38 return ERR_PTR(-EINVAL);
39
40 - while (new_sgl && sg) {
41 + while (new_sgl && sg && max_ents) {
42 sg_set_page(sg, sg_page(new_sgl), new_sgl->length,
43 new_sgl->offset);
44 sg_last = sg;
45 sg = sg_next(sg);
46 new_sgl = sg_next(new_sgl);
47 + max_ents--;
48 }
49
50 return sg_last;
51 --- a/drivers/crypto/qce/dma.h
52 +++ b/drivers/crypto/qce/dma.h
53 @@ -50,6 +50,7 @@ int qce_dma_prep_sgs(struct qce_dma_data
54 void qce_dma_issue_pending(struct qce_dma_data *dma);
55 int qce_dma_terminate_all(struct qce_dma_data *dma);
56 struct scatterlist *
57 -qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add);
58 +qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add,
59 + int max_ents);
60
61 #endif /* _DMA_H_ */
62 --- a/drivers/crypto/qce/skcipher.c
63 +++ b/drivers/crypto/qce/skcipher.c
64 @@ -103,13 +103,13 @@ qce_skcipher_async_req_handle(struct cry
65
66 sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
67
68 - sg = qce_sgtable_add(&rctx->dst_tbl, req->dst);
69 + sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, rctx->dst_nents - 1);
70 if (IS_ERR(sg)) {
71 ret = PTR_ERR(sg);
72 goto error_free;
73 }
74
75 - sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg);
76 + sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg, 1);
77 if (IS_ERR(sg)) {
78 ret = PTR_ERR(sg);
79 goto error_free;