xref: /dpdk/drivers/crypto/cnxk/cnxk_ae.h (revision 06c047b6)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 
5 #ifndef _CNXK_AE_H_
6 #define _CNXK_AE_H_
7 
8 #include <rte_common.h>
9 #include <rte_crypto_asym.h>
10 #include <rte_malloc.h>
11 
12 #include "roc_api.h"
13 #include "cnxk_cryptodev_ops.h"
14 
15 struct cnxk_ae_sess {
16 	enum rte_crypto_asym_xform_type xfrm_type;
17 	union {
18 		struct rte_crypto_rsa_xform rsa_ctx;
19 		struct rte_crypto_modex_xform mod_ctx;
20 		struct roc_ae_ec_ctx ec_ctx;
21 	};
22 	uint64_t *cnxk_fpm_iova;
23 	struct roc_ae_ec_group **ec_grp;
24 	uint64_t cpt_inst_w7;
25 };
26 
27 static __rte_always_inline void
cnxk_ae_modex_param_normalize(uint8_t ** data,size_t * len)28 cnxk_ae_modex_param_normalize(uint8_t **data, size_t *len)
29 {
30 	size_t i;
31 
32 	/* Strip leading NUL bytes */
33 	for (i = 0; i < *len; i++) {
34 		if ((*data)[i] != 0)
35 			break;
36 	}
37 	*data += i;
38 	*len -= i;
39 }
40 
41 static __rte_always_inline int
cnxk_ae_fill_modex_params(struct cnxk_ae_sess * sess,struct rte_crypto_asym_xform * xform)42 cnxk_ae_fill_modex_params(struct cnxk_ae_sess *sess,
43 			  struct rte_crypto_asym_xform *xform)
44 {
45 	struct rte_crypto_modex_xform *ctx = &sess->mod_ctx;
46 	size_t exp_len = xform->modex.exponent.length;
47 	size_t mod_len = xform->modex.modulus.length;
48 	uint8_t *exp = xform->modex.exponent.data;
49 	uint8_t *mod = xform->modex.modulus.data;
50 
51 	cnxk_ae_modex_param_normalize(&mod, &mod_len);
52 	cnxk_ae_modex_param_normalize(&exp, &exp_len);
53 
54 	if (unlikely(exp_len == 0 || mod_len == 0))
55 		return -EINVAL;
56 
57 	if (unlikely(exp_len > mod_len))
58 		return -ENOTSUP;
59 
60 	/* Allocate buffer to hold modexp params */
61 	ctx->modulus.data = rte_malloc(NULL, mod_len + exp_len, 0);
62 	if (ctx->modulus.data == NULL)
63 		return -ENOMEM;
64 
65 	/* Set up modexp prime modulus and private exponent */
66 	memcpy(ctx->modulus.data, mod, mod_len);
67 	ctx->exponent.data = ctx->modulus.data + mod_len;
68 	memcpy(ctx->exponent.data, exp, exp_len);
69 
70 	ctx->modulus.length = mod_len;
71 	ctx->exponent.length = exp_len;
72 
73 	return 0;
74 }
75 
76 static __rte_always_inline int
cnxk_ae_fill_rsa_params(struct cnxk_ae_sess * sess,struct rte_crypto_asym_xform * xform)77 cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess,
78 			struct rte_crypto_asym_xform *xform)
79 {
80 	struct rte_crypto_rsa_priv_key_qt qt = xform->rsa.qt;
81 	struct rte_crypto_rsa_xform *xfrm_rsa = &xform->rsa;
82 	struct rte_crypto_rsa_xform *rsa = &sess->rsa_ctx;
83 	size_t mod_len = xfrm_rsa->n.length;
84 	size_t exp_len = xfrm_rsa->e.length;
85 	uint64_t total_size;
86 	size_t len = 0;
87 
88 	if (qt.p.length != 0 && qt.p.data == NULL)
89 		return -EINVAL;
90 
91 	/* Make sure key length used is not more than mod_len/2 */
92 	if (qt.p.data != NULL)
93 		len = (((mod_len / 2) < qt.p.length) ? 0 : qt.p.length);
94 
95 	/* Total size required for RSA key params(n,e,(q,dQ,p,dP,qInv)) */
96 	total_size = mod_len + exp_len + 5 * len;
97 
98 	/* Allocate buffer to hold all RSA keys */
99 	rsa->n.data = rte_malloc(NULL, total_size, 0);
100 	if (rsa->n.data == NULL)
101 		return -ENOMEM;
102 
103 	/* Set up RSA prime modulus and public key exponent */
104 	memcpy(rsa->n.data, xfrm_rsa->n.data, mod_len);
105 	rsa->e.data = rsa->n.data + mod_len;
106 	memcpy(rsa->e.data, xfrm_rsa->e.data, exp_len);
107 
108 	/* Private key in quintuple format */
109 	if (len != 0) {
110 		rsa->qt.q.data = rsa->e.data + exp_len;
111 		memcpy(rsa->qt.q.data, qt.q.data, qt.q.length);
112 		rsa->qt.dQ.data = rsa->qt.q.data + qt.q.length;
113 		memcpy(rsa->qt.dQ.data, qt.dQ.data, qt.dQ.length);
114 		rsa->qt.p.data = rsa->qt.dQ.data + qt.dQ.length;
115 		if (qt.p.data != NULL)
116 			memcpy(rsa->qt.p.data, qt.p.data, qt.p.length);
117 		rsa->qt.dP.data = rsa->qt.p.data + qt.p.length;
118 		memcpy(rsa->qt.dP.data, qt.dP.data, qt.dP.length);
119 		rsa->qt.qInv.data = rsa->qt.dP.data + qt.dP.length;
120 		memcpy(rsa->qt.qInv.data, qt.qInv.data, qt.qInv.length);
121 
122 		rsa->qt.q.length = qt.q.length;
123 		rsa->qt.dQ.length = qt.dQ.length;
124 		rsa->qt.p.length = qt.p.length;
125 		rsa->qt.dP.length = qt.dP.length;
126 		rsa->qt.qInv.length = qt.qInv.length;
127 	}
128 	rsa->n.length = mod_len;
129 	rsa->e.length = exp_len;
130 
131 	return 0;
132 }
133 
134 static __rte_always_inline int
cnxk_ae_fill_ec_params(struct cnxk_ae_sess * sess,struct rte_crypto_asym_xform * xform)135 cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
136 		       struct rte_crypto_asym_xform *xform)
137 {
138 	struct roc_ae_ec_ctx *ec = &sess->ec_ctx;
139 
140 	switch (xform->ec.curve_id) {
141 	case RTE_CRYPTO_EC_GROUP_SECP192R1:
142 		ec->curveid = ROC_AE_EC_ID_P192;
143 		break;
144 	case RTE_CRYPTO_EC_GROUP_SECP224R1:
145 		ec->curveid = ROC_AE_EC_ID_P224;
146 		break;
147 	case RTE_CRYPTO_EC_GROUP_SECP256R1:
148 		ec->curveid = ROC_AE_EC_ID_P256;
149 		break;
150 	case RTE_CRYPTO_EC_GROUP_SECP384R1:
151 		ec->curveid = ROC_AE_EC_ID_P384;
152 		break;
153 	case RTE_CRYPTO_EC_GROUP_SECP521R1:
154 		ec->curveid = ROC_AE_EC_ID_P521;
155 		break;
156 	default:
157 		/* Only NIST curves (FIPS 186-4) are supported */
158 		return -EINVAL;
159 	}
160 
161 	return 0;
162 }
163 
164 static __rte_always_inline int
cnxk_ae_fill_session_parameters(struct cnxk_ae_sess * sess,struct rte_crypto_asym_xform * xform)165 cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
166 				struct rte_crypto_asym_xform *xform)
167 {
168 	int ret;
169 
170 	sess->xfrm_type = xform->xform_type;
171 
172 	switch (xform->xform_type) {
173 	case RTE_CRYPTO_ASYM_XFORM_RSA:
174 		ret = cnxk_ae_fill_rsa_params(sess, xform);
175 		break;
176 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
177 		ret = cnxk_ae_fill_modex_params(sess, xform);
178 		break;
179 	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
180 		/* Fall through */
181 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
182 		ret = cnxk_ae_fill_ec_params(sess, xform);
183 		break;
184 	default:
185 		return -ENOTSUP;
186 	}
187 	return ret;
188 }
189 
190 static inline void
cnxk_ae_free_session_parameters(struct cnxk_ae_sess * sess)191 cnxk_ae_free_session_parameters(struct cnxk_ae_sess *sess)
192 {
193 	struct rte_crypto_modex_xform *mod;
194 	struct rte_crypto_rsa_xform *rsa;
195 
196 	switch (sess->xfrm_type) {
197 	case RTE_CRYPTO_ASYM_XFORM_RSA:
198 		rsa = &sess->rsa_ctx;
199 		rte_free(rsa->n.data);
200 		break;
201 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
202 		mod = &sess->mod_ctx;
203 		rte_free(mod->modulus.data);
204 		break;
205 	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
206 		/* Fall through */
207 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
208 		break;
209 	default:
210 		break;
211 	}
212 }
213 
214 static __rte_always_inline int
cnxk_ae_modex_prep(struct rte_crypto_op * op,struct roc_ae_buf_ptr * meta_buf,struct rte_crypto_modex_xform * mod,struct cpt_inst_s * inst)215 cnxk_ae_modex_prep(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
216 		   struct rte_crypto_modex_xform *mod, struct cpt_inst_s *inst)
217 {
218 	uint32_t exp_len = mod->exponent.length;
219 	uint32_t mod_len = mod->modulus.length;
220 	struct rte_crypto_mod_op_param mod_op;
221 	uint64_t total_key_len;
222 	union cpt_inst_w4 w4;
223 	uint32_t base_len;
224 	uint32_t dlen;
225 	uint8_t *dptr;
226 
227 	mod_op = op->asym->modex;
228 
229 	base_len = mod_op.base.length;
230 	if (unlikely(base_len > mod_len)) {
231 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
232 		return -ENOTSUP;
233 	}
234 
235 	total_key_len = mod_len + exp_len;
236 
237 	/* Input buffer */
238 	dptr = meta_buf->vaddr;
239 	inst->dptr = (uintptr_t)dptr;
240 	memcpy(dptr, mod->modulus.data, total_key_len);
241 	dptr += total_key_len;
242 	memcpy(dptr, mod_op.base.data, base_len);
243 	dptr += base_len;
244 	dlen = total_key_len + base_len;
245 
246 	/* Setup opcodes */
247 	w4.s.opcode_major = ROC_AE_MAJOR_OP_MODEX;
248 	w4.s.opcode_minor = ROC_AE_MINOR_OP_MODEX;
249 
250 	w4.s.param1 = mod_len;
251 	w4.s.param2 = exp_len;
252 	w4.s.dlen = dlen;
253 
254 	inst->w4.u64 = w4.u64;
255 	inst->rptr = (uintptr_t)dptr;
256 
257 	return 0;
258 }
259 
260 static __rte_always_inline void
cnxk_ae_rsa_prep(struct rte_crypto_op * op,struct roc_ae_buf_ptr * meta_buf,struct rte_crypto_rsa_xform * rsa,rte_crypto_param * crypto_param,struct cpt_inst_s * inst)261 cnxk_ae_rsa_prep(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
262 		 struct rte_crypto_rsa_xform *rsa,
263 		 rte_crypto_param *crypto_param, struct cpt_inst_s *inst)
264 {
265 	struct rte_crypto_rsa_op_param rsa_op;
266 	uint32_t mod_len = rsa->n.length;
267 	uint32_t exp_len = rsa->e.length;
268 	uint64_t total_key_len;
269 	union cpt_inst_w4 w4;
270 	uint32_t in_size;
271 	uint32_t dlen;
272 	uint8_t *dptr;
273 
274 	rsa_op = op->asym->rsa;
275 	total_key_len = mod_len + exp_len;
276 
277 	/* Input buffer */
278 	dptr = meta_buf->vaddr;
279 	inst->dptr = (uintptr_t)dptr;
280 	memcpy(dptr, rsa->n.data, total_key_len);
281 	dptr += total_key_len;
282 
283 	in_size = crypto_param->length;
284 	memcpy(dptr, crypto_param->data, in_size);
285 
286 	dptr += in_size;
287 	dlen = total_key_len + in_size;
288 
289 	if (rsa_op.pad == RTE_CRYPTO_RSA_PADDING_NONE) {
290 		/* Use mod_exp operation for no_padding type */
291 		w4.s.opcode_minor = ROC_AE_MINOR_OP_MODEX;
292 		w4.s.param2 = exp_len;
293 	} else {
294 		if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) {
295 			w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_ENC;
296 			/* Public key encrypt, use BT2*/
297 			w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE2 |
298 				      ((uint16_t)(exp_len) << 1);
299 		} else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) {
300 			w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_DEC;
301 			/* Public key decrypt, use BT1 */
302 			w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE1;
303 		}
304 	}
305 
306 	w4.s.opcode_major = ROC_AE_MAJOR_OP_MODEX;
307 
308 	w4.s.param1 = mod_len;
309 	w4.s.dlen = dlen;
310 
311 	inst->w4.u64 = w4.u64;
312 	inst->rptr = (uintptr_t)dptr;
313 }
314 
315 static __rte_always_inline void
cnxk_ae_rsa_crt_prep(struct rte_crypto_op * op,struct roc_ae_buf_ptr * meta_buf,struct rte_crypto_rsa_xform * rsa,rte_crypto_param * crypto_param,struct cpt_inst_s * inst)316 cnxk_ae_rsa_crt_prep(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
317 		     struct rte_crypto_rsa_xform *rsa,
318 		     rte_crypto_param *crypto_param, struct cpt_inst_s *inst)
319 {
320 	uint32_t qInv_len = rsa->qt.qInv.length;
321 	struct rte_crypto_rsa_op_param rsa_op;
322 	uint32_t dP_len = rsa->qt.dP.length;
323 	uint32_t dQ_len = rsa->qt.dQ.length;
324 	uint32_t p_len = rsa->qt.p.length;
325 	uint32_t q_len = rsa->qt.q.length;
326 	uint32_t mod_len = rsa->n.length;
327 	uint64_t total_key_len;
328 	union cpt_inst_w4 w4;
329 	uint32_t in_size;
330 	uint32_t dlen;
331 	uint8_t *dptr;
332 
333 	rsa_op = op->asym->rsa;
334 	total_key_len = p_len + q_len + dP_len + dQ_len + qInv_len;
335 
336 	/* Input buffer */
337 	dptr = meta_buf->vaddr;
338 	inst->dptr = (uintptr_t)dptr;
339 	memcpy(dptr, rsa->qt.q.data, total_key_len);
340 	dptr += total_key_len;
341 
342 	in_size = crypto_param->length;
343 	memcpy(dptr, crypto_param->data, in_size);
344 
345 	dptr += in_size;
346 	dlen = total_key_len + in_size;
347 
348 	if (rsa_op.pad == RTE_CRYPTO_RSA_PADDING_NONE) {
349 		/*Use mod_exp operation for no_padding type */
350 		w4.s.opcode_minor = ROC_AE_MINOR_OP_MODEX_CRT;
351 	} else {
352 		if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_SIGN) {
353 			w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_ENC_CRT;
354 			/* Private encrypt, use BT1 */
355 			w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE1;
356 		} else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) {
357 			w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_DEC_CRT;
358 			/* Private decrypt, use BT2 */
359 			w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE2;
360 		}
361 	}
362 
363 	w4.s.opcode_major = ROC_AE_MAJOR_OP_MODEX;
364 
365 	w4.s.param1 = mod_len;
366 	w4.s.dlen = dlen;
367 
368 	inst->w4.u64 = w4.u64;
369 	inst->rptr = (uintptr_t)dptr;
370 }
371 
372 static __rte_always_inline int __rte_hot
cnxk_ae_enqueue_rsa_op(struct rte_crypto_op * op,struct roc_ae_buf_ptr * meta_buf,struct cnxk_ae_sess * sess,struct cpt_inst_s * inst)373 cnxk_ae_enqueue_rsa_op(struct rte_crypto_op *op,
374 		       struct roc_ae_buf_ptr *meta_buf,
375 		       struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
376 {
377 	struct rte_crypto_rsa_op_param *rsa = &op->asym->rsa;
378 
379 	switch (rsa->op_type) {
380 	case RTE_CRYPTO_ASYM_OP_VERIFY:
381 		cnxk_ae_rsa_prep(op, meta_buf, &sess->rsa_ctx, &rsa->sign,
382 				 inst);
383 		break;
384 	case RTE_CRYPTO_ASYM_OP_ENCRYPT:
385 		cnxk_ae_rsa_prep(op, meta_buf, &sess->rsa_ctx, &rsa->message,
386 				 inst);
387 		break;
388 	case RTE_CRYPTO_ASYM_OP_SIGN:
389 		cnxk_ae_rsa_crt_prep(op, meta_buf, &sess->rsa_ctx,
390 				     &rsa->message, inst);
391 		break;
392 	case RTE_CRYPTO_ASYM_OP_DECRYPT:
393 		cnxk_ae_rsa_crt_prep(op, meta_buf, &sess->rsa_ctx, &rsa->cipher,
394 				     inst);
395 		break;
396 	default:
397 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
398 		return -EINVAL;
399 	}
400 	return 0;
401 }
402 
403 static __rte_always_inline void
cnxk_ae_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param * ecdsa,struct roc_ae_buf_ptr * meta_buf,uint64_t fpm_table_iova,struct roc_ae_ec_group * ec_grp,uint8_t curveid,struct cpt_inst_s * inst)404 cnxk_ae_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
405 			struct roc_ae_buf_ptr *meta_buf,
406 			uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
407 			uint8_t curveid, struct cpt_inst_s *inst)
408 {
409 	uint16_t message_len = ecdsa->message.length;
410 	uint16_t pkey_len = ecdsa->pkey.length;
411 	uint16_t p_align, k_align, m_align;
412 	uint16_t k_len = ecdsa->k.length;
413 	uint16_t order_len, prime_len;
414 	uint16_t o_offset, pk_offset;
415 	union cpt_inst_w4 w4;
416 	uint16_t dlen;
417 	uint8_t *dptr;
418 
419 	prime_len = ec_grp->prime.length;
420 	order_len = ec_grp->order.length;
421 
422 	/* Truncate input length to curve prime length */
423 	if (message_len > prime_len)
424 		message_len = prime_len;
425 	m_align = RTE_ALIGN_CEIL(message_len, 8);
426 
427 	p_align = RTE_ALIGN_CEIL(prime_len, 8);
428 	k_align = RTE_ALIGN_CEIL(k_len, 8);
429 
430 	/* Set write offset for order and private key */
431 	o_offset = prime_len - order_len;
432 	pk_offset = prime_len - pkey_len;
433 
434 	/* Input buffer */
435 	dptr = meta_buf->vaddr;
436 	inst->dptr = (uintptr_t)dptr;
437 
438 	/*
439 	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(scalar len, input len),
440 	 * ROUNDUP8(priv key len, prime len, order len)).
441 	 * Please note, private key, order cannot exceed prime
442 	 * length i.e 3 * p_align.
443 	 */
444 	dlen = sizeof(fpm_table_iova) + k_align + m_align + p_align * 5;
445 
446 	memset(dptr, 0, dlen);
447 
448 	*(uint64_t *)dptr = fpm_table_iova;
449 	dptr += sizeof(fpm_table_iova);
450 
451 	memcpy(dptr, ecdsa->k.data, k_len);
452 	dptr += k_align;
453 
454 	memcpy(dptr, ec_grp->prime.data, prime_len);
455 	dptr += p_align;
456 
457 	memcpy(dptr + o_offset, ec_grp->order.data, order_len);
458 	dptr += p_align;
459 
460 	memcpy(dptr + pk_offset, ecdsa->pkey.data, pkey_len);
461 	dptr += p_align;
462 
463 	memcpy(dptr, ecdsa->message.data, message_len);
464 	dptr += m_align;
465 
466 	memcpy(dptr, ec_grp->consta.data, prime_len);
467 	dptr += p_align;
468 
469 	memcpy(dptr, ec_grp->constb.data, prime_len);
470 	dptr += p_align;
471 
472 	/* Setup opcodes */
473 	w4.s.opcode_major = ROC_AE_MAJOR_OP_ECDSA;
474 	w4.s.opcode_minor = ROC_AE_MINOR_OP_ECDSA_SIGN;
475 
476 	w4.s.param1 = curveid | (message_len << 8);
477 	w4.s.param2 = (pkey_len << 8) | k_len;
478 	w4.s.dlen = dlen;
479 
480 	inst->w4.u64 = w4.u64;
481 	inst->rptr = (uintptr_t)dptr;
482 }
483 
484 static __rte_always_inline void
cnxk_ae_ecdsa_verify_prep(struct rte_crypto_ecdsa_op_param * ecdsa,struct roc_ae_buf_ptr * meta_buf,uint64_t fpm_table_iova,struct roc_ae_ec_group * ec_grp,uint8_t curveid,struct cpt_inst_s * inst)485 cnxk_ae_ecdsa_verify_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
486 			  struct roc_ae_buf_ptr *meta_buf,
487 			  uint64_t fpm_table_iova,
488 			  struct roc_ae_ec_group *ec_grp, uint8_t curveid,
489 			  struct cpt_inst_s *inst)
490 {
491 	uint32_t message_len = ecdsa->message.length;
492 	uint16_t o_offset, r_offset, s_offset;
493 	uint16_t qx_len = ecdsa->q.x.length;
494 	uint16_t qy_len = ecdsa->q.y.length;
495 	uint16_t r_len = ecdsa->r.length;
496 	uint16_t s_len = ecdsa->s.length;
497 	uint16_t order_len, prime_len;
498 	uint16_t qx_offset, qy_offset;
499 	uint16_t p_align, m_align;
500 	union cpt_inst_w4 w4;
501 	uint16_t dlen;
502 	uint8_t *dptr;
503 
504 	prime_len = ec_grp->prime.length;
505 	order_len = ec_grp->order.length;
506 
507 	/* Truncate input length to curve prime length */
508 	if (message_len > prime_len)
509 		message_len = prime_len;
510 
511 	m_align = RTE_ALIGN_CEIL(message_len, 8);
512 	p_align = RTE_ALIGN_CEIL(prime_len, 8);
513 
514 	/* Set write offset for sign, order and public key coordinates */
515 	o_offset = prime_len - order_len;
516 	qx_offset = prime_len - qx_len;
517 	qy_offset = prime_len - qy_len;
518 	r_offset = prime_len - r_len;
519 	s_offset = prime_len - s_len;
520 
521 	/* Input buffer */
522 	dptr = meta_buf->vaddr;
523 	inst->dptr = (uintptr_t)dptr;
524 
525 	/*
526 	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(message len),
527 	 * ROUNDUP8(sign len(r and s), public key len(x and y coordinates),
528 	 * prime len, order len)).
529 	 * Please note sign, public key and order can not exceed prime length
530 	 * i.e. 6 * p_align
531 	 */
532 	dlen = sizeof(fpm_table_iova) + m_align + (8 * p_align);
533 
534 	memset(dptr, 0, dlen);
535 
536 	*(uint64_t *)dptr = fpm_table_iova;
537 	dptr += sizeof(fpm_table_iova);
538 
539 	memcpy(dptr + r_offset, ecdsa->r.data, r_len);
540 	dptr += p_align;
541 
542 	memcpy(dptr + s_offset, ecdsa->s.data, s_len);
543 	dptr += p_align;
544 
545 	memcpy(dptr, ecdsa->message.data, message_len);
546 	dptr += m_align;
547 
548 	memcpy(dptr + o_offset, ec_grp->order.data, order_len);
549 	dptr += p_align;
550 
551 	memcpy(dptr, ec_grp->prime.data, prime_len);
552 	dptr += p_align;
553 
554 	memcpy(dptr + qx_offset, ecdsa->q.x.data, qx_len);
555 	dptr += p_align;
556 
557 	memcpy(dptr + qy_offset, ecdsa->q.y.data, qy_len);
558 	dptr += p_align;
559 
560 	memcpy(dptr, ec_grp->consta.data, prime_len);
561 	dptr += p_align;
562 
563 	memcpy(dptr, ec_grp->constb.data, prime_len);
564 	dptr += p_align;
565 
566 	/* Setup opcodes */
567 	w4.s.opcode_major = ROC_AE_MAJOR_OP_ECDSA;
568 	w4.s.opcode_minor = ROC_AE_MINOR_OP_ECDSA_VERIFY;
569 
570 	w4.s.param1 = curveid | (message_len << 8);
571 	w4.s.param2 = 0;
572 	w4.s.dlen = dlen;
573 
574 	inst->w4.u64 = w4.u64;
575 	inst->rptr = (uintptr_t)dptr;
576 }
577 
578 static __rte_always_inline int __rte_hot
cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op * op,struct roc_ae_buf_ptr * meta_buf,struct cnxk_ae_sess * sess,uint64_t * fpm_iova,struct roc_ae_ec_group ** ec_grp,struct cpt_inst_s * inst)579 cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op *op,
580 			 struct roc_ae_buf_ptr *meta_buf,
581 			 struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
582 			 struct roc_ae_ec_group **ec_grp,
583 			 struct cpt_inst_s *inst)
584 {
585 	struct rte_crypto_ecdsa_op_param *ecdsa = &op->asym->ecdsa;
586 	uint8_t curveid = sess->ec_ctx.curveid;
587 
588 	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
589 		cnxk_ae_ecdsa_sign_prep(ecdsa, meta_buf, fpm_iova[curveid],
590 					ec_grp[curveid], curveid, inst);
591 	else if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
592 		cnxk_ae_ecdsa_verify_prep(ecdsa, meta_buf, fpm_iova[curveid],
593 					  ec_grp[curveid], curveid, inst);
594 	else {
595 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
596 		return -EINVAL;
597 	}
598 	return 0;
599 }
600 
601 static __rte_always_inline int
cnxk_ae_ecpm_prep(struct rte_crypto_ecpm_op_param * ecpm,struct roc_ae_buf_ptr * meta_buf,struct roc_ae_ec_group * ec_grp,uint8_t curveid,struct cpt_inst_s * inst)602 cnxk_ae_ecpm_prep(struct rte_crypto_ecpm_op_param *ecpm,
603 		  struct roc_ae_buf_ptr *meta_buf,
604 		  struct roc_ae_ec_group *ec_grp, uint8_t curveid,
605 		  struct cpt_inst_s *inst)
606 {
607 	uint16_t x1_len = ecpm->p.x.length;
608 	uint16_t y1_len = ecpm->p.y.length;
609 	uint16_t scalar_align, p_align;
610 	uint16_t x1_offset, y1_offset;
611 	uint16_t dlen, prime_len;
612 	union cpt_inst_w4 w4;
613 	uint8_t *dptr;
614 
615 	prime_len = ec_grp->prime.length;
616 
617 	/* Input buffer */
618 	dptr = meta_buf->vaddr;
619 	inst->dptr = (uintptr_t)dptr;
620 
621 	p_align = RTE_ALIGN_CEIL(prime_len, 8);
622 	scalar_align = RTE_ALIGN_CEIL(ecpm->scalar.length, 8);
623 
624 	/*
625 	 * Set dlen = sum(ROUNDUP8(input point(x and y coordinates), prime,
626 	 * scalar length),
627 	 * Please note point length is equivalent to prime of the curve
628 	 */
629 	dlen = 5 * p_align + scalar_align;
630 
631 	x1_offset = prime_len - x1_len;
632 	y1_offset = prime_len - y1_len;
633 
634 	memset(dptr, 0, dlen);
635 
636 	/* Copy input point, scalar, prime */
637 	memcpy(dptr + x1_offset, ecpm->p.x.data, x1_len);
638 	dptr += p_align;
639 	memcpy(dptr + y1_offset, ecpm->p.y.data, y1_len);
640 	dptr += p_align;
641 	memcpy(dptr, ecpm->scalar.data, ecpm->scalar.length);
642 	dptr += scalar_align;
643 	memcpy(dptr, ec_grp->prime.data, ec_grp->prime.length);
644 	dptr += p_align;
645 	memcpy(dptr, ec_grp->consta.data, ec_grp->consta.length);
646 	dptr += p_align;
647 	memcpy(dptr, ec_grp->constb.data, ec_grp->constb.length);
648 	dptr += p_align;
649 
650 	/* Setup opcodes */
651 	w4.s.opcode_major = ROC_AE_MAJOR_OP_ECC;
652 	w4.s.opcode_minor = ROC_AE_MINOR_OP_ECC_UMP;
653 
654 	w4.s.param1 = curveid;
655 	w4.s.param2 = ecpm->scalar.length;
656 	w4.s.dlen = dlen;
657 
658 	inst->w4.u64 = w4.u64;
659 	inst->rptr = (uintptr_t)dptr;
660 
661 	return 0;
662 }
663 
664 static __rte_always_inline void
cnxk_ae_dequeue_rsa_op(struct rte_crypto_op * cop,uint8_t * rptr,struct rte_crypto_rsa_xform * rsa_ctx)665 cnxk_ae_dequeue_rsa_op(struct rte_crypto_op *cop, uint8_t *rptr,
666 		       struct rte_crypto_rsa_xform *rsa_ctx)
667 {
668 	struct rte_crypto_rsa_op_param *rsa = &cop->asym->rsa;
669 
670 	switch (rsa->op_type) {
671 	case RTE_CRYPTO_ASYM_OP_ENCRYPT:
672 		rsa->cipher.length = rsa_ctx->n.length;
673 		memcpy(rsa->cipher.data, rptr, rsa->cipher.length);
674 		break;
675 	case RTE_CRYPTO_ASYM_OP_DECRYPT:
676 		if (rsa->pad == RTE_CRYPTO_RSA_PADDING_NONE) {
677 			rsa->message.length = rsa_ctx->n.length;
678 			memcpy(rsa->message.data, rptr, rsa->message.length);
679 		} else {
680 			/* Get length of decrypted output */
681 			rsa->message.length =
682 				rte_cpu_to_be_16(*((uint16_t *)rptr));
683 			/*
684 			 * Offset output data pointer by length field
685 			 * (2 bytes) and copy decrypted data.
686 			 */
687 			memcpy(rsa->message.data, rptr + 2,
688 			       rsa->message.length);
689 		}
690 		break;
691 	case RTE_CRYPTO_ASYM_OP_SIGN:
692 		rsa->sign.length = rsa_ctx->n.length;
693 		memcpy(rsa->sign.data, rptr, rsa->sign.length);
694 		break;
695 	case RTE_CRYPTO_ASYM_OP_VERIFY:
696 		if (rsa->pad == RTE_CRYPTO_RSA_PADDING_NONE) {
697 			rsa->sign.length = rsa_ctx->n.length;
698 			memcpy(rsa->sign.data, rptr, rsa->sign.length);
699 		} else {
700 			/* Get length of signed output */
701 			rsa->sign.length =
702 				rte_cpu_to_be_16(*((uint16_t *)rptr));
703 			/*
704 			 * Offset output data pointer by length field
705 			 * (2 bytes) and copy signed data.
706 			 */
707 			memcpy(rsa->sign.data, rptr + 2, rsa->sign.length);
708 		}
709 		if (memcmp(rsa->sign.data, rsa->message.data,
710 			   rsa->message.length)) {
711 			cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
712 		}
713 		break;
714 	default:
715 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
716 		break;
717 	}
718 }
719 
720 static __rte_always_inline void
cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param * ecdsa,uint8_t * rptr,struct roc_ae_ec_ctx * ec,struct roc_ae_ec_group ** ec_grp)721 cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa, uint8_t *rptr,
722 			 struct roc_ae_ec_ctx *ec,
723 			 struct roc_ae_ec_group **ec_grp)
724 {
725 	int prime_len = ec_grp[ec->curveid]->prime.length;
726 
727 	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
728 		return;
729 
730 	/* Separate out sign r and s components */
731 	memcpy(ecdsa->r.data, rptr, prime_len);
732 	memcpy(ecdsa->s.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
733 	ecdsa->r.length = prime_len;
734 	ecdsa->s.length = prime_len;
735 }
736 
737 static __rte_always_inline void
cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param * ecpm,uint8_t * rptr,struct roc_ae_ec_ctx * ec,struct roc_ae_ec_group ** ec_grp)738 cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm, uint8_t *rptr,
739 			struct roc_ae_ec_ctx *ec,
740 			struct roc_ae_ec_group **ec_grp)
741 {
742 	int prime_len = ec_grp[ec->curveid]->prime.length;
743 
744 	memcpy(ecpm->r.x.data, rptr, prime_len);
745 	memcpy(ecpm->r.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
746 	ecpm->r.x.length = prime_len;
747 	ecpm->r.y.length = prime_len;
748 }
749 
750 static __rte_always_inline void *
cnxk_ae_alloc_meta(struct roc_ae_buf_ptr * buf,struct rte_mempool * cpt_meta_pool,struct cpt_inflight_req * infl_req)751 cnxk_ae_alloc_meta(struct roc_ae_buf_ptr *buf,
752 		   struct rte_mempool *cpt_meta_pool,
753 		   struct cpt_inflight_req *infl_req)
754 {
755 	uint8_t *mdata;
756 
757 	if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0))
758 		return NULL;
759 
760 	buf->vaddr = mdata;
761 
762 	infl_req->mdata = mdata;
763 	infl_req->op_flags |= CPT_OP_FLAGS_METABUF;
764 
765 	return mdata;
766 }
767 
768 static __rte_always_inline int32_t __rte_hot
cnxk_ae_enqueue(struct cnxk_cpt_qp * qp,struct rte_crypto_op * op,struct cpt_inflight_req * infl_req,struct cpt_inst_s * inst,struct cnxk_ae_sess * sess)769 cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
770 		struct cpt_inflight_req *infl_req, struct cpt_inst_s *inst,
771 		struct cnxk_ae_sess *sess)
772 {
773 	struct cpt_qp_meta_info *minfo = &qp->meta_info;
774 	struct rte_crypto_asym_op *asym_op = op->asym;
775 	struct roc_ae_buf_ptr meta_buf;
776 	uint64_t *mop;
777 	void *mdata;
778 	int ret;
779 
780 	mdata = cnxk_ae_alloc_meta(&meta_buf, minfo->pool, infl_req);
781 	if (mdata == NULL)
782 		return -ENOMEM;
783 
784 	/* Reserve 8B for RPTR */
785 	meta_buf.vaddr = PLT_PTR_ADD(mdata, sizeof(uint64_t));
786 
787 	switch (sess->xfrm_type) {
788 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
789 		ret = cnxk_ae_modex_prep(op, &meta_buf, &sess->mod_ctx, inst);
790 		if (unlikely(ret))
791 			goto req_fail;
792 		break;
793 	case RTE_CRYPTO_ASYM_XFORM_RSA:
794 		ret = cnxk_ae_enqueue_rsa_op(op, &meta_buf, sess, inst);
795 		if (unlikely(ret))
796 			goto req_fail;
797 		break;
798 	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
799 		ret = cnxk_ae_enqueue_ecdsa_op(op, &meta_buf, sess,
800 					       sess->cnxk_fpm_iova,
801 					       sess->ec_grp, inst);
802 		if (unlikely(ret))
803 			goto req_fail;
804 		break;
805 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
806 		ret = cnxk_ae_ecpm_prep(&asym_op->ecpm, &meta_buf,
807 					sess->ec_grp[sess->ec_ctx.curveid],
808 					sess->ec_ctx.curveid, inst);
809 		if (unlikely(ret))
810 			goto req_fail;
811 		break;
812 	default:
813 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
814 		ret = -EINVAL;
815 		goto req_fail;
816 	}
817 
818 	mop = mdata;
819 	mop[0] = inst->rptr;
820 	return 0;
821 
822 req_fail:
823 	rte_mempool_put(minfo->pool, infl_req->mdata);
824 	return ret;
825 }
826 
827 static __rte_always_inline void
cnxk_ae_post_process(struct rte_crypto_op * cop,struct cnxk_ae_sess * sess,uint8_t * rptr)828 cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
829 		     uint8_t *rptr)
830 {
831 	struct rte_crypto_asym_op *op = cop->asym;
832 
833 	switch (sess->xfrm_type) {
834 	case RTE_CRYPTO_ASYM_XFORM_RSA:
835 		cnxk_ae_dequeue_rsa_op(cop, rptr, &sess->rsa_ctx);
836 		break;
837 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
838 		op->modex.result.length = sess->mod_ctx.modulus.length;
839 		memcpy(op->modex.result.data, rptr, op->modex.result.length);
840 		break;
841 	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
842 		cnxk_ae_dequeue_ecdsa_op(&op->ecdsa, rptr, &sess->ec_ctx,
843 					 sess->ec_grp);
844 		break;
845 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
846 		cnxk_ae_dequeue_ecpm_op(&op->ecpm, rptr, &sess->ec_ctx,
847 					sess->ec_grp);
848 		break;
849 	default:
850 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
851 		break;
852 	}
853 }
854 #endif /* _CNXK_AE_H_ */
855