ipq40xx: qce - add fixes for AES ciphers
[openwrt/staging/wigyori.git] / target / linux / ipq40xx / patches-4.19 / 047-crypto-qce-use-cryptlen-when-adding-extra-sgl.patch
1 From 686aa4db696270dadc5e8b2971769e1676251ff1 Mon Sep 17 00:00:00 2001
2 From: Eneas U de Queiroz <cotequeiroz@gmail.com>
3 Date: Fri, 31 Jan 2020 17:43:16 -0300
4 Subject: [PATCH] crypto: qce - use cryptlen when adding extra sgl
5
6 The qce crypto driver appends an extra entry to the dst sgl, to maintain
7 private state information.
8
9 When the gcm driver sends requests to the ctr skcipher, it passes the
10 authentication tag after the actual crypto payload, but it must not be
11 touched.
12
13 Commit 1336c2221bee ("crypto: qce - save a sg table slot for result
14 buf") limited the destination sgl to avoid overwriting the
15 authentication tag but it assumed the tag would be in a separate sgl
16 entry.
17
18 This is not always the case, so it is better to limit the length of the
19 destination buffer to req->cryptlen before appending the result buf.
20
21 Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
22
23 --- a/drivers/crypto/qce/dma.c
24 +++ b/drivers/crypto/qce/dma.c
25 @@ -56,9 +56,10 @@ void qce_dma_release(struct qce_dma_data
26
27 struct scatterlist *
28 qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl,
29 - int max_ents)
30 + unsigned int max_len)
31 {
32 struct scatterlist *sg = sgt->sgl, *sg_last = NULL;
33 + unsigned int new_len;
34
35 while (sg) {
36 if (!sg_page(sg))
37 @@ -69,13 +70,13 @@ qce_sgtable_add(struct sg_table *sgt, st
38 if (!sg)
39 return ERR_PTR(-EINVAL);
40
41 - while (new_sgl && sg && max_ents) {
42 - sg_set_page(sg, sg_page(new_sgl), new_sgl->length,
43 - new_sgl->offset);
44 + while (new_sgl && sg && max_len) {
45 + new_len = new_sgl->length > max_len ? max_len : new_sgl->length;
46 + sg_set_page(sg, sg_page(new_sgl), new_len, new_sgl->offset);
47 sg_last = sg;
48 sg = sg_next(sg);
49 new_sgl = sg_next(new_sgl);
50 - max_ents--;
51 + max_len -= new_len;
52 }
53
54 return sg_last;
55 --- a/drivers/crypto/qce/dma.h
56 +++ b/drivers/crypto/qce/dma.h
57 @@ -51,6 +51,6 @@ void qce_dma_issue_pending(struct qce_dm
58 int qce_dma_terminate_all(struct qce_dma_data *dma);
59 struct scatterlist *
60 qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add,
61 - int max_ents);
62 + unsigned int max_len);
63
64 #endif /* _DMA_H_ */
65 --- a/drivers/crypto/qce/skcipher.c
66 +++ b/drivers/crypto/qce/skcipher.c
67 @@ -105,13 +105,14 @@ qce_skcipher_async_req_handle(struct cry
68
69 sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
70
71 - sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, rctx->dst_nents - 1);
72 + sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, req->cryptlen);
73 if (IS_ERR(sg)) {
74 ret = PTR_ERR(sg);
75 goto error_free;
76 }
77
78 - sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg, 1);
79 + sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg,
80 + QCE_RESULT_BUF_SZ);
81 if (IS_ERR(sg)) {
82 ret = PTR_ERR(sg);
83 goto error_free;