xref: /openbmc/linux/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1d9b45418SCorentin Labbe // SPDX-License-Identifier: GPL-2.0
2d9b45418SCorentin Labbe /*
3d9b45418SCorentin Labbe  * sun8i-ss-hash.c - hardware cryptographic offloader for
4d9b45418SCorentin Labbe  * Allwinner A80/A83T SoC
5d9b45418SCorentin Labbe  *
6d9b45418SCorentin Labbe  * Copyright (C) 2015-2020 Corentin Labbe <clabbe@baylibre.com>
7d9b45418SCorentin Labbe  *
8d9b45418SCorentin Labbe  * This file add support for MD5 and SHA1/SHA224/SHA256.
9d9b45418SCorentin Labbe  *
1039db3f15SJonathan Corbet  * You could find the datasheet in Documentation/arch/arm/sunxi.rst
11d9b45418SCorentin Labbe  */
12*4c19e8fbSHerbert Xu 
13801b7d57SCorentin Labbe #include <crypto/hmac.h>
14*4c19e8fbSHerbert Xu #include <crypto/internal/hash.h>
15*4c19e8fbSHerbert Xu #include <crypto/md5.h>
16c35e523aSCorentin Labbe #include <crypto/scatterwalk.h>
17a24d22b2SEric Biggers #include <crypto/sha1.h>
18a24d22b2SEric Biggers #include <crypto/sha2.h>
19*4c19e8fbSHerbert Xu #include <linux/bottom_half.h>
20*4c19e8fbSHerbert Xu #include <linux/dma-mapping.h>
21*4c19e8fbSHerbert Xu #include <linux/err.h>
22*4c19e8fbSHerbert Xu #include <linux/kernel.h>
23*4c19e8fbSHerbert Xu #include <linux/pm_runtime.h>
24*4c19e8fbSHerbert Xu #include <linux/scatterlist.h>
25*4c19e8fbSHerbert Xu #include <linux/slab.h>
26*4c19e8fbSHerbert Xu #include <linux/string.h>
27d9b45418SCorentin Labbe #include "sun8i-ss.h"
28d9b45418SCorentin Labbe 
sun8i_ss_hashkey(struct sun8i_ss_hash_tfm_ctx * tfmctx,const u8 * key,unsigned int keylen)29801b7d57SCorentin Labbe static int sun8i_ss_hashkey(struct sun8i_ss_hash_tfm_ctx *tfmctx, const u8 *key,
30801b7d57SCorentin Labbe 			    unsigned int keylen)
31801b7d57SCorentin Labbe {
32801b7d57SCorentin Labbe 	struct crypto_shash *xtfm;
33801b7d57SCorentin Labbe 	struct shash_desc *sdesc;
34801b7d57SCorentin Labbe 	size_t len;
35801b7d57SCorentin Labbe 	int ret = 0;
36801b7d57SCorentin Labbe 
37801b7d57SCorentin Labbe 	xtfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_NEED_FALLBACK);
387e8df1fcSPeng Wu 	if (IS_ERR(xtfm))
397e8df1fcSPeng Wu 		return PTR_ERR(xtfm);
40801b7d57SCorentin Labbe 
41801b7d57SCorentin Labbe 	len = sizeof(*sdesc) + crypto_shash_descsize(xtfm);
42801b7d57SCorentin Labbe 	sdesc = kmalloc(len, GFP_KERNEL);
43801b7d57SCorentin Labbe 	if (!sdesc) {
44801b7d57SCorentin Labbe 		ret = -ENOMEM;
45801b7d57SCorentin Labbe 		goto err_hashkey_sdesc;
46801b7d57SCorentin Labbe 	}
47801b7d57SCorentin Labbe 	sdesc->tfm = xtfm;
48801b7d57SCorentin Labbe 
49801b7d57SCorentin Labbe 	ret = crypto_shash_init(sdesc);
50801b7d57SCorentin Labbe 	if (ret) {
51801b7d57SCorentin Labbe 		dev_err(tfmctx->ss->dev, "shash init error ret=%d\n", ret);
52801b7d57SCorentin Labbe 		goto err_hashkey;
53801b7d57SCorentin Labbe 	}
54801b7d57SCorentin Labbe 	ret = crypto_shash_finup(sdesc, key, keylen, tfmctx->key);
55801b7d57SCorentin Labbe 	if (ret)
56801b7d57SCorentin Labbe 		dev_err(tfmctx->ss->dev, "shash finup error\n");
57801b7d57SCorentin Labbe err_hashkey:
58801b7d57SCorentin Labbe 	kfree(sdesc);
59801b7d57SCorentin Labbe err_hashkey_sdesc:
60801b7d57SCorentin Labbe 	crypto_free_shash(xtfm);
61801b7d57SCorentin Labbe 	return ret;
62801b7d57SCorentin Labbe }
63801b7d57SCorentin Labbe 
sun8i_ss_hmac_setkey(struct crypto_ahash * ahash,const u8 * key,unsigned int keylen)64801b7d57SCorentin Labbe int sun8i_ss_hmac_setkey(struct crypto_ahash *ahash, const u8 *key,
65801b7d57SCorentin Labbe 			 unsigned int keylen)
66801b7d57SCorentin Labbe {
67801b7d57SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(ahash);
68801b7d57SCorentin Labbe 	int digestsize, i;
69801b7d57SCorentin Labbe 	int bs = crypto_ahash_blocksize(ahash);
70801b7d57SCorentin Labbe 	int ret;
71801b7d57SCorentin Labbe 
72*4c19e8fbSHerbert Xu 	digestsize = crypto_ahash_digestsize(ahash);
73801b7d57SCorentin Labbe 
74801b7d57SCorentin Labbe 	if (keylen > bs) {
75801b7d57SCorentin Labbe 		ret = sun8i_ss_hashkey(tfmctx, key, keylen);
76801b7d57SCorentin Labbe 		if (ret)
77801b7d57SCorentin Labbe 			return ret;
78801b7d57SCorentin Labbe 		tfmctx->keylen = digestsize;
79801b7d57SCorentin Labbe 	} else {
80801b7d57SCorentin Labbe 		tfmctx->keylen = keylen;
81801b7d57SCorentin Labbe 		memcpy(tfmctx->key, key, keylen);
82801b7d57SCorentin Labbe 	}
83801b7d57SCorentin Labbe 
8439a76cf1SHerbert Xu 	tfmctx->ipad = kzalloc(bs, GFP_KERNEL);
85801b7d57SCorentin Labbe 	if (!tfmctx->ipad)
86801b7d57SCorentin Labbe 		return -ENOMEM;
8739a76cf1SHerbert Xu 	tfmctx->opad = kzalloc(bs, GFP_KERNEL);
88801b7d57SCorentin Labbe 	if (!tfmctx->opad) {
89801b7d57SCorentin Labbe 		ret = -ENOMEM;
90801b7d57SCorentin Labbe 		goto err_opad;
91801b7d57SCorentin Labbe 	}
92801b7d57SCorentin Labbe 
93801b7d57SCorentin Labbe 	memset(tfmctx->key + tfmctx->keylen, 0, bs - tfmctx->keylen);
94801b7d57SCorentin Labbe 	memcpy(tfmctx->ipad, tfmctx->key, tfmctx->keylen);
95801b7d57SCorentin Labbe 	memcpy(tfmctx->opad, tfmctx->key, tfmctx->keylen);
96801b7d57SCorentin Labbe 	for (i = 0; i < bs; i++) {
97801b7d57SCorentin Labbe 		tfmctx->ipad[i] ^= HMAC_IPAD_VALUE;
98801b7d57SCorentin Labbe 		tfmctx->opad[i] ^= HMAC_OPAD_VALUE;
99801b7d57SCorentin Labbe 	}
100801b7d57SCorentin Labbe 
101801b7d57SCorentin Labbe 	ret = crypto_ahash_setkey(tfmctx->fallback_tfm, key, keylen);
102801b7d57SCorentin Labbe 	if (!ret)
103801b7d57SCorentin Labbe 		return 0;
104801b7d57SCorentin Labbe 
105801b7d57SCorentin Labbe 	memzero_explicit(tfmctx->key, keylen);
106801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->opad);
107801b7d57SCorentin Labbe err_opad:
108801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->ipad);
109801b7d57SCorentin Labbe 	return ret;
110801b7d57SCorentin Labbe }
111801b7d57SCorentin Labbe 
sun8i_ss_hash_init_tfm(struct crypto_ahash * tfm)112*4c19e8fbSHerbert Xu int sun8i_ss_hash_init_tfm(struct crypto_ahash *tfm)
113d9b45418SCorentin Labbe {
114*4c19e8fbSHerbert Xu 	struct sun8i_ss_hash_tfm_ctx *op = crypto_ahash_ctx(tfm);
115*4c19e8fbSHerbert Xu 	struct ahash_alg *alg = crypto_ahash_alg(tfm);
116d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
117d9b45418SCorentin Labbe 	int err;
118d9b45418SCorentin Labbe 
119*4c19e8fbSHerbert Xu 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash.base);
120d9b45418SCorentin Labbe 	op->ss = algt->ss;
121d9b45418SCorentin Labbe 
122d9b45418SCorentin Labbe 	/* FALLBACK */
123*4c19e8fbSHerbert Xu 	op->fallback_tfm = crypto_alloc_ahash(crypto_ahash_alg_name(tfm), 0,
124d9b45418SCorentin Labbe 					      CRYPTO_ALG_NEED_FALLBACK);
125d9b45418SCorentin Labbe 	if (IS_ERR(op->fallback_tfm)) {
126d9b45418SCorentin Labbe 		dev_err(algt->ss->dev, "Fallback driver could no be loaded\n");
127d9b45418SCorentin Labbe 		return PTR_ERR(op->fallback_tfm);
128d9b45418SCorentin Labbe 	}
129d9b45418SCorentin Labbe 
130*4c19e8fbSHerbert Xu 	crypto_ahash_set_statesize(tfm,
131*4c19e8fbSHerbert Xu 				   crypto_ahash_statesize(op->fallback_tfm));
132d9b45418SCorentin Labbe 
133*4c19e8fbSHerbert Xu 	crypto_ahash_set_reqsize(tfm,
134d9b45418SCorentin Labbe 				 sizeof(struct sun8i_ss_hash_reqctx) +
135d9b45418SCorentin Labbe 				 crypto_ahash_reqsize(op->fallback_tfm));
136d9b45418SCorentin Labbe 
137*4c19e8fbSHerbert Xu 	memcpy(algt->fbname, crypto_ahash_driver_name(op->fallback_tfm),
138*4c19e8fbSHerbert Xu 	       CRYPTO_MAX_ALG_NAME);
139f95f61d0SCorentin Labbe 
140d9b45418SCorentin Labbe 	err = pm_runtime_get_sync(op->ss->dev);
141d9b45418SCorentin Labbe 	if (err < 0)
142d9b45418SCorentin Labbe 		goto error_pm;
143d9b45418SCorentin Labbe 	return 0;
144d9b45418SCorentin Labbe error_pm:
145d9b45418SCorentin Labbe 	pm_runtime_put_noidle(op->ss->dev);
146d9b45418SCorentin Labbe 	crypto_free_ahash(op->fallback_tfm);
147d9b45418SCorentin Labbe 	return err;
148d9b45418SCorentin Labbe }
149d9b45418SCorentin Labbe 
sun8i_ss_hash_exit_tfm(struct crypto_ahash * tfm)150*4c19e8fbSHerbert Xu void sun8i_ss_hash_exit_tfm(struct crypto_ahash *tfm)
151d9b45418SCorentin Labbe {
152*4c19e8fbSHerbert Xu 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
153d9b45418SCorentin Labbe 
154801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->ipad);
155801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->opad);
156801b7d57SCorentin Labbe 
157d9b45418SCorentin Labbe 	crypto_free_ahash(tfmctx->fallback_tfm);
158d9b45418SCorentin Labbe 	pm_runtime_put_sync_suspend(tfmctx->ss->dev);
159d9b45418SCorentin Labbe }
160d9b45418SCorentin Labbe 
sun8i_ss_hash_init(struct ahash_request * areq)161d9b45418SCorentin Labbe int sun8i_ss_hash_init(struct ahash_request *areq)
162d9b45418SCorentin Labbe {
163d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
164d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
165d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
166d9b45418SCorentin Labbe 
167d9b45418SCorentin Labbe 	memset(rctx, 0, sizeof(struct sun8i_ss_hash_reqctx));
168d9b45418SCorentin Labbe 
169d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
170d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
171d9b45418SCorentin Labbe 
172d9b45418SCorentin Labbe 	return crypto_ahash_init(&rctx->fallback_req);
173d9b45418SCorentin Labbe }
174d9b45418SCorentin Labbe 
sun8i_ss_hash_export(struct ahash_request * areq,void * out)175d9b45418SCorentin Labbe int sun8i_ss_hash_export(struct ahash_request *areq, void *out)
176d9b45418SCorentin Labbe {
177d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
178d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
179d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
180d9b45418SCorentin Labbe 
181d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
182d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
183d9b45418SCorentin Labbe 
184d9b45418SCorentin Labbe 	return crypto_ahash_export(&rctx->fallback_req, out);
185d9b45418SCorentin Labbe }
186d9b45418SCorentin Labbe 
sun8i_ss_hash_import(struct ahash_request * areq,const void * in)187d9b45418SCorentin Labbe int sun8i_ss_hash_import(struct ahash_request *areq, const void *in)
188d9b45418SCorentin Labbe {
189d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
190d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
191d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
192d9b45418SCorentin Labbe 
193d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
194d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
195d9b45418SCorentin Labbe 
196d9b45418SCorentin Labbe 	return crypto_ahash_import(&rctx->fallback_req, in);
197d9b45418SCorentin Labbe }
198d9b45418SCorentin Labbe 
sun8i_ss_hash_final(struct ahash_request * areq)199d9b45418SCorentin Labbe int sun8i_ss_hash_final(struct ahash_request *areq)
200d9b45418SCorentin Labbe {
201d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
202d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
203d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
204d9b45418SCorentin Labbe 
205d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
206d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags &
207d9b45418SCorentin Labbe 					CRYPTO_TFM_REQ_MAY_SLEEP;
208d9b45418SCorentin Labbe 	rctx->fallback_req.result = areq->result;
209d9b45418SCorentin Labbe 
210*4c19e8fbSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG)) {
211*4c19e8fbSHerbert Xu 		struct ahash_alg *alg = crypto_ahash_alg(tfm);
212*4c19e8fbSHerbert Xu 		struct sun8i_ss_alg_template *algt __maybe_unused;
213*4c19e8fbSHerbert Xu 
214*4c19e8fbSHerbert Xu 		algt = container_of(alg, struct sun8i_ss_alg_template,
215*4c19e8fbSHerbert Xu 				    alg.hash.base);
216*4c19e8fbSHerbert Xu 
217d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
218d9b45418SCorentin Labbe 		algt->stat_fb++;
219d9b45418SCorentin Labbe #endif
220*4c19e8fbSHerbert Xu 	}
221d9b45418SCorentin Labbe 
222d9b45418SCorentin Labbe 	return crypto_ahash_final(&rctx->fallback_req);
223d9b45418SCorentin Labbe }
224d9b45418SCorentin Labbe 
sun8i_ss_hash_update(struct ahash_request * areq)225d9b45418SCorentin Labbe int sun8i_ss_hash_update(struct ahash_request *areq)
226d9b45418SCorentin Labbe {
227d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
228d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
229d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
230d9b45418SCorentin Labbe 
231d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
232d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags &
233d9b45418SCorentin Labbe 					CRYPTO_TFM_REQ_MAY_SLEEP;
234d9b45418SCorentin Labbe 	rctx->fallback_req.nbytes = areq->nbytes;
235d9b45418SCorentin Labbe 	rctx->fallback_req.src = areq->src;
236d9b45418SCorentin Labbe 
237d9b45418SCorentin Labbe 	return crypto_ahash_update(&rctx->fallback_req);
238d9b45418SCorentin Labbe }
239d9b45418SCorentin Labbe 
sun8i_ss_hash_finup(struct ahash_request * areq)240d9b45418SCorentin Labbe int sun8i_ss_hash_finup(struct ahash_request *areq)
241d9b45418SCorentin Labbe {
242d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
243d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
244d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
245d9b45418SCorentin Labbe 
246d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
247d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags &
248d9b45418SCorentin Labbe 					CRYPTO_TFM_REQ_MAY_SLEEP;
249d9b45418SCorentin Labbe 
250d9b45418SCorentin Labbe 	rctx->fallback_req.nbytes = areq->nbytes;
251d9b45418SCorentin Labbe 	rctx->fallback_req.src = areq->src;
252d9b45418SCorentin Labbe 	rctx->fallback_req.result = areq->result;
253*4c19e8fbSHerbert Xu 
254*4c19e8fbSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG)) {
255*4c19e8fbSHerbert Xu 		struct ahash_alg *alg = crypto_ahash_alg(tfm);
256*4c19e8fbSHerbert Xu 		struct sun8i_ss_alg_template *algt __maybe_unused;
257*4c19e8fbSHerbert Xu 
258*4c19e8fbSHerbert Xu 		algt = container_of(alg, struct sun8i_ss_alg_template,
259*4c19e8fbSHerbert Xu 				    alg.hash.base);
260*4c19e8fbSHerbert Xu 
261d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
262d9b45418SCorentin Labbe 		algt->stat_fb++;
263d9b45418SCorentin Labbe #endif
264*4c19e8fbSHerbert Xu 	}
265d9b45418SCorentin Labbe 
266d9b45418SCorentin Labbe 	return crypto_ahash_finup(&rctx->fallback_req);
267d9b45418SCorentin Labbe }
268d9b45418SCorentin Labbe 
sun8i_ss_hash_digest_fb(struct ahash_request * areq)269d9b45418SCorentin Labbe static int sun8i_ss_hash_digest_fb(struct ahash_request *areq)
270d9b45418SCorentin Labbe {
271d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
272d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
273d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
274d9b45418SCorentin Labbe 
275d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
276d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags &
277d9b45418SCorentin Labbe 					CRYPTO_TFM_REQ_MAY_SLEEP;
278d9b45418SCorentin Labbe 
279d9b45418SCorentin Labbe 	rctx->fallback_req.nbytes = areq->nbytes;
280d9b45418SCorentin Labbe 	rctx->fallback_req.src = areq->src;
281d9b45418SCorentin Labbe 	rctx->fallback_req.result = areq->result;
282*4c19e8fbSHerbert Xu 
283*4c19e8fbSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG)) {
284*4c19e8fbSHerbert Xu 		struct ahash_alg *alg = crypto_ahash_alg(tfm);
285*4c19e8fbSHerbert Xu 		struct sun8i_ss_alg_template *algt __maybe_unused;
286*4c19e8fbSHerbert Xu 
287*4c19e8fbSHerbert Xu 		algt = container_of(alg, struct sun8i_ss_alg_template,
288*4c19e8fbSHerbert Xu 				    alg.hash.base);
289*4c19e8fbSHerbert Xu 
290d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
291d9b45418SCorentin Labbe 		algt->stat_fb++;
292d9b45418SCorentin Labbe #endif
293*4c19e8fbSHerbert Xu 	}
294d9b45418SCorentin Labbe 
295d9b45418SCorentin Labbe 	return crypto_ahash_digest(&rctx->fallback_req);
296d9b45418SCorentin Labbe }
297d9b45418SCorentin Labbe 
sun8i_ss_run_hash_task(struct sun8i_ss_dev * ss,struct sun8i_ss_hash_reqctx * rctx,const char * name)298d9b45418SCorentin Labbe static int sun8i_ss_run_hash_task(struct sun8i_ss_dev *ss,
299d9b45418SCorentin Labbe 				  struct sun8i_ss_hash_reqctx *rctx,
300d9b45418SCorentin Labbe 				  const char *name)
301d9b45418SCorentin Labbe {
302d9b45418SCorentin Labbe 	int flow = rctx->flow;
303d9b45418SCorentin Labbe 	u32 v = SS_START;
304d9b45418SCorentin Labbe 	int i;
305d9b45418SCorentin Labbe 
306d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
307d9b45418SCorentin Labbe 	ss->flows[flow].stat_req++;
308d9b45418SCorentin Labbe #endif
309d9b45418SCorentin Labbe 
310d9b45418SCorentin Labbe 	/* choose between stream0/stream1 */
311d9b45418SCorentin Labbe 	if (flow)
312d9b45418SCorentin Labbe 		v |= SS_FLOW1;
313d9b45418SCorentin Labbe 	else
314d9b45418SCorentin Labbe 		v |= SS_FLOW0;
315d9b45418SCorentin Labbe 
316d9b45418SCorentin Labbe 	v |= rctx->method;
317d9b45418SCorentin Labbe 
318d9b45418SCorentin Labbe 	for (i = 0; i < MAX_SG; i++) {
319d9b45418SCorentin Labbe 		if (!rctx->t_dst[i].addr)
320d9b45418SCorentin Labbe 			break;
321d9b45418SCorentin Labbe 
322d9b45418SCorentin Labbe 		mutex_lock(&ss->mlock);
323d9b45418SCorentin Labbe 		if (i > 0) {
324d9b45418SCorentin Labbe 			v |= BIT(17);
325d9b45418SCorentin Labbe 			writel(rctx->t_dst[i - 1].addr, ss->base + SS_KEY_ADR_REG);
326d9b45418SCorentin Labbe 			writel(rctx->t_dst[i - 1].addr, ss->base + SS_IV_ADR_REG);
327d9b45418SCorentin Labbe 		}
328d9b45418SCorentin Labbe 
329d9b45418SCorentin Labbe 		dev_dbg(ss->dev,
330d9b45418SCorentin Labbe 			"Processing SG %d on flow %d %s ctl=%x %d to %d method=%x src=%x dst=%x\n",
331d9b45418SCorentin Labbe 			i, flow, name, v,
332d9b45418SCorentin Labbe 			rctx->t_src[i].len, rctx->t_dst[i].len,
333d9b45418SCorentin Labbe 			rctx->method, rctx->t_src[i].addr, rctx->t_dst[i].addr);
334d9b45418SCorentin Labbe 
335d9b45418SCorentin Labbe 		writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG);
336d9b45418SCorentin Labbe 		writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG);
337d9b45418SCorentin Labbe 		writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG);
338d9b45418SCorentin Labbe 		writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG);
339d9b45418SCorentin Labbe 
340d9b45418SCorentin Labbe 		reinit_completion(&ss->flows[flow].complete);
341d9b45418SCorentin Labbe 		ss->flows[flow].status = 0;
342d9b45418SCorentin Labbe 		wmb();
343d9b45418SCorentin Labbe 
344d9b45418SCorentin Labbe 		writel(v, ss->base + SS_CTL_REG);
345d9b45418SCorentin Labbe 		mutex_unlock(&ss->mlock);
346d9b45418SCorentin Labbe 		wait_for_completion_interruptible_timeout(&ss->flows[flow].complete,
347d9b45418SCorentin Labbe 							  msecs_to_jiffies(2000));
348d9b45418SCorentin Labbe 		if (ss->flows[flow].status == 0) {
349d9b45418SCorentin Labbe 			dev_err(ss->dev, "DMA timeout for %s\n", name);
350d9b45418SCorentin Labbe 			return -EFAULT;
351d9b45418SCorentin Labbe 		}
352d9b45418SCorentin Labbe 	}
353d9b45418SCorentin Labbe 
354d9b45418SCorentin Labbe 	return 0;
355d9b45418SCorentin Labbe }
356d9b45418SCorentin Labbe 
sun8i_ss_hash_need_fallback(struct ahash_request * areq)357d9b45418SCorentin Labbe static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
358d9b45418SCorentin Labbe {
359f95f61d0SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
360*4c19e8fbSHerbert Xu 	struct ahash_alg *alg = crypto_ahash_alg(tfm);
361f95f61d0SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
362d9b45418SCorentin Labbe 	struct scatterlist *sg;
363d9b45418SCorentin Labbe 
364*4c19e8fbSHerbert Xu 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash.base);
365f95f61d0SCorentin Labbe 
366f95f61d0SCorentin Labbe 	if (areq->nbytes == 0) {
367f95f61d0SCorentin Labbe 		algt->stat_fb_len++;
368d9b45418SCorentin Labbe 		return true;
369f95f61d0SCorentin Labbe 	}
370f95f61d0SCorentin Labbe 
371f95f61d0SCorentin Labbe 	if (areq->nbytes >= MAX_PAD_SIZE - 64) {
372f95f61d0SCorentin Labbe 		algt->stat_fb_len++;
373c35e523aSCorentin Labbe 		return true;
374f95f61d0SCorentin Labbe 	}
375c35e523aSCorentin Labbe 
376d9b45418SCorentin Labbe 	/* we need to reserve one SG for the padding one */
377f95f61d0SCorentin Labbe 	if (sg_nents(areq->src) > MAX_SG - 1) {
378f95f61d0SCorentin Labbe 		algt->stat_fb_sgnum++;
379d9b45418SCorentin Labbe 		return true;
380f95f61d0SCorentin Labbe 	}
381f95f61d0SCorentin Labbe 
382d9b45418SCorentin Labbe 	sg = areq->src;
383d9b45418SCorentin Labbe 	while (sg) {
384d9b45418SCorentin Labbe 		/* SS can operate hash only on full block size
385d9b45418SCorentin Labbe 		 * since SS support only MD5,sha1,sha224 and sha256, blocksize
386d9b45418SCorentin Labbe 		 * is always 64
387d9b45418SCorentin Labbe 		 */
388c35e523aSCorentin Labbe 		/* Only the last block could be bounced to the pad buffer */
389f95f61d0SCorentin Labbe 		if (sg->length % 64 && sg_next(sg)) {
390f95f61d0SCorentin Labbe 			algt->stat_fb_sglen++;
391c35e523aSCorentin Labbe 			return true;
392f95f61d0SCorentin Labbe 		}
393f95f61d0SCorentin Labbe 		if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
394f95f61d0SCorentin Labbe 			algt->stat_fb_align++;
395c35e523aSCorentin Labbe 			return true;
396f95f61d0SCorentin Labbe 		}
397f95f61d0SCorentin Labbe 		if (sg->length % 4) {
398f95f61d0SCorentin Labbe 			algt->stat_fb_sglen++;
399d9b45418SCorentin Labbe 			return true;
400f95f61d0SCorentin Labbe 		}
401d9b45418SCorentin Labbe 		sg = sg_next(sg);
402d9b45418SCorentin Labbe 	}
403d9b45418SCorentin Labbe 	return false;
404d9b45418SCorentin Labbe }
405d9b45418SCorentin Labbe 
sun8i_ss_hash_digest(struct ahash_request * areq)406d9b45418SCorentin Labbe int sun8i_ss_hash_digest(struct ahash_request *areq)
407d9b45418SCorentin Labbe {
408d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
409d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
410*4c19e8fbSHerbert Xu 	struct ahash_alg *alg = crypto_ahash_alg(tfm);
411d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
412d9b45418SCorentin Labbe 	struct sun8i_ss_dev *ss;
413d9b45418SCorentin Labbe 	struct crypto_engine *engine;
41446e2fcbcSCorentin Labbe 	int e;
415d9b45418SCorentin Labbe 
416d9b45418SCorentin Labbe 	if (sun8i_ss_hash_need_fallback(areq))
417d9b45418SCorentin Labbe 		return sun8i_ss_hash_digest_fb(areq);
418d9b45418SCorentin Labbe 
419*4c19e8fbSHerbert Xu 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash.base);
420d9b45418SCorentin Labbe 	ss = algt->ss;
421d9b45418SCorentin Labbe 
422d9b45418SCorentin Labbe 	e = sun8i_ss_get_engine_number(ss);
423d9b45418SCorentin Labbe 	rctx->flow = e;
424d9b45418SCorentin Labbe 	engine = ss->flows[e].engine;
425d9b45418SCorentin Labbe 
426d9b45418SCorentin Labbe 	return crypto_transfer_hash_request_to_engine(engine, areq);
427d9b45418SCorentin Labbe }
428d9b45418SCorentin Labbe 
hash_pad(__le32 * buf,unsigned int bufsize,u64 padi,u64 byte_count,bool le,int bs)429e76ee4dbSCorentin Labbe static u64 hash_pad(__le32 *buf, unsigned int bufsize, u64 padi, u64 byte_count, bool le, int bs)
430e76ee4dbSCorentin Labbe {
431e76ee4dbSCorentin Labbe 	u64 fill, min_fill, j, k;
432e76ee4dbSCorentin Labbe 	__be64 *bebits;
433e76ee4dbSCorentin Labbe 	__le64 *lebits;
434e76ee4dbSCorentin Labbe 
435e76ee4dbSCorentin Labbe 	j = padi;
436e76ee4dbSCorentin Labbe 	buf[j++] = cpu_to_le32(0x80);
437e76ee4dbSCorentin Labbe 
438e76ee4dbSCorentin Labbe 	if (bs == 64) {
439e76ee4dbSCorentin Labbe 		fill = 64 - (byte_count % 64);
440e76ee4dbSCorentin Labbe 		min_fill = 2 * sizeof(u32) + sizeof(u32);
441e76ee4dbSCorentin Labbe 	} else {
442e76ee4dbSCorentin Labbe 		fill = 128 - (byte_count % 128);
443e76ee4dbSCorentin Labbe 		min_fill = 4 * sizeof(u32) + sizeof(u32);
444e76ee4dbSCorentin Labbe 	}
445e76ee4dbSCorentin Labbe 
446e76ee4dbSCorentin Labbe 	if (fill < min_fill)
447e76ee4dbSCorentin Labbe 		fill += bs;
448e76ee4dbSCorentin Labbe 
449e76ee4dbSCorentin Labbe 	k = j;
450e76ee4dbSCorentin Labbe 	j += (fill - min_fill) / sizeof(u32);
451e76ee4dbSCorentin Labbe 	if (j * 4 > bufsize) {
452e76ee4dbSCorentin Labbe 		pr_err("%s OVERFLOW %llu\n", __func__, j);
453e76ee4dbSCorentin Labbe 		return 0;
454e76ee4dbSCorentin Labbe 	}
455e76ee4dbSCorentin Labbe 	for (; k < j; k++)
456e76ee4dbSCorentin Labbe 		buf[k] = 0;
457e76ee4dbSCorentin Labbe 
458e76ee4dbSCorentin Labbe 	if (le) {
459e76ee4dbSCorentin Labbe 		/* MD5 */
460e76ee4dbSCorentin Labbe 		lebits = (__le64 *)&buf[j];
461e76ee4dbSCorentin Labbe 		*lebits = cpu_to_le64(byte_count << 3);
462e76ee4dbSCorentin Labbe 		j += 2;
463e76ee4dbSCorentin Labbe 	} else {
464e76ee4dbSCorentin Labbe 		if (bs == 64) {
465e76ee4dbSCorentin Labbe 			/* sha1 sha224 sha256 */
466e76ee4dbSCorentin Labbe 			bebits = (__be64 *)&buf[j];
467e76ee4dbSCorentin Labbe 			*bebits = cpu_to_be64(byte_count << 3);
468e76ee4dbSCorentin Labbe 			j += 2;
469e76ee4dbSCorentin Labbe 		} else {
470e76ee4dbSCorentin Labbe 			/* sha384 sha512*/
471e76ee4dbSCorentin Labbe 			bebits = (__be64 *)&buf[j];
472e76ee4dbSCorentin Labbe 			*bebits = cpu_to_be64(byte_count >> 61);
473e76ee4dbSCorentin Labbe 			j += 2;
474e76ee4dbSCorentin Labbe 			bebits = (__be64 *)&buf[j];
475e76ee4dbSCorentin Labbe 			*bebits = cpu_to_be64(byte_count << 3);
476e76ee4dbSCorentin Labbe 			j += 2;
477e76ee4dbSCorentin Labbe 		}
478e76ee4dbSCorentin Labbe 	}
479e76ee4dbSCorentin Labbe 	if (j * 4 > bufsize) {
480e76ee4dbSCorentin Labbe 		pr_err("%s OVERFLOW %llu\n", __func__, j);
481e76ee4dbSCorentin Labbe 		return 0;
482e76ee4dbSCorentin Labbe 	}
483e76ee4dbSCorentin Labbe 
484e76ee4dbSCorentin Labbe 	return j;
485e76ee4dbSCorentin Labbe }
486e76ee4dbSCorentin Labbe 
487d9b45418SCorentin Labbe /* sun8i_ss_hash_run - run an ahash request
488d9b45418SCorentin Labbe  * Send the data of the request to the SS along with an extra SG with padding
489d9b45418SCorentin Labbe  */
sun8i_ss_hash_run(struct crypto_engine * engine,void * breq)490d9b45418SCorentin Labbe int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
491d9b45418SCorentin Labbe {
492d9b45418SCorentin Labbe 	struct ahash_request *areq = container_of(breq, struct ahash_request, base);
493d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
494801b7d57SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
495d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
496*4c19e8fbSHerbert Xu 	struct ahash_alg *alg = crypto_ahash_alg(tfm);
497d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
498d9b45418SCorentin Labbe 	struct sun8i_ss_dev *ss;
499d9b45418SCorentin Labbe 	struct scatterlist *sg;
500801b7d57SCorentin Labbe 	int bs = crypto_ahash_blocksize(tfm);
501d9b45418SCorentin Labbe 	int nr_sgs, err, digestsize;
502d9b45418SCorentin Labbe 	unsigned int len;
503e76ee4dbSCorentin Labbe 	u64 byte_count;
504d9b45418SCorentin Labbe 	void *pad, *result;
505db0c62bcSCorentin Labbe 	int j, i, k, todo;
506801b7d57SCorentin Labbe 	dma_addr_t addr_res, addr_pad, addr_xpad;
507d9b45418SCorentin Labbe 	__le32 *bf;
508801b7d57SCorentin Labbe 	/* HMAC step:
509801b7d57SCorentin Labbe 	 * 0: normal hashing
510801b7d57SCorentin Labbe 	 * 1: IPAD
511801b7d57SCorentin Labbe 	 * 2: OPAD
512801b7d57SCorentin Labbe 	 */
513801b7d57SCorentin Labbe 	int hmac = 0;
514d9b45418SCorentin Labbe 
515*4c19e8fbSHerbert Xu 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash.base);
516d9b45418SCorentin Labbe 	ss = algt->ss;
517d9b45418SCorentin Labbe 
518*4c19e8fbSHerbert Xu 	digestsize = crypto_ahash_digestsize(tfm);
519d9b45418SCorentin Labbe 	if (digestsize == SHA224_DIGEST_SIZE)
520d9b45418SCorentin Labbe 		digestsize = SHA256_DIGEST_SIZE;
521d9b45418SCorentin Labbe 
5228eec4563SCorentin Labbe 	result = ss->flows[rctx->flow].result;
5238eec4563SCorentin Labbe 	pad = ss->flows[rctx->flow].pad;
524d9b45418SCorentin Labbe 	bf = (__le32 *)pad;
525d9b45418SCorentin Labbe 
526d9b45418SCorentin Labbe 	for (i = 0; i < MAX_SG; i++) {
527d9b45418SCorentin Labbe 		rctx->t_dst[i].addr = 0;
528d9b45418SCorentin Labbe 		rctx->t_dst[i].len = 0;
529d9b45418SCorentin Labbe 	}
530d9b45418SCorentin Labbe 
531d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
532d9b45418SCorentin Labbe 	algt->stat_req++;
533d9b45418SCorentin Labbe #endif
534d9b45418SCorentin Labbe 
535d9b45418SCorentin Labbe 	rctx->method = ss->variant->alg_hash[algt->ss_algo_id];
536d9b45418SCorentin Labbe 
537d9b45418SCorentin Labbe 	nr_sgs = dma_map_sg(ss->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
538d9b45418SCorentin Labbe 	if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
539d9b45418SCorentin Labbe 		dev_err(ss->dev, "Invalid sg number %d\n", nr_sgs);
540d9b45418SCorentin Labbe 		err = -EINVAL;
541d9b45418SCorentin Labbe 		goto theend;
542d9b45418SCorentin Labbe 	}
543d9b45418SCorentin Labbe 
544d9b45418SCorentin Labbe 	addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
545d9b45418SCorentin Labbe 	if (dma_mapping_error(ss->dev, addr_res)) {
546d9b45418SCorentin Labbe 		dev_err(ss->dev, "DMA map dest\n");
547d9b45418SCorentin Labbe 		err = -EINVAL;
548801b7d57SCorentin Labbe 		goto err_dma_result;
549d9b45418SCorentin Labbe 	}
550d9b45418SCorentin Labbe 
551c35e523aSCorentin Labbe 	j = 0;
552d9b45418SCorentin Labbe 	len = areq->nbytes;
553c149e476SCorentin Labbe 	sg = areq->src;
554c149e476SCorentin Labbe 	i = 0;
555c149e476SCorentin Labbe 	while (len > 0 && sg) {
556c149e476SCorentin Labbe 		if (sg_dma_len(sg) == 0) {
557c149e476SCorentin Labbe 			sg = sg_next(sg);
558c149e476SCorentin Labbe 			continue;
559c149e476SCorentin Labbe 		}
560d9b45418SCorentin Labbe 		todo = min(len, sg_dma_len(sg));
561c35e523aSCorentin Labbe 		/* only the last SG could be with a size not modulo64 */
562c35e523aSCorentin Labbe 		if (todo % 64 == 0) {
563c35e523aSCorentin Labbe 			rctx->t_src[i].addr = sg_dma_address(sg);
564d9b45418SCorentin Labbe 			rctx->t_src[i].len = todo / 4;
565d9b45418SCorentin Labbe 			rctx->t_dst[i].addr = addr_res;
566d9b45418SCorentin Labbe 			rctx->t_dst[i].len = digestsize / 4;
567c35e523aSCorentin Labbe 			len -= todo;
568c35e523aSCorentin Labbe 		} else {
569c35e523aSCorentin Labbe 			scatterwalk_map_and_copy(bf, sg, 0, todo, 0);
570c35e523aSCorentin Labbe 			j += todo / 4;
571c35e523aSCorentin Labbe 			len -= todo;
572c35e523aSCorentin Labbe 		}
573c149e476SCorentin Labbe 		sg = sg_next(sg);
574c149e476SCorentin Labbe 		i++;
575d9b45418SCorentin Labbe 	}
576d9b45418SCorentin Labbe 	if (len > 0) {
577d9b45418SCorentin Labbe 		dev_err(ss->dev, "remaining len %d\n", len);
578d9b45418SCorentin Labbe 		err = -EINVAL;
579d9b45418SCorentin Labbe 		goto theend;
580d9b45418SCorentin Labbe 	}
581d9b45418SCorentin Labbe 
582c35e523aSCorentin Labbe 	if (j > 0)
583c35e523aSCorentin Labbe 		i--;
584c35e523aSCorentin Labbe 
585801b7d57SCorentin Labbe retry:
586d9b45418SCorentin Labbe 	byte_count = areq->nbytes;
587801b7d57SCorentin Labbe 	if (tfmctx->keylen && hmac == 0) {
588801b7d57SCorentin Labbe 		hmac = 1;
589801b7d57SCorentin Labbe 		/* shift all SG one slot up, to free slot 0 for IPAD */
590801b7d57SCorentin Labbe 		for (k = 6; k >= 0; k--) {
591801b7d57SCorentin Labbe 			rctx->t_src[k + 1].addr = rctx->t_src[k].addr;
592801b7d57SCorentin Labbe 			rctx->t_src[k + 1].len = rctx->t_src[k].len;
593801b7d57SCorentin Labbe 			rctx->t_dst[k + 1].addr = rctx->t_dst[k].addr;
594801b7d57SCorentin Labbe 			rctx->t_dst[k + 1].len = rctx->t_dst[k].len;
595801b7d57SCorentin Labbe 		}
596801b7d57SCorentin Labbe 		addr_xpad = dma_map_single(ss->dev, tfmctx->ipad, bs, DMA_TO_DEVICE);
5976cb3f9b2SDan Carpenter 		err = dma_mapping_error(ss->dev, addr_xpad);
5986cb3f9b2SDan Carpenter 		if (err) {
599801b7d57SCorentin Labbe 			dev_err(ss->dev, "Fail to create DMA mapping of ipad\n");
600801b7d57SCorentin Labbe 			goto err_dma_xpad;
601801b7d57SCorentin Labbe 		}
602801b7d57SCorentin Labbe 		rctx->t_src[0].addr = addr_xpad;
603801b7d57SCorentin Labbe 		rctx->t_src[0].len = bs / 4;
604801b7d57SCorentin Labbe 		rctx->t_dst[0].addr = addr_res;
605801b7d57SCorentin Labbe 		rctx->t_dst[0].len = digestsize / 4;
606801b7d57SCorentin Labbe 		i++;
607801b7d57SCorentin Labbe 		byte_count = areq->nbytes + bs;
608801b7d57SCorentin Labbe 	}
609801b7d57SCorentin Labbe 	if (tfmctx->keylen && hmac == 2) {
610801b7d57SCorentin Labbe 		for (i = 0; i < MAX_SG; i++) {
611801b7d57SCorentin Labbe 			rctx->t_src[i].addr = 0;
612801b7d57SCorentin Labbe 			rctx->t_src[i].len = 0;
613801b7d57SCorentin Labbe 			rctx->t_dst[i].addr = 0;
614801b7d57SCorentin Labbe 			rctx->t_dst[i].len = 0;
615801b7d57SCorentin Labbe 		}
616801b7d57SCorentin Labbe 
617801b7d57SCorentin Labbe 		addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
618801b7d57SCorentin Labbe 		if (dma_mapping_error(ss->dev, addr_res)) {
619801b7d57SCorentin Labbe 			dev_err(ss->dev, "Fail to create DMA mapping of result\n");
620801b7d57SCorentin Labbe 			err = -EINVAL;
621801b7d57SCorentin Labbe 			goto err_dma_result;
622801b7d57SCorentin Labbe 		}
623801b7d57SCorentin Labbe 		addr_xpad = dma_map_single(ss->dev, tfmctx->opad, bs, DMA_TO_DEVICE);
6246cb3f9b2SDan Carpenter 		err = dma_mapping_error(ss->dev, addr_xpad);
6256cb3f9b2SDan Carpenter 		if (err) {
626801b7d57SCorentin Labbe 			dev_err(ss->dev, "Fail to create DMA mapping of opad\n");
627801b7d57SCorentin Labbe 			goto err_dma_xpad;
628801b7d57SCorentin Labbe 		}
629801b7d57SCorentin Labbe 		rctx->t_src[0].addr = addr_xpad;
630801b7d57SCorentin Labbe 		rctx->t_src[0].len = bs / 4;
631801b7d57SCorentin Labbe 
632801b7d57SCorentin Labbe 		memcpy(bf, result, digestsize);
633801b7d57SCorentin Labbe 		j = digestsize / 4;
634801b7d57SCorentin Labbe 		i = 1;
635801b7d57SCorentin Labbe 		byte_count = digestsize + bs;
636801b7d57SCorentin Labbe 
637801b7d57SCorentin Labbe 		rctx->t_dst[0].addr = addr_res;
638801b7d57SCorentin Labbe 		rctx->t_dst[0].len = digestsize / 4;
639801b7d57SCorentin Labbe 	}
640801b7d57SCorentin Labbe 
641d9b45418SCorentin Labbe 	switch (algt->ss_algo_id) {
642d9b45418SCorentin Labbe 	case SS_ID_HASH_MD5:
643e76ee4dbSCorentin Labbe 		j = hash_pad(bf, 4096, j, byte_count, true, bs);
644d9b45418SCorentin Labbe 		break;
645d9b45418SCorentin Labbe 	case SS_ID_HASH_SHA1:
646d9b45418SCorentin Labbe 	case SS_ID_HASH_SHA224:
647d9b45418SCorentin Labbe 	case SS_ID_HASH_SHA256:
648e76ee4dbSCorentin Labbe 		j = hash_pad(bf, 4096, j, byte_count, false, bs);
649d9b45418SCorentin Labbe 		break;
650d9b45418SCorentin Labbe 	}
651e76ee4dbSCorentin Labbe 	if (!j) {
652e76ee4dbSCorentin Labbe 		err = -EINVAL;
653e76ee4dbSCorentin Labbe 		goto theend;
654e76ee4dbSCorentin Labbe 	}
655d9b45418SCorentin Labbe 
656d9b45418SCorentin Labbe 	addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE);
657d9b45418SCorentin Labbe 	if (dma_mapping_error(ss->dev, addr_pad)) {
658d9b45418SCorentin Labbe 		dev_err(ss->dev, "DMA error on padding SG\n");
659d9b45418SCorentin Labbe 		err = -EINVAL;
660801b7d57SCorentin Labbe 		goto err_dma_pad;
661d9b45418SCorentin Labbe 	}
662d86e3f37SCorentin Labbe 	rctx->t_src[i].addr = addr_pad;
663d86e3f37SCorentin Labbe 	rctx->t_src[i].len = j;
664d86e3f37SCorentin Labbe 	rctx->t_dst[i].addr = addr_res;
665d86e3f37SCorentin Labbe 	rctx->t_dst[i].len = digestsize / 4;
666d9b45418SCorentin Labbe 
667d9b45418SCorentin Labbe 	err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
668d9b45418SCorentin Labbe 
669801b7d57SCorentin Labbe 	/*
670801b7d57SCorentin Labbe 	 * mini helper for checking dma map/unmap
671801b7d57SCorentin Labbe 	 * flow start for hmac = 0 (and HMAC = 1)
672801b7d57SCorentin Labbe 	 * HMAC = 0
673801b7d57SCorentin Labbe 	 * MAP src
674801b7d57SCorentin Labbe 	 * MAP res
675801b7d57SCorentin Labbe 	 *
676801b7d57SCorentin Labbe 	 * retry:
677801b7d57SCorentin Labbe 	 * if hmac then hmac = 1
678801b7d57SCorentin Labbe 	 *	MAP xpad (ipad)
679801b7d57SCorentin Labbe 	 * if hmac == 2
680801b7d57SCorentin Labbe 	 *	MAP res
681801b7d57SCorentin Labbe 	 *	MAP xpad (opad)
682801b7d57SCorentin Labbe 	 * MAP pad
683801b7d57SCorentin Labbe 	 * ACTION!
684801b7d57SCorentin Labbe 	 * UNMAP pad
685801b7d57SCorentin Labbe 	 * if hmac
686801b7d57SCorentin Labbe 	 *	UNMAP xpad
687801b7d57SCorentin Labbe 	 * UNMAP res
688801b7d57SCorentin Labbe 	 * if hmac < 2
689801b7d57SCorentin Labbe 	 *	UNMAP SRC
690801b7d57SCorentin Labbe 	 *
691801b7d57SCorentin Labbe 	 * if hmac = 1 then hmac = 2 goto retry
692801b7d57SCorentin Labbe 	 */
693801b7d57SCorentin Labbe 
694d9b45418SCorentin Labbe 	dma_unmap_single(ss->dev, addr_pad, j * 4, DMA_TO_DEVICE);
695801b7d57SCorentin Labbe 
696801b7d57SCorentin Labbe err_dma_pad:
697801b7d57SCorentin Labbe 	if (hmac > 0)
698801b7d57SCorentin Labbe 		dma_unmap_single(ss->dev, addr_xpad, bs, DMA_TO_DEVICE);
699801b7d57SCorentin Labbe err_dma_xpad:
700801b7d57SCorentin Labbe 	dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE);
701801b7d57SCorentin Labbe err_dma_result:
702801b7d57SCorentin Labbe 	if (hmac < 2)
703884b93c5SXiang Chen 		dma_unmap_sg(ss->dev, areq->src, sg_nents(areq->src),
704884b93c5SXiang Chen 			     DMA_TO_DEVICE);
705801b7d57SCorentin Labbe 	if (hmac == 1 && !err) {
706801b7d57SCorentin Labbe 		hmac = 2;
707801b7d57SCorentin Labbe 		goto retry;
708801b7d57SCorentin Labbe 	}
709d9b45418SCorentin Labbe 
710801b7d57SCorentin Labbe 	if (!err)
711*4c19e8fbSHerbert Xu 		memcpy(areq->result, result, crypto_ahash_digestsize(tfm));
712d9b45418SCorentin Labbe theend:
713b169b376SCorentin Labbe 	local_bh_disable();
714d9b45418SCorentin Labbe 	crypto_finalize_hash_request(engine, breq, err);
715b169b376SCorentin Labbe 	local_bh_enable();
716d9b45418SCorentin Labbe 	return 0;
717d9b45418SCorentin Labbe }
718