xref: /dpdk/app/test-crypto-perf/cperf_ops.c (revision db1162b4)
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 }
855