xref: /openbmc/linux/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c (revision 39db3f15194954568b626bfb8cf50910ad811bdc)
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  *
10*39db3f15SJonathan Corbet  * You could find the datasheet in Documentation/arch/arm/sunxi.rst
11d9b45418SCorentin Labbe  */
12b169b376SCorentin Labbe #include <linux/bottom_half.h>
13d9b45418SCorentin Labbe #include <linux/dma-mapping.h>
14d9b45418SCorentin Labbe #include <linux/pm_runtime.h>
15d9b45418SCorentin Labbe #include <linux/scatterlist.h>
16d9b45418SCorentin Labbe #include <crypto/internal/hash.h>
17801b7d57SCorentin Labbe #include <crypto/hmac.h>
18c35e523aSCorentin Labbe #include <crypto/scatterwalk.h>
19a24d22b2SEric Biggers #include <crypto/sha1.h>
20a24d22b2SEric Biggers #include <crypto/sha2.h>
21d9b45418SCorentin Labbe #include <crypto/md5.h>
22d9b45418SCorentin Labbe #include "sun8i-ss.h"
23d9b45418SCorentin Labbe 
24801b7d57SCorentin Labbe static int sun8i_ss_hashkey(struct sun8i_ss_hash_tfm_ctx *tfmctx, const u8 *key,
25801b7d57SCorentin Labbe 			    unsigned int keylen)
26801b7d57SCorentin Labbe {
27801b7d57SCorentin Labbe 	struct crypto_shash *xtfm;
28801b7d57SCorentin Labbe 	struct shash_desc *sdesc;
29801b7d57SCorentin Labbe 	size_t len;
30801b7d57SCorentin Labbe 	int ret = 0;
31801b7d57SCorentin Labbe 
32801b7d57SCorentin Labbe 	xtfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_NEED_FALLBACK);
337e8df1fcSPeng Wu 	if (IS_ERR(xtfm))
347e8df1fcSPeng Wu 		return PTR_ERR(xtfm);
35801b7d57SCorentin Labbe 
36801b7d57SCorentin Labbe 	len = sizeof(*sdesc) + crypto_shash_descsize(xtfm);
37801b7d57SCorentin Labbe 	sdesc = kmalloc(len, GFP_KERNEL);
38801b7d57SCorentin Labbe 	if (!sdesc) {
39801b7d57SCorentin Labbe 		ret = -ENOMEM;
40801b7d57SCorentin Labbe 		goto err_hashkey_sdesc;
41801b7d57SCorentin Labbe 	}
42801b7d57SCorentin Labbe 	sdesc->tfm = xtfm;
43801b7d57SCorentin Labbe 
44801b7d57SCorentin Labbe 	ret = crypto_shash_init(sdesc);
45801b7d57SCorentin Labbe 	if (ret) {
46801b7d57SCorentin Labbe 		dev_err(tfmctx->ss->dev, "shash init error ret=%d\n", ret);
47801b7d57SCorentin Labbe 		goto err_hashkey;
48801b7d57SCorentin Labbe 	}
49801b7d57SCorentin Labbe 	ret = crypto_shash_finup(sdesc, key, keylen, tfmctx->key);
50801b7d57SCorentin Labbe 	if (ret)
51801b7d57SCorentin Labbe 		dev_err(tfmctx->ss->dev, "shash finup error\n");
52801b7d57SCorentin Labbe err_hashkey:
53801b7d57SCorentin Labbe 	kfree(sdesc);
54801b7d57SCorentin Labbe err_hashkey_sdesc:
55801b7d57SCorentin Labbe 	crypto_free_shash(xtfm);
56801b7d57SCorentin Labbe 	return ret;
57801b7d57SCorentin Labbe }
58801b7d57SCorentin Labbe 
59801b7d57SCorentin Labbe int sun8i_ss_hmac_setkey(struct crypto_ahash *ahash, const u8 *key,
60801b7d57SCorentin Labbe 			 unsigned int keylen)
61801b7d57SCorentin Labbe {
62801b7d57SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(ahash);
63801b7d57SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(ahash->base.__crt_alg);
64801b7d57SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
65801b7d57SCorentin Labbe 	int digestsize, i;
66801b7d57SCorentin Labbe 	int bs = crypto_ahash_blocksize(ahash);
67801b7d57SCorentin Labbe 	int ret;
68801b7d57SCorentin Labbe 
69801b7d57SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
70801b7d57SCorentin Labbe 	digestsize = algt->alg.hash.halg.digestsize;
71801b7d57SCorentin Labbe 
72801b7d57SCorentin Labbe 	if (keylen > bs) {
73801b7d57SCorentin Labbe 		ret = sun8i_ss_hashkey(tfmctx, key, keylen);
74801b7d57SCorentin Labbe 		if (ret)
75801b7d57SCorentin Labbe 			return ret;
76801b7d57SCorentin Labbe 		tfmctx->keylen = digestsize;
77801b7d57SCorentin Labbe 	} else {
78801b7d57SCorentin Labbe 		tfmctx->keylen = keylen;
79801b7d57SCorentin Labbe 		memcpy(tfmctx->key, key, keylen);
80801b7d57SCorentin Labbe 	}
81801b7d57SCorentin Labbe 
8239a76cf1SHerbert Xu 	tfmctx->ipad = kzalloc(bs, GFP_KERNEL);
83801b7d57SCorentin Labbe 	if (!tfmctx->ipad)
84801b7d57SCorentin Labbe 		return -ENOMEM;
8539a76cf1SHerbert Xu 	tfmctx->opad = kzalloc(bs, GFP_KERNEL);
86801b7d57SCorentin Labbe 	if (!tfmctx->opad) {
87801b7d57SCorentin Labbe 		ret = -ENOMEM;
88801b7d57SCorentin Labbe 		goto err_opad;
89801b7d57SCorentin Labbe 	}
90801b7d57SCorentin Labbe 
91801b7d57SCorentin Labbe 	memset(tfmctx->key + tfmctx->keylen, 0, bs - tfmctx->keylen);
92801b7d57SCorentin Labbe 	memcpy(tfmctx->ipad, tfmctx->key, tfmctx->keylen);
93801b7d57SCorentin Labbe 	memcpy(tfmctx->opad, tfmctx->key, tfmctx->keylen);
94801b7d57SCorentin Labbe 	for (i = 0; i < bs; i++) {
95801b7d57SCorentin Labbe 		tfmctx->ipad[i] ^= HMAC_IPAD_VALUE;
96801b7d57SCorentin Labbe 		tfmctx->opad[i] ^= HMAC_OPAD_VALUE;
97801b7d57SCorentin Labbe 	}
98801b7d57SCorentin Labbe 
99801b7d57SCorentin Labbe 	ret = crypto_ahash_setkey(tfmctx->fallback_tfm, key, keylen);
100801b7d57SCorentin Labbe 	if (!ret)
101801b7d57SCorentin Labbe 		return 0;
102801b7d57SCorentin Labbe 
103801b7d57SCorentin Labbe 	memzero_explicit(tfmctx->key, keylen);
104801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->opad);
105801b7d57SCorentin Labbe err_opad:
106801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->ipad);
107801b7d57SCorentin Labbe 	return ret;
108801b7d57SCorentin Labbe }
109801b7d57SCorentin Labbe 
110d9b45418SCorentin Labbe int sun8i_ss_hash_crainit(struct crypto_tfm *tfm)
111d9b45418SCorentin Labbe {
112d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *op = crypto_tfm_ctx(tfm);
113d9b45418SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
114d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
115d9b45418SCorentin Labbe 	int err;
116d9b45418SCorentin Labbe 
117d9b45418SCorentin Labbe 	memset(op, 0, sizeof(struct sun8i_ss_hash_tfm_ctx));
118d9b45418SCorentin Labbe 
119d9b45418SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
120d9b45418SCorentin Labbe 	op->ss = algt->ss;
121d9b45418SCorentin Labbe 
122d9b45418SCorentin Labbe 	op->enginectx.op.do_one_request = sun8i_ss_hash_run;
123d9b45418SCorentin Labbe 	op->enginectx.op.prepare_request = NULL;
124d9b45418SCorentin Labbe 	op->enginectx.op.unprepare_request = NULL;
125d9b45418SCorentin Labbe 
126d9b45418SCorentin Labbe 	/* FALLBACK */
127d9b45418SCorentin Labbe 	op->fallback_tfm = crypto_alloc_ahash(crypto_tfm_alg_name(tfm), 0,
128d9b45418SCorentin Labbe 					      CRYPTO_ALG_NEED_FALLBACK);
129d9b45418SCorentin Labbe 	if (IS_ERR(op->fallback_tfm)) {
130d9b45418SCorentin Labbe 		dev_err(algt->ss->dev, "Fallback driver could no be loaded\n");
131d9b45418SCorentin Labbe 		return PTR_ERR(op->fallback_tfm);
132d9b45418SCorentin Labbe 	}
133d9b45418SCorentin Labbe 
134d9b45418SCorentin Labbe 	if (algt->alg.hash.halg.statesize < crypto_ahash_statesize(op->fallback_tfm))
135d9b45418SCorentin Labbe 		algt->alg.hash.halg.statesize = crypto_ahash_statesize(op->fallback_tfm);
136d9b45418SCorentin Labbe 
137d9b45418SCorentin Labbe 	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
138d9b45418SCorentin Labbe 				 sizeof(struct sun8i_ss_hash_reqctx) +
139d9b45418SCorentin Labbe 				 crypto_ahash_reqsize(op->fallback_tfm));
140d9b45418SCorentin Labbe 
141f95f61d0SCorentin Labbe 	memcpy(algt->fbname, crypto_tfm_alg_driver_name(&op->fallback_tfm->base), CRYPTO_MAX_ALG_NAME);
142f95f61d0SCorentin Labbe 
143d9b45418SCorentin Labbe 	err = pm_runtime_get_sync(op->ss->dev);
144d9b45418SCorentin Labbe 	if (err < 0)
145d9b45418SCorentin Labbe 		goto error_pm;
146d9b45418SCorentin Labbe 	return 0;
147d9b45418SCorentin Labbe error_pm:
148d9b45418SCorentin Labbe 	pm_runtime_put_noidle(op->ss->dev);
149d9b45418SCorentin Labbe 	crypto_free_ahash(op->fallback_tfm);
150d9b45418SCorentin Labbe 	return err;
151d9b45418SCorentin Labbe }
152d9b45418SCorentin Labbe 
153d9b45418SCorentin Labbe void sun8i_ss_hash_craexit(struct crypto_tfm *tfm)
154d9b45418SCorentin Labbe {
155d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_tfm_ctx(tfm);
156d9b45418SCorentin Labbe 
157801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->ipad);
158801b7d57SCorentin Labbe 	kfree_sensitive(tfmctx->opad);
159801b7d57SCorentin Labbe 
160d9b45418SCorentin Labbe 	crypto_free_ahash(tfmctx->fallback_tfm);
161d9b45418SCorentin Labbe 	pm_runtime_put_sync_suspend(tfmctx->ss->dev);
162d9b45418SCorentin Labbe }
163d9b45418SCorentin Labbe 
164d9b45418SCorentin Labbe int sun8i_ss_hash_init(struct ahash_request *areq)
165d9b45418SCorentin Labbe {
166d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
167d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
168d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
169d9b45418SCorentin Labbe 
170d9b45418SCorentin Labbe 	memset(rctx, 0, sizeof(struct sun8i_ss_hash_reqctx));
171d9b45418SCorentin Labbe 
172d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
173d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
174d9b45418SCorentin Labbe 
175d9b45418SCorentin Labbe 	return crypto_ahash_init(&rctx->fallback_req);
176d9b45418SCorentin Labbe }
177d9b45418SCorentin Labbe 
178d9b45418SCorentin Labbe int sun8i_ss_hash_export(struct ahash_request *areq, void *out)
179d9b45418SCorentin Labbe {
180d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
181d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
182d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
183d9b45418SCorentin Labbe 
184d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
185d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
186d9b45418SCorentin Labbe 
187d9b45418SCorentin Labbe 	return crypto_ahash_export(&rctx->fallback_req, out);
188d9b45418SCorentin Labbe }
189d9b45418SCorentin Labbe 
190d9b45418SCorentin Labbe int sun8i_ss_hash_import(struct ahash_request *areq, const void *in)
191d9b45418SCorentin Labbe {
192d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
193d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
194d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
195d9b45418SCorentin Labbe 
196d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
197d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
198d9b45418SCorentin Labbe 
199d9b45418SCorentin Labbe 	return crypto_ahash_import(&rctx->fallback_req, in);
200d9b45418SCorentin Labbe }
201d9b45418SCorentin Labbe 
202d9b45418SCorentin Labbe int sun8i_ss_hash_final(struct ahash_request *areq)
203d9b45418SCorentin Labbe {
204d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
205d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
206d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
207d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
208d9b45418SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
209d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
210d9b45418SCorentin Labbe #endif
211d9b45418SCorentin Labbe 
212d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
213d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags &
214d9b45418SCorentin Labbe 					CRYPTO_TFM_REQ_MAY_SLEEP;
215d9b45418SCorentin Labbe 	rctx->fallback_req.result = areq->result;
216d9b45418SCorentin Labbe 
217d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
218d9b45418SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
219d9b45418SCorentin Labbe 	algt->stat_fb++;
220d9b45418SCorentin Labbe #endif
221d9b45418SCorentin Labbe 
222d9b45418SCorentin Labbe 	return crypto_ahash_final(&rctx->fallback_req);
223d9b45418SCorentin Labbe }
224d9b45418SCorentin Labbe 
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 
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 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
246d9b45418SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
247d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
248d9b45418SCorentin Labbe #endif
249d9b45418SCorentin Labbe 
250d9b45418SCorentin Labbe 	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
251d9b45418SCorentin Labbe 	rctx->fallback_req.base.flags = areq->base.flags &
252d9b45418SCorentin Labbe 					CRYPTO_TFM_REQ_MAY_SLEEP;
253d9b45418SCorentin Labbe 
254d9b45418SCorentin Labbe 	rctx->fallback_req.nbytes = areq->nbytes;
255d9b45418SCorentin Labbe 	rctx->fallback_req.src = areq->src;
256d9b45418SCorentin Labbe 	rctx->fallback_req.result = areq->result;
257d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
258d9b45418SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
259d9b45418SCorentin Labbe 	algt->stat_fb++;
260d9b45418SCorentin Labbe #endif
261d9b45418SCorentin Labbe 
262d9b45418SCorentin Labbe 	return crypto_ahash_finup(&rctx->fallback_req);
263d9b45418SCorentin Labbe }
264d9b45418SCorentin Labbe 
265d9b45418SCorentin Labbe static int sun8i_ss_hash_digest_fb(struct ahash_request *areq)
266d9b45418SCorentin Labbe {
267d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
268d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
269d9b45418SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
270d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
271d9b45418SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
272d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
273d9b45418SCorentin Labbe #endif
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;
282d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
283d9b45418SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
284d9b45418SCorentin Labbe 	algt->stat_fb++;
285d9b45418SCorentin Labbe #endif
286d9b45418SCorentin Labbe 
287d9b45418SCorentin Labbe 	return crypto_ahash_digest(&rctx->fallback_req);
288d9b45418SCorentin Labbe }
289d9b45418SCorentin Labbe 
290d9b45418SCorentin Labbe static int sun8i_ss_run_hash_task(struct sun8i_ss_dev *ss,
291d9b45418SCorentin Labbe 				  struct sun8i_ss_hash_reqctx *rctx,
292d9b45418SCorentin Labbe 				  const char *name)
293d9b45418SCorentin Labbe {
294d9b45418SCorentin Labbe 	int flow = rctx->flow;
295d9b45418SCorentin Labbe 	u32 v = SS_START;
296d9b45418SCorentin Labbe 	int i;
297d9b45418SCorentin Labbe 
298d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
299d9b45418SCorentin Labbe 	ss->flows[flow].stat_req++;
300d9b45418SCorentin Labbe #endif
301d9b45418SCorentin Labbe 
302d9b45418SCorentin Labbe 	/* choose between stream0/stream1 */
303d9b45418SCorentin Labbe 	if (flow)
304d9b45418SCorentin Labbe 		v |= SS_FLOW1;
305d9b45418SCorentin Labbe 	else
306d9b45418SCorentin Labbe 		v |= SS_FLOW0;
307d9b45418SCorentin Labbe 
308d9b45418SCorentin Labbe 	v |= rctx->method;
309d9b45418SCorentin Labbe 
310d9b45418SCorentin Labbe 	for (i = 0; i < MAX_SG; i++) {
311d9b45418SCorentin Labbe 		if (!rctx->t_dst[i].addr)
312d9b45418SCorentin Labbe 			break;
313d9b45418SCorentin Labbe 
314d9b45418SCorentin Labbe 		mutex_lock(&ss->mlock);
315d9b45418SCorentin Labbe 		if (i > 0) {
316d9b45418SCorentin Labbe 			v |= BIT(17);
317d9b45418SCorentin Labbe 			writel(rctx->t_dst[i - 1].addr, ss->base + SS_KEY_ADR_REG);
318d9b45418SCorentin Labbe 			writel(rctx->t_dst[i - 1].addr, ss->base + SS_IV_ADR_REG);
319d9b45418SCorentin Labbe 		}
320d9b45418SCorentin Labbe 
321d9b45418SCorentin Labbe 		dev_dbg(ss->dev,
322d9b45418SCorentin Labbe 			"Processing SG %d on flow %d %s ctl=%x %d to %d method=%x src=%x dst=%x\n",
323d9b45418SCorentin Labbe 			i, flow, name, v,
324d9b45418SCorentin Labbe 			rctx->t_src[i].len, rctx->t_dst[i].len,
325d9b45418SCorentin Labbe 			rctx->method, rctx->t_src[i].addr, rctx->t_dst[i].addr);
326d9b45418SCorentin Labbe 
327d9b45418SCorentin Labbe 		writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG);
328d9b45418SCorentin Labbe 		writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG);
329d9b45418SCorentin Labbe 		writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG);
330d9b45418SCorentin Labbe 		writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG);
331d9b45418SCorentin Labbe 
332d9b45418SCorentin Labbe 		reinit_completion(&ss->flows[flow].complete);
333d9b45418SCorentin Labbe 		ss->flows[flow].status = 0;
334d9b45418SCorentin Labbe 		wmb();
335d9b45418SCorentin Labbe 
336d9b45418SCorentin Labbe 		writel(v, ss->base + SS_CTL_REG);
337d9b45418SCorentin Labbe 		mutex_unlock(&ss->mlock);
338d9b45418SCorentin Labbe 		wait_for_completion_interruptible_timeout(&ss->flows[flow].complete,
339d9b45418SCorentin Labbe 							  msecs_to_jiffies(2000));
340d9b45418SCorentin Labbe 		if (ss->flows[flow].status == 0) {
341d9b45418SCorentin Labbe 			dev_err(ss->dev, "DMA timeout for %s\n", name);
342d9b45418SCorentin Labbe 			return -EFAULT;
343d9b45418SCorentin Labbe 		}
344d9b45418SCorentin Labbe 	}
345d9b45418SCorentin Labbe 
346d9b45418SCorentin Labbe 	return 0;
347d9b45418SCorentin Labbe }
348d9b45418SCorentin Labbe 
349d9b45418SCorentin Labbe static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
350d9b45418SCorentin Labbe {
351f95f61d0SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
352f95f61d0SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
353f95f61d0SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
354d9b45418SCorentin Labbe 	struct scatterlist *sg;
355d9b45418SCorentin Labbe 
356f95f61d0SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
357f95f61d0SCorentin Labbe 
358f95f61d0SCorentin Labbe 	if (areq->nbytes == 0) {
359f95f61d0SCorentin Labbe 		algt->stat_fb_len++;
360d9b45418SCorentin Labbe 		return true;
361f95f61d0SCorentin Labbe 	}
362f95f61d0SCorentin Labbe 
363f95f61d0SCorentin Labbe 	if (areq->nbytes >= MAX_PAD_SIZE - 64) {
364f95f61d0SCorentin Labbe 		algt->stat_fb_len++;
365c35e523aSCorentin Labbe 		return true;
366f95f61d0SCorentin Labbe 	}
367c35e523aSCorentin Labbe 
368d9b45418SCorentin Labbe 	/* we need to reserve one SG for the padding one */
369f95f61d0SCorentin Labbe 	if (sg_nents(areq->src) > MAX_SG - 1) {
370f95f61d0SCorentin Labbe 		algt->stat_fb_sgnum++;
371d9b45418SCorentin Labbe 		return true;
372f95f61d0SCorentin Labbe 	}
373f95f61d0SCorentin Labbe 
374d9b45418SCorentin Labbe 	sg = areq->src;
375d9b45418SCorentin Labbe 	while (sg) {
376d9b45418SCorentin Labbe 		/* SS can operate hash only on full block size
377d9b45418SCorentin Labbe 		 * since SS support only MD5,sha1,sha224 and sha256, blocksize
378d9b45418SCorentin Labbe 		 * is always 64
379d9b45418SCorentin Labbe 		 */
380c35e523aSCorentin Labbe 		/* Only the last block could be bounced to the pad buffer */
381f95f61d0SCorentin Labbe 		if (sg->length % 64 && sg_next(sg)) {
382f95f61d0SCorentin Labbe 			algt->stat_fb_sglen++;
383c35e523aSCorentin Labbe 			return true;
384f95f61d0SCorentin Labbe 		}
385f95f61d0SCorentin Labbe 		if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
386f95f61d0SCorentin Labbe 			algt->stat_fb_align++;
387c35e523aSCorentin Labbe 			return true;
388f95f61d0SCorentin Labbe 		}
389f95f61d0SCorentin Labbe 		if (sg->length % 4) {
390f95f61d0SCorentin Labbe 			algt->stat_fb_sglen++;
391d9b45418SCorentin Labbe 			return true;
392f95f61d0SCorentin Labbe 		}
393d9b45418SCorentin Labbe 		sg = sg_next(sg);
394d9b45418SCorentin Labbe 	}
395d9b45418SCorentin Labbe 	return false;
396d9b45418SCorentin Labbe }
397d9b45418SCorentin Labbe 
398d9b45418SCorentin Labbe int sun8i_ss_hash_digest(struct ahash_request *areq)
399d9b45418SCorentin Labbe {
400d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
401d9b45418SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
402d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
403d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
404d9b45418SCorentin Labbe 	struct sun8i_ss_dev *ss;
405d9b45418SCorentin Labbe 	struct crypto_engine *engine;
40646e2fcbcSCorentin Labbe 	int e;
407d9b45418SCorentin Labbe 
408d9b45418SCorentin Labbe 	if (sun8i_ss_hash_need_fallback(areq))
409d9b45418SCorentin Labbe 		return sun8i_ss_hash_digest_fb(areq);
410d9b45418SCorentin Labbe 
411d9b45418SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
412d9b45418SCorentin Labbe 	ss = algt->ss;
413d9b45418SCorentin Labbe 
414d9b45418SCorentin Labbe 	e = sun8i_ss_get_engine_number(ss);
415d9b45418SCorentin Labbe 	rctx->flow = e;
416d9b45418SCorentin Labbe 	engine = ss->flows[e].engine;
417d9b45418SCorentin Labbe 
418d9b45418SCorentin Labbe 	return crypto_transfer_hash_request_to_engine(engine, areq);
419d9b45418SCorentin Labbe }
420d9b45418SCorentin Labbe 
421e76ee4dbSCorentin Labbe static u64 hash_pad(__le32 *buf, unsigned int bufsize, u64 padi, u64 byte_count, bool le, int bs)
422e76ee4dbSCorentin Labbe {
423e76ee4dbSCorentin Labbe 	u64 fill, min_fill, j, k;
424e76ee4dbSCorentin Labbe 	__be64 *bebits;
425e76ee4dbSCorentin Labbe 	__le64 *lebits;
426e76ee4dbSCorentin Labbe 
427e76ee4dbSCorentin Labbe 	j = padi;
428e76ee4dbSCorentin Labbe 	buf[j++] = cpu_to_le32(0x80);
429e76ee4dbSCorentin Labbe 
430e76ee4dbSCorentin Labbe 	if (bs == 64) {
431e76ee4dbSCorentin Labbe 		fill = 64 - (byte_count % 64);
432e76ee4dbSCorentin Labbe 		min_fill = 2 * sizeof(u32) + sizeof(u32);
433e76ee4dbSCorentin Labbe 	} else {
434e76ee4dbSCorentin Labbe 		fill = 128 - (byte_count % 128);
435e76ee4dbSCorentin Labbe 		min_fill = 4 * sizeof(u32) + sizeof(u32);
436e76ee4dbSCorentin Labbe 	}
437e76ee4dbSCorentin Labbe 
438e76ee4dbSCorentin Labbe 	if (fill < min_fill)
439e76ee4dbSCorentin Labbe 		fill += bs;
440e76ee4dbSCorentin Labbe 
441e76ee4dbSCorentin Labbe 	k = j;
442e76ee4dbSCorentin Labbe 	j += (fill - min_fill) / sizeof(u32);
443e76ee4dbSCorentin Labbe 	if (j * 4 > bufsize) {
444e76ee4dbSCorentin Labbe 		pr_err("%s OVERFLOW %llu\n", __func__, j);
445e76ee4dbSCorentin Labbe 		return 0;
446e76ee4dbSCorentin Labbe 	}
447e76ee4dbSCorentin Labbe 	for (; k < j; k++)
448e76ee4dbSCorentin Labbe 		buf[k] = 0;
449e76ee4dbSCorentin Labbe 
450e76ee4dbSCorentin Labbe 	if (le) {
451e76ee4dbSCorentin Labbe 		/* MD5 */
452e76ee4dbSCorentin Labbe 		lebits = (__le64 *)&buf[j];
453e76ee4dbSCorentin Labbe 		*lebits = cpu_to_le64(byte_count << 3);
454e76ee4dbSCorentin Labbe 		j += 2;
455e76ee4dbSCorentin Labbe 	} else {
456e76ee4dbSCorentin Labbe 		if (bs == 64) {
457e76ee4dbSCorentin Labbe 			/* sha1 sha224 sha256 */
458e76ee4dbSCorentin Labbe 			bebits = (__be64 *)&buf[j];
459e76ee4dbSCorentin Labbe 			*bebits = cpu_to_be64(byte_count << 3);
460e76ee4dbSCorentin Labbe 			j += 2;
461e76ee4dbSCorentin Labbe 		} else {
462e76ee4dbSCorentin Labbe 			/* sha384 sha512*/
463e76ee4dbSCorentin Labbe 			bebits = (__be64 *)&buf[j];
464e76ee4dbSCorentin Labbe 			*bebits = cpu_to_be64(byte_count >> 61);
465e76ee4dbSCorentin Labbe 			j += 2;
466e76ee4dbSCorentin Labbe 			bebits = (__be64 *)&buf[j];
467e76ee4dbSCorentin Labbe 			*bebits = cpu_to_be64(byte_count << 3);
468e76ee4dbSCorentin Labbe 			j += 2;
469e76ee4dbSCorentin Labbe 		}
470e76ee4dbSCorentin Labbe 	}
471e76ee4dbSCorentin Labbe 	if (j * 4 > bufsize) {
472e76ee4dbSCorentin Labbe 		pr_err("%s OVERFLOW %llu\n", __func__, j);
473e76ee4dbSCorentin Labbe 		return 0;
474e76ee4dbSCorentin Labbe 	}
475e76ee4dbSCorentin Labbe 
476e76ee4dbSCorentin Labbe 	return j;
477e76ee4dbSCorentin Labbe }
478e76ee4dbSCorentin Labbe 
479d9b45418SCorentin Labbe /* sun8i_ss_hash_run - run an ahash request
480d9b45418SCorentin Labbe  * Send the data of the request to the SS along with an extra SG with padding
481d9b45418SCorentin Labbe  */
482d9b45418SCorentin Labbe int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
483d9b45418SCorentin Labbe {
484d9b45418SCorentin Labbe 	struct ahash_request *areq = container_of(breq, struct ahash_request, base);
485d9b45418SCorentin Labbe 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
486801b7d57SCorentin Labbe 	struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
487d9b45418SCorentin Labbe 	struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
488d9b45418SCorentin Labbe 	struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
489d9b45418SCorentin Labbe 	struct sun8i_ss_alg_template *algt;
490d9b45418SCorentin Labbe 	struct sun8i_ss_dev *ss;
491d9b45418SCorentin Labbe 	struct scatterlist *sg;
492801b7d57SCorentin Labbe 	int bs = crypto_ahash_blocksize(tfm);
493d9b45418SCorentin Labbe 	int nr_sgs, err, digestsize;
494d9b45418SCorentin Labbe 	unsigned int len;
495e76ee4dbSCorentin Labbe 	u64 byte_count;
496d9b45418SCorentin Labbe 	void *pad, *result;
497db0c62bcSCorentin Labbe 	int j, i, k, todo;
498801b7d57SCorentin Labbe 	dma_addr_t addr_res, addr_pad, addr_xpad;
499d9b45418SCorentin Labbe 	__le32 *bf;
500801b7d57SCorentin Labbe 	/* HMAC step:
501801b7d57SCorentin Labbe 	 * 0: normal hashing
502801b7d57SCorentin Labbe 	 * 1: IPAD
503801b7d57SCorentin Labbe 	 * 2: OPAD
504801b7d57SCorentin Labbe 	 */
505801b7d57SCorentin Labbe 	int hmac = 0;
506d9b45418SCorentin Labbe 
507d9b45418SCorentin Labbe 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
508d9b45418SCorentin Labbe 	ss = algt->ss;
509d9b45418SCorentin Labbe 
510d9b45418SCorentin Labbe 	digestsize = algt->alg.hash.halg.digestsize;
511d9b45418SCorentin Labbe 	if (digestsize == SHA224_DIGEST_SIZE)
512d9b45418SCorentin Labbe 		digestsize = SHA256_DIGEST_SIZE;
513d9b45418SCorentin Labbe 
5148eec4563SCorentin Labbe 	result = ss->flows[rctx->flow].result;
5158eec4563SCorentin Labbe 	pad = ss->flows[rctx->flow].pad;
516d9b45418SCorentin Labbe 	bf = (__le32 *)pad;
517d9b45418SCorentin Labbe 
518d9b45418SCorentin Labbe 	for (i = 0; i < MAX_SG; i++) {
519d9b45418SCorentin Labbe 		rctx->t_dst[i].addr = 0;
520d9b45418SCorentin Labbe 		rctx->t_dst[i].len = 0;
521d9b45418SCorentin Labbe 	}
522d9b45418SCorentin Labbe 
523d9b45418SCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
524d9b45418SCorentin Labbe 	algt->stat_req++;
525d9b45418SCorentin Labbe #endif
526d9b45418SCorentin Labbe 
527d9b45418SCorentin Labbe 	rctx->method = ss->variant->alg_hash[algt->ss_algo_id];
528d9b45418SCorentin Labbe 
529d9b45418SCorentin Labbe 	nr_sgs = dma_map_sg(ss->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
530d9b45418SCorentin Labbe 	if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
531d9b45418SCorentin Labbe 		dev_err(ss->dev, "Invalid sg number %d\n", nr_sgs);
532d9b45418SCorentin Labbe 		err = -EINVAL;
533d9b45418SCorentin Labbe 		goto theend;
534d9b45418SCorentin Labbe 	}
535d9b45418SCorentin Labbe 
536d9b45418SCorentin Labbe 	addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
537d9b45418SCorentin Labbe 	if (dma_mapping_error(ss->dev, addr_res)) {
538d9b45418SCorentin Labbe 		dev_err(ss->dev, "DMA map dest\n");
539d9b45418SCorentin Labbe 		err = -EINVAL;
540801b7d57SCorentin Labbe 		goto err_dma_result;
541d9b45418SCorentin Labbe 	}
542d9b45418SCorentin Labbe 
543c35e523aSCorentin Labbe 	j = 0;
544d9b45418SCorentin Labbe 	len = areq->nbytes;
545c149e476SCorentin Labbe 	sg = areq->src;
546c149e476SCorentin Labbe 	i = 0;
547c149e476SCorentin Labbe 	while (len > 0 && sg) {
548c149e476SCorentin Labbe 		if (sg_dma_len(sg) == 0) {
549c149e476SCorentin Labbe 			sg = sg_next(sg);
550c149e476SCorentin Labbe 			continue;
551c149e476SCorentin Labbe 		}
552d9b45418SCorentin Labbe 		todo = min(len, sg_dma_len(sg));
553c35e523aSCorentin Labbe 		/* only the last SG could be with a size not modulo64 */
554c35e523aSCorentin Labbe 		if (todo % 64 == 0) {
555c35e523aSCorentin Labbe 			rctx->t_src[i].addr = sg_dma_address(sg);
556d9b45418SCorentin Labbe 			rctx->t_src[i].len = todo / 4;
557d9b45418SCorentin Labbe 			rctx->t_dst[i].addr = addr_res;
558d9b45418SCorentin Labbe 			rctx->t_dst[i].len = digestsize / 4;
559c35e523aSCorentin Labbe 			len -= todo;
560c35e523aSCorentin Labbe 		} else {
561c35e523aSCorentin Labbe 			scatterwalk_map_and_copy(bf, sg, 0, todo, 0);
562c35e523aSCorentin Labbe 			j += todo / 4;
563c35e523aSCorentin Labbe 			len -= todo;
564c35e523aSCorentin Labbe 		}
565c149e476SCorentin Labbe 		sg = sg_next(sg);
566c149e476SCorentin Labbe 		i++;
567d9b45418SCorentin Labbe 	}
568d9b45418SCorentin Labbe 	if (len > 0) {
569d9b45418SCorentin Labbe 		dev_err(ss->dev, "remaining len %d\n", len);
570d9b45418SCorentin Labbe 		err = -EINVAL;
571d9b45418SCorentin Labbe 		goto theend;
572d9b45418SCorentin Labbe 	}
573d9b45418SCorentin Labbe 
574c35e523aSCorentin Labbe 	if (j > 0)
575c35e523aSCorentin Labbe 		i--;
576c35e523aSCorentin Labbe 
577801b7d57SCorentin Labbe retry:
578d9b45418SCorentin Labbe 	byte_count = areq->nbytes;
579801b7d57SCorentin Labbe 	if (tfmctx->keylen && hmac == 0) {
580801b7d57SCorentin Labbe 		hmac = 1;
581801b7d57SCorentin Labbe 		/* shift all SG one slot up, to free slot 0 for IPAD */
582801b7d57SCorentin Labbe 		for (k = 6; k >= 0; k--) {
583801b7d57SCorentin Labbe 			rctx->t_src[k + 1].addr = rctx->t_src[k].addr;
584801b7d57SCorentin Labbe 			rctx->t_src[k + 1].len = rctx->t_src[k].len;
585801b7d57SCorentin Labbe 			rctx->t_dst[k + 1].addr = rctx->t_dst[k].addr;
586801b7d57SCorentin Labbe 			rctx->t_dst[k + 1].len = rctx->t_dst[k].len;
587801b7d57SCorentin Labbe 		}
588801b7d57SCorentin Labbe 		addr_xpad = dma_map_single(ss->dev, tfmctx->ipad, bs, DMA_TO_DEVICE);
5896cb3f9b2SDan Carpenter 		err = dma_mapping_error(ss->dev, addr_xpad);
5906cb3f9b2SDan Carpenter 		if (err) {
591801b7d57SCorentin Labbe 			dev_err(ss->dev, "Fail to create DMA mapping of ipad\n");
592801b7d57SCorentin Labbe 			goto err_dma_xpad;
593801b7d57SCorentin Labbe 		}
594801b7d57SCorentin Labbe 		rctx->t_src[0].addr = addr_xpad;
595801b7d57SCorentin Labbe 		rctx->t_src[0].len = bs / 4;
596801b7d57SCorentin Labbe 		rctx->t_dst[0].addr = addr_res;
597801b7d57SCorentin Labbe 		rctx->t_dst[0].len = digestsize / 4;
598801b7d57SCorentin Labbe 		i++;
599801b7d57SCorentin Labbe 		byte_count = areq->nbytes + bs;
600801b7d57SCorentin Labbe 	}
601801b7d57SCorentin Labbe 	if (tfmctx->keylen && hmac == 2) {
602801b7d57SCorentin Labbe 		for (i = 0; i < MAX_SG; i++) {
603801b7d57SCorentin Labbe 			rctx->t_src[i].addr = 0;
604801b7d57SCorentin Labbe 			rctx->t_src[i].len = 0;
605801b7d57SCorentin Labbe 			rctx->t_dst[i].addr = 0;
606801b7d57SCorentin Labbe 			rctx->t_dst[i].len = 0;
607801b7d57SCorentin Labbe 		}
608801b7d57SCorentin Labbe 
609801b7d57SCorentin Labbe 		addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
610801b7d57SCorentin Labbe 		if (dma_mapping_error(ss->dev, addr_res)) {
611801b7d57SCorentin Labbe 			dev_err(ss->dev, "Fail to create DMA mapping of result\n");
612801b7d57SCorentin Labbe 			err = -EINVAL;
613801b7d57SCorentin Labbe 			goto err_dma_result;
614801b7d57SCorentin Labbe 		}
615801b7d57SCorentin Labbe 		addr_xpad = dma_map_single(ss->dev, tfmctx->opad, bs, DMA_TO_DEVICE);
6166cb3f9b2SDan Carpenter 		err = dma_mapping_error(ss->dev, addr_xpad);
6176cb3f9b2SDan Carpenter 		if (err) {
618801b7d57SCorentin Labbe 			dev_err(ss->dev, "Fail to create DMA mapping of opad\n");
619801b7d57SCorentin Labbe 			goto err_dma_xpad;
620801b7d57SCorentin Labbe 		}
621801b7d57SCorentin Labbe 		rctx->t_src[0].addr = addr_xpad;
622801b7d57SCorentin Labbe 		rctx->t_src[0].len = bs / 4;
623801b7d57SCorentin Labbe 
624801b7d57SCorentin Labbe 		memcpy(bf, result, digestsize);
625801b7d57SCorentin Labbe 		j = digestsize / 4;
626801b7d57SCorentin Labbe 		i = 1;
627801b7d57SCorentin Labbe 		byte_count = digestsize + bs;
628801b7d57SCorentin Labbe 
629801b7d57SCorentin Labbe 		rctx->t_dst[0].addr = addr_res;
630801b7d57SCorentin Labbe 		rctx->t_dst[0].len = digestsize / 4;
631801b7d57SCorentin Labbe 	}
632801b7d57SCorentin Labbe 
633d9b45418SCorentin Labbe 	switch (algt->ss_algo_id) {
634d9b45418SCorentin Labbe 	case SS_ID_HASH_MD5:
635e76ee4dbSCorentin Labbe 		j = hash_pad(bf, 4096, j, byte_count, true, bs);
636d9b45418SCorentin Labbe 		break;
637d9b45418SCorentin Labbe 	case SS_ID_HASH_SHA1:
638d9b45418SCorentin Labbe 	case SS_ID_HASH_SHA224:
639d9b45418SCorentin Labbe 	case SS_ID_HASH_SHA256:
640e76ee4dbSCorentin Labbe 		j = hash_pad(bf, 4096, j, byte_count, false, bs);
641d9b45418SCorentin Labbe 		break;
642d9b45418SCorentin Labbe 	}
643e76ee4dbSCorentin Labbe 	if (!j) {
644e76ee4dbSCorentin Labbe 		err = -EINVAL;
645e76ee4dbSCorentin Labbe 		goto theend;
646e76ee4dbSCorentin Labbe 	}
647d9b45418SCorentin Labbe 
648d9b45418SCorentin Labbe 	addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE);
649d9b45418SCorentin Labbe 	if (dma_mapping_error(ss->dev, addr_pad)) {
650d9b45418SCorentin Labbe 		dev_err(ss->dev, "DMA error on padding SG\n");
651d9b45418SCorentin Labbe 		err = -EINVAL;
652801b7d57SCorentin Labbe 		goto err_dma_pad;
653d9b45418SCorentin Labbe 	}
654d86e3f37SCorentin Labbe 	rctx->t_src[i].addr = addr_pad;
655d86e3f37SCorentin Labbe 	rctx->t_src[i].len = j;
656d86e3f37SCorentin Labbe 	rctx->t_dst[i].addr = addr_res;
657d86e3f37SCorentin Labbe 	rctx->t_dst[i].len = digestsize / 4;
658d9b45418SCorentin Labbe 
659d9b45418SCorentin Labbe 	err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
660d9b45418SCorentin Labbe 
661801b7d57SCorentin Labbe 	/*
662801b7d57SCorentin Labbe 	 * mini helper for checking dma map/unmap
663801b7d57SCorentin Labbe 	 * flow start for hmac = 0 (and HMAC = 1)
664801b7d57SCorentin Labbe 	 * HMAC = 0
665801b7d57SCorentin Labbe 	 * MAP src
666801b7d57SCorentin Labbe 	 * MAP res
667801b7d57SCorentin Labbe 	 *
668801b7d57SCorentin Labbe 	 * retry:
669801b7d57SCorentin Labbe 	 * if hmac then hmac = 1
670801b7d57SCorentin Labbe 	 *	MAP xpad (ipad)
671801b7d57SCorentin Labbe 	 * if hmac == 2
672801b7d57SCorentin Labbe 	 *	MAP res
673801b7d57SCorentin Labbe 	 *	MAP xpad (opad)
674801b7d57SCorentin Labbe 	 * MAP pad
675801b7d57SCorentin Labbe 	 * ACTION!
676801b7d57SCorentin Labbe 	 * UNMAP pad
677801b7d57SCorentin Labbe 	 * if hmac
678801b7d57SCorentin Labbe 	 *	UNMAP xpad
679801b7d57SCorentin Labbe 	 * UNMAP res
680801b7d57SCorentin Labbe 	 * if hmac < 2
681801b7d57SCorentin Labbe 	 *	UNMAP SRC
682801b7d57SCorentin Labbe 	 *
683801b7d57SCorentin Labbe 	 * if hmac = 1 then hmac = 2 goto retry
684801b7d57SCorentin Labbe 	 */
685801b7d57SCorentin Labbe 
686d9b45418SCorentin Labbe 	dma_unmap_single(ss->dev, addr_pad, j * 4, DMA_TO_DEVICE);
687801b7d57SCorentin Labbe 
688801b7d57SCorentin Labbe err_dma_pad:
689801b7d57SCorentin Labbe 	if (hmac > 0)
690801b7d57SCorentin Labbe 		dma_unmap_single(ss->dev, addr_xpad, bs, DMA_TO_DEVICE);
691801b7d57SCorentin Labbe err_dma_xpad:
692801b7d57SCorentin Labbe 	dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE);
693801b7d57SCorentin Labbe err_dma_result:
694801b7d57SCorentin Labbe 	if (hmac < 2)
695884b93c5SXiang Chen 		dma_unmap_sg(ss->dev, areq->src, sg_nents(areq->src),
696884b93c5SXiang Chen 			     DMA_TO_DEVICE);
697801b7d57SCorentin Labbe 	if (hmac == 1 && !err) {
698801b7d57SCorentin Labbe 		hmac = 2;
699801b7d57SCorentin Labbe 		goto retry;
700801b7d57SCorentin Labbe 	}
701d9b45418SCorentin Labbe 
702801b7d57SCorentin Labbe 	if (!err)
703d9b45418SCorentin Labbe 		memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
704d9b45418SCorentin Labbe theend:
705b169b376SCorentin Labbe 	local_bh_disable();
706d9b45418SCorentin Labbe 	crypto_finalize_hash_request(engine, breq, err);
707b169b376SCorentin Labbe 	local_bh_enable();
708d9b45418SCorentin Labbe 	return 0;
709d9b45418SCorentin Labbe }
710