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