1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2019 Marvell International Ltd. 3 */ 4 5 #ifndef _CPT_UCODE_ASYM_H_ 6 #define _CPT_UCODE_ASYM_H_ 7 8 #include <rte_common.h> 9 #include <rte_crypto_asym.h> 10 #include <rte_malloc.h> 11 12 #include "cpt_common.h" 13 #include "cpt_hw_types.h" 14 #include "cpt_mcode_defines.h" 15 16 static __rte_always_inline void 17 cpt_modex_param_normalize(uint8_t **data, size_t *len) 18 { 19 size_t i; 20 21 /* Strip leading NUL bytes */ 22 23 for (i = 0; i < *len; i++) { 24 if ((*data)[i] != 0) 25 break; 26 } 27 28 *data += i; 29 *len -= i; 30 } 31 32 static __rte_always_inline int 33 cpt_fill_modex_params(struct cpt_asym_sess_misc *sess, 34 struct rte_crypto_asym_xform *xform) 35 { 36 struct rte_crypto_modex_xform *ctx = &sess->mod_ctx; 37 size_t exp_len = xform->modex.exponent.length; 38 size_t mod_len = xform->modex.modulus.length; 39 uint8_t *exp = xform->modex.exponent.data; 40 uint8_t *mod = xform->modex.modulus.data; 41 42 cpt_modex_param_normalize(&mod, &mod_len); 43 cpt_modex_param_normalize(&exp, &exp_len); 44 45 if (unlikely(exp_len == 0 || mod_len == 0)) 46 return -EINVAL; 47 48 if (unlikely(exp_len > mod_len)) { 49 CPT_LOG_DP_ERR("Exponent length greater than modulus length is not supported"); 50 return -ENOTSUP; 51 } 52 53 /* Allocate buffer to hold modexp params */ 54 ctx->modulus.data = rte_malloc(NULL, mod_len + exp_len, 0); 55 if (ctx->modulus.data == NULL) { 56 CPT_LOG_DP_ERR("Could not allocate buffer for modex params"); 57 return -ENOMEM; 58 } 59 60 /* Set up modexp prime modulus and private exponent */ 61 62 memcpy(ctx->modulus.data, mod, mod_len); 63 ctx->exponent.data = ctx->modulus.data + mod_len; 64 memcpy(ctx->exponent.data, exp, exp_len); 65 66 ctx->modulus.length = mod_len; 67 ctx->exponent.length = exp_len; 68 69 return 0; 70 } 71 72 static __rte_always_inline int 73 cpt_fill_rsa_params(struct cpt_asym_sess_misc *sess, 74 struct rte_crypto_asym_xform *xform) 75 { 76 struct rte_crypto_rsa_priv_key_qt qt = xform->rsa.qt; 77 struct rte_crypto_rsa_xform *xfrm_rsa = &xform->rsa; 78 struct rte_crypto_rsa_xform *rsa = &sess->rsa_ctx; 79 size_t mod_len = xfrm_rsa->n.length; 80 size_t exp_len = xfrm_rsa->e.length; 81 uint64_t total_size; 82 size_t len = 0; 83 84 /* Make sure key length used is not more than mod_len/2 */ 85 if (qt.p.data != NULL) 86 len = (((mod_len / 2) < qt.p.length) ? len : qt.p.length); 87 88 /* Total size required for RSA key params(n,e,(q,dQ,p,dP,qInv)) */ 89 total_size = mod_len + exp_len + 5 * len; 90 91 /* Allocate buffer to hold all RSA keys */ 92 rsa->n.data = rte_malloc(NULL, total_size, 0); 93 if (rsa->n.data == NULL) { 94 CPT_LOG_DP_ERR("Could not allocate buffer for RSA keys"); 95 return -ENOMEM; 96 } 97 98 /* Set up RSA prime modulus and public key exponent */ 99 memcpy(rsa->n.data, xfrm_rsa->n.data, mod_len); 100 rsa->e.data = rsa->n.data + mod_len; 101 memcpy(rsa->e.data, xfrm_rsa->e.data, exp_len); 102 103 /* Private key in quintuple format */ 104 if (len != 0) { 105 rsa->qt.q.data = rsa->e.data + exp_len; 106 memcpy(rsa->qt.q.data, qt.q.data, qt.q.length); 107 rsa->qt.dQ.data = rsa->qt.q.data + qt.q.length; 108 memcpy(rsa->qt.dQ.data, qt.dQ.data, qt.dQ.length); 109 rsa->qt.p.data = rsa->qt.dQ.data + qt.dQ.length; 110 memcpy(rsa->qt.p.data, qt.p.data, qt.p.length); 111 rsa->qt.dP.data = rsa->qt.p.data + qt.p.length; 112 memcpy(rsa->qt.dP.data, qt.dP.data, qt.dP.length); 113 rsa->qt.qInv.data = rsa->qt.dP.data + qt.dP.length; 114 memcpy(rsa->qt.qInv.data, qt.qInv.data, qt.qInv.length); 115 116 rsa->qt.q.length = qt.q.length; 117 rsa->qt.dQ.length = qt.dQ.length; 118 rsa->qt.p.length = qt.p.length; 119 rsa->qt.dP.length = qt.dP.length; 120 rsa->qt.qInv.length = qt.qInv.length; 121 } 122 rsa->n.length = mod_len; 123 rsa->e.length = exp_len; 124 125 return 0; 126 } 127 128 static __rte_always_inline int 129 cpt_fill_ec_params(struct cpt_asym_sess_misc *sess, 130 struct rte_crypto_asym_xform *xform) 131 { 132 struct cpt_asym_ec_ctx *ec = &sess->ec_ctx; 133 134 switch (xform->ec.curve_id) { 135 case RTE_CRYPTO_EC_GROUP_SECP192R1: 136 ec->curveid = CPT_EC_ID_P192; 137 break; 138 case RTE_CRYPTO_EC_GROUP_SECP224R1: 139 ec->curveid = CPT_EC_ID_P224; 140 break; 141 case RTE_CRYPTO_EC_GROUP_SECP256R1: 142 ec->curveid = CPT_EC_ID_P256; 143 break; 144 case RTE_CRYPTO_EC_GROUP_SECP384R1: 145 ec->curveid = CPT_EC_ID_P384; 146 break; 147 case RTE_CRYPTO_EC_GROUP_SECP521R1: 148 ec->curveid = CPT_EC_ID_P521; 149 break; 150 default: 151 /* Only NIST curves (FIPS 186-4) are supported */ 152 CPT_LOG_DP_ERR("Unsupported curve"); 153 return -EINVAL; 154 } 155 156 return 0; 157 } 158 159 static __rte_always_inline int 160 cpt_fill_asym_session_parameters(struct cpt_asym_sess_misc *sess, 161 struct rte_crypto_asym_xform *xform) 162 { 163 int ret; 164 165 sess->xfrm_type = xform->xform_type; 166 167 switch (xform->xform_type) { 168 case RTE_CRYPTO_ASYM_XFORM_RSA: 169 ret = cpt_fill_rsa_params(sess, xform); 170 break; 171 case RTE_CRYPTO_ASYM_XFORM_MODEX: 172 ret = cpt_fill_modex_params(sess, xform); 173 break; 174 case RTE_CRYPTO_ASYM_XFORM_ECDSA: 175 /* Fall through */ 176 case RTE_CRYPTO_ASYM_XFORM_ECPM: 177 ret = cpt_fill_ec_params(sess, xform); 178 break; 179 default: 180 CPT_LOG_DP_ERR("Unsupported transform type"); 181 return -ENOTSUP; 182 } 183 return ret; 184 } 185 186 static __rte_always_inline void 187 cpt_free_asym_session_parameters(struct cpt_asym_sess_misc *sess) 188 { 189 struct rte_crypto_modex_xform *mod; 190 struct rte_crypto_rsa_xform *rsa; 191 192 switch (sess->xfrm_type) { 193 case RTE_CRYPTO_ASYM_XFORM_RSA: 194 rsa = &sess->rsa_ctx; 195 if (rsa->n.data) 196 rte_free(rsa->n.data); 197 break; 198 case RTE_CRYPTO_ASYM_XFORM_MODEX: 199 mod = &sess->mod_ctx; 200 if (mod->modulus.data) 201 rte_free(mod->modulus.data); 202 break; 203 case RTE_CRYPTO_ASYM_XFORM_ECDSA: 204 /* Fall through */ 205 case RTE_CRYPTO_ASYM_XFORM_ECPM: 206 break; 207 default: 208 CPT_LOG_DP_ERR("Invalid transform type"); 209 break; 210 } 211 } 212 213 static __rte_always_inline void 214 cpt_fill_req_comp_addr(struct cpt_request_info *req, buf_ptr_t addr) 215 { 216 void *completion_addr = RTE_PTR_ALIGN(addr.vaddr, 16); 217 218 /* Pointer to cpt_res_s, updated by CPT */ 219 req->completion_addr = (volatile uint64_t *)completion_addr; 220 req->comp_baddr = addr.dma_addr + 221 RTE_PTR_DIFF(completion_addr, addr.vaddr); 222 *(req->completion_addr) = COMPLETION_CODE_INIT; 223 } 224 225 static __rte_always_inline int 226 cpt_modex_prep(struct asym_op_params *modex_params, 227 struct rte_crypto_modex_xform *mod) 228 { 229 struct cpt_request_info *req = modex_params->req; 230 phys_addr_t mphys = modex_params->meta_buf; 231 uint32_t exp_len = mod->exponent.length; 232 uint32_t mod_len = mod->modulus.length; 233 struct rte_crypto_mod_op_param mod_op; 234 struct rte_crypto_op **op; 235 vq_cmd_word0_t vq_cmd_w0; 236 uint64_t total_key_len; 237 uint32_t dlen, rlen; 238 uint32_t base_len; 239 buf_ptr_t caddr; 240 uint8_t *dptr; 241 242 /* Extracting modex op form params->req->op[1]->asym->modex */ 243 op = RTE_PTR_ADD(req->op, sizeof(uintptr_t)); 244 mod_op = ((struct rte_crypto_op *)*op)->asym->modex; 245 246 base_len = mod_op.base.length; 247 if (unlikely(base_len > mod_len)) { 248 CPT_LOG_DP_ERR("Base length greater than modulus length is not supported"); 249 (*op)->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 250 return -ENOTSUP; 251 } 252 253 total_key_len = mod_len + exp_len; 254 255 /* Input buffer */ 256 dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info)); 257 memcpy(dptr, mod->modulus.data, total_key_len); 258 dptr += total_key_len; 259 memcpy(dptr, mod_op.base.data, base_len); 260 dptr += base_len; 261 dlen = total_key_len + base_len; 262 263 /* Result buffer */ 264 rlen = mod_len; 265 266 /* Setup opcodes */ 267 vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MODEX; 268 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_MODEX; 269 270 /* GP op header */ 271 vq_cmd_w0.s.param1 = mod_len; 272 vq_cmd_w0.s.param2 = exp_len; 273 vq_cmd_w0.s.dlen = dlen; 274 275 /* Filling cpt_request_info structure */ 276 req->ist.ei0 = vq_cmd_w0.u64; 277 req->ist.ei1 = mphys; 278 req->ist.ei2 = mphys + dlen; 279 280 /* Result pointer to store result data */ 281 req->rptr = dptr; 282 283 /* alternate_caddr to write completion status of the microcode */ 284 req->alternate_caddr = (uint64_t *)(dptr + rlen); 285 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 286 287 /* Preparing completion addr, +1 for completion code */ 288 caddr.vaddr = dptr + rlen + 1; 289 caddr.dma_addr = mphys + dlen + rlen + 1; 290 291 cpt_fill_req_comp_addr(req, caddr); 292 return 0; 293 } 294 295 static __rte_always_inline void 296 cpt_rsa_prep(struct asym_op_params *rsa_params, 297 struct rte_crypto_rsa_xform *rsa, 298 rte_crypto_param *crypto_param) 299 { 300 struct cpt_request_info *req = rsa_params->req; 301 phys_addr_t mphys = rsa_params->meta_buf; 302 struct rte_crypto_rsa_op_param rsa_op; 303 uint32_t mod_len = rsa->n.length; 304 uint32_t exp_len = rsa->e.length; 305 struct rte_crypto_op **op; 306 vq_cmd_word0_t vq_cmd_w0; 307 uint64_t total_key_len; 308 uint32_t dlen, rlen; 309 uint32_t in_size; 310 buf_ptr_t caddr; 311 uint8_t *dptr; 312 313 /* Extracting rsa op form params->req->op[1]->asym->rsa */ 314 op = RTE_PTR_ADD(req->op, sizeof(uintptr_t)); 315 rsa_op = ((struct rte_crypto_op *)*op)->asym->rsa; 316 total_key_len = mod_len + exp_len; 317 318 /* Input buffer */ 319 dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info)); 320 memcpy(dptr, rsa->n.data, total_key_len); 321 dptr += total_key_len; 322 323 in_size = crypto_param->length; 324 memcpy(dptr, crypto_param->data, in_size); 325 326 dptr += in_size; 327 dlen = total_key_len + in_size; 328 329 /* Result buffer */ 330 rlen = mod_len; 331 332 if (rsa_op.pad == RTE_CRYPTO_RSA_PADDING_NONE) { 333 /* Use mod_exp operation for no_padding type */ 334 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_MODEX; 335 vq_cmd_w0.s.param2 = exp_len; 336 } else { 337 if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) { 338 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_ENC; 339 /* Public key encrypt, use BT2*/ 340 vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE2 | 341 ((uint16_t)(exp_len) << 1); 342 } else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) { 343 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_DEC; 344 /* Public key decrypt, use BT1 */ 345 vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE1; 346 /* + 2 for decrypted len */ 347 rlen += 2; 348 } 349 } 350 351 vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MODEX; 352 353 /* GP op header */ 354 vq_cmd_w0.s.param1 = mod_len; 355 vq_cmd_w0.s.dlen = dlen; 356 357 /* Filling cpt_request_info structure */ 358 req->ist.ei0 = vq_cmd_w0.u64; 359 req->ist.ei1 = mphys; 360 req->ist.ei2 = mphys + dlen; 361 362 /* Result pointer to store result data */ 363 req->rptr = dptr; 364 365 /* alternate_caddr to write completion status of the microcode */ 366 req->alternate_caddr = (uint64_t *)(dptr + rlen); 367 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 368 369 /* Preparing completion addr, +1 for completion code */ 370 caddr.vaddr = dptr + rlen + 1; 371 caddr.dma_addr = mphys + dlen + rlen + 1; 372 373 cpt_fill_req_comp_addr(req, caddr); 374 } 375 376 static __rte_always_inline void 377 cpt_rsa_crt_prep(struct asym_op_params *rsa_params, 378 struct rte_crypto_rsa_xform *rsa, 379 rte_crypto_param *crypto_param) 380 { 381 struct cpt_request_info *req = rsa_params->req; 382 phys_addr_t mphys = rsa_params->meta_buf; 383 uint32_t qInv_len = rsa->qt.qInv.length; 384 struct rte_crypto_rsa_op_param rsa_op; 385 uint32_t dP_len = rsa->qt.dP.length; 386 uint32_t dQ_len = rsa->qt.dQ.length; 387 uint32_t p_len = rsa->qt.p.length; 388 uint32_t q_len = rsa->qt.q.length; 389 uint32_t mod_len = rsa->n.length; 390 struct rte_crypto_op **op; 391 vq_cmd_word0_t vq_cmd_w0; 392 uint64_t total_key_len; 393 uint32_t dlen, rlen; 394 uint32_t in_size; 395 buf_ptr_t caddr; 396 uint8_t *dptr; 397 398 /* Extracting rsa op form params->req->op[1]->asym->rsa */ 399 op = RTE_PTR_ADD(req->op, sizeof(uintptr_t)); 400 rsa_op = ((struct rte_crypto_op *)*op)->asym->rsa; 401 total_key_len = p_len + q_len + dP_len + dQ_len + qInv_len; 402 403 /* Input buffer */ 404 dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info)); 405 memcpy(dptr, rsa->qt.q.data, total_key_len); 406 dptr += total_key_len; 407 408 in_size = crypto_param->length; 409 memcpy(dptr, crypto_param->data, in_size); 410 411 dptr += in_size; 412 dlen = total_key_len + in_size; 413 414 /* Result buffer */ 415 rlen = mod_len; 416 417 if (rsa_op.pad == RTE_CRYPTO_RSA_PADDING_NONE) { 418 /*Use mod_exp operation for no_padding type */ 419 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_MODEX_CRT; 420 } else { 421 if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_SIGN) { 422 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_ENC_CRT; 423 /* Private encrypt, use BT1 */ 424 vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE1; 425 } else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) { 426 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_DEC_CRT; 427 /* Private decrypt, use BT2 */ 428 vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE2; 429 /* + 2 for decrypted len */ 430 rlen += 2; 431 } 432 } 433 434 vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MODEX; 435 436 /* GP op header */ 437 vq_cmd_w0.s.param1 = mod_len; 438 vq_cmd_w0.s.dlen = dlen; 439 440 /* Filling cpt_request_info structure */ 441 req->ist.ei0 = vq_cmd_w0.u64; 442 req->ist.ei1 = mphys; 443 req->ist.ei2 = mphys + dlen; 444 445 /* Result pointer to store result data */ 446 req->rptr = dptr; 447 448 /* alternate_caddr to write completion status of the microcode */ 449 req->alternate_caddr = (uint64_t *)(dptr + rlen); 450 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 451 452 /* Preparing completion addr, +1 for completion code */ 453 caddr.vaddr = dptr + rlen + 1; 454 caddr.dma_addr = mphys + dlen + rlen + 1; 455 456 cpt_fill_req_comp_addr(req, caddr); 457 } 458 459 static __rte_always_inline int __rte_hot 460 cpt_enqueue_rsa_op(struct rte_crypto_op *op, 461 struct asym_op_params *params, 462 struct cpt_asym_sess_misc *sess) 463 { 464 struct rte_crypto_rsa_op_param *rsa = &op->asym->rsa; 465 466 switch (rsa->op_type) { 467 case RTE_CRYPTO_ASYM_OP_VERIFY: 468 cpt_rsa_prep(params, &sess->rsa_ctx, &rsa->sign); 469 break; 470 case RTE_CRYPTO_ASYM_OP_ENCRYPT: 471 cpt_rsa_prep(params, &sess->rsa_ctx, &rsa->message); 472 break; 473 case RTE_CRYPTO_ASYM_OP_SIGN: 474 cpt_rsa_crt_prep(params, &sess->rsa_ctx, &rsa->message); 475 break; 476 case RTE_CRYPTO_ASYM_OP_DECRYPT: 477 cpt_rsa_crt_prep(params, &sess->rsa_ctx, &rsa->cipher); 478 break; 479 default: 480 op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 481 return -EINVAL; 482 } 483 return 0; 484 } 485 486 static const struct cpt_ec_group ec_grp[CPT_EC_ID_PMAX] = { 487 { 488 .prime = { 489 .data = { 490 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 491 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 492 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 493 }, 494 .length = 24, 495 }, 496 .order = { 497 .data = { 498 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 499 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, 500 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31 501 }, 502 .length = 24 503 }, 504 }, 505 { 506 .prime = { 507 .data = { 508 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 509 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 511 0x00, 0x00, 0x00, 0x01 512 }, 513 .length = 28 514 }, 515 .order = { 516 .data = { 517 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 518 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X16, 0XA2, 519 0XE0, 0XB8, 0XF0, 0X3E, 0X13, 0XDD, 0X29, 0X45, 520 0X5C, 0X5C, 0X2A, 0X3D 521 }, 522 .length = 28 523 }, 524 }, 525 { 526 .prime = { 527 .data = { 528 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 530 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 531 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 532 }, 533 .length = 32 534 }, 535 .order = { 536 .data = { 537 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 538 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 539 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 540 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 541 }, 542 .length = 32 543 }, 544 }, 545 { 546 .prime = { 547 .data = { 548 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 549 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 550 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 551 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 552 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 553 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF 554 }, 555 .length = 48 556 }, 557 .order = { 558 .data = { 559 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 560 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 561 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 562 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 563 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, 564 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 565 }, 566 .length = 48 567 } 568 }, 569 { 570 .prime = { 571 .data = { 572 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 573 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 574 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 575 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 576 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 577 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 578 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 579 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 580 0xFF, 0xFF 581 }, 582 .length = 66 583 }, 584 .order = { 585 .data = { 586 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 587 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 588 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 589 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 590 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 591 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 592 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 593 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 594 0x64, 0x09 595 }, 596 .length = 66 597 } 598 } 599 }; 600 601 static __rte_always_inline void 602 cpt_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param *ecdsa, 603 struct asym_op_params *ecdsa_params, 604 uint64_t fpm_table_iova, 605 uint8_t curveid) 606 { 607 struct cpt_request_info *req = ecdsa_params->req; 608 uint16_t message_len = ecdsa->message.length; 609 phys_addr_t mphys = ecdsa_params->meta_buf; 610 uint16_t pkey_len = ecdsa->pkey.length; 611 uint16_t p_align, k_align, m_align; 612 uint16_t k_len = ecdsa->k.length; 613 uint16_t order_len, prime_len; 614 uint16_t o_offset, pk_offset; 615 vq_cmd_word0_t vq_cmd_w0; 616 uint16_t rlen, dlen; 617 buf_ptr_t caddr; 618 uint8_t *dptr; 619 620 prime_len = ec_grp[curveid].prime.length; 621 order_len = ec_grp[curveid].order.length; 622 623 /* Truncate input length to curve prime length */ 624 if (message_len > prime_len) 625 message_len = prime_len; 626 m_align = RTE_ALIGN_CEIL(message_len, 8); 627 628 p_align = RTE_ALIGN_CEIL(prime_len, 8); 629 k_align = RTE_ALIGN_CEIL(k_len, 8); 630 631 /* Set write offset for order and private key */ 632 o_offset = prime_len - order_len; 633 pk_offset = prime_len - pkey_len; 634 635 /* Input buffer */ 636 dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info)); 637 638 /* 639 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(scalar len, input len), 640 * ROUNDUP8(priv key len, prime len, order len)). 641 * Please note, private key, order cannot exceed prime 642 * length i.e 3 * p_align. 643 */ 644 dlen = sizeof(fpm_table_iova) + k_align + m_align + p_align * 3; 645 646 memset(dptr, 0, dlen); 647 648 *(uint64_t *)dptr = fpm_table_iova; 649 dptr += sizeof(fpm_table_iova); 650 651 memcpy(dptr, ecdsa->k.data, k_len); 652 dptr += k_align; 653 654 memcpy(dptr, ec_grp[curveid].prime.data, prime_len); 655 dptr += p_align; 656 657 memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len); 658 dptr += p_align; 659 660 memcpy(dptr + pk_offset, ecdsa->pkey.data, pkey_len); 661 dptr += p_align; 662 663 memcpy(dptr, ecdsa->message.data, message_len); 664 dptr += m_align; 665 666 /* 2 * prime length (for sign r and s ) */ 667 rlen = 2 * p_align; 668 669 /* Setup opcodes */ 670 vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ECDSA; 671 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_ECDSA_SIGN; 672 673 /* GP op header */ 674 vq_cmd_w0.s.param1 = curveid | (message_len << 8); 675 vq_cmd_w0.s.param2 = k_len; 676 vq_cmd_w0.s.dlen = dlen; 677 678 /* Filling cpt_request_info structure */ 679 req->ist.ei0 = vq_cmd_w0.u64; 680 req->ist.ei1 = mphys; 681 req->ist.ei2 = mphys + dlen; 682 683 /* Result pointer to store result data */ 684 req->rptr = dptr; 685 686 /* alternate_caddr to write completion status of the microcode */ 687 req->alternate_caddr = (uint64_t *)(dptr + rlen); 688 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 689 690 /* Preparing completion addr, +1 for completion code */ 691 caddr.vaddr = dptr + rlen + 1; 692 caddr.dma_addr = mphys + dlen + rlen + 1; 693 694 cpt_fill_req_comp_addr(req, caddr); 695 } 696 697 static __rte_always_inline void 698 cpt_ecdsa_verify_prep(struct rte_crypto_ecdsa_op_param *ecdsa, 699 struct asym_op_params *ecdsa_params, 700 uint64_t fpm_table_iova, 701 uint8_t curveid) 702 { 703 struct cpt_request_info *req = ecdsa_params->req; 704 uint32_t message_len = ecdsa->message.length; 705 phys_addr_t mphys = ecdsa_params->meta_buf; 706 uint16_t o_offset, r_offset, s_offset; 707 uint16_t qx_len = ecdsa->q.x.length; 708 uint16_t qy_len = ecdsa->q.y.length; 709 uint16_t r_len = ecdsa->r.length; 710 uint16_t s_len = ecdsa->s.length; 711 uint16_t order_len, prime_len; 712 uint16_t qx_offset, qy_offset; 713 uint16_t p_align, m_align; 714 vq_cmd_word0_t vq_cmd_w0; 715 buf_ptr_t caddr; 716 uint16_t dlen; 717 uint8_t *dptr; 718 719 prime_len = ec_grp[curveid].prime.length; 720 order_len = ec_grp[curveid].order.length; 721 722 /* Truncate input length to curve prime length */ 723 if (message_len > prime_len) 724 message_len = prime_len; 725 726 m_align = RTE_ALIGN_CEIL(message_len, 8); 727 p_align = RTE_ALIGN_CEIL(prime_len, 8); 728 729 /* Set write offset for sign, order and public key coordinates */ 730 o_offset = prime_len - order_len; 731 qx_offset = prime_len - qx_len; 732 qy_offset = prime_len - qy_len; 733 r_offset = prime_len - r_len; 734 s_offset = prime_len - s_len; 735 736 /* Input buffer */ 737 dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info)); 738 739 /* 740 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(message len), 741 * ROUNDUP8(sign len(r and s), public key len(x and y coordinates), 742 * prime len, order len)). 743 * Please note sign, public key and order can not excede prime length 744 * i.e. 6 * p_align 745 */ 746 dlen = sizeof(fpm_table_iova) + m_align + (6 * p_align); 747 748 memset(dptr, 0, dlen); 749 750 *(uint64_t *)dptr = fpm_table_iova; 751 dptr += sizeof(fpm_table_iova); 752 753 memcpy(dptr + r_offset, ecdsa->r.data, r_len); 754 dptr += p_align; 755 756 memcpy(dptr + s_offset, ecdsa->s.data, s_len); 757 dptr += p_align; 758 759 memcpy(dptr, ecdsa->message.data, message_len); 760 dptr += m_align; 761 762 memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len); 763 dptr += p_align; 764 765 memcpy(dptr, ec_grp[curveid].prime.data, prime_len); 766 dptr += p_align; 767 768 memcpy(dptr + qx_offset, ecdsa->q.x.data, qx_len); 769 dptr += p_align; 770 771 memcpy(dptr + qy_offset, ecdsa->q.y.data, qy_len); 772 dptr += p_align; 773 774 /* Setup opcodes */ 775 vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ECDSA; 776 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_ECDSA_VERIFY; 777 778 /* GP op header */ 779 vq_cmd_w0.s.param1 = curveid | (message_len << 8); 780 vq_cmd_w0.s.param2 = 0; 781 vq_cmd_w0.s.dlen = dlen; 782 783 /* Filling cpt_request_info structure */ 784 req->ist.ei0 = vq_cmd_w0.u64; 785 req->ist.ei1 = mphys; 786 req->ist.ei2 = mphys + dlen; 787 788 /* Result pointer to store result data */ 789 req->rptr = dptr; 790 791 /* alternate_caddr to write completion status of the microcode */ 792 req->alternate_caddr = (uint64_t *)dptr; 793 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 794 795 /* Preparing completion addr, +1 for completion code */ 796 caddr.vaddr = dptr + 1; 797 caddr.dma_addr = mphys + dlen + 1; 798 799 cpt_fill_req_comp_addr(req, caddr); 800 } 801 802 static __rte_always_inline int __rte_hot 803 cpt_enqueue_ecdsa_op(struct rte_crypto_op *op, 804 struct asym_op_params *params, 805 struct cpt_asym_sess_misc *sess, 806 uint64_t *fpm_iova) 807 { 808 struct rte_crypto_ecdsa_op_param *ecdsa = &op->asym->ecdsa; 809 uint8_t curveid = sess->ec_ctx.curveid; 810 811 if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN) 812 cpt_ecdsa_sign_prep(ecdsa, params, fpm_iova[curveid], curveid); 813 else if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY) 814 cpt_ecdsa_verify_prep(ecdsa, params, fpm_iova[curveid], 815 curveid); 816 else { 817 op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 818 return -EINVAL; 819 } 820 return 0; 821 } 822 823 static __rte_always_inline int 824 cpt_ecpm_prep(struct rte_crypto_ecpm_op_param *ecpm, 825 struct asym_op_params *asym_params, 826 uint8_t curveid) 827 { 828 struct cpt_request_info *req = asym_params->req; 829 phys_addr_t mphys = asym_params->meta_buf; 830 uint16_t x1_len = ecpm->p.x.length; 831 uint16_t y1_len = ecpm->p.y.length; 832 uint16_t scalar_align, p_align; 833 uint16_t dlen, rlen, prime_len; 834 uint16_t x1_offset, y1_offset; 835 vq_cmd_word0_t vq_cmd_w0; 836 buf_ptr_t caddr; 837 uint8_t *dptr; 838 839 prime_len = ec_grp[curveid].prime.length; 840 841 /* Input buffer */ 842 dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info)); 843 844 p_align = RTE_ALIGN_CEIL(prime_len, 8); 845 scalar_align = RTE_ALIGN_CEIL(ecpm->scalar.length, 8); 846 847 /* 848 * Set dlen = sum(ROUNDUP8(input point(x and y coordinates), prime, 849 * scalar length), 850 * Please note point length is equivalent to prime of the curve 851 */ 852 dlen = 3 * p_align + scalar_align; 853 854 x1_offset = prime_len - x1_len; 855 y1_offset = prime_len - y1_len; 856 857 memset(dptr, 0, dlen); 858 859 /* Copy input point, scalar, prime */ 860 memcpy(dptr + x1_offset, ecpm->p.x.data, x1_len); 861 dptr += p_align; 862 memcpy(dptr + y1_offset, ecpm->p.y.data, y1_len); 863 dptr += p_align; 864 memcpy(dptr, ecpm->scalar.data, ecpm->scalar.length); 865 dptr += scalar_align; 866 memcpy(dptr, ec_grp[curveid].prime.data, ec_grp[curveid].prime.length); 867 dptr += p_align; 868 869 /* Setup opcodes */ 870 vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ECC; 871 vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_ECC_UMP; 872 873 /* GP op header */ 874 vq_cmd_w0.s.param1 = curveid; 875 vq_cmd_w0.s.param2 = ecpm->scalar.length; 876 vq_cmd_w0.s.dlen = dlen; 877 878 /* Filling cpt_request_info structure */ 879 req->ist.ei0 = vq_cmd_w0.u64; 880 req->ist.ei1 = mphys; 881 req->ist.ei2 = mphys + dlen; 882 883 /* Result buffer will store output point where length of 884 * each coordinate will be of prime length, thus set 885 * rlen to twice of prime length. 886 */ 887 rlen = p_align << 1; 888 req->rptr = dptr; 889 890 /* alternate_caddr to write completion status by the microcode */ 891 req->alternate_caddr = (uint64_t *)(dptr + rlen); 892 *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); 893 894 /* Preparing completion addr, +1 for completion code */ 895 caddr.vaddr = dptr + rlen + 1; 896 caddr.dma_addr = mphys + dlen + rlen + 1; 897 898 cpt_fill_req_comp_addr(req, caddr); 899 return 0; 900 } 901 #endif /* _CPT_UCODE_ASYM_H_ */ 902