1 // SPDX-License-Identifier: GPL-2.0
3 * StarFive Public Key Algo acceleration driver
5 * Copyright (c) 2022 StarFive Technology
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>
16 #include "jh7110-cryp.h"
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)
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
34 #define STARFIVE_RSA_RESET 0x2
36 static inline int starfive_pka_wait_done(struct starfive_cryp_ctx
*ctx
)
38 struct starfive_cryp_dev
*cryp
= ctx
->cryp
;
41 return readl_relaxed_poll_timeout(cryp
->base
+ STARFIVE_PKA_CASR_OFFSET
, status
,
42 status
& STARFIVE_PKA_DONE
, 10, 100000);
45 static void starfive_rsa_free_key(struct starfive_rsa_key
*key
)
50 kfree_sensitive(key
->d
);
51 kfree_sensitive(key
->e
);
52 kfree_sensitive(key
->n
);
53 memset(key
, 0, sizeof(*key
));
56 static unsigned int starfive_rsa_get_nbit(u8
*pa
, u32 snum
, int key_sz
)
63 value
= pa
[key_sz
- i
- 1];
70 static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx
*ctx
,
71 u32
*out
, u32
*in
, u8 mont
,
72 u32
*mod
, int bit_len
)
74 struct starfive_cryp_dev
*cryp
= ctx
->cryp
;
75 struct starfive_cryp_request_ctx
*rctx
= ctx
->rctx
;
76 int count
= (ALIGN(rctx
->total
, 4) / 4) - 1;
81 opsize
= (bit_len
- 1) >> 5;
84 writel(rctx
->csr
.pka
.v
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
86 for (loop
= 0; loop
<= opsize
; loop
++)
87 writel(mod
[opsize
- loop
], cryp
->base
+ STARFIVE_PKA_CANR_OFFSET
+ loop
* 4);
91 rctx
->csr
.pka
.cln_done
= 1;
92 rctx
->csr
.pka
.opsize
= opsize
;
93 rctx
->csr
.pka
.exposize
= opsize
;
94 rctx
->csr
.pka
.cmd
= CRYPTO_CMD_PRE
;
95 rctx
->csr
.pka
.start
= 1;
96 rctx
->csr
.pka
.not_r2
= 1;
99 writel(rctx
->csr
.pka
.v
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
101 if (starfive_pka_wait_done(ctx
))
104 for (loop
= 0; loop
<= opsize
; loop
++)
105 writel(in
[opsize
- loop
], cryp
->base
+ STARFIVE_PKA_CAAR_OFFSET
+ loop
* 4);
107 writel(0x1000000, cryp
->base
+ STARFIVE_PKA_CAER_OFFSET
);
109 for (loop
= 1; loop
<= opsize
; loop
++)
110 writel(0, cryp
->base
+ STARFIVE_PKA_CAER_OFFSET
+ loop
* 4);
113 rctx
->csr
.pka
.cln_done
= 1;
114 rctx
->csr
.pka
.opsize
= opsize
;
115 rctx
->csr
.pka
.exposize
= opsize
;
116 rctx
->csr
.pka
.cmd
= CRYPTO_CMD_AERN
;
117 rctx
->csr
.pka
.start
= 1;
118 rctx
->csr
.pka
.ie
= 1;
120 writel(rctx
->csr
.pka
.v
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
122 if (starfive_pka_wait_done(ctx
))
126 rctx
->csr
.pka
.cln_done
= 1;
127 rctx
->csr
.pka
.opsize
= opsize
;
128 rctx
->csr
.pka
.exposize
= opsize
;
129 rctx
->csr
.pka
.cmd
= CRYPTO_CMD_PRE
;
130 rctx
->csr
.pka
.start
= 1;
131 rctx
->csr
.pka
.pre_expf
= 1;
132 rctx
->csr
.pka
.ie
= 1;
134 writel(rctx
->csr
.pka
.v
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
136 if (starfive_pka_wait_done(ctx
))
139 for (loop
= 0; loop
<= count
; loop
++)
140 writel(in
[count
- loop
], cryp
->base
+ STARFIVE_PKA_CAER_OFFSET
+ loop
* 4);
142 /*pad with 0 up to opsize*/
143 for (loop
= count
+ 1; loop
<= opsize
; loop
++)
144 writel(0, cryp
->base
+ STARFIVE_PKA_CAER_OFFSET
+ loop
* 4);
147 rctx
->csr
.pka
.cln_done
= 1;
148 rctx
->csr
.pka
.opsize
= opsize
;
149 rctx
->csr
.pka
.exposize
= opsize
;
150 rctx
->csr
.pka
.cmd
= CRYPTO_CMD_ARN
;
151 rctx
->csr
.pka
.start
= 1;
152 rctx
->csr
.pka
.ie
= 1;
154 writel(rctx
->csr
.pka
.v
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
156 if (starfive_pka_wait_done(ctx
))
160 for (loop
= 0; loop
<= opsize
; loop
++) {
161 temp
= readl(cryp
->base
+ STARFIVE_PKA_CAAR_OFFSET
+ 0x4 * loop
);
162 out
[opsize
- loop
] = temp
;
168 static int starfive_rsa_cpu_start(struct starfive_cryp_ctx
*ctx
, u32
*result
,
169 u8
*de
, u32
*n
, int key_sz
)
171 struct starfive_cryp_dev
*cryp
= ctx
->cryp
;
172 struct starfive_cryp_request_ctx
*rctx
= ctx
->rctx
;
173 struct starfive_rsa_key
*key
= &ctx
->rsa_key
;
176 int opsize
, mlen
, loop
;
179 opsize
= (key_sz
- 1) >> 2;
181 mta
= kmalloc(key_sz
, GFP_KERNEL
);
185 ret
= starfive_rsa_montgomery_form(ctx
, mta
, (u32
*)rctx
->rsa_data
,
188 dev_err_probe(cryp
->dev
, ret
, "Conversion to Montgomery failed");
192 for (loop
= 0; loop
<= opsize
; loop
++)
193 writel(mta
[opsize
- loop
],
194 cryp
->base
+ STARFIVE_PKA_CAER_OFFSET
+ loop
* 4);
196 for (loop
= key
->bitlen
- 1; loop
> 0; loop
--) {
197 mlen
= starfive_rsa_get_nbit(de
, loop
- 1, key_sz
);
200 rctx
->csr
.pka
.cln_done
= 1;
201 rctx
->csr
.pka
.opsize
= opsize
;
202 rctx
->csr
.pka
.exposize
= opsize
;
203 rctx
->csr
.pka
.cmd
= CRYPTO_CMD_AARN
;
204 rctx
->csr
.pka
.start
= 1;
205 rctx
->csr
.pka
.ie
= 1;
207 writel(rctx
->csr
.pka
.v
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
210 if (starfive_pka_wait_done(ctx
))
215 rctx
->csr
.pka
.cln_done
= 1;
216 rctx
->csr
.pka
.opsize
= opsize
;
217 rctx
->csr
.pka
.exposize
= opsize
;
218 rctx
->csr
.pka
.cmd
= CRYPTO_CMD_AERN
;
219 rctx
->csr
.pka
.start
= 1;
220 rctx
->csr
.pka
.ie
= 1;
222 writel(rctx
->csr
.pka
.v
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
224 if (starfive_pka_wait_done(ctx
))
229 for (loop
= 0; loop
<= opsize
; loop
++) {
230 temp
= readl(cryp
->base
+ STARFIVE_PKA_CAAR_OFFSET
+ 0x4 * loop
);
231 result
[opsize
- loop
] = temp
;
234 ret
= starfive_rsa_montgomery_form(ctx
, result
, result
, 1, n
, key_sz
<< 3);
236 dev_err_probe(cryp
->dev
, ret
, "Conversion from Montgomery failed");
242 static int starfive_rsa_start(struct starfive_cryp_ctx
*ctx
, u8
*result
,
243 u8
*de
, u8
*n
, int key_sz
)
245 return starfive_rsa_cpu_start(ctx
, (u32
*)result
, de
, (u32
*)n
, key_sz
);
248 static int starfive_rsa_enc_core(struct starfive_cryp_ctx
*ctx
, int enc
)
250 struct starfive_cryp_dev
*cryp
= ctx
->cryp
;
251 struct starfive_cryp_request_ctx
*rctx
= ctx
->rctx
;
252 struct starfive_rsa_key
*key
= &ctx
->rsa_key
;
253 int ret
= 0, shift
= 0;
255 writel(STARFIVE_RSA_RESET
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
257 if (!IS_ALIGNED(rctx
->total
, sizeof(u32
))) {
258 shift
= sizeof(u32
) - (rctx
->total
& 0x3);
259 memset(rctx
->rsa_data
, 0, shift
);
262 rctx
->total
= sg_copy_to_buffer(rctx
->in_sg
, sg_nents(rctx
->in_sg
),
263 rctx
->rsa_data
+ shift
, rctx
->total
);
266 key
->bitlen
= key
->e_bitlen
;
267 ret
= starfive_rsa_start(ctx
, rctx
->rsa_data
, key
->e
,
268 key
->n
, key
->key_sz
);
270 key
->bitlen
= key
->d_bitlen
;
271 ret
= starfive_rsa_start(ctx
, rctx
->rsa_data
, key
->d
,
272 key
->n
, key
->key_sz
);
278 sg_copy_buffer(rctx
->out_sg
, sg_nents(rctx
->out_sg
),
279 rctx
->rsa_data
, key
->key_sz
, 0, 0);
282 writel(STARFIVE_RSA_RESET
, cryp
->base
+ STARFIVE_PKA_CACR_OFFSET
);
286 static int starfive_rsa_enc(struct akcipher_request
*req
)
288 struct crypto_akcipher
*tfm
= crypto_akcipher_reqtfm(req
);
289 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
290 struct starfive_cryp_dev
*cryp
= ctx
->cryp
;
291 struct starfive_rsa_key
*key
= &ctx
->rsa_key
;
292 struct starfive_cryp_request_ctx
*rctx
= akcipher_request_ctx(req
);
296 akcipher_request_set_tfm(req
, ctx
->akcipher_fbk
);
297 ret
= crypto_akcipher_encrypt(req
);
298 akcipher_request_set_tfm(req
, tfm
);
302 if (unlikely(!key
->n
|| !key
->e
))
305 if (req
->dst_len
< key
->key_sz
)
306 return dev_err_probe(cryp
->dev
, -EOVERFLOW
,
307 "Output buffer length less than parameter n\n");
309 rctx
->in_sg
= req
->src
;
310 rctx
->out_sg
= req
->dst
;
311 rctx
->total
= req
->src_len
;
314 return starfive_rsa_enc_core(ctx
, 1);
317 static int starfive_rsa_dec(struct akcipher_request
*req
)
319 struct crypto_akcipher
*tfm
= crypto_akcipher_reqtfm(req
);
320 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
321 struct starfive_cryp_dev
*cryp
= ctx
->cryp
;
322 struct starfive_rsa_key
*key
= &ctx
->rsa_key
;
323 struct starfive_cryp_request_ctx
*rctx
= akcipher_request_ctx(req
);
327 akcipher_request_set_tfm(req
, ctx
->akcipher_fbk
);
328 ret
= crypto_akcipher_decrypt(req
);
329 akcipher_request_set_tfm(req
, tfm
);
333 if (unlikely(!key
->n
|| !key
->d
))
336 if (req
->dst_len
< key
->key_sz
)
337 return dev_err_probe(cryp
->dev
, -EOVERFLOW
,
338 "Output buffer length less than parameter n\n");
340 rctx
->in_sg
= req
->src
;
341 rctx
->out_sg
= req
->dst
;
343 rctx
->total
= req
->src_len
;
345 return starfive_rsa_enc_core(ctx
, 0);
348 static int starfive_rsa_set_n(struct starfive_rsa_key
*rsa_key
,
349 const char *value
, size_t vlen
)
351 const char *ptr
= value
;
352 unsigned int bitslen
;
355 while (!*ptr
&& vlen
) {
359 rsa_key
->key_sz
= vlen
;
360 bitslen
= rsa_key
->key_sz
<< 3;
362 /* check valid key size */
367 rsa_key
->n
= kmemdup(ptr
, rsa_key
->key_sz
, GFP_KERNEL
);
375 starfive_rsa_free_key(rsa_key
);
379 static int starfive_rsa_set_e(struct starfive_rsa_key
*rsa_key
,
380 const char *value
, size_t vlen
)
382 const char *ptr
= value
;
386 while (!*ptr
&& vlen
) {
392 if (!rsa_key
->key_sz
|| !vlen
|| vlen
> rsa_key
->key_sz
) {
397 rsa_key
->e
= kzalloc(rsa_key
->key_sz
, GFP_KERNEL
);
401 for (loop
= 8; loop
> 0; loop
--) {
402 if (pt
>> (loop
- 1))
406 rsa_key
->e_bitlen
= (vlen
- 1) * 8 + loop
;
408 memcpy(rsa_key
->e
+ (rsa_key
->key_sz
- vlen
), ptr
, vlen
);
413 static int starfive_rsa_set_d(struct starfive_rsa_key
*rsa_key
,
414 const char *value
, size_t vlen
)
416 const char *ptr
= value
;
421 while (!*ptr
&& vlen
) {
428 if (!rsa_key
->key_sz
|| !vlen
|| vlen
> rsa_key
->key_sz
)
432 rsa_key
->d
= kzalloc(rsa_key
->key_sz
, GFP_KERNEL
);
436 for (loop
= 8; loop
> 0; loop
--) {
437 if (pt
>> (loop
- 1))
441 rsa_key
->d_bitlen
= (vlen
- 1) * 8 + loop
;
443 memcpy(rsa_key
->d
+ (rsa_key
->key_sz
- vlen
), ptr
, vlen
);
451 static int starfive_rsa_setkey(struct crypto_akcipher
*tfm
, const void *key
,
452 unsigned int keylen
, bool private)
454 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
455 struct rsa_key raw_key
= {NULL
};
456 struct starfive_rsa_key
*rsa_key
= &ctx
->rsa_key
;
460 ret
= rsa_parse_priv_key(&raw_key
, key
, keylen
);
462 ret
= rsa_parse_pub_key(&raw_key
, key
, keylen
);
466 starfive_rsa_free_key(rsa_key
);
468 /* Use fallback for mod > 256 + 1 byte prefix */
469 if (raw_key
.n_sz
> STARFIVE_RSA_MAX_KEYSZ
+ 1)
472 ret
= starfive_rsa_set_n(rsa_key
, raw_key
.n
, raw_key
.n_sz
);
476 ret
= starfive_rsa_set_e(rsa_key
, raw_key
.e
, raw_key
.e_sz
);
481 ret
= starfive_rsa_set_d(rsa_key
, raw_key
.d
, raw_key
.d_sz
);
486 if (!rsa_key
->n
|| !rsa_key
->e
) {
491 if (private && !rsa_key
->d
) {
498 starfive_rsa_free_key(rsa_key
);
502 static int starfive_rsa_set_pub_key(struct crypto_akcipher
*tfm
, const void *key
,
505 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
508 ret
= crypto_akcipher_set_pub_key(ctx
->akcipher_fbk
, key
, keylen
);
512 return starfive_rsa_setkey(tfm
, key
, keylen
, false);
515 static int starfive_rsa_set_priv_key(struct crypto_akcipher
*tfm
, const void *key
,
518 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
521 ret
= crypto_akcipher_set_priv_key(ctx
->akcipher_fbk
, key
, keylen
);
525 return starfive_rsa_setkey(tfm
, key
, keylen
, true);
528 static unsigned int starfive_rsa_max_size(struct crypto_akcipher
*tfm
)
530 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
532 if (ctx
->rsa_key
.key_sz
)
533 return ctx
->rsa_key
.key_sz
;
535 return crypto_akcipher_maxsize(ctx
->akcipher_fbk
);
538 static int starfive_rsa_init_tfm(struct crypto_akcipher
*tfm
)
540 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
542 ctx
->cryp
= starfive_cryp_find_dev(ctx
);
546 ctx
->akcipher_fbk
= crypto_alloc_akcipher("rsa-generic", 0, 0);
547 if (IS_ERR(ctx
->akcipher_fbk
))
548 return PTR_ERR(ctx
->akcipher_fbk
);
550 akcipher_set_reqsize(tfm
, sizeof(struct starfive_cryp_request_ctx
) +
551 sizeof(struct crypto_akcipher
) + 32);
556 static void starfive_rsa_exit_tfm(struct crypto_akcipher
*tfm
)
558 struct starfive_cryp_ctx
*ctx
= akcipher_tfm_ctx(tfm
);
559 struct starfive_rsa_key
*key
= (struct starfive_rsa_key
*)&ctx
->rsa_key
;
561 crypto_free_akcipher(ctx
->akcipher_fbk
);
562 starfive_rsa_free_key(key
);
565 static struct akcipher_alg starfive_rsa
= {
566 .encrypt
= starfive_rsa_enc
,
567 .decrypt
= starfive_rsa_dec
,
568 .set_pub_key
= starfive_rsa_set_pub_key
,
569 .set_priv_key
= starfive_rsa_set_priv_key
,
570 .max_size
= starfive_rsa_max_size
,
571 .init
= starfive_rsa_init_tfm
,
572 .exit
= starfive_rsa_exit_tfm
,
575 .cra_driver_name
= "starfive-rsa",
576 .cra_flags
= CRYPTO_ALG_TYPE_AKCIPHER
|
577 CRYPTO_ALG_NEED_FALLBACK
,
578 .cra_priority
= 3000,
579 .cra_module
= THIS_MODULE
,
580 .cra_ctxsize
= sizeof(struct starfive_cryp_ctx
),
584 int starfive_rsa_register_algs(void)
586 return crypto_register_akcipher(&starfive_rsa
);
589 void starfive_rsa_unregister_algs(void)
591 crypto_unregister_akcipher(&starfive_rsa
);