xref: /dpdk/drivers/common/cpt/cpt_ucode_asym.h (revision 29fd052d)
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 		rte_free(rsa->n.data);
196 		break;
197 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
198 		mod = &sess->mod_ctx;
199 		rte_free(mod->modulus.data);
200 		break;
201 	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
202 		/* Fall through */
203 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
204 		break;
205 	default:
206 		CPT_LOG_DP_ERR("Invalid transform type");
207 		break;
208 	}
209 }
210 
211 static __rte_always_inline void
212 cpt_fill_req_comp_addr(struct cpt_request_info *req, buf_ptr_t addr)
213 {
214 	void *completion_addr = RTE_PTR_ALIGN(addr.vaddr, 16);
215 
216 	/* Pointer to cpt_res_s, updated by CPT */
217 	req->completion_addr = (volatile uint64_t *)completion_addr;
218 	req->comp_baddr = addr.dma_addr +
219 			  RTE_PTR_DIFF(completion_addr, addr.vaddr);
220 	*(req->completion_addr) = COMPLETION_CODE_INIT;
221 }
222 
223 static __rte_always_inline int
224 cpt_modex_prep(struct asym_op_params *modex_params,
225 	       struct rte_crypto_modex_xform *mod)
226 {
227 	struct cpt_request_info *req = modex_params->req;
228 	phys_addr_t mphys = modex_params->meta_buf;
229 	uint32_t exp_len = mod->exponent.length;
230 	uint32_t mod_len = mod->modulus.length;
231 	struct rte_crypto_mod_op_param mod_op;
232 	struct rte_crypto_op **op;
233 	vq_cmd_word0_t vq_cmd_w0;
234 	uint64_t total_key_len;
235 	uint32_t dlen, rlen;
236 	uint32_t base_len;
237 	buf_ptr_t caddr;
238 	uint8_t *dptr;
239 
240 	/* Extracting modex op form params->req->op[1]->asym->modex */
241 	op = RTE_PTR_ADD(req->op, sizeof(uintptr_t));
242 	mod_op = ((struct rte_crypto_op *)*op)->asym->modex;
243 
244 	base_len = mod_op.base.length;
245 	if (unlikely(base_len > mod_len)) {
246 		CPT_LOG_DP_ERR("Base length greater than modulus length is not supported");
247 		(*op)->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
248 		return -ENOTSUP;
249 	}
250 
251 	total_key_len = mod_len + exp_len;
252 
253 	/* Input buffer */
254 	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
255 	memcpy(dptr, mod->modulus.data, total_key_len);
256 	dptr += total_key_len;
257 	memcpy(dptr, mod_op.base.data, base_len);
258 	dptr += base_len;
259 	dlen = total_key_len + base_len;
260 
261 	/* Result buffer */
262 	rlen = mod_len;
263 
264 	/* Setup opcodes */
265 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MODEX;
266 	vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_MODEX;
267 
268 	/* GP op header */
269 	vq_cmd_w0.s.param1 = mod_len;
270 	vq_cmd_w0.s.param2 = exp_len;
271 	vq_cmd_w0.s.dlen = dlen;
272 
273 	/* Filling cpt_request_info structure */
274 	req->ist.ei0 = vq_cmd_w0.u64;
275 	req->ist.ei1 = mphys;
276 	req->ist.ei2 = mphys + dlen;
277 
278 	/* Result pointer to store result data */
279 	req->rptr = dptr;
280 
281 	/* alternate_caddr to write completion status of the microcode */
282 	req->alternate_caddr = (uint64_t *)(dptr + rlen);
283 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
284 
285 	/* Preparing completion addr, +1 for completion code */
286 	caddr.vaddr = dptr + rlen + 1;
287 	caddr.dma_addr = mphys + dlen + rlen + 1;
288 
289 	cpt_fill_req_comp_addr(req, caddr);
290 	return 0;
291 }
292 
293 static __rte_always_inline void
294 cpt_rsa_prep(struct asym_op_params *rsa_params,
295 	     struct rte_crypto_rsa_xform *rsa,
296 	     rte_crypto_param *crypto_param)
297 {
298 	struct cpt_request_info *req = rsa_params->req;
299 	phys_addr_t mphys = rsa_params->meta_buf;
300 	struct rte_crypto_rsa_op_param rsa_op;
301 	uint32_t mod_len = rsa->n.length;
302 	uint32_t exp_len = rsa->e.length;
303 	struct rte_crypto_op **op;
304 	vq_cmd_word0_t vq_cmd_w0;
305 	uint64_t total_key_len;
306 	uint32_t dlen, rlen;
307 	uint32_t in_size;
308 	buf_ptr_t caddr;
309 	uint8_t *dptr;
310 
311 	/* Extracting rsa op form params->req->op[1]->asym->rsa */
312 	op = RTE_PTR_ADD(req->op, sizeof(uintptr_t));
313 	rsa_op = ((struct rte_crypto_op *)*op)->asym->rsa;
314 	total_key_len  = mod_len + exp_len;
315 
316 	/* Input buffer */
317 	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
318 	memcpy(dptr, rsa->n.data, total_key_len);
319 	dptr += total_key_len;
320 
321 	in_size = crypto_param->length;
322 	memcpy(dptr, crypto_param->data, in_size);
323 
324 	dptr += in_size;
325 	dlen = total_key_len + in_size;
326 
327 	/* Result buffer */
328 	rlen = mod_len;
329 
330 	if (rsa_op.pad == RTE_CRYPTO_RSA_PADDING_NONE) {
331 		/* Use mod_exp operation for no_padding type */
332 		vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_MODEX;
333 		vq_cmd_w0.s.param2 = exp_len;
334 	} else {
335 		if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) {
336 			vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_ENC;
337 			/* Public key encrypt, use BT2*/
338 			vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE2 |
339 					((uint16_t)(exp_len) << 1);
340 		} else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) {
341 			vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_DEC;
342 			/* Public key decrypt, use BT1 */
343 			vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE1;
344 			/* + 2 for decrypted len */
345 			rlen += 2;
346 		}
347 	}
348 
349 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MODEX;
350 
351 	/* GP op header */
352 	vq_cmd_w0.s.param1 = mod_len;
353 	vq_cmd_w0.s.dlen = dlen;
354 
355 	/* Filling cpt_request_info structure */
356 	req->ist.ei0 = vq_cmd_w0.u64;
357 	req->ist.ei1 = mphys;
358 	req->ist.ei2 = mphys + dlen;
359 
360 	/* Result pointer to store result data */
361 	req->rptr = dptr;
362 
363 	/* alternate_caddr to write completion status of the microcode */
364 	req->alternate_caddr = (uint64_t *)(dptr + rlen);
365 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
366 
367 	/* Preparing completion addr, +1 for completion code */
368 	caddr.vaddr = dptr + rlen + 1;
369 	caddr.dma_addr = mphys + dlen + rlen + 1;
370 
371 	cpt_fill_req_comp_addr(req, caddr);
372 }
373 
374 static __rte_always_inline void
375 cpt_rsa_crt_prep(struct asym_op_params *rsa_params,
376 		 struct rte_crypto_rsa_xform *rsa,
377 		 rte_crypto_param *crypto_param)
378 {
379 	struct cpt_request_info *req = rsa_params->req;
380 	phys_addr_t mphys = rsa_params->meta_buf;
381 	uint32_t qInv_len = rsa->qt.qInv.length;
382 	struct rte_crypto_rsa_op_param rsa_op;
383 	uint32_t dP_len = rsa->qt.dP.length;
384 	uint32_t dQ_len = rsa->qt.dQ.length;
385 	uint32_t p_len = rsa->qt.p.length;
386 	uint32_t q_len = rsa->qt.q.length;
387 	uint32_t mod_len = rsa->n.length;
388 	struct rte_crypto_op **op;
389 	vq_cmd_word0_t vq_cmd_w0;
390 	uint64_t total_key_len;
391 	uint32_t dlen, rlen;
392 	uint32_t in_size;
393 	buf_ptr_t caddr;
394 	uint8_t *dptr;
395 
396 	/* Extracting rsa op form params->req->op[1]->asym->rsa */
397 	op = RTE_PTR_ADD(req->op, sizeof(uintptr_t));
398 	rsa_op = ((struct rte_crypto_op *)*op)->asym->rsa;
399 	total_key_len = p_len + q_len + dP_len + dQ_len + qInv_len;
400 
401 	/* Input buffer */
402 	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
403 	memcpy(dptr, rsa->qt.q.data, total_key_len);
404 	dptr += total_key_len;
405 
406 	in_size = crypto_param->length;
407 	memcpy(dptr, crypto_param->data, in_size);
408 
409 	dptr += in_size;
410 	dlen = total_key_len + in_size;
411 
412 	/* Result buffer */
413 	rlen = mod_len;
414 
415 	if (rsa_op.pad == RTE_CRYPTO_RSA_PADDING_NONE) {
416 		/*Use mod_exp operation for no_padding type */
417 		vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_MODEX_CRT;
418 	} else {
419 		if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_SIGN) {
420 			vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_ENC_CRT;
421 			/* Private encrypt, use BT1 */
422 			vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE1;
423 		} else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) {
424 			vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_PKCS_DEC_CRT;
425 			/* Private decrypt, use BT2 */
426 			vq_cmd_w0.s.param2 = CPT_BLOCK_TYPE2;
427 			/* + 2 for decrypted len */
428 			rlen += 2;
429 		}
430 	}
431 
432 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MODEX;
433 
434 	/* GP op header */
435 	vq_cmd_w0.s.param1 = mod_len;
436 	vq_cmd_w0.s.dlen = dlen;
437 
438 	/* Filling cpt_request_info structure */
439 	req->ist.ei0 = vq_cmd_w0.u64;
440 	req->ist.ei1 = mphys;
441 	req->ist.ei2 = mphys + dlen;
442 
443 	/* Result pointer to store result data */
444 	req->rptr = dptr;
445 
446 	/* alternate_caddr to write completion status of the microcode */
447 	req->alternate_caddr = (uint64_t *)(dptr + rlen);
448 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
449 
450 	/* Preparing completion addr, +1 for completion code */
451 	caddr.vaddr = dptr + rlen + 1;
452 	caddr.dma_addr = mphys + dlen + rlen + 1;
453 
454 	cpt_fill_req_comp_addr(req, caddr);
455 }
456 
457 static __rte_always_inline int __rte_hot
458 cpt_enqueue_rsa_op(struct rte_crypto_op *op,
459 	       struct asym_op_params *params,
460 	       struct cpt_asym_sess_misc *sess)
461 {
462 	struct rte_crypto_rsa_op_param *rsa = &op->asym->rsa;
463 
464 	switch (rsa->op_type) {
465 	case RTE_CRYPTO_ASYM_OP_VERIFY:
466 		cpt_rsa_prep(params, &sess->rsa_ctx, &rsa->sign);
467 		break;
468 	case RTE_CRYPTO_ASYM_OP_ENCRYPT:
469 		cpt_rsa_prep(params, &sess->rsa_ctx, &rsa->message);
470 		break;
471 	case RTE_CRYPTO_ASYM_OP_SIGN:
472 		cpt_rsa_crt_prep(params, &sess->rsa_ctx, &rsa->message);
473 		break;
474 	case RTE_CRYPTO_ASYM_OP_DECRYPT:
475 		cpt_rsa_crt_prep(params, &sess->rsa_ctx, &rsa->cipher);
476 		break;
477 	default:
478 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
479 		return -EINVAL;
480 	}
481 	return 0;
482 }
483 
484 static const struct cpt_ec_group ec_grp[CPT_EC_ID_PMAX] = {
485 	{
486 		.prime = {
487 				.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
488 					 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
489 					 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
490 					 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
491 				.length = 24,
492 			},
493 		.order = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
494 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
495 				   0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B,
496 				   0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31},
497 			  .length = 24},
498 		.consta = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
499 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
500 				    0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF,
501 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC},
502 			   .length = 24},
503 		.constb = {.data = {0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C,
504 				    0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB,
505 				    0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8,
506 				    0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1},
507 			   .length = 24},
508 	},
509 	{
510 		.prime = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
511 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
512 				   0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
513 				   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
514 			  .length = 28},
515 		.order = {.data = {0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
516 				   0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
517 				   0X16, 0XA2, 0XE0, 0XB8, 0XF0, 0X3E, 0X13,
518 				   0XDD, 0X29, 0X45, 0X5C, 0X5C, 0X2A, 0X3D},
519 			  .length = 28},
520 		.consta = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
521 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
522 				    0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
523 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
524 			   .length = 28},
525 		.constb = {.data = {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3,
526 				    0xAB, 0xF5, 0x41, 0x32, 0x56, 0x50, 0x44,
527 				    0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27,
528 				    0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
529 			   .length = 28},
530 	},
531 	{
532 		.prime = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
533 				   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 				   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
535 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
536 				   0xFF, 0xFF, 0xFF, 0xFF},
537 			  .length = 32},
538 		.order = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
539 				   0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
540 				   0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7,
541 				   0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2,
542 				   0xFC, 0x63, 0x25, 0x51},
543 			  .length = 32},
544 		.consta = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
545 				    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 				    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
547 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
548 				    0xFF, 0xFF, 0xFF, 0xFC},
549 			   .length = 32},
550 		.constb = {.data = {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93,
551 				    0xE7, 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98,
552 				    0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC,
553 				    0x53, 0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E,
554 				    0x27, 0xD2, 0x60, 0x4B},
555 			   .length = 32},
556 	},
557 	{
558 		.prime = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
559 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
560 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
561 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
562 				   0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF,
563 				   0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 				   0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
565 			  .length = 48},
566 		.order = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
567 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
568 				   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
569 				   0xFF, 0xFF, 0xFF, 0xC7, 0x63, 0x4D, 0x81,
570 				   0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D,
571 				   0xB2, 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC,
572 				   0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73},
573 			  .length = 48},
574 		.consta = {.data = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
575 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
576 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
577 				    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
578 				    0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF,
579 				    0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 				    0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC},
581 			   .length = 48},
582 		.constb = {.data = {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7,
583 				    0xE4, 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8,
584 				    0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE,
585 				    0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8F,
586 				    0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39,
587 				    0x8D, 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85,
588 				    0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF},
589 			   .length = 48},
590 	},
591 	{.prime = {.data = {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
592 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
593 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
594 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
595 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
596 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
597 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
598 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
599 			    0xFF, 0xFF},
600 		   .length = 66},
601 	 .order = {.data = {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
602 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
603 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
604 			    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
605 			    0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
606 			    0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
607 			    0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
608 			    0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
609 			    0x64, 0x09},
610 		   .length = 66},
611 	 .consta = {.data = {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
612 			     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
613 			     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
614 			     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
615 			     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
616 			     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
617 			     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
618 			     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
619 			     0xFF, 0xFC},
620 		    .length = 66},
621 	 .constb = {.data = {0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C,
622 			     0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85,
623 			     0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
624 			     0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1,
625 			     0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E,
626 			     0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
627 			     0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C,
628 			     0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50,
629 			     0x3F, 0x00},
630 		    .length = 66}}};
631 
632 static __rte_always_inline void
633 cpt_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
634 		    struct asym_op_params *ecdsa_params,
635 		    uint64_t fpm_table_iova,
636 		    uint8_t curveid)
637 {
638 	struct cpt_request_info *req = ecdsa_params->req;
639 	uint16_t message_len = ecdsa->message.length;
640 	phys_addr_t mphys = ecdsa_params->meta_buf;
641 	uint16_t pkey_len = ecdsa->pkey.length;
642 	uint16_t p_align, k_align, m_align;
643 	uint16_t k_len = ecdsa->k.length;
644 	uint16_t order_len, prime_len;
645 	uint16_t o_offset, pk_offset;
646 	vq_cmd_word0_t vq_cmd_w0;
647 	uint16_t rlen, dlen;
648 	buf_ptr_t caddr;
649 	uint8_t *dptr;
650 
651 	prime_len = ec_grp[curveid].prime.length;
652 	order_len = ec_grp[curveid].order.length;
653 
654 	/* Truncate input length to curve prime length */
655 	if (message_len > prime_len)
656 		message_len = prime_len;
657 	m_align = RTE_ALIGN_CEIL(message_len, 8);
658 
659 	p_align = RTE_ALIGN_CEIL(prime_len, 8);
660 	k_align = RTE_ALIGN_CEIL(k_len, 8);
661 
662 	/* Set write offset for order and private key */
663 	o_offset = prime_len - order_len;
664 	pk_offset = prime_len - pkey_len;
665 
666 	/* Input buffer */
667 	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
668 
669 	/*
670 	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(scalar len, input len),
671 	 * ROUNDUP8(priv key len, prime len, order len)).
672 	 * Please note, private key, order cannot exceed prime
673 	 * length i.e 3 * p_align.
674 	 */
675 	dlen = sizeof(fpm_table_iova) + k_align + m_align + p_align * 5;
676 
677 	memset(dptr, 0, dlen);
678 
679 	*(uint64_t *)dptr = fpm_table_iova;
680 	dptr += sizeof(fpm_table_iova);
681 
682 	memcpy(dptr, ecdsa->k.data, k_len);
683 	dptr += k_align;
684 
685 	memcpy(dptr, ec_grp[curveid].prime.data, prime_len);
686 	dptr += p_align;
687 
688 	memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len);
689 	dptr += p_align;
690 
691 	memcpy(dptr + pk_offset, ecdsa->pkey.data, pkey_len);
692 	dptr += p_align;
693 
694 	memcpy(dptr, ecdsa->message.data, message_len);
695 	dptr += m_align;
696 
697 	memcpy(dptr, ec_grp[curveid].consta.data, prime_len);
698 	dptr += p_align;
699 
700 	memcpy(dptr, ec_grp[curveid].constb.data, prime_len);
701 	dptr += p_align;
702 
703 	/* 2 * prime length (for sign r and s ) */
704 	rlen = 2 * p_align;
705 
706 	/* Setup opcodes */
707 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ECDSA;
708 	vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_ECDSA_SIGN;
709 
710 	/* GP op header */
711 	vq_cmd_w0.s.param1 = curveid | (message_len << 8);
712 	vq_cmd_w0.s.param2 = (pkey_len << 8) | k_len;
713 	vq_cmd_w0.s.dlen = dlen;
714 
715 	/* Filling cpt_request_info structure */
716 	req->ist.ei0 = vq_cmd_w0.u64;
717 	req->ist.ei1 = mphys;
718 	req->ist.ei2 = mphys + dlen;
719 
720 	/* Result pointer to store result data */
721 	req->rptr = dptr;
722 
723 	/* alternate_caddr to write completion status of the microcode */
724 	req->alternate_caddr = (uint64_t *)(dptr + rlen);
725 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
726 
727 	/* Preparing completion addr, +1 for completion code */
728 	caddr.vaddr = dptr + rlen + 1;
729 	caddr.dma_addr = mphys + dlen + rlen + 1;
730 
731 	cpt_fill_req_comp_addr(req, caddr);
732 }
733 
734 static __rte_always_inline void
735 cpt_ecdsa_verify_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
736 		      struct asym_op_params *ecdsa_params,
737 		      uint64_t fpm_table_iova,
738 		      uint8_t curveid)
739 {
740 	struct cpt_request_info *req = ecdsa_params->req;
741 	uint32_t message_len = ecdsa->message.length;
742 	phys_addr_t mphys = ecdsa_params->meta_buf;
743 	uint16_t o_offset, r_offset, s_offset;
744 	uint16_t qx_len = ecdsa->q.x.length;
745 	uint16_t qy_len = ecdsa->q.y.length;
746 	uint16_t r_len = ecdsa->r.length;
747 	uint16_t s_len = ecdsa->s.length;
748 	uint16_t order_len, prime_len;
749 	uint16_t qx_offset, qy_offset;
750 	uint16_t p_align, m_align;
751 	vq_cmd_word0_t vq_cmd_w0;
752 	buf_ptr_t caddr;
753 	uint16_t dlen;
754 	uint8_t *dptr;
755 
756 	prime_len = ec_grp[curveid].prime.length;
757 	order_len = ec_grp[curveid].order.length;
758 
759 	/* Truncate input length to curve prime length */
760 	if (message_len > prime_len)
761 		message_len = prime_len;
762 
763 	m_align = RTE_ALIGN_CEIL(message_len, 8);
764 	p_align = RTE_ALIGN_CEIL(prime_len, 8);
765 
766 	/* Set write offset for sign, order and public key coordinates */
767 	o_offset = prime_len - order_len;
768 	qx_offset = prime_len - qx_len;
769 	qy_offset = prime_len - qy_len;
770 	r_offset = prime_len - r_len;
771 	s_offset = prime_len - s_len;
772 
773 	/* Input buffer */
774 	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
775 
776 	/*
777 	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(message len),
778 	 * ROUNDUP8(sign len(r and s), public key len(x and y coordinates),
779 	 * prime len, order len)).
780 	 * Please note sign, public key and order can not exceed prime length
781 	 * i.e. 6 * p_align
782 	 */
783 	dlen = sizeof(fpm_table_iova) + m_align + (8 * p_align);
784 
785 	memset(dptr, 0, dlen);
786 
787 	*(uint64_t *)dptr = fpm_table_iova;
788 	dptr += sizeof(fpm_table_iova);
789 
790 	memcpy(dptr + r_offset, ecdsa->r.data, r_len);
791 	dptr += p_align;
792 
793 	memcpy(dptr + s_offset, ecdsa->s.data, s_len);
794 	dptr += p_align;
795 
796 	memcpy(dptr, ecdsa->message.data, message_len);
797 	dptr += m_align;
798 
799 	memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len);
800 	dptr += p_align;
801 
802 	memcpy(dptr, ec_grp[curveid].prime.data, prime_len);
803 	dptr += p_align;
804 
805 	memcpy(dptr + qx_offset, ecdsa->q.x.data, qx_len);
806 	dptr += p_align;
807 
808 	memcpy(dptr + qy_offset, ecdsa->q.y.data, qy_len);
809 	dptr += p_align;
810 
811 	memcpy(dptr, ec_grp[curveid].consta.data, prime_len);
812 	dptr += p_align;
813 
814 	memcpy(dptr, ec_grp[curveid].constb.data, prime_len);
815 	dptr += p_align;
816 
817 	/* Setup opcodes */
818 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ECDSA;
819 	vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_ECDSA_VERIFY;
820 
821 	/* GP op header */
822 	vq_cmd_w0.s.param1 = curveid | (message_len << 8);
823 	vq_cmd_w0.s.param2 = 0;
824 	vq_cmd_w0.s.dlen = dlen;
825 
826 	/* Filling cpt_request_info structure */
827 	req->ist.ei0 = vq_cmd_w0.u64;
828 	req->ist.ei1 = mphys;
829 	req->ist.ei2 = mphys + dlen;
830 
831 	/* Result pointer to store result data */
832 	req->rptr = dptr;
833 
834 	/* alternate_caddr to write completion status of the microcode */
835 	req->alternate_caddr = (uint64_t *)dptr;
836 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
837 
838 	/* Preparing completion addr, +1 for completion code */
839 	caddr.vaddr = dptr + 1;
840 	caddr.dma_addr = mphys + dlen + 1;
841 
842 	cpt_fill_req_comp_addr(req, caddr);
843 }
844 
845 static __rte_always_inline int __rte_hot
846 cpt_enqueue_ecdsa_op(struct rte_crypto_op *op,
847 		     struct asym_op_params *params,
848 		     struct cpt_asym_sess_misc *sess,
849 		     uint64_t *fpm_iova)
850 {
851 	struct rte_crypto_ecdsa_op_param *ecdsa = &op->asym->ecdsa;
852 	uint8_t curveid = sess->ec_ctx.curveid;
853 
854 	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
855 		cpt_ecdsa_sign_prep(ecdsa, params, fpm_iova[curveid], curveid);
856 	else if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
857 		cpt_ecdsa_verify_prep(ecdsa, params, fpm_iova[curveid],
858 				      curveid);
859 	else {
860 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
861 		return -EINVAL;
862 	}
863 	return 0;
864 }
865 
866 static __rte_always_inline int
867 cpt_ecpm_prep(struct rte_crypto_ecpm_op_param *ecpm,
868 	      struct asym_op_params *asym_params,
869 	      uint8_t curveid)
870 {
871 	struct cpt_request_info *req = asym_params->req;
872 	phys_addr_t mphys = asym_params->meta_buf;
873 	uint16_t x1_len = ecpm->p.x.length;
874 	uint16_t y1_len = ecpm->p.y.length;
875 	uint16_t scalar_align, p_align;
876 	uint16_t dlen, rlen, prime_len;
877 	uint16_t x1_offset, y1_offset;
878 	vq_cmd_word0_t vq_cmd_w0;
879 	buf_ptr_t caddr;
880 	uint8_t *dptr;
881 
882 	prime_len = ec_grp[curveid].prime.length;
883 
884 	/* Input buffer */
885 	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
886 
887 	p_align = RTE_ALIGN_CEIL(prime_len, 8);
888 	scalar_align = RTE_ALIGN_CEIL(ecpm->scalar.length, 8);
889 
890 	/*
891 	 * Set dlen = sum(ROUNDUP8(input point(x and y coordinates), prime,
892 	 * scalar length),
893 	 * Please note point length is equivalent to prime of the curve
894 	 */
895 	dlen = 5 * p_align + scalar_align;
896 
897 	x1_offset = prime_len - x1_len;
898 	y1_offset = prime_len - y1_len;
899 
900 	memset(dptr, 0, dlen);
901 
902 	/* Copy input point, scalar, prime */
903 	memcpy(dptr + x1_offset, ecpm->p.x.data, x1_len);
904 	dptr += p_align;
905 	memcpy(dptr + y1_offset, ecpm->p.y.data, y1_len);
906 	dptr += p_align;
907 	memcpy(dptr, ecpm->scalar.data, ecpm->scalar.length);
908 	dptr += scalar_align;
909 	memcpy(dptr, ec_grp[curveid].prime.data, ec_grp[curveid].prime.length);
910 	dptr += p_align;
911 
912 	memcpy(dptr, ec_grp[curveid].consta.data,
913 	       ec_grp[curveid].consta.length);
914 	dptr += p_align;
915 
916 	memcpy(dptr, ec_grp[curveid].constb.data,
917 	       ec_grp[curveid].constb.length);
918 	dptr += p_align;
919 
920 	/* Setup opcodes */
921 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ECC;
922 	vq_cmd_w0.s.opcode.minor = CPT_MINOR_OP_ECC_UMP;
923 
924 	/* GP op header */
925 	vq_cmd_w0.s.param1 = curveid;
926 	vq_cmd_w0.s.param2 = ecpm->scalar.length;
927 	vq_cmd_w0.s.dlen = dlen;
928 
929 	/* Filling cpt_request_info structure */
930 	req->ist.ei0 = vq_cmd_w0.u64;
931 	req->ist.ei1 = mphys;
932 	req->ist.ei2 = mphys + dlen;
933 
934 	/* Result buffer will store output point where length of
935 	 * each coordinate will be of prime length, thus set
936 	 * rlen to twice of prime length.
937 	 */
938 	rlen = p_align << 1;
939 	req->rptr = dptr;
940 
941 	/* alternate_caddr to write completion status by the microcode */
942 	req->alternate_caddr = (uint64_t *)(dptr + rlen);
943 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
944 
945 	/* Preparing completion addr, +1 for completion code */
946 	caddr.vaddr = dptr + rlen + 1;
947 	caddr.dma_addr = mphys + dlen + rlen + 1;
948 
949 	cpt_fill_req_comp_addr(req, caddr);
950 	return 0;
951 }
952 #endif /* _CPT_UCODE_ASYM_H_ */
953