xref: /dpdk/app/test/test_cryptodev_blockcipher.c (revision bbbe38a6d59ccdda25917712701e629d0b10af6f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2017 Intel Corporation
3  */
4 
5 #include <rte_common.h>
6 #include <rte_hexdump.h>
7 #include <rte_mbuf.h>
8 #include <rte_malloc.h>
9 #include <rte_memcpy.h>
10 #include <rte_pause.h>
11 
12 #include <rte_crypto.h>
13 #include <rte_cryptodev.h>
14 #include <rte_cryptodev_pmd.h>
15 
16 #include "test.h"
17 #include "test_cryptodev.h"
18 #include "test_cryptodev_blockcipher.h"
19 #include "test_cryptodev_aes_test_vectors.h"
20 #include "test_cryptodev_des_test_vectors.h"
21 #include "test_cryptodev_hash_test_vectors.h"
22 
23 static int
24 verify_algo_support(const struct blockcipher_test_case *t,
25 		const uint8_t dev_id, const uint32_t digest_len)
26 {
27 	int ret = 0;
28 	const struct blockcipher_test_data *tdata = t->test_data;
29 	struct rte_cryptodev_sym_capability_idx cap_idx;
30 	const struct rte_cryptodev_symmetric_capability *capability;
31 
32 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
33 		cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
34 		cap_idx.algo.cipher = tdata->crypto_algo;
35 		capability = rte_cryptodev_sym_capability_get(dev_id, &cap_idx);
36 		if (capability == NULL)
37 			return -1;
38 
39 		if (cap_idx.algo.cipher != RTE_CRYPTO_CIPHER_NULL)
40 			ret = rte_cryptodev_sym_capability_check_cipher(capability,
41 							tdata->cipher_key.len,
42 							tdata->iv.len);
43 		if (ret != 0)
44 			return -1;
45 	}
46 
47 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
48 		cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
49 		cap_idx.algo.auth = tdata->auth_algo;
50 		capability = rte_cryptodev_sym_capability_get(dev_id, &cap_idx);
51 		if (capability == NULL)
52 			return -1;
53 
54 		if (cap_idx.algo.auth != RTE_CRYPTO_AUTH_NULL)
55 			ret = rte_cryptodev_sym_capability_check_auth(capability,
56 							tdata->auth_key.len,
57 							digest_len,
58 							0);
59 		if (ret != 0)
60 			return -1;
61 	}
62 
63 	return 0;
64 }
65 
66 static int
67 test_blockcipher_one_case(const struct blockcipher_test_case *t,
68 	struct rte_mempool *mbuf_pool,
69 	struct rte_mempool *op_mpool,
70 	struct rte_mempool *sess_mpool,
71 	struct rte_mempool *sess_priv_mpool,
72 	uint8_t dev_id,
73 	char *test_msg)
74 {
75 	struct rte_mbuf *ibuf = NULL;
76 	struct rte_mbuf *obuf = NULL;
77 	struct rte_mbuf *iobuf;
78 	struct rte_crypto_sym_xform *cipher_xform = NULL;
79 	struct rte_crypto_sym_xform *auth_xform = NULL;
80 	struct rte_crypto_sym_xform *init_xform = NULL;
81 	struct rte_crypto_sym_op *sym_op = NULL;
82 	struct rte_crypto_op *op = NULL;
83 	struct rte_cryptodev_info dev_info;
84 	struct rte_cryptodev_sym_session *sess = NULL;
85 
86 	int status = TEST_SUCCESS;
87 	const struct blockcipher_test_data *tdata = t->test_data;
88 	uint8_t cipher_key[tdata->cipher_key.len];
89 	uint8_t auth_key[tdata->auth_key.len];
90 	uint32_t buf_len = tdata->ciphertext.len;
91 	uint32_t digest_len = tdata->digest.len;
92 	char *buf_p = NULL;
93 	uint8_t src_pattern = 0xa5;
94 	uint8_t dst_pattern = 0xb6;
95 	uint8_t tmp_src_buf[MBUF_SIZE];
96 	uint8_t tmp_dst_buf[MBUF_SIZE];
97 	uint32_t pad_len;
98 
99 	int nb_segs = 1;
100 	uint32_t nb_iterates = 0;
101 
102 	rte_cryptodev_info_get(dev_id, &dev_info);
103 	uint64_t feat_flags = dev_info.feature_flags;
104 
105 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
106 		if (!(feat_flags & RTE_CRYPTODEV_FF_SYM_SESSIONLESS)) {
107 			printf("Device doesn't support sessionless operations "
108 				"Test Skipped.\n");
109 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
110 				"SKIPPED");
111 			return TEST_SKIPPED;
112 		}
113 	}
114 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_DIGEST_ENCRYPTED) {
115 		if (!(feat_flags & RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED)) {
116 			printf("Device doesn't support encrypted digest "
117 				"Test Skipped.\n");
118 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
119 				"SKIPPED");
120 			return TEST_SKIPPED;
121 		}
122 	}
123 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
124 		uint64_t oop_flag = RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT;
125 
126 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
127 			if (!(feat_flags & oop_flag)) {
128 				printf("Device doesn't support out-of-place "
129 					"scatter-gather in input mbuf. "
130 					"Test Skipped.\n");
131 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
132 					"SKIPPED");
133 				return TEST_SKIPPED;
134 			}
135 		} else {
136 			if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
137 				printf("Device doesn't support in-place "
138 					"scatter-gather mbufs. "
139 					"Test Skipped.\n");
140 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
141 					"SKIPPED");
142 				return TEST_SKIPPED;
143 			}
144 		}
145 
146 		nb_segs = 3;
147 	}
148 
149 	if (global_api_test_type == CRYPTODEV_RAW_API_TEST &&
150 		!(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP)) {
151 		printf("Device doesn't support raw data-path APIs. "
152 			"Test Skipped.\n");
153 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
154 		return TEST_SKIPPED;
155 	}
156 
157 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
158 		uint64_t oop_flags = RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
159 			RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT |
160 			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
161 			RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT;
162 		if (!(feat_flags & oop_flags)) {
163 			printf("Device doesn't support out-of-place operations."
164 				"Test Skipped.\n");
165 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
166 				"SKIPPED");
167 			return TEST_SKIPPED;
168 		}
169 		if (global_api_test_type == CRYPTODEV_RAW_API_TEST) {
170 			printf("Raw Data Path APIs do not support OOP, "
171 				"Test Skipped.\n");
172 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
173 			status = TEST_SKIPPED;
174 			goto error_exit;
175 		}
176 	}
177 
178 	if (tdata->cipher_key.len)
179 		memcpy(cipher_key, tdata->cipher_key.data,
180 			tdata->cipher_key.len);
181 	if (tdata->auth_key.len)
182 		memcpy(auth_key, tdata->auth_key.data,
183 			tdata->auth_key.len);
184 
185 	/* Check if PMD is capable of performing that test */
186 	if (verify_algo_support(t, dev_id, digest_len) < 0) {
187 		RTE_LOG(DEBUG, USER1,
188 			"Device does not support this algorithm."
189 			"Test Skipped.\n");
190 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
191 		return TEST_SKIPPED;
192 	}
193 
194 	/* preparing data */
195 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
196 		buf_len += digest_len;
197 
198 	pad_len = RTE_ALIGN(buf_len, 16) - buf_len;
199 	if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
200 		buf_len += pad_len;
201 
202 	/* for contiguous mbuf, nb_segs is 1 */
203 	ibuf = create_segmented_mbuf(mbuf_pool,
204 			tdata->ciphertext.len, nb_segs, src_pattern);
205 	if (ibuf == NULL) {
206 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
207 			"line %u FAILED: %s",
208 			__LINE__, "Cannot create source mbuf");
209 		status = TEST_FAILED;
210 		goto error_exit;
211 	}
212 
213 	/* only encryption requires plaintext.data input,
214 	 * decryption/(digest gen)/(digest verify) use ciphertext.data
215 	 * to be computed
216 	 */
217 	if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
218 		pktmbuf_write(ibuf, 0, tdata->plaintext.len,
219 				tdata->plaintext.data);
220 	else
221 		pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
222 				tdata->ciphertext.data);
223 
224 	buf_p = rte_pktmbuf_append(ibuf, digest_len);
225 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
226 		if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
227 			rte_memcpy(buf_p,
228 				tdata->ciphertext.data + tdata->ciphertext.len,
229 				 digest_len);
230 		else
231 			rte_memcpy(buf_p, tdata->digest.data, digest_len);
232 	else
233 		memset(buf_p, 0, digest_len);
234 	if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED) {
235 		buf_p = rte_pktmbuf_append(ibuf, pad_len);
236 		if (!buf_p) {
237 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
238 				"FAILED: %s", __LINE__,
239 				"No room to append mbuf");
240 			status = TEST_FAILED;
241 			goto error_exit;
242 		}
243 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
244 			const uint8_t *temp_p = tdata->ciphertext.data +
245 					tdata->ciphertext.len +
246 					digest_len;
247 			rte_memcpy(buf_p, temp_p, pad_len);
248 		} else
249 			memset(buf_p, 0xa5, pad_len);
250 	}
251 
252 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
253 		obuf = rte_pktmbuf_alloc(mbuf_pool);
254 		if (!obuf) {
255 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
256 				"FAILED: %s", __LINE__,
257 				"Allocation of rte_mbuf failed");
258 			status = TEST_FAILED;
259 			goto error_exit;
260 		}
261 		memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
262 
263 		buf_p = rte_pktmbuf_append(obuf, buf_len + pad_len);
264 		if (!buf_p) {
265 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
266 				"FAILED: %s", __LINE__,
267 				"No room to append mbuf");
268 			status = TEST_FAILED;
269 			goto error_exit;
270 		}
271 		memset(buf_p, 0, buf_len);
272 	}
273 
274 	/* Generate Crypto op data structure */
275 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
276 	if (!op) {
277 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
278 			"line %u FAILED: %s",
279 			__LINE__, "Failed to allocate symmetric crypto "
280 			"operation struct");
281 		status = TEST_FAILED;
282 		goto error_exit;
283 	}
284 
285 	sym_op = op->sym;
286 
287 iterate:
288 	if (nb_iterates) {
289 		struct rte_mbuf *tmp_buf = ibuf;
290 
291 		ibuf = obuf;
292 		obuf = tmp_buf;
293 
294 		rte_pktmbuf_reset(ibuf);
295 		rte_pktmbuf_reset(obuf);
296 
297 		rte_pktmbuf_append(ibuf, tdata->ciphertext.len);
298 
299 		/* only encryption requires plaintext.data input,
300 		 * decryption/(digest gen)/(digest verify) use ciphertext.data
301 		 * to be computed
302 		 */
303 		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
304 			pktmbuf_write(ibuf, 0, tdata->plaintext.len,
305 					tdata->plaintext.data);
306 		else
307 			pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
308 					tdata->ciphertext.data);
309 
310 		buf_p = rte_pktmbuf_append(ibuf, digest_len);
311 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
312 			rte_memcpy(buf_p, tdata->digest.data, digest_len);
313 		else
314 			memset(buf_p, 0, digest_len);
315 
316 		memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
317 
318 		buf_p = rte_pktmbuf_append(obuf, buf_len);
319 		if (!buf_p) {
320 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
321 				"FAILED: %s", __LINE__,
322 				"No room to append mbuf");
323 			status = TEST_FAILED;
324 			goto error_exit;
325 		}
326 		memset(buf_p, 0, buf_len);
327 	}
328 
329 	sym_op->m_src = ibuf;
330 
331 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
332 		sym_op->m_dst = obuf;
333 		iobuf = obuf;
334 	} else {
335 		sym_op->m_dst = NULL;
336 		iobuf = ibuf;
337 	}
338 
339 	/* sessionless op requires allocate xform using
340 	 * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
341 	 * is used
342 	 */
343 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
344 		uint32_t n_xforms = 0;
345 
346 		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
347 			n_xforms++;
348 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
349 			n_xforms++;
350 
351 		if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
352 			== NULL) {
353 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
354 				"FAILED: %s", __LINE__, "Failed to "
355 				"allocate space for crypto transforms");
356 			status = TEST_FAILED;
357 			goto error_exit;
358 		}
359 	} else {
360 		cipher_xform = rte_zmalloc(NULL,
361 			sizeof(struct rte_crypto_sym_xform), 0);
362 
363 		auth_xform = rte_zmalloc(NULL,
364 			sizeof(struct rte_crypto_sym_xform), 0);
365 
366 		if (!cipher_xform || !auth_xform) {
367 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
368 				"FAILED: %s", __LINE__, "Failed to "
369 				"allocate memory for crypto transforms");
370 			status = TEST_FAILED;
371 			goto error_exit;
372 		}
373 	}
374 
375 	/* preparing xform, for sessioned op, init_xform is initialized
376 	 * here and later as param in rte_cryptodev_sym_session_create() call
377 	 */
378 	if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) {
379 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
380 			cipher_xform = op->sym->xform;
381 			auth_xform = cipher_xform->next;
382 			auth_xform->next = NULL;
383 		} else {
384 			cipher_xform->next = auth_xform;
385 			auth_xform->next = NULL;
386 			init_xform = cipher_xform;
387 		}
388 	} else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) {
389 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
390 			auth_xform = op->sym->xform;
391 			cipher_xform = auth_xform->next;
392 			cipher_xform->next = NULL;
393 		} else {
394 			auth_xform->next = cipher_xform;
395 			cipher_xform->next = NULL;
396 			init_xform = auth_xform;
397 		}
398 	} else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN_ENC) {
399 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
400 			auth_xform = op->sym->xform;
401 			cipher_xform = auth_xform->next;
402 			cipher_xform->next = NULL;
403 		} else {
404 			auth_xform->next = cipher_xform;
405 			cipher_xform->next = NULL;
406 			init_xform = auth_xform;
407 		}
408 	} else if (t->op_mask == BLOCKCIPHER_TEST_OP_DEC_AUTH_VERIFY) {
409 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
410 			cipher_xform = op->sym->xform;
411 			auth_xform = cipher_xform->next;
412 			auth_xform->next = NULL;
413 		} else {
414 			cipher_xform->next = auth_xform;
415 			auth_xform->next = NULL;
416 			init_xform = cipher_xform;
417 		}
418 	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) ||
419 			(t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) {
420 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
421 			cipher_xform = op->sym->xform;
422 		else
423 			init_xform = cipher_xform;
424 		cipher_xform->next = NULL;
425 	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) ||
426 			(t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) {
427 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
428 			auth_xform = op->sym->xform;
429 		else
430 			init_xform = auth_xform;
431 		auth_xform->next = NULL;
432 	} else {
433 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
434 			"line %u FAILED: %s",
435 			__LINE__, "Unrecognized operation");
436 		status = TEST_FAILED;
437 		goto error_exit;
438 	}
439 
440 	/*configure xforms & sym_op cipher and auth data*/
441 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
442 		cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
443 		cipher_xform->cipher.algo = tdata->crypto_algo;
444 		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
445 			cipher_xform->cipher.op =
446 				RTE_CRYPTO_CIPHER_OP_ENCRYPT;
447 		else
448 			cipher_xform->cipher.op =
449 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
450 		cipher_xform->cipher.key.data = cipher_key;
451 		cipher_xform->cipher.key.length = tdata->cipher_key.len;
452 		cipher_xform->cipher.iv.offset = IV_OFFSET;
453 
454 		if (tdata->crypto_algo == RTE_CRYPTO_CIPHER_NULL)
455 			cipher_xform->cipher.iv.length = 0;
456 		else
457 			cipher_xform->cipher.iv.length = tdata->iv.len;
458 
459 		sym_op->cipher.data.offset = tdata->cipher_offset;
460 		sym_op->cipher.data.length = tdata->ciphertext.len -
461 				tdata->cipher_offset;
462 		if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED) {
463 			sym_op->cipher.data.length += tdata->digest.len;
464 			sym_op->cipher.data.length += pad_len;
465 		}
466 		rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET),
467 				tdata->iv.data,
468 				tdata->iv.len);
469 	}
470 
471 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
472 		uint32_t digest_offset = tdata->ciphertext.len;
473 
474 		auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
475 		auth_xform->auth.algo = tdata->auth_algo;
476 		auth_xform->auth.key.length = tdata->auth_key.len;
477 		auth_xform->auth.key.data = auth_key;
478 		auth_xform->auth.digest_length = digest_len;
479 
480 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
481 			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
482 			sym_op->auth.digest.data = pktmbuf_mtod_offset
483 				(iobuf, digest_offset);
484 			sym_op->auth.digest.phys_addr =
485 				pktmbuf_iova_offset(iobuf,
486 					digest_offset);
487 		} else {
488 			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
489 			sym_op->auth.digest.data = pktmbuf_mtod_offset
490 				(sym_op->m_src, digest_offset);
491 			sym_op->auth.digest.phys_addr =
492 				pktmbuf_iova_offset(sym_op->m_src,
493 					digest_offset);
494 		}
495 
496 		sym_op->auth.data.offset = tdata->auth_offset;
497 		sym_op->auth.data.length = tdata->ciphertext.len -
498 				tdata->auth_offset;
499 	}
500 
501 	/**
502 	 * Create session for sessioned op. For mbuf iteration test,
503 	 * skip the session creation for the second iteration.
504 	 */
505 	if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) &&
506 			nb_iterates == 0) {
507 		sess = rte_cryptodev_sym_session_create(sess_mpool);
508 
509 		status = rte_cryptodev_sym_session_init(dev_id, sess,
510 				init_xform, sess_priv_mpool);
511 		if (status == -ENOTSUP) {
512 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "UNSUPPORTED");
513 			status = TEST_SKIPPED;
514 			goto error_exit;
515 		}
516 		if (!sess || status < 0) {
517 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
518 				"FAILED: %s", __LINE__,
519 				"Session creation failed");
520 			status = TEST_FAILED;
521 			goto error_exit;
522 		}
523 
524 		/* attach symmetric crypto session to crypto operations */
525 		rte_crypto_op_attach_sym_session(op, sess);
526 	}
527 
528 	debug_hexdump(stdout, "m_src(before):",
529 			sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
530 	rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr,
531 						sym_op->m_src->buf_len);
532 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
533 		debug_hexdump(stdout, "m_dst(before):",
534 			sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
535 		rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr,
536 						sym_op->m_dst->buf_len);
537 	}
538 
539 	/* Process crypto operation */
540 	if (global_api_test_type == CRYPTODEV_RAW_API_TEST) {
541 		uint8_t is_cipher = 0, is_auth = 0;
542 		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
543 			is_cipher = 1;
544 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
545 			is_auth = 1;
546 
547 		process_sym_raw_dp_op(dev_id, 0, op, is_cipher, is_auth, 0,
548 				tdata->iv.len);
549 	} else {
550 		if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
551 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
552 				"line %u FAILED: %s",
553 				__LINE__, "Error sending packet for encryption");
554 			status = TEST_FAILED;
555 			goto error_exit;
556 		}
557 
558 		op = NULL;
559 
560 		while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
561 			rte_pause();
562 
563 		if (!op) {
564 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
565 				"line %u FAILED: %s",
566 				__LINE__, "Failed to process sym crypto op");
567 			status = TEST_FAILED;
568 			goto error_exit;
569 		}
570 	}
571 
572 	debug_hexdump(stdout, "m_src(after):",
573 			sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
574 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
575 		debug_hexdump(stdout, "m_dst(after):",
576 			sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
577 
578 	/* Verify results */
579 	if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
580 		if ((t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) &&
581 			(op->status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED))
582 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
583 				"FAILED: Digest verification failed "
584 				"(0x%X)", __LINE__, op->status);
585 		else
586 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
587 				"FAILED: Operation failed "
588 				"(0x%X)", __LINE__, op->status);
589 		status = TEST_FAILED;
590 		goto error_exit;
591 	}
592 
593 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
594 		uint8_t buffer[2048];
595 		const uint8_t *compare_ref;
596 		uint32_t compare_len;
597 
598 		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
599 			compare_ref = tdata->ciphertext.data +
600 					tdata->cipher_offset;
601 			compare_len = tdata->ciphertext.len -
602 					tdata->cipher_offset;
603 			if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
604 				compare_len += tdata->digest.len;
605 		} else {
606 			compare_ref = tdata->plaintext.data +
607 					tdata->cipher_offset;
608 			compare_len = tdata->plaintext.len -
609 					tdata->cipher_offset;
610 		}
611 
612 		if (memcmp(rte_pktmbuf_read(iobuf, tdata->cipher_offset,
613 				compare_len, buffer), compare_ref,
614 				compare_len)) {
615 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
616 				"FAILED: %s", __LINE__,
617 				"Crypto data not as expected");
618 			status = TEST_FAILED;
619 			goto error_exit;
620 		}
621 	}
622 
623 	/* Check digest data only in enc-then-auth_gen case.
624 	 * In auth_gen-then-enc case, cipher text contains both encrypted
625 	 * plain text and encrypted digest value. If cipher text is correct,
626 	 * it implies digest is also generated properly.
627 	 */
628 	if (!(t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED))
629 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
630 			uint8_t *auth_res = pktmbuf_mtod_offset(iobuf,
631 						tdata->ciphertext.len);
632 
633 			if (memcmp(auth_res, tdata->digest.data, digest_len)) {
634 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
635 					"FAILED: %s", __LINE__, "Generated "
636 					"digest data not as expected");
637 				status = TEST_FAILED;
638 				goto error_exit;
639 			}
640 		}
641 
642 	/* The only parts that should have changed in the buffer are
643 	 * plaintext/ciphertext and digest.
644 	 * In OOP only the dest buffer should change.
645 	 */
646 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
647 		struct rte_mbuf *mbuf;
648 		uint8_t value;
649 		uint32_t head_unchanged_len, changed_len = 0;
650 		uint32_t i;
651 		uint32_t hdroom_used = 0, tlroom_used = 0;
652 		uint32_t hdroom = 0;
653 
654 		mbuf = sym_op->m_src;
655 		/*
656 		 * Crypto PMDs specify the headroom & tailroom it would use
657 		 * when processing the crypto operation. PMD is free to modify
658 		 * this space, and so the verification check should skip that
659 		 * block.
660 		 */
661 		hdroom_used = dev_info.min_mbuf_headroom_req;
662 		tlroom_used = dev_info.min_mbuf_tailroom_req;
663 
664 		/* Get headroom */
665 		hdroom = rte_pktmbuf_headroom(mbuf);
666 
667 		head_unchanged_len = mbuf->buf_len;
668 
669 		for (i = 0; i < mbuf->buf_len; i++) {
670 
671 			/* Skip headroom used by PMD */
672 			if (i == hdroom - hdroom_used)
673 				i += hdroom_used;
674 
675 			/* Skip tailroom used by PMD */
676 			if (i == (hdroom + mbuf->data_len))
677 				i += tlroom_used;
678 
679 			value = *((uint8_t *)(mbuf->buf_addr)+i);
680 			if (value != tmp_src_buf[i]) {
681 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
682 	"line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)",
683 					__LINE__, value, tmp_src_buf[i]);
684 				status = TEST_FAILED;
685 				goto error_exit;
686 			}
687 		}
688 
689 		mbuf = sym_op->m_dst;
690 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
691 			head_unchanged_len = hdroom + sym_op->auth.data.offset;
692 			changed_len = sym_op->auth.data.length;
693 			if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
694 				changed_len += digest_len;
695 		} else {
696 			/* cipher-only */
697 			head_unchanged_len = hdroom +
698 					sym_op->cipher.data.offset;
699 			changed_len = sym_op->cipher.data.length;
700 		}
701 
702 		if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
703 			changed_len = sym_op->cipher.data.length +
704 				digest_len + pad_len;
705 
706 		for (i = 0; i < mbuf->buf_len; i++) {
707 			if (i == head_unchanged_len)
708 				i += changed_len;
709 			value = *((uint8_t *)(mbuf->buf_addr)+i);
710 			if (value != tmp_dst_buf[i]) {
711 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
712 				"line %u FAILED: OOP dst outer mbuf data "
713 				"(0x%x) not as expected (0x%x)",
714 				__LINE__, value, tmp_dst_buf[i]);
715 				status = TEST_FAILED;
716 				goto error_exit;
717 			}
718 		}
719 
720 		if (!nb_iterates) {
721 			nb_iterates++;
722 			goto iterate;
723 		}
724 	} else {
725 		/* In-place operation */
726 		struct rte_mbuf *mbuf;
727 		uint8_t value;
728 		uint32_t head_unchanged_len = 0, changed_len = 0;
729 		uint32_t i;
730 		uint32_t hdroom_used = 0, tlroom_used = 0;
731 		uint32_t hdroom = 0;
732 
733 		/*
734 		 * Crypto PMDs specify the headroom & tailroom it would use
735 		 * when processing the crypto operation. PMD is free to modify
736 		 * this space, and so the verification check should skip that
737 		 * block.
738 		 */
739 		hdroom_used = dev_info.min_mbuf_headroom_req;
740 		tlroom_used = dev_info.min_mbuf_tailroom_req;
741 
742 		mbuf = sym_op->m_src;
743 
744 		/* Get headroom */
745 		hdroom = rte_pktmbuf_headroom(mbuf);
746 
747 		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
748 			head_unchanged_len = hdroom +
749 					sym_op->cipher.data.offset;
750 			changed_len = sym_op->cipher.data.length;
751 		} else {
752 			/* auth-only */
753 			head_unchanged_len = hdroom +
754 					sym_op->auth.data.offset +
755 					sym_op->auth.data.length;
756 			changed_len = 0;
757 		}
758 
759 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
760 			changed_len += digest_len;
761 
762 		if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
763 			changed_len = sym_op->cipher.data.length;
764 
765 		for (i = 0; i < mbuf->buf_len; i++) {
766 
767 			/* Skip headroom used by PMD */
768 			if (i == hdroom - hdroom_used)
769 				i += hdroom_used;
770 
771 			if (i == head_unchanged_len)
772 				i += changed_len;
773 
774 			/* Skip tailroom used by PMD */
775 			if (i == (hdroom + mbuf->data_len))
776 				i += tlroom_used;
777 
778 			value = *((uint8_t *)(mbuf->buf_addr)+i);
779 			if (value != tmp_src_buf[i]) {
780 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
781 				"line %u FAILED: outer mbuf data (0x%x) "
782 				"not as expected (0x%x)",
783 				__LINE__, value, tmp_src_buf[i]);
784 				status = TEST_FAILED;
785 				goto error_exit;
786 			}
787 		}
788 	}
789 
790 	snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
791 
792 error_exit:
793 	if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
794 		if (sess) {
795 			rte_cryptodev_sym_session_clear(dev_id, sess);
796 			rte_cryptodev_sym_session_free(sess);
797 		}
798 		if (cipher_xform)
799 			rte_free(cipher_xform);
800 		if (auth_xform)
801 			rte_free(auth_xform);
802 	}
803 
804 	if (op)
805 		rte_crypto_op_free(op);
806 
807 	if (obuf)
808 		rte_pktmbuf_free(obuf);
809 
810 	if (ibuf)
811 		rte_pktmbuf_free(ibuf);
812 
813 	return status;
814 }
815 
816 static int
817 blockcipher_test_case_run(const void *data)
818 {
819 	const struct blockcipher_test_case *tc_data = data;
820 	int status;
821 	char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];
822 
823 	status = test_blockcipher_one_case(tc_data,
824 			p_testsuite_params->mbuf_pool,
825 			p_testsuite_params->op_mpool,
826 			p_testsuite_params->session_mpool,
827 			p_testsuite_params->session_priv_mpool,
828 			p_testsuite_params->valid_devs[0],
829 			test_msg);
830 	return status;
831 }
832 
833 static int
834 aes_chain_setup(void)
835 {
836 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
837 	struct rte_cryptodev_info dev_info;
838 	uint64_t feat_flags;
839 	const enum rte_crypto_cipher_algorithm ciphers[] = {
840 		RTE_CRYPTO_CIPHER_NULL,
841 		RTE_CRYPTO_CIPHER_AES_CTR,
842 		RTE_CRYPTO_CIPHER_AES_CBC
843 	};
844 	const enum rte_crypto_auth_algorithm auths[] = {
845 		RTE_CRYPTO_AUTH_NULL,
846 		RTE_CRYPTO_AUTH_SHA1_HMAC,
847 		RTE_CRYPTO_AUTH_AES_XCBC_MAC,
848 		RTE_CRYPTO_AUTH_SHA256_HMAC,
849 		RTE_CRYPTO_AUTH_SHA512_HMAC,
850 		RTE_CRYPTO_AUTH_SHA224_HMAC,
851 		RTE_CRYPTO_AUTH_SHA384_HMAC
852 	};
853 
854 	rte_cryptodev_info_get(dev_id, &dev_info);
855 	feat_flags = dev_info.feature_flags;
856 
857 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
858 			((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
859 			!(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
860 		RTE_LOG(INFO, USER1, "Feature flag requirements for AES Chain "
861 				"testsuite not met\n");
862 		return TEST_SKIPPED;
863 	}
864 
865 	if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
866 			&& check_auth_capabilities_supported(auths,
867 			RTE_DIM(auths)) != 0) {
868 		RTE_LOG(INFO, USER1, "Capability requirements for AES Chain "
869 				"testsuite not met\n");
870 		return TEST_SKIPPED;
871 	}
872 
873 	return 0;
874 }
875 
876 static int
877 aes_cipheronly_setup(void)
878 {
879 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
880 	struct rte_cryptodev_info dev_info;
881 	uint64_t feat_flags;
882 	const enum rte_crypto_cipher_algorithm ciphers[] = {
883 		RTE_CRYPTO_CIPHER_NULL,
884 		RTE_CRYPTO_CIPHER_AES_CTR,
885 		RTE_CRYPTO_CIPHER_AES_CBC,
886 		RTE_CRYPTO_CIPHER_AES_ECB,
887 		RTE_CRYPTO_CIPHER_AES_XTS
888 	};
889 	const enum rte_crypto_auth_algorithm auths[] = {
890 		RTE_CRYPTO_AUTH_NULL,
891 		RTE_CRYPTO_AUTH_SHA1_HMAC,
892 		RTE_CRYPTO_AUTH_AES_XCBC_MAC
893 	};
894 
895 	rte_cryptodev_info_get(dev_id, &dev_info);
896 	feat_flags = dev_info.feature_flags;
897 
898 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
899 			((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
900 			!(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
901 		RTE_LOG(INFO, USER1, "Feature flag requirements for AES Cipheronly "
902 				"testsuite not met\n");
903 		return TEST_SKIPPED;
904 	}
905 
906 	if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
907 			&& check_auth_capabilities_supported(auths,
908 			RTE_DIM(auths)) != 0) {
909 		RTE_LOG(INFO, USER1, "Capability requirements for AES Cipheronly "
910 				"testsuite not met\n");
911 		return TEST_SKIPPED;
912 	}
913 
914 	return 0;
915 }
916 
917 static int
918 aes_docsis_setup(void)
919 {
920 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
921 	struct rte_cryptodev_info dev_info;
922 	uint64_t feat_flags;
923 	const enum rte_crypto_cipher_algorithm ciphers[] = {
924 		RTE_CRYPTO_CIPHER_AES_DOCSISBPI
925 	};
926 
927 	rte_cryptodev_info_get(dev_id, &dev_info);
928 	feat_flags = dev_info.feature_flags;
929 
930 	/* Data-path service does not support DOCSIS yet */
931 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
932 			(global_api_test_type == CRYPTODEV_RAW_API_TEST)) {
933 		RTE_LOG(INFO, USER1, "Feature flag requirements for AES Docsis "
934 				"testsuite not met\n");
935 		return TEST_SKIPPED;
936 	}
937 
938 	if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
939 		RTE_LOG(INFO, USER1, "Capability requirements for AES Docsis "
940 				"testsuite not met\n");
941 		return TEST_SKIPPED;
942 	}
943 
944 	return 0;
945 }
946 
947 static int
948 triple_des_chain_setup(void)
949 {
950 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
951 	struct rte_cryptodev_info dev_info;
952 	uint64_t feat_flags;
953 	const enum rte_crypto_cipher_algorithm ciphers[] = {
954 		RTE_CRYPTO_CIPHER_3DES_CTR,
955 		RTE_CRYPTO_CIPHER_3DES_CBC
956 	};
957 	const enum rte_crypto_auth_algorithm auths[] = {
958 		RTE_CRYPTO_AUTH_SHA1_HMAC,
959 		RTE_CRYPTO_AUTH_SHA1
960 	};
961 
962 	rte_cryptodev_info_get(dev_id, &dev_info);
963 	feat_flags = dev_info.feature_flags;
964 
965 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
966 			((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
967 			!(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
968 		RTE_LOG(INFO, USER1, "Feature flag requirements for 3DES Chain "
969 				"testsuite not met\n");
970 		return TEST_SKIPPED;
971 	}
972 
973 	if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
974 			&& check_auth_capabilities_supported(auths,
975 			RTE_DIM(auths)) != 0) {
976 		RTE_LOG(INFO, USER1, "Capability requirements for 3DES Chain "
977 				"testsuite not met\n");
978 		return TEST_SKIPPED;
979 	}
980 
981 	return 0;
982 }
983 
984 static int
985 triple_des_cipheronly_setup(void)
986 {
987 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
988 	struct rte_cryptodev_info dev_info;
989 	uint64_t feat_flags;
990 	const enum rte_crypto_cipher_algorithm ciphers[] = {
991 		RTE_CRYPTO_CIPHER_3DES_CTR,
992 		RTE_CRYPTO_CIPHER_3DES_CBC
993 	};
994 
995 	rte_cryptodev_info_get(dev_id, &dev_info);
996 	feat_flags = dev_info.feature_flags;
997 
998 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
999 			((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1000 			!(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1001 		RTE_LOG(INFO, USER1, "Feature flag requirements for 3DES "
1002 				"Cipheronly testsuite not met\n");
1003 		return TEST_SKIPPED;
1004 	}
1005 
1006 	if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1007 		RTE_LOG(INFO, USER1, "Capability requirements for 3DES "
1008 				"Cipheronly testsuite not met\n");
1009 		return TEST_SKIPPED;
1010 	}
1011 
1012 	return 0;
1013 }
1014 
1015 static int
1016 des_cipheronly_setup(void)
1017 {
1018 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
1019 	struct rte_cryptodev_info dev_info;
1020 	uint64_t feat_flags;
1021 	const enum rte_crypto_cipher_algorithm ciphers[] = {
1022 		RTE_CRYPTO_CIPHER_DES_CBC
1023 	};
1024 
1025 	rte_cryptodev_info_get(dev_id, &dev_info);
1026 	feat_flags = dev_info.feature_flags;
1027 
1028 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1029 			((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1030 			!(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1031 		RTE_LOG(INFO, USER1, "Feature flag requirements for DES "
1032 				"Cipheronly testsuite not met\n");
1033 		return TEST_SKIPPED;
1034 	}
1035 
1036 	if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1037 		RTE_LOG(INFO, USER1, "Capability requirements for DES "
1038 				"Cipheronly testsuite not met\n");
1039 		return TEST_SKIPPED;
1040 	}
1041 
1042 	return 0;
1043 }
1044 
1045 static int
1046 des_docsis_setup(void)
1047 {
1048 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
1049 	struct rte_cryptodev_info dev_info;
1050 	uint64_t feat_flags;
1051 	const enum rte_crypto_cipher_algorithm ciphers[] = {
1052 		RTE_CRYPTO_CIPHER_DES_DOCSISBPI
1053 	};
1054 
1055 	rte_cryptodev_info_get(dev_id, &dev_info);
1056 	feat_flags = dev_info.feature_flags;
1057 
1058 	/* Data-path service does not support DOCSIS yet */
1059 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1060 			(global_api_test_type == CRYPTODEV_RAW_API_TEST)) {
1061 		RTE_LOG(INFO, USER1, "Feature flag requirements for DES Docsis "
1062 				"testsuite not met\n");
1063 		return TEST_SKIPPED;
1064 	}
1065 
1066 	if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1067 		RTE_LOG(INFO, USER1, "Capability requirements for DES Docsis "
1068 				"testsuite not met\n");
1069 		return TEST_SKIPPED;
1070 	}
1071 
1072 	return 0;
1073 }
1074 
1075 static int
1076 authonly_setup(void)
1077 {
1078 	uint8_t dev_id = p_testsuite_params->valid_devs[0];
1079 	struct rte_cryptodev_info dev_info;
1080 	uint64_t feat_flags;
1081 	const enum rte_crypto_auth_algorithm auths[] = {
1082 		RTE_CRYPTO_AUTH_MD5,
1083 		RTE_CRYPTO_AUTH_MD5_HMAC,
1084 		RTE_CRYPTO_AUTH_SHA1,
1085 		RTE_CRYPTO_AUTH_SHA1_HMAC,
1086 		RTE_CRYPTO_AUTH_SHA224,
1087 		RTE_CRYPTO_AUTH_SHA224_HMAC,
1088 		RTE_CRYPTO_AUTH_SHA256,
1089 		RTE_CRYPTO_AUTH_SHA256_HMAC,
1090 		RTE_CRYPTO_AUTH_SHA384,
1091 		RTE_CRYPTO_AUTH_SHA384_HMAC,
1092 		RTE_CRYPTO_AUTH_SHA512,
1093 		RTE_CRYPTO_AUTH_SHA512_HMAC,
1094 		RTE_CRYPTO_AUTH_AES_CMAC,
1095 		RTE_CRYPTO_AUTH_NULL,
1096 		RTE_CRYPTO_AUTH_AES_XCBC_MAC
1097 	};
1098 
1099 	rte_cryptodev_info_get(dev_id, &dev_info);
1100 	feat_flags = dev_info.feature_flags;
1101 
1102 	if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1103 			((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1104 			!(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1105 		RTE_LOG(INFO, USER1, "Feature flag requirements for Auth Only "
1106 				"testsuite not met\n");
1107 		return TEST_SKIPPED;
1108 	}
1109 
1110 	if (check_auth_capabilities_supported(auths, RTE_DIM(auths)) != 0) {
1111 		RTE_LOG(INFO, USER1, "Capability requirements for Auth Only "
1112 				"testsuite not met\n");
1113 		return TEST_SKIPPED;
1114 	}
1115 
1116 	return 0;
1117 }
1118 
1119 struct unit_test_suite *
1120 build_blockcipher_test_suite(enum blockcipher_test_type test_type)
1121 {
1122 	int i, n_test_cases = 0;
1123 	struct unit_test_suite *ts;
1124 	const char *ts_name = NULL;
1125 	const struct blockcipher_test_case *blk_tcs;
1126 	struct unit_test_case *tc;
1127 	int (*ts_setup)(void) = NULL;
1128 
1129 	switch (test_type) {
1130 	case BLKCIPHER_AES_CHAIN_TYPE:
1131 		n_test_cases = RTE_DIM(aes_chain_test_cases);
1132 		blk_tcs = aes_chain_test_cases;
1133 		ts_name = "AES Chain";
1134 		ts_setup = aes_chain_setup;
1135 		break;
1136 	case BLKCIPHER_AES_CIPHERONLY_TYPE:
1137 		n_test_cases = RTE_DIM(aes_cipheronly_test_cases);
1138 		blk_tcs = aes_cipheronly_test_cases;
1139 		ts_name = "AES Cipher Only";
1140 		ts_setup = aes_cipheronly_setup;
1141 		break;
1142 	case BLKCIPHER_AES_DOCSIS_TYPE:
1143 		n_test_cases = RTE_DIM(aes_docsis_test_cases);
1144 		blk_tcs = aes_docsis_test_cases;
1145 		ts_name = "AES Docsis";
1146 		ts_setup = aes_docsis_setup;
1147 		break;
1148 	case BLKCIPHER_3DES_CHAIN_TYPE:
1149 		n_test_cases = RTE_DIM(triple_des_chain_test_cases);
1150 		blk_tcs = triple_des_chain_test_cases;
1151 		ts_name = "3DES Chain";
1152 		ts_setup = triple_des_chain_setup;
1153 		break;
1154 	case BLKCIPHER_3DES_CIPHERONLY_TYPE:
1155 		n_test_cases = RTE_DIM(triple_des_cipheronly_test_cases);
1156 		blk_tcs = triple_des_cipheronly_test_cases;
1157 		ts_name = "3DES Cipher Only";
1158 		ts_setup = triple_des_cipheronly_setup;
1159 		break;
1160 	case BLKCIPHER_DES_CIPHERONLY_TYPE:
1161 		n_test_cases = RTE_DIM(des_cipheronly_test_cases);
1162 		blk_tcs = des_cipheronly_test_cases;
1163 		ts_name = "DES Cipher Only";
1164 		ts_setup = des_cipheronly_setup;
1165 		break;
1166 	case BLKCIPHER_DES_DOCSIS_TYPE:
1167 		n_test_cases = RTE_DIM(des_docsis_test_cases);
1168 		blk_tcs = des_docsis_test_cases;
1169 		ts_name = "DES Docsis";
1170 		ts_setup = des_docsis_setup;
1171 		break;
1172 	case BLKCIPHER_AUTHONLY_TYPE:
1173 		n_test_cases = RTE_DIM(hash_test_cases);
1174 		blk_tcs = hash_test_cases;
1175 		ts_name = "Auth Only";
1176 		ts_setup = authonly_setup;
1177 		break;
1178 	default:
1179 		break;
1180 	}
1181 
1182 	ts = calloc(1, sizeof(struct unit_test_suite) +
1183 			(sizeof(struct unit_test_case) * (n_test_cases + 1)));
1184 	ts->suite_name = ts_name;
1185 	ts->setup = ts_setup;
1186 
1187 	for (i = 0; i < n_test_cases; i++) {
1188 		tc = &ts->unit_test_cases[i];
1189 		tc->name = blk_tcs[i].test_descr;
1190 		tc->enabled = 1;
1191 		tc->setup = ut_setup;
1192 		tc->teardown = ut_teardown;
1193 		tc->testcase = NULL;
1194 		tc->testcase_with_data = blockcipher_test_case_run;
1195 		tc->data = &blk_tcs[i];
1196 	}
1197 	tc = &ts->unit_test_cases[i];
1198 	tc->name = NULL;
1199 	tc->enabled = 0;
1200 	tc->setup = NULL;
1201 	tc->teardown = NULL;
1202 	tc->testcase = NULL;
1203 	tc->testcase_with_data = NULL;
1204 	tc->data = NULL;
1205 
1206 	return ts;
1207 }
1208 
1209 void
1210 free_blockcipher_test_suite(struct unit_test_suite *ts)
1211 {
1212 	free(ts);
1213 }
1214