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