]> Git Repo - linux.git/blob - drivers/crypto/starfive/jh7110-rsa.c
Merge patch series "riscv: Extension parsing fixes"
[linux.git] / drivers / crypto / starfive / jh7110-rsa.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * StarFive Public Key Algo acceleration driver
4  *
5  * Copyright (c) 2022 StarFive Technology
6  */
7
8 #include <linux/crypto.h>
9 #include <linux/iopoll.h>
10 #include <crypto/akcipher.h>
11 #include <crypto/algapi.h>
12 #include <crypto/internal/akcipher.h>
13 #include <crypto/internal/rsa.h>
14 #include <crypto/scatterwalk.h>
15
16 #include "jh7110-cryp.h"
17
18 #define STARFIVE_PKA_REGS_OFFSET        0x400
19 #define STARFIVE_PKA_CACR_OFFSET        (STARFIVE_PKA_REGS_OFFSET + 0x0)
20 #define STARFIVE_PKA_CASR_OFFSET        (STARFIVE_PKA_REGS_OFFSET + 0x4)
21 #define STARFIVE_PKA_CAAR_OFFSET        (STARFIVE_PKA_REGS_OFFSET + 0x8)
22 #define STARFIVE_PKA_CAER_OFFSET        (STARFIVE_PKA_REGS_OFFSET + 0x108)
23 #define STARFIVE_PKA_CANR_OFFSET        (STARFIVE_PKA_REGS_OFFSET + 0x208)
24
25 /* R ^ 2 mod N and N0' */
26 #define CRYPTO_CMD_PRE                  0x0
27 /* A * R mod N   ==> A */
28 #define CRYPTO_CMD_ARN                  0x5
29 /* A * E * R mod N ==> A */
30 #define CRYPTO_CMD_AERN                 0x6
31 /* A * A * R mod N ==> A */
32 #define CRYPTO_CMD_AARN                 0x7
33
34 #define STARFIVE_RSA_MAX_KEYSZ          256
35 #define STARFIVE_RSA_RESET              0x2
36
37 static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx)
38 {
39         struct starfive_cryp_dev *cryp = ctx->cryp;
40         u32 status;
41
42         return readl_relaxed_poll_timeout(cryp->base + STARFIVE_PKA_CASR_OFFSET, status,
43                                           status & STARFIVE_PKA_DONE, 10, 100000);
44 }
45
46 static void starfive_rsa_free_key(struct starfive_rsa_key *key)
47 {
48         if (!key->key_sz)
49                 return;
50
51         kfree_sensitive(key->d);
52         kfree_sensitive(key->e);
53         kfree_sensitive(key->n);
54         memset(key, 0, sizeof(*key));
55 }
56
57 static unsigned int starfive_rsa_get_nbit(u8 *pa, u32 snum, int key_sz)
58 {
59         u32 i;
60         u8 value;
61
62         i = snum >> 3;
63
64         value = pa[key_sz - i - 1];
65         value >>= snum & 0x7;
66         value &= 0x1;
67
68         return value;
69 }
70
71 static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx,
72                                         u32 *out, u32 *in, u8 mont,
73                                         u32 *mod, int bit_len)
74 {
75         struct starfive_cryp_dev *cryp = ctx->cryp;
76         struct starfive_cryp_request_ctx *rctx = ctx->rctx;
77         int count = rctx->total / sizeof(u32) - 1;
78         int loop;
79         u32 temp;
80         u8 opsize;
81
82         opsize = (bit_len - 1) >> 5;
83         rctx->csr.pka.v = 0;
84
85         writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
86
87         for (loop = 0; loop <= opsize; loop++)
88                 writel(mod[opsize - loop], cryp->base + STARFIVE_PKA_CANR_OFFSET + loop * 4);
89
90         if (mont) {
91                 rctx->csr.pka.v = 0;
92                 rctx->csr.pka.cln_done = 1;
93                 rctx->csr.pka.opsize = opsize;
94                 rctx->csr.pka.exposize = opsize;
95                 rctx->csr.pka.cmd = CRYPTO_CMD_PRE;
96                 rctx->csr.pka.start = 1;
97                 rctx->csr.pka.not_r2 = 1;
98                 rctx->csr.pka.ie = 1;
99
100                 writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
101
102                 if (starfive_pka_wait_done(ctx))
103                         return -ETIMEDOUT;
104
105                 for (loop = 0; loop <= opsize; loop++)
106                         writel(in[opsize - loop], cryp->base + STARFIVE_PKA_CAAR_OFFSET + loop * 4);
107
108                 writel(0x1000000, cryp->base + STARFIVE_PKA_CAER_OFFSET);
109
110                 for (loop = 1; loop <= opsize; loop++)
111                         writel(0, cryp->base + STARFIVE_PKA_CAER_OFFSET + loop * 4);
112
113                 rctx->csr.pka.v = 0;
114                 rctx->csr.pka.cln_done = 1;
115                 rctx->csr.pka.opsize = opsize;
116                 rctx->csr.pka.exposize = opsize;
117                 rctx->csr.pka.cmd = CRYPTO_CMD_AERN;
118                 rctx->csr.pka.start = 1;
119                 rctx->csr.pka.ie = 1;
120
121                 writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
122
123                 if (starfive_pka_wait_done(ctx))
124                         return -ETIMEDOUT;
125         } else {
126                 rctx->csr.pka.v = 0;
127                 rctx->csr.pka.cln_done = 1;
128                 rctx->csr.pka.opsize = opsize;
129                 rctx->csr.pka.exposize = opsize;
130                 rctx->csr.pka.cmd = CRYPTO_CMD_PRE;
131                 rctx->csr.pka.start = 1;
132                 rctx->csr.pka.pre_expf = 1;
133                 rctx->csr.pka.ie = 1;
134
135                 writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
136
137                 if (starfive_pka_wait_done(ctx))
138                         return -ETIMEDOUT;
139
140                 for (loop = 0; loop <= count; loop++)
141                         writel(in[count - loop], cryp->base + STARFIVE_PKA_CAER_OFFSET + loop * 4);
142
143                 /*pad with 0 up to opsize*/
144                 for (loop = count + 1; loop <= opsize; loop++)
145                         writel(0, cryp->base + STARFIVE_PKA_CAER_OFFSET + loop * 4);
146
147                 rctx->csr.pka.v = 0;
148                 rctx->csr.pka.cln_done = 1;
149                 rctx->csr.pka.opsize = opsize;
150                 rctx->csr.pka.exposize = opsize;
151                 rctx->csr.pka.cmd = CRYPTO_CMD_ARN;
152                 rctx->csr.pka.start = 1;
153                 rctx->csr.pka.ie = 1;
154
155                 writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
156
157                 if (starfive_pka_wait_done(ctx))
158                         return -ETIMEDOUT;
159         }
160
161         for (loop = 0; loop <= opsize; loop++) {
162                 temp = readl(cryp->base + STARFIVE_PKA_CAAR_OFFSET + 0x4 * loop);
163                 out[opsize - loop] = temp;
164         }
165
166         return 0;
167 }
168
169 static int starfive_rsa_cpu_start(struct starfive_cryp_ctx *ctx, u32 *result,
170                                   u8 *de, u32 *n, int key_sz)
171 {
172         struct starfive_cryp_dev *cryp = ctx->cryp;
173         struct starfive_cryp_request_ctx *rctx = ctx->rctx;
174         struct starfive_rsa_key *key = &ctx->rsa_key;
175         u32 temp;
176         int ret = 0;
177         int opsize, mlen, loop;
178         unsigned int *mta;
179
180         opsize = (key_sz - 1) >> 2;
181
182         mta = kmalloc(key_sz, GFP_KERNEL);
183         if (!mta)
184                 return -ENOMEM;
185
186         ret = starfive_rsa_montgomery_form(ctx, mta, (u32 *)rctx->rsa_data,
187                                            0, n, key_sz << 3);
188         if (ret) {
189                 dev_err_probe(cryp->dev, ret, "Conversion to Montgomery failed");
190                 goto rsa_err;
191         }
192
193         for (loop = 0; loop <= opsize; loop++)
194                 writel(mta[opsize - loop],
195                        cryp->base + STARFIVE_PKA_CAER_OFFSET + loop * 4);
196
197         for (loop = key->bitlen - 1; loop > 0; loop--) {
198                 mlen = starfive_rsa_get_nbit(de, loop - 1, key_sz);
199
200                 rctx->csr.pka.v = 0;
201                 rctx->csr.pka.cln_done = 1;
202                 rctx->csr.pka.opsize = opsize;
203                 rctx->csr.pka.exposize = opsize;
204                 rctx->csr.pka.cmd = CRYPTO_CMD_AARN;
205                 rctx->csr.pka.start = 1;
206                 rctx->csr.pka.ie = 1;
207
208                 writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
209
210                 ret = -ETIMEDOUT;
211                 if (starfive_pka_wait_done(ctx))
212                         goto rsa_err;
213
214                 if (mlen) {
215                         rctx->csr.pka.v = 0;
216                         rctx->csr.pka.cln_done = 1;
217                         rctx->csr.pka.opsize = opsize;
218                         rctx->csr.pka.exposize = opsize;
219                         rctx->csr.pka.cmd = CRYPTO_CMD_AERN;
220                         rctx->csr.pka.start = 1;
221                         rctx->csr.pka.ie = 1;
222
223                         writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
224
225                         if (starfive_pka_wait_done(ctx))
226                                 goto rsa_err;
227                 }
228         }
229
230         for (loop = 0; loop <= opsize; loop++) {
231                 temp = readl(cryp->base + STARFIVE_PKA_CAAR_OFFSET + 0x4 * loop);
232                 result[opsize - loop] = temp;
233         }
234
235         ret = starfive_rsa_montgomery_form(ctx, result, result, 1, n, key_sz << 3);
236         if (ret)
237                 dev_err_probe(cryp->dev, ret, "Conversion from Montgomery failed");
238 rsa_err:
239         kfree(mta);
240         return ret;
241 }
242
243 static int starfive_rsa_start(struct starfive_cryp_ctx *ctx, u8 *result,
244                               u8 *de, u8 *n, int key_sz)
245 {
246         return starfive_rsa_cpu_start(ctx, (u32 *)result, de, (u32 *)n, key_sz);
247 }
248
249 static int starfive_rsa_enc_core(struct starfive_cryp_ctx *ctx, int enc)
250 {
251         struct starfive_cryp_dev *cryp = ctx->cryp;
252         struct starfive_cryp_request_ctx *rctx = ctx->rctx;
253         struct starfive_rsa_key *key = &ctx->rsa_key;
254         int ret = 0;
255
256         writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET);
257
258         rctx->total = sg_copy_to_buffer(rctx->in_sg, rctx->nents,
259                                         rctx->rsa_data, rctx->total);
260
261         if (enc) {
262                 key->bitlen = key->e_bitlen;
263                 ret = starfive_rsa_start(ctx, rctx->rsa_data, key->e,
264                                          key->n, key->key_sz);
265         } else {
266                 key->bitlen = key->d_bitlen;
267                 ret = starfive_rsa_start(ctx, rctx->rsa_data, key->d,
268                                          key->n, key->key_sz);
269         }
270
271         if (ret)
272                 goto err_rsa_crypt;
273
274         sg_copy_buffer(rctx->out_sg, sg_nents(rctx->out_sg),
275                        rctx->rsa_data, key->key_sz, 0, 0);
276
277 err_rsa_crypt:
278         writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET);
279         return ret;
280 }
281
282 static int starfive_rsa_enc(struct akcipher_request *req)
283 {
284         struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
285         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
286         struct starfive_cryp_dev *cryp = ctx->cryp;
287         struct starfive_rsa_key *key = &ctx->rsa_key;
288         struct starfive_cryp_request_ctx *rctx = akcipher_request_ctx(req);
289         int ret;
290
291         if (!key->key_sz) {
292                 akcipher_request_set_tfm(req, ctx->akcipher_fbk);
293                 ret = crypto_akcipher_encrypt(req);
294                 akcipher_request_set_tfm(req, tfm);
295                 return ret;
296         }
297
298         if (unlikely(!key->n || !key->e))
299                 return -EINVAL;
300
301         if (req->dst_len < key->key_sz)
302                 return dev_err_probe(cryp->dev, -EOVERFLOW,
303                                      "Output buffer length less than parameter n\n");
304
305         rctx->in_sg = req->src;
306         rctx->out_sg = req->dst;
307         rctx->total = req->src_len;
308         rctx->nents = sg_nents(rctx->in_sg);
309         ctx->rctx = rctx;
310
311         return starfive_rsa_enc_core(ctx, 1);
312 }
313
314 static int starfive_rsa_dec(struct akcipher_request *req)
315 {
316         struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
317         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
318         struct starfive_cryp_dev *cryp = ctx->cryp;
319         struct starfive_rsa_key *key = &ctx->rsa_key;
320         struct starfive_cryp_request_ctx *rctx = akcipher_request_ctx(req);
321         int ret;
322
323         if (!key->key_sz) {
324                 akcipher_request_set_tfm(req, ctx->akcipher_fbk);
325                 ret = crypto_akcipher_decrypt(req);
326                 akcipher_request_set_tfm(req, tfm);
327                 return ret;
328         }
329
330         if (unlikely(!key->n || !key->d))
331                 return -EINVAL;
332
333         if (req->dst_len < key->key_sz)
334                 return dev_err_probe(cryp->dev, -EOVERFLOW,
335                                      "Output buffer length less than parameter n\n");
336
337         rctx->in_sg = req->src;
338         rctx->out_sg = req->dst;
339         ctx->rctx = rctx;
340         rctx->total = req->src_len;
341
342         return starfive_rsa_enc_core(ctx, 0);
343 }
344
345 static int starfive_rsa_set_n(struct starfive_rsa_key *rsa_key,
346                               const char *value, size_t vlen)
347 {
348         const char *ptr = value;
349         unsigned int bitslen;
350         int ret;
351
352         while (!*ptr && vlen) {
353                 ptr++;
354                 vlen--;
355         }
356         rsa_key->key_sz = vlen;
357         bitslen = rsa_key->key_sz << 3;
358
359         /* check valid key size */
360         if (bitslen & 0x1f)
361                 return -EINVAL;
362
363         ret = -ENOMEM;
364         rsa_key->n = kmemdup(ptr, rsa_key->key_sz, GFP_KERNEL);
365         if (!rsa_key->n)
366                 goto err;
367
368         return 0;
369  err:
370         rsa_key->key_sz = 0;
371         rsa_key->n = NULL;
372         starfive_rsa_free_key(rsa_key);
373         return ret;
374 }
375
376 static int starfive_rsa_set_e(struct starfive_rsa_key *rsa_key,
377                               const char *value, size_t vlen)
378 {
379         const char *ptr = value;
380         unsigned char pt;
381         int loop;
382
383         while (!*ptr && vlen) {
384                 ptr++;
385                 vlen--;
386         }
387         pt = *ptr;
388
389         if (!rsa_key->key_sz || !vlen || vlen > rsa_key->key_sz) {
390                 rsa_key->e = NULL;
391                 return -EINVAL;
392         }
393
394         rsa_key->e = kzalloc(rsa_key->key_sz, GFP_KERNEL);
395         if (!rsa_key->e)
396                 return -ENOMEM;
397
398         for (loop = 8; loop > 0; loop--) {
399                 if (pt >> (loop - 1))
400                         break;
401         }
402
403         rsa_key->e_bitlen = (vlen - 1) * 8 + loop;
404
405         memcpy(rsa_key->e + (rsa_key->key_sz - vlen), ptr, vlen);
406
407         return 0;
408 }
409
410 static int starfive_rsa_set_d(struct starfive_rsa_key *rsa_key,
411                               const char *value, size_t vlen)
412 {
413         const char *ptr = value;
414         unsigned char pt;
415         int loop;
416         int ret;
417
418         while (!*ptr && vlen) {
419                 ptr++;
420                 vlen--;
421         }
422         pt = *ptr;
423
424         ret = -EINVAL;
425         if (!rsa_key->key_sz || !vlen || vlen > rsa_key->key_sz)
426                 goto err;
427
428         ret = -ENOMEM;
429         rsa_key->d = kzalloc(rsa_key->key_sz, GFP_KERNEL);
430         if (!rsa_key->d)
431                 goto err;
432
433         for (loop = 8; loop > 0; loop--) {
434                 if (pt >> (loop - 1))
435                         break;
436         }
437
438         rsa_key->d_bitlen = (vlen - 1) * 8 + loop;
439
440         memcpy(rsa_key->d + (rsa_key->key_sz - vlen), ptr, vlen);
441
442         return 0;
443  err:
444         rsa_key->d = NULL;
445         return ret;
446 }
447
448 static int starfive_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
449                                unsigned int keylen, bool private)
450 {
451         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
452         struct rsa_key raw_key = {NULL};
453         struct starfive_rsa_key *rsa_key = &ctx->rsa_key;
454         int ret;
455
456         if (private)
457                 ret = rsa_parse_priv_key(&raw_key, key, keylen);
458         else
459                 ret = rsa_parse_pub_key(&raw_key, key, keylen);
460         if (ret < 0)
461                 goto err;
462
463         starfive_rsa_free_key(rsa_key);
464
465         /* Use fallback for mod > 256 + 1 byte prefix */
466         if (raw_key.n_sz > STARFIVE_RSA_MAX_KEYSZ + 1)
467                 return 0;
468
469         ret = starfive_rsa_set_n(rsa_key, raw_key.n, raw_key.n_sz);
470         if (ret)
471                 return ret;
472
473         ret = starfive_rsa_set_e(rsa_key, raw_key.e, raw_key.e_sz);
474         if (ret)
475                 goto err;
476
477         if (private) {
478                 ret = starfive_rsa_set_d(rsa_key, raw_key.d, raw_key.d_sz);
479                 if (ret)
480                         goto err;
481         }
482
483         if (!rsa_key->n || !rsa_key->e) {
484                 ret = -EINVAL;
485                 goto err;
486         }
487
488         if (private && !rsa_key->d) {
489                 ret = -EINVAL;
490                 goto err;
491         }
492
493         return 0;
494  err:
495         starfive_rsa_free_key(rsa_key);
496         return ret;
497 }
498
499 static int starfive_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
500                                     unsigned int keylen)
501 {
502         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
503         int ret;
504
505         ret = crypto_akcipher_set_pub_key(ctx->akcipher_fbk, key, keylen);
506         if (ret)
507                 return ret;
508
509         return starfive_rsa_setkey(tfm, key, keylen, false);
510 }
511
512 static int starfive_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
513                                      unsigned int keylen)
514 {
515         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
516         int ret;
517
518         ret = crypto_akcipher_set_priv_key(ctx->akcipher_fbk, key, keylen);
519         if (ret)
520                 return ret;
521
522         return starfive_rsa_setkey(tfm, key, keylen, true);
523 }
524
525 static unsigned int starfive_rsa_max_size(struct crypto_akcipher *tfm)
526 {
527         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
528
529         if (ctx->rsa_key.key_sz)
530                 return ctx->rsa_key.key_sz;
531
532         return crypto_akcipher_maxsize(ctx->akcipher_fbk);
533 }
534
535 static int starfive_rsa_init_tfm(struct crypto_akcipher *tfm)
536 {
537         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
538
539         ctx->cryp = starfive_cryp_find_dev(ctx);
540         if (!ctx->cryp)
541                 return -ENODEV;
542
543         ctx->akcipher_fbk = crypto_alloc_akcipher("rsa-generic", 0, 0);
544         if (IS_ERR(ctx->akcipher_fbk))
545                 return PTR_ERR(ctx->akcipher_fbk);
546
547         akcipher_set_reqsize(tfm, sizeof(struct starfive_cryp_request_ctx) +
548                              sizeof(struct crypto_akcipher) + 32);
549
550         return 0;
551 }
552
553 static void starfive_rsa_exit_tfm(struct crypto_akcipher *tfm)
554 {
555         struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
556         struct starfive_rsa_key *key = (struct starfive_rsa_key *)&ctx->rsa_key;
557
558         crypto_free_akcipher(ctx->akcipher_fbk);
559         starfive_rsa_free_key(key);
560 }
561
562 static struct akcipher_alg starfive_rsa = {
563         .encrypt = starfive_rsa_enc,
564         .decrypt = starfive_rsa_dec,
565         .sign = starfive_rsa_dec,
566         .verify = starfive_rsa_enc,
567         .set_pub_key = starfive_rsa_set_pub_key,
568         .set_priv_key = starfive_rsa_set_priv_key,
569         .max_size = starfive_rsa_max_size,
570         .init = starfive_rsa_init_tfm,
571         .exit = starfive_rsa_exit_tfm,
572         .base = {
573                 .cra_name = "rsa",
574                 .cra_driver_name = "starfive-rsa",
575                 .cra_flags = CRYPTO_ALG_TYPE_AKCIPHER |
576                              CRYPTO_ALG_NEED_FALLBACK,
577                 .cra_priority = 3000,
578                 .cra_module = THIS_MODULE,
579                 .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
580         },
581 };
582
583 int starfive_rsa_register_algs(void)
584 {
585         return crypto_register_akcipher(&starfive_rsa);
586 }
587
588 void starfive_rsa_unregister_algs(void)
589 {
590         crypto_unregister_akcipher(&starfive_rsa);
591 }
This page took 0.067307 seconds and 4 git commands to generate.