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