xref: /linux/drivers/crypto/hisilicon/sec2/sec_crypto.c (revision 416d82204df44ef727de6eafafeaa4d12fdc78dc)
1*416d8220SZaibo Xu // SPDX-License-Identifier: GPL-2.0
2*416d8220SZaibo Xu /* Copyright (c) 2019 HiSilicon Limited. */
3*416d8220SZaibo Xu 
4*416d8220SZaibo Xu #include <crypto/aes.h>
5*416d8220SZaibo Xu #include <crypto/algapi.h>
6*416d8220SZaibo Xu #include <crypto/des.h>
7*416d8220SZaibo Xu #include <crypto/skcipher.h>
8*416d8220SZaibo Xu #include <crypto/xts.h>
9*416d8220SZaibo Xu #include <linux/crypto.h>
10*416d8220SZaibo Xu #include <linux/dma-mapping.h>
11*416d8220SZaibo Xu #include <linux/idr.h>
12*416d8220SZaibo Xu 
13*416d8220SZaibo Xu #include "sec.h"
14*416d8220SZaibo Xu #include "sec_crypto.h"
15*416d8220SZaibo Xu 
16*416d8220SZaibo Xu #define SEC_PRIORITY		4001
17*416d8220SZaibo Xu #define SEC_XTS_MIN_KEY_SIZE	(2 * AES_MIN_KEY_SIZE)
18*416d8220SZaibo Xu #define SEC_XTS_MAX_KEY_SIZE	(2 * AES_MAX_KEY_SIZE)
19*416d8220SZaibo Xu #define SEC_DES3_2KEY_SIZE	(2 * DES_KEY_SIZE)
20*416d8220SZaibo Xu #define SEC_DES3_3KEY_SIZE	(3 * DES_KEY_SIZE)
21*416d8220SZaibo Xu 
22*416d8220SZaibo Xu /* SEC sqe(bd) bit operational relative MACRO */
23*416d8220SZaibo Xu #define SEC_DE_OFFSET		1
24*416d8220SZaibo Xu #define SEC_CIPHER_OFFSET	4
25*416d8220SZaibo Xu #define SEC_SCENE_OFFSET	3
26*416d8220SZaibo Xu #define SEC_DST_SGL_OFFSET	2
27*416d8220SZaibo Xu #define SEC_SRC_SGL_OFFSET	7
28*416d8220SZaibo Xu #define SEC_CKEY_OFFSET		9
29*416d8220SZaibo Xu #define SEC_CMODE_OFFSET	12
30*416d8220SZaibo Xu #define SEC_FLAG_OFFSET		7
31*416d8220SZaibo Xu #define SEC_FLAG_MASK		0x0780
32*416d8220SZaibo Xu #define SEC_TYPE_MASK		0x0F
33*416d8220SZaibo Xu #define SEC_DONE_MASK		0x0001
34*416d8220SZaibo Xu 
35*416d8220SZaibo Xu #define SEC_TOTAL_IV_SZ		(SEC_IV_SIZE * QM_Q_DEPTH)
36*416d8220SZaibo Xu #define SEC_SGL_SGE_NR		128
37*416d8220SZaibo Xu #define SEC_CTX_DEV(ctx)	(&(ctx)->sec->qm.pdev->dev)
38*416d8220SZaibo Xu 
39*416d8220SZaibo Xu static DEFINE_MUTEX(sec_algs_lock);
40*416d8220SZaibo Xu static unsigned int sec_active_devs;
41*416d8220SZaibo Xu 
42*416d8220SZaibo Xu /* Get an en/de-cipher queue cyclically to balance load over queues of TFM */
43*416d8220SZaibo Xu static inline int sec_get_queue_id(struct sec_ctx *ctx, struct sec_req *req)
44*416d8220SZaibo Xu {
45*416d8220SZaibo Xu 	if (req->c_req.encrypt)
46*416d8220SZaibo Xu 		return (u32)atomic_inc_return(&ctx->enc_qcyclic) %
47*416d8220SZaibo Xu 				 ctx->hlf_q_num;
48*416d8220SZaibo Xu 
49*416d8220SZaibo Xu 	return (u32)atomic_inc_return(&ctx->dec_qcyclic) % ctx->hlf_q_num +
50*416d8220SZaibo Xu 				 ctx->hlf_q_num;
51*416d8220SZaibo Xu }
52*416d8220SZaibo Xu 
53*416d8220SZaibo Xu static inline void sec_put_queue_id(struct sec_ctx *ctx, struct sec_req *req)
54*416d8220SZaibo Xu {
55*416d8220SZaibo Xu 	if (req->c_req.encrypt)
56*416d8220SZaibo Xu 		atomic_dec(&ctx->enc_qcyclic);
57*416d8220SZaibo Xu 	else
58*416d8220SZaibo Xu 		atomic_dec(&ctx->dec_qcyclic);
59*416d8220SZaibo Xu }
60*416d8220SZaibo Xu 
61*416d8220SZaibo Xu static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx)
62*416d8220SZaibo Xu {
63*416d8220SZaibo Xu 	int req_id;
64*416d8220SZaibo Xu 
65*416d8220SZaibo Xu 	mutex_lock(&qp_ctx->req_lock);
66*416d8220SZaibo Xu 
67*416d8220SZaibo Xu 	req_id = idr_alloc_cyclic(&qp_ctx->req_idr, NULL,
68*416d8220SZaibo Xu 				  0, QM_Q_DEPTH, GFP_ATOMIC);
69*416d8220SZaibo Xu 	mutex_unlock(&qp_ctx->req_lock);
70*416d8220SZaibo Xu 	if (req_id < 0) {
71*416d8220SZaibo Xu 		dev_err(SEC_CTX_DEV(req->ctx), "alloc req id fail!\n");
72*416d8220SZaibo Xu 		return req_id;
73*416d8220SZaibo Xu 	}
74*416d8220SZaibo Xu 
75*416d8220SZaibo Xu 	req->qp_ctx = qp_ctx;
76*416d8220SZaibo Xu 	qp_ctx->req_list[req_id] = req;
77*416d8220SZaibo Xu 	return req_id;
78*416d8220SZaibo Xu }
79*416d8220SZaibo Xu 
80*416d8220SZaibo Xu static void sec_free_req_id(struct sec_req *req)
81*416d8220SZaibo Xu {
82*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
83*416d8220SZaibo Xu 	int req_id = req->req_id;
84*416d8220SZaibo Xu 
85*416d8220SZaibo Xu 	if (req_id < 0 || req_id >= QM_Q_DEPTH) {
86*416d8220SZaibo Xu 		dev_err(SEC_CTX_DEV(req->ctx), "free request id invalid!\n");
87*416d8220SZaibo Xu 		return;
88*416d8220SZaibo Xu 	}
89*416d8220SZaibo Xu 
90*416d8220SZaibo Xu 	qp_ctx->req_list[req_id] = NULL;
91*416d8220SZaibo Xu 	req->qp_ctx = NULL;
92*416d8220SZaibo Xu 
93*416d8220SZaibo Xu 	mutex_lock(&qp_ctx->req_lock);
94*416d8220SZaibo Xu 	idr_remove(&qp_ctx->req_idr, req_id);
95*416d8220SZaibo Xu 	mutex_unlock(&qp_ctx->req_lock);
96*416d8220SZaibo Xu }
97*416d8220SZaibo Xu 
98*416d8220SZaibo Xu static void sec_req_cb(struct hisi_qp *qp, void *resp)
99*416d8220SZaibo Xu {
100*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx = qp->qp_ctx;
101*416d8220SZaibo Xu 	struct sec_sqe *bd = resp;
102*416d8220SZaibo Xu 	u16 done, flag;
103*416d8220SZaibo Xu 	u8 type;
104*416d8220SZaibo Xu 	struct sec_req *req;
105*416d8220SZaibo Xu 
106*416d8220SZaibo Xu 	type = bd->type_cipher_auth & SEC_TYPE_MASK;
107*416d8220SZaibo Xu 	if (type == SEC_BD_TYPE2) {
108*416d8220SZaibo Xu 		req = qp_ctx->req_list[le16_to_cpu(bd->type2.tag)];
109*416d8220SZaibo Xu 		req->err_type = bd->type2.error_type;
110*416d8220SZaibo Xu 
111*416d8220SZaibo Xu 		done = le16_to_cpu(bd->type2.done_flag) & SEC_DONE_MASK;
112*416d8220SZaibo Xu 		flag = (le16_to_cpu(bd->type2.done_flag) &
113*416d8220SZaibo Xu 				   SEC_FLAG_MASK) >> SEC_FLAG_OFFSET;
114*416d8220SZaibo Xu 		if (req->err_type || done != 0x1 || flag != 0x2)
115*416d8220SZaibo Xu 			dev_err(SEC_CTX_DEV(req->ctx),
116*416d8220SZaibo Xu 				"err_type[%d],done[%d],flag[%d]\n",
117*416d8220SZaibo Xu 				req->err_type, done, flag);
118*416d8220SZaibo Xu 	} else {
119*416d8220SZaibo Xu 		pr_err("err bd type [%d]\n", type);
120*416d8220SZaibo Xu 		return;
121*416d8220SZaibo Xu 	}
122*416d8220SZaibo Xu 
123*416d8220SZaibo Xu 	req->ctx->req_op->buf_unmap(req->ctx, req);
124*416d8220SZaibo Xu 
125*416d8220SZaibo Xu 	req->ctx->req_op->callback(req->ctx, req);
126*416d8220SZaibo Xu }
127*416d8220SZaibo Xu 
128*416d8220SZaibo Xu static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req)
129*416d8220SZaibo Xu {
130*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
131*416d8220SZaibo Xu 	int ret;
132*416d8220SZaibo Xu 
133*416d8220SZaibo Xu 	mutex_lock(&qp_ctx->req_lock);
134*416d8220SZaibo Xu 	ret = hisi_qp_send(qp_ctx->qp, &req->sec_sqe);
135*416d8220SZaibo Xu 	mutex_unlock(&qp_ctx->req_lock);
136*416d8220SZaibo Xu 
137*416d8220SZaibo Xu 	if (ret == -EBUSY)
138*416d8220SZaibo Xu 		return -ENOBUFS;
139*416d8220SZaibo Xu 
140*416d8220SZaibo Xu 	if (!ret) {
141*416d8220SZaibo Xu 		if (req->fake_busy)
142*416d8220SZaibo Xu 			ret = -EBUSY;
143*416d8220SZaibo Xu 		else
144*416d8220SZaibo Xu 			ret = -EINPROGRESS;
145*416d8220SZaibo Xu 	}
146*416d8220SZaibo Xu 
147*416d8220SZaibo Xu 	return ret;
148*416d8220SZaibo Xu }
149*416d8220SZaibo Xu 
150*416d8220SZaibo Xu static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx,
151*416d8220SZaibo Xu 			     int qp_ctx_id, int alg_type)
152*416d8220SZaibo Xu {
153*416d8220SZaibo Xu 	struct device *dev = SEC_CTX_DEV(ctx);
154*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx;
155*416d8220SZaibo Xu 	struct hisi_qp *qp;
156*416d8220SZaibo Xu 	int ret = -ENOMEM;
157*416d8220SZaibo Xu 
158*416d8220SZaibo Xu 	qp = hisi_qm_create_qp(qm, alg_type);
159*416d8220SZaibo Xu 	if (IS_ERR(qp))
160*416d8220SZaibo Xu 		return PTR_ERR(qp);
161*416d8220SZaibo Xu 
162*416d8220SZaibo Xu 	qp_ctx = &ctx->qp_ctx[qp_ctx_id];
163*416d8220SZaibo Xu 	qp->req_type = 0;
164*416d8220SZaibo Xu 	qp->qp_ctx = qp_ctx;
165*416d8220SZaibo Xu 	qp->req_cb = sec_req_cb;
166*416d8220SZaibo Xu 	qp_ctx->qp = qp;
167*416d8220SZaibo Xu 	qp_ctx->ctx = ctx;
168*416d8220SZaibo Xu 
169*416d8220SZaibo Xu 	mutex_init(&qp_ctx->req_lock);
170*416d8220SZaibo Xu 	atomic_set(&qp_ctx->pending_reqs, 0);
171*416d8220SZaibo Xu 	idr_init(&qp_ctx->req_idr);
172*416d8220SZaibo Xu 
173*416d8220SZaibo Xu 	qp_ctx->req_list = kcalloc(QM_Q_DEPTH, sizeof(void *), GFP_ATOMIC);
174*416d8220SZaibo Xu 	if (!qp_ctx->req_list)
175*416d8220SZaibo Xu 		goto err_destroy_idr;
176*416d8220SZaibo Xu 
177*416d8220SZaibo Xu 	qp_ctx->c_in_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH,
178*416d8220SZaibo Xu 						     SEC_SGL_SGE_NR);
179*416d8220SZaibo Xu 	if (!qp_ctx->c_in_pool) {
180*416d8220SZaibo Xu 		dev_err(dev, "fail to create sgl pool for input!\n");
181*416d8220SZaibo Xu 		goto err_free_req_list;
182*416d8220SZaibo Xu 	}
183*416d8220SZaibo Xu 
184*416d8220SZaibo Xu 	qp_ctx->c_out_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH,
185*416d8220SZaibo Xu 						      SEC_SGL_SGE_NR);
186*416d8220SZaibo Xu 	if (!qp_ctx->c_out_pool) {
187*416d8220SZaibo Xu 		dev_err(dev, "fail to create sgl pool for output!\n");
188*416d8220SZaibo Xu 		goto err_free_c_in_pool;
189*416d8220SZaibo Xu 	}
190*416d8220SZaibo Xu 
191*416d8220SZaibo Xu 	ret = ctx->req_op->resource_alloc(ctx, qp_ctx);
192*416d8220SZaibo Xu 	if (ret)
193*416d8220SZaibo Xu 		goto err_free_c_out_pool;
194*416d8220SZaibo Xu 
195*416d8220SZaibo Xu 	ret = hisi_qm_start_qp(qp, 0);
196*416d8220SZaibo Xu 	if (ret < 0)
197*416d8220SZaibo Xu 		goto err_queue_free;
198*416d8220SZaibo Xu 
199*416d8220SZaibo Xu 	return 0;
200*416d8220SZaibo Xu 
201*416d8220SZaibo Xu err_queue_free:
202*416d8220SZaibo Xu 	ctx->req_op->resource_free(ctx, qp_ctx);
203*416d8220SZaibo Xu err_free_c_out_pool:
204*416d8220SZaibo Xu 	hisi_acc_free_sgl_pool(dev, qp_ctx->c_out_pool);
205*416d8220SZaibo Xu err_free_c_in_pool:
206*416d8220SZaibo Xu 	hisi_acc_free_sgl_pool(dev, qp_ctx->c_in_pool);
207*416d8220SZaibo Xu err_free_req_list:
208*416d8220SZaibo Xu 	kfree(qp_ctx->req_list);
209*416d8220SZaibo Xu err_destroy_idr:
210*416d8220SZaibo Xu 	idr_destroy(&qp_ctx->req_idr);
211*416d8220SZaibo Xu 	hisi_qm_release_qp(qp);
212*416d8220SZaibo Xu 
213*416d8220SZaibo Xu 	return ret;
214*416d8220SZaibo Xu }
215*416d8220SZaibo Xu 
216*416d8220SZaibo Xu static void sec_release_qp_ctx(struct sec_ctx *ctx,
217*416d8220SZaibo Xu 			       struct sec_qp_ctx *qp_ctx)
218*416d8220SZaibo Xu {
219*416d8220SZaibo Xu 	struct device *dev = SEC_CTX_DEV(ctx);
220*416d8220SZaibo Xu 
221*416d8220SZaibo Xu 	hisi_qm_stop_qp(qp_ctx->qp);
222*416d8220SZaibo Xu 	ctx->req_op->resource_free(ctx, qp_ctx);
223*416d8220SZaibo Xu 
224*416d8220SZaibo Xu 	hisi_acc_free_sgl_pool(dev, qp_ctx->c_out_pool);
225*416d8220SZaibo Xu 	hisi_acc_free_sgl_pool(dev, qp_ctx->c_in_pool);
226*416d8220SZaibo Xu 
227*416d8220SZaibo Xu 	idr_destroy(&qp_ctx->req_idr);
228*416d8220SZaibo Xu 	kfree(qp_ctx->req_list);
229*416d8220SZaibo Xu 	hisi_qm_release_qp(qp_ctx->qp);
230*416d8220SZaibo Xu }
231*416d8220SZaibo Xu 
232*416d8220SZaibo Xu static int sec_skcipher_init(struct crypto_skcipher *tfm)
233*416d8220SZaibo Xu {
234*416d8220SZaibo Xu 	struct sec_ctx *ctx = crypto_skcipher_ctx(tfm);
235*416d8220SZaibo Xu 	struct sec_cipher_ctx *c_ctx;
236*416d8220SZaibo Xu 	struct sec_dev *sec;
237*416d8220SZaibo Xu 	struct device *dev;
238*416d8220SZaibo Xu 	struct hisi_qm *qm;
239*416d8220SZaibo Xu 	int i, ret;
240*416d8220SZaibo Xu 
241*416d8220SZaibo Xu 	crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_req));
242*416d8220SZaibo Xu 
243*416d8220SZaibo Xu 	sec = sec_find_device(cpu_to_node(smp_processor_id()));
244*416d8220SZaibo Xu 	if (!sec) {
245*416d8220SZaibo Xu 		pr_err("find no Hisilicon SEC device!\n");
246*416d8220SZaibo Xu 		return -ENODEV;
247*416d8220SZaibo Xu 	}
248*416d8220SZaibo Xu 	ctx->sec = sec;
249*416d8220SZaibo Xu 	qm = &sec->qm;
250*416d8220SZaibo Xu 	dev = &qm->pdev->dev;
251*416d8220SZaibo Xu 	ctx->hlf_q_num = sec->ctx_q_num >> 0x1;
252*416d8220SZaibo Xu 
253*416d8220SZaibo Xu 	/* Half of queue depth is taken as fake requests limit in the queue. */
254*416d8220SZaibo Xu 	ctx->fake_req_limit = QM_Q_DEPTH >> 0x1;
255*416d8220SZaibo Xu 	ctx->qp_ctx = kcalloc(sec->ctx_q_num, sizeof(struct sec_qp_ctx),
256*416d8220SZaibo Xu 			      GFP_KERNEL);
257*416d8220SZaibo Xu 	if (!ctx->qp_ctx)
258*416d8220SZaibo Xu 		return -ENOMEM;
259*416d8220SZaibo Xu 
260*416d8220SZaibo Xu 	for (i = 0; i < sec->ctx_q_num; i++) {
261*416d8220SZaibo Xu 		ret = sec_create_qp_ctx(qm, ctx, i, 0);
262*416d8220SZaibo Xu 		if (ret)
263*416d8220SZaibo Xu 			goto err_sec_release_qp_ctx;
264*416d8220SZaibo Xu 	}
265*416d8220SZaibo Xu 
266*416d8220SZaibo Xu 	c_ctx = &ctx->c_ctx;
267*416d8220SZaibo Xu 	c_ctx->ivsize = crypto_skcipher_ivsize(tfm);
268*416d8220SZaibo Xu 	if (c_ctx->ivsize > SEC_IV_SIZE) {
269*416d8220SZaibo Xu 		dev_err(dev, "get error iv size!\n");
270*416d8220SZaibo Xu 		ret = -EINVAL;
271*416d8220SZaibo Xu 		goto err_sec_release_qp_ctx;
272*416d8220SZaibo Xu 	}
273*416d8220SZaibo Xu 	c_ctx->c_key = dma_alloc_coherent(dev, SEC_MAX_KEY_SIZE,
274*416d8220SZaibo Xu 					  &c_ctx->c_key_dma, GFP_KERNEL);
275*416d8220SZaibo Xu 	if (!c_ctx->c_key) {
276*416d8220SZaibo Xu 		ret = -ENOMEM;
277*416d8220SZaibo Xu 		goto err_sec_release_qp_ctx;
278*416d8220SZaibo Xu 	}
279*416d8220SZaibo Xu 
280*416d8220SZaibo Xu 	return 0;
281*416d8220SZaibo Xu 
282*416d8220SZaibo Xu err_sec_release_qp_ctx:
283*416d8220SZaibo Xu 	for (i = i - 1; i >= 0; i--)
284*416d8220SZaibo Xu 		sec_release_qp_ctx(ctx, &ctx->qp_ctx[i]);
285*416d8220SZaibo Xu 
286*416d8220SZaibo Xu 	kfree(ctx->qp_ctx);
287*416d8220SZaibo Xu 	return ret;
288*416d8220SZaibo Xu }
289*416d8220SZaibo Xu 
290*416d8220SZaibo Xu static void sec_skcipher_exit(struct crypto_skcipher *tfm)
291*416d8220SZaibo Xu {
292*416d8220SZaibo Xu 	struct sec_ctx *ctx = crypto_skcipher_ctx(tfm);
293*416d8220SZaibo Xu 	struct sec_cipher_ctx *c_ctx = &ctx->c_ctx;
294*416d8220SZaibo Xu 	int i = 0;
295*416d8220SZaibo Xu 
296*416d8220SZaibo Xu 	if (c_ctx->c_key) {
297*416d8220SZaibo Xu 		dma_free_coherent(SEC_CTX_DEV(ctx), SEC_MAX_KEY_SIZE,
298*416d8220SZaibo Xu 				  c_ctx->c_key, c_ctx->c_key_dma);
299*416d8220SZaibo Xu 		c_ctx->c_key = NULL;
300*416d8220SZaibo Xu 	}
301*416d8220SZaibo Xu 
302*416d8220SZaibo Xu 	for (i = 0; i < ctx->sec->ctx_q_num; i++)
303*416d8220SZaibo Xu 		sec_release_qp_ctx(ctx, &ctx->qp_ctx[i]);
304*416d8220SZaibo Xu 
305*416d8220SZaibo Xu 	kfree(ctx->qp_ctx);
306*416d8220SZaibo Xu }
307*416d8220SZaibo Xu 
308*416d8220SZaibo Xu static int sec_skcipher_3des_setkey(struct sec_cipher_ctx *c_ctx,
309*416d8220SZaibo Xu 				    const u32 keylen,
310*416d8220SZaibo Xu 				    const enum sec_cmode c_mode)
311*416d8220SZaibo Xu {
312*416d8220SZaibo Xu 	switch (keylen) {
313*416d8220SZaibo Xu 	case SEC_DES3_2KEY_SIZE:
314*416d8220SZaibo Xu 		c_ctx->c_key_len = SEC_CKEY_3DES_2KEY;
315*416d8220SZaibo Xu 		break;
316*416d8220SZaibo Xu 	case SEC_DES3_3KEY_SIZE:
317*416d8220SZaibo Xu 		c_ctx->c_key_len = SEC_CKEY_3DES_3KEY;
318*416d8220SZaibo Xu 		break;
319*416d8220SZaibo Xu 	default:
320*416d8220SZaibo Xu 		return -EINVAL;
321*416d8220SZaibo Xu 	}
322*416d8220SZaibo Xu 
323*416d8220SZaibo Xu 	return 0;
324*416d8220SZaibo Xu }
325*416d8220SZaibo Xu 
326*416d8220SZaibo Xu static int sec_skcipher_aes_sm4_setkey(struct sec_cipher_ctx *c_ctx,
327*416d8220SZaibo Xu 				       const u32 keylen,
328*416d8220SZaibo Xu 				       const enum sec_cmode c_mode)
329*416d8220SZaibo Xu {
330*416d8220SZaibo Xu 	if (c_mode == SEC_CMODE_XTS) {
331*416d8220SZaibo Xu 		switch (keylen) {
332*416d8220SZaibo Xu 		case SEC_XTS_MIN_KEY_SIZE:
333*416d8220SZaibo Xu 			c_ctx->c_key_len = SEC_CKEY_128BIT;
334*416d8220SZaibo Xu 			break;
335*416d8220SZaibo Xu 		case SEC_XTS_MAX_KEY_SIZE:
336*416d8220SZaibo Xu 			c_ctx->c_key_len = SEC_CKEY_256BIT;
337*416d8220SZaibo Xu 			break;
338*416d8220SZaibo Xu 		default:
339*416d8220SZaibo Xu 			pr_err("hisi_sec2: xts mode key error!\n");
340*416d8220SZaibo Xu 			return -EINVAL;
341*416d8220SZaibo Xu 		}
342*416d8220SZaibo Xu 	} else {
343*416d8220SZaibo Xu 		switch (keylen) {
344*416d8220SZaibo Xu 		case AES_KEYSIZE_128:
345*416d8220SZaibo Xu 			c_ctx->c_key_len = SEC_CKEY_128BIT;
346*416d8220SZaibo Xu 			break;
347*416d8220SZaibo Xu 		case AES_KEYSIZE_192:
348*416d8220SZaibo Xu 			c_ctx->c_key_len = SEC_CKEY_192BIT;
349*416d8220SZaibo Xu 			break;
350*416d8220SZaibo Xu 		case AES_KEYSIZE_256:
351*416d8220SZaibo Xu 			c_ctx->c_key_len = SEC_CKEY_256BIT;
352*416d8220SZaibo Xu 			break;
353*416d8220SZaibo Xu 		default:
354*416d8220SZaibo Xu 			pr_err("hisi_sec2: aes key error!\n");
355*416d8220SZaibo Xu 			return -EINVAL;
356*416d8220SZaibo Xu 		}
357*416d8220SZaibo Xu 	}
358*416d8220SZaibo Xu 
359*416d8220SZaibo Xu 	return 0;
360*416d8220SZaibo Xu }
361*416d8220SZaibo Xu 
362*416d8220SZaibo Xu static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
363*416d8220SZaibo Xu 			       const u32 keylen, const enum sec_calg c_alg,
364*416d8220SZaibo Xu 			       const enum sec_cmode c_mode)
365*416d8220SZaibo Xu {
366*416d8220SZaibo Xu 	struct sec_ctx *ctx = crypto_skcipher_ctx(tfm);
367*416d8220SZaibo Xu 	struct sec_cipher_ctx *c_ctx = &ctx->c_ctx;
368*416d8220SZaibo Xu 	int ret;
369*416d8220SZaibo Xu 
370*416d8220SZaibo Xu 	if (c_mode == SEC_CMODE_XTS) {
371*416d8220SZaibo Xu 		ret = xts_verify_key(tfm, key, keylen);
372*416d8220SZaibo Xu 		if (ret) {
373*416d8220SZaibo Xu 			dev_err(SEC_CTX_DEV(ctx), "xts mode key err!\n");
374*416d8220SZaibo Xu 			return ret;
375*416d8220SZaibo Xu 		}
376*416d8220SZaibo Xu 	}
377*416d8220SZaibo Xu 
378*416d8220SZaibo Xu 	c_ctx->c_alg  = c_alg;
379*416d8220SZaibo Xu 	c_ctx->c_mode = c_mode;
380*416d8220SZaibo Xu 
381*416d8220SZaibo Xu 	switch (c_alg) {
382*416d8220SZaibo Xu 	case SEC_CALG_3DES:
383*416d8220SZaibo Xu 		ret = sec_skcipher_3des_setkey(c_ctx, keylen, c_mode);
384*416d8220SZaibo Xu 		break;
385*416d8220SZaibo Xu 	case SEC_CALG_AES:
386*416d8220SZaibo Xu 	case SEC_CALG_SM4:
387*416d8220SZaibo Xu 		ret = sec_skcipher_aes_sm4_setkey(c_ctx, keylen, c_mode);
388*416d8220SZaibo Xu 		break;
389*416d8220SZaibo Xu 	default:
390*416d8220SZaibo Xu 		return -EINVAL;
391*416d8220SZaibo Xu 	}
392*416d8220SZaibo Xu 
393*416d8220SZaibo Xu 	if (ret) {
394*416d8220SZaibo Xu 		dev_err(SEC_CTX_DEV(ctx), "set sec key err!\n");
395*416d8220SZaibo Xu 		return ret;
396*416d8220SZaibo Xu 	}
397*416d8220SZaibo Xu 
398*416d8220SZaibo Xu 	memcpy(c_ctx->c_key, key, keylen);
399*416d8220SZaibo Xu 
400*416d8220SZaibo Xu 	return 0;
401*416d8220SZaibo Xu }
402*416d8220SZaibo Xu 
403*416d8220SZaibo Xu #define GEN_SEC_SETKEY_FUNC(name, c_alg, c_mode)			\
404*416d8220SZaibo Xu static int sec_setkey_##name(struct crypto_skcipher *tfm, const u8 *key,\
405*416d8220SZaibo Xu 	u32 keylen)							\
406*416d8220SZaibo Xu {									\
407*416d8220SZaibo Xu 	return sec_skcipher_setkey(tfm, key, keylen, c_alg, c_mode);	\
408*416d8220SZaibo Xu }
409*416d8220SZaibo Xu 
410*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(aes_ecb, SEC_CALG_AES, SEC_CMODE_ECB)
411*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(aes_cbc, SEC_CALG_AES, SEC_CMODE_CBC)
412*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(aes_xts, SEC_CALG_AES, SEC_CMODE_XTS)
413*416d8220SZaibo Xu 
414*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(3des_ecb, SEC_CALG_3DES, SEC_CMODE_ECB)
415*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(3des_cbc, SEC_CALG_3DES, SEC_CMODE_CBC)
416*416d8220SZaibo Xu 
417*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(sm4_xts, SEC_CALG_SM4, SEC_CMODE_XTS)
418*416d8220SZaibo Xu GEN_SEC_SETKEY_FUNC(sm4_cbc, SEC_CALG_SM4, SEC_CMODE_CBC)
419*416d8220SZaibo Xu 
420*416d8220SZaibo Xu static int sec_skcipher_get_res(struct sec_ctx *ctx,
421*416d8220SZaibo Xu 				struct sec_req *req)
422*416d8220SZaibo Xu {
423*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
424*416d8220SZaibo Xu 	struct sec_cipher_res *c_res = qp_ctx->alg_meta_data;
425*416d8220SZaibo Xu 	struct sec_cipher_req *c_req = &req->c_req;
426*416d8220SZaibo Xu 	int req_id = req->req_id;
427*416d8220SZaibo Xu 
428*416d8220SZaibo Xu 	c_req->c_ivin = c_res[req_id].c_ivin;
429*416d8220SZaibo Xu 	c_req->c_ivin_dma = c_res[req_id].c_ivin_dma;
430*416d8220SZaibo Xu 
431*416d8220SZaibo Xu 	return 0;
432*416d8220SZaibo Xu }
433*416d8220SZaibo Xu 
434*416d8220SZaibo Xu static int sec_skcipher_resource_alloc(struct sec_ctx *ctx,
435*416d8220SZaibo Xu 				       struct sec_qp_ctx *qp_ctx)
436*416d8220SZaibo Xu {
437*416d8220SZaibo Xu 	struct device *dev = SEC_CTX_DEV(ctx);
438*416d8220SZaibo Xu 	struct sec_cipher_res *res;
439*416d8220SZaibo Xu 	int i;
440*416d8220SZaibo Xu 
441*416d8220SZaibo Xu 	res = kcalloc(QM_Q_DEPTH, sizeof(struct sec_cipher_res), GFP_KERNEL);
442*416d8220SZaibo Xu 	if (!res)
443*416d8220SZaibo Xu 		return -ENOMEM;
444*416d8220SZaibo Xu 
445*416d8220SZaibo Xu 	res->c_ivin = dma_alloc_coherent(dev, SEC_TOTAL_IV_SZ,
446*416d8220SZaibo Xu 					   &res->c_ivin_dma, GFP_KERNEL);
447*416d8220SZaibo Xu 	if (!res->c_ivin) {
448*416d8220SZaibo Xu 		kfree(res);
449*416d8220SZaibo Xu 		return -ENOMEM;
450*416d8220SZaibo Xu 	}
451*416d8220SZaibo Xu 
452*416d8220SZaibo Xu 	for (i = 1; i < QM_Q_DEPTH; i++) {
453*416d8220SZaibo Xu 		res[i].c_ivin_dma = res->c_ivin_dma + i * SEC_IV_SIZE;
454*416d8220SZaibo Xu 		res[i].c_ivin = res->c_ivin + i * SEC_IV_SIZE;
455*416d8220SZaibo Xu 	}
456*416d8220SZaibo Xu 	qp_ctx->alg_meta_data = res;
457*416d8220SZaibo Xu 
458*416d8220SZaibo Xu 	return 0;
459*416d8220SZaibo Xu }
460*416d8220SZaibo Xu 
461*416d8220SZaibo Xu static void sec_skcipher_resource_free(struct sec_ctx *ctx,
462*416d8220SZaibo Xu 				      struct sec_qp_ctx *qp_ctx)
463*416d8220SZaibo Xu {
464*416d8220SZaibo Xu 	struct sec_cipher_res *res = qp_ctx->alg_meta_data;
465*416d8220SZaibo Xu 	struct device *dev = SEC_CTX_DEV(ctx);
466*416d8220SZaibo Xu 
467*416d8220SZaibo Xu 	if (!res)
468*416d8220SZaibo Xu 		return;
469*416d8220SZaibo Xu 
470*416d8220SZaibo Xu 	dma_free_coherent(dev, SEC_TOTAL_IV_SZ, res->c_ivin, res->c_ivin_dma);
471*416d8220SZaibo Xu 	kfree(res);
472*416d8220SZaibo Xu }
473*416d8220SZaibo Xu 
474*416d8220SZaibo Xu static int sec_skcipher_map(struct device *dev, struct sec_req *req,
475*416d8220SZaibo Xu 			    struct scatterlist *src, struct scatterlist *dst)
476*416d8220SZaibo Xu {
477*416d8220SZaibo Xu 	struct sec_cipher_req *c_req = &req->c_req;
478*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
479*416d8220SZaibo Xu 
480*416d8220SZaibo Xu 	c_req->c_in = hisi_acc_sg_buf_map_to_hw_sgl(dev, src,
481*416d8220SZaibo Xu 						    qp_ctx->c_in_pool,
482*416d8220SZaibo Xu 						    req->req_id,
483*416d8220SZaibo Xu 						    &c_req->c_in_dma);
484*416d8220SZaibo Xu 
485*416d8220SZaibo Xu 	if (IS_ERR(c_req->c_in)) {
486*416d8220SZaibo Xu 		dev_err(dev, "fail to dma map input sgl buffers!\n");
487*416d8220SZaibo Xu 		return PTR_ERR(c_req->c_in);
488*416d8220SZaibo Xu 	}
489*416d8220SZaibo Xu 
490*416d8220SZaibo Xu 	if (dst == src) {
491*416d8220SZaibo Xu 		c_req->c_out = c_req->c_in;
492*416d8220SZaibo Xu 		c_req->c_out_dma = c_req->c_in_dma;
493*416d8220SZaibo Xu 	} else {
494*416d8220SZaibo Xu 		c_req->c_out = hisi_acc_sg_buf_map_to_hw_sgl(dev, dst,
495*416d8220SZaibo Xu 							     qp_ctx->c_out_pool,
496*416d8220SZaibo Xu 							     req->req_id,
497*416d8220SZaibo Xu 							     &c_req->c_out_dma);
498*416d8220SZaibo Xu 
499*416d8220SZaibo Xu 		if (IS_ERR(c_req->c_out)) {
500*416d8220SZaibo Xu 			dev_err(dev, "fail to dma map output sgl buffers!\n");
501*416d8220SZaibo Xu 			hisi_acc_sg_buf_unmap(dev, src, c_req->c_in);
502*416d8220SZaibo Xu 			return PTR_ERR(c_req->c_out);
503*416d8220SZaibo Xu 		}
504*416d8220SZaibo Xu 	}
505*416d8220SZaibo Xu 
506*416d8220SZaibo Xu 	return 0;
507*416d8220SZaibo Xu }
508*416d8220SZaibo Xu 
509*416d8220SZaibo Xu static int sec_skcipher_sgl_map(struct sec_ctx *ctx, struct sec_req *req)
510*416d8220SZaibo Xu {
511*416d8220SZaibo Xu 	struct sec_cipher_req *c_req = &req->c_req;
512*416d8220SZaibo Xu 
513*416d8220SZaibo Xu 	return sec_skcipher_map(SEC_CTX_DEV(ctx), req,
514*416d8220SZaibo Xu 				c_req->sk_req->src, c_req->sk_req->dst);
515*416d8220SZaibo Xu }
516*416d8220SZaibo Xu 
517*416d8220SZaibo Xu static void sec_skcipher_sgl_unmap(struct sec_ctx *ctx, struct sec_req *req)
518*416d8220SZaibo Xu {
519*416d8220SZaibo Xu 	struct device *dev = SEC_CTX_DEV(ctx);
520*416d8220SZaibo Xu 	struct sec_cipher_req *c_req = &req->c_req;
521*416d8220SZaibo Xu 	struct skcipher_request *sk_req = c_req->sk_req;
522*416d8220SZaibo Xu 
523*416d8220SZaibo Xu 	if (sk_req->dst != sk_req->src)
524*416d8220SZaibo Xu 		hisi_acc_sg_buf_unmap(dev, sk_req->src, c_req->c_in);
525*416d8220SZaibo Xu 
526*416d8220SZaibo Xu 	hisi_acc_sg_buf_unmap(dev, sk_req->dst, c_req->c_out);
527*416d8220SZaibo Xu }
528*416d8220SZaibo Xu 
529*416d8220SZaibo Xu static int sec_request_transfer(struct sec_ctx *ctx, struct sec_req *req)
530*416d8220SZaibo Xu {
531*416d8220SZaibo Xu 	int ret;
532*416d8220SZaibo Xu 
533*416d8220SZaibo Xu 	ret = ctx->req_op->buf_map(ctx, req);
534*416d8220SZaibo Xu 	if (ret)
535*416d8220SZaibo Xu 		return ret;
536*416d8220SZaibo Xu 
537*416d8220SZaibo Xu 	ctx->req_op->do_transfer(ctx, req);
538*416d8220SZaibo Xu 
539*416d8220SZaibo Xu 	ret = ctx->req_op->bd_fill(ctx, req);
540*416d8220SZaibo Xu 	if (ret)
541*416d8220SZaibo Xu 		goto unmap_req_buf;
542*416d8220SZaibo Xu 
543*416d8220SZaibo Xu 	return ret;
544*416d8220SZaibo Xu 
545*416d8220SZaibo Xu unmap_req_buf:
546*416d8220SZaibo Xu 	ctx->req_op->buf_unmap(ctx, req);
547*416d8220SZaibo Xu 
548*416d8220SZaibo Xu 	return ret;
549*416d8220SZaibo Xu }
550*416d8220SZaibo Xu 
551*416d8220SZaibo Xu static void sec_request_untransfer(struct sec_ctx *ctx, struct sec_req *req)
552*416d8220SZaibo Xu {
553*416d8220SZaibo Xu 	ctx->req_op->buf_unmap(ctx, req);
554*416d8220SZaibo Xu }
555*416d8220SZaibo Xu 
556*416d8220SZaibo Xu static void sec_skcipher_copy_iv(struct sec_ctx *ctx, struct sec_req *req)
557*416d8220SZaibo Xu {
558*416d8220SZaibo Xu 	struct skcipher_request *sk_req = req->c_req.sk_req;
559*416d8220SZaibo Xu 	struct sec_cipher_req *c_req = &req->c_req;
560*416d8220SZaibo Xu 
561*416d8220SZaibo Xu 	c_req->c_len = sk_req->cryptlen;
562*416d8220SZaibo Xu 	memcpy(c_req->c_ivin, sk_req->iv, ctx->c_ctx.ivsize);
563*416d8220SZaibo Xu }
564*416d8220SZaibo Xu 
565*416d8220SZaibo Xu static int sec_skcipher_bd_fill(struct sec_ctx *ctx, struct sec_req *req)
566*416d8220SZaibo Xu {
567*416d8220SZaibo Xu 	struct sec_cipher_ctx *c_ctx = &ctx->c_ctx;
568*416d8220SZaibo Xu 	struct sec_cipher_req *c_req = &req->c_req;
569*416d8220SZaibo Xu 	struct sec_sqe *sec_sqe = &req->sec_sqe;
570*416d8220SZaibo Xu 	u8 de = 0;
571*416d8220SZaibo Xu 	u8 scene, sa_type, da_type;
572*416d8220SZaibo Xu 	u8 bd_type, cipher;
573*416d8220SZaibo Xu 
574*416d8220SZaibo Xu 	memset(sec_sqe, 0, sizeof(struct sec_sqe));
575*416d8220SZaibo Xu 
576*416d8220SZaibo Xu 	sec_sqe->type2.c_key_addr = cpu_to_le64(c_ctx->c_key_dma);
577*416d8220SZaibo Xu 	sec_sqe->type2.c_ivin_addr = cpu_to_le64(c_req->c_ivin_dma);
578*416d8220SZaibo Xu 	sec_sqe->type2.data_src_addr = cpu_to_le64(c_req->c_in_dma);
579*416d8220SZaibo Xu 	sec_sqe->type2.data_dst_addr = cpu_to_le64(c_req->c_out_dma);
580*416d8220SZaibo Xu 
581*416d8220SZaibo Xu 	sec_sqe->type2.icvw_kmode |= cpu_to_le16(((u16)c_ctx->c_mode) <<
582*416d8220SZaibo Xu 						SEC_CMODE_OFFSET);
583*416d8220SZaibo Xu 	sec_sqe->type2.c_alg = c_ctx->c_alg;
584*416d8220SZaibo Xu 	sec_sqe->type2.icvw_kmode |= cpu_to_le16(((u16)c_ctx->c_key_len) <<
585*416d8220SZaibo Xu 						SEC_CKEY_OFFSET);
586*416d8220SZaibo Xu 
587*416d8220SZaibo Xu 	bd_type = SEC_BD_TYPE2;
588*416d8220SZaibo Xu 	if (c_req->encrypt)
589*416d8220SZaibo Xu 		cipher = SEC_CIPHER_ENC << SEC_CIPHER_OFFSET;
590*416d8220SZaibo Xu 	else
591*416d8220SZaibo Xu 		cipher = SEC_CIPHER_DEC << SEC_CIPHER_OFFSET;
592*416d8220SZaibo Xu 	sec_sqe->type_cipher_auth = bd_type | cipher;
593*416d8220SZaibo Xu 
594*416d8220SZaibo Xu 	sa_type = SEC_SGL << SEC_SRC_SGL_OFFSET;
595*416d8220SZaibo Xu 	scene = SEC_COMM_SCENE << SEC_SCENE_OFFSET;
596*416d8220SZaibo Xu 	if (c_req->c_in_dma != c_req->c_out_dma)
597*416d8220SZaibo Xu 		de = 0x1 << SEC_DE_OFFSET;
598*416d8220SZaibo Xu 
599*416d8220SZaibo Xu 	sec_sqe->sds_sa_type = (de | scene | sa_type);
600*416d8220SZaibo Xu 
601*416d8220SZaibo Xu 	/* Just set DST address type */
602*416d8220SZaibo Xu 	da_type = SEC_SGL << SEC_DST_SGL_OFFSET;
603*416d8220SZaibo Xu 	sec_sqe->sdm_addr_type |= da_type;
604*416d8220SZaibo Xu 
605*416d8220SZaibo Xu 	sec_sqe->type2.clen_ivhlen |= cpu_to_le32(c_req->c_len);
606*416d8220SZaibo Xu 	sec_sqe->type2.tag = cpu_to_le16((u16)req->req_id);
607*416d8220SZaibo Xu 
608*416d8220SZaibo Xu 	return 0;
609*416d8220SZaibo Xu }
610*416d8220SZaibo Xu 
611*416d8220SZaibo Xu static void sec_update_iv(struct sec_req *req)
612*416d8220SZaibo Xu {
613*416d8220SZaibo Xu 	struct skcipher_request *sk_req = req->c_req.sk_req;
614*416d8220SZaibo Xu 	u32 iv_size = req->ctx->c_ctx.ivsize;
615*416d8220SZaibo Xu 	struct scatterlist *sgl;
616*416d8220SZaibo Xu 	size_t sz;
617*416d8220SZaibo Xu 
618*416d8220SZaibo Xu 	if (req->c_req.encrypt)
619*416d8220SZaibo Xu 		sgl = sk_req->dst;
620*416d8220SZaibo Xu 	else
621*416d8220SZaibo Xu 		sgl = sk_req->src;
622*416d8220SZaibo Xu 
623*416d8220SZaibo Xu 	sz = sg_pcopy_to_buffer(sgl, sg_nents(sgl), sk_req->iv,
624*416d8220SZaibo Xu 				iv_size, sk_req->cryptlen - iv_size);
625*416d8220SZaibo Xu 	if (sz != iv_size)
626*416d8220SZaibo Xu 		dev_err(SEC_CTX_DEV(req->ctx), "copy output iv error!\n");
627*416d8220SZaibo Xu }
628*416d8220SZaibo Xu 
629*416d8220SZaibo Xu static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req)
630*416d8220SZaibo Xu {
631*416d8220SZaibo Xu 	struct skcipher_request *sk_req = req->c_req.sk_req;
632*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
633*416d8220SZaibo Xu 
634*416d8220SZaibo Xu 	atomic_dec(&qp_ctx->pending_reqs);
635*416d8220SZaibo Xu 	sec_free_req_id(req);
636*416d8220SZaibo Xu 
637*416d8220SZaibo Xu 	/* IV output at encrypto of CBC mode */
638*416d8220SZaibo Xu 	if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && req->c_req.encrypt)
639*416d8220SZaibo Xu 		sec_update_iv(req);
640*416d8220SZaibo Xu 
641*416d8220SZaibo Xu 	if (__sync_bool_compare_and_swap(&req->fake_busy, 1, 0))
642*416d8220SZaibo Xu 		sk_req->base.complete(&sk_req->base, -EINPROGRESS);
643*416d8220SZaibo Xu 
644*416d8220SZaibo Xu 	sk_req->base.complete(&sk_req->base, req->err_type);
645*416d8220SZaibo Xu }
646*416d8220SZaibo Xu 
647*416d8220SZaibo Xu static void sec_request_uninit(struct sec_ctx *ctx, struct sec_req *req)
648*416d8220SZaibo Xu {
649*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
650*416d8220SZaibo Xu 
651*416d8220SZaibo Xu 	atomic_dec(&qp_ctx->pending_reqs);
652*416d8220SZaibo Xu 	sec_free_req_id(req);
653*416d8220SZaibo Xu 	sec_put_queue_id(ctx, req);
654*416d8220SZaibo Xu }
655*416d8220SZaibo Xu 
656*416d8220SZaibo Xu static int sec_request_init(struct sec_ctx *ctx, struct sec_req *req)
657*416d8220SZaibo Xu {
658*416d8220SZaibo Xu 	struct sec_qp_ctx *qp_ctx;
659*416d8220SZaibo Xu 	int issue_id, ret;
660*416d8220SZaibo Xu 
661*416d8220SZaibo Xu 	/* To load balance */
662*416d8220SZaibo Xu 	issue_id = sec_get_queue_id(ctx, req);
663*416d8220SZaibo Xu 	qp_ctx = &ctx->qp_ctx[issue_id];
664*416d8220SZaibo Xu 
665*416d8220SZaibo Xu 	req->req_id = sec_alloc_req_id(req, qp_ctx);
666*416d8220SZaibo Xu 	if (req->req_id < 0) {
667*416d8220SZaibo Xu 		sec_put_queue_id(ctx, req);
668*416d8220SZaibo Xu 		return req->req_id;
669*416d8220SZaibo Xu 	}
670*416d8220SZaibo Xu 
671*416d8220SZaibo Xu 	if (ctx->fake_req_limit <= atomic_inc_return(&qp_ctx->pending_reqs))
672*416d8220SZaibo Xu 		req->fake_busy = 1;
673*416d8220SZaibo Xu 	else
674*416d8220SZaibo Xu 		req->fake_busy = 0;
675*416d8220SZaibo Xu 
676*416d8220SZaibo Xu 	ret = ctx->req_op->get_res(ctx, req);
677*416d8220SZaibo Xu 	if (ret) {
678*416d8220SZaibo Xu 		atomic_dec(&qp_ctx->pending_reqs);
679*416d8220SZaibo Xu 		sec_request_uninit(ctx, req);
680*416d8220SZaibo Xu 		dev_err(SEC_CTX_DEV(ctx), "get resources failed!\n");
681*416d8220SZaibo Xu 	}
682*416d8220SZaibo Xu 
683*416d8220SZaibo Xu 	return ret;
684*416d8220SZaibo Xu }
685*416d8220SZaibo Xu 
686*416d8220SZaibo Xu static int sec_process(struct sec_ctx *ctx, struct sec_req *req)
687*416d8220SZaibo Xu {
688*416d8220SZaibo Xu 	int ret;
689*416d8220SZaibo Xu 
690*416d8220SZaibo Xu 	ret = sec_request_init(ctx, req);
691*416d8220SZaibo Xu 	if (ret)
692*416d8220SZaibo Xu 		return ret;
693*416d8220SZaibo Xu 
694*416d8220SZaibo Xu 	ret = sec_request_transfer(ctx, req);
695*416d8220SZaibo Xu 	if (ret)
696*416d8220SZaibo Xu 		goto err_uninit_req;
697*416d8220SZaibo Xu 
698*416d8220SZaibo Xu 	/* Output IV as decrypto */
699*416d8220SZaibo Xu 	if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && !req->c_req.encrypt)
700*416d8220SZaibo Xu 		sec_update_iv(req);
701*416d8220SZaibo Xu 
702*416d8220SZaibo Xu 	ret = ctx->req_op->bd_send(ctx, req);
703*416d8220SZaibo Xu 	if (ret != -EBUSY && ret != -EINPROGRESS) {
704*416d8220SZaibo Xu 		dev_err(SEC_CTX_DEV(ctx), "send sec request failed!\n");
705*416d8220SZaibo Xu 		goto err_send_req;
706*416d8220SZaibo Xu 	}
707*416d8220SZaibo Xu 
708*416d8220SZaibo Xu 	return ret;
709*416d8220SZaibo Xu 
710*416d8220SZaibo Xu err_send_req:
711*416d8220SZaibo Xu 	/* As failing, restore the IV from user */
712*416d8220SZaibo Xu 	if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && !req->c_req.encrypt)
713*416d8220SZaibo Xu 		memcpy(req->c_req.sk_req->iv, req->c_req.c_ivin,
714*416d8220SZaibo Xu 		       ctx->c_ctx.ivsize);
715*416d8220SZaibo Xu 
716*416d8220SZaibo Xu 	sec_request_untransfer(ctx, req);
717*416d8220SZaibo Xu err_uninit_req:
718*416d8220SZaibo Xu 	sec_request_uninit(ctx, req);
719*416d8220SZaibo Xu 
720*416d8220SZaibo Xu 	return ret;
721*416d8220SZaibo Xu }
722*416d8220SZaibo Xu 
723*416d8220SZaibo Xu static struct sec_req_op sec_req_ops_tbl = {
724*416d8220SZaibo Xu 	.get_res	= sec_skcipher_get_res,
725*416d8220SZaibo Xu 	.resource_alloc	= sec_skcipher_resource_alloc,
726*416d8220SZaibo Xu 	.resource_free	= sec_skcipher_resource_free,
727*416d8220SZaibo Xu 	.buf_map	= sec_skcipher_sgl_map,
728*416d8220SZaibo Xu 	.buf_unmap	= sec_skcipher_sgl_unmap,
729*416d8220SZaibo Xu 	.do_transfer	= sec_skcipher_copy_iv,
730*416d8220SZaibo Xu 	.bd_fill	= sec_skcipher_bd_fill,
731*416d8220SZaibo Xu 	.bd_send	= sec_bd_send,
732*416d8220SZaibo Xu 	.callback	= sec_skcipher_callback,
733*416d8220SZaibo Xu 	.process	= sec_process,
734*416d8220SZaibo Xu };
735*416d8220SZaibo Xu 
736*416d8220SZaibo Xu static int sec_skcipher_ctx_init(struct crypto_skcipher *tfm)
737*416d8220SZaibo Xu {
738*416d8220SZaibo Xu 	struct sec_ctx *ctx = crypto_skcipher_ctx(tfm);
739*416d8220SZaibo Xu 
740*416d8220SZaibo Xu 	ctx->req_op = &sec_req_ops_tbl;
741*416d8220SZaibo Xu 
742*416d8220SZaibo Xu 	return sec_skcipher_init(tfm);
743*416d8220SZaibo Xu }
744*416d8220SZaibo Xu 
745*416d8220SZaibo Xu static void sec_skcipher_ctx_exit(struct crypto_skcipher *tfm)
746*416d8220SZaibo Xu {
747*416d8220SZaibo Xu 	sec_skcipher_exit(tfm);
748*416d8220SZaibo Xu }
749*416d8220SZaibo Xu 
750*416d8220SZaibo Xu static int sec_skcipher_param_check(struct sec_ctx *ctx,
751*416d8220SZaibo Xu 				    struct skcipher_request *sk_req)
752*416d8220SZaibo Xu {
753*416d8220SZaibo Xu 	u8 c_alg = ctx->c_ctx.c_alg;
754*416d8220SZaibo Xu 	struct device *dev = SEC_CTX_DEV(ctx);
755*416d8220SZaibo Xu 
756*416d8220SZaibo Xu 	if (!sk_req->src || !sk_req->dst) {
757*416d8220SZaibo Xu 		dev_err(dev, "skcipher input param error!\n");
758*416d8220SZaibo Xu 		return -EINVAL;
759*416d8220SZaibo Xu 	}
760*416d8220SZaibo Xu 
761*416d8220SZaibo Xu 	if (c_alg == SEC_CALG_3DES) {
762*416d8220SZaibo Xu 		if (sk_req->cryptlen & (DES3_EDE_BLOCK_SIZE - 1)) {
763*416d8220SZaibo Xu 			dev_err(dev, "skcipher 3des input length error!\n");
764*416d8220SZaibo Xu 			return -EINVAL;
765*416d8220SZaibo Xu 		}
766*416d8220SZaibo Xu 		return 0;
767*416d8220SZaibo Xu 	} else if (c_alg == SEC_CALG_AES || c_alg == SEC_CALG_SM4) {
768*416d8220SZaibo Xu 		if (sk_req->cryptlen & (AES_BLOCK_SIZE - 1)) {
769*416d8220SZaibo Xu 			dev_err(dev, "skcipher aes input length error!\n");
770*416d8220SZaibo Xu 			return -EINVAL;
771*416d8220SZaibo Xu 		}
772*416d8220SZaibo Xu 		return 0;
773*416d8220SZaibo Xu 	}
774*416d8220SZaibo Xu 
775*416d8220SZaibo Xu 	dev_err(dev, "skcipher algorithm error!\n");
776*416d8220SZaibo Xu 	return -EINVAL;
777*416d8220SZaibo Xu }
778*416d8220SZaibo Xu 
779*416d8220SZaibo Xu static int sec_skcipher_crypto(struct skcipher_request *sk_req, bool encrypt)
780*416d8220SZaibo Xu {
781*416d8220SZaibo Xu 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(sk_req);
782*416d8220SZaibo Xu 	struct sec_req *req = skcipher_request_ctx(sk_req);
783*416d8220SZaibo Xu 	struct sec_ctx *ctx = crypto_skcipher_ctx(tfm);
784*416d8220SZaibo Xu 	int ret;
785*416d8220SZaibo Xu 
786*416d8220SZaibo Xu 	if (!sk_req->cryptlen)
787*416d8220SZaibo Xu 		return 0;
788*416d8220SZaibo Xu 
789*416d8220SZaibo Xu 	ret = sec_skcipher_param_check(ctx, sk_req);
790*416d8220SZaibo Xu 	if (ret)
791*416d8220SZaibo Xu 		return ret;
792*416d8220SZaibo Xu 
793*416d8220SZaibo Xu 	req->c_req.sk_req = sk_req;
794*416d8220SZaibo Xu 	req->c_req.encrypt = encrypt;
795*416d8220SZaibo Xu 	req->ctx = ctx;
796*416d8220SZaibo Xu 
797*416d8220SZaibo Xu 	return ctx->req_op->process(ctx, req);
798*416d8220SZaibo Xu }
799*416d8220SZaibo Xu 
800*416d8220SZaibo Xu static int sec_skcipher_encrypt(struct skcipher_request *sk_req)
801*416d8220SZaibo Xu {
802*416d8220SZaibo Xu 	return sec_skcipher_crypto(sk_req, true);
803*416d8220SZaibo Xu }
804*416d8220SZaibo Xu 
805*416d8220SZaibo Xu static int sec_skcipher_decrypt(struct skcipher_request *sk_req)
806*416d8220SZaibo Xu {
807*416d8220SZaibo Xu 	return sec_skcipher_crypto(sk_req, false);
808*416d8220SZaibo Xu }
809*416d8220SZaibo Xu 
810*416d8220SZaibo Xu #define SEC_SKCIPHER_GEN_ALG(sec_cra_name, sec_set_key, sec_min_key_size, \
811*416d8220SZaibo Xu 	sec_max_key_size, ctx_init, ctx_exit, blk_size, iv_size)\
812*416d8220SZaibo Xu {\
813*416d8220SZaibo Xu 	.base = {\
814*416d8220SZaibo Xu 		.cra_name = sec_cra_name,\
815*416d8220SZaibo Xu 		.cra_driver_name = "hisi_sec_"sec_cra_name,\
816*416d8220SZaibo Xu 		.cra_priority = SEC_PRIORITY,\
817*416d8220SZaibo Xu 		.cra_flags = CRYPTO_ALG_ASYNC,\
818*416d8220SZaibo Xu 		.cra_blocksize = blk_size,\
819*416d8220SZaibo Xu 		.cra_ctxsize = sizeof(struct sec_ctx),\
820*416d8220SZaibo Xu 		.cra_module = THIS_MODULE,\
821*416d8220SZaibo Xu 	},\
822*416d8220SZaibo Xu 	.init = ctx_init,\
823*416d8220SZaibo Xu 	.exit = ctx_exit,\
824*416d8220SZaibo Xu 	.setkey = sec_set_key,\
825*416d8220SZaibo Xu 	.decrypt = sec_skcipher_decrypt,\
826*416d8220SZaibo Xu 	.encrypt = sec_skcipher_encrypt,\
827*416d8220SZaibo Xu 	.min_keysize = sec_min_key_size,\
828*416d8220SZaibo Xu 	.max_keysize = sec_max_key_size,\
829*416d8220SZaibo Xu 	.ivsize = iv_size,\
830*416d8220SZaibo Xu },
831*416d8220SZaibo Xu 
832*416d8220SZaibo Xu #define SEC_SKCIPHER_ALG(name, key_func, min_key_size, \
833*416d8220SZaibo Xu 	max_key_size, blk_size, iv_size) \
834*416d8220SZaibo Xu 	SEC_SKCIPHER_GEN_ALG(name, key_func, min_key_size, max_key_size, \
835*416d8220SZaibo Xu 	sec_skcipher_ctx_init, sec_skcipher_ctx_exit, blk_size, iv_size)
836*416d8220SZaibo Xu 
837*416d8220SZaibo Xu static struct skcipher_alg sec_algs[] = {
838*416d8220SZaibo Xu 	SEC_SKCIPHER_ALG("ecb(aes)", sec_setkey_aes_ecb,
839*416d8220SZaibo Xu 			 AES_MIN_KEY_SIZE, AES_MAX_KEY_SIZE,
840*416d8220SZaibo Xu 			 AES_BLOCK_SIZE, 0)
841*416d8220SZaibo Xu 
842*416d8220SZaibo Xu 	SEC_SKCIPHER_ALG("cbc(aes)", sec_setkey_aes_cbc,
843*416d8220SZaibo Xu 			 AES_MIN_KEY_SIZE, AES_MAX_KEY_SIZE,
844*416d8220SZaibo Xu 			 AES_BLOCK_SIZE, AES_BLOCK_SIZE)
845*416d8220SZaibo Xu 
846*416d8220SZaibo Xu 	SEC_SKCIPHER_ALG("xts(aes)", sec_setkey_aes_xts,
847*416d8220SZaibo Xu 			 SEC_XTS_MIN_KEY_SIZE, SEC_XTS_MAX_KEY_SIZE,
848*416d8220SZaibo Xu 			 AES_BLOCK_SIZE, AES_BLOCK_SIZE)
849*416d8220SZaibo Xu 
850*416d8220SZaibo Xu 	SEC_SKCIPHER_ALG("ecb(des3_ede)", sec_setkey_3des_ecb,
851*416d8220SZaibo Xu 			 SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE,
852*416d8220SZaibo Xu 			 DES3_EDE_BLOCK_SIZE, 0)
853*416d8220SZaibo Xu 
854*416d8220SZaibo Xu 	SEC_SKCIPHER_ALG("cbc(des3_ede)", sec_setkey_3des_cbc,
855*416d8220SZaibo Xu 			 SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE,
856*416d8220SZaibo Xu 			 DES3_EDE_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE)
857*416d8220SZaibo Xu 
858*416d8220SZaibo Xu 	SEC_SKCIPHER_ALG("xts(sm4)", sec_setkey_sm4_xts,
859*416d8220SZaibo Xu 			 SEC_XTS_MIN_KEY_SIZE, SEC_XTS_MIN_KEY_SIZE,
860*416d8220SZaibo Xu 			 AES_BLOCK_SIZE, AES_BLOCK_SIZE)
861*416d8220SZaibo Xu 
862*416d8220SZaibo Xu 	SEC_SKCIPHER_ALG("cbc(sm4)", sec_setkey_sm4_cbc,
863*416d8220SZaibo Xu 			 AES_MIN_KEY_SIZE, AES_MIN_KEY_SIZE,
864*416d8220SZaibo Xu 			 AES_BLOCK_SIZE, AES_BLOCK_SIZE)
865*416d8220SZaibo Xu };
866*416d8220SZaibo Xu 
867*416d8220SZaibo Xu int sec_register_to_crypto(void)
868*416d8220SZaibo Xu {
869*416d8220SZaibo Xu 	int ret = 0;
870*416d8220SZaibo Xu 
871*416d8220SZaibo Xu 	/* To avoid repeat register */
872*416d8220SZaibo Xu 	mutex_lock(&sec_algs_lock);
873*416d8220SZaibo Xu 	if (++sec_active_devs == 1)
874*416d8220SZaibo Xu 		ret = crypto_register_skciphers(sec_algs, ARRAY_SIZE(sec_algs));
875*416d8220SZaibo Xu 	mutex_unlock(&sec_algs_lock);
876*416d8220SZaibo Xu 
877*416d8220SZaibo Xu 	return ret;
878*416d8220SZaibo Xu }
879*416d8220SZaibo Xu 
880*416d8220SZaibo Xu void sec_unregister_from_crypto(void)
881*416d8220SZaibo Xu {
882*416d8220SZaibo Xu 	mutex_lock(&sec_algs_lock);
883*416d8220SZaibo Xu 	if (--sec_active_devs == 0)
884*416d8220SZaibo Xu 		crypto_unregister_skciphers(sec_algs, ARRAY_SIZE(sec_algs));
885*416d8220SZaibo Xu 	mutex_unlock(&sec_algs_lock);
886*416d8220SZaibo Xu }
887