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