1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2017 Intel Corporation
5 #include <rte_common.h>
6 #include <rte_hexdump.h>
8 #include <rte_malloc.h>
9 #include <rte_memcpy.h>
10 #include <rte_pause.h>
12 #include <rte_crypto.h>
13 #include <rte_cryptodev.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"
23 verify_algo_support(const struct blockcipher_test_case *t,
24 const uint8_t dev_id, const uint32_t digest_len)
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;
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)
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,
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)
54 if (cap_idx.algo.auth != RTE_CRYPTO_AUTH_NULL)
55 ret = rte_cryptodev_sym_capability_check_auth(capability,
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,
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;
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;
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];
100 uint32_t nb_iterates = 0;
102 rte_cryptodev_info_get(dev_id, &dev_info);
103 uint64_t feat_flags = dev_info.feature_flags;
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 "
109 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
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 "
118 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
123 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SG) {
124 uint64_t oop_flag = RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT;
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. "
131 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
136 if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
137 printf("Device doesn't support in-place "
138 "scatter-gather mbufs. "
140 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
148 if (!!(feat_flags & RTE_CRYPTODEV_FF_CIPHER_WRAPPED_KEY) ^
149 tdata->wrapped_key) {
150 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
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. "
159 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
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."
171 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
175 if (global_api_test_type == CRYPTODEV_RAW_API_TEST) {
176 printf("Raw Data Path APIs do not support OOP, "
178 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
179 status = TEST_SKIPPED;
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);
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."
196 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
201 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
202 buf_len += digest_len;
204 pad_len = RTE_ALIGN(buf_len, 16) - buf_len;
205 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
208 /* for contiguous mbuf, nb_segs is 1 */
209 ibuf = create_segmented_mbuf(mbuf_pool,
210 tdata->ciphertext.len, nb_segs, src_pattern);
212 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
213 "line %u FAILED: %s",
214 __LINE__, "Cannot create source mbuf");
215 status = TEST_FAILED;
219 /* only encryption requires plaintext.data input,
220 * decryption/(digest gen)/(digest verify) use ciphertext.data
223 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
224 pktmbuf_write(ibuf, 0, tdata->plaintext.len,
225 tdata->plaintext.data);
227 pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
228 tdata->ciphertext.data);
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)
234 tdata->ciphertext.data + tdata->ciphertext.len,
237 rte_memcpy(buf_p, tdata->digest.data, digest_len);
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);
243 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
244 "FAILED: %s", __LINE__,
245 "No room to append mbuf");
246 status = TEST_FAILED;
249 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
250 const uint8_t *temp_p = tdata->ciphertext.data +
251 tdata->ciphertext.len +
253 rte_memcpy(buf_p, temp_p, pad_len);
255 memset(buf_p, 0xa5, pad_len);
258 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
259 obuf = rte_pktmbuf_alloc(mbuf_pool);
261 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
262 "FAILED: %s", __LINE__,
263 "Allocation of rte_mbuf failed");
264 status = TEST_FAILED;
267 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
269 buf_p = rte_pktmbuf_append(obuf, buf_len + pad_len);
271 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
272 "FAILED: %s", __LINE__,
273 "No room to append mbuf");
274 status = TEST_FAILED;
277 memset(buf_p, 0, buf_len);
280 /* Generate Crypto op data structure */
281 op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
283 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
284 "line %u FAILED: %s",
285 __LINE__, "Failed to allocate symmetric crypto "
287 status = TEST_FAILED;
295 struct rte_mbuf *tmp_buf = ibuf;
300 rte_pktmbuf_reset(ibuf);
301 rte_pktmbuf_reset(obuf);
303 rte_pktmbuf_append(ibuf, tdata->ciphertext.len);
305 /* only encryption requires plaintext.data input,
306 * decryption/(digest gen)/(digest verify) use ciphertext.data
309 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
310 pktmbuf_write(ibuf, 0, tdata->plaintext.len,
311 tdata->plaintext.data);
313 pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
314 tdata->ciphertext.data);
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);
320 memset(buf_p, 0, digest_len);
322 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
324 buf_p = rte_pktmbuf_append(obuf, buf_len);
326 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
327 "FAILED: %s", __LINE__,
328 "No room to append mbuf");
329 status = TEST_FAILED;
332 memset(buf_p, 0, buf_len);
335 sym_op->m_src = ibuf;
337 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
338 sym_op->m_dst = obuf;
341 sym_op->m_dst = NULL;
345 /* sessionless op requires allocate xform using
346 * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
349 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
350 uint32_t n_xforms = 0;
352 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
354 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
357 if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
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;
366 cipher_xform = rte_zmalloc(NULL,
367 sizeof(struct rte_crypto_sym_xform), 0);
369 auth_xform = rte_zmalloc(NULL,
370 sizeof(struct rte_crypto_sym_xform), 0);
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;
381 /* preparing xform, for sessioned op, init_xform is initialized
382 * here and later as param in rte_cryptodev_sym_session_create() call
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;
390 cipher_xform->next = auth_xform;
391 auth_xform->next = NULL;
392 init_xform = cipher_xform;
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;
400 auth_xform->next = cipher_xform;
401 cipher_xform->next = NULL;
402 init_xform = auth_xform;
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;
410 auth_xform->next = cipher_xform;
411 cipher_xform->next = NULL;
412 init_xform = auth_xform;
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;
420 cipher_xform->next = auth_xform;
421 auth_xform->next = NULL;
422 init_xform = cipher_xform;
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;
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;
436 init_xform = auth_xform;
437 auth_xform->next = NULL;
439 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
440 "line %u FAILED: %s",
441 __LINE__, "Unrecognized operation");
442 status = TEST_FAILED;
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;
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;
461 if (tdata->crypto_algo == RTE_CRYPTO_CIPHER_NULL)
462 cipher_xform->cipher.iv.length = 0;
464 cipher_xform->cipher.iv.length = tdata->iv.len;
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;
473 rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET),
478 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
479 uint32_t digest_offset = tdata->ciphertext.len;
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;
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,
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,
503 sym_op->auth.data.offset = tdata->auth_offset;
504 sym_op->auth.data.length = tdata->ciphertext.len -
509 * Create session for sessioned op. For mbuf iteration test,
510 * skip the session creation for the second iteration.
512 if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) &&
514 sess = rte_cryptodev_sym_session_create(sess_mpool);
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;
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;
531 /* attach symmetric crypto session to crypto operations */
532 rte_crypto_op_attach_sym_session(op, sess);
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);
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)
551 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
554 process_sym_raw_dp_op(dev_id, 0, op, is_cipher, is_auth, 0,
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;
567 while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
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;
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);
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);
593 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
594 "FAILED: Operation failed "
595 "(0x%X)", __LINE__, op->status);
596 status = TEST_FAILED;
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;
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;
613 compare_ref = tdata->plaintext.data +
614 tdata->cipher_offset;
615 compare_len = tdata->plaintext.len -
616 tdata->cipher_offset;
619 if (memcmp(rte_pktmbuf_read(iobuf, tdata->cipher_offset,
620 compare_len, buffer), compare_ref,
622 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
623 "FAILED: %s", __LINE__,
624 "Crypto data not as expected");
625 status = TEST_FAILED;
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.
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);
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;
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.
653 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
654 struct rte_mbuf *mbuf;
656 uint32_t head_unchanged_len, changed_len = 0;
658 uint32_t hdroom_used = 0, tlroom_used = 0;
661 mbuf = sym_op->m_src;
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
668 hdroom_used = dev_info.min_mbuf_headroom_req;
669 tlroom_used = dev_info.min_mbuf_tailroom_req;
672 hdroom = rte_pktmbuf_headroom(mbuf);
674 head_unchanged_len = mbuf->buf_len;
676 for (i = 0; i < mbuf->buf_len; i++) {
678 /* Skip headroom used by PMD */
679 if (i == hdroom - hdroom_used)
682 /* Skip tailroom used by PMD */
683 if (i == (hdroom + mbuf->data_len))
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;
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;
704 head_unchanged_len = hdroom +
705 sym_op->cipher.data.offset;
706 changed_len = sym_op->cipher.data.length;
709 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
710 changed_len = sym_op->cipher.data.length +
711 digest_len + pad_len;
713 for (i = 0; i < mbuf->buf_len; i++) {
714 if (i == head_unchanged_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;
732 /* In-place operation */
733 struct rte_mbuf *mbuf;
735 uint32_t head_unchanged_len = 0, changed_len = 0;
737 uint32_t hdroom_used = 0, tlroom_used = 0;
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
746 hdroom_used = dev_info.min_mbuf_headroom_req;
747 tlroom_used = dev_info.min_mbuf_tailroom_req;
749 mbuf = sym_op->m_src;
752 hdroom = rte_pktmbuf_headroom(mbuf);
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;
760 head_unchanged_len = hdroom +
761 sym_op->auth.data.offset +
762 sym_op->auth.data.length;
766 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
767 changed_len += digest_len;
769 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
770 changed_len = sym_op->cipher.data.length;
772 for (i = 0; i < mbuf->buf_len; i++) {
774 /* Skip headroom used by PMD */
775 if (i == hdroom - hdroom_used)
778 if (i == head_unchanged_len)
781 /* Skip tailroom used by PMD */
782 if (i == (hdroom + mbuf->data_len))
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;
797 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
800 if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
802 rte_cryptodev_sym_session_clear(dev_id, sess);
803 rte_cryptodev_sym_session_free(sess);
806 rte_free(cipher_xform);
808 rte_free(auth_xform);
812 rte_crypto_op_free(op);
815 rte_pktmbuf_free(obuf);
818 rte_pktmbuf_free(ibuf);
824 blockcipher_test_case_run(const void *data)
826 const struct blockcipher_test_case *tc_data = data;
828 char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];
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],
841 aes_chain_setup(void)
843 uint8_t dev_id = p_testsuite_params->valid_devs[0];
844 struct rte_cryptodev_info dev_info;
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
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
861 rte_cryptodev_info_get(dev_id, &dev_info);
862 feat_flags = dev_info.feature_flags;
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");
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");
884 aes_cipheronly_setup(void)
886 uint8_t dev_id = p_testsuite_params->valid_devs[0];
887 struct rte_cryptodev_info dev_info;
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
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
902 rte_cryptodev_info_get(dev_id, &dev_info);
903 feat_flags = dev_info.feature_flags;
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");
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");
925 aes_docsis_setup(void)
927 uint8_t dev_id = p_testsuite_params->valid_devs[0];
928 struct rte_cryptodev_info dev_info;
930 const enum rte_crypto_cipher_algorithm ciphers[] = {
931 RTE_CRYPTO_CIPHER_AES_DOCSISBPI
934 rte_cryptodev_info_get(dev_id, &dev_info);
935 feat_flags = dev_info.feature_flags;
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");
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");
955 triple_des_chain_setup(void)
957 uint8_t dev_id = p_testsuite_params->valid_devs[0];
958 struct rte_cryptodev_info dev_info;
960 const enum rte_crypto_cipher_algorithm ciphers[] = {
961 RTE_CRYPTO_CIPHER_3DES_CTR,
962 RTE_CRYPTO_CIPHER_3DES_CBC
964 const enum rte_crypto_auth_algorithm auths[] = {
965 RTE_CRYPTO_AUTH_SHA1_HMAC,
969 rte_cryptodev_info_get(dev_id, &dev_info);
970 feat_flags = dev_info.feature_flags;
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");
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");
992 triple_des_cipheronly_setup(void)
994 uint8_t dev_id = p_testsuite_params->valid_devs[0];
995 struct rte_cryptodev_info dev_info;
997 const enum rte_crypto_cipher_algorithm ciphers[] = {
998 RTE_CRYPTO_CIPHER_3DES_CTR,
999 RTE_CRYPTO_CIPHER_3DES_CBC
1002 rte_cryptodev_info_get(dev_id, &dev_info);
1003 feat_flags = dev_info.feature_flags;
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;
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;
1023 des_cipheronly_setup(void)
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
1032 rte_cryptodev_info_get(dev_id, &dev_info);
1033 feat_flags = dev_info.feature_flags;
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;
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;
1053 des_docsis_setup(void)
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
1062 rte_cryptodev_info_get(dev_id, &dev_info);
1063 feat_flags = dev_info.feature_flags;
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;
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;
1083 authonly_setup(void)
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
1106 rte_cryptodev_info_get(dev_id, &dev_info);
1107 feat_flags = dev_info.feature_flags;
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;
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;
1126 struct unit_test_suite *
1127 build_blockcipher_test_suite(enum blockcipher_test_type test_type)
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
1194 for (i = 0; i < n_test_cases; i++) {
1195 tc = &ts->unit_test_cases[i];
1196 tc->name = blk_tcs[i].test_descr;
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];
1204 tc = &ts->unit_test_cases[i];
1208 tc->teardown = NULL;
1209 tc->testcase = NULL;
1210 tc->testcase_with_data = NULL;
1217 free_blockcipher_test_suite(struct unit_test_suite *ts)