1 // SPDX-License-Identifier: GPL-2.0
3 * sun8i-ss-hash.c - hardware cryptographic offloader for
4 * Allwinner A80/A83T SoC
6 * Copyright (C) 2015-2020 Corentin Labbe <clabbe@baylibre.com>
8 * This file add support for MD5 and SHA1/SHA224/SHA256.
10 * You could find the datasheet in Documentation/arch/arm/sunxi.rst
12 #include <linux/bottom_half.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/scatterlist.h>
16 #include <crypto/internal/hash.h>
17 #include <crypto/hmac.h>
18 #include <crypto/scatterwalk.h>
19 #include <crypto/sha1.h>
20 #include <crypto/sha2.h>
21 #include <crypto/md5.h>
24 static int sun8i_ss_hashkey(struct sun8i_ss_hash_tfm_ctx *tfmctx, const u8 *key,
27 struct crypto_shash *xtfm;
28 struct shash_desc *sdesc;
32 xtfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_NEED_FALLBACK);
36 len = sizeof(*sdesc) + crypto_shash_descsize(xtfm);
37 sdesc = kmalloc(len, GFP_KERNEL);
40 goto err_hashkey_sdesc;
44 ret = crypto_shash_init(sdesc);
46 dev_err(tfmctx->ss->dev, "shash init error ret=%d\n", ret);
49 ret = crypto_shash_finup(sdesc, key, keylen, tfmctx->key);
51 dev_err(tfmctx->ss->dev, "shash finup error\n");
55 crypto_free_shash(xtfm);
59 int sun8i_ss_hmac_setkey(struct crypto_ahash *ahash, const u8 *key,
62 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(ahash);
63 struct ahash_alg *alg = __crypto_ahash_alg(ahash->base.__crt_alg);
64 struct sun8i_ss_alg_template *algt;
66 int bs = crypto_ahash_blocksize(ahash);
69 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
70 digestsize = algt->alg.hash.halg.digestsize;
73 ret = sun8i_ss_hashkey(tfmctx, key, keylen);
76 tfmctx->keylen = digestsize;
78 tfmctx->keylen = keylen;
79 memcpy(tfmctx->key, key, keylen);
82 tfmctx->ipad = kzalloc(bs, GFP_KERNEL);
85 tfmctx->opad = kzalloc(bs, GFP_KERNEL);
91 memset(tfmctx->key + tfmctx->keylen, 0, bs - tfmctx->keylen);
92 memcpy(tfmctx->ipad, tfmctx->key, tfmctx->keylen);
93 memcpy(tfmctx->opad, tfmctx->key, tfmctx->keylen);
94 for (i = 0; i < bs; i++) {
95 tfmctx->ipad[i] ^= HMAC_IPAD_VALUE;
96 tfmctx->opad[i] ^= HMAC_OPAD_VALUE;
99 ret = crypto_ahash_setkey(tfmctx->fallback_tfm, key, keylen);
103 memzero_explicit(tfmctx->key, keylen);
104 kfree_sensitive(tfmctx->opad);
106 kfree_sensitive(tfmctx->ipad);
110 int sun8i_ss_hash_crainit(struct crypto_tfm *tfm)
112 struct sun8i_ss_hash_tfm_ctx *op = crypto_tfm_ctx(tfm);
113 struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
114 struct sun8i_ss_alg_template *algt;
117 memset(op, 0, sizeof(struct sun8i_ss_hash_tfm_ctx));
119 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
122 op->enginectx.op.do_one_request = sun8i_ss_hash_run;
125 op->fallback_tfm = crypto_alloc_ahash(crypto_tfm_alg_name(tfm), 0,
126 CRYPTO_ALG_NEED_FALLBACK);
127 if (IS_ERR(op->fallback_tfm)) {
128 dev_err(algt->ss->dev, "Fallback driver could no be loaded\n");
129 return PTR_ERR(op->fallback_tfm);
132 if (algt->alg.hash.halg.statesize < crypto_ahash_statesize(op->fallback_tfm))
133 algt->alg.hash.halg.statesize = crypto_ahash_statesize(op->fallback_tfm);
135 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
136 sizeof(struct sun8i_ss_hash_reqctx) +
137 crypto_ahash_reqsize(op->fallback_tfm));
139 memcpy(algt->fbname, crypto_tfm_alg_driver_name(&op->fallback_tfm->base), CRYPTO_MAX_ALG_NAME);
141 err = pm_runtime_get_sync(op->ss->dev);
146 pm_runtime_put_noidle(op->ss->dev);
147 crypto_free_ahash(op->fallback_tfm);
151 void sun8i_ss_hash_craexit(struct crypto_tfm *tfm)
153 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_tfm_ctx(tfm);
155 kfree_sensitive(tfmctx->ipad);
156 kfree_sensitive(tfmctx->opad);
158 crypto_free_ahash(tfmctx->fallback_tfm);
159 pm_runtime_put_sync_suspend(tfmctx->ss->dev);
162 int sun8i_ss_hash_init(struct ahash_request *areq)
164 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
165 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
166 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
168 memset(rctx, 0, sizeof(struct sun8i_ss_hash_reqctx));
170 ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
171 rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
173 return crypto_ahash_init(&rctx->fallback_req);
176 int sun8i_ss_hash_export(struct ahash_request *areq, void *out)
178 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
179 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
180 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
182 ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
183 rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
185 return crypto_ahash_export(&rctx->fallback_req, out);
188 int sun8i_ss_hash_import(struct ahash_request *areq, const void *in)
190 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
191 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
192 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
194 ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
195 rctx->fallback_req.base.flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP;
197 return crypto_ahash_import(&rctx->fallback_req, in);
200 int sun8i_ss_hash_final(struct ahash_request *areq)
202 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
203 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
204 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
205 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
206 struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
207 struct sun8i_ss_alg_template *algt;
210 ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
211 rctx->fallback_req.base.flags = areq->base.flags &
212 CRYPTO_TFM_REQ_MAY_SLEEP;
213 rctx->fallback_req.result = areq->result;
215 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
216 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
220 return crypto_ahash_final(&rctx->fallback_req);
223 int sun8i_ss_hash_update(struct ahash_request *areq)
225 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
226 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
227 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
229 ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
230 rctx->fallback_req.base.flags = areq->base.flags &
231 CRYPTO_TFM_REQ_MAY_SLEEP;
232 rctx->fallback_req.nbytes = areq->nbytes;
233 rctx->fallback_req.src = areq->src;
235 return crypto_ahash_update(&rctx->fallback_req);
238 int sun8i_ss_hash_finup(struct ahash_request *areq)
240 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
241 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
242 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
243 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
244 struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
245 struct sun8i_ss_alg_template *algt;
248 ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
249 rctx->fallback_req.base.flags = areq->base.flags &
250 CRYPTO_TFM_REQ_MAY_SLEEP;
252 rctx->fallback_req.nbytes = areq->nbytes;
253 rctx->fallback_req.src = areq->src;
254 rctx->fallback_req.result = areq->result;
255 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
256 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
260 return crypto_ahash_finup(&rctx->fallback_req);
263 static int sun8i_ss_hash_digest_fb(struct ahash_request *areq)
265 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
266 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
267 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
268 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
269 struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
270 struct sun8i_ss_alg_template *algt;
273 ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
274 rctx->fallback_req.base.flags = areq->base.flags &
275 CRYPTO_TFM_REQ_MAY_SLEEP;
277 rctx->fallback_req.nbytes = areq->nbytes;
278 rctx->fallback_req.src = areq->src;
279 rctx->fallback_req.result = areq->result;
280 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
281 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
285 return crypto_ahash_digest(&rctx->fallback_req);
288 static int sun8i_ss_run_hash_task(struct sun8i_ss_dev *ss,
289 struct sun8i_ss_hash_reqctx *rctx,
292 int flow = rctx->flow;
296 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
297 ss->flows[flow].stat_req++;
300 /* choose between stream0/stream1 */
308 for (i = 0; i < MAX_SG; i++) {
309 if (!rctx->t_dst[i].addr)
312 mutex_lock(&ss->mlock);
315 writel(rctx->t_dst[i - 1].addr, ss->base + SS_KEY_ADR_REG);
316 writel(rctx->t_dst[i - 1].addr, ss->base + SS_IV_ADR_REG);
320 "Processing SG %d on flow %d %s ctl=%x %d to %d method=%x src=%x dst=%x\n",
322 rctx->t_src[i].len, rctx->t_dst[i].len,
323 rctx->method, rctx->t_src[i].addr, rctx->t_dst[i].addr);
325 writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG);
326 writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG);
327 writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG);
328 writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG);
330 reinit_completion(&ss->flows[flow].complete);
331 ss->flows[flow].status = 0;
334 writel(v, ss->base + SS_CTL_REG);
335 mutex_unlock(&ss->mlock);
336 wait_for_completion_interruptible_timeout(&ss->flows[flow].complete,
337 msecs_to_jiffies(2000));
338 if (ss->flows[flow].status == 0) {
339 dev_err(ss->dev, "DMA timeout for %s\n", name);
347 static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
349 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
350 struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
351 struct sun8i_ss_alg_template *algt;
352 struct scatterlist *sg;
354 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
356 if (areq->nbytes == 0) {
361 if (areq->nbytes >= MAX_PAD_SIZE - 64) {
366 /* we need to reserve one SG for the padding one */
367 if (sg_nents(areq->src) > MAX_SG - 1) {
368 algt->stat_fb_sgnum++;
374 /* SS can operate hash only on full block size
375 * since SS support only MD5,sha1,sha224 and sha256, blocksize
378 /* Only the last block could be bounced to the pad buffer */
379 if (sg->length % 64 && sg_next(sg)) {
380 algt->stat_fb_sglen++;
383 if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
384 algt->stat_fb_align++;
387 if (sg->length % 4) {
388 algt->stat_fb_sglen++;
396 int sun8i_ss_hash_digest(struct ahash_request *areq)
398 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
399 struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
400 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
401 struct sun8i_ss_alg_template *algt;
402 struct sun8i_ss_dev *ss;
403 struct crypto_engine *engine;
406 if (sun8i_ss_hash_need_fallback(areq))
407 return sun8i_ss_hash_digest_fb(areq);
409 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
412 e = sun8i_ss_get_engine_number(ss);
414 engine = ss->flows[e].engine;
416 return crypto_transfer_hash_request_to_engine(engine, areq);
419 static u64 hash_pad(__le32 *buf, unsigned int bufsize, u64 padi, u64 byte_count, bool le, int bs)
421 u64 fill, min_fill, j, k;
426 buf[j++] = cpu_to_le32(0x80);
429 fill = 64 - (byte_count % 64);
430 min_fill = 2 * sizeof(u32) + sizeof(u32);
432 fill = 128 - (byte_count % 128);
433 min_fill = 4 * sizeof(u32) + sizeof(u32);
440 j += (fill - min_fill) / sizeof(u32);
441 if (j * 4 > bufsize) {
442 pr_err("%s OVERFLOW %llu\n", __func__, j);
450 lebits = (__le64 *)&buf[j];
451 *lebits = cpu_to_le64(byte_count << 3);
455 /* sha1 sha224 sha256 */
456 bebits = (__be64 *)&buf[j];
457 *bebits = cpu_to_be64(byte_count << 3);
461 bebits = (__be64 *)&buf[j];
462 *bebits = cpu_to_be64(byte_count >> 61);
464 bebits = (__be64 *)&buf[j];
465 *bebits = cpu_to_be64(byte_count << 3);
469 if (j * 4 > bufsize) {
470 pr_err("%s OVERFLOW %llu\n", __func__, j);
477 /* sun8i_ss_hash_run - run an ahash request
478 * Send the data of the request to the SS along with an extra SG with padding
480 int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
482 struct ahash_request *areq = container_of(breq, struct ahash_request, base);
483 struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
484 struct sun8i_ss_hash_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
485 struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
486 struct sun8i_ss_hash_reqctx *rctx = ahash_request_ctx(areq);
487 struct sun8i_ss_alg_template *algt;
488 struct sun8i_ss_dev *ss;
489 struct scatterlist *sg;
490 int bs = crypto_ahash_blocksize(tfm);
491 int nr_sgs, err, digestsize;
496 dma_addr_t addr_res, addr_pad, addr_xpad;
505 algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
508 digestsize = algt->alg.hash.halg.digestsize;
509 if (digestsize == SHA224_DIGEST_SIZE)
510 digestsize = SHA256_DIGEST_SIZE;
512 result = ss->flows[rctx->flow].result;
513 pad = ss->flows[rctx->flow].pad;
516 for (i = 0; i < MAX_SG; i++) {
517 rctx->t_dst[i].addr = 0;
518 rctx->t_dst[i].len = 0;
521 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
525 rctx->method = ss->variant->alg_hash[algt->ss_algo_id];
527 nr_sgs = dma_map_sg(ss->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
528 if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
529 dev_err(ss->dev, "Invalid sg number %d\n", nr_sgs);
534 addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
535 if (dma_mapping_error(ss->dev, addr_res)) {
536 dev_err(ss->dev, "DMA map dest\n");
545 while (len > 0 && sg) {
546 if (sg_dma_len(sg) == 0) {
550 todo = min(len, sg_dma_len(sg));
551 /* only the last SG could be with a size not modulo64 */
552 if (todo % 64 == 0) {
553 rctx->t_src[i].addr = sg_dma_address(sg);
554 rctx->t_src[i].len = todo / 4;
555 rctx->t_dst[i].addr = addr_res;
556 rctx->t_dst[i].len = digestsize / 4;
559 scatterwalk_map_and_copy(bf, sg, 0, todo, 0);
567 dev_err(ss->dev, "remaining len %d\n", len);
576 byte_count = areq->nbytes;
577 if (tfmctx->keylen && hmac == 0) {
579 /* shift all SG one slot up, to free slot 0 for IPAD */
580 for (k = 6; k >= 0; k--) {
581 rctx->t_src[k + 1].addr = rctx->t_src[k].addr;
582 rctx->t_src[k + 1].len = rctx->t_src[k].len;
583 rctx->t_dst[k + 1].addr = rctx->t_dst[k].addr;
584 rctx->t_dst[k + 1].len = rctx->t_dst[k].len;
586 addr_xpad = dma_map_single(ss->dev, tfmctx->ipad, bs, DMA_TO_DEVICE);
587 err = dma_mapping_error(ss->dev, addr_xpad);
589 dev_err(ss->dev, "Fail to create DMA mapping of ipad\n");
592 rctx->t_src[0].addr = addr_xpad;
593 rctx->t_src[0].len = bs / 4;
594 rctx->t_dst[0].addr = addr_res;
595 rctx->t_dst[0].len = digestsize / 4;
597 byte_count = areq->nbytes + bs;
599 if (tfmctx->keylen && hmac == 2) {
600 for (i = 0; i < MAX_SG; i++) {
601 rctx->t_src[i].addr = 0;
602 rctx->t_src[i].len = 0;
603 rctx->t_dst[i].addr = 0;
604 rctx->t_dst[i].len = 0;
607 addr_res = dma_map_single(ss->dev, result, digestsize, DMA_FROM_DEVICE);
608 if (dma_mapping_error(ss->dev, addr_res)) {
609 dev_err(ss->dev, "Fail to create DMA mapping of result\n");
613 addr_xpad = dma_map_single(ss->dev, tfmctx->opad, bs, DMA_TO_DEVICE);
614 err = dma_mapping_error(ss->dev, addr_xpad);
616 dev_err(ss->dev, "Fail to create DMA mapping of opad\n");
619 rctx->t_src[0].addr = addr_xpad;
620 rctx->t_src[0].len = bs / 4;
622 memcpy(bf, result, digestsize);
625 byte_count = digestsize + bs;
627 rctx->t_dst[0].addr = addr_res;
628 rctx->t_dst[0].len = digestsize / 4;
631 switch (algt->ss_algo_id) {
633 j = hash_pad(bf, 4096, j, byte_count, true, bs);
635 case SS_ID_HASH_SHA1:
636 case SS_ID_HASH_SHA224:
637 case SS_ID_HASH_SHA256:
638 j = hash_pad(bf, 4096, j, byte_count, false, bs);
646 addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE);
647 if (dma_mapping_error(ss->dev, addr_pad)) {
648 dev_err(ss->dev, "DMA error on padding SG\n");
652 rctx->t_src[i].addr = addr_pad;
653 rctx->t_src[i].len = j;
654 rctx->t_dst[i].addr = addr_res;
655 rctx->t_dst[i].len = digestsize / 4;
657 err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
660 * mini helper for checking dma map/unmap
661 * flow start for hmac = 0 (and HMAC = 1)
667 * if hmac then hmac = 1
681 * if hmac = 1 then hmac = 2 goto retry
684 dma_unmap_single(ss->dev, addr_pad, j * 4, DMA_TO_DEVICE);
688 dma_unmap_single(ss->dev, addr_xpad, bs, DMA_TO_DEVICE);
690 dma_unmap_single(ss->dev, addr_res, digestsize, DMA_FROM_DEVICE);
693 dma_unmap_sg(ss->dev, areq->src, sg_nents(areq->src),
695 if (hmac == 1 && !err) {
701 memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
704 crypto_finalize_hash_request(engine, breq, err);