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