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