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>
14 #include <rte_cryptodev_pmd.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"
24 verify_algo_support(const struct blockcipher_test_case *t,
25 const uint8_t dev_id, const uint32_t digest_len)
28 const struct blockcipher_test_data *tdata = t->test_data;
29 struct rte_cryptodev_sym_capability_idx cap_idx;
30 const struct rte_cryptodev_symmetric_capability *capability;
32 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
33 cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
34 cap_idx.algo.cipher = tdata->crypto_algo;
35 capability = rte_cryptodev_sym_capability_get(dev_id, &cap_idx);
36 if (capability == NULL)
39 if (cap_idx.algo.cipher != RTE_CRYPTO_CIPHER_NULL)
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,
149 if (global_api_test_type == CRYPTODEV_RAW_API_TEST &&
150 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP)) {
151 printf("Device doesn't support raw data-path APIs. "
153 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
157 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
158 uint64_t oop_flags = RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
159 RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT |
160 RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
161 RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT;
162 if (!(feat_flags & oop_flags)) {
163 printf("Device doesn't support out-of-place operations."
165 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
169 if (global_api_test_type == CRYPTODEV_RAW_API_TEST) {
170 printf("Raw Data Path APIs do not support OOP, "
172 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
173 status = TEST_SKIPPED;
178 if (tdata->cipher_key.len)
179 memcpy(cipher_key, tdata->cipher_key.data,
180 tdata->cipher_key.len);
181 if (tdata->auth_key.len)
182 memcpy(auth_key, tdata->auth_key.data,
183 tdata->auth_key.len);
185 /* Check if PMD is capable of performing that test */
186 if (verify_algo_support(t, dev_id, digest_len) < 0) {
187 RTE_LOG(DEBUG, USER1,
188 "Device does not support this algorithm."
190 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "SKIPPED");
195 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
196 buf_len += digest_len;
198 pad_len = RTE_ALIGN(buf_len, 16) - buf_len;
199 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
202 /* for contiguous mbuf, nb_segs is 1 */
203 ibuf = create_segmented_mbuf(mbuf_pool,
204 tdata->ciphertext.len, nb_segs, src_pattern);
206 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
207 "line %u FAILED: %s",
208 __LINE__, "Cannot create source mbuf");
209 status = TEST_FAILED;
213 /* only encryption requires plaintext.data input,
214 * decryption/(digest gen)/(digest verify) use ciphertext.data
217 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
218 pktmbuf_write(ibuf, 0, tdata->plaintext.len,
219 tdata->plaintext.data);
221 pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
222 tdata->ciphertext.data);
224 buf_p = rte_pktmbuf_append(ibuf, digest_len);
225 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
226 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
228 tdata->ciphertext.data + tdata->ciphertext.len,
231 rte_memcpy(buf_p, tdata->digest.data, digest_len);
233 memset(buf_p, 0, digest_len);
234 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED) {
235 buf_p = rte_pktmbuf_append(ibuf, pad_len);
237 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
238 "FAILED: %s", __LINE__,
239 "No room to append mbuf");
240 status = TEST_FAILED;
243 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) {
244 const uint8_t *temp_p = tdata->ciphertext.data +
245 tdata->ciphertext.len +
247 rte_memcpy(buf_p, temp_p, pad_len);
249 memset(buf_p, 0xa5, pad_len);
252 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
253 obuf = rte_pktmbuf_alloc(mbuf_pool);
255 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
256 "FAILED: %s", __LINE__,
257 "Allocation of rte_mbuf failed");
258 status = TEST_FAILED;
261 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
263 buf_p = rte_pktmbuf_append(obuf, buf_len + pad_len);
265 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
266 "FAILED: %s", __LINE__,
267 "No room to append mbuf");
268 status = TEST_FAILED;
271 memset(buf_p, 0, buf_len);
274 /* Generate Crypto op data structure */
275 op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
277 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
278 "line %u FAILED: %s",
279 __LINE__, "Failed to allocate symmetric crypto "
281 status = TEST_FAILED;
289 struct rte_mbuf *tmp_buf = ibuf;
294 rte_pktmbuf_reset(ibuf);
295 rte_pktmbuf_reset(obuf);
297 rte_pktmbuf_append(ibuf, tdata->ciphertext.len);
299 /* only encryption requires plaintext.data input,
300 * decryption/(digest gen)/(digest verify) use ciphertext.data
303 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
304 pktmbuf_write(ibuf, 0, tdata->plaintext.len,
305 tdata->plaintext.data);
307 pktmbuf_write(ibuf, 0, tdata->ciphertext.len,
308 tdata->ciphertext.data);
310 buf_p = rte_pktmbuf_append(ibuf, digest_len);
311 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
312 rte_memcpy(buf_p, tdata->digest.data, digest_len);
314 memset(buf_p, 0, digest_len);
316 memset(obuf->buf_addr, dst_pattern, obuf->buf_len);
318 buf_p = rte_pktmbuf_append(obuf, buf_len);
320 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
321 "FAILED: %s", __LINE__,
322 "No room to append mbuf");
323 status = TEST_FAILED;
326 memset(buf_p, 0, buf_len);
329 sym_op->m_src = ibuf;
331 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
332 sym_op->m_dst = obuf;
335 sym_op->m_dst = NULL;
339 /* sessionless op requires allocate xform using
340 * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
343 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
344 uint32_t n_xforms = 0;
346 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
348 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
351 if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
353 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
354 "FAILED: %s", __LINE__, "Failed to "
355 "allocate space for crypto transforms");
356 status = TEST_FAILED;
360 cipher_xform = rte_zmalloc(NULL,
361 sizeof(struct rte_crypto_sym_xform), 0);
363 auth_xform = rte_zmalloc(NULL,
364 sizeof(struct rte_crypto_sym_xform), 0);
366 if (!cipher_xform || !auth_xform) {
367 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
368 "FAILED: %s", __LINE__, "Failed to "
369 "allocate memory for crypto transforms");
370 status = TEST_FAILED;
375 /* preparing xform, for sessioned op, init_xform is initialized
376 * here and later as param in rte_cryptodev_sym_session_create() call
378 if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) {
379 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
380 cipher_xform = op->sym->xform;
381 auth_xform = cipher_xform->next;
382 auth_xform->next = NULL;
384 cipher_xform->next = auth_xform;
385 auth_xform->next = NULL;
386 init_xform = cipher_xform;
388 } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) {
389 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
390 auth_xform = op->sym->xform;
391 cipher_xform = auth_xform->next;
392 cipher_xform->next = NULL;
394 auth_xform->next = cipher_xform;
395 cipher_xform->next = NULL;
396 init_xform = auth_xform;
398 } else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN_ENC) {
399 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
400 auth_xform = op->sym->xform;
401 cipher_xform = auth_xform->next;
402 cipher_xform->next = NULL;
404 auth_xform->next = cipher_xform;
405 cipher_xform->next = NULL;
406 init_xform = auth_xform;
408 } else if (t->op_mask == BLOCKCIPHER_TEST_OP_DEC_AUTH_VERIFY) {
409 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
410 cipher_xform = op->sym->xform;
411 auth_xform = cipher_xform->next;
412 auth_xform->next = NULL;
414 cipher_xform->next = auth_xform;
415 auth_xform->next = NULL;
416 init_xform = cipher_xform;
418 } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) ||
419 (t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) {
420 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
421 cipher_xform = op->sym->xform;
423 init_xform = cipher_xform;
424 cipher_xform->next = NULL;
425 } else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) ||
426 (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) {
427 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
428 auth_xform = op->sym->xform;
430 init_xform = auth_xform;
431 auth_xform->next = NULL;
433 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
434 "line %u FAILED: %s",
435 __LINE__, "Unrecognized operation");
436 status = TEST_FAILED;
440 /*configure xforms & sym_op cipher and auth data*/
441 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
442 cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
443 cipher_xform->cipher.algo = tdata->crypto_algo;
444 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
445 cipher_xform->cipher.op =
446 RTE_CRYPTO_CIPHER_OP_ENCRYPT;
448 cipher_xform->cipher.op =
449 RTE_CRYPTO_CIPHER_OP_DECRYPT;
450 cipher_xform->cipher.key.data = cipher_key;
451 cipher_xform->cipher.key.length = tdata->cipher_key.len;
452 cipher_xform->cipher.iv.offset = IV_OFFSET;
454 if (tdata->crypto_algo == RTE_CRYPTO_CIPHER_NULL)
455 cipher_xform->cipher.iv.length = 0;
457 cipher_xform->cipher.iv.length = tdata->iv.len;
459 sym_op->cipher.data.offset = tdata->cipher_offset;
460 sym_op->cipher.data.length = tdata->ciphertext.len -
461 tdata->cipher_offset;
462 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED) {
463 sym_op->cipher.data.length += tdata->digest.len;
464 sym_op->cipher.data.length += pad_len;
466 rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET),
471 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
472 uint32_t digest_offset = tdata->ciphertext.len;
474 auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
475 auth_xform->auth.algo = tdata->auth_algo;
476 auth_xform->auth.key.length = tdata->auth_key.len;
477 auth_xform->auth.key.data = auth_key;
478 auth_xform->auth.digest_length = digest_len;
480 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
481 auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
482 sym_op->auth.digest.data = pktmbuf_mtod_offset
483 (iobuf, digest_offset);
484 sym_op->auth.digest.phys_addr =
485 pktmbuf_iova_offset(iobuf,
488 auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
489 sym_op->auth.digest.data = pktmbuf_mtod_offset
490 (sym_op->m_src, digest_offset);
491 sym_op->auth.digest.phys_addr =
492 pktmbuf_iova_offset(sym_op->m_src,
496 sym_op->auth.data.offset = tdata->auth_offset;
497 sym_op->auth.data.length = tdata->ciphertext.len -
502 * Create session for sessioned op. For mbuf iteration test,
503 * skip the session creation for the second iteration.
505 if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) &&
507 sess = rte_cryptodev_sym_session_create(sess_mpool);
509 status = rte_cryptodev_sym_session_init(dev_id, sess,
510 init_xform, sess_priv_mpool);
511 if (status == -ENOTSUP) {
512 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "UNSUPPORTED");
513 status = TEST_SKIPPED;
516 if (!sess || status < 0) {
517 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
518 "FAILED: %s", __LINE__,
519 "Session creation failed");
520 status = TEST_FAILED;
524 /* attach symmetric crypto session to crypto operations */
525 rte_crypto_op_attach_sym_session(op, sess);
528 debug_hexdump(stdout, "m_src(before):",
529 sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
530 rte_memcpy(tmp_src_buf, sym_op->m_src->buf_addr,
531 sym_op->m_src->buf_len);
532 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
533 debug_hexdump(stdout, "m_dst(before):",
534 sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
535 rte_memcpy(tmp_dst_buf, sym_op->m_dst->buf_addr,
536 sym_op->m_dst->buf_len);
539 /* Process crypto operation */
540 if (global_api_test_type == CRYPTODEV_RAW_API_TEST) {
541 uint8_t is_cipher = 0, is_auth = 0;
542 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
544 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
547 process_sym_raw_dp_op(dev_id, 0, op, is_cipher, is_auth, 0,
550 if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
551 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
552 "line %u FAILED: %s",
553 __LINE__, "Error sending packet for encryption");
554 status = TEST_FAILED;
560 while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
564 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
565 "line %u FAILED: %s",
566 __LINE__, "Failed to process sym crypto op");
567 status = TEST_FAILED;
572 debug_hexdump(stdout, "m_src(after):",
573 sym_op->m_src->buf_addr, sym_op->m_src->buf_len);
574 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
575 debug_hexdump(stdout, "m_dst(after):",
576 sym_op->m_dst->buf_addr, sym_op->m_dst->buf_len);
579 if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
580 if ((t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY) &&
581 (op->status == RTE_CRYPTO_OP_STATUS_AUTH_FAILED))
582 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
583 "FAILED: Digest verification failed "
584 "(0x%X)", __LINE__, op->status);
586 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
587 "FAILED: Operation failed "
588 "(0x%X)", __LINE__, op->status);
589 status = TEST_FAILED;
593 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
594 uint8_t buffer[2048];
595 const uint8_t *compare_ref;
596 uint32_t compare_len;
598 if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
599 compare_ref = tdata->ciphertext.data +
600 tdata->cipher_offset;
601 compare_len = tdata->ciphertext.len -
602 tdata->cipher_offset;
603 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
604 compare_len += tdata->digest.len;
606 compare_ref = tdata->plaintext.data +
607 tdata->cipher_offset;
608 compare_len = tdata->plaintext.len -
609 tdata->cipher_offset;
612 if (memcmp(rte_pktmbuf_read(iobuf, tdata->cipher_offset,
613 compare_len, buffer), compare_ref,
615 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
616 "FAILED: %s", __LINE__,
617 "Crypto data not as expected");
618 status = TEST_FAILED;
623 /* Check digest data only in enc-then-auth_gen case.
624 * In auth_gen-then-enc case, cipher text contains both encrypted
625 * plain text and encrypted digest value. If cipher text is correct,
626 * it implies digest is also generated properly.
628 if (!(t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED))
629 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
630 uint8_t *auth_res = pktmbuf_mtod_offset(iobuf,
631 tdata->ciphertext.len);
633 if (memcmp(auth_res, tdata->digest.data, digest_len)) {
634 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
635 "FAILED: %s", __LINE__, "Generated "
636 "digest data not as expected");
637 status = TEST_FAILED;
642 /* The only parts that should have changed in the buffer are
643 * plaintext/ciphertext and digest.
644 * In OOP only the dest buffer should change.
646 if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
647 struct rte_mbuf *mbuf;
649 uint32_t head_unchanged_len, changed_len = 0;
651 uint32_t hdroom_used = 0, tlroom_used = 0;
654 mbuf = sym_op->m_src;
656 * Crypto PMDs specify the headroom & tailroom it would use
657 * when processing the crypto operation. PMD is free to modify
658 * this space, and so the verification check should skip that
661 hdroom_used = dev_info.min_mbuf_headroom_req;
662 tlroom_used = dev_info.min_mbuf_tailroom_req;
665 hdroom = rte_pktmbuf_headroom(mbuf);
667 head_unchanged_len = mbuf->buf_len;
669 for (i = 0; i < mbuf->buf_len; i++) {
671 /* Skip headroom used by PMD */
672 if (i == hdroom - hdroom_used)
675 /* Skip tailroom used by PMD */
676 if (i == (hdroom + mbuf->data_len))
679 value = *((uint8_t *)(mbuf->buf_addr)+i);
680 if (value != tmp_src_buf[i]) {
681 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
682 "line %u FAILED: OOP src outer mbuf data (0x%x) not as expected (0x%x)",
683 __LINE__, value, tmp_src_buf[i]);
684 status = TEST_FAILED;
689 mbuf = sym_op->m_dst;
690 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
691 head_unchanged_len = hdroom + sym_op->auth.data.offset;
692 changed_len = sym_op->auth.data.length;
693 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
694 changed_len += digest_len;
697 head_unchanged_len = hdroom +
698 sym_op->cipher.data.offset;
699 changed_len = sym_op->cipher.data.length;
702 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
703 changed_len = sym_op->cipher.data.length +
704 digest_len + pad_len;
706 for (i = 0; i < mbuf->buf_len; i++) {
707 if (i == head_unchanged_len)
709 value = *((uint8_t *)(mbuf->buf_addr)+i);
710 if (value != tmp_dst_buf[i]) {
711 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
712 "line %u FAILED: OOP dst outer mbuf data "
713 "(0x%x) not as expected (0x%x)",
714 __LINE__, value, tmp_dst_buf[i]);
715 status = TEST_FAILED;
725 /* In-place operation */
726 struct rte_mbuf *mbuf;
728 uint32_t head_unchanged_len = 0, changed_len = 0;
730 uint32_t hdroom_used = 0, tlroom_used = 0;
734 * Crypto PMDs specify the headroom & tailroom it would use
735 * when processing the crypto operation. PMD is free to modify
736 * this space, and so the verification check should skip that
739 hdroom_used = dev_info.min_mbuf_headroom_req;
740 tlroom_used = dev_info.min_mbuf_tailroom_req;
742 mbuf = sym_op->m_src;
745 hdroom = rte_pktmbuf_headroom(mbuf);
747 if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
748 head_unchanged_len = hdroom +
749 sym_op->cipher.data.offset;
750 changed_len = sym_op->cipher.data.length;
753 head_unchanged_len = hdroom +
754 sym_op->auth.data.offset +
755 sym_op->auth.data.length;
759 if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN)
760 changed_len += digest_len;
762 if (t->op_mask & BLOCKCIPHER_TEST_OP_DIGEST_ENCRYPTED)
763 changed_len = sym_op->cipher.data.length;
765 for (i = 0; i < mbuf->buf_len; i++) {
767 /* Skip headroom used by PMD */
768 if (i == hdroom - hdroom_used)
771 if (i == head_unchanged_len)
774 /* Skip tailroom used by PMD */
775 if (i == (hdroom + mbuf->data_len))
778 value = *((uint8_t *)(mbuf->buf_addr)+i);
779 if (value != tmp_src_buf[i]) {
780 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN,
781 "line %u FAILED: outer mbuf data (0x%x) "
782 "not as expected (0x%x)",
783 __LINE__, value, tmp_src_buf[i]);
784 status = TEST_FAILED;
790 snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
793 if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
795 rte_cryptodev_sym_session_clear(dev_id, sess);
796 rte_cryptodev_sym_session_free(sess);
799 rte_free(cipher_xform);
801 rte_free(auth_xform);
805 rte_crypto_op_free(op);
808 rte_pktmbuf_free(obuf);
811 rte_pktmbuf_free(ibuf);
817 blockcipher_test_case_run(const void *data)
819 const struct blockcipher_test_case *tc_data = data;
821 char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];
823 status = test_blockcipher_one_case(tc_data,
824 p_testsuite_params->mbuf_pool,
825 p_testsuite_params->op_mpool,
826 p_testsuite_params->session_mpool,
827 p_testsuite_params->session_priv_mpool,
828 p_testsuite_params->valid_devs[0],
834 aes_chain_setup(void)
836 uint8_t dev_id = p_testsuite_params->valid_devs[0];
837 struct rte_cryptodev_info dev_info;
839 const enum rte_crypto_cipher_algorithm ciphers[] = {
840 RTE_CRYPTO_CIPHER_NULL,
841 RTE_CRYPTO_CIPHER_AES_CTR,
842 RTE_CRYPTO_CIPHER_AES_CBC
844 const enum rte_crypto_auth_algorithm auths[] = {
845 RTE_CRYPTO_AUTH_NULL,
846 RTE_CRYPTO_AUTH_SHA1_HMAC,
847 RTE_CRYPTO_AUTH_AES_XCBC_MAC,
848 RTE_CRYPTO_AUTH_SHA256_HMAC,
849 RTE_CRYPTO_AUTH_SHA512_HMAC,
850 RTE_CRYPTO_AUTH_SHA224_HMAC,
851 RTE_CRYPTO_AUTH_SHA384_HMAC
854 rte_cryptodev_info_get(dev_id, &dev_info);
855 feat_flags = dev_info.feature_flags;
857 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
858 ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
859 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
860 RTE_LOG(INFO, USER1, "Feature flag requirements for AES Chain "
861 "testsuite not met\n");
865 if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
866 && check_auth_capabilities_supported(auths,
867 RTE_DIM(auths)) != 0) {
868 RTE_LOG(INFO, USER1, "Capability requirements for AES Chain "
869 "testsuite not met\n");
877 aes_cipheronly_setup(void)
879 uint8_t dev_id = p_testsuite_params->valid_devs[0];
880 struct rte_cryptodev_info dev_info;
882 const enum rte_crypto_cipher_algorithm ciphers[] = {
883 RTE_CRYPTO_CIPHER_NULL,
884 RTE_CRYPTO_CIPHER_AES_CTR,
885 RTE_CRYPTO_CIPHER_AES_CBC,
886 RTE_CRYPTO_CIPHER_AES_ECB,
887 RTE_CRYPTO_CIPHER_AES_XTS
889 const enum rte_crypto_auth_algorithm auths[] = {
890 RTE_CRYPTO_AUTH_NULL,
891 RTE_CRYPTO_AUTH_SHA1_HMAC,
892 RTE_CRYPTO_AUTH_AES_XCBC_MAC
895 rte_cryptodev_info_get(dev_id, &dev_info);
896 feat_flags = dev_info.feature_flags;
898 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
899 ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
900 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
901 RTE_LOG(INFO, USER1, "Feature flag requirements for AES Cipheronly "
902 "testsuite not met\n");
906 if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
907 && check_auth_capabilities_supported(auths,
908 RTE_DIM(auths)) != 0) {
909 RTE_LOG(INFO, USER1, "Capability requirements for AES Cipheronly "
910 "testsuite not met\n");
918 aes_docsis_setup(void)
920 uint8_t dev_id = p_testsuite_params->valid_devs[0];
921 struct rte_cryptodev_info dev_info;
923 const enum rte_crypto_cipher_algorithm ciphers[] = {
924 RTE_CRYPTO_CIPHER_AES_DOCSISBPI
927 rte_cryptodev_info_get(dev_id, &dev_info);
928 feat_flags = dev_info.feature_flags;
930 /* Data-path service does not support DOCSIS yet */
931 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
932 (global_api_test_type == CRYPTODEV_RAW_API_TEST)) {
933 RTE_LOG(INFO, USER1, "Feature flag requirements for AES Docsis "
934 "testsuite not met\n");
938 if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
939 RTE_LOG(INFO, USER1, "Capability requirements for AES Docsis "
940 "testsuite not met\n");
948 triple_des_chain_setup(void)
950 uint8_t dev_id = p_testsuite_params->valid_devs[0];
951 struct rte_cryptodev_info dev_info;
953 const enum rte_crypto_cipher_algorithm ciphers[] = {
954 RTE_CRYPTO_CIPHER_3DES_CTR,
955 RTE_CRYPTO_CIPHER_3DES_CBC
957 const enum rte_crypto_auth_algorithm auths[] = {
958 RTE_CRYPTO_AUTH_SHA1_HMAC,
962 rte_cryptodev_info_get(dev_id, &dev_info);
963 feat_flags = dev_info.feature_flags;
965 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
966 ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
967 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
968 RTE_LOG(INFO, USER1, "Feature flag requirements for 3DES Chain "
969 "testsuite not met\n");
973 if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0
974 && check_auth_capabilities_supported(auths,
975 RTE_DIM(auths)) != 0) {
976 RTE_LOG(INFO, USER1, "Capability requirements for 3DES Chain "
977 "testsuite not met\n");
985 triple_des_cipheronly_setup(void)
987 uint8_t dev_id = p_testsuite_params->valid_devs[0];
988 struct rte_cryptodev_info dev_info;
990 const enum rte_crypto_cipher_algorithm ciphers[] = {
991 RTE_CRYPTO_CIPHER_3DES_CTR,
992 RTE_CRYPTO_CIPHER_3DES_CBC
995 rte_cryptodev_info_get(dev_id, &dev_info);
996 feat_flags = dev_info.feature_flags;
998 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
999 ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1000 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1001 RTE_LOG(INFO, USER1, "Feature flag requirements for 3DES "
1002 "Cipheronly testsuite not met\n");
1003 return TEST_SKIPPED;
1006 if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1007 RTE_LOG(INFO, USER1, "Capability requirements for 3DES "
1008 "Cipheronly testsuite not met\n");
1009 return TEST_SKIPPED;
1016 des_cipheronly_setup(void)
1018 uint8_t dev_id = p_testsuite_params->valid_devs[0];
1019 struct rte_cryptodev_info dev_info;
1020 uint64_t feat_flags;
1021 const enum rte_crypto_cipher_algorithm ciphers[] = {
1022 RTE_CRYPTO_CIPHER_DES_CBC
1025 rte_cryptodev_info_get(dev_id, &dev_info);
1026 feat_flags = dev_info.feature_flags;
1028 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1029 ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1030 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1031 RTE_LOG(INFO, USER1, "Feature flag requirements for DES "
1032 "Cipheronly testsuite not met\n");
1033 return TEST_SKIPPED;
1036 if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1037 RTE_LOG(INFO, USER1, "Capability requirements for DES "
1038 "Cipheronly testsuite not met\n");
1039 return TEST_SKIPPED;
1046 des_docsis_setup(void)
1048 uint8_t dev_id = p_testsuite_params->valid_devs[0];
1049 struct rte_cryptodev_info dev_info;
1050 uint64_t feat_flags;
1051 const enum rte_crypto_cipher_algorithm ciphers[] = {
1052 RTE_CRYPTO_CIPHER_DES_DOCSISBPI
1055 rte_cryptodev_info_get(dev_id, &dev_info);
1056 feat_flags = dev_info.feature_flags;
1058 /* Data-path service does not support DOCSIS yet */
1059 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1060 (global_api_test_type == CRYPTODEV_RAW_API_TEST)) {
1061 RTE_LOG(INFO, USER1, "Feature flag requirements for DES Docsis "
1062 "testsuite not met\n");
1063 return TEST_SKIPPED;
1066 if (check_cipher_capabilities_supported(ciphers, RTE_DIM(ciphers)) != 0) {
1067 RTE_LOG(INFO, USER1, "Capability requirements for DES Docsis "
1068 "testsuite not met\n");
1069 return TEST_SKIPPED;
1076 authonly_setup(void)
1078 uint8_t dev_id = p_testsuite_params->valid_devs[0];
1079 struct rte_cryptodev_info dev_info;
1080 uint64_t feat_flags;
1081 const enum rte_crypto_auth_algorithm auths[] = {
1082 RTE_CRYPTO_AUTH_MD5,
1083 RTE_CRYPTO_AUTH_MD5_HMAC,
1084 RTE_CRYPTO_AUTH_SHA1,
1085 RTE_CRYPTO_AUTH_SHA1_HMAC,
1086 RTE_CRYPTO_AUTH_SHA224,
1087 RTE_CRYPTO_AUTH_SHA224_HMAC,
1088 RTE_CRYPTO_AUTH_SHA256,
1089 RTE_CRYPTO_AUTH_SHA256_HMAC,
1090 RTE_CRYPTO_AUTH_SHA384,
1091 RTE_CRYPTO_AUTH_SHA384_HMAC,
1092 RTE_CRYPTO_AUTH_SHA512,
1093 RTE_CRYPTO_AUTH_SHA512_HMAC,
1094 RTE_CRYPTO_AUTH_AES_CMAC,
1095 RTE_CRYPTO_AUTH_NULL,
1096 RTE_CRYPTO_AUTH_AES_XCBC_MAC
1099 rte_cryptodev_info_get(dev_id, &dev_info);
1100 feat_flags = dev_info.feature_flags;
1102 if (!(feat_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ||
1103 ((global_api_test_type == CRYPTODEV_RAW_API_TEST) &&
1104 !(feat_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP))) {
1105 RTE_LOG(INFO, USER1, "Feature flag requirements for Auth Only "
1106 "testsuite not met\n");
1107 return TEST_SKIPPED;
1110 if (check_auth_capabilities_supported(auths, RTE_DIM(auths)) != 0) {
1111 RTE_LOG(INFO, USER1, "Capability requirements for Auth Only "
1112 "testsuite not met\n");
1113 return TEST_SKIPPED;
1119 struct unit_test_suite *
1120 build_blockcipher_test_suite(enum blockcipher_test_type test_type)
1122 int i, n_test_cases = 0;
1123 struct unit_test_suite *ts;
1124 const char *ts_name = NULL;
1125 const struct blockcipher_test_case *blk_tcs;
1126 struct unit_test_case *tc;
1127 int (*ts_setup)(void) = NULL;
1129 switch (test_type) {
1130 case BLKCIPHER_AES_CHAIN_TYPE:
1131 n_test_cases = RTE_DIM(aes_chain_test_cases);
1132 blk_tcs = aes_chain_test_cases;
1133 ts_name = "AES Chain";
1134 ts_setup = aes_chain_setup;
1136 case BLKCIPHER_AES_CIPHERONLY_TYPE:
1137 n_test_cases = RTE_DIM(aes_cipheronly_test_cases);
1138 blk_tcs = aes_cipheronly_test_cases;
1139 ts_name = "AES Cipher Only";
1140 ts_setup = aes_cipheronly_setup;
1142 case BLKCIPHER_AES_DOCSIS_TYPE:
1143 n_test_cases = RTE_DIM(aes_docsis_test_cases);
1144 blk_tcs = aes_docsis_test_cases;
1145 ts_name = "AES Docsis";
1146 ts_setup = aes_docsis_setup;
1148 case BLKCIPHER_3DES_CHAIN_TYPE:
1149 n_test_cases = RTE_DIM(triple_des_chain_test_cases);
1150 blk_tcs = triple_des_chain_test_cases;
1151 ts_name = "3DES Chain";
1152 ts_setup = triple_des_chain_setup;
1154 case BLKCIPHER_3DES_CIPHERONLY_TYPE:
1155 n_test_cases = RTE_DIM(triple_des_cipheronly_test_cases);
1156 blk_tcs = triple_des_cipheronly_test_cases;
1157 ts_name = "3DES Cipher Only";
1158 ts_setup = triple_des_cipheronly_setup;
1160 case BLKCIPHER_DES_CIPHERONLY_TYPE:
1161 n_test_cases = RTE_DIM(des_cipheronly_test_cases);
1162 blk_tcs = des_cipheronly_test_cases;
1163 ts_name = "DES Cipher Only";
1164 ts_setup = des_cipheronly_setup;
1166 case BLKCIPHER_DES_DOCSIS_TYPE:
1167 n_test_cases = RTE_DIM(des_docsis_test_cases);
1168 blk_tcs = des_docsis_test_cases;
1169 ts_name = "DES Docsis";
1170 ts_setup = des_docsis_setup;
1172 case BLKCIPHER_AUTHONLY_TYPE:
1173 n_test_cases = RTE_DIM(hash_test_cases);
1174 blk_tcs = hash_test_cases;
1175 ts_name = "Auth Only";
1176 ts_setup = authonly_setup;
1182 ts = calloc(1, sizeof(struct unit_test_suite) +
1183 (sizeof(struct unit_test_case) * (n_test_cases + 1)));
1184 ts->suite_name = ts_name;
1185 ts->setup = ts_setup;
1187 for (i = 0; i < n_test_cases; i++) {
1188 tc = &ts->unit_test_cases[i];
1189 tc->name = blk_tcs[i].test_descr;
1191 tc->setup = ut_setup;
1192 tc->teardown = ut_teardown;
1193 tc->testcase = NULL;
1194 tc->testcase_with_data = blockcipher_test_case_run;
1195 tc->data = &blk_tcs[i];
1197 tc = &ts->unit_test_cases[i];
1201 tc->teardown = NULL;
1202 tc->testcase = NULL;
1203 tc->testcase_with_data = NULL;
1210 free_blockcipher_test_suite(struct unit_test_suite *ts)