Branch data Line data Source code
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_ae.h"
13 : :
14 : : #include "cnxk_cryptodev_ops.h"
15 : :
16 : : #define ASYM_SESS_SIZE sizeof(struct rte_cryptodev_asym_session)
17 : :
18 : : struct cnxk_ae_sess {
19 : : uint8_t rte_sess[ASYM_SESS_SIZE];
20 : : enum rte_crypto_asym_xform_type xfrm_type;
21 : : union {
22 : : struct rte_crypto_rsa_xform rsa_ctx;
23 : : struct rte_crypto_modex_xform mod_ctx;
24 : : struct roc_ae_ec_ctx ec_ctx;
25 : : };
26 : : uint64_t *cnxk_fpm_iova;
27 : : struct roc_ae_ec_group **ec_grp;
28 : : uint64_t cpt_inst_w7;
29 : : uint64_t cpt_inst_w2;
30 : : struct cnxk_cpt_qp *qp;
31 : : struct roc_cpt_lf *lf;
32 : : struct hw_ctx_s {
33 : : union {
34 : : struct {
35 : : uint64_t rsvd : 48;
36 : :
37 : : uint64_t ctx_push_size : 7;
38 : : uint64_t rsvd1 : 1;
39 : :
40 : : uint64_t ctx_hdr_size : 2;
41 : : uint64_t aop_valid : 1;
42 : : uint64_t rsvd2 : 1;
43 : : uint64_t ctx_size : 4;
44 : : } s;
45 : : uint64_t u64;
46 : : } w0;
47 : : uint8_t rsvd[256];
48 : : } hw_ctx __plt_aligned(ROC_ALIGN);
49 : : };
50 : :
51 : : static __rte_always_inline void
52 : : cnxk_ae_modex_param_normalize(uint8_t **data, size_t *len)
53 : : {
54 : : size_t i;
55 : :
56 : : /* Strip leading NUL bytes */
57 [ # # # # ]: 0 : for (i = 0; i < *len; i++) {
58 [ # # # # ]: 0 : if ((*data)[i] != 0)
59 : : break;
60 : : }
61 : 0 : *data += i;
62 : 0 : *len -= i;
63 : 0 : }
64 : :
65 : : static __rte_always_inline int
66 : : cnxk_ae_fill_modex_params(struct cnxk_ae_sess *sess,
67 : : struct rte_crypto_asym_xform *xform)
68 : : {
69 : : struct rte_crypto_modex_xform *ctx = &sess->mod_ctx;
70 : 0 : size_t exp_len = xform->modex.exponent.length;
71 : 0 : size_t mod_len = xform->modex.modulus.length;
72 : 0 : uint8_t *exp = xform->modex.exponent.data;
73 : 0 : uint8_t *mod = xform->modex.modulus.data;
74 : :
75 : : cnxk_ae_modex_param_normalize(&mod, &mod_len);
76 : : cnxk_ae_modex_param_normalize(&exp, &exp_len);
77 : :
78 [ # # # # ]: 0 : if (unlikely(exp_len == 0 || mod_len == 0))
79 : : return -EINVAL;
80 : :
81 [ # # ]: 0 : if (unlikely(exp_len > mod_len))
82 : : return -ENOTSUP;
83 : :
84 : : /* Allocate buffer to hold modexp params */
85 : 0 : ctx->modulus.data = rte_malloc(NULL, mod_len + exp_len, 0);
86 [ # # ]: 0 : if (ctx->modulus.data == NULL)
87 : : return -ENOMEM;
88 : :
89 : : /* Set up modexp prime modulus and private exponent */
90 : : memcpy(ctx->modulus.data, mod, mod_len);
91 : 0 : ctx->exponent.data = ctx->modulus.data + mod_len;
92 : : memcpy(ctx->exponent.data, exp, exp_len);
93 : :
94 : 0 : ctx->modulus.length = mod_len;
95 : 0 : ctx->exponent.length = exp_len;
96 : :
97 : : return 0;
98 : : }
99 : :
100 : : static __rte_always_inline int
101 : : cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess,
102 : : struct rte_crypto_asym_xform *xform)
103 : : {
104 : 0 : struct rte_crypto_rsa_priv_key_qt qt = xform->rsa.qt;
105 : : struct rte_crypto_rsa_xform *xfrm_rsa = &xform->rsa;
106 : : struct rte_crypto_rsa_xform *rsa = &sess->rsa_ctx;
107 : : struct rte_crypto_param_t d = xform->rsa.d;
108 : 0 : size_t mod_len = xfrm_rsa->n.length;
109 : 0 : size_t exp_len = xfrm_rsa->e.length;
110 : : uint64_t total_size;
111 : : size_t len = 0;
112 : :
113 : : /* Set private key type */
114 : 0 : rsa->key_type = xfrm_rsa->key_type;
115 : :
116 [ # # ]: 0 : if (rsa->key_type == RTE_RSA_KEY_TYPE_QT) {
117 [ # # # # ]: 0 : if (qt.p.length != 0 && qt.p.data == NULL)
118 : : return -EINVAL;
119 : :
120 : : /* Make sure key length used is not more than mod_len/2 */
121 [ # # ]: 0 : if (qt.p.data != NULL)
122 [ # # ]: 0 : len = (((mod_len / 2) < qt.p.length) ? 0 : qt.p.length * 5);
123 [ # # ]: 0 : } else if (rsa->key_type == RTE_RSA_KEY_TYPE_EXP) {
124 [ # # # # ]: 0 : if (d.length != 0 && d.data == NULL)
125 : : return -EINVAL;
126 : :
127 : : len = d.length;
128 : : }
129 : :
130 : : /* Total size required for RSA key params(n,e,(q,dQ,p,dP,qInv)) */
131 : 0 : total_size = mod_len + exp_len + len;
132 : :
133 : : /* Allocate buffer to hold all RSA keys */
134 : 0 : rsa->n.data = rte_malloc(NULL, total_size, 0);
135 [ # # ]: 0 : if (rsa->n.data == NULL)
136 : : return -ENOMEM;
137 : :
138 : : /* Set up RSA prime modulus and public key exponent */
139 [ # # ]: 0 : memcpy(rsa->n.data, xfrm_rsa->n.data, mod_len);
140 : 0 : rsa->e.data = rsa->n.data + mod_len;
141 : 0 : memcpy(rsa->e.data, xfrm_rsa->e.data, exp_len);
142 : :
143 [ # # ]: 0 : if (rsa->key_type == RTE_RSA_KEY_TYPE_QT) {
144 : : /* Private key in quintuple format */
145 [ # # ]: 0 : rsa->qt.q.data = rsa->e.data + exp_len;
146 : : memcpy(rsa->qt.q.data, qt.q.data, qt.q.length);
147 : 0 : rsa->qt.dQ.data = rsa->qt.q.data + qt.q.length;
148 : : memcpy(rsa->qt.dQ.data, qt.dQ.data, qt.dQ.length);
149 : 0 : rsa->qt.p.data = rsa->qt.dQ.data + qt.dQ.length;
150 [ # # ]: 0 : if (qt.p.data != NULL)
151 : : memcpy(rsa->qt.p.data, qt.p.data, qt.p.length);
152 : 0 : rsa->qt.dP.data = rsa->qt.p.data + qt.p.length;
153 : : memcpy(rsa->qt.dP.data, qt.dP.data, qt.dP.length);
154 : 0 : rsa->qt.qInv.data = rsa->qt.dP.data + qt.dP.length;
155 : : memcpy(rsa->qt.qInv.data, qt.qInv.data, qt.qInv.length);
156 : :
157 : 0 : rsa->qt.q.length = qt.q.length;
158 : 0 : rsa->qt.dQ.length = qt.dQ.length;
159 : 0 : rsa->qt.p.length = qt.p.length;
160 : 0 : rsa->qt.dP.length = qt.dP.length;
161 : 0 : rsa->qt.qInv.length = qt.qInv.length;
162 [ # # ]: 0 : } else if (rsa->key_type == RTE_RSA_KEY_TYPE_EXP) {
163 : : /* Private key in exponent format */
164 : 0 : rsa->d.data = rsa->e.data + exp_len;
165 : : memcpy(rsa->d.data, d.data, d.length);
166 : 0 : rsa->d.length = d.length;
167 : : }
168 : 0 : rsa->n.length = mod_len;
169 : 0 : rsa->e.length = exp_len;
170 : :
171 : : return 0;
172 : : }
173 : :
174 : : static __rte_always_inline int
175 : : cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
176 : : struct rte_crypto_asym_xform *xform)
177 : : {
178 : : struct roc_ae_ec_ctx *ec = &sess->ec_ctx;
179 : :
180 [ # # # # : 0 : switch (xform->ec.curve_id) {
# # # ]
181 : 0 : case RTE_CRYPTO_EC_GROUP_SECP192R1:
182 : 0 : ec->curveid = ROC_AE_EC_ID_P192;
183 : 0 : break;
184 : 0 : case RTE_CRYPTO_EC_GROUP_SECP224R1:
185 : 0 : ec->curveid = ROC_AE_EC_ID_P224;
186 : 0 : break;
187 : 0 : case RTE_CRYPTO_EC_GROUP_SECP256R1:
188 : 0 : ec->curveid = ROC_AE_EC_ID_P256;
189 : 0 : break;
190 : 0 : case RTE_CRYPTO_EC_GROUP_SECP384R1:
191 : 0 : ec->curveid = ROC_AE_EC_ID_P384;
192 : 0 : break;
193 : 0 : case RTE_CRYPTO_EC_GROUP_SECP521R1:
194 : 0 : ec->curveid = ROC_AE_EC_ID_P521;
195 : 0 : break;
196 : 0 : case RTE_CRYPTO_EC_GROUP_SM2:
197 : 0 : ec->curveid = ROC_AE_EC_ID_SM2;
198 : 0 : break;
199 : : default:
200 : : /* Only NIST curves (FIPS 186-4) and SM2 are supported */
201 : : return -EINVAL;
202 : : }
203 : :
204 [ # # ]: 0 : if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_ECPM)
205 : : return 0;
206 : :
207 : 0 : ec->pkey.length = xform->ec.pkey.length;
208 [ # # ]: 0 : if (xform->ec.pkey.length)
209 [ # # ]: 0 : rte_memcpy(ec->pkey.data, xform->ec.pkey.data, xform->ec.pkey.length);
210 : :
211 : 0 : ec->q.x.length = xform->ec.q.x.length;
212 [ # # ]: 0 : if (xform->ec.q.x.length)
213 [ # # ]: 0 : rte_memcpy(ec->q.x.data, xform->ec.q.x.data, xform->ec.q.x.length);
214 : :
215 : 0 : ec->q.y.length = xform->ec.q.y.length;
216 [ # # ]: 0 : if (xform->ec.q.y.length)
217 [ # # ]: 0 : rte_memcpy(ec->q.y.data, xform->ec.q.y.data, xform->ec.q.y.length);
218 : :
219 : : return 0;
220 : : }
221 : :
222 : : static __rte_always_inline int
223 : : cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
224 : : struct rte_crypto_asym_xform *xform)
225 : : {
226 : : int ret;
227 : :
228 : 0 : sess->xfrm_type = xform->xform_type;
229 : :
230 [ # # # # ]: 0 : switch (xform->xform_type) {
231 : : case RTE_CRYPTO_ASYM_XFORM_RSA:
232 : : ret = cnxk_ae_fill_rsa_params(sess, xform);
233 : : break;
234 : : case RTE_CRYPTO_ASYM_XFORM_MODEX:
235 : : ret = cnxk_ae_fill_modex_params(sess, xform);
236 : : break;
237 : : case RTE_CRYPTO_ASYM_XFORM_ECDSA:
238 : : /* Fall through */
239 : : case RTE_CRYPTO_ASYM_XFORM_ECDH:
240 : : case RTE_CRYPTO_ASYM_XFORM_ECPM:
241 : : case RTE_CRYPTO_ASYM_XFORM_ECFPM:
242 : : case RTE_CRYPTO_ASYM_XFORM_SM2:
243 : : ret = cnxk_ae_fill_ec_params(sess, xform);
244 : : break;
245 : : default:
246 : : return -ENOTSUP;
247 : : }
248 : : return ret;
249 : : }
250 : :
251 : : static inline void
252 : 0 : cnxk_ae_free_session_parameters(struct cnxk_ae_sess *sess)
253 : : {
254 : : struct rte_crypto_modex_xform *mod;
255 : : struct rte_crypto_rsa_xform *rsa;
256 : :
257 [ # # # ]: 0 : switch (sess->xfrm_type) {
258 : 0 : case RTE_CRYPTO_ASYM_XFORM_RSA:
259 : : rsa = &sess->rsa_ctx;
260 : 0 : rte_free(rsa->n.data);
261 : 0 : break;
262 : 0 : case RTE_CRYPTO_ASYM_XFORM_MODEX:
263 : : mod = &sess->mod_ctx;
264 : 0 : rte_free(mod->modulus.data);
265 : 0 : break;
266 : : case RTE_CRYPTO_ASYM_XFORM_ECDSA:
267 : : /* Fall through */
268 : : case RTE_CRYPTO_ASYM_XFORM_ECPM:
269 : : case RTE_CRYPTO_ASYM_XFORM_ECFPM:
270 : : break;
271 : : default:
272 : : break;
273 : : }
274 : 0 : }
275 : :
276 : : static __rte_always_inline int
277 : : cnxk_ae_modex_prep(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
278 : : struct rte_crypto_modex_xform *mod, struct cpt_inst_s *inst)
279 : : {
280 : 0 : uint32_t exp_len = mod->exponent.length;
281 : 0 : uint32_t mod_len = mod->modulus.length;
282 : : struct rte_crypto_mod_op_param mod_op;
283 : : uint64_t total_key_len;
284 : : union cpt_inst_w4 w4;
285 : : uint32_t base_len;
286 : : uint32_t dlen;
287 : : uint8_t *dptr;
288 : :
289 : 0 : mod_op = op->asym->modex;
290 : :
291 : 0 : base_len = mod_op.base.length;
292 : 0 : if (unlikely(base_len > mod_len)) {
293 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
294 : 0 : return -ENOTSUP;
295 : : }
296 : :
297 : 0 : total_key_len = mod_len + exp_len;
298 : :
299 : : /* Input buffer */
300 : : dptr = meta_buf->vaddr;
301 : 0 : inst->dptr = (uintptr_t)dptr;
302 : 0 : memcpy(dptr, mod->modulus.data, total_key_len);
303 : 0 : dptr += total_key_len;
304 : : memcpy(dptr, mod_op.base.data, base_len);
305 : 0 : dptr += base_len;
306 : 0 : dlen = total_key_len + base_len;
307 : :
308 : : /* Setup opcodes */
309 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_MODEX;
310 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_MODEX;
311 : :
312 : 0 : w4.s.param1 = mod_len;
313 : 0 : w4.s.param2 = exp_len;
314 : 0 : w4.s.dlen = dlen;
315 : :
316 : 0 : inst->w4.u64 = w4.u64;
317 : 0 : inst->rptr = (uintptr_t)dptr;
318 : :
319 : 0 : return 0;
320 : : }
321 : :
322 : : static __rte_always_inline void
323 : : cnxk_ae_rsa_prep(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
324 : : struct rte_crypto_rsa_xform *rsa,
325 : : rte_crypto_param *crypto_param, struct cpt_inst_s *inst)
326 : : {
327 : : struct rte_crypto_rsa_op_param rsa_op;
328 : 0 : uint32_t mod_len = rsa->n.length;
329 : 0 : uint32_t exp_len = rsa->e.length;
330 : : uint64_t total_key_len;
331 : : union cpt_inst_w4 w4;
332 : : uint32_t in_size;
333 : : uint32_t dlen;
334 : : uint8_t *dptr;
335 : :
336 : 0 : rsa_op = op->asym->rsa;
337 : 0 : total_key_len = mod_len + exp_len;
338 : :
339 : : /* Input buffer */
340 : : dptr = meta_buf->vaddr;
341 : 0 : inst->dptr = (uintptr_t)dptr;
342 : 0 : memcpy(dptr, rsa->n.data, total_key_len);
343 : 0 : dptr += total_key_len;
344 : :
345 : 0 : in_size = crypto_param->length;
346 : 0 : memcpy(dptr, crypto_param->data, in_size);
347 : :
348 : 0 : dptr += in_size;
349 : 0 : dlen = total_key_len + in_size;
350 : :
351 [ # # # # ]: 0 : if (rsa_op.padding.type == RTE_CRYPTO_RSA_PADDING_NONE) {
352 : : /* Use mod_exp operation for no_padding type */
353 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_MODEX;
354 : 0 : w4.s.param2 = exp_len;
355 : : } else {
356 : : if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) {
357 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_ENC;
358 : : /* Public key encrypt, use BT2*/
359 : 0 : w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE2 |
360 : 0 : ((uint16_t)(exp_len) << 1);
361 : : } else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) {
362 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_DEC;
363 : : /* Public key decrypt, use BT1 */
364 : 0 : w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE1;
365 : : }
366 : : }
367 : :
368 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_MODEX;
369 : :
370 : 0 : w4.s.param1 = mod_len;
371 : 0 : w4.s.dlen = dlen;
372 : :
373 : 0 : inst->w4.u64 = w4.u64;
374 : 0 : inst->rptr = (uintptr_t)dptr;
375 : 0 : }
376 : :
377 : : static __rte_always_inline void
378 : : cnxk_ae_rsa_exp_prep(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
379 : : struct rte_crypto_rsa_xform *rsa, rte_crypto_param *crypto_param,
380 : : struct cpt_inst_s *inst)
381 : : {
382 : : struct rte_crypto_rsa_op_param rsa_op;
383 : 0 : uint32_t privkey_len = rsa->d.length;
384 : 0 : uint32_t mod_len = rsa->n.length;
385 : : union cpt_inst_w4 w4;
386 : : uint32_t in_size;
387 : : uint32_t dlen;
388 : : uint8_t *dptr;
389 : :
390 : 0 : rsa_op = op->asym->rsa;
391 : :
392 : : /* Input buffer */
393 : : dptr = meta_buf->vaddr;
394 : 0 : inst->dptr = (uintptr_t)dptr;
395 [ # # # # ]: 0 : memcpy(dptr, rsa->n.data, mod_len);
396 : 0 : dptr += mod_len;
397 : 0 : memcpy(dptr, rsa->d.data, privkey_len);
398 : 0 : dptr += privkey_len;
399 : :
400 : 0 : in_size = crypto_param->length;
401 : 0 : memcpy(dptr, crypto_param->data, in_size);
402 : :
403 : 0 : dptr += in_size;
404 : 0 : dlen = mod_len + privkey_len + in_size;
405 : :
406 [ # # # # ]: 0 : if (rsa_op.padding.type == RTE_CRYPTO_RSA_PADDING_NONE) {
407 : : /* Use mod_exp operation for no_padding type */
408 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_MODEX;
409 : 0 : w4.s.param2 = privkey_len;
410 : : } else {
411 : : if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_SIGN) {
412 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_ENC;
413 : : /* Private key encrypt (exponent), use BT1*/
414 : 0 : w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE1 | ((uint16_t)(privkey_len) << 1);
415 : : } else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) {
416 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_DEC;
417 : : /* Private key decrypt (exponent), use BT2 */
418 : 0 : w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE2;
419 : : }
420 : : }
421 : :
422 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_MODEX;
423 : :
424 : 0 : w4.s.param1 = mod_len;
425 : 0 : w4.s.dlen = dlen;
426 : :
427 : 0 : inst->w4.u64 = w4.u64;
428 : 0 : inst->rptr = (uintptr_t)dptr;
429 : 0 : }
430 : :
431 : : static __rte_always_inline void
432 : : cnxk_ae_rsa_crt_prep(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
433 : : struct rte_crypto_rsa_xform *rsa, rte_crypto_param *crypto_param,
434 : : struct cpt_inst_s *inst)
435 : : {
436 : 0 : uint32_t qInv_len = rsa->qt.qInv.length;
437 : : struct rte_crypto_rsa_op_param rsa_op;
438 : 0 : uint32_t dP_len = rsa->qt.dP.length;
439 : 0 : uint32_t dQ_len = rsa->qt.dQ.length;
440 : 0 : uint32_t p_len = rsa->qt.p.length;
441 : 0 : uint32_t q_len = rsa->qt.q.length;
442 : 0 : uint32_t mod_len = rsa->n.length;
443 : : uint64_t total_key_len;
444 : : union cpt_inst_w4 w4;
445 : : uint32_t in_size;
446 : : uint32_t dlen;
447 : : uint8_t *dptr;
448 : :
449 : 0 : rsa_op = op->asym->rsa;
450 : 0 : total_key_len = p_len + q_len + dP_len + dQ_len + qInv_len;
451 : :
452 : : /* Input buffer */
453 : : dptr = meta_buf->vaddr;
454 : 0 : inst->dptr = (uintptr_t)dptr;
455 [ # # # # ]: 0 : memcpy(dptr, rsa->qt.q.data, total_key_len);
456 : 0 : dptr += total_key_len;
457 : :
458 : 0 : in_size = crypto_param->length;
459 : 0 : memcpy(dptr, crypto_param->data, in_size);
460 : :
461 : 0 : dptr += in_size;
462 : 0 : dlen = total_key_len + in_size;
463 : :
464 [ # # # # ]: 0 : if (rsa_op.padding.type == RTE_CRYPTO_RSA_PADDING_NONE) {
465 : : /*Use mod_exp operation for no_padding type */
466 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_MODEX_CRT;
467 : : } else {
468 : : if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_SIGN) {
469 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_ENC_CRT;
470 : : /* Private encrypt, use BT1 */
471 : 0 : w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE1;
472 : : } else if (rsa_op.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) {
473 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_PKCS_DEC_CRT;
474 : : /* Private decrypt, use BT2 */
475 : 0 : w4.s.param2 = ROC_AE_CPT_BLOCK_TYPE2;
476 : : }
477 : : }
478 : :
479 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_MODEX;
480 : :
481 : 0 : w4.s.param1 = mod_len;
482 : 0 : w4.s.dlen = dlen;
483 : :
484 : 0 : inst->w4.u64 = w4.u64;
485 : 0 : inst->rptr = (uintptr_t)dptr;
486 : 0 : }
487 : :
488 : : static __rte_always_inline int __rte_hot
489 : : cnxk_ae_enqueue_rsa_op(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
490 : : struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
491 : : {
492 : : struct rte_crypto_rsa_op_param *rsa = &op->asym->rsa;
493 : : struct rte_crypto_rsa_xform *ctx = &sess->rsa_ctx;
494 : :
495 [ # # # # : 0 : switch (rsa->op_type) {
# ]
496 [ # # ]: 0 : case RTE_CRYPTO_ASYM_OP_VERIFY:
497 : : cnxk_ae_rsa_prep(op, meta_buf, ctx, &rsa->sign, inst);
498 : : break;
499 [ # # ]: 0 : case RTE_CRYPTO_ASYM_OP_ENCRYPT:
500 : : cnxk_ae_rsa_prep(op, meta_buf, ctx, &rsa->message, inst);
501 : : break;
502 : 0 : case RTE_CRYPTO_ASYM_OP_SIGN:
503 [ # # ]: 0 : if (ctx->key_type == RTE_RSA_KEY_TYPE_QT)
504 : : cnxk_ae_rsa_crt_prep(op, meta_buf, ctx, &rsa->message, inst);
505 : : else
506 : : cnxk_ae_rsa_exp_prep(op, meta_buf, ctx, &rsa->message, inst);
507 : : break;
508 : 0 : case RTE_CRYPTO_ASYM_OP_DECRYPT:
509 [ # # ]: 0 : if (ctx->key_type == RTE_RSA_KEY_TYPE_QT)
510 : : cnxk_ae_rsa_crt_prep(op, meta_buf, ctx, &rsa->cipher, inst);
511 : : else
512 : : cnxk_ae_rsa_exp_prep(op, meta_buf, ctx, &rsa->cipher, inst);
513 : : break;
514 : 0 : default:
515 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
516 : 0 : return -EINVAL;
517 : : }
518 : : return 0;
519 : : }
520 : :
521 : : static __rte_always_inline void
522 : : cnxk_ae_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
523 : : struct roc_ae_buf_ptr *meta_buf,
524 : : uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
525 : : struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
526 : : {
527 : 0 : uint16_t message_len = ecdsa->message.length;
528 : 0 : uint16_t pkey_len = sess->ec_ctx.pkey.length;
529 : : uint8_t curveid = sess->ec_ctx.curveid;
530 : : uint16_t p_align, k_align, m_align;
531 : 0 : uint16_t k_len = ecdsa->k.length;
532 : : uint16_t order_len, prime_len;
533 : : uint16_t o_offset, pk_offset;
534 : : union cpt_inst_w4 w4;
535 : : uint16_t dlen;
536 : : uint8_t *dptr;
537 : :
538 : 0 : prime_len = ec_grp->prime.length;
539 : 0 : order_len = ec_grp->order.length;
540 : :
541 : : /* Truncate input length to curve prime length */
542 : : if (message_len > prime_len)
543 : : message_len = prime_len;
544 : 0 : m_align = RTE_ALIGN_CEIL(message_len, 8);
545 : :
546 : 0 : p_align = RTE_ALIGN_CEIL(prime_len, 8);
547 : 0 : k_align = RTE_ALIGN_CEIL(k_len, 8);
548 : :
549 : : /* Set write offset for order and private key */
550 : 0 : o_offset = prime_len - order_len;
551 : 0 : pk_offset = p_align - pkey_len;
552 : :
553 : : /* Input buffer */
554 : : dptr = meta_buf->vaddr;
555 : 0 : inst->dptr = (uintptr_t)dptr;
556 : :
557 : : /*
558 : : * Set dlen = sum(sizeof(fpm address), ROUNDUP8(scalar len, input len),
559 : : * ROUNDUP8(priv key len, prime len, order len)).
560 : : * Please note, private key, order cannot exceed prime
561 : : * length i.e 3 * p_align.
562 : : */
563 : 0 : dlen = sizeof(fpm_table_iova) + k_align + m_align + p_align * 5;
564 : :
565 : 0 : memset(dptr, 0, dlen);
566 : :
567 : 0 : *(uint64_t *)dptr = fpm_table_iova;
568 : 0 : dptr += sizeof(fpm_table_iova);
569 : :
570 : 0 : memcpy(dptr, ecdsa->k.data, k_len);
571 : 0 : dptr += k_align;
572 : :
573 : 0 : memcpy(dptr, ec_grp->prime.data, prime_len);
574 : 0 : dptr += p_align;
575 : :
576 : 0 : memcpy(dptr + o_offset, ec_grp->order.data, order_len);
577 : 0 : dptr += p_align;
578 : :
579 : 0 : memcpy(dptr + pk_offset, sess->ec_ctx.pkey.data, pkey_len);
580 : 0 : dptr += p_align;
581 : :
582 : 0 : memcpy(dptr, ecdsa->message.data, message_len);
583 : 0 : dptr += m_align;
584 : :
585 : 0 : memcpy(dptr, ec_grp->consta.data, prime_len);
586 : 0 : dptr += p_align;
587 : :
588 : 0 : memcpy(dptr, ec_grp->constb.data, prime_len);
589 : 0 : dptr += p_align;
590 : :
591 : : /* Setup opcodes */
592 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_EC;
593 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_EC_SIGN;
594 : :
595 : 0 : w4.s.param1 = curveid | (message_len << 8);
596 : 0 : w4.s.param2 = (p_align << 8) | k_len;
597 : 0 : w4.s.dlen = dlen;
598 : :
599 : 0 : inst->w4.u64 = w4.u64;
600 : 0 : inst->rptr = (uintptr_t)dptr;
601 : 0 : }
602 : :
603 : : static __rte_always_inline void
604 : : cnxk_ae_ecdsa_verify_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
605 : : struct roc_ae_buf_ptr *meta_buf,
606 : : uint64_t fpm_table_iova,
607 : : struct roc_ae_ec_group *ec_grp, struct cnxk_ae_sess *sess,
608 : : struct cpt_inst_s *inst)
609 : : {
610 : 0 : uint32_t message_len = ecdsa->message.length;
611 : 0 : uint16_t qx_len = sess->ec_ctx.q.x.length;
612 : 0 : uint16_t qy_len = sess->ec_ctx.q.y.length;
613 : : uint8_t curveid = sess->ec_ctx.curveid;
614 : : uint16_t o_offset, r_offset, s_offset;
615 : 0 : uint16_t r_len = ecdsa->r.length;
616 : 0 : uint16_t s_len = ecdsa->s.length;
617 : : uint16_t order_len, prime_len;
618 : : uint16_t qx_offset, qy_offset;
619 : : uint16_t p_align, m_align;
620 : : union cpt_inst_w4 w4;
621 : : uint16_t dlen;
622 : : uint8_t *dptr;
623 : :
624 : 0 : prime_len = ec_grp->prime.length;
625 : 0 : order_len = ec_grp->order.length;
626 : :
627 : : /* Truncate input length to curve prime length */
628 : : if (message_len > prime_len)
629 : : message_len = prime_len;
630 : :
631 : 0 : m_align = RTE_ALIGN_CEIL(message_len, 8);
632 : 0 : p_align = RTE_ALIGN_CEIL(prime_len, 8);
633 : :
634 : : /* Set write offset for sign, order and public key coordinates */
635 : 0 : o_offset = prime_len - order_len;
636 : 0 : qx_offset = prime_len - qx_len;
637 : 0 : qy_offset = prime_len - qy_len;
638 : 0 : r_offset = prime_len - r_len;
639 : 0 : s_offset = prime_len - s_len;
640 : :
641 : : /* Input buffer */
642 : : dptr = meta_buf->vaddr;
643 : 0 : inst->dptr = (uintptr_t)dptr;
644 : :
645 : : /*
646 : : * Set dlen = sum(sizeof(fpm address), ROUNDUP8(message len),
647 : : * ROUNDUP8(sign len(r and s), public key len(x and y coordinates),
648 : : * prime len, order len)).
649 : : * Please note sign, public key and order can not exceed prime length
650 : : * i.e. 6 * p_align
651 : : */
652 : 0 : dlen = sizeof(fpm_table_iova) + m_align + (8 * p_align);
653 : :
654 : 0 : memset(dptr, 0, dlen);
655 : :
656 : 0 : *(uint64_t *)dptr = fpm_table_iova;
657 : 0 : dptr += sizeof(fpm_table_iova);
658 : :
659 : 0 : memcpy(dptr + r_offset, ecdsa->r.data, r_len);
660 : 0 : dptr += p_align;
661 : :
662 : 0 : memcpy(dptr + s_offset, ecdsa->s.data, s_len);
663 : 0 : dptr += p_align;
664 : :
665 : 0 : memcpy(dptr, ecdsa->message.data, message_len);
666 : 0 : dptr += m_align;
667 : :
668 : 0 : memcpy(dptr + o_offset, ec_grp->order.data, order_len);
669 : 0 : dptr += p_align;
670 : :
671 : 0 : memcpy(dptr, ec_grp->prime.data, prime_len);
672 : 0 : dptr += p_align;
673 : :
674 : 0 : memcpy(dptr + qx_offset, sess->ec_ctx.q.x.data, qx_len);
675 : 0 : dptr += p_align;
676 : :
677 : 0 : memcpy(dptr + qy_offset, sess->ec_ctx.q.y.data, qy_len);
678 : 0 : dptr += p_align;
679 : :
680 : 0 : memcpy(dptr, ec_grp->consta.data, prime_len);
681 : 0 : dptr += p_align;
682 : :
683 : 0 : memcpy(dptr, ec_grp->constb.data, prime_len);
684 : 0 : dptr += p_align;
685 : :
686 : : /* Setup opcodes */
687 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_EC;
688 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_EC_VERIFY;
689 : :
690 : 0 : w4.s.param1 = curveid | (message_len << 8);
691 : 0 : w4.s.param2 = 0;
692 : 0 : w4.s.dlen = dlen;
693 : :
694 : 0 : inst->w4.u64 = w4.u64;
695 : 0 : inst->rptr = (uintptr_t)dptr;
696 : 0 : }
697 : :
698 : : static __rte_always_inline int __rte_hot
699 : : cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op *op,
700 : : struct roc_ae_buf_ptr *meta_buf,
701 : : struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
702 : : struct roc_ae_ec_group **ec_grp,
703 : : struct cpt_inst_s *inst)
704 : : {
705 : : struct rte_crypto_ecdsa_op_param *ecdsa = &op->asym->ecdsa;
706 : 0 : uint8_t curveid = sess->ec_ctx.curveid;
707 : :
708 : 0 : if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
709 : 0 : cnxk_ae_ecdsa_sign_prep(ecdsa, meta_buf, fpm_iova[curveid],
710 : 0 : ec_grp[curveid], sess, inst);
711 [ # # ]: 0 : else if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
712 : 0 : cnxk_ae_ecdsa_verify_prep(ecdsa, meta_buf, fpm_iova[curveid],
713 : 0 : ec_grp[curveid], sess, inst);
714 : : else {
715 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
716 : 0 : return -EINVAL;
717 : : }
718 : : return 0;
719 : : }
720 : :
721 : : static __rte_always_inline void
722 : : cnxk_ae_sm2_sign_prep(struct rte_crypto_sm2_op_param *sm2,
723 : : struct roc_ae_buf_ptr *meta_buf,
724 : : uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
725 : : struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
726 : : {
727 : 0 : uint16_t message_len = sm2->message.length;
728 : 0 : uint16_t pkey_len = sess->ec_ctx.pkey.length;
729 : : uint16_t p_align, k_align, m_align;
730 : 0 : uint16_t k_len = sm2->k.length;
731 : : uint16_t order_len, prime_len;
732 : : uint16_t o_offset, pk_offset;
733 : : union cpt_inst_w4 w4;
734 : : uint16_t dlen;
735 : : uint8_t *dptr;
736 : :
737 : 0 : prime_len = ec_grp->prime.length;
738 : 0 : order_len = ec_grp->order.length;
739 : :
740 : : /* Truncate input length to curve prime length */
741 : : if (message_len > prime_len)
742 : : message_len = prime_len;
743 : 0 : m_align = RTE_ALIGN_CEIL(message_len, 8);
744 : :
745 : 0 : p_align = RTE_ALIGN_CEIL(prime_len, 8);
746 : 0 : k_align = RTE_ALIGN_CEIL(k_len, 8);
747 : :
748 : : /* Set write offset for order and private key */
749 : 0 : o_offset = prime_len - order_len;
750 : 0 : pk_offset = p_align - pkey_len;
751 : :
752 : : /* Input buffer */
753 : : dptr = meta_buf->vaddr;
754 : 0 : inst->dptr = (uintptr_t)dptr;
755 : :
756 : : /*
757 : : * Set dlen = sum(sizeof(fpm address), ROUNDUP8(scalar len, input len),
758 : : * ROUNDUP8(priv key len, prime len, order len)).
759 : : * Please note, private key, order cannot exceed prime
760 : : * length i.e 3 * p_align.
761 : : */
762 : 0 : dlen = sizeof(fpm_table_iova) + k_align + m_align + p_align * 5;
763 : :
764 : 0 : memset(dptr, 0, dlen);
765 : :
766 : 0 : *(uint64_t *)dptr = fpm_table_iova;
767 : 0 : dptr += sizeof(fpm_table_iova);
768 : :
769 [ # # ]: 0 : rte_memcpy(dptr, sm2->k.data, k_len);
770 : 0 : dptr += k_align;
771 : :
772 [ # # ]: 0 : rte_memcpy(dptr, ec_grp->prime.data, prime_len);
773 : 0 : dptr += p_align;
774 : :
775 [ # # ]: 0 : rte_memcpy(dptr + o_offset, ec_grp->order.data, order_len);
776 : 0 : dptr += p_align;
777 : :
778 [ # # ]: 0 : rte_memcpy(dptr + pk_offset, sess->ec_ctx.pkey.data, pkey_len);
779 : 0 : dptr += p_align;
780 : :
781 [ # # ]: 0 : rte_memcpy(dptr, sm2->message.data, message_len);
782 : 0 : dptr += m_align;
783 : :
784 [ # # ]: 0 : rte_memcpy(dptr, ec_grp->consta.data, prime_len);
785 : 0 : dptr += p_align;
786 : :
787 [ # # ]: 0 : rte_memcpy(dptr, ec_grp->constb.data, prime_len);
788 : 0 : dptr += p_align;
789 : :
790 : : /* Setup opcodes */
791 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_EC;
792 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_EC_SIGN;
793 : :
794 : : /* prime length of SM2 curve is same as that of P256. */
795 : 0 : w4.s.param1 = ROC_AE_EC_ID_P256 |
796 : 0 : ROC_AE_EC_PARAM1_SM2 | ROC_AE_EC_PARAM1_NONNIST | (message_len << 8);
797 : 0 : w4.s.param2 = (p_align << 8) | k_len;
798 : 0 : w4.s.dlen = dlen;
799 : :
800 : 0 : inst->w4.u64 = w4.u64;
801 : 0 : inst->rptr = (uintptr_t)dptr;
802 : 0 : }
803 : :
804 : : static __rte_always_inline void
805 : : cnxk_ae_sm2_verify_prep(struct rte_crypto_sm2_op_param *sm2,
806 : : struct roc_ae_buf_ptr *meta_buf,
807 : : uint64_t fpm_table_iova,
808 : : struct roc_ae_ec_group *ec_grp, struct cnxk_ae_sess *sess,
809 : : struct cpt_inst_s *inst)
810 : : {
811 : 0 : uint32_t message_len = sm2->message.length;
812 : : uint16_t o_offset, r_offset, s_offset;
813 : 0 : uint16_t qx_len = sess->ec_ctx.q.x.length;
814 : 0 : uint16_t qy_len = sess->ec_ctx.q.y.length;
815 : 0 : uint16_t r_len = sm2->r.length;
816 : 0 : uint16_t s_len = sm2->s.length;
817 : : uint16_t order_len, prime_len;
818 : : uint16_t qx_offset, qy_offset;
819 : : uint16_t p_align, m_align;
820 : : union cpt_inst_w4 w4;
821 : : uint16_t dlen;
822 : : uint8_t *dptr;
823 : :
824 : 0 : prime_len = ec_grp->prime.length;
825 : 0 : order_len = ec_grp->order.length;
826 : :
827 : : /* Truncate input length to curve prime length */
828 : : if (message_len > prime_len)
829 : : message_len = prime_len;
830 : :
831 : 0 : m_align = RTE_ALIGN_CEIL(message_len, 8);
832 : 0 : p_align = RTE_ALIGN_CEIL(prime_len, 8);
833 : :
834 : : /* Set write offset for sign, order and public key coordinates */
835 : 0 : o_offset = prime_len - order_len;
836 : 0 : qx_offset = prime_len - qx_len;
837 : 0 : qy_offset = prime_len - qy_len;
838 : 0 : r_offset = prime_len - r_len;
839 : 0 : s_offset = prime_len - s_len;
840 : :
841 : : /* Input buffer */
842 : : dptr = meta_buf->vaddr;
843 : 0 : inst->dptr = (uintptr_t)dptr;
844 : :
845 : : /*
846 : : * Set dlen = sum(sizeof(fpm address), ROUNDUP8(message len),
847 : : * ROUNDUP8(sign len(r and s), public key len(x and y coordinates),
848 : : * prime len, order len)).
849 : : * Please note sign, public key and order can not exceed prime length
850 : : * i.e. 6 * p_align
851 : : */
852 : 0 : dlen = sizeof(fpm_table_iova) + m_align + (8 * p_align);
853 : :
854 : 0 : memset(dptr, 0, dlen);
855 : :
856 : 0 : *(uint64_t *)dptr = fpm_table_iova;
857 : 0 : dptr += sizeof(fpm_table_iova);
858 : :
859 [ # # ]: 0 : rte_memcpy(dptr + r_offset, sm2->r.data, r_len);
860 : 0 : dptr += p_align;
861 : :
862 [ # # ]: 0 : rte_memcpy(dptr + s_offset, sm2->s.data, s_len);
863 : 0 : dptr += p_align;
864 : :
865 [ # # # # ]: 0 : rte_memcpy(dptr, sm2->message.data, message_len);
866 : 0 : dptr += m_align;
867 : :
868 [ # # ]: 0 : rte_memcpy(dptr + o_offset, ec_grp->order.data, order_len);
869 : 0 : dptr += p_align;
870 : :
871 [ # # ]: 0 : rte_memcpy(dptr, ec_grp->prime.data, prime_len);
872 : 0 : dptr += p_align;
873 : :
874 [ # # ]: 0 : rte_memcpy(dptr + qx_offset, sess->ec_ctx.q.x.data, qx_len);
875 : 0 : dptr += p_align;
876 : :
877 [ # # ]: 0 : rte_memcpy(dptr + qy_offset, sess->ec_ctx.q.y.data, qy_len);
878 : 0 : dptr += p_align;
879 : :
880 [ # # ]: 0 : rte_memcpy(dptr, ec_grp->consta.data, prime_len);
881 : 0 : dptr += p_align;
882 : :
883 [ # # ]: 0 : rte_memcpy(dptr, ec_grp->constb.data, prime_len);
884 : 0 : dptr += p_align;
885 : :
886 : : /* Setup opcodes */
887 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_EC;
888 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_EC_VERIFY;
889 : :
890 : : /* prime length of SM2 curve is same as that of P256. */
891 : 0 : w4.s.param1 = ROC_AE_EC_ID_P256 |
892 : 0 : ROC_AE_EC_PARAM1_SM2 | ROC_AE_EC_PARAM1_NONNIST | (message_len << 8);
893 : 0 : w4.s.param2 = 0;
894 : 0 : w4.s.dlen = dlen;
895 : :
896 : 0 : inst->w4.u64 = w4.u64;
897 : 0 : inst->rptr = (uintptr_t)dptr;
898 : 0 : }
899 : :
900 : : static __rte_always_inline int __rte_hot
901 : : cnxk_ae_enqueue_sm2_op(struct rte_crypto_op *op,
902 : : struct roc_ae_buf_ptr *meta_buf,
903 : : struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
904 : : struct roc_ae_ec_group **ec_grp,
905 : : struct cpt_inst_s *inst)
906 : : {
907 : : struct rte_crypto_sm2_op_param *sm2 = &op->asym->sm2;
908 : 0 : uint8_t curveid = sess->ec_ctx.curveid;
909 : :
910 : 0 : if (sm2->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
911 : 0 : cnxk_ae_sm2_sign_prep(sm2, meta_buf, fpm_iova[curveid],
912 [ # # ]: 0 : ec_grp[curveid], sess, inst);
913 [ # # ]: 0 : else if (sm2->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
914 : 0 : cnxk_ae_sm2_verify_prep(sm2, meta_buf, fpm_iova[curveid],
915 [ # # ]: 0 : ec_grp[curveid], sess, inst);
916 : : else {
917 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
918 : 0 : return -EINVAL;
919 : : }
920 : : return 0;
921 : : }
922 : :
923 : : static __rte_always_inline int
924 : : cnxk_ae_ecfpm_prep(rte_crypto_param *scalar,
925 : : struct roc_ae_buf_ptr *meta_buf, uint64_t *fpm_iova,
926 : : struct roc_ae_ec_group *ec_grp, uint8_t curveid,
927 : : struct cpt_inst_s *inst)
928 : : {
929 : : uint16_t scalar_align, p_align;
930 : : uint16_t dlen, prime_len;
931 : : uint64_t fpm_table_iova;
932 : : union cpt_inst_w4 w4;
933 : : uint8_t *dptr;
934 : :
935 : 0 : prime_len = ec_grp->prime.length;
936 : 0 : fpm_table_iova = (uint64_t)fpm_iova[curveid];
937 : :
938 : : /* Input buffer */
939 : : dptr = meta_buf->vaddr;
940 : 0 : inst->dptr = (uintptr_t)dptr;
941 : :
942 : 0 : p_align = RTE_ALIGN_CEIL(prime_len, 8);
943 : 0 : scalar_align = RTE_ALIGN_CEIL(scalar->length, 8);
944 : :
945 : : /*
946 : : * Set dlen = sum(ROUNDUP8(input point(x and y coordinates), prime,
947 : : * scalar length),
948 : : * Please note point length is equivalent to prime of the curve
949 : : */
950 : 0 : dlen = sizeof(fpm_table_iova) + 3 * p_align + scalar_align;
951 : :
952 : 0 : memset(dptr, 0, dlen);
953 : :
954 : 0 : *(uint64_t *)dptr = fpm_table_iova;
955 : 0 : dptr += sizeof(fpm_table_iova);
956 : :
957 : : /* Copy scalar, prime */
958 : 0 : memcpy(dptr, scalar->data, scalar->length);
959 : 0 : dptr += scalar_align;
960 : 0 : memcpy(dptr, ec_grp->prime.data, ec_grp->prime.length);
961 : 0 : dptr += p_align;
962 : 0 : memcpy(dptr, ec_grp->consta.data, ec_grp->consta.length);
963 : 0 : dptr += p_align;
964 : 0 : memcpy(dptr, ec_grp->constb.data, ec_grp->constb.length);
965 : 0 : dptr += p_align;
966 : :
967 : : /* Setup opcodes */
968 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_ECC;
969 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_ECC_FPM;
970 : :
971 : 0 : w4.s.param1 = curveid | (1 << 8);
972 : 0 : w4.s.param2 = scalar->length;
973 : 0 : w4.s.dlen = dlen;
974 : :
975 : 0 : inst->w4.u64 = w4.u64;
976 : 0 : inst->rptr = (uintptr_t)dptr;
977 : :
978 : 0 : return 0;
979 : : }
980 : :
981 : : static __rte_always_inline int
982 : : cnxk_ae_ecpm_prep(rte_crypto_param *scalar, struct rte_crypto_ec_point *p,
983 : : struct roc_ae_buf_ptr *meta_buf,
984 : : struct roc_ae_ec_group *ec_grp, uint8_t curveid,
985 : : struct cpt_inst_s *inst)
986 : : {
987 : 0 : uint16_t x1_len = p->x.length;
988 : 0 : uint16_t y1_len = p->y.length;
989 : : uint16_t scalar_align, p_align;
990 : : uint16_t x1_offset, y1_offset;
991 : : uint16_t dlen, prime_len;
992 : : union cpt_inst_w4 w4;
993 : : uint8_t *dptr;
994 : :
995 : 0 : prime_len = ec_grp->prime.length;
996 : :
997 : : /* Input buffer */
998 : : dptr = meta_buf->vaddr;
999 : 0 : inst->dptr = (uintptr_t)dptr;
1000 : :
1001 : 0 : p_align = RTE_ALIGN_CEIL(prime_len, 8);
1002 : 0 : scalar_align = RTE_ALIGN_CEIL(scalar->length, 8);
1003 : :
1004 : : /*
1005 : : * Set dlen = sum(ROUNDUP8(input point(x and y coordinates), prime,
1006 : : * scalar length),
1007 : : * Please note point length is equivalent to prime of the curve
1008 : : */
1009 : 0 : dlen = 5 * p_align + scalar_align;
1010 : :
1011 : 0 : x1_offset = prime_len - x1_len;
1012 : 0 : y1_offset = prime_len - y1_len;
1013 : :
1014 : 0 : memset(dptr, 0, dlen);
1015 : :
1016 : : /* Copy input point, scalar, prime */
1017 : 0 : memcpy(dptr + x1_offset, p->x.data, x1_len);
1018 : 0 : dptr += p_align;
1019 : 0 : memcpy(dptr + y1_offset, p->y.data, y1_len);
1020 : 0 : dptr += p_align;
1021 : 0 : memcpy(dptr, scalar->data, scalar->length);
1022 : 0 : dptr += scalar_align;
1023 : 0 : memcpy(dptr, ec_grp->prime.data, ec_grp->prime.length);
1024 : 0 : dptr += p_align;
1025 : 0 : memcpy(dptr, ec_grp->consta.data, ec_grp->consta.length);
1026 : 0 : dptr += p_align;
1027 : 0 : memcpy(dptr, ec_grp->constb.data, ec_grp->constb.length);
1028 : 0 : dptr += p_align;
1029 : :
1030 : : /* Setup opcodes */
1031 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_ECC;
1032 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_ECC_UMP;
1033 : :
1034 : 0 : w4.s.param1 = curveid;
1035 : 0 : w4.s.param2 = scalar->length;
1036 : 0 : w4.s.dlen = dlen;
1037 : :
1038 : 0 : inst->w4.u64 = w4.u64;
1039 : 0 : inst->rptr = (uintptr_t)dptr;
1040 : :
1041 : 0 : return 0;
1042 : : }
1043 : :
1044 : : static __rte_always_inline int
1045 : : cnxk_ae_random_prep(uint16_t len, struct roc_ae_buf_ptr *meta_buf,
1046 : : struct cpt_inst_s *inst)
1047 : : {
1048 : : union cpt_inst_w4 w4;
1049 : : uint8_t *dptr;
1050 : :
1051 : : /* Input buffer */
1052 : : dptr = meta_buf->vaddr;
1053 : 0 : inst->dptr = (uintptr_t)dptr;
1054 : :
1055 : : /* Setup opcodes */
1056 : 0 : w4.s.opcode_major = ROC_AE_MAJOR_OP_RANDOM;
1057 : 0 : w4.s.opcode_minor = ROC_AE_MINOR_OP_RANDOM;
1058 : :
1059 : 0 : w4.s.param1 = len;
1060 : 0 : w4.s.param2 = 0;
1061 : 0 : w4.s.dlen = 0;
1062 : :
1063 : 0 : inst->w4.u64 = w4.u64;
1064 : 0 : inst->rptr = (uintptr_t)dptr;
1065 : :
1066 : 0 : return 0;
1067 : : }
1068 : :
1069 : : static __rte_always_inline int __rte_hot
1070 : : cnxk_ae_enqueue_ecdh_op(struct rte_crypto_op *op,
1071 : : struct roc_ae_buf_ptr *meta_buf,
1072 : : struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
1073 : : struct roc_ae_ec_group **ec_grp,
1074 : : struct cpt_inst_s *inst)
1075 : : {
1076 : : struct rte_crypto_ecdh_op_param *ecdh = &op->asym->ecdh;
1077 : 0 : uint8_t curveid = sess->ec_ctx.curveid;
1078 : : struct rte_crypto_ec_point point;
1079 : : rte_crypto_uint scalar;
1080 : : int ret = 0;
1081 : :
1082 : 0 : switch (ecdh->ke_type) {
1083 : 0 : case RTE_CRYPTO_ASYM_KE_PRIV_KEY_GENERATE:
1084 : 0 : cnxk_ae_random_prep(ecdh->priv_key.length, meta_buf, inst);
1085 : : break;
1086 : 0 : case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
1087 : 0 : scalar.data = sess->ec_ctx.pkey.data;
1088 : 0 : scalar.length = sess->ec_ctx.pkey.length;
1089 : 0 : cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
1090 : : curveid, inst);
1091 : : break;
1092 : 0 : case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
1093 : 0 : scalar.data = ec_grp[curveid]->order.data;
1094 : 0 : scalar.length = ec_grp[curveid]->order.length;
1095 : : cnxk_ae_ecpm_prep(&scalar, &ecdh->pub_key, meta_buf,
1096 : : ec_grp[curveid], curveid, inst);
1097 : : break;
1098 : 0 : case RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE:
1099 : 0 : scalar.data = sess->ec_ctx.pkey.data;
1100 : 0 : scalar.length = sess->ec_ctx.pkey.length;
1101 : 0 : point.x.data = sess->ec_ctx.q.x.data;
1102 : 0 : point.x.length = sess->ec_ctx.q.x.length;
1103 : 0 : point.y.data = sess->ec_ctx.q.y.data;
1104 : 0 : point.y.length = sess->ec_ctx.q.y.length;
1105 : 0 : cnxk_ae_ecpm_prep(&scalar, &point, meta_buf,
1106 : 0 : ec_grp[curveid], curveid, inst);
1107 : : break;
1108 : 0 : default:
1109 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
1110 : : ret = -EINVAL;
1111 : : }
1112 : :
1113 : : return ret;
1114 : : }
1115 : :
1116 : : static __rte_always_inline void
1117 : : cnxk_ae_dequeue_rsa_op(struct rte_crypto_op *cop, uint8_t *rptr,
1118 : : struct rte_crypto_rsa_xform *rsa_ctx)
1119 : : {
1120 : : struct rte_crypto_rsa_op_param *rsa = &cop->asym->rsa;
1121 : :
1122 : 0 : switch (rsa->op_type) {
1123 : 0 : case RTE_CRYPTO_ASYM_OP_ENCRYPT:
1124 : 0 : rsa->cipher.length = rsa_ctx->n.length;
1125 : 0 : memcpy(rsa->cipher.data, rptr, rsa->cipher.length);
1126 : : break;
1127 : 0 : case RTE_CRYPTO_ASYM_OP_DECRYPT:
1128 [ # # ]: 0 : if (rsa->padding.type == RTE_CRYPTO_RSA_PADDING_NONE) {
1129 : 0 : rsa->message.length = rsa_ctx->n.length;
1130 : 0 : memcpy(rsa->message.data, rptr, rsa->message.length);
1131 : : } else {
1132 : : /* Get length of decrypted output */
1133 : 0 : rsa->message.length =
1134 [ # # ]: 0 : rte_cpu_to_be_16(*((uint16_t *)rptr));
1135 : : /*
1136 : : * Offset output data pointer by length field
1137 : : * (2 bytes) and copy decrypted data.
1138 : : */
1139 : 0 : memcpy(rsa->message.data, rptr + 2,
1140 : : rsa->message.length);
1141 : : }
1142 : : break;
1143 : 0 : case RTE_CRYPTO_ASYM_OP_SIGN:
1144 : 0 : rsa->sign.length = rsa_ctx->n.length;
1145 : 0 : memcpy(rsa->sign.data, rptr, rsa->sign.length);
1146 : : break;
1147 : 0 : case RTE_CRYPTO_ASYM_OP_VERIFY:
1148 [ # # ]: 0 : if (rsa->padding.type == RTE_CRYPTO_RSA_PADDING_NONE) {
1149 : 0 : rsa->sign.length = rsa_ctx->n.length;
1150 : 0 : memcpy(rsa->sign.data, rptr, rsa->sign.length);
1151 : : } else {
1152 : : /* Get length of signed output */
1153 : 0 : rsa->sign.length =
1154 [ # # ]: 0 : rte_cpu_to_be_16(*((uint16_t *)rptr));
1155 : : /*
1156 : : * Offset output data pointer by length field
1157 : : * (2 bytes) and copy signed data.
1158 : : */
1159 : 0 : memcpy(rsa->sign.data, rptr + 2, rsa->sign.length);
1160 : : }
1161 [ # # ]: 0 : if (memcmp(rsa->sign.data, rsa->message.data,
1162 : : rsa->message.length)) {
1163 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1164 : : }
1165 : : break;
1166 : 0 : default:
1167 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
1168 : 0 : break;
1169 : : }
1170 : : }
1171 : :
1172 : : static __rte_always_inline void
1173 : : cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa, uint8_t *rptr,
1174 : : struct roc_ae_ec_ctx *ec,
1175 : : struct roc_ae_ec_group **ec_grp)
1176 : : {
1177 : 0 : int prime_len = ec_grp[ec->curveid]->prime.length;
1178 : :
1179 : 0 : if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
1180 : : return;
1181 : :
1182 : : /* Separate out sign r and s components */
1183 : 0 : memcpy(ecdsa->r.data, rptr, prime_len);
1184 : 0 : memcpy(ecdsa->s.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
1185 : 0 : ecdsa->r.length = prime_len;
1186 : 0 : ecdsa->s.length = prime_len;
1187 : : }
1188 : :
1189 : : static __rte_always_inline void
1190 : : cnxk_ae_dequeue_sm2_op(struct rte_crypto_sm2_op_param *sm2, uint8_t *rptr,
1191 : : struct roc_ae_ec_ctx *ec,
1192 : : struct roc_ae_ec_group **ec_grp)
1193 : : {
1194 : 0 : int prime_len = ec_grp[ec->curveid]->prime.length;
1195 : :
1196 : 0 : if (sm2->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
1197 : : return;
1198 : :
1199 : : /* Separate out sign r and s components */
1200 [ # # ]: 0 : rte_memcpy(sm2->r.data, rptr, prime_len);
1201 [ # # ]: 0 : rte_memcpy(sm2->s.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
1202 : 0 : sm2->r.length = prime_len;
1203 : 0 : sm2->s.length = prime_len;
1204 : : }
1205 : :
1206 : : static __rte_always_inline void
1207 : : cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm, uint8_t *rptr,
1208 : : struct roc_ae_ec_ctx *ec,
1209 : : struct roc_ae_ec_group **ec_grp)
1210 : : {
1211 : 0 : int prime_len = ec_grp[ec->curveid]->prime.length;
1212 : :
1213 : 0 : memcpy(ecpm->r.x.data, rptr, prime_len);
1214 : 0 : memcpy(ecpm->r.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
1215 : 0 : ecpm->r.x.length = prime_len;
1216 : 0 : ecpm->r.y.length = prime_len;
1217 : 0 : }
1218 : :
1219 : : static __rte_always_inline void
1220 : : cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
1221 : : struct roc_ae_ec_ctx *ec,
1222 : : struct roc_ae_ec_group **ec_grp)
1223 : : {
1224 : 0 : int prime_len = ec_grp[ec->curveid]->prime.length;
1225 : :
1226 : 0 : switch (ecdh->ke_type) {
1227 : 0 : case RTE_CRYPTO_ASYM_KE_PRIV_KEY_GENERATE:
1228 : 0 : memcpy(ecdh->priv_key.data, rptr, prime_len);
1229 : 0 : ecdh->priv_key.length = prime_len;
1230 : 0 : break;
1231 : 0 : case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
1232 : 0 : memcpy(ecdh->pub_key.x.data, rptr, prime_len);
1233 : 0 : memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
1234 : 0 : ecdh->pub_key.x.length = prime_len;
1235 : 0 : ecdh->pub_key.y.length = prime_len;
1236 : 0 : break;
1237 : : case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
1238 : : break;
1239 : 0 : case RTE_CRYPTO_ASYM_KE_SHARED_SECRET_COMPUTE:
1240 : 0 : memcpy(ecdh->shared_secret.x.data, rptr, prime_len);
1241 : 0 : memcpy(ecdh->shared_secret.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
1242 : 0 : ecdh->shared_secret.x.length = prime_len;
1243 : 0 : ecdh->shared_secret.y.length = prime_len;
1244 : 0 : break;
1245 : : default:
1246 : : break;
1247 : : }
1248 : : }
1249 : :
1250 : : static __rte_always_inline void *
1251 : : cnxk_ae_alloc_meta(struct roc_ae_buf_ptr *buf,
1252 : : struct rte_mempool *cpt_meta_pool,
1253 : : struct cpt_inflight_req *infl_req)
1254 : : {
1255 : : uint8_t *mdata;
1256 : :
1257 [ # # ]: 0 : if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0))
1258 : : return NULL;
1259 : :
1260 : 0 : buf->vaddr = mdata;
1261 : :
1262 : 0 : infl_req->mdata = mdata;
1263 : 0 : infl_req->op_flags |= CPT_OP_FLAGS_METABUF;
1264 : :
1265 : : return mdata;
1266 : : }
1267 : :
1268 : : static __rte_always_inline int32_t __rte_hot
1269 : : cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
1270 : : struct cpt_inflight_req *infl_req, struct cpt_inst_s *inst,
1271 : : struct cnxk_ae_sess *sess)
1272 : : {
1273 : : struct cpt_qp_meta_info *minfo = &qp->meta_info;
1274 : : struct rte_crypto_asym_op *asym_op = op->asym;
1275 : : struct roc_ae_buf_ptr meta_buf;
1276 : : uint64_t *mop;
1277 : : void *mdata;
1278 : : int ret;
1279 : :
1280 [ # # ]: 0 : mdata = cnxk_ae_alloc_meta(&meta_buf, minfo->pool, infl_req);
1281 [ # # ]: 0 : if (mdata == NULL)
1282 : : return -ENOMEM;
1283 : :
1284 : : /* Reserve 8B for RPTR */
1285 : 0 : meta_buf.vaddr = PLT_PTR_ADD(mdata, sizeof(uint64_t));
1286 : :
1287 [ # # # # : 0 : switch (sess->xfrm_type) {
# # # # ]
1288 [ # # ]: 0 : case RTE_CRYPTO_ASYM_XFORM_MODEX:
1289 : : ret = cnxk_ae_modex_prep(op, &meta_buf, &sess->mod_ctx, inst);
1290 [ # # ]: 0 : if (unlikely(ret))
1291 : 0 : goto req_fail;
1292 : : break;
1293 : : case RTE_CRYPTO_ASYM_XFORM_RSA:
1294 : : ret = cnxk_ae_enqueue_rsa_op(op, &meta_buf, sess, inst);
1295 [ # # ]: 0 : if (unlikely(ret))
1296 : 0 : goto req_fail;
1297 : : break;
1298 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECDSA:
1299 [ # # ]: 0 : ret = cnxk_ae_enqueue_ecdsa_op(op, &meta_buf, sess,
1300 : : sess->cnxk_fpm_iova,
1301 : : sess->ec_grp, inst);
1302 [ # # ]: 0 : if (unlikely(ret))
1303 : 0 : goto req_fail;
1304 : : break;
1305 : 0 : case RTE_CRYPTO_ASYM_XFORM_SM2:
1306 [ # # ]: 0 : ret = cnxk_ae_enqueue_sm2_op(op, &meta_buf, sess,
1307 : : sess->cnxk_fpm_iova,
1308 : : sess->ec_grp, inst);
1309 [ # # ]: 0 : if (unlikely(ret))
1310 : 0 : goto req_fail;
1311 : : break;
1312 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECPM:
1313 : 0 : ret = cnxk_ae_ecpm_prep(&asym_op->ecpm.scalar, &asym_op->ecpm.p, &meta_buf,
1314 : 0 : sess->ec_grp[sess->ec_ctx.curveid],
1315 : 0 : sess->ec_ctx.curveid, inst);
1316 : : if (unlikely(ret))
1317 : : goto req_fail;
1318 : : break;
1319 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECFPM:
1320 : 0 : ret = cnxk_ae_ecfpm_prep(&asym_op->ecpm.scalar, &meta_buf,
1321 : : sess->cnxk_fpm_iova,
1322 : 0 : sess->ec_grp[sess->ec_ctx.curveid],
1323 : 0 : sess->ec_ctx.curveid, inst);
1324 : : if (unlikely(ret))
1325 : : goto req_fail;
1326 : : break;
1327 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECDH:
1328 [ # # # # : 0 : ret = cnxk_ae_enqueue_ecdh_op(op, &meta_buf, sess,
# ]
1329 : : sess->cnxk_fpm_iova,
1330 : : sess->ec_grp, inst);
1331 [ # # ]: 0 : if (unlikely(ret))
1332 : 0 : goto req_fail;
1333 : : break;
1334 : 0 : default:
1335 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
1336 : : ret = -EINVAL;
1337 : 0 : goto req_fail;
1338 : : }
1339 : :
1340 : : mop = mdata;
1341 : 0 : mop[0] = inst->rptr;
1342 : 0 : return 0;
1343 : :
1344 : 0 : req_fail:
1345 [ # # ]: 0 : rte_mempool_put(minfo->pool, infl_req->mdata);
1346 : 0 : return ret;
1347 : : }
1348 : :
1349 : : static __rte_always_inline void
1350 : : cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
1351 : : uint8_t *rptr)
1352 : : {
1353 : : struct rte_crypto_asym_op *op = cop->asym;
1354 : :
1355 [ # # # # : 0 : switch (sess->xfrm_type) {
# # # ]
1356 [ # # # # : 0 : case RTE_CRYPTO_ASYM_XFORM_RSA:
# ]
1357 : : cnxk_ae_dequeue_rsa_op(cop, rptr, &sess->rsa_ctx);
1358 : : break;
1359 : 0 : case RTE_CRYPTO_ASYM_XFORM_MODEX:
1360 : 0 : op->modex.result.length = sess->mod_ctx.modulus.length;
1361 : 0 : memcpy(op->modex.result.data, rptr, op->modex.result.length);
1362 : : break;
1363 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECDSA:
1364 [ # # ]: 0 : cnxk_ae_dequeue_ecdsa_op(&op->ecdsa, rptr, &sess->ec_ctx,
1365 : : sess->ec_grp);
1366 : : break;
1367 : 0 : case RTE_CRYPTO_ASYM_XFORM_SM2:
1368 [ # # ]: 0 : cnxk_ae_dequeue_sm2_op(&op->sm2, rptr, &sess->ec_ctx,
1369 : : sess->ec_grp);
1370 : : break;
1371 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECPM:
1372 : : case RTE_CRYPTO_ASYM_XFORM_ECFPM:
1373 : 0 : cnxk_ae_dequeue_ecpm_op(&op->ecpm, rptr, &sess->ec_ctx,
1374 : : sess->ec_grp);
1375 : : break;
1376 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECDH:
1377 [ # # # # ]: 0 : cnxk_ae_dequeue_ecdh_op(&op->ecdh, rptr, &sess->ec_ctx,
1378 : : sess->ec_grp);
1379 : : break;
1380 : 0 : default:
1381 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
1382 : 0 : break;
1383 : : }
1384 : : }
1385 : : #endif /* _CNXK_AE_H_ */
|