]>
Commit | Line | Data |
---|---|---|
d074880a GKH |
1 | From e8662a6a5f8f7f2cadc0edb934aef622d96ac3ee Mon Sep 17 00:00:00 2001 |
2 | From: Gilad Ben-Yossef <gilad@benyossef.com> | |
3 | Date: Thu, 18 Apr 2019 16:39:05 +0300 | |
4 | Subject: crypto: ccree - don't map AEAD key and IV on stack | |
5 | ||
6 | From: Gilad Ben-Yossef <gilad@benyossef.com> | |
7 | ||
8 | commit e8662a6a5f8f7f2cadc0edb934aef622d96ac3ee upstream. | |
9 | ||
10 | The AEAD authenc key and IVs might be passed to us on stack. Copy it to | |
11 | a slab buffer before mapping to gurantee proper DMA mapping. | |
12 | ||
13 | Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> | |
14 | Cc: stable@vger.kernel.org # v4.19+ | |
15 | Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> | |
16 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
17 | ||
18 | --- | |
19 | drivers/crypto/ccree/cc_aead.c | 11 ++++++++++- | |
20 | drivers/crypto/ccree/cc_buffer_mgr.c | 15 ++++++++++++--- | |
21 | drivers/crypto/ccree/cc_driver.h | 1 + | |
22 | 3 files changed, 23 insertions(+), 4 deletions(-) | |
23 | ||
24 | --- a/drivers/crypto/ccree/cc_aead.c | |
25 | +++ b/drivers/crypto/ccree/cc_aead.c | |
26 | @@ -415,7 +415,7 @@ static int validate_keys_sizes(struct cc | |
27 | /* This function prepers the user key so it can pass to the hmac processing | |
28 | * (copy to intenral buffer or hash in case of key longer than block | |
29 | */ | |
30 | -static int cc_get_plain_hmac_key(struct crypto_aead *tfm, const u8 *key, | |
31 | +static int cc_get_plain_hmac_key(struct crypto_aead *tfm, const u8 *authkey, | |
32 | unsigned int keylen) | |
33 | { | |
34 | dma_addr_t key_dma_addr = 0; | |
35 | @@ -428,6 +428,7 @@ static int cc_get_plain_hmac_key(struct | |
36 | unsigned int hashmode; | |
37 | unsigned int idx = 0; | |
38 | int rc = 0; | |
39 | + u8 *key = NULL; | |
40 | struct cc_hw_desc desc[MAX_AEAD_SETKEY_SEQ]; | |
41 | dma_addr_t padded_authkey_dma_addr = | |
42 | ctx->auth_state.hmac.padded_authkey_dma_addr; | |
43 | @@ -446,11 +447,17 @@ static int cc_get_plain_hmac_key(struct | |
44 | } | |
45 | ||
46 | if (keylen != 0) { | |
47 | + | |
48 | + key = kmemdup(authkey, keylen, GFP_KERNEL); | |
49 | + if (!key) | |
50 | + return -ENOMEM; | |
51 | + | |
52 | key_dma_addr = dma_map_single(dev, (void *)key, keylen, | |
53 | DMA_TO_DEVICE); | |
54 | if (dma_mapping_error(dev, key_dma_addr)) { | |
55 | dev_err(dev, "Mapping key va=0x%p len=%u for DMA failed\n", | |
56 | key, keylen); | |
57 | + kzfree(key); | |
58 | return -ENOMEM; | |
59 | } | |
60 | if (keylen > blocksize) { | |
61 | @@ -533,6 +540,8 @@ static int cc_get_plain_hmac_key(struct | |
62 | if (key_dma_addr) | |
63 | dma_unmap_single(dev, key_dma_addr, keylen, DMA_TO_DEVICE); | |
64 | ||
65 | + kzfree(key); | |
66 | + | |
67 | return rc; | |
68 | } | |
69 | ||
70 | --- a/drivers/crypto/ccree/cc_buffer_mgr.c | |
71 | +++ b/drivers/crypto/ccree/cc_buffer_mgr.c | |
72 | @@ -560,6 +560,7 @@ void cc_unmap_aead_request(struct device | |
73 | if (areq_ctx->gen_ctx.iv_dma_addr) { | |
74 | dma_unmap_single(dev, areq_ctx->gen_ctx.iv_dma_addr, | |
75 | hw_iv_size, DMA_BIDIRECTIONAL); | |
76 | + kzfree(areq_ctx->gen_ctx.iv); | |
77 | } | |
78 | ||
79 | /* Release pool */ | |
80 | @@ -664,19 +665,27 @@ static int cc_aead_chain_iv(struct cc_dr | |
81 | struct aead_req_ctx *areq_ctx = aead_request_ctx(req); | |
82 | unsigned int hw_iv_size = areq_ctx->hw_iv_size; | |
83 | struct device *dev = drvdata_to_dev(drvdata); | |
84 | + gfp_t flags = cc_gfp_flags(&req->base); | |
85 | int rc = 0; | |
86 | ||
87 | if (!req->iv) { | |
88 | areq_ctx->gen_ctx.iv_dma_addr = 0; | |
89 | + areq_ctx->gen_ctx.iv = NULL; | |
90 | goto chain_iv_exit; | |
91 | } | |
92 | ||
93 | - areq_ctx->gen_ctx.iv_dma_addr = dma_map_single(dev, req->iv, | |
94 | - hw_iv_size, | |
95 | - DMA_BIDIRECTIONAL); | |
96 | + areq_ctx->gen_ctx.iv = kmemdup(req->iv, hw_iv_size, flags); | |
97 | + if (!areq_ctx->gen_ctx.iv) | |
98 | + return -ENOMEM; | |
99 | + | |
100 | + areq_ctx->gen_ctx.iv_dma_addr = | |
101 | + dma_map_single(dev, areq_ctx->gen_ctx.iv, hw_iv_size, | |
102 | + DMA_BIDIRECTIONAL); | |
103 | if (dma_mapping_error(dev, areq_ctx->gen_ctx.iv_dma_addr)) { | |
104 | dev_err(dev, "Mapping iv %u B at va=%pK for DMA failed\n", | |
105 | hw_iv_size, req->iv); | |
106 | + kzfree(areq_ctx->gen_ctx.iv); | |
107 | + areq_ctx->gen_ctx.iv = NULL; | |
108 | rc = -ENOMEM; | |
109 | goto chain_iv_exit; | |
110 | } | |
111 | --- a/drivers/crypto/ccree/cc_driver.h | |
112 | +++ b/drivers/crypto/ccree/cc_driver.h | |
113 | @@ -162,6 +162,7 @@ struct cc_alg_template { | |
114 | ||
115 | struct async_gen_req_ctx { | |
116 | dma_addr_t iv_dma_addr; | |
117 | + u8 *iv; | |
118 | enum drv_crypto_direction op_type; | |
119 | }; | |
120 |