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