f851509ec50442227c2b9bd141d3d9793bb5da58
[dpdk.git] / app / test-crypto-perf / cperf_ops.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2017 Intel Corporation
3  */
4
5 #include <rte_cryptodev.h>
6 #include <rte_ether.h>
7
8 #include "cperf_ops.h"
9 #include "cperf_test_vectors.h"
10
11 #ifdef RTE_LIBRTE_SECURITY
12 static int
13 cperf_set_ops_security(struct rte_crypto_op **ops,
14                 uint32_t src_buf_offset __rte_unused,
15                 uint32_t dst_buf_offset __rte_unused,
16                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
17                 const struct cperf_options *options __rte_unused,
18                 const struct cperf_test_vector *test_vector __rte_unused,
19                 uint16_t iv_offset __rte_unused, uint32_t *imix_idx)
20 {
21         uint16_t i;
22
23         for (i = 0; i < nb_ops; i++) {
24                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
25                 struct rte_security_session *sec_sess =
26                         (struct rte_security_session *)sess;
27                 uint32_t buf_sz;
28
29                 uint32_t *per_pkt_hfn = rte_crypto_op_ctod_offset(ops[i],
30                                         uint32_t *, iv_offset);
31                 *per_pkt_hfn = options->pdcp_ses_hfn_en ? 0 : PDCP_DEFAULT_HFN;
32
33                 ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
34                 rte_security_attach_session(ops[i], sec_sess);
35                 sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
36                                                         src_buf_offset);
37
38                 if (options->op_type == CPERF_PDCP) {
39                         sym_op->m_src->buf_len = options->segment_sz;
40                         sym_op->m_src->data_len = options->test_buffer_size;
41                         sym_op->m_src->pkt_len = sym_op->m_src->data_len;
42                 }
43
44                 if (options->op_type == CPERF_DOCSIS) {
45                         if (options->imix_distribution_count) {
46                                 buf_sz = options->imix_buffer_sizes[*imix_idx];
47                                 *imix_idx = (*imix_idx + 1) % options->pool_sz;
48                         } else
49                                 buf_sz = options->test_buffer_size;
50
51                         /* DOCSIS header is not CRC'ed */
52                         sym_op->auth.data.offset = options->docsis_hdr_sz;
53                         sym_op->auth.data.length = buf_sz -
54                                 sym_op->auth.data.offset - RTE_ETHER_CRC_LEN;
55                         /*
56                          * DOCSIS header and SRC and DST MAC addresses are not
57                          * ciphered
58                          */
59                         sym_op->cipher.data.offset = sym_op->auth.data.offset +
60                                 RTE_ETHER_HDR_LEN - RTE_ETHER_TYPE_LEN;
61                         sym_op->cipher.data.length = buf_sz -
62                                 sym_op->cipher.data.offset;
63                 }
64
65                 /* Set dest mbuf to NULL if out-of-place (dst_buf_offset = 0) */
66                 if (dst_buf_offset == 0)
67                         sym_op->m_dst = NULL;
68                 else
69                         sym_op->m_dst = (struct rte_mbuf *)((uint8_t *)ops[i] +
70                                                         dst_buf_offset);
71         }
72
73         return 0;
74 }
75 #endif
76
77 static int
78 cperf_set_ops_null_cipher(struct rte_crypto_op **ops,
79                 uint32_t src_buf_offset, uint32_t dst_buf_offset,
80                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
81                 const struct cperf_options *options,
82                 const struct cperf_test_vector *test_vector __rte_unused,
83                 uint16_t iv_offset __rte_unused, uint32_t *imix_idx)
84 {
85         uint16_t i;
86
87         for (i = 0; i < nb_ops; i++) {
88                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
89
90                 ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
91                 rte_crypto_op_attach_sym_session(ops[i], sess);
92
93                 sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
94                                                         src_buf_offset);
95
96                 /* Set dest mbuf to NULL if out-of-place (dst_buf_offset = 0) */
97                 if (dst_buf_offset == 0)
98                         sym_op->m_dst = NULL;
99                 else
100                         sym_op->m_dst = (struct rte_mbuf *)((uint8_t *)ops[i] +
101                                                         dst_buf_offset);
102
103                 /* cipher parameters */
104                 if (options->imix_distribution_count) {
105                         sym_op->cipher.data.length =
106                                 options->imix_buffer_sizes[*imix_idx];
107                         *imix_idx = (*imix_idx + 1) % options->pool_sz;
108                 } else
109                         sym_op->cipher.data.length = options->test_buffer_size;
110                 sym_op->cipher.data.offset = 0;
111         }
112
113         return 0;
114 }
115
116 static int
117 cperf_set_ops_null_auth(struct rte_crypto_op **ops,
118                 uint32_t src_buf_offset, uint32_t dst_buf_offset,
119                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
120                 const struct cperf_options *options,
121                 const struct cperf_test_vector *test_vector __rte_unused,
122                 uint16_t iv_offset __rte_unused, uint32_t *imix_idx)
123 {
124         uint16_t i;
125
126         for (i = 0; i < nb_ops; i++) {
127                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
128
129                 ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
130                 rte_crypto_op_attach_sym_session(ops[i], sess);
131
132                 sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
133                                                         src_buf_offset);
134
135                 /* Set dest mbuf to NULL if out-of-place (dst_buf_offset = 0) */
136                 if (dst_buf_offset == 0)
137                         sym_op->m_dst = NULL;
138                 else
139                         sym_op->m_dst = (struct rte_mbuf *)((uint8_t *)ops[i] +
140                                                         dst_buf_offset);
141
142                 /* auth parameters */
143                 if (options->imix_distribution_count) {
144                         sym_op->auth.data.length =
145                                 options->imix_buffer_sizes[*imix_idx];
146                         *imix_idx = (*imix_idx + 1) % options->pool_sz;
147                 } else
148                         sym_op->auth.data.length = options->test_buffer_size;
149                 sym_op->auth.data.offset = 0;
150         }
151
152         return 0;
153 }
154
155 static int
156 cperf_set_ops_cipher(struct rte_crypto_op **ops,
157                 uint32_t src_buf_offset, uint32_t dst_buf_offset,
158                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
159                 const struct cperf_options *options,
160                 const struct cperf_test_vector *test_vector,
161                 uint16_t iv_offset, uint32_t *imix_idx)
162 {
163         uint16_t i;
164
165         for (i = 0; i < nb_ops; i++) {
166                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
167
168                 ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
169                 rte_crypto_op_attach_sym_session(ops[i], sess);
170
171                 sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
172                                                         src_buf_offset);
173
174                 /* Set dest mbuf to NULL if out-of-place (dst_buf_offset = 0) */
175                 if (dst_buf_offset == 0)
176                         sym_op->m_dst = NULL;
177                 else
178                         sym_op->m_dst = (struct rte_mbuf *)((uint8_t *)ops[i] +
179                                                         dst_buf_offset);
180
181                 /* cipher parameters */
182                 if (options->imix_distribution_count) {
183                         sym_op->cipher.data.length =
184                                 options->imix_buffer_sizes[*imix_idx];
185                         *imix_idx = (*imix_idx + 1) % options->pool_sz;
186                 } else
187                         sym_op->cipher.data.length = options->test_buffer_size;
188
189                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ||
190                                 options->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 ||
191                                 options->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3)
192                         sym_op->cipher.data.length <<= 3;
193
194                 sym_op->cipher.data.offset = 0;
195         }
196
197         if (options->test == CPERF_TEST_TYPE_VERIFY) {
198                 for (i = 0; i < nb_ops; i++) {
199                         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
200                                         uint8_t *, iv_offset);
201
202                         memcpy(iv_ptr, test_vector->cipher_iv.data,
203                                         test_vector->cipher_iv.length);
204
205                 }
206         }
207
208         return 0;
209 }
210
211 static int
212 cperf_set_ops_auth(struct rte_crypto_op **ops,
213                 uint32_t src_buf_offset, uint32_t dst_buf_offset,
214                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
215                 const struct cperf_options *options,
216                 const struct cperf_test_vector *test_vector,
217                 uint16_t iv_offset, uint32_t *imix_idx)
218 {
219         uint16_t i;
220
221         for (i = 0; i < nb_ops; i++) {
222                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
223
224                 ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
225                 rte_crypto_op_attach_sym_session(ops[i], sess);
226
227                 sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
228                                                         src_buf_offset);
229
230                 /* Set dest mbuf to NULL if out-of-place (dst_buf_offset = 0) */
231                 if (dst_buf_offset == 0)
232                         sym_op->m_dst = NULL;
233                 else
234                         sym_op->m_dst = (struct rte_mbuf *)((uint8_t *)ops[i] +
235                                                         dst_buf_offset);
236
237                 if (test_vector->auth_iv.length) {
238                         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
239                                                                 uint8_t *,
240                                                                 iv_offset);
241                         memcpy(iv_ptr, test_vector->auth_iv.data,
242                                         test_vector->auth_iv.length);
243                 }
244
245                 /* authentication parameters */
246                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
247                         sym_op->auth.digest.data = test_vector->digest.data;
248                         sym_op->auth.digest.phys_addr =
249                                         test_vector->digest.phys_addr;
250                 } else {
251
252                         uint32_t offset = options->test_buffer_size;
253                         struct rte_mbuf *buf, *tbuf;
254
255                         if (options->out_of_place) {
256                                 buf = sym_op->m_dst;
257                         } else {
258                                 tbuf = sym_op->m_src;
259                                 while ((tbuf->next != NULL) &&
260                                                 (offset >= tbuf->data_len)) {
261                                         offset -= tbuf->data_len;
262                                         tbuf = tbuf->next;
263                                 }
264                                 /*
265                                  * If there is not enough room in segment,
266                                  * place the digest in the next segment
267                                  */
268                                 if ((tbuf->data_len - offset) < options->digest_sz) {
269                                         tbuf = tbuf->next;
270                                         offset = 0;
271                                 }
272                                 buf = tbuf;
273                         }
274
275                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
276                                         uint8_t *, offset);
277                         sym_op->auth.digest.phys_addr =
278                                         rte_pktmbuf_iova_offset(buf, offset);
279
280                 }
281
282                 if (options->imix_distribution_count) {
283                         sym_op->auth.data.length =
284                                 options->imix_buffer_sizes[*imix_idx];
285                         *imix_idx = (*imix_idx + 1) % options->pool_sz;
286                 } else
287                         sym_op->auth.data.length = options->test_buffer_size;
288
289                 if (options->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 ||
290                                 options->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 ||
291                                 options->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3)
292                         sym_op->auth.data.length <<= 3;
293
294                 sym_op->auth.data.offset = 0;
295         }
296
297         if (options->test == CPERF_TEST_TYPE_VERIFY) {
298                 if (test_vector->auth_iv.length) {
299                         for (i = 0; i < nb_ops; i++) {
300                                 uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
301                                                 uint8_t *, iv_offset);
302
303                                 memcpy(iv_ptr, test_vector->auth_iv.data,
304                                                 test_vector->auth_iv.length);
305                         }
306                 }
307         }
308         return 0;
309 }
310
311 static int
312 cperf_set_ops_cipher_auth(struct rte_crypto_op **ops,
313                 uint32_t src_buf_offset, uint32_t dst_buf_offset,
314                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
315                 const struct cperf_options *options,
316                 const struct cperf_test_vector *test_vector,
317                 uint16_t iv_offset, uint32_t *imix_idx)
318 {
319         uint16_t i;
320
321         for (i = 0; i < nb_ops; i++) {
322                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
323
324                 ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
325                 rte_crypto_op_attach_sym_session(ops[i], sess);
326
327                 sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
328                                                         src_buf_offset);
329
330                 /* Set dest mbuf to NULL if out-of-place (dst_buf_offset = 0) */
331                 if (dst_buf_offset == 0)
332                         sym_op->m_dst = NULL;
333                 else
334                         sym_op->m_dst = (struct rte_mbuf *)((uint8_t *)ops[i] +
335                                                         dst_buf_offset);
336
337                 /* cipher parameters */
338                 if (options->imix_distribution_count) {
339                         sym_op->cipher.data.length =
340                                 options->imix_buffer_sizes[*imix_idx];
341                         *imix_idx = (*imix_idx + 1) % options->pool_sz;
342                 } else
343                         sym_op->cipher.data.length = options->test_buffer_size;
344
345                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ||
346                                 options->cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 ||
347                                 options->cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3)
348                         sym_op->cipher.data.length <<= 3;
349
350                 sym_op->cipher.data.offset = 0;
351
352                 /* authentication parameters */
353                 if (options->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY) {
354                         sym_op->auth.digest.data = test_vector->digest.data;
355                         sym_op->auth.digest.phys_addr =
356                                         test_vector->digest.phys_addr;
357                 } else {
358
359                         uint32_t offset = options->test_buffer_size;
360                         struct rte_mbuf *buf, *tbuf;
361
362                         if (options->out_of_place) {
363                                 buf = sym_op->m_dst;
364                         } else {
365                                 tbuf = sym_op->m_src;
366                                 while ((tbuf->next != NULL) &&
367                                                 (offset >= tbuf->data_len)) {
368                                         offset -= tbuf->data_len;
369                                         tbuf = tbuf->next;
370                                 }
371                                 /*
372                                  * If there is not enough room in segment,
373                                  * place the digest in the next segment
374                                  */
375                                 if ((tbuf->data_len - offset) < options->digest_sz) {
376                                         tbuf = tbuf->next;
377                                         offset = 0;
378                                 }
379                                 buf = tbuf;
380                         }
381
382                         sym_op->auth.digest.data = rte_pktmbuf_mtod_offset(buf,
383                                         uint8_t *, offset);
384                         sym_op->auth.digest.phys_addr =
385                                         rte_pktmbuf_iova_offset(buf, offset);
386                 }
387
388                 if (options->imix_distribution_count) {
389                         sym_op->auth.data.length =
390                                 options->imix_buffer_sizes[*imix_idx];
391                         *imix_idx = (*imix_idx + 1) % options->pool_sz;
392                 } else
393                         sym_op->auth.data.length = options->test_buffer_size;
394
395                 if (options->auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 ||
396                                 options->auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 ||
397                                 options->auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3)
398                         sym_op->auth.data.length <<= 3;
399
400                 sym_op->auth.data.offset = 0;
401         }
402
403         if (options->test == CPERF_TEST_TYPE_VERIFY) {
404                 for (i = 0; i < nb_ops; i++) {
405                         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
406                                         uint8_t *, iv_offset);
407
408                         memcpy(iv_ptr, test_vector->cipher_iv.data,
409                                         test_vector->cipher_iv.length);
410                         if (test_vector->auth_iv.length) {
411                                 /*
412                                  * Copy IV after the crypto operation and
413                                  * the cipher IV
414                                  */
415                                 iv_ptr += test_vector->cipher_iv.length;
416                                 memcpy(iv_ptr, test_vector->auth_iv.data,
417                                                 test_vector->auth_iv.length);
418                         }
419                 }
420
421         }
422
423         return 0;
424 }
425
426 static int
427 cperf_set_ops_aead(struct rte_crypto_op **ops,
428                 uint32_t src_buf_offset, uint32_t dst_buf_offset,
429                 uint16_t nb_ops, struct rte_cryptodev_sym_session *sess,
430                 const struct cperf_options *options,
431                 const struct cperf_test_vector *test_vector,
432                 uint16_t iv_offset, uint32_t *imix_idx)
433 {
434         uint16_t i;
435         /* AAD is placed after the IV */
436         uint16_t aad_offset = iv_offset +
437                         RTE_ALIGN_CEIL(test_vector->aead_iv.length, 16);
438
439         for (i = 0; i < nb_ops; i++) {
440                 struct rte_crypto_sym_op *sym_op = ops[i]->sym;
441
442                 ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
443                 rte_crypto_op_attach_sym_session(ops[i], sess);
444
445                 sym_op->m_src = (struct rte_mbuf *)((uint8_t *)ops[i] +
446                                                         src_buf_offset);
447
448                 /* Set dest mbuf to NULL if out-of-place (dst_buf_offset = 0) */
449                 if (dst_buf_offset == 0)
450                         sym_op->m_dst = NULL;
451                 else
452                         sym_op->m_dst = (struct rte_mbuf *)((uint8_t *)ops[i] +
453                                                         dst_buf_offset);
454
455                 /* AEAD parameters */
456                 if (options->imix_distribution_count) {
457                         sym_op->aead.data.length =
458                                 options->imix_buffer_sizes[*imix_idx];
459                         *imix_idx = (*imix_idx + 1) % options->pool_sz;
460                 } else
461                         sym_op->aead.data.length = options->test_buffer_size;
462                 sym_op->aead.data.offset = 0;
463
464                 sym_op->aead.aad.data = rte_crypto_op_ctod_offset(ops[i],
465                                         uint8_t *, aad_offset);
466                 sym_op->aead.aad.phys_addr = rte_crypto_op_ctophys_offset(ops[i],
467                                         aad_offset);
468
469                 if (options->aead_op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
470                         sym_op->aead.digest.data = test_vector->digest.data;
471                         sym_op->aead.digest.phys_addr =
472                                         test_vector->digest.phys_addr;
473                 } else {
474
475                         uint32_t offset = sym_op->aead.data.length +
476                                                 sym_op->aead.data.offset;
477                         struct rte_mbuf *buf, *tbuf;
478
479                         if (options->out_of_place) {
480                                 buf = sym_op->m_dst;
481                         } else {
482                                 tbuf = sym_op->m_src;
483                                 while ((tbuf->next != NULL) &&
484                                                 (offset >= tbuf->data_len)) {
485                                         offset -= tbuf->data_len;
486                                         tbuf = tbuf->next;
487                                 }
488                                 /*
489                                  * If there is not enough room in segment,
490                                  * place the digest in the next segment
491                                  */
492                                 if ((tbuf->data_len - offset) < options->digest_sz) {
493                                         tbuf = tbuf->next;
494                                         offset = 0;
495                                 }
496                                 buf = tbuf;
497                         }
498
499                         sym_op->aead.digest.data = rte_pktmbuf_mtod_offset(buf,
500                                         uint8_t *, offset);
501                         sym_op->aead.digest.phys_addr =
502                                         rte_pktmbuf_iova_offset(buf, offset);
503                 }
504         }
505
506         if (options->test == CPERF_TEST_TYPE_VERIFY) {
507                 for (i = 0; i < nb_ops; i++) {
508                         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ops[i],
509                                         uint8_t *, iv_offset);
510
511                         /*
512                          * If doing AES-CCM, nonce is copied one byte
513                          * after the start of IV field, and AAD is copied
514                          * 18 bytes after the start of the AAD field.
515                          */
516                         if (options->aead_algo == RTE_CRYPTO_AEAD_AES_CCM) {
517                                 memcpy(iv_ptr + 1, test_vector->aead_iv.data,
518                                         test_vector->aead_iv.length);
519
520                                 memcpy(ops[i]->sym->aead.aad.data + 18,
521                                         test_vector->aad.data,
522                                         test_vector->aad.length);
523                         } else {
524                                 memcpy(iv_ptr, test_vector->aead_iv.data,
525                                         test_vector->aead_iv.length);
526
527                                 memcpy(ops[i]->sym->aead.aad.data,
528                                         test_vector->aad.data,
529                                         test_vector->aad.length);
530                         }
531                 }
532         }
533
534         return 0;
535 }
536
537 static struct rte_cryptodev_sym_session *
538 cperf_create_session(struct rte_mempool *sess_mp,
539         struct rte_mempool *priv_mp,
540         uint8_t dev_id,
541         const struct cperf_options *options,
542         const struct cperf_test_vector *test_vector,
543         uint16_t iv_offset)
544 {
545         struct rte_crypto_sym_xform cipher_xform;
546         struct rte_crypto_sym_xform auth_xform;
547         struct rte_crypto_sym_xform aead_xform;
548         struct rte_cryptodev_sym_session *sess = NULL;
549
550 #ifdef RTE_LIBRTE_SECURITY
551         /*
552          * security only
553          */
554         if (options->op_type == CPERF_PDCP) {
555                 /* Setup Cipher Parameters */
556                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
557                 cipher_xform.next = NULL;
558                 cipher_xform.cipher.algo = options->cipher_algo;
559                 cipher_xform.cipher.op = options->cipher_op;
560                 cipher_xform.cipher.iv.offset = iv_offset;
561                 cipher_xform.cipher.iv.length = 4;
562
563                 /* cipher different than null */
564                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
565                         cipher_xform.cipher.key.data = test_vector->cipher_key.data;
566                         cipher_xform.cipher.key.length = test_vector->cipher_key.length;
567                 } else {
568                         cipher_xform.cipher.key.data = NULL;
569                         cipher_xform.cipher.key.length = 0;
570                 }
571
572                 /* Setup Auth Parameters */
573                 if (options->auth_algo != 0) {
574                         auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
575                         auth_xform.next = NULL;
576                         auth_xform.auth.algo = options->auth_algo;
577                         auth_xform.auth.op = options->auth_op;
578                         auth_xform.auth.iv.offset = iv_offset +
579                                 cipher_xform.cipher.iv.length;
580
581                         /* auth different than null */
582                         if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
583                                 auth_xform.auth.digest_length = options->digest_sz;
584                                 auth_xform.auth.key.length = test_vector->auth_key.length;
585                                 auth_xform.auth.key.data = test_vector->auth_key.data;
586                                 auth_xform.auth.iv.length = test_vector->auth_iv.length;
587                         } else {
588                                 auth_xform.auth.digest_length = 0;
589                                 auth_xform.auth.key.length = 0;
590                                 auth_xform.auth.key.data = NULL;
591                                 auth_xform.auth.iv.length = 0;
592                         }
593
594                         cipher_xform.next = &auth_xform;
595                 } else {
596                         cipher_xform.next = NULL;
597                 }
598
599                 struct rte_security_session_conf sess_conf = {
600                         .action_type = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
601                         .protocol = RTE_SECURITY_PROTOCOL_PDCP,
602                         {.pdcp = {
603                                 .bearer = 0x16,
604                                 .domain = options->pdcp_domain,
605                                 .pkt_dir = 0,
606                                 .sn_size = options->pdcp_sn_sz,
607                                 .hfn = options->pdcp_ses_hfn_en ?
608                                         PDCP_DEFAULT_HFN : 0,
609                                 .hfn_threshold = 0x70C0A,
610                                 .hfn_ovrd = !(options->pdcp_ses_hfn_en),
611                         } },
612                         .crypto_xform = &cipher_xform
613                 };
614
615                 struct rte_security_ctx *ctx = (struct rte_security_ctx *)
616                                         rte_cryptodev_get_sec_ctx(dev_id);
617
618                 /* Create security session */
619                 return (void *)rte_security_session_create(ctx,
620                                         &sess_conf, sess_mp);
621         }
622         if (options->op_type == CPERF_DOCSIS) {
623                 enum rte_security_docsis_direction direction;
624
625                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
626                 cipher_xform.next = NULL;
627                 cipher_xform.cipher.algo = options->cipher_algo;
628                 cipher_xform.cipher.op = options->cipher_op;
629                 cipher_xform.cipher.iv.offset = iv_offset;
630                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
631                         cipher_xform.cipher.key.data =
632                                 test_vector->cipher_key.data;
633                         cipher_xform.cipher.key.length =
634                                 test_vector->cipher_key.length;
635                         cipher_xform.cipher.iv.length =
636                                 test_vector->cipher_iv.length;
637                 } else {
638                         cipher_xform.cipher.key.data = NULL;
639                         cipher_xform.cipher.key.length = 0;
640                         cipher_xform.cipher.iv.length = 0;
641                 }
642                 cipher_xform.next = NULL;
643
644                 if (options->cipher_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
645                         direction = RTE_SECURITY_DOCSIS_DOWNLINK;
646                 else
647                         direction = RTE_SECURITY_DOCSIS_UPLINK;
648
649                 struct rte_security_session_conf sess_conf = {
650                         .action_type =
651                                 RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
652                         .protocol = RTE_SECURITY_PROTOCOL_DOCSIS,
653                         {.docsis = {
654                                 .direction = direction,
655                         } },
656                         .crypto_xform = &cipher_xform
657                 };
658                 struct rte_security_ctx *ctx = (struct rte_security_ctx *)
659                                         rte_cryptodev_get_sec_ctx(dev_id);
660
661                 /* Create security session */
662                 return (void *)rte_security_session_create(ctx,
663                                         &sess_conf, priv_mp);
664         }
665 #endif
666         sess = rte_cryptodev_sym_session_create(sess_mp);
667         /*
668          * cipher only
669          */
670         if (options->op_type == CPERF_CIPHER_ONLY) {
671                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
672                 cipher_xform.next = NULL;
673                 cipher_xform.cipher.algo = options->cipher_algo;
674                 cipher_xform.cipher.op = options->cipher_op;
675                 cipher_xform.cipher.iv.offset = iv_offset;
676
677                 /* cipher different than null */
678                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
679                         cipher_xform.cipher.key.data =
680                                         test_vector->cipher_key.data;
681                         cipher_xform.cipher.key.length =
682                                         test_vector->cipher_key.length;
683                         cipher_xform.cipher.iv.length =
684                                         test_vector->cipher_iv.length;
685                 } else {
686                         cipher_xform.cipher.key.data = NULL;
687                         cipher_xform.cipher.key.length = 0;
688                         cipher_xform.cipher.iv.length = 0;
689                 }
690                 /* create crypto session */
691                 rte_cryptodev_sym_session_init(dev_id, sess, &cipher_xform,
692                                 priv_mp);
693         /*
694          *  auth only
695          */
696         } else if (options->op_type == CPERF_AUTH_ONLY) {
697                 auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
698                 auth_xform.next = NULL;
699                 auth_xform.auth.algo = options->auth_algo;
700                 auth_xform.auth.op = options->auth_op;
701                 auth_xform.auth.iv.offset = iv_offset;
702
703                 /* auth different than null */
704                 if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
705                         auth_xform.auth.digest_length =
706                                         options->digest_sz;
707                         auth_xform.auth.key.length =
708                                         test_vector->auth_key.length;
709                         auth_xform.auth.key.data = test_vector->auth_key.data;
710                         auth_xform.auth.iv.length =
711                                         test_vector->auth_iv.length;
712                 } else {
713                         auth_xform.auth.digest_length = 0;
714                         auth_xform.auth.key.length = 0;
715                         auth_xform.auth.key.data = NULL;
716                         auth_xform.auth.iv.length = 0;
717                 }
718                 /* create crypto session */
719                 rte_cryptodev_sym_session_init(dev_id, sess, &auth_xform,
720                                 priv_mp);
721         /*
722          * cipher and auth
723          */
724         } else if (options->op_type == CPERF_CIPHER_THEN_AUTH
725                         || options->op_type == CPERF_AUTH_THEN_CIPHER) {
726                 /*
727                  * cipher
728                  */
729                 cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
730                 cipher_xform.next = NULL;
731                 cipher_xform.cipher.algo = options->cipher_algo;
732                 cipher_xform.cipher.op = options->cipher_op;
733                 cipher_xform.cipher.iv.offset = iv_offset;
734
735                 /* cipher different than null */
736                 if (options->cipher_algo != RTE_CRYPTO_CIPHER_NULL) {
737                         cipher_xform.cipher.key.data =
738                                         test_vector->cipher_key.data;
739                         cipher_xform.cipher.key.length =
740                                         test_vector->cipher_key.length;
741                         cipher_xform.cipher.iv.length =
742                                         test_vector->cipher_iv.length;
743                 } else {
744                         cipher_xform.cipher.key.data = NULL;
745                         cipher_xform.cipher.key.length = 0;
746                         cipher_xform.cipher.iv.length = 0;
747                 }
748
749                 /*
750                  * auth
751                  */
752                 auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
753                 auth_xform.next = NULL;
754                 auth_xform.auth.algo = options->auth_algo;
755                 auth_xform.auth.op = options->auth_op;
756                 auth_xform.auth.iv.offset = iv_offset +
757                         cipher_xform.cipher.iv.length;
758
759                 /* auth different than null */
760                 if (options->auth_algo != RTE_CRYPTO_AUTH_NULL) {
761                         auth_xform.auth.digest_length = options->digest_sz;
762                         auth_xform.auth.iv.length = test_vector->auth_iv.length;
763                         auth_xform.auth.key.length =
764                                         test_vector->auth_key.length;
765                         auth_xform.auth.key.data =
766                                         test_vector->auth_key.data;
767                 } else {
768                         auth_xform.auth.digest_length = 0;
769                         auth_xform.auth.key.length = 0;
770                         auth_xform.auth.key.data = NULL;
771                         auth_xform.auth.iv.length = 0;
772                 }
773
774                 /* cipher then auth */
775                 if (options->op_type == CPERF_CIPHER_THEN_AUTH) {
776                         cipher_xform.next = &auth_xform;
777                         /* create crypto session */
778                         rte_cryptodev_sym_session_init(dev_id,
779                                         sess, &cipher_xform, priv_mp);
780                 } else { /* auth then cipher */
781                         auth_xform.next = &cipher_xform;
782                         /* create crypto session */
783                         rte_cryptodev_sym_session_init(dev_id,
784                                         sess, &auth_xform, priv_mp);
785                 }
786         } else { /* options->op_type == CPERF_AEAD */
787                 aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD;
788                 aead_xform.next = NULL;
789                 aead_xform.aead.algo = options->aead_algo;
790                 aead_xform.aead.op = options->aead_op;
791                 aead_xform.aead.iv.offset = iv_offset;
792
793                 aead_xform.aead.key.data =
794                                         test_vector->aead_key.data;
795                 aead_xform.aead.key.length =
796                                         test_vector->aead_key.length;
797                 aead_xform.aead.iv.length = test_vector->aead_iv.length;
798
799                 aead_xform.aead.digest_length = options->digest_sz;
800                 aead_xform.aead.aad_length =
801                                         options->aead_aad_sz;
802
803                 /* Create crypto session */
804                 rte_cryptodev_sym_session_init(dev_id,
805                                         sess, &aead_xform, priv_mp);
806         }
807
808         return sess;
809 }
810
811 int
812 cperf_get_op_functions(const struct cperf_options *options,
813                 struct cperf_op_fns *op_fns)
814 {
815         memset(op_fns, 0, sizeof(struct cperf_op_fns));
816
817         op_fns->sess_create = cperf_create_session;
818
819         if (options->op_type == CPERF_AEAD) {
820                 op_fns->populate_ops = cperf_set_ops_aead;
821                 return 0;
822         }
823
824         if (options->op_type == CPERF_AUTH_THEN_CIPHER
825                         || options->op_type == CPERF_CIPHER_THEN_AUTH) {
826                 op_fns->populate_ops = cperf_set_ops_cipher_auth;
827                 return 0;
828         }
829         if (options->op_type == CPERF_AUTH_ONLY) {
830                 if (options->auth_algo == RTE_CRYPTO_AUTH_NULL)
831                         op_fns->populate_ops = cperf_set_ops_null_auth;
832                 else
833                         op_fns->populate_ops = cperf_set_ops_auth;
834                 return 0;
835         }
836         if (options->op_type == CPERF_CIPHER_ONLY) {
837                 if (options->cipher_algo == RTE_CRYPTO_CIPHER_NULL)
838                         op_fns->populate_ops = cperf_set_ops_null_cipher;
839                 else
840                         op_fns->populate_ops = cperf_set_ops_cipher;
841                 return 0;
842         }
843 #ifdef RTE_LIBRTE_SECURITY
844         if (options->op_type == CPERF_PDCP) {
845                 op_fns->populate_ops = cperf_set_ops_security;
846                 return 0;
847         }
848         if (options->op_type == CPERF_DOCSIS) {
849                 op_fns->populate_ops = cperf_set_ops_security;
850                 return 0;
851         }
852 #endif
853         return -1;
854 }