xref: /OK3568_Linux_fs/kernel/drivers/crypto/rockchip/rk_crypto_v2_akcipher.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * RSA acceleration support for Rockchip crypto v2
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Lin Jinhan <troy.lin@rock-chips.com>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Some ideas are from marvell/cesa.c and s5p-sss.c driver.
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include "rk_crypto_core.h"
15*4882a593Smuzhiyun #include "rk_crypto_v2.h"
16*4882a593Smuzhiyun #include "rk_crypto_v2_reg.h"
17*4882a593Smuzhiyun #include "rk_crypto_v2_pka.h"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define BG_WORDS2BYTES(words)	((words) * sizeof(u32))
20*4882a593Smuzhiyun #define BG_BYTES2WORDS(bytes)	(((bytes) + sizeof(u32) - 1) / sizeof(u32))
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun static DEFINE_MUTEX(akcipher_mutex);
23*4882a593Smuzhiyun 
rk_rsa_adjust_rsa_key(struct rsa_key * key)24*4882a593Smuzhiyun static void rk_rsa_adjust_rsa_key(struct rsa_key *key)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	if (key->n_sz && key->n && !key->n[0]) {
27*4882a593Smuzhiyun 		key->n++;
28*4882a593Smuzhiyun 		key->n_sz--;
29*4882a593Smuzhiyun 	}
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	if (key->e_sz && key->e && !key->e[0]) {
32*4882a593Smuzhiyun 		key->e++;
33*4882a593Smuzhiyun 		key->e_sz--;
34*4882a593Smuzhiyun 	}
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	if (key->d_sz && key->d && !key->d[0]) {
37*4882a593Smuzhiyun 		key->d++;
38*4882a593Smuzhiyun 		key->d_sz--;
39*4882a593Smuzhiyun 	}
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun 
rk_rsa_clear_ctx(struct rk_rsa_ctx * ctx)42*4882a593Smuzhiyun static void rk_rsa_clear_ctx(struct rk_rsa_ctx *ctx)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun 	/* Free the old key if any */
45*4882a593Smuzhiyun 	rk_bn_free(ctx->n);
46*4882a593Smuzhiyun 	ctx->n = NULL;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	rk_bn_free(ctx->e);
49*4882a593Smuzhiyun 	ctx->e = NULL;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	rk_bn_free(ctx->d);
52*4882a593Smuzhiyun 	ctx->d = NULL;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
rk_rsa_setkey(struct crypto_akcipher * tfm,const void * key,unsigned int keylen,bool private)55*4882a593Smuzhiyun static int rk_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
56*4882a593Smuzhiyun 			 unsigned int keylen, bool private)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun 	struct rk_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
59*4882a593Smuzhiyun 	struct rsa_key rsa_key;
60*4882a593Smuzhiyun 	int ret = -ENOMEM;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	rk_rsa_clear_ctx(ctx);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	memset(&rsa_key, 0x00, sizeof(rsa_key));
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	if (private)
67*4882a593Smuzhiyun 		ret = rsa_parse_priv_key(&rsa_key, key, keylen);
68*4882a593Smuzhiyun 	else
69*4882a593Smuzhiyun 		ret = rsa_parse_pub_key(&rsa_key, key, keylen);
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	if (ret < 0)
72*4882a593Smuzhiyun 		goto error;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	rk_rsa_adjust_rsa_key(&rsa_key);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	ctx->n = rk_bn_alloc(rsa_key.n_sz);
77*4882a593Smuzhiyun 	if (!ctx->n)
78*4882a593Smuzhiyun 		goto error;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	ctx->e = rk_bn_alloc(rsa_key.e_sz);
81*4882a593Smuzhiyun 	if (!ctx->e)
82*4882a593Smuzhiyun 		goto error;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	rk_bn_set_data(ctx->n, rsa_key.n, rsa_key.n_sz, RK_BG_BIG_ENDIAN);
85*4882a593Smuzhiyun 	rk_bn_set_data(ctx->e, rsa_key.e, rsa_key.e_sz, RK_BG_BIG_ENDIAN);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	CRYPTO_DUMPHEX("n = ", ctx->n->data, BG_WORDS2BYTES(ctx->n->n_words));
88*4882a593Smuzhiyun 	CRYPTO_DUMPHEX("e = ", ctx->e->data, BG_WORDS2BYTES(ctx->e->n_words));
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	if (private) {
91*4882a593Smuzhiyun 		ctx->d = rk_bn_alloc(rsa_key.d_sz);
92*4882a593Smuzhiyun 		if (!ctx->d)
93*4882a593Smuzhiyun 			goto error;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 		rk_bn_set_data(ctx->d, rsa_key.d, rsa_key.d_sz, RK_BG_BIG_ENDIAN);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 		CRYPTO_DUMPHEX("d = ", ctx->d->data, BG_WORDS2BYTES(ctx->d->n_words));
98*4882a593Smuzhiyun 	}
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	return 0;
101*4882a593Smuzhiyun error:
102*4882a593Smuzhiyun 	rk_rsa_clear_ctx(ctx);
103*4882a593Smuzhiyun 	return ret;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
rk_rsa_max_size(struct crypto_akcipher * tfm)106*4882a593Smuzhiyun static unsigned int rk_rsa_max_size(struct crypto_akcipher *tfm)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	struct rk_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	CRYPTO_TRACE();
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	return rk_bn_get_size(ctx->n);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
rk_rsa_setpubkey(struct crypto_akcipher * tfm,const void * key,unsigned int keylen)115*4882a593Smuzhiyun static int rk_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key,
116*4882a593Smuzhiyun 			    unsigned int keylen)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	CRYPTO_TRACE();
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	return rk_rsa_setkey(tfm, key, keylen, false);
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
rk_rsa_setprivkey(struct crypto_akcipher * tfm,const void * key,unsigned int keylen)123*4882a593Smuzhiyun static int rk_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key,
124*4882a593Smuzhiyun 			     unsigned int keylen)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun 	CRYPTO_TRACE();
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	return rk_rsa_setkey(tfm, key, keylen, true);
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
rk_rsa_calc(struct akcipher_request * req,bool encypt)131*4882a593Smuzhiyun static int rk_rsa_calc(struct akcipher_request *req, bool encypt)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
134*4882a593Smuzhiyun 	struct rk_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
135*4882a593Smuzhiyun 	struct rk_bignum *in = NULL, *out = NULL;
136*4882a593Smuzhiyun 	u32 key_byte_size;
137*4882a593Smuzhiyun 	u8 *tmp_buf = NULL;
138*4882a593Smuzhiyun 	int ret = -ENOMEM;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	CRYPTO_TRACE();
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	if (unlikely(!ctx->n || !ctx->e))
143*4882a593Smuzhiyun 		return -EINVAL;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	if (!encypt && !ctx->d)
146*4882a593Smuzhiyun 		return -EINVAL;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	key_byte_size = rk_bn_get_size(ctx->n);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	if (req->dst_len < key_byte_size) {
151*4882a593Smuzhiyun 		req->dst_len = key_byte_size;
152*4882a593Smuzhiyun 		return -EOVERFLOW;
153*4882a593Smuzhiyun 	}
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	if (req->src_len > key_byte_size)
156*4882a593Smuzhiyun 		return -EINVAL;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	in = rk_bn_alloc(key_byte_size);
159*4882a593Smuzhiyun 	if (!in)
160*4882a593Smuzhiyun 		goto exit;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	out = rk_bn_alloc(key_byte_size);
163*4882a593Smuzhiyun 	if (!out)
164*4882a593Smuzhiyun 		goto exit;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	tmp_buf = kzalloc(key_byte_size, GFP_KERNEL);
167*4882a593Smuzhiyun 	if (!tmp_buf)
168*4882a593Smuzhiyun 		goto exit;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	if (!sg_copy_to_buffer(req->src, sg_nents(req->src), tmp_buf, req->src_len)) {
171*4882a593Smuzhiyun 		dev_err(ctx->rk_dev->dev, "[%s:%d] sg copy err\n",
172*4882a593Smuzhiyun 			__func__, __LINE__);
173*4882a593Smuzhiyun 		ret =  -EINVAL;
174*4882a593Smuzhiyun 		goto exit;
175*4882a593Smuzhiyun 	}
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	ret = rk_bn_set_data(in, tmp_buf, req->src_len, RK_BG_BIG_ENDIAN);
178*4882a593Smuzhiyun 	if (ret)
179*4882a593Smuzhiyun 		goto exit;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	CRYPTO_DUMPHEX("in = ", in->data, BG_WORDS2BYTES(in->n_words));
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	mutex_lock(&akcipher_mutex);
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if (encypt)
186*4882a593Smuzhiyun 		ret = rk_pka_expt_mod(in, ctx->e, ctx->n, out);
187*4882a593Smuzhiyun 	else
188*4882a593Smuzhiyun 		ret = rk_pka_expt_mod(in, ctx->d, ctx->n, out);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	mutex_unlock(&akcipher_mutex);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	if (ret)
193*4882a593Smuzhiyun 		goto exit;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	CRYPTO_DUMPHEX("out = ", out->data, BG_WORDS2BYTES(out->n_words));
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	ret = rk_bn_get_data(out, tmp_buf, key_byte_size, RK_BG_BIG_ENDIAN);
198*4882a593Smuzhiyun 	if (ret)
199*4882a593Smuzhiyun 		goto exit;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	CRYPTO_DUMPHEX("tmp_buf = ", tmp_buf, key_byte_size);
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	if (!sg_copy_from_buffer(req->dst, sg_nents(req->dst), tmp_buf, key_byte_size)) {
204*4882a593Smuzhiyun 		dev_err(ctx->rk_dev->dev, "[%s:%d] sg copy err\n",
205*4882a593Smuzhiyun 			__func__, __LINE__);
206*4882a593Smuzhiyun 		ret =  -EINVAL;
207*4882a593Smuzhiyun 		goto exit;
208*4882a593Smuzhiyun 	}
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	req->dst_len = key_byte_size;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	CRYPTO_TRACE("ret = %d", ret);
213*4882a593Smuzhiyun exit:
214*4882a593Smuzhiyun 	kfree(tmp_buf);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	rk_bn_free(in);
217*4882a593Smuzhiyun 	rk_bn_free(out);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	return ret;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun 
rk_rsa_enc(struct akcipher_request * req)222*4882a593Smuzhiyun static int rk_rsa_enc(struct akcipher_request *req)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun 	CRYPTO_TRACE();
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	return rk_rsa_calc(req, true);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun 
rk_rsa_dec(struct akcipher_request * req)229*4882a593Smuzhiyun static int rk_rsa_dec(struct akcipher_request *req)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun 	CRYPTO_TRACE();
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	return rk_rsa_calc(req, false);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
rk_rsa_start(struct rk_crypto_dev * rk_dev)236*4882a593Smuzhiyun static int rk_rsa_start(struct rk_crypto_dev *rk_dev)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	CRYPTO_TRACE();
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	return -ENOSYS;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
rk_rsa_crypto_rx(struct rk_crypto_dev * rk_dev)243*4882a593Smuzhiyun static int rk_rsa_crypto_rx(struct rk_crypto_dev *rk_dev)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	CRYPTO_TRACE();
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	return -ENOSYS;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun 
rk_rsa_complete(struct crypto_async_request * base,int err)250*4882a593Smuzhiyun static void rk_rsa_complete(struct crypto_async_request *base, int err)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	if (base->complete)
253*4882a593Smuzhiyun 		base->complete(base, err);
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
rk_rsa_init_tfm(struct crypto_akcipher * tfm)256*4882a593Smuzhiyun static int rk_rsa_init_tfm(struct crypto_akcipher *tfm)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	struct rk_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
259*4882a593Smuzhiyun 	struct akcipher_alg *alg = __crypto_akcipher_alg(tfm->base.__crt_alg);
260*4882a593Smuzhiyun 	struct rk_crypto_algt *algt;
261*4882a593Smuzhiyun 	struct rk_crypto_dev *rk_dev;
262*4882a593Smuzhiyun 	struct rk_alg_ctx *alg_ctx = &ctx->algs_ctx;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	CRYPTO_TRACE();
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	memset(ctx, 0x00, sizeof(*ctx));
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	algt = container_of(alg, struct rk_crypto_algt, alg.asym);
269*4882a593Smuzhiyun 	rk_dev = algt->rk_dev;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	if (!rk_dev->request_crypto)
272*4882a593Smuzhiyun 		return -EFAULT;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	rk_dev->request_crypto(rk_dev, "rsa");
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	alg_ctx->align_size     = crypto_tfm_alg_alignmask(&tfm->base) + 1;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	alg_ctx->ops.start      = rk_rsa_start;
279*4882a593Smuzhiyun 	alg_ctx->ops.update     = rk_rsa_crypto_rx;
280*4882a593Smuzhiyun 	alg_ctx->ops.complete   = rk_rsa_complete;
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	ctx->rk_dev = rk_dev;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	rk_pka_set_crypto_base(ctx->rk_dev->pka_reg);
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	return 0;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
rk_rsa_exit_tfm(struct crypto_akcipher * tfm)289*4882a593Smuzhiyun static void rk_rsa_exit_tfm(struct crypto_akcipher *tfm)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	struct rk_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	CRYPTO_TRACE();
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	rk_rsa_clear_ctx(ctx);
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	ctx->rk_dev->release_crypto(ctx->rk_dev, "rsa");
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun struct rk_crypto_algt rk_v2_asym_rsa = {
301*4882a593Smuzhiyun 	.name = "rsa",
302*4882a593Smuzhiyun 	.type = ALG_TYPE_ASYM,
303*4882a593Smuzhiyun 	.alg.asym = {
304*4882a593Smuzhiyun 		.encrypt = rk_rsa_enc,
305*4882a593Smuzhiyun 		.decrypt = rk_rsa_dec,
306*4882a593Smuzhiyun 		.set_pub_key = rk_rsa_setpubkey,
307*4882a593Smuzhiyun 		.set_priv_key = rk_rsa_setprivkey,
308*4882a593Smuzhiyun 		.max_size = rk_rsa_max_size,
309*4882a593Smuzhiyun 		.init = rk_rsa_init_tfm,
310*4882a593Smuzhiyun 		.exit = rk_rsa_exit_tfm,
311*4882a593Smuzhiyun 		.reqsize = 64,
312*4882a593Smuzhiyun 		.base = {
313*4882a593Smuzhiyun 			.cra_name = "rsa",
314*4882a593Smuzhiyun 			.cra_driver_name = "rsa-rk",
315*4882a593Smuzhiyun 			.cra_priority = RK_CRYPTO_PRIORITY,
316*4882a593Smuzhiyun 			.cra_module = THIS_MODULE,
317*4882a593Smuzhiyun 			.cra_ctxsize = sizeof(struct rk_rsa_ctx),
318*4882a593Smuzhiyun 		},
319*4882a593Smuzhiyun 	},
320*4882a593Smuzhiyun };
321*4882a593Smuzhiyun 
322