175a6faf6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2bfd927ffSZain Wang /*
3bfd927ffSZain Wang * Crypto acceleration support for Rockchip RK3288
4bfd927ffSZain Wang *
5bfd927ffSZain Wang * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd
6bfd927ffSZain Wang *
7bfd927ffSZain Wang * Author: Zain Wang <zain.wang@rock-chips.com>
8bfd927ffSZain Wang *
9bfd927ffSZain Wang * Some ideas are from marvell/cesa.c and s5p-sss.c driver.
10bfd927ffSZain Wang */
111a15d26cSHerbert Xu
1257d67c6eSCorentin Labbe #include <asm/unaligned.h>
131a15d26cSHerbert Xu #include <crypto/internal/hash.h>
141a15d26cSHerbert Xu #include <linux/device.h>
151a15d26cSHerbert Xu #include <linux/err.h>
1637bc2215SCorentin Labbe #include <linux/iopoll.h>
171a15d26cSHerbert Xu #include <linux/kernel.h>
181a15d26cSHerbert Xu #include <linux/module.h>
191a15d26cSHerbert Xu #include <linux/string.h>
20bfd927ffSZain Wang #include "rk3288_crypto.h"
21bfd927ffSZain Wang
22bfd927ffSZain Wang /*
23bfd927ffSZain Wang * IC can not process zero message hash,
24bfd927ffSZain Wang * so we put the fixed hash out when met zero message.
25bfd927ffSZain Wang */
26bfd927ffSZain Wang
rk_ahash_need_fallback(struct ahash_request * req)2781660048SCorentin Labbe static bool rk_ahash_need_fallback(struct ahash_request *req)
2881660048SCorentin Labbe {
2981660048SCorentin Labbe struct scatterlist *sg;
3081660048SCorentin Labbe
3181660048SCorentin Labbe sg = req->src;
3281660048SCorentin Labbe while (sg) {
3381660048SCorentin Labbe if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
3481660048SCorentin Labbe return true;
3581660048SCorentin Labbe }
3681660048SCorentin Labbe if (sg->length % 4) {
3781660048SCorentin Labbe return true;
3881660048SCorentin Labbe }
3981660048SCorentin Labbe sg = sg_next(sg);
4081660048SCorentin Labbe }
4181660048SCorentin Labbe return false;
4281660048SCorentin Labbe }
4381660048SCorentin Labbe
rk_ahash_digest_fb(struct ahash_request * areq)4481660048SCorentin Labbe static int rk_ahash_digest_fb(struct ahash_request *areq)
4581660048SCorentin Labbe {
4681660048SCorentin Labbe struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
4781660048SCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
4881660048SCorentin Labbe struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm);
491a15d26cSHerbert Xu struct ahash_alg *alg = crypto_ahash_alg(tfm);
501a15d26cSHerbert Xu struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash.base);
5148d904d4SCorentin Labbe
5248d904d4SCorentin Labbe algt->stat_fb++;
5381660048SCorentin Labbe
5481660048SCorentin Labbe ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
5581660048SCorentin Labbe rctx->fallback_req.base.flags = areq->base.flags &
5681660048SCorentin Labbe CRYPTO_TFM_REQ_MAY_SLEEP;
5781660048SCorentin Labbe
5881660048SCorentin Labbe rctx->fallback_req.nbytes = areq->nbytes;
5981660048SCorentin Labbe rctx->fallback_req.src = areq->src;
6081660048SCorentin Labbe rctx->fallback_req.result = areq->result;
6181660048SCorentin Labbe
6281660048SCorentin Labbe return crypto_ahash_digest(&rctx->fallback_req);
6381660048SCorentin Labbe }
6481660048SCorentin Labbe
zero_message_process(struct ahash_request * req)65bfd927ffSZain Wang static int zero_message_process(struct ahash_request *req)
66bfd927ffSZain Wang {
67bfd927ffSZain Wang struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
68bfd927ffSZain Wang int rk_digest_size = crypto_ahash_digestsize(tfm);
69bfd927ffSZain Wang
70bfd927ffSZain Wang switch (rk_digest_size) {
71bfd927ffSZain Wang case SHA1_DIGEST_SIZE:
72bfd927ffSZain Wang memcpy(req->result, sha1_zero_message_hash, rk_digest_size);
73bfd927ffSZain Wang break;
74bfd927ffSZain Wang case SHA256_DIGEST_SIZE:
75bfd927ffSZain Wang memcpy(req->result, sha256_zero_message_hash, rk_digest_size);
76bfd927ffSZain Wang break;
77bfd927ffSZain Wang case MD5_DIGEST_SIZE:
78bfd927ffSZain Wang memcpy(req->result, md5_zero_message_hash, rk_digest_size);
79bfd927ffSZain Wang break;
80bfd927ffSZain Wang default:
81bfd927ffSZain Wang return -EINVAL;
82bfd927ffSZain Wang }
83bfd927ffSZain Wang
84bfd927ffSZain Wang return 0;
85bfd927ffSZain Wang }
86bfd927ffSZain Wang
rk_ahash_reg_init(struct ahash_request * req,struct rk_crypto_info * dev)870d31b14cSCorentin Labbe static void rk_ahash_reg_init(struct ahash_request *req,
880d31b14cSCorentin Labbe struct rk_crypto_info *dev)
89bfd927ffSZain Wang {
905a7801f6SZain Wang struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
913d8c5f5aSKai Ye int reg_status;
92bfd927ffSZain Wang
93bfd927ffSZain Wang reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) |
94bfd927ffSZain Wang RK_CRYPTO_HASH_FLUSH | _SBF(0xffff, 16);
95bfd927ffSZain Wang CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, reg_status);
96bfd927ffSZain Wang
97bfd927ffSZain Wang reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL);
98bfd927ffSZain Wang reg_status &= (~RK_CRYPTO_HASH_FLUSH);
99bfd927ffSZain Wang reg_status |= _SBF(0xffff, 16);
100bfd927ffSZain Wang CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, reg_status);
101bfd927ffSZain Wang
102bfd927ffSZain Wang memset_io(dev->reg + RK_CRYPTO_HASH_DOUT_0, 0, 32);
103bfd927ffSZain Wang
104bfd927ffSZain Wang CRYPTO_WRITE(dev, RK_CRYPTO_INTENA, RK_CRYPTO_HRDMA_ERR_ENA |
105bfd927ffSZain Wang RK_CRYPTO_HRDMA_DONE_ENA);
106bfd927ffSZain Wang
107bfd927ffSZain Wang CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, RK_CRYPTO_HRDMA_ERR_INT |
108bfd927ffSZain Wang RK_CRYPTO_HRDMA_DONE_INT);
109bfd927ffSZain Wang
1105a7801f6SZain Wang CRYPTO_WRITE(dev, RK_CRYPTO_HASH_CTRL, rctx->mode |
111bfd927ffSZain Wang RK_CRYPTO_HASH_SWAP_DO);
112bfd927ffSZain Wang
113bfd927ffSZain Wang CRYPTO_WRITE(dev, RK_CRYPTO_CONF, RK_CRYPTO_BYTESWAP_HRFIFO |
114bfd927ffSZain Wang RK_CRYPTO_BYTESWAP_BRFIFO |
115bfd927ffSZain Wang RK_CRYPTO_BYTESWAP_BTFIFO);
116bfd927ffSZain Wang
11757d67c6eSCorentin Labbe CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes);
118bfd927ffSZain Wang }
119bfd927ffSZain Wang
rk_ahash_init(struct ahash_request * req)120bfd927ffSZain Wang static int rk_ahash_init(struct ahash_request *req)
121bfd927ffSZain Wang {
122bfd927ffSZain Wang struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
123bfd927ffSZain Wang struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
124bfd927ffSZain Wang struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
125bfd927ffSZain Wang
126bfd927ffSZain Wang ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
127bfd927ffSZain Wang rctx->fallback_req.base.flags = req->base.flags &
128bfd927ffSZain Wang CRYPTO_TFM_REQ_MAY_SLEEP;
129bfd927ffSZain Wang
130bfd927ffSZain Wang return crypto_ahash_init(&rctx->fallback_req);
131bfd927ffSZain Wang }
132bfd927ffSZain Wang
rk_ahash_update(struct ahash_request * req)133bfd927ffSZain Wang static int rk_ahash_update(struct ahash_request *req)
134bfd927ffSZain Wang {
135bfd927ffSZain Wang struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
136bfd927ffSZain Wang struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
137bfd927ffSZain Wang struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
138bfd927ffSZain Wang
139bfd927ffSZain Wang ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
140bfd927ffSZain Wang rctx->fallback_req.base.flags = req->base.flags &
141bfd927ffSZain Wang CRYPTO_TFM_REQ_MAY_SLEEP;
142bfd927ffSZain Wang rctx->fallback_req.nbytes = req->nbytes;
143bfd927ffSZain Wang rctx->fallback_req.src = req->src;
144bfd927ffSZain Wang
145bfd927ffSZain Wang return crypto_ahash_update(&rctx->fallback_req);
146bfd927ffSZain Wang }
147bfd927ffSZain Wang
rk_ahash_final(struct ahash_request * req)148bfd927ffSZain Wang static int rk_ahash_final(struct ahash_request *req)
149bfd927ffSZain Wang {
150bfd927ffSZain Wang struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
151bfd927ffSZain Wang struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
152bfd927ffSZain Wang struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
153bfd927ffSZain Wang
154bfd927ffSZain Wang ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
155bfd927ffSZain Wang rctx->fallback_req.base.flags = req->base.flags &
156bfd927ffSZain Wang CRYPTO_TFM_REQ_MAY_SLEEP;
157bfd927ffSZain Wang rctx->fallback_req.result = req->result;
158bfd927ffSZain Wang
159bfd927ffSZain Wang return crypto_ahash_final(&rctx->fallback_req);
160bfd927ffSZain Wang }
161bfd927ffSZain Wang
rk_ahash_finup(struct ahash_request * req)162bfd927ffSZain Wang static int rk_ahash_finup(struct ahash_request *req)
163bfd927ffSZain Wang {
164bfd927ffSZain Wang struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
165bfd927ffSZain Wang struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
166bfd927ffSZain Wang struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
167bfd927ffSZain Wang
168bfd927ffSZain Wang ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
169bfd927ffSZain Wang rctx->fallback_req.base.flags = req->base.flags &
170bfd927ffSZain Wang CRYPTO_TFM_REQ_MAY_SLEEP;
171bfd927ffSZain Wang
172bfd927ffSZain Wang rctx->fallback_req.nbytes = req->nbytes;
173bfd927ffSZain Wang rctx->fallback_req.src = req->src;
174bfd927ffSZain Wang rctx->fallback_req.result = req->result;
175bfd927ffSZain Wang
176bfd927ffSZain Wang return crypto_ahash_finup(&rctx->fallback_req);
177bfd927ffSZain Wang }
178bfd927ffSZain Wang
rk_ahash_import(struct ahash_request * req,const void * in)179bfd927ffSZain Wang static int rk_ahash_import(struct ahash_request *req, const void *in)
180bfd927ffSZain Wang {
181bfd927ffSZain Wang struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
182bfd927ffSZain Wang struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
183bfd927ffSZain Wang struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
184bfd927ffSZain Wang
185bfd927ffSZain Wang ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
186bfd927ffSZain Wang rctx->fallback_req.base.flags = req->base.flags &
187bfd927ffSZain Wang CRYPTO_TFM_REQ_MAY_SLEEP;
188bfd927ffSZain Wang
189bfd927ffSZain Wang return crypto_ahash_import(&rctx->fallback_req, in);
190bfd927ffSZain Wang }
191bfd927ffSZain Wang
rk_ahash_export(struct ahash_request * req,void * out)192bfd927ffSZain Wang static int rk_ahash_export(struct ahash_request *req, void *out)
193bfd927ffSZain Wang {
194bfd927ffSZain Wang struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
195bfd927ffSZain Wang struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
196bfd927ffSZain Wang struct rk_ahash_ctx *ctx = crypto_ahash_ctx(tfm);
197bfd927ffSZain Wang
198bfd927ffSZain Wang ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm);
199bfd927ffSZain Wang rctx->fallback_req.base.flags = req->base.flags &
200bfd927ffSZain Wang CRYPTO_TFM_REQ_MAY_SLEEP;
201bfd927ffSZain Wang
202bfd927ffSZain Wang return crypto_ahash_export(&rctx->fallback_req, out);
203bfd927ffSZain Wang }
204bfd927ffSZain Wang
rk_ahash_digest(struct ahash_request * req)205bfd927ffSZain Wang static int rk_ahash_digest(struct ahash_request *req)
206bfd927ffSZain Wang {
2072d3c756aSCorentin Labbe struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
2089dcd71c8SCorentin Labbe struct rk_crypto_info *dev;
2099dcd71c8SCorentin Labbe struct crypto_engine *engine;
210bfd927ffSZain Wang
21181660048SCorentin Labbe if (rk_ahash_need_fallback(req))
21281660048SCorentin Labbe return rk_ahash_digest_fb(req);
21381660048SCorentin Labbe
214bfd927ffSZain Wang if (!req->nbytes)
215bfd927ffSZain Wang return zero_message_process(req);
21657d67c6eSCorentin Labbe
2179dcd71c8SCorentin Labbe dev = get_rk_crypto();
2182d3c756aSCorentin Labbe
2199dcd71c8SCorentin Labbe rctx->dev = dev;
2209dcd71c8SCorentin Labbe engine = dev->engine;
2219dcd71c8SCorentin Labbe
2229dcd71c8SCorentin Labbe return crypto_transfer_hash_request_to_engine(engine, req);
223bfd927ffSZain Wang }
224bfd927ffSZain Wang
crypto_ahash_dma_start(struct rk_crypto_info * dev,struct scatterlist * sg)22557d67c6eSCorentin Labbe static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg)
226bfd927ffSZain Wang {
22757d67c6eSCorentin Labbe CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg));
22857d67c6eSCorentin Labbe CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4);
229bfd927ffSZain Wang CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START |
230bfd927ffSZain Wang (RK_CRYPTO_HASH_START << 16));
231bfd927ffSZain Wang }
232bfd927ffSZain Wang
rk_hash_prepare(struct crypto_engine * engine,void * breq)23357d67c6eSCorentin Labbe static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
234bfd927ffSZain Wang {
23557d67c6eSCorentin Labbe struct ahash_request *areq = container_of(breq, struct ahash_request, base);
23657d67c6eSCorentin Labbe struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
2372d3c756aSCorentin Labbe struct rk_crypto_info *rkc = rctx->dev;
23857d67c6eSCorentin Labbe int ret;
239bfd927ffSZain Wang
240c018c7a9SCorentin Labbe ret = dma_map_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
24157d67c6eSCorentin Labbe if (ret <= 0)
24257d67c6eSCorentin Labbe return -EINVAL;
24357d67c6eSCorentin Labbe
24457d67c6eSCorentin Labbe rctx->nrsg = ret;
24557d67c6eSCorentin Labbe
24657d67c6eSCorentin Labbe return 0;
247bfd927ffSZain Wang }
248bfd927ffSZain Wang
rk_hash_unprepare(struct crypto_engine * engine,void * breq)249c66c17a0SHerbert Xu static void rk_hash_unprepare(struct crypto_engine *engine, void *breq)
250bfd927ffSZain Wang {
25157d67c6eSCorentin Labbe struct ahash_request *areq = container_of(breq, struct ahash_request, base);
25257d67c6eSCorentin Labbe struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
2532d3c756aSCorentin Labbe struct rk_crypto_info *rkc = rctx->dev;
2545a7801f6SZain Wang
255c018c7a9SCorentin Labbe dma_unmap_sg(rkc->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
25657d67c6eSCorentin Labbe }
25757d67c6eSCorentin Labbe
rk_hash_run(struct crypto_engine * engine,void * breq)25857d67c6eSCorentin Labbe static int rk_hash_run(struct crypto_engine *engine, void *breq)
25957d67c6eSCorentin Labbe {
26057d67c6eSCorentin Labbe struct ahash_request *areq = container_of(breq, struct ahash_request, base);
26157d67c6eSCorentin Labbe struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
26257d67c6eSCorentin Labbe struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
2631a15d26cSHerbert Xu struct ahash_alg *alg = crypto_ahash_alg(tfm);
2641a15d26cSHerbert Xu struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash.base);
26557d67c6eSCorentin Labbe struct scatterlist *sg = areq->src;
2662d3c756aSCorentin Labbe struct rk_crypto_info *rkc = rctx->dev;
267c66c17a0SHerbert Xu int err;
26857d67c6eSCorentin Labbe int i;
26957d67c6eSCorentin Labbe u32 v;
27057d67c6eSCorentin Labbe
2719dcd71c8SCorentin Labbe err = pm_runtime_resume_and_get(rkc->dev);
2729dcd71c8SCorentin Labbe if (err)
2739dcd71c8SCorentin Labbe return err;
2749dcd71c8SCorentin Labbe
275c66c17a0SHerbert Xu err = rk_hash_prepare(engine, breq);
276c66c17a0SHerbert Xu if (err)
277c66c17a0SHerbert Xu goto theend;
278c66c17a0SHerbert Xu
2795a7801f6SZain Wang rctx->mode = 0;
2805a7801f6SZain Wang
28148d904d4SCorentin Labbe algt->stat_req++;
2829dcd71c8SCorentin Labbe rkc->nreq++;
28348d904d4SCorentin Labbe
2845a7801f6SZain Wang switch (crypto_ahash_digestsize(tfm)) {
2855a7801f6SZain Wang case SHA1_DIGEST_SIZE:
2865a7801f6SZain Wang rctx->mode = RK_CRYPTO_HASH_SHA1;
2875a7801f6SZain Wang break;
2885a7801f6SZain Wang case SHA256_DIGEST_SIZE:
2895a7801f6SZain Wang rctx->mode = RK_CRYPTO_HASH_SHA256;
2905a7801f6SZain Wang break;
2915a7801f6SZain Wang case MD5_DIGEST_SIZE:
2925a7801f6SZain Wang rctx->mode = RK_CRYPTO_HASH_MD5;
2935a7801f6SZain Wang break;
2945a7801f6SZain Wang default:
29557d67c6eSCorentin Labbe err = -EINVAL;
29657d67c6eSCorentin Labbe goto theend;
2975a7801f6SZain Wang }
2985a7801f6SZain Wang
2990d31b14cSCorentin Labbe rk_ahash_reg_init(areq, rkc);
30057d67c6eSCorentin Labbe
30157d67c6eSCorentin Labbe while (sg) {
302c018c7a9SCorentin Labbe reinit_completion(&rkc->complete);
303c018c7a9SCorentin Labbe rkc->status = 0;
304c018c7a9SCorentin Labbe crypto_ahash_dma_start(rkc, sg);
305c018c7a9SCorentin Labbe wait_for_completion_interruptible_timeout(&rkc->complete,
30657d67c6eSCorentin Labbe msecs_to_jiffies(2000));
307c018c7a9SCorentin Labbe if (!rkc->status) {
308c018c7a9SCorentin Labbe dev_err(rkc->dev, "DMA timeout\n");
30957d67c6eSCorentin Labbe err = -EFAULT;
31057d67c6eSCorentin Labbe goto theend;
31157d67c6eSCorentin Labbe }
31257d67c6eSCorentin Labbe sg = sg_next(sg);
313bfd927ffSZain Wang }
314bfd927ffSZain Wang
3155a7801f6SZain Wang /*
3165a7801f6SZain Wang * it will take some time to process date after last dma
3175a7801f6SZain Wang * transmission.
3185a7801f6SZain Wang *
3195a7801f6SZain Wang * waiting time is relative with the last date len,
3205a7801f6SZain Wang * so cannot set a fixed time here.
3215a7801f6SZain Wang * 10us makes system not call here frequently wasting
3225a7801f6SZain Wang * efficiency, and make it response quickly when dma
3235a7801f6SZain Wang * complete.
3245a7801f6SZain Wang */
325c018c7a9SCorentin Labbe readl_poll_timeout(rkc->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000);
3265a7801f6SZain Wang
32757d67c6eSCorentin Labbe for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
328c018c7a9SCorentin Labbe v = readl(rkc->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
32957d67c6eSCorentin Labbe put_unaligned_le32(v, areq->result + i * 4);
330bfd927ffSZain Wang }
331bfd927ffSZain Wang
33257d67c6eSCorentin Labbe theend:
3339dcd71c8SCorentin Labbe pm_runtime_put_autosuspend(rkc->dev);
3349dcd71c8SCorentin Labbe
335*c0afb6b8SHerbert Xu rk_hash_unprepare(engine, breq);
336*c0afb6b8SHerbert Xu
33757d67c6eSCorentin Labbe local_bh_disable();
33857d67c6eSCorentin Labbe crypto_finalize_hash_request(engine, breq, err);
33957d67c6eSCorentin Labbe local_bh_enable();
34057d67c6eSCorentin Labbe
34157d67c6eSCorentin Labbe return 0;
342bfd927ffSZain Wang }
343bfd927ffSZain Wang
rk_hash_init_tfm(struct crypto_ahash * tfm)3441a15d26cSHerbert Xu static int rk_hash_init_tfm(struct crypto_ahash *tfm)
345bfd927ffSZain Wang {
3461a15d26cSHerbert Xu struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
3471a15d26cSHerbert Xu const char *alg_name = crypto_ahash_alg_name(tfm);
3481a15d26cSHerbert Xu struct ahash_alg *alg = crypto_ahash_alg(tfm);
3491a15d26cSHerbert Xu struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash.base);
350bfd927ffSZain Wang
351bfd927ffSZain Wang /* for fallback */
352bfd927ffSZain Wang tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
353bfd927ffSZain Wang CRYPTO_ALG_NEED_FALLBACK);
354bfd927ffSZain Wang if (IS_ERR(tctx->fallback_tfm)) {
3559dcd71c8SCorentin Labbe dev_err(algt->dev->dev, "Could not load fallback driver.\n");
356bfd927ffSZain Wang return PTR_ERR(tctx->fallback_tfm);
357bfd927ffSZain Wang }
35857d67c6eSCorentin Labbe
3591a15d26cSHerbert Xu crypto_ahash_set_reqsize(tfm,
360bfd927ffSZain Wang sizeof(struct rk_ahash_rctx) +
361bfd927ffSZain Wang crypto_ahash_reqsize(tctx->fallback_tfm));
362bfd927ffSZain Wang
363c50ef141SCorentin Labbe return 0;
364bfd927ffSZain Wang }
365bfd927ffSZain Wang
rk_hash_exit_tfm(struct crypto_ahash * tfm)3661a15d26cSHerbert Xu static void rk_hash_exit_tfm(struct crypto_ahash *tfm)
367bfd927ffSZain Wang {
3681a15d26cSHerbert Xu struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
369bfd927ffSZain Wang
37081660048SCorentin Labbe crypto_free_ahash(tctx->fallback_tfm);
371bfd927ffSZain Wang }
372bfd927ffSZain Wang
373bfd927ffSZain Wang struct rk_crypto_tmp rk_ahash_sha1 = {
3746d55c4a2SCorentin Labbe .type = CRYPTO_ALG_TYPE_AHASH,
3751a15d26cSHerbert Xu .alg.hash.base = {
376bfd927ffSZain Wang .init = rk_ahash_init,
377bfd927ffSZain Wang .update = rk_ahash_update,
378bfd927ffSZain Wang .final = rk_ahash_final,
379bfd927ffSZain Wang .finup = rk_ahash_finup,
380bfd927ffSZain Wang .export = rk_ahash_export,
381bfd927ffSZain Wang .import = rk_ahash_import,
382bfd927ffSZain Wang .digest = rk_ahash_digest,
3831a15d26cSHerbert Xu .init_tfm = rk_hash_init_tfm,
3841a15d26cSHerbert Xu .exit_tfm = rk_hash_exit_tfm,
385bfd927ffSZain Wang .halg = {
386bfd927ffSZain Wang .digestsize = SHA1_DIGEST_SIZE,
387bfd927ffSZain Wang .statesize = sizeof(struct sha1_state),
388bfd927ffSZain Wang .base = {
389bfd927ffSZain Wang .cra_name = "sha1",
390bfd927ffSZain Wang .cra_driver_name = "rk-sha1",
391bfd927ffSZain Wang .cra_priority = 300,
392bfd927ffSZain Wang .cra_flags = CRYPTO_ALG_ASYNC |
393bfd927ffSZain Wang CRYPTO_ALG_NEED_FALLBACK,
394bfd927ffSZain Wang .cra_blocksize = SHA1_BLOCK_SIZE,
395bfd927ffSZain Wang .cra_ctxsize = sizeof(struct rk_ahash_ctx),
396bfd927ffSZain Wang .cra_module = THIS_MODULE,
397bfd927ffSZain Wang }
398bfd927ffSZain Wang }
3991a15d26cSHerbert Xu },
4001a15d26cSHerbert Xu .alg.hash.op = {
4011a15d26cSHerbert Xu .do_one_request = rk_hash_run,
4021a15d26cSHerbert Xu },
403bfd927ffSZain Wang };
404bfd927ffSZain Wang
405bfd927ffSZain Wang struct rk_crypto_tmp rk_ahash_sha256 = {
4066d55c4a2SCorentin Labbe .type = CRYPTO_ALG_TYPE_AHASH,
4071a15d26cSHerbert Xu .alg.hash.base = {
408bfd927ffSZain Wang .init = rk_ahash_init,
409bfd927ffSZain Wang .update = rk_ahash_update,
410bfd927ffSZain Wang .final = rk_ahash_final,
411bfd927ffSZain Wang .finup = rk_ahash_finup,
412bfd927ffSZain Wang .export = rk_ahash_export,
413bfd927ffSZain Wang .import = rk_ahash_import,
414bfd927ffSZain Wang .digest = rk_ahash_digest,
4151a15d26cSHerbert Xu .init_tfm = rk_hash_init_tfm,
4161a15d26cSHerbert Xu .exit_tfm = rk_hash_exit_tfm,
417bfd927ffSZain Wang .halg = {
418bfd927ffSZain Wang .digestsize = SHA256_DIGEST_SIZE,
419bfd927ffSZain Wang .statesize = sizeof(struct sha256_state),
420bfd927ffSZain Wang .base = {
421bfd927ffSZain Wang .cra_name = "sha256",
422bfd927ffSZain Wang .cra_driver_name = "rk-sha256",
423bfd927ffSZain Wang .cra_priority = 300,
424bfd927ffSZain Wang .cra_flags = CRYPTO_ALG_ASYNC |
425bfd927ffSZain Wang CRYPTO_ALG_NEED_FALLBACK,
426bfd927ffSZain Wang .cra_blocksize = SHA256_BLOCK_SIZE,
427bfd927ffSZain Wang .cra_ctxsize = sizeof(struct rk_ahash_ctx),
428bfd927ffSZain Wang .cra_module = THIS_MODULE,
429bfd927ffSZain Wang }
430bfd927ffSZain Wang }
4311a15d26cSHerbert Xu },
4321a15d26cSHerbert Xu .alg.hash.op = {
4331a15d26cSHerbert Xu .do_one_request = rk_hash_run,
4341a15d26cSHerbert Xu },
435bfd927ffSZain Wang };
436bfd927ffSZain Wang
437bfd927ffSZain Wang struct rk_crypto_tmp rk_ahash_md5 = {
4386d55c4a2SCorentin Labbe .type = CRYPTO_ALG_TYPE_AHASH,
4391a15d26cSHerbert Xu .alg.hash.base = {
440bfd927ffSZain Wang .init = rk_ahash_init,
441bfd927ffSZain Wang .update = rk_ahash_update,
442bfd927ffSZain Wang .final = rk_ahash_final,
443bfd927ffSZain Wang .finup = rk_ahash_finup,
444bfd927ffSZain Wang .export = rk_ahash_export,
445bfd927ffSZain Wang .import = rk_ahash_import,
446bfd927ffSZain Wang .digest = rk_ahash_digest,
4471a15d26cSHerbert Xu .init_tfm = rk_hash_init_tfm,
4481a15d26cSHerbert Xu .exit_tfm = rk_hash_exit_tfm,
449bfd927ffSZain Wang .halg = {
450bfd927ffSZain Wang .digestsize = MD5_DIGEST_SIZE,
451bfd927ffSZain Wang .statesize = sizeof(struct md5_state),
452bfd927ffSZain Wang .base = {
453bfd927ffSZain Wang .cra_name = "md5",
454bfd927ffSZain Wang .cra_driver_name = "rk-md5",
455bfd927ffSZain Wang .cra_priority = 300,
456bfd927ffSZain Wang .cra_flags = CRYPTO_ALG_ASYNC |
457bfd927ffSZain Wang CRYPTO_ALG_NEED_FALLBACK,
458bfd927ffSZain Wang .cra_blocksize = SHA1_BLOCK_SIZE,
459bfd927ffSZain Wang .cra_ctxsize = sizeof(struct rk_ahash_ctx),
460bfd927ffSZain Wang .cra_module = THIS_MODULE,
461bfd927ffSZain Wang }
462bfd927ffSZain Wang }
4631a15d26cSHerbert Xu },
4641a15d26cSHerbert Xu .alg.hash.op = {
4651a15d26cSHerbert Xu .do_one_request = rk_hash_run,
4661a15d26cSHerbert Xu },
467bfd927ffSZain Wang };
468