xref: /dpdk/app/test/test_cryptodev_blockcipher.c (revision 1cde1b9a9b4dbf31cb5e5ccdfc5da3cb079f43a2)
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 test_blockcipher_one_case(const struct blockcipher_test_case *t,
25 	struct rte_mempool *mbuf_pool,
26 	struct rte_mempool *op_mpool,
27 	struct rte_mempool *sess_mpool,
28 	struct rte_mempool *sess_priv_mpool,
29 	uint8_t dev_id,
30 	int driver_id,
31 	char *test_msg)
32 {
33 	struct rte_mbuf *ibuf = NULL;
34 	struct rte_mbuf *obuf = NULL;
35 	struct rte_mbuf *iobuf;
36 	struct rte_crypto_sym_xform *cipher_xform = NULL;
37 	struct rte_crypto_sym_xform *auth_xform = NULL;
38 	struct rte_crypto_sym_xform *init_xform = NULL;
39 	struct rte_crypto_sym_op *sym_op = NULL;
40 	struct rte_crypto_op *op = NULL;
41 	struct rte_cryptodev_info dev_info;
42 	struct rte_cryptodev_sym_session *sess = NULL;
43 
44 	int status = TEST_SUCCESS;
45 	const struct blockcipher_test_data *tdata = t->test_data;
46 	uint8_t cipher_key[tdata->cipher_key.len];
47 	uint8_t auth_key[tdata->auth_key.len];
48 	uint32_t buf_len = tdata->ciphertext.len;
49 	uint32_t digest_len = 0;
50 	char *buf_p = NULL;
51 	uint8_t src_pattern = 0xa5;
52 	uint8_t dst_pattern = 0xb6;
53 	uint8_t tmp_src_buf[MBUF_SIZE];
54 	uint8_t tmp_dst_buf[MBUF_SIZE];
55 
56 	int openssl_pmd = rte_cryptodev_driver_id_get(
57 			RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
58 	int ccp_pmd = rte_cryptodev_driver_id_get(
59 			RTE_STR(CRYPTODEV_NAME_CCP_PMD));
60 	int scheduler_pmd = rte_cryptodev_driver_id_get(
61 			RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD));
62 	int armv8_pmd = rte_cryptodev_driver_id_get(
63 			RTE_STR(CRYPTODEV_NAME_ARMV8_PMD));
64 	int aesni_mb_pmd = rte_cryptodev_driver_id_get(
65 			RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD));
66 	int qat_pmd = rte_cryptodev_driver_id_get(
67 			RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD));
68 	int dpaa2_sec_pmd = rte_cryptodev_driver_id_get(
69 			RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD));
70 	int dpaa_sec_pmd = rte_cryptodev_driver_id_get(
71 			RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD));
72 	int caam_jr_pmd = rte_cryptodev_driver_id_get(
73 			RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD));
74 	int mrvl_pmd = rte_cryptodev_driver_id_get(
75 			RTE_STR(CRYPTODEV_NAME_MVSAM_PMD));
76 	int virtio_pmd = rte_cryptodev_driver_id_get(
77 			RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD));
78 	int octeontx_pmd = rte_cryptodev_driver_id_get(
79 			RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD));
80 	int null_pmd = rte_cryptodev_driver_id_get(
81 				RTE_STR(CRYPTODEV_NAME_NULL_PMD));
82 	int nitrox_pmd = rte_cryptodev_driver_id_get(
83 			RTE_STR(CRYPTODEV_NAME_NITROX_PMD));
84 
85 	int nb_segs = 1;
86 	uint32_t nb_iterates = 0;
87 
88 	rte_cryptodev_info_get(dev_id, &dev_info);
89 
90 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
91 		uint64_t feat_flags = dev_info.feature_flags;
92 		uint64_t oop_flag = RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT;
93 
94 		if (t->feature_mask && BLOCKCIPHER_TEST_FEATURE_OOP) {
95 			if (!(feat_flags & oop_flag)) {
96 				printf("Device doesn't support out-of-place "
97 					"scatter-gather in input mbuf. "
98 					"Test Skipped.\n");
99 				return 0;
100 			}
101 		} else {
102 			if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
103 				printf("Device doesn't support in-place "
104 					"scatter-gather mbufs. "
105 					"Test Skipped.\n");
106 				return 0;
107 			}
108 		}
109 
110 		nb_segs = 3;
111 	}
112 
113 	if (tdata->cipher_key.len)
114 		memcpy(cipher_key, tdata->cipher_key.data,
115 			tdata->cipher_key.len);
116 	if (tdata->auth_key.len)
117 		memcpy(auth_key, tdata->auth_key.data,
118 			tdata->auth_key.len);
119 
120 	if (driver_id == dpaa2_sec_pmd ||
121 			driver_id == dpaa_sec_pmd ||
122 			driver_id == caam_jr_pmd ||
123 			driver_id == qat_pmd ||
124 			driver_id == openssl_pmd ||
125 			driver_id == armv8_pmd ||
126 			driver_id == mrvl_pmd ||
127 			driver_id == ccp_pmd ||
128 			driver_id == virtio_pmd ||
129 			driver_id == octeontx_pmd ||
130 			driver_id == null_pmd ||
131 			driver_id == nitrox_pmd) { /* Fall through */
132 		digest_len = tdata->digest.len;
133 	} else if (driver_id == aesni_mb_pmd ||
134 			driver_id == scheduler_pmd) {
135 		digest_len = tdata->digest.truncated_len;
136 	} else {
137 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
138 			"line %u FAILED: %s",
139 			__LINE__, "Unsupported PMD type");
140 		status = TEST_FAILED;
141 		goto error_exit;
142 	}
143 
144 	/* preparing data */
145 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
146 		buf_len += digest_len;
147 
148 	/* for contiguous mbuf, nb_segs is 1 */
149 	ibuf = create_segmented_mbuf(mbuf_pool,
150 			tdata->ciphertext.len, nb_segs, src_pattern);
151 	if (ibuf == NULL) {
152 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
153 			"line %u FAILED: %s",
154 			__LINE__, "Cannot create source mbuf");
155 		status = TEST_FAILED;
156 		goto error_exit;
157 	}
158 
159 	/* only encryption requires plaintext.data input,
160 	 * decryption/(digest gen)/(digest verify) use ciphertext.data
161 	 * to be computed
162 	 */
163 	if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
164 		pktmbuf_write(ibuf, 0, tdata->plaintext.len,
165 				tdata->plaintext.data);
166 	else
167 		pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
168 				tdata->ciphertext.data);
169 
170 	buf_p = rte_pktmbuf_append(ibuf, digest_len);
171 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
172 		rte_memcpy(buf_p, tdata->digest.data, digest_len);
173 	else
174 		memset(buf_p, 0, digest_len);
175 
176 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
177 		obuf = rte_pktmbuf_alloc(mbuf_pool);
178 		if (!obuf) {
179 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
180 				"FAILED: %s", __LINE__,
181 				"Allocation of rte_mbuf failed");
182 			status = TEST_FAILED;
183 			goto error_exit;
184 		}
185 		memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
186 
187 		buf_p = rte_pktmbuf_append(obuf, buf_len);
188 		if (!buf_p) {
189 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
190 				"FAILED: %s", __LINE__,
191 				"No room to append mbuf");
192 			status = TEST_FAILED;
193 			goto error_exit;
194 		}
195 		memset(buf_p, 0, buf_len);
196 	}
197 
198 	/* Generate Crypto op data structure */
199 	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
200 	if (!op) {
201 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
202 			"line %u FAILED: %s",
203 			__LINE__, "Failed to allocate symmetric crypto "
204 			"operation struct");
205 		status = TEST_FAILED;
206 		goto error_exit;
207 	}
208 
209 	sym_op = op->sym;
210 
211 iterate:
212 	if (nb_iterates) {
213 		struct rte_mbuf *tmp_buf = ibuf;
214 
215 		ibuf = obuf;
216 		obuf = tmp_buf;
217 
218 		rte_pktmbuf_reset(ibuf);
219 		rte_pktmbuf_reset(obuf);
220 
221 		rte_pktmbuf_append(ibuf, tdata->ciphertext.len);
222 
223 		/* only encryption requires plaintext.data input,
224 		 * decryption/(digest gen)/(digest verify) use ciphertext.data
225 		 * to be computed
226 		 */
227 		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
228 			pktmbuf_write(ibuf, 0, tdata->plaintext.len,
229 					tdata->plaintext.data);
230 		else
231 			pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
232 					tdata->ciphertext.data);
233 
234 		buf_p = rte_pktmbuf_append(ibuf, digest_len);
235 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
236 			rte_memcpy(buf_p, tdata->digest.data, digest_len);
237 		else
238 			memset(buf_p, 0, digest_len);
239 
240 		memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
241 
242 		buf_p = rte_pktmbuf_append(obuf, buf_len);
243 		if (!buf_p) {
244 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
245 				"FAILED: %s", __LINE__,
246 				"No room to append mbuf");
247 			status = TEST_FAILED;
248 			goto error_exit;
249 		}
250 		memset(buf_p, 0, buf_len);
251 	}
252 
253 	sym_op->m_src = ibuf;
254 
255 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
256 		sym_op->m_dst = obuf;
257 		iobuf = obuf;
258 	} else {
259 		sym_op->m_dst = NULL;
260 		iobuf = ibuf;
261 	}
262 
263 	/* sessionless op requires allocate xform using
264 	 * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
265 	 * is used
266 	 */
267 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
268 		uint32_t n_xforms = 0;
269 
270 		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
271 			n_xforms++;
272 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
273 			n_xforms++;
274 
275 		if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
276 			== NULL) {
277 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
278 				"FAILED: %s", __LINE__, "Failed to "
279 				"allocate space for crypto transforms");
280 			status = TEST_FAILED;
281 			goto error_exit;
282 		}
283 	} else {
284 		cipher_xform = rte_zmalloc(NULL,
285 			sizeof(struct rte_crypto_sym_xform), 0);
286 
287 		auth_xform = rte_zmalloc(NULL,
288 			sizeof(struct rte_crypto_sym_xform), 0);
289 
290 		if (!cipher_xform || !auth_xform) {
291 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
292 				"FAILED: %s", __LINE__, "Failed to "
293 				"allocate memory for crypto transforms");
294 			status = TEST_FAILED;
295 			goto error_exit;
296 		}
297 	}
298 
299 	/* preparing xform, for sessioned op, init_xform is initialized
300 	 * here and later as param in rte_cryptodev_sym_session_create() call
301 	 */
302 	if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) {
303 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
304 			cipher_xform = op->sym->xform;
305 			auth_xform = cipher_xform->next;
306 			auth_xform->next = NULL;
307 		} else {
308 			cipher_xform->next = auth_xform;
309 			auth_xform->next = NULL;
310 			init_xform = cipher_xform;
311 		}
312 	} else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) {
313 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
314 			auth_xform = op->sym->xform;
315 			cipher_xform = auth_xform->next;
316 			cipher_xform->next = NULL;
317 		} else {
318 			auth_xform->next = cipher_xform;
319 			cipher_xform->next = NULL;
320 			init_xform = auth_xform;
321 		}
322 	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) ||
323 			(t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) {
324 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
325 			cipher_xform = op->sym->xform;
326 		else
327 			init_xform = cipher_xform;
328 		cipher_xform->next = NULL;
329 	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) ||
330 			(t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) {
331 		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
332 			auth_xform = op->sym->xform;
333 		else
334 			init_xform = auth_xform;
335 		auth_xform->next = NULL;
336 	} else {
337 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
338 			"line %u FAILED: %s",
339 			__LINE__, "Unrecognized operation");
340 		status = TEST_FAILED;
341 		goto error_exit;
342 	}
343 
344 	/*configure xforms & sym_op cipher and auth data*/
345 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
346 		cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
347 		cipher_xform->cipher.algo = tdata->crypto_algo;
348 		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
349 			cipher_xform->cipher.op =
350 				RTE_CRYPTO_CIPHER_OP_ENCRYPT;
351 		else
352 			cipher_xform->cipher.op =
353 				RTE_CRYPTO_CIPHER_OP_DECRYPT;
354 		cipher_xform->cipher.key.data = cipher_key;
355 		cipher_xform->cipher.key.length = tdata->cipher_key.len;
356 		cipher_xform->cipher.iv.offset = IV_OFFSET;
357 		cipher_xform->cipher.iv.length = tdata->iv.len;
358 
359 		sym_op->cipher.data.offset = tdata->cipher_offset;
360 		sym_op->cipher.data.length = tdata->ciphertext.len -
361 				tdata->cipher_offset;
362 		rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET),
363 				tdata->iv.data,
364 				tdata->iv.len);
365 	}
366 
367 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
368 		uint32_t digest_offset = tdata->ciphertext.len;
369 
370 		auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
371 		auth_xform->auth.algo = tdata->auth_algo;
372 		auth_xform->auth.key.length = tdata->auth_key.len;
373 		auth_xform->auth.key.data = auth_key;
374 		auth_xform->auth.digest_length = digest_len;
375 
376 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
377 			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
378 			sym_op->auth.digest.data = pktmbuf_mtod_offset
379 				(iobuf, digest_offset);
380 			sym_op->auth.digest.phys_addr =
381 				pktmbuf_iova_offset(iobuf,
382 					digest_offset);
383 		} else {
384 			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
385 			sym_op->auth.digest.data = pktmbuf_mtod_offset
386 				(sym_op->m_src, digest_offset);
387 			sym_op->auth.digest.phys_addr =
388 				pktmbuf_iova_offset(sym_op->m_src,
389 					digest_offset);
390 		}
391 
392 		sym_op->auth.data.offset = tdata->auth_offset;
393 		sym_op->auth.data.length = tdata->ciphertext.len -
394 				tdata->auth_offset;
395 	}
396 
397 	/**
398 	 * Create session for sessioned op. For mbuf iteration test,
399 	 * skip the session creation for the second iteration.
400 	 */
401 	if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) &&
402 			nb_iterates == 0) {
403 		sess = rte_cryptodev_sym_session_create(sess_mpool);
404 
405 		rte_cryptodev_sym_session_init(dev_id, sess, init_xform,
406 				sess_priv_mpool);
407 		if (!sess) {
408 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
409 				"FAILED: %s", __LINE__,
410 				"Session creation failed");
411 			status = TEST_FAILED;
412 			goto error_exit;
413 		}
414 
415 		/* attach symmetric crypto session to crypto operations */
416 		rte_crypto_op_attach_sym_session(op, sess);
417 	}
418 
419 	debug_hexdump(stdout, "m_src(before):",
420 			sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
421 	rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr,
422 						sym_op->m_src->buf_len);
423 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
424 		debug_hexdump(stdout, "m_dst(before):",
425 			sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
426 		rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr,
427 						sym_op->m_dst->buf_len);
428 	}
429 
430 	/* Process crypto operation */
431 	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
432 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
433 			"line %u FAILED: %s",
434 			__LINE__, "Error sending packet for encryption");
435 		status = TEST_FAILED;
436 		goto error_exit;
437 	}
438 
439 	op = NULL;
440 
441 	while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
442 		rte_pause();
443 
444 	if (!op) {
445 		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
446 			"line %u FAILED: %s",
447 			__LINE__, "Failed to process sym crypto op");
448 		status = TEST_FAILED;
449 		goto error_exit;
450 	}
451 
452 	debug_hexdump(stdout, "m_src(after):",
453 			sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
454 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
455 		debug_hexdump(stdout, "m_dst(after):",
456 			sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
457 
458 	/* Verify results */
459 	if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
460 		if ((t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) &&
461 			(op->status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED))
462 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
463 				"FAILED: Digest verification failed "
464 				"(0x%X)", __LINE__, op->status);
465 		else
466 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
467 				"FAILED: Operation failed "
468 				"(0x%X)", __LINE__, op->status);
469 		status = TEST_FAILED;
470 		goto error_exit;
471 	}
472 
473 	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
474 		uint8_t buffer[2048];
475 		const uint8_t *compare_ref;
476 		uint32_t compare_len;
477 
478 		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
479 			compare_ref = tdata->ciphertext.data +
480 					tdata->cipher_offset;
481 			compare_len = tdata->ciphertext.len -
482 					tdata->cipher_offset;
483 		} else {
484 			compare_ref = tdata->plaintext.data +
485 					tdata->cipher_offset;
486 			compare_len = tdata->plaintext.len -
487 					tdata->cipher_offset;
488 		}
489 
490 		if (memcmp(rte_pktmbuf_read(iobuf, tdata->cipher_offset,
491 				compare_len, buffer), compare_ref,
492 				compare_len)) {
493 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
494 				"FAILED: %s", __LINE__,
495 				"Crypto data not as expected");
496 			status = TEST_FAILED;
497 			goto error_exit;
498 		}
499 	}
500 
501 	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
502 		uint8_t *auth_res = pktmbuf_mtod_offset(iobuf,
503 					tdata->ciphertext.len);
504 
505 		if (memcmp(auth_res, tdata->digest.data, digest_len)) {
506 			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
507 				"FAILED: %s", __LINE__, "Generated "
508 				"digest data not as expected");
509 			status = TEST_FAILED;
510 			goto error_exit;
511 		}
512 	}
513 
514 	/* The only parts that should have changed in the buffer are
515 	 * plaintext/ciphertext and digest.
516 	 * In OOP only the dest buffer should change.
517 	 */
518 	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
519 		struct rte_mbuf *mbuf;
520 		uint8_t value;
521 		uint32_t head_unchanged_len, changed_len = 0;
522 		uint32_t i;
523 		uint32_t hdroom_used = 0, tlroom_used = 0;
524 		uint32_t hdroom = 0;
525 
526 		mbuf = sym_op->m_src;
527 		/*
528 		 * Crypto PMDs specify the headroom & tailroom it would use
529 		 * when processing the crypto operation. PMD is free to modify
530 		 * this space, and so the verification check should skip that
531 		 * block.
532 		 */
533 		hdroom_used = dev_info.min_mbuf_headroom_req;
534 		tlroom_used = dev_info.min_mbuf_tailroom_req;
535 
536 		/* Get headroom */
537 		hdroom = rte_pktmbuf_headroom(mbuf);
538 
539 		head_unchanged_len = mbuf->buf_len;
540 
541 		for (i = 0; i < mbuf->buf_len; i++) {
542 
543 			/* Skip headroom used by PMD */
544 			if (i == hdroom - hdroom_used)
545 				i += hdroom_used;
546 
547 			/* Skip tailroom used by PMD */
548 			if (i == (hdroom + mbuf->data_len))
549 				i += tlroom_used;
550 
551 			value = *((uint8_t *)(mbuf->buf_addr)+i);
552 			if (value != tmp_src_buf[i]) {
553 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
554 	"line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)",
555 					__LINE__, value, tmp_src_buf[i]);
556 				status = TEST_FAILED;
557 				goto error_exit;
558 			}
559 		}
560 
561 		mbuf = sym_op->m_dst;
562 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
563 			head_unchanged_len = hdroom + sym_op->auth.data.offset;
564 			changed_len = sym_op->auth.data.length;
565 			if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
566 				changed_len += digest_len;
567 		} else {
568 			/* cipher-only */
569 			head_unchanged_len = hdroom +
570 					sym_op->cipher.data.offset;
571 			changed_len = sym_op->cipher.data.length;
572 		}
573 
574 		for (i = 0; i < mbuf->buf_len; i++) {
575 			if (i == head_unchanged_len)
576 				i += changed_len;
577 			value = *((uint8_t *)(mbuf->buf_addr)+i);
578 			if (value != tmp_dst_buf[i]) {
579 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
580 				"line %u FAILED: OOP dst outer mbuf data "
581 				"(0x%x) not as expected (0x%x)",
582 				__LINE__, value, tmp_dst_buf[i]);
583 				status = TEST_FAILED;
584 				goto error_exit;
585 			}
586 		}
587 
588 		if (!nb_iterates) {
589 			nb_iterates++;
590 			goto iterate;
591 		}
592 	} else {
593 		/* In-place operation */
594 		struct rte_mbuf *mbuf;
595 		uint8_t value;
596 		uint32_t head_unchanged_len = 0, changed_len = 0;
597 		uint32_t i;
598 		uint32_t hdroom_used = 0, tlroom_used = 0;
599 		uint32_t hdroom = 0;
600 
601 		/*
602 		 * Crypto PMDs specify the headroom & tailroom it would use
603 		 * when processing the crypto operation. PMD is free to modify
604 		 * this space, and so the verification check should skip that
605 		 * block.
606 		 */
607 		hdroom_used = dev_info.min_mbuf_headroom_req;
608 		tlroom_used = dev_info.min_mbuf_tailroom_req;
609 
610 		mbuf = sym_op->m_src;
611 
612 		/* Get headroom */
613 		hdroom = rte_pktmbuf_headroom(mbuf);
614 
615 		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
616 			head_unchanged_len = hdroom +
617 					sym_op->cipher.data.offset;
618 			changed_len = sym_op->cipher.data.length;
619 		} else {
620 			/* auth-only */
621 			head_unchanged_len = hdroom +
622 					sym_op->auth.data.offset +
623 					sym_op->auth.data.length;
624 			changed_len = 0;
625 		}
626 
627 		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
628 			changed_len += digest_len;
629 
630 		for (i = 0; i < mbuf->buf_len; i++) {
631 
632 			/* Skip headroom used by PMD */
633 			if (i == hdroom - hdroom_used)
634 				i += hdroom_used;
635 
636 			if (i == head_unchanged_len)
637 				i += changed_len;
638 
639 			/* Skip tailroom used by PMD */
640 			if (i == (hdroom + mbuf->data_len))
641 				i += tlroom_used;
642 
643 			value = *((uint8_t *)(mbuf->buf_addr)+i);
644 			if (value != tmp_src_buf[i]) {
645 				snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
646 				"line %u FAILED: outer mbuf data (0x%x) "
647 				"not as expected (0x%x)",
648 				__LINE__, value, tmp_src_buf[i]);
649 				status = TEST_FAILED;
650 				goto error_exit;
651 			}
652 		}
653 	}
654 
655 	snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
656 
657 error_exit:
658 	if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
659 		if (sess) {
660 			rte_cryptodev_sym_session_clear(dev_id, sess);
661 			rte_cryptodev_sym_session_free(sess);
662 		}
663 		if (cipher_xform)
664 			rte_free(cipher_xform);
665 		if (auth_xform)
666 			rte_free(auth_xform);
667 	}
668 
669 	if (op)
670 		rte_crypto_op_free(op);
671 
672 	if (obuf)
673 		rte_pktmbuf_free(obuf);
674 
675 	if (ibuf)
676 		rte_pktmbuf_free(ibuf);
677 
678 	return status;
679 }
680 
681 int
682 test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
683 	struct rte_mempool *op_mpool,
684 	struct rte_mempool *sess_mpool,
685 	struct rte_mempool *sess_priv_mpool,
686 	uint8_t dev_id,
687 	int driver_id,
688 	enum blockcipher_test_type test_type)
689 {
690 	int status, overall_status = TEST_SUCCESS;
691 	uint32_t i, test_index = 0;
692 	char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];
693 	uint32_t n_test_cases = 0;
694 	uint32_t target_pmd_mask = 0;
695 	const struct blockcipher_test_case *tcs = NULL;
696 
697 	int openssl_pmd = rte_cryptodev_driver_id_get(
698 			RTE_STR(CRYPTODEV_NAME_OPENSSL_PMD));
699 	int ccp_pmd = rte_cryptodev_driver_id_get(
700 			RTE_STR(CRYPTODEV_NAME_CCP_PMD));
701 	int dpaa2_sec_pmd = rte_cryptodev_driver_id_get(
702 			RTE_STR(CRYPTODEV_NAME_DPAA2_SEC_PMD));
703 	int dpaa_sec_pmd = rte_cryptodev_driver_id_get(
704 			RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD));
705 	int caam_jr_pmd = rte_cryptodev_driver_id_get(
706 			RTE_STR(CRYPTODEV_NAME_CAAM_JR_PMD));
707 	int scheduler_pmd = rte_cryptodev_driver_id_get(
708 			RTE_STR(CRYPTODEV_NAME_SCHEDULER_PMD));
709 	int armv8_pmd = rte_cryptodev_driver_id_get(
710 			RTE_STR(CRYPTODEV_NAME_ARMV8_PMD));
711 	int aesni_mb_pmd = rte_cryptodev_driver_id_get(
712 			RTE_STR(CRYPTODEV_NAME_AESNI_MB_PMD));
713 	int qat_pmd = rte_cryptodev_driver_id_get(
714 			RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD));
715 	int mrvl_pmd = rte_cryptodev_driver_id_get(
716 			RTE_STR(CRYPTODEV_NAME_MVSAM_PMD));
717 	int virtio_pmd = rte_cryptodev_driver_id_get(
718 			RTE_STR(CRYPTODEV_NAME_VIRTIO_PMD));
719 	int octeontx_pmd = rte_cryptodev_driver_id_get(
720 			RTE_STR(CRYPTODEV_NAME_OCTEONTX_SYM_PMD));
721 	int null_pmd = rte_cryptodev_driver_id_get(
722 				RTE_STR(CRYPTODEV_NAME_NULL_PMD));
723 	int nitrox_pmd = rte_cryptodev_driver_id_get(
724 			RTE_STR(CRYPTODEV_NAME_NITROX_PMD));
725 
726 	switch (test_type) {
727 	case BLKCIPHER_AES_CHAIN_TYPE:
728 		n_test_cases = sizeof(aes_chain_test_cases) /
729 		sizeof(aes_chain_test_cases[0]);
730 		tcs = aes_chain_test_cases;
731 		break;
732 	case BLKCIPHER_AES_CIPHERONLY_TYPE:
733 		n_test_cases = sizeof(aes_cipheronly_test_cases) /
734 		sizeof(aes_cipheronly_test_cases[0]);
735 		tcs = aes_cipheronly_test_cases;
736 		break;
737 	case BLKCIPHER_AES_DOCSIS_TYPE:
738 		n_test_cases = sizeof(aes_docsis_test_cases) /
739 		sizeof(aes_docsis_test_cases[0]);
740 		tcs = aes_docsis_test_cases;
741 		break;
742 	case BLKCIPHER_3DES_CHAIN_TYPE:
743 		n_test_cases = sizeof(triple_des_chain_test_cases) /
744 		sizeof(triple_des_chain_test_cases[0]);
745 		tcs = triple_des_chain_test_cases;
746 		break;
747 	case BLKCIPHER_3DES_CIPHERONLY_TYPE:
748 		n_test_cases = sizeof(triple_des_cipheronly_test_cases) /
749 		sizeof(triple_des_cipheronly_test_cases[0]);
750 		tcs = triple_des_cipheronly_test_cases;
751 		break;
752 	case BLKCIPHER_DES_CIPHERONLY_TYPE:
753 		n_test_cases = sizeof(des_cipheronly_test_cases) /
754 		sizeof(des_cipheronly_test_cases[0]);
755 		tcs = des_cipheronly_test_cases;
756 		break;
757 	case BLKCIPHER_DES_DOCSIS_TYPE:
758 		n_test_cases = sizeof(des_docsis_test_cases) /
759 		sizeof(des_docsis_test_cases[0]);
760 		tcs = des_docsis_test_cases;
761 		break;
762 	case BLKCIPHER_AUTHONLY_TYPE:
763 		n_test_cases = sizeof(hash_test_cases) /
764 		sizeof(hash_test_cases[0]);
765 		tcs = hash_test_cases;
766 		break;
767 	default:
768 		break;
769 	}
770 
771 	if (driver_id == aesni_mb_pmd)
772 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB;
773 	else if (driver_id == qat_pmd)
774 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT;
775 	else if (driver_id == openssl_pmd)
776 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL;
777 	else if (driver_id == armv8_pmd)
778 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_ARMV8;
779 	else if (driver_id == scheduler_pmd)
780 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER;
781 	else if (driver_id == dpaa2_sec_pmd)
782 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC;
783 	else if (driver_id == ccp_pmd)
784 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CCP;
785 	else if (driver_id == dpaa_sec_pmd)
786 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC;
787 	else if (driver_id == caam_jr_pmd)
788 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR;
789 	else if (driver_id == mrvl_pmd)
790 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MVSAM;
791 	else if (driver_id == virtio_pmd)
792 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO;
793 	else if (driver_id == octeontx_pmd)
794 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX;
795 	else if (driver_id == null_pmd)
796 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_NULL;
797 	else if (driver_id == nitrox_pmd)
798 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_NITROX;
799 	else
800 		TEST_ASSERT(0, "Unrecognized cryptodev type");
801 
802 	for (i = 0; i < n_test_cases; i++) {
803 		const struct blockcipher_test_case *tc = &tcs[i];
804 
805 		if (!(tc->pmd_mask & target_pmd_mask))
806 			continue;
807 
808 		status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool,
809 			sess_mpool, sess_priv_mpool, dev_id, driver_id,
810 			test_msg);
811 
812 		printf("  %u) TestCase %s %s\n", test_index ++,
813 			tc->test_descr, test_msg);
814 
815 		if (status != TEST_SUCCESS) {
816 			if (overall_status == TEST_SUCCESS)
817 				overall_status = status;
818 
819 			if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER)
820 				break;
821 		}
822 	}
823 
824 	return overall_status;
825 }
826