1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 38 #include "util/dif.c" 39 40 #define DATA_PATTERN(offset) ((uint8_t)(0xAB + (offset))) 41 #define GUARD_SEED 0xCD 42 43 static int 44 ut_data_pattern_generate(struct iovec *iovs, int iovcnt, 45 uint32_t block_size, uint32_t md_size, uint32_t num_blocks) 46 { 47 struct _dif_sgl sgl; 48 uint32_t offset_blocks, offset_in_block, buf_len, data_offset, i; 49 uint8_t *buf; 50 51 _dif_sgl_init(&sgl, iovs, iovcnt); 52 53 if (!_dif_sgl_is_valid(&sgl, block_size * num_blocks)) { 54 return -1; 55 } 56 57 offset_blocks = 0; 58 data_offset = 0; 59 60 while (offset_blocks < num_blocks) { 61 offset_in_block = 0; 62 while (offset_in_block < block_size) { 63 _dif_sgl_get_buf(&sgl, (void *)&buf, &buf_len); 64 if (offset_in_block < block_size - md_size) { 65 buf_len = spdk_min(buf_len, 66 block_size - md_size - offset_in_block); 67 for (i = 0; i < buf_len; i++) { 68 buf[i] = DATA_PATTERN(data_offset + i); 69 } 70 data_offset += buf_len; 71 } else { 72 buf_len = spdk_min(buf_len, block_size - offset_in_block); 73 memset(buf, 0, buf_len); 74 } 75 _dif_sgl_advance(&sgl, buf_len); 76 offset_in_block += buf_len; 77 } 78 offset_blocks++; 79 } 80 81 return 0; 82 } 83 84 static int 85 ut_data_pattern_verify(struct iovec *iovs, int iovcnt, 86 uint32_t block_size, uint32_t md_size, uint32_t num_blocks) 87 { 88 struct _dif_sgl sgl; 89 uint32_t offset_blocks, offset_in_block, buf_len, data_offset, i; 90 uint8_t *buf; 91 92 _dif_sgl_init(&sgl, iovs, iovcnt); 93 94 if (!_dif_sgl_is_valid(&sgl, block_size * num_blocks)) { 95 return -1; 96 } 97 98 offset_blocks = 0; 99 data_offset = 0; 100 101 while (offset_blocks < num_blocks) { 102 offset_in_block = 0; 103 while (offset_in_block < block_size) { 104 _dif_sgl_get_buf(&sgl, (void *)&buf, &buf_len); 105 106 if (offset_in_block < block_size - md_size) { 107 buf_len = spdk_min(buf_len, 108 block_size - md_size - offset_in_block); 109 for (i = 0; i < buf_len; i++) { 110 if (buf[i] != DATA_PATTERN(data_offset + i)) { 111 return -1; 112 } 113 } 114 data_offset += buf_len; 115 } else { 116 buf_len = spdk_min(buf_len, block_size - offset_in_block); 117 } 118 _dif_sgl_advance(&sgl, buf_len); 119 offset_in_block += buf_len; 120 } 121 offset_blocks++; 122 } 123 124 return 0; 125 } 126 127 static void 128 _iov_alloc_buf(struct iovec *iov, uint32_t len) 129 { 130 iov->iov_base = calloc(1, len); 131 iov->iov_len = len; 132 SPDK_CU_ASSERT_FATAL(iov->iov_base != NULL); 133 } 134 135 static void 136 _iov_free_buf(struct iovec *iov) 137 { 138 free(iov->iov_base); 139 } 140 141 static void 142 _iov_set_buf(struct iovec *iov, uint8_t *buf, uint32_t buf_len) 143 { 144 iov->iov_base = buf; 145 iov->iov_len = buf_len; 146 } 147 148 static bool 149 _iov_check(struct iovec *iov, void *iov_base, uint32_t iov_len) 150 { 151 return (iov->iov_base == iov_base && iov->iov_len == iov_len); 152 } 153 154 static void 155 _dif_generate_and_verify(struct iovec *iov, 156 uint32_t block_size, uint32_t md_size, bool dif_loc, 157 enum spdk_dif_type dif_type, uint32_t dif_flags, 158 uint32_t ref_tag, uint32_t e_ref_tag, 159 uint16_t app_tag, uint16_t apptag_mask, uint16_t e_app_tag, 160 bool expect_pass) 161 { 162 struct spdk_dif_ctx ctx = {}; 163 uint32_t guard_interval; 164 uint16_t guard = 0; 165 int rc; 166 167 rc = ut_data_pattern_generate(iov, 1, block_size, md_size, 1); 168 CU_ASSERT(rc == 0); 169 170 guard_interval = _get_guard_interval(block_size, md_size, dif_loc, true); 171 172 ctx.dif_type = dif_type; 173 ctx.dif_flags = dif_flags; 174 ctx.init_ref_tag = ref_tag; 175 ctx.app_tag = app_tag; 176 177 if (dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) { 178 guard = spdk_crc16_t10dif(0, iov->iov_base, guard_interval); 179 } 180 181 _dif_generate(iov->iov_base + guard_interval, guard, 0, &ctx); 182 183 ctx.init_ref_tag = e_ref_tag; 184 ctx.apptag_mask = apptag_mask; 185 ctx.app_tag = e_app_tag; 186 187 rc = _dif_verify(iov->iov_base + guard_interval, guard, 0, &ctx, NULL); 188 CU_ASSERT((expect_pass && rc == 0) || (!expect_pass && rc != 0)); 189 190 rc = ut_data_pattern_verify(iov, 1, block_size, md_size, 1); 191 CU_ASSERT(rc == 0); 192 } 193 194 static void 195 dif_generate_and_verify_test(void) 196 { 197 struct iovec iov; 198 uint32_t dif_flags; 199 200 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 201 SPDK_DIF_FLAGS_REFTAG_CHECK; 202 203 _iov_alloc_buf(&iov, 4096 + 128); 204 205 /* Positive cases */ 206 207 /* The case that DIF is contained in the first 8 bytes of metadata. */ 208 _dif_generate_and_verify(&iov, 209 4096 + 128, 128, true, 210 SPDK_DIF_TYPE1, dif_flags, 211 22, 22, 212 0x22, 0xFFFF, 0x22, 213 true); 214 215 /* The case that DIF is contained in the last 8 bytes of metadata. */ 216 _dif_generate_and_verify(&iov, 217 4096 + 128, 128, false, 218 SPDK_DIF_TYPE1, dif_flags, 219 22, 22, 220 0x22, 0xFFFF, 0x22, 221 true); 222 223 /* Negative cases */ 224 225 /* Reference tag doesn't match. */ 226 _dif_generate_and_verify(&iov, 227 4096 + 128, 128, false, 228 SPDK_DIF_TYPE1, dif_flags, 229 22, 23, 230 0x22, 0xFFFF, 0x22, 231 false); 232 233 /* Application tag doesn't match. */ 234 _dif_generate_and_verify(&iov, 235 4096 + 128, 128, false, 236 SPDK_DIF_TYPE1, dif_flags, 237 22, 22, 238 0x22, 0xFFFF, 0x23, 239 false); 240 241 _iov_free_buf(&iov); 242 } 243 244 static void 245 dif_disable_check_test(void) 246 { 247 struct iovec iov; 248 uint32_t dif_flags; 249 250 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 251 SPDK_DIF_FLAGS_REFTAG_CHECK; 252 253 _iov_alloc_buf(&iov, 4096 + 128); 254 255 /* The case that DIF check is disabled when the Application Tag is 0xFFFF for 256 * Type 1. DIF check is disabled and pass is expected. 257 */ 258 _dif_generate_and_verify(&iov, 259 4096 + 128, 128, false, 260 SPDK_DIF_TYPE1, dif_flags, 261 22, 22, 262 0xFFFF, 0xFFFF, 0x22, 263 true); 264 265 /* The case that DIF check is not disabled when the Application Tag is 0xFFFF but 266 * the Reference Tag is not 0xFFFFFFFF for Type 3. DIF check is not disabled and 267 * fail is expected. 268 */ 269 _dif_generate_and_verify(&iov, 270 4096 + 128, 128, false, 271 SPDK_DIF_TYPE3, dif_flags, 272 22, 22, 273 0xFFFF, 0xFFFF, 0x22, 274 false); 275 276 /* The case that DIF check is disabled when the Application Tag is 0xFFFF and 277 * the Reference Tag is 0xFFFFFFFF for Type 3. DIF check is disabled and 278 * pass is expected. 279 */ 280 _dif_generate_and_verify(&iov, 281 4096 + 128, 128, false, 282 SPDK_DIF_TYPE3, dif_flags, 283 0xFFFFFFFF, 22, 284 0xFFFF, 0xFFFF, 0x22, 285 true); 286 287 _iov_free_buf(&iov); 288 } 289 290 static void 291 dif_sec_512_md_0_error_test(void) 292 { 293 struct spdk_dif_ctx ctx = {}; 294 int rc; 295 296 /* Metadata size is 0. */ 297 rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0); 298 CU_ASSERT(rc != 0); 299 } 300 301 static void 302 dif_guard_seed_test(void) 303 { 304 struct iovec iov; 305 struct spdk_dif_ctx ctx = {}; 306 struct spdk_dif_error err_blk = {}; 307 struct spdk_dif *dif; 308 uint16_t guard; 309 int rc; 310 311 _iov_alloc_buf(&iov, 512 + 8); 312 313 memset(iov.iov_base, 0, 512 + 8); 314 315 dif = (struct spdk_dif *)(iov.iov_base + 512); 316 317 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 318 SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0); 319 CU_ASSERT(rc == 0); 320 321 rc = spdk_dif_generate(&iov, 1, 1, &ctx); 322 CU_ASSERT(rc == 0); 323 324 /* Guard should be zero if the block is all zero and seed is not added. */ 325 guard = from_be16(&dif->guard); 326 CU_ASSERT(guard == 0); 327 328 rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk); 329 CU_ASSERT(rc == 0); 330 331 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 332 SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, GUARD_SEED); 333 CU_ASSERT(rc == 0); 334 335 rc = spdk_dif_generate(&iov, 1, 1, &ctx); 336 CU_ASSERT(rc == 0); 337 338 /* Guard should not be zero if the block is all zero but seed is added. */ 339 guard = from_be16(&dif->guard); 340 CU_ASSERT(guard != 0); 341 342 rc = spdk_dif_verify(&iov, 1, 1, &ctx, &err_blk); 343 CU_ASSERT(rc == 0); 344 345 _iov_free_buf(&iov); 346 } 347 348 static void 349 dif_generate_and_verify(struct iovec *iovs, int iovcnt, 350 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 351 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 352 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) 353 { 354 struct spdk_dif_ctx ctx = {}; 355 int rc; 356 357 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); 358 CU_ASSERT(rc == 0); 359 360 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 361 init_ref_tag, apptag_mask, app_tag, GUARD_SEED); 362 CU_ASSERT(rc == 0); 363 364 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); 365 CU_ASSERT(rc == 0); 366 367 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, NULL); 368 CU_ASSERT(rc == 0); 369 370 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks); 371 CU_ASSERT(rc == 0); 372 } 373 374 static void 375 dif_disable_sec_512_md_8_single_iov_test(void) 376 { 377 struct iovec iov; 378 379 _iov_alloc_buf(&iov, 512 + 8); 380 381 dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_DISABLE, 0, 0, 0, 0); 382 383 _iov_free_buf(&iov); 384 } 385 386 static void 387 dif_sec_512_md_8_prchk_0_single_iov_test(void) 388 { 389 struct iovec iov; 390 391 _iov_alloc_buf(&iov, 512 + 8); 392 393 dif_generate_and_verify(&iov, 1, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); 394 395 _iov_free_buf(&iov); 396 } 397 398 static void 399 dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test(void) 400 { 401 struct iovec iovs[4]; 402 int i, num_blocks; 403 404 num_blocks = 0; 405 406 for (i = 0; i < 4; i++) { 407 _iov_alloc_buf(&iovs[i], (512 + 8) * (i + 1)); 408 num_blocks += i + 1; 409 } 410 411 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 412 0, 22, 0xFFFF, 0x22); 413 414 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 415 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22); 416 417 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 418 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22); 419 420 dif_generate_and_verify(iovs, 4, 512 + 8, 8, num_blocks, false, SPDK_DIF_TYPE1, 421 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22); 422 423 for (i = 0; i < 4; i++) { 424 _iov_free_buf(&iovs[i]); 425 } 426 } 427 428 static void 429 dif_sec_4096_md_128_prchk_7_multi_iovs_test(void) 430 { 431 struct iovec iovs[4]; 432 int i, num_blocks; 433 uint32_t dif_flags; 434 435 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 436 SPDK_DIF_FLAGS_REFTAG_CHECK; 437 438 num_blocks = 0; 439 440 for (i = 0; i < 4; i++) { 441 _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1)); 442 num_blocks += i + 1; 443 } 444 445 dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, false, SPDK_DIF_TYPE1, 446 dif_flags, 22, 0xFFFF, 0x22); 447 448 dif_generate_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, true, SPDK_DIF_TYPE1, 449 dif_flags, 22, 0xFFFF, 0x22); 450 451 for (i = 0; i < 4; i++) { 452 _iov_free_buf(&iovs[i]); 453 } 454 } 455 456 static void 457 dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test(void) 458 { 459 struct iovec iovs[2]; 460 uint32_t dif_flags; 461 462 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 463 SPDK_DIF_FLAGS_REFTAG_CHECK; 464 465 _iov_alloc_buf(&iovs[0], 512); 466 _iov_alloc_buf(&iovs[1], 8); 467 468 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 469 dif_flags, 22, 0xFFFF, 0x22); 470 471 _iov_free_buf(&iovs[0]); 472 _iov_free_buf(&iovs[1]); 473 } 474 475 static void 476 dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test(void) 477 { 478 struct iovec iovs[2]; 479 uint32_t dif_flags; 480 481 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 482 SPDK_DIF_FLAGS_REFTAG_CHECK; 483 484 _iov_alloc_buf(&iovs[0], 256); 485 _iov_alloc_buf(&iovs[1], 264); 486 487 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 488 dif_flags, 22, 0xFFFF, 0x22); 489 490 _iov_free_buf(&iovs[0]); 491 _iov_free_buf(&iovs[1]); 492 } 493 494 static void 495 dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test(void) 496 { 497 struct iovec iovs[2]; 498 uint32_t dif_flags; 499 500 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 501 SPDK_DIF_FLAGS_REFTAG_CHECK; 502 503 _iov_alloc_buf(&iovs[0], 513); 504 _iov_alloc_buf(&iovs[1], 7); 505 506 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 507 dif_flags, 22, 0xFFFF, 0x22); 508 509 _iov_free_buf(&iovs[0]); 510 _iov_free_buf(&iovs[1]); 511 } 512 513 static void 514 dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test(void) 515 { 516 struct iovec iovs[2]; 517 uint32_t dif_flags; 518 519 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 520 SPDK_DIF_FLAGS_REFTAG_CHECK; 521 522 _iov_alloc_buf(&iovs[0], 515); 523 _iov_alloc_buf(&iovs[1], 5); 524 525 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 526 dif_flags, 22, 0xFFFF, 0x22); 527 528 _iov_free_buf(&iovs[0]); 529 _iov_free_buf(&iovs[1]); 530 } 531 532 static void 533 dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test(void) 534 { 535 struct iovec iovs[2]; 536 uint32_t dif_flags; 537 538 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 539 SPDK_DIF_FLAGS_REFTAG_CHECK; 540 541 _iov_alloc_buf(&iovs[0], 518); 542 _iov_alloc_buf(&iovs[1], 2); 543 544 dif_generate_and_verify(iovs, 2, 512 + 8, 8, 1, false, SPDK_DIF_TYPE1, 545 dif_flags, 22, 0xFFFF, 0x22); 546 547 _iov_free_buf(&iovs[0]); 548 _iov_free_buf(&iovs[1]); 549 } 550 551 static void 552 dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test(void) 553 { 554 struct iovec iovs[9]; 555 uint32_t dif_flags; 556 int i; 557 558 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 559 SPDK_DIF_FLAGS_REFTAG_CHECK; 560 561 /* data[0][255:0] */ 562 _iov_alloc_buf(&iovs[0], 256); 563 564 /* data[0][511:256], guard[0][0] */ 565 _iov_alloc_buf(&iovs[1], 256 + 1); 566 567 /* guard[0][1], apptag[0][0] */ 568 _iov_alloc_buf(&iovs[2], 1 + 1); 569 570 /* apptag[0][1], reftag[0][0] */ 571 _iov_alloc_buf(&iovs[3], 1 + 1); 572 573 /* reftag[0][3:1], data[1][255:0] */ 574 _iov_alloc_buf(&iovs[4], 3 + 256); 575 576 /* data[1][511:256], guard[1][0] */ 577 _iov_alloc_buf(&iovs[5], 256 + 1); 578 579 /* guard[1][1], apptag[1][0] */ 580 _iov_alloc_buf(&iovs[6], 1 + 1); 581 582 /* apptag[1][1], reftag[1][0] */ 583 _iov_alloc_buf(&iovs[7], 1 + 1); 584 585 /* reftag[1][3:1] */ 586 _iov_alloc_buf(&iovs[8], 3); 587 588 dif_generate_and_verify(iovs, 9, 512 + 8, 8, 2, false, SPDK_DIF_TYPE1, dif_flags, 589 22, 0xFFFF, 0x22); 590 591 for (i = 0; i < 9; i++) { 592 _iov_free_buf(&iovs[i]); 593 } 594 } 595 596 static void 597 dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test(void) 598 { 599 struct iovec iovs[11]; 600 uint32_t dif_flags; 601 int i; 602 603 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 604 SPDK_DIF_FLAGS_REFTAG_CHECK; 605 606 /* data[0][1000:0] */ 607 _iov_alloc_buf(&iovs[0], 1000); 608 609 /* data[0][3095:1000], guard[0][0] */ 610 _iov_alloc_buf(&iovs[1], 3096 + 1); 611 612 /* guard[0][1], apptag[0][0] */ 613 _iov_alloc_buf(&iovs[2], 1 + 1); 614 615 /* apptag[0][1], reftag[0][0] */ 616 _iov_alloc_buf(&iovs[3], 1 + 1); 617 618 /* reftag[0][3:1], ignore[0][59:0] */ 619 _iov_alloc_buf(&iovs[4], 3 + 60); 620 621 /* ignore[119:60], data[1][3050:0] */ 622 _iov_alloc_buf(&iovs[5], 60 + 3051); 623 624 /* data[1][4095:3050], guard[1][0] */ 625 _iov_alloc_buf(&iovs[6], 1045 + 1); 626 627 /* guard[1][1], apptag[1][0] */ 628 _iov_alloc_buf(&iovs[7], 1 + 1); 629 630 /* apptag[1][1], reftag[1][0] */ 631 _iov_alloc_buf(&iovs[8], 1 + 1); 632 633 /* reftag[1][3:1], ignore[1][9:0] */ 634 _iov_alloc_buf(&iovs[9], 3 + 10); 635 636 /* ignore[1][127:9] */ 637 _iov_alloc_buf(&iovs[10], 118); 638 639 dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, false, SPDK_DIF_TYPE1, dif_flags, 640 22, 0xFFFF, 0x22); 641 dif_generate_and_verify(iovs, 11, 4096 + 128, 128, 2, true, SPDK_DIF_TYPE1, dif_flags, 642 22, 0xFFFF, 0x22); 643 644 for (i = 0; i < 11; i++) { 645 _iov_free_buf(&iovs[i]); 646 } 647 } 648 649 static void 650 _dif_inject_error_and_verify(struct iovec *iovs, int iovcnt, 651 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 652 uint32_t inject_flags, bool dif_loc) 653 { 654 struct spdk_dif_ctx ctx = {}; 655 struct spdk_dif_error err_blk = {}; 656 uint32_t inject_offset = 0, dif_flags; 657 int rc; 658 659 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 660 SPDK_DIF_FLAGS_REFTAG_CHECK; 661 662 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); 663 CU_ASSERT(rc == 0); 664 665 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, 666 SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88, GUARD_SEED); 667 CU_ASSERT(rc == 0); 668 669 rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); 670 CU_ASSERT(rc == 0); 671 672 rc = spdk_dif_inject_error(iovs, iovcnt, num_blocks, &ctx, inject_flags, &inject_offset); 673 CU_ASSERT(rc == 0); 674 675 rc = spdk_dif_verify(iovs, iovcnt, num_blocks, &ctx, &err_blk); 676 CU_ASSERT(rc != 0); 677 if (inject_flags == SPDK_DIF_DATA_ERROR) { 678 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 679 } else { 680 CU_ASSERT(inject_flags == err_blk.err_type); 681 } 682 CU_ASSERT(inject_offset == err_blk.err_offset); 683 684 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, md_size, num_blocks); 685 CU_ASSERT((rc == 0 && (inject_flags != SPDK_DIF_DATA_ERROR)) || 686 (rc != 0 && (inject_flags == SPDK_DIF_DATA_ERROR))); 687 } 688 689 static void 690 dif_inject_error_and_verify(struct iovec *iovs, int iovcnt, 691 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 692 uint32_t inject_flags) 693 { 694 /* The case that DIF is contained in the first 8 bytes of metadata. */ 695 _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks, 696 inject_flags, true); 697 698 /* The case that DIF is contained in the last 8 bytes of metadata. */ 699 _dif_inject_error_and_verify(iovs, iovcnt, block_size, md_size, num_blocks, 700 inject_flags, false); 701 } 702 703 static void 704 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 705 { 706 struct iovec iovs[4]; 707 int i, num_blocks; 708 709 num_blocks = 0; 710 711 for (i = 0; i < 4; i++) { 712 _iov_alloc_buf(&iovs[i], (4096 + 128) * (i + 1)); 713 num_blocks += i + 1; 714 } 715 716 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_GUARD_ERROR); 717 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_APPTAG_ERROR); 718 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_REFTAG_ERROR); 719 dif_inject_error_and_verify(iovs, 4, 4096 + 128, 128, num_blocks, SPDK_DIF_DATA_ERROR); 720 721 for (i = 0; i < 4; i++) { 722 _iov_free_buf(&iovs[i]); 723 } 724 } 725 726 static void 727 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test(void) 728 { 729 struct iovec iovs[2]; 730 731 _iov_alloc_buf(&iovs[0], 4096); 732 _iov_alloc_buf(&iovs[1], 128); 733 734 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 735 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 736 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 737 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 738 739 _iov_free_buf(&iovs[0]); 740 _iov_free_buf(&iovs[1]); 741 } 742 743 static void 744 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test(void) 745 { 746 struct iovec iovs[2]; 747 748 _iov_alloc_buf(&iovs[0], 2048); 749 _iov_alloc_buf(&iovs[1], 2048 + 128); 750 751 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 752 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 753 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 754 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 755 756 _iov_free_buf(&iovs[0]); 757 _iov_free_buf(&iovs[1]); 758 } 759 760 static void 761 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test(void) 762 { 763 struct iovec iovs[2]; 764 765 _iov_alloc_buf(&iovs[0], 4096 + 1); 766 _iov_alloc_buf(&iovs[1], 127); 767 768 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 769 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 770 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 771 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 772 773 _iov_free_buf(&iovs[0]); 774 _iov_free_buf(&iovs[1]); 775 } 776 777 static void 778 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test(void) 779 { 780 struct iovec iovs[2]; 781 782 _iov_alloc_buf(&iovs[0], 4096 + 3); 783 _iov_alloc_buf(&iovs[1], 125); 784 785 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 786 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 787 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 788 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 789 790 _iov_free_buf(&iovs[0]); 791 _iov_free_buf(&iovs[1]); 792 } 793 794 static void 795 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test(void) 796 { 797 struct iovec iovs[2]; 798 799 _iov_alloc_buf(&iovs[0], 4096 + 6); 800 _iov_alloc_buf(&iovs[1], 122); 801 802 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_GUARD_ERROR); 803 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_APPTAG_ERROR); 804 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_REFTAG_ERROR); 805 dif_inject_error_and_verify(iovs, 2, 4096 + 128, 128, 1, SPDK_DIF_DATA_ERROR); 806 807 _iov_free_buf(&iovs[0]); 808 _iov_free_buf(&iovs[1]); 809 } 810 811 static void 812 dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 813 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 814 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 815 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) 816 { 817 struct spdk_dif_ctx ctx = {}; 818 int rc; 819 820 rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks); 821 CU_ASSERT(rc == 0); 822 823 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, 824 init_ref_tag, apptag_mask, app_tag, GUARD_SEED); 825 CU_ASSERT(rc == 0); 826 827 rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx); 828 CU_ASSERT(rc == 0); 829 830 rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, NULL); 831 CU_ASSERT(rc == 0); 832 833 rc = ut_data_pattern_verify(iovs, iovcnt, block_size - md_size, 0, num_blocks); 834 CU_ASSERT(rc == 0); 835 } 836 837 static void 838 dif_copy_sec_512_md_8_prchk_0_single_iov(void) 839 { 840 struct iovec iov, bounce_iov; 841 842 _iov_alloc_buf(&iov, 512 * 4); 843 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4); 844 845 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4, 846 false, SPDK_DIF_TYPE1, 0, 0, 0, 0); 847 dif_copy_gen_and_verify(&iov, 1, &bounce_iov, 512 + 8, 8, 4, 848 true, SPDK_DIF_TYPE1, 0, 0, 0, 0); 849 850 _iov_free_buf(&iov); 851 _iov_free_buf(&bounce_iov); 852 } 853 854 static void 855 dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void) 856 { 857 struct iovec iovs[4], bounce_iov; 858 int i, num_blocks; 859 860 num_blocks = 0; 861 862 for (i = 0; i < 4; i++) { 863 _iov_alloc_buf(&iovs[i], 512 * (i + 1)); 864 num_blocks += i + 1; 865 } 866 867 _iov_alloc_buf(&bounce_iov, (512 + 8) * num_blocks); 868 869 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 870 false, SPDK_DIF_TYPE1, 0, 22, 0xFFFF, 0x22); 871 872 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 873 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22); 874 875 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 876 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22); 877 878 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 512 + 8, 8, num_blocks, 879 false, SPDK_DIF_TYPE1, SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22); 880 881 for (i = 0; i < 4; i++) { 882 _iov_free_buf(&iovs[i]); 883 } 884 _iov_free_buf(&bounce_iov); 885 } 886 887 static void 888 dif_copy_sec_4096_md_128_prchk_7_multi_iovs(void) 889 { 890 struct iovec iovs[4], bounce_iov; 891 uint32_t dif_flags; 892 int i, num_blocks; 893 894 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 895 SPDK_DIF_FLAGS_REFTAG_CHECK; 896 897 num_blocks = 0; 898 899 for (i = 0; i < 4; i++) { 900 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 901 num_blocks += i + 1; 902 } 903 904 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks); 905 906 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks, 907 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 908 dif_copy_gen_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, num_blocks, 909 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 910 911 for (i = 0; i < 4; i++) { 912 _iov_free_buf(&iovs[i]); 913 } 914 _iov_free_buf(&bounce_iov); 915 } 916 917 static void 918 dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data(void) 919 { 920 struct iovec iovs[2], bounce_iov; 921 uint32_t dif_flags; 922 923 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 924 SPDK_DIF_FLAGS_REFTAG_CHECK; 925 926 _iov_alloc_buf(&iovs[0], 256); 927 _iov_alloc_buf(&iovs[1], 256); 928 929 _iov_alloc_buf(&bounce_iov, 512 + 8); 930 931 dif_copy_gen_and_verify(iovs, 2, &bounce_iov, 512 + 8, 8, 1, 932 false, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 933 934 _iov_free_buf(&iovs[0]); 935 _iov_free_buf(&iovs[1]); 936 _iov_free_buf(&bounce_iov); 937 } 938 939 static void 940 dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void) 941 { 942 struct iovec iovs[6], bounce_iov; 943 uint32_t dif_flags; 944 int i; 945 946 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 947 SPDK_DIF_FLAGS_REFTAG_CHECK; 948 949 /* data[0][255:0] */ 950 _iov_alloc_buf(&iovs[0], 256); 951 952 /* data[0][511:256], data[1][255:0] */ 953 _iov_alloc_buf(&iovs[1], 256 + 256); 954 955 /* data[1][382:256] */ 956 _iov_alloc_buf(&iovs[2], 128); 957 958 /* data[1][383] */ 959 _iov_alloc_buf(&iovs[3], 1); 960 961 /* data[1][510:384] */ 962 _iov_alloc_buf(&iovs[4], 126); 963 964 /* data[1][511], data[2][511:0], data[3][511:0] */ 965 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 966 967 _iov_alloc_buf(&bounce_iov, (512 + 8) * 4); 968 969 dif_copy_gen_and_verify(iovs, 6, &bounce_iov, 512 + 8, 8, 4, 970 true, SPDK_DIF_TYPE1, dif_flags, 22, 0xFFFF, 0x22); 971 972 for (i = 0; i < 6; i++) { 973 _iov_free_buf(&iovs[i]); 974 } 975 _iov_free_buf(&bounce_iov); 976 } 977 978 static void 979 _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 980 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 981 uint32_t inject_flags, bool dif_loc) 982 { 983 struct spdk_dif_ctx ctx = {}; 984 struct spdk_dif_error err_blk = {}; 985 uint32_t inject_offset = 0, dif_flags; 986 int rc; 987 988 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 989 SPDK_DIF_FLAGS_REFTAG_CHECK; 990 991 rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks); 992 CU_ASSERT(rc == 0); 993 994 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags, 995 88, 0xFFFF, 0x88, GUARD_SEED); 996 SPDK_CU_ASSERT_FATAL(rc == 0); 997 998 rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx); 999 CU_ASSERT(rc == 0); 1000 1001 rc = spdk_dif_inject_error(bounce_iov, 1, num_blocks, &ctx, inject_flags, &inject_offset); 1002 CU_ASSERT(rc == 0); 1003 1004 rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, &err_blk); 1005 CU_ASSERT(rc != 0); 1006 if (inject_flags == SPDK_DIF_DATA_ERROR) { 1007 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 1008 } else { 1009 CU_ASSERT(inject_flags == err_blk.err_type); 1010 } 1011 CU_ASSERT(inject_offset == err_blk.err_offset); 1012 } 1013 1014 static void 1015 dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov, 1016 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 1017 uint32_t inject_flags) 1018 { 1019 /* The case that DIF is contained in the first 8 bytes of metadata. */ 1020 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov, 1021 block_size, md_size, num_blocks, 1022 inject_flags, true); 1023 1024 /* The case that DIF is contained in the last 8 bytes of metadata. */ 1025 _dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov, 1026 block_size, md_size, num_blocks, 1027 inject_flags, false); 1028 } 1029 1030 static void 1031 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 1032 { 1033 struct iovec iovs[4], bounce_iov; 1034 int i, num_blocks; 1035 1036 num_blocks = 0; 1037 1038 for (i = 0; i < 4; i++) { 1039 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1040 num_blocks += i + 1; 1041 } 1042 1043 _iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks); 1044 1045 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1046 num_blocks, SPDK_DIF_GUARD_ERROR); 1047 1048 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1049 num_blocks, SPDK_DIF_APPTAG_ERROR); 1050 1051 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1052 num_blocks, SPDK_DIF_REFTAG_ERROR); 1053 1054 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1055 num_blocks, SPDK_DIF_DATA_ERROR); 1056 1057 for (i = 0; i < 4; i++) { 1058 _iov_free_buf(&iovs[i]); 1059 } 1060 _iov_free_buf(&bounce_iov); 1061 } 1062 1063 static void 1064 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void) 1065 { 1066 struct iovec iovs[4], bounce_iov; 1067 int i; 1068 1069 _iov_alloc_buf(&iovs[0], 2048); 1070 _iov_alloc_buf(&iovs[1], 2048); 1071 _iov_alloc_buf(&iovs[2], 1); 1072 _iov_alloc_buf(&iovs[3], 4095); 1073 1074 _iov_alloc_buf(&bounce_iov, (4096 + 128) * 2); 1075 1076 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1077 2, SPDK_DIF_GUARD_ERROR); 1078 1079 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1080 2, SPDK_DIF_APPTAG_ERROR); 1081 1082 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1083 2, SPDK_DIF_REFTAG_ERROR); 1084 1085 dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128, 1086 2, SPDK_DIF_DATA_ERROR); 1087 1088 for (i = 0; i < 4; i++) { 1089 _iov_free_buf(&iovs[i]); 1090 } 1091 _iov_free_buf(&bounce_iov); 1092 } 1093 1094 static void 1095 dix_sec_512_md_0_error(void) 1096 { 1097 struct spdk_dif_ctx ctx; 1098 int rc; 1099 1100 rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0); 1101 CU_ASSERT(rc != 0); 1102 } 1103 1104 static void 1105 dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 1106 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 1107 bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 1108 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) 1109 { 1110 struct spdk_dif_ctx ctx; 1111 int rc; 1112 1113 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 1114 CU_ASSERT(rc == 0); 1115 1116 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, 1117 init_ref_tag, apptag_mask, app_tag, GUARD_SEED); 1118 CU_ASSERT(rc == 0); 1119 1120 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 1121 CU_ASSERT(rc == 0); 1122 1123 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, NULL); 1124 CU_ASSERT(rc == 0); 1125 1126 rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks); 1127 CU_ASSERT(rc == 0); 1128 } 1129 1130 static void 1131 dix_sec_512_md_8_prchk_0_single_iov(void) 1132 { 1133 struct iovec iov, md_iov; 1134 1135 _iov_alloc_buf(&iov, 512 * 4); 1136 _iov_alloc_buf(&md_iov, 8 * 4); 1137 1138 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); 1139 dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0); 1140 1141 _iov_free_buf(&iov); 1142 _iov_free_buf(&md_iov); 1143 } 1144 1145 static void 1146 dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void) 1147 { 1148 struct iovec iovs[4], md_iov; 1149 int i, num_blocks; 1150 1151 num_blocks = 0; 1152 1153 for (i = 0; i < 4; i++) { 1154 _iov_alloc_buf(&iovs[i], 512 * (i + 1)); 1155 num_blocks += i + 1; 1156 } 1157 _iov_alloc_buf(&md_iov, 8 * num_blocks); 1158 1159 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1160 0, 22, 0xFFFF, 0x22); 1161 1162 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1163 SPDK_DIF_FLAGS_GUARD_CHECK, 22, 0xFFFF, 0x22); 1164 1165 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1166 SPDK_DIF_FLAGS_APPTAG_CHECK, 22, 0xFFFF, 0x22); 1167 1168 dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, 1169 SPDK_DIF_FLAGS_REFTAG_CHECK, 22, 0xFFFF, 0x22); 1170 1171 for (i = 0; i < 4; i++) { 1172 _iov_free_buf(&iovs[i]); 1173 } 1174 _iov_free_buf(&md_iov); 1175 } 1176 1177 static void 1178 dix_sec_4096_md_128_prchk_7_multi_iovs(void) 1179 { 1180 struct iovec iovs[4], md_iov; 1181 uint32_t dif_flags; 1182 int i, num_blocks; 1183 1184 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1185 SPDK_DIF_FLAGS_REFTAG_CHECK; 1186 1187 num_blocks = 0; 1188 1189 for (i = 0; i < 4; i++) { 1190 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1191 num_blocks += i + 1; 1192 } 1193 _iov_alloc_buf(&md_iov, 128 * num_blocks); 1194 1195 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, 1196 dif_flags, 22, 0xFFFF, 0x22); 1197 dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, 1198 dif_flags, 22, 0xFFFF, 0x22); 1199 1200 for (i = 0; i < 4; i++) { 1201 _iov_free_buf(&iovs[i]); 1202 } 1203 _iov_free_buf(&md_iov); 1204 } 1205 1206 static void 1207 dix_sec_512_md_8_prchk_7_multi_iovs_split_data(void) 1208 { 1209 struct iovec iovs[2], md_iov; 1210 uint32_t dif_flags; 1211 1212 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1213 SPDK_DIF_FLAGS_REFTAG_CHECK; 1214 1215 _iov_alloc_buf(&iovs[0], 256); 1216 _iov_alloc_buf(&iovs[1], 256); 1217 _iov_alloc_buf(&md_iov, 8); 1218 1219 dix_generate_and_verify(iovs, 2, &md_iov, 512, 8, 1, false, SPDK_DIF_TYPE1, 1220 dif_flags, 22, 0xFFFF, 0x22); 1221 1222 _iov_free_buf(&iovs[0]); 1223 _iov_free_buf(&iovs[1]); 1224 _iov_free_buf(&md_iov); 1225 } 1226 1227 static void 1228 dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void) 1229 { 1230 struct iovec iovs[6], md_iov; 1231 uint32_t dif_flags; 1232 int i; 1233 1234 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1235 SPDK_DIF_FLAGS_REFTAG_CHECK; 1236 1237 /* data[0][255:0] */ 1238 _iov_alloc_buf(&iovs[0], 256); 1239 1240 /* data[0][511:256], data[1][255:0] */ 1241 _iov_alloc_buf(&iovs[1], 256 + 256); 1242 1243 /* data[1][382:256] */ 1244 _iov_alloc_buf(&iovs[2], 128); 1245 1246 /* data[1][383] */ 1247 _iov_alloc_buf(&iovs[3], 1); 1248 1249 /* data[1][510:384] */ 1250 _iov_alloc_buf(&iovs[4], 126); 1251 1252 /* data[1][511], data[2][511:0], data[3][511:0] */ 1253 _iov_alloc_buf(&iovs[5], 1 + 512 * 2); 1254 1255 _iov_alloc_buf(&md_iov, 8 * 4); 1256 1257 dix_generate_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 1258 dif_flags, 22, 0xFFFF, 0x22); 1259 1260 for (i = 0; i < 6; i++) { 1261 _iov_free_buf(&iovs[i]); 1262 } 1263 _iov_free_buf(&md_iov); 1264 } 1265 1266 static void 1267 _dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 1268 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 1269 uint32_t inject_flags, bool dif_loc) 1270 { 1271 struct spdk_dif_ctx ctx = {}; 1272 struct spdk_dif_error err_blk = {}; 1273 uint32_t inject_offset = 0, dif_flags; 1274 int rc; 1275 1276 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1277 SPDK_DIF_FLAGS_REFTAG_CHECK; 1278 1279 rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); 1280 CU_ASSERT(rc == 0); 1281 1282 rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, SPDK_DIF_TYPE1, dif_flags, 1283 88, 0xFFFF, 0x88, GUARD_SEED); 1284 CU_ASSERT(rc == 0); 1285 1286 rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); 1287 CU_ASSERT(rc == 0); 1288 1289 rc = spdk_dix_inject_error(iovs, iovcnt, md_iov, num_blocks, &ctx, inject_flags, &inject_offset); 1290 CU_ASSERT(rc == 0); 1291 1292 rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx, &err_blk); 1293 CU_ASSERT(rc != 0); 1294 1295 if (inject_flags == SPDK_DIF_DATA_ERROR) { 1296 CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type); 1297 } else { 1298 CU_ASSERT(inject_flags == err_blk.err_type); 1299 } 1300 CU_ASSERT(inject_offset == err_blk.err_offset); 1301 } 1302 1303 static void 1304 dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, 1305 uint32_t block_size, uint32_t md_size, uint32_t num_blocks, 1306 uint32_t inject_flags) 1307 { 1308 /* The case that DIF is contained in the first 8 bytes of metadata. */ 1309 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks, 1310 inject_flags, true); 1311 1312 /* The case that DIF is contained in the last 8 bytes of metadata. */ 1313 _dix_inject_error_and_verify(iovs, iovcnt, md_iov, block_size, md_size, num_blocks, 1314 inject_flags, false); 1315 } 1316 1317 static void 1318 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void) 1319 { 1320 struct iovec iovs[4], md_iov; 1321 int i, num_blocks; 1322 1323 num_blocks = 0; 1324 1325 for (i = 0; i < 4; i++) { 1326 _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); 1327 num_blocks += i + 1; 1328 } 1329 1330 _iov_alloc_buf(&md_iov, 128 * num_blocks); 1331 1332 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_GUARD_ERROR); 1333 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_APPTAG_ERROR); 1334 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_REFTAG_ERROR); 1335 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, SPDK_DIF_DATA_ERROR); 1336 1337 for (i = 0; i < 4; i++) { 1338 _iov_free_buf(&iovs[i]); 1339 } 1340 _iov_free_buf(&md_iov); 1341 } 1342 1343 static void 1344 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void) 1345 { 1346 struct iovec iovs[4], md_iov; 1347 int i; 1348 1349 _iov_alloc_buf(&iovs[0], 2048); 1350 _iov_alloc_buf(&iovs[1], 2048); 1351 _iov_alloc_buf(&iovs[2], 1); 1352 _iov_alloc_buf(&iovs[3], 4095); 1353 1354 _iov_alloc_buf(&md_iov, 128 * 2); 1355 1356 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_GUARD_ERROR); 1357 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_APPTAG_ERROR); 1358 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_REFTAG_ERROR); 1359 dix_inject_error_and_verify(iovs, 4, &md_iov, 4096, 128, 2, SPDK_DIF_DATA_ERROR); 1360 1361 for (i = 0; i < 4; i++) { 1362 _iov_free_buf(&iovs[i]); 1363 } 1364 _iov_free_buf(&md_iov); 1365 } 1366 1367 static int 1368 ut_readv(uint32_t read_base, uint32_t read_len, struct iovec *iovs, int iovcnt) 1369 { 1370 int i; 1371 uint32_t j, offset; 1372 uint8_t *buf; 1373 1374 offset = 0; 1375 for (i = 0; i < iovcnt; i++) { 1376 buf = iovs[i].iov_base; 1377 for (j = 0; j < iovs[i].iov_len; j++, offset++) { 1378 if (offset >= read_len) { 1379 return offset; 1380 } 1381 buf[j] = DATA_PATTERN(read_base + offset); 1382 } 1383 } 1384 1385 return offset; 1386 } 1387 1388 static void 1389 set_md_interleave_iovs_test(void) 1390 { 1391 struct spdk_dif_ctx ctx = {}; 1392 struct spdk_dif_error err_blk = {}; 1393 struct iovec iov1, iov2, dif_iovs[4]; 1394 uint32_t dif_check_flags, mapped_len = 0, read_base = 0; 1395 uint8_t *buf1, *buf2; 1396 int rc; 1397 1398 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1399 SPDK_DIF_FLAGS_REFTAG_CHECK; 1400 1401 rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, 1402 dif_check_flags, 22, 0xFFFF, 0x22, GUARD_SEED); 1403 CU_ASSERT(rc == 0); 1404 1405 /* The first data buffer: 1406 * - Create iovec array to Leave a space for metadata for each block 1407 * - Split vectored read and so creating iovec array is done before every vectored read. 1408 */ 1409 buf1 = calloc(1, (4096 + 128) * 4); 1410 SPDK_CU_ASSERT_FATAL(buf1 != NULL); 1411 _iov_set_buf(&iov1, buf1, (4096 + 128) * 4); 1412 1413 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1414 0, 4096 * 4, &mapped_len, &ctx); 1415 CU_ASSERT(rc == 4); 1416 CU_ASSERT(mapped_len == 4096 * 4); 1417 CU_ASSERT(_iov_check(&dif_iovs[0], buf1, 4096) == true); 1418 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1419 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1420 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 1421 1422 read_base = ut_readv(0, 1024, dif_iovs, 4); 1423 CU_ASSERT(read_base == 1024); 1424 1425 rc = spdk_dif_generate_stream(&iov1, 1, 0, 1024, &ctx); 1426 CU_ASSERT(rc == 0); 1427 1428 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1429 read_base, 4096 * 4, &mapped_len, &ctx); 1430 CU_ASSERT(rc == 4); 1431 CU_ASSERT(mapped_len == 3072 + 4096 * 3); 1432 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 1024, 3072) == true); 1433 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1434 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1435 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 1436 1437 read_base += ut_readv(read_base, 3071, dif_iovs, 4); 1438 CU_ASSERT(read_base == 4095); 1439 1440 rc = spdk_dif_generate_stream(&iov1, 1, 1024, 3071, &ctx); 1441 CU_ASSERT(rc == 0); 1442 1443 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1444 read_base, 4096 * 4, &mapped_len, &ctx); 1445 CU_ASSERT(rc == 4); 1446 CU_ASSERT(mapped_len == 1 + 4096 * 3); 1447 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + 4095, 1) == true); 1448 CU_ASSERT(_iov_check(&dif_iovs[1], buf1 + 4096 + 128, 4096) == true); 1449 CU_ASSERT(_iov_check(&dif_iovs[2], buf1 + (4096 + 128) * 2, 4096) == true); 1450 CU_ASSERT(_iov_check(&dif_iovs[3], buf1 + (4096 + 128) * 3, 4096) == true); 1451 1452 read_base += ut_readv(read_base, 1 + 4096 * 2 + 512, dif_iovs, 4); 1453 CU_ASSERT(read_base == 4096 * 3 + 512); 1454 1455 rc = spdk_dif_generate_stream(&iov1, 1, 4095, 1 + 4096 * 2 + 512, &ctx); 1456 CU_ASSERT(rc == 0); 1457 1458 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1, 1459 read_base, 4096 * 4, &mapped_len, &ctx); 1460 CU_ASSERT(rc == 1); 1461 CU_ASSERT(mapped_len == 3584); 1462 CU_ASSERT(_iov_check(&dif_iovs[0], buf1 + (4096 + 128) * 3 + 512, 3584) == true); 1463 1464 read_base += ut_readv(read_base, 3584, dif_iovs, 1); 1465 CU_ASSERT(read_base == 4096 * 4); 1466 1467 rc = spdk_dif_generate_stream(&iov1, 1, 4096 * 3 + 512, 3584, &ctx); 1468 CU_ASSERT(rc == 0); 1469 1470 /* The second data buffer: 1471 * - Set data pattern with a space for metadata for each block. 1472 */ 1473 buf2 = calloc(1, (4096 + 128) * 4); 1474 SPDK_CU_ASSERT_FATAL(buf2 != NULL); 1475 _iov_set_buf(&iov2, buf2, (4096 + 128) * 4); 1476 1477 rc = ut_data_pattern_generate(&iov2, 1, 4096 + 128, 128, 4); 1478 CU_ASSERT(rc == 0); 1479 rc = spdk_dif_generate(&iov2, 1, 4, &ctx); 1480 CU_ASSERT(rc == 0); 1481 1482 rc = spdk_dif_verify(&iov1, 1, 4, &ctx, &err_blk); 1483 CU_ASSERT(rc == 0); 1484 1485 rc = spdk_dif_verify(&iov2, 1, 4, &ctx, &err_blk); 1486 CU_ASSERT(rc == 0); 1487 1488 /* Compare the first and the second data buffer by byte. */ 1489 rc = memcmp(buf1, buf2, (4096 + 128) * 4); 1490 CU_ASSERT(rc == 0); 1491 1492 free(buf1); 1493 free(buf2); 1494 } 1495 1496 static void 1497 set_md_interleave_iovs_split_test(void) 1498 { 1499 struct spdk_dif_ctx ctx = {}; 1500 struct spdk_dif_error err_blk = {}; 1501 struct iovec iovs1[7], iovs2[7], dif_iovs[8]; 1502 uint32_t dif_check_flags, mapped_len = 0, read_base = 0; 1503 int rc, i; 1504 1505 dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1506 SPDK_DIF_FLAGS_REFTAG_CHECK; 1507 1508 rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, 1509 dif_check_flags, 22, 0xFFFF, 0x22, GUARD_SEED); 1510 CU_ASSERT(rc == 0); 1511 1512 /* The first SGL data buffer: 1513 * - Create iovec array to leave a space for metadata for each block 1514 * - Split vectored read and so creating iovec array is done before every vectored read. 1515 */ 1516 _iov_alloc_buf(&iovs1[0], 512 + 8 + 128); 1517 _iov_alloc_buf(&iovs1[1], 128); 1518 _iov_alloc_buf(&iovs1[2], 256 + 8); 1519 _iov_alloc_buf(&iovs1[3], 100); 1520 _iov_alloc_buf(&iovs1[4], 412 + 5); 1521 _iov_alloc_buf(&iovs1[5], 3 + 300); 1522 _iov_alloc_buf(&iovs1[6], 212 + 8); 1523 1524 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1525 0, 512 * 4, &mapped_len, &ctx); 1526 CU_ASSERT(rc == 8); 1527 CU_ASSERT(mapped_len == 512 * 4); 1528 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base, 512) == true); 1529 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 1530 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 1531 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 1532 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 1533 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 1534 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 1535 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 1536 1537 read_base = ut_readv(0, 128, dif_iovs, 8); 1538 CU_ASSERT(read_base == 128); 1539 1540 rc = spdk_dif_generate_stream(iovs1, 7, 0, 128, &ctx); 1541 CU_ASSERT(rc == 0); 1542 1543 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1544 read_base, 512 * 4, &mapped_len, &ctx); 1545 CU_ASSERT(rc == 8); 1546 CU_ASSERT(mapped_len == 384 + 512 * 3); 1547 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 128, 384) == true); 1548 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 1549 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 1550 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 1551 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 1552 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 1553 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 1554 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 1555 1556 read_base += ut_readv(read_base, 383, dif_iovs, 8); 1557 CU_ASSERT(read_base == 511); 1558 1559 rc = spdk_dif_generate_stream(iovs1, 7, 128, 383, &ctx); 1560 CU_ASSERT(rc == 0); 1561 1562 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1563 read_base, 512 * 4, &mapped_len, &ctx); 1564 CU_ASSERT(rc == 8); 1565 CU_ASSERT(mapped_len == 1 + 512 * 3); 1566 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 511, 1) == true); 1567 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true); 1568 CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true); 1569 CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true); 1570 CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true); 1571 CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true); 1572 CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true); 1573 CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true); 1574 1575 read_base += ut_readv(read_base, 1 + 512 * 2 + 128, dif_iovs, 8); 1576 CU_ASSERT(read_base == 512 * 3 + 128); 1577 1578 rc = spdk_dif_generate_stream(iovs1, 7, 383, 1 + 512 * 2 + 128, &ctx); 1579 CU_ASSERT(rc == 0); 1580 1581 rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7, 1582 read_base, 512 * 4, &mapped_len, &ctx); 1583 CU_ASSERT(rc == 2); 1584 CU_ASSERT(mapped_len == 384); 1585 CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[5].iov_base + 3 + 128, 172) == true); 1586 CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[6].iov_base, 212) == true); 1587 1588 read_base += ut_readv(read_base, 384, dif_iovs, 8); 1589 CU_ASSERT(read_base == 512 * 4); 1590 1591 rc = spdk_dif_generate_stream(iovs1, 7, 512 * 3 + 128, 384, &ctx); 1592 CU_ASSERT(rc == 0); 1593 1594 /* The second SGL data buffer: 1595 * - Set data pattern with a space for metadata for each block. 1596 */ 1597 _iov_alloc_buf(&iovs2[0], 512 + 8 + 128); 1598 _iov_alloc_buf(&iovs2[1], 128); 1599 _iov_alloc_buf(&iovs2[2], 256 + 8); 1600 _iov_alloc_buf(&iovs2[3], 100); 1601 _iov_alloc_buf(&iovs2[4], 412 + 5); 1602 _iov_alloc_buf(&iovs2[5], 3 + 300); 1603 _iov_alloc_buf(&iovs2[6], 212 + 8); 1604 1605 rc = ut_data_pattern_generate(iovs2, 7, 512 + 8, 8, 4); 1606 CU_ASSERT(rc == 0); 1607 rc = spdk_dif_generate(iovs2, 7, 4, &ctx); 1608 CU_ASSERT(rc == 0); 1609 1610 rc = spdk_dif_verify(iovs1, 7, 4, &ctx, &err_blk); 1611 CU_ASSERT(rc == 0); 1612 1613 rc = spdk_dif_verify(iovs2, 7, 4, &ctx, &err_blk); 1614 CU_ASSERT(rc == 0); 1615 1616 /* Compare the first and the second SGL data buffer by byte. */ 1617 for (i = 0; i < 7; i++) { 1618 rc = memcmp(iovs1[i].iov_base, iovs2[i].iov_base, 1619 iovs1[i].iov_len); 1620 CU_ASSERT(rc == 0); 1621 } 1622 1623 for (i = 0; i < 7; i++) { 1624 _iov_free_buf(&iovs1[i]); 1625 _iov_free_buf(&iovs2[i]); 1626 } 1627 } 1628 1629 static void 1630 dif_generate_stream_test(void) 1631 { 1632 struct iovec iov; 1633 struct spdk_dif_ctx ctx; 1634 struct spdk_dif_error err_blk; 1635 uint32_t dif_flags; 1636 int rc; 1637 1638 _iov_alloc_buf(&iov, (512 + 8) * 5); 1639 1640 rc = ut_data_pattern_generate(&iov, 1, 512, 8, 5); 1641 CU_ASSERT(rc == 0); 1642 1643 dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | 1644 SPDK_DIF_FLAGS_REFTAG_CHECK; 1645 1646 rc = spdk_dif_ctx_init(&ctx, 512, 8, true, false, SPDK_DIF_TYPE1, dif_flags, 1647 22, 0xFFFF, 0x22, GUARD_SEED); 1648 CU_ASSERT(rc == 0); 1649 1650 rc = spdk_dif_generate_stream(&iov, 1, 0, 511, &ctx); 1651 CU_ASSERT(rc == 0); 1652 1653 rc = spdk_dif_generate_stream(&iov, 1, 511, 1, &ctx); 1654 CU_ASSERT(rc == 0); 1655 1656 rc = spdk_dif_generate_stream(&iov, 1, 512, 256, &ctx); 1657 CU_ASSERT(rc == 0); 1658 1659 rc = spdk_dif_generate_stream(&iov, 1, 768, 512, &ctx); 1660 CU_ASSERT(rc == 0); 1661 1662 rc = spdk_dif_generate_stream(&iov, 1, 1280, 1024, &ctx); 1663 CU_ASSERT(rc == 0); 1664 1665 rc = spdk_dif_generate_stream(&iov, 1, 2304, 256, &ctx); 1666 CU_ASSERT(rc == 0); 1667 1668 rc = spdk_dif_generate_stream(&iov, 1, 2560, 512, &ctx); 1669 CU_ASSERT(rc == -ERANGE); 1670 1671 rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk); 1672 CU_ASSERT(rc == 0); 1673 1674 rc = ut_data_pattern_verify(&iov, 1, 512, 8, 5); 1675 CU_ASSERT(rc == 0); 1676 1677 _iov_free_buf(&iov); 1678 } 1679 1680 int 1681 main(int argc, char **argv) 1682 { 1683 CU_pSuite suite = NULL; 1684 unsigned int num_failures; 1685 1686 if (CU_initialize_registry() != CUE_SUCCESS) { 1687 return CU_get_error(); 1688 } 1689 1690 suite = CU_add_suite("dif", NULL, NULL); 1691 if (suite == NULL) { 1692 CU_cleanup_registry(); 1693 return CU_get_error(); 1694 } 1695 1696 if ( 1697 CU_add_test(suite, "dif_generate_and_verify_test", dif_generate_and_verify_test) == NULL || 1698 CU_add_test(suite, "dif_disable_check_test", dif_disable_check_test) == NULL || 1699 CU_add_test(suite, "dif_sec_512_md_0_error_test", dif_sec_512_md_0_error_test) == NULL || 1700 CU_add_test(suite, "dif_guard_seed_test", dif_guard_seed_test) == NULL || 1701 CU_add_test(suite, "dif_disable_sec_512_md_8_single_iov_test", 1702 dif_disable_sec_512_md_8_single_iov_test) == NULL || 1703 CU_add_test(suite, "dif_sec_512_md_8_prchk_0_single_iov_test", 1704 dif_sec_512_md_8_prchk_0_single_iov_test) == NULL || 1705 CU_add_test(suite, "dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test", 1706 dif_sec_512_md_8_prchk_0_1_2_4_multi_iovs_test) == NULL || 1707 CU_add_test(suite, "dif_sec_4096_md_128_prchk_7_multi_iovs_test", 1708 dif_sec_4096_md_128_prchk_7_multi_iovs_test) == NULL || 1709 CU_add_test(suite, "dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test", 1710 dif_sec_512_md_8_prchk_7_multi_iovs_split_data_and_md_test) == NULL || 1711 CU_add_test(suite, "dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test", 1712 dif_sec_512_md_8_prchk_7_multi_iovs_split_data_test) == NULL || 1713 CU_add_test(suite, "dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test", 1714 dif_sec_512_md_8_prchk_7_multi_iovs_split_guard_test) == NULL || 1715 CU_add_test(suite, "dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test", 1716 dif_sec_512_md_8_prchk_7_multi_iovs_split_apptag_test) == NULL || 1717 CU_add_test(suite, "dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test", 1718 dif_sec_512_md_8_prchk_7_multi_iovs_split_reftag_test) == NULL || 1719 CU_add_test(suite, "dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test", 1720 dif_sec_512_md_8_prchk_7_multi_iovs_complex_splits_test) == NULL || 1721 CU_add_test(suite, "dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test", 1722 dif_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_test) == NULL || 1723 CU_add_test(suite, "dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test", 1724 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test) == NULL || 1725 CU_add_test(suite, "dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test", 1726 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_and_md_test) == NULL || 1727 CU_add_test(suite, "dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test", 1728 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_data_test) == NULL || 1729 CU_add_test(suite, "dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test", 1730 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_guard_test) == NULL || 1731 CU_add_test(suite, "dif_sec_4096_md_128_inject_1_2_4_8__multi_iovs_split_apptag_test", 1732 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_apptag_test) == NULL || 1733 CU_add_test(suite, "dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test", 1734 dif_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_reftag_test) == NULL || 1735 CU_add_test(suite, "dif_copy_sec_512_md_8_prchk_0_single_iov", 1736 dif_copy_sec_512_md_8_prchk_0_single_iov) == NULL || 1737 CU_add_test(suite, "dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs", 1738 dif_copy_sec_512_md_8_prchk_0_1_2_4_multi_iovs) == NULL || 1739 CU_add_test(suite, "dif_copy_sec_4096_md_128_prchk_7_multi_iovs", 1740 dif_copy_sec_4096_md_128_prchk_7_multi_iovs) == NULL || 1741 CU_add_test(suite, "dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data", 1742 dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data) == NULL || 1743 CU_add_test(suite, "dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits", 1744 dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits) == NULL || 1745 CU_add_test(suite, "dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test", 1746 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test) == NULL || 1747 CU_add_test(suite, "dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test", 1748 dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test) == NULL || 1749 CU_add_test(suite, "dix_sec_512_md_0_error", dix_sec_512_md_0_error) == NULL || 1750 CU_add_test(suite, "dix_sec_512_md_8_prchk_0_single_iov", 1751 dix_sec_512_md_8_prchk_0_single_iov) == NULL || 1752 CU_add_test(suite, "dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs", 1753 dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs) == NULL || 1754 CU_add_test(suite, "dix_sec_4096_md_128_prchk_7_multi_iovs", 1755 dix_sec_4096_md_128_prchk_7_multi_iovs) == NULL || 1756 CU_add_test(suite, "dix_sec_512_md_8_prchk_7_multi_iovs_split_data", 1757 dix_sec_512_md_8_prchk_7_multi_iovs_split_data) == NULL || 1758 CU_add_test(suite, "dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits", 1759 dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits) == NULL || 1760 CU_add_test(suite, "dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test", 1761 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test) == NULL || 1762 CU_add_test(suite, "dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test", 1763 dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test) == NULL || 1764 CU_add_test(suite, "set_md_interleave_iovs_test", set_md_interleave_iovs_test) == NULL || 1765 CU_add_test(suite, "set_md_interleave_iovs_split_test", 1766 set_md_interleave_iovs_split_test) == NULL || 1767 CU_add_test(suite, "dif_generate_stream_test", dif_generate_stream_test) == NULL 1768 ) { 1769 CU_cleanup_registry(); 1770 return CU_get_error(); 1771 } 1772 1773 CU_basic_set_mode(CU_BRM_VERBOSE); 1774 1775 CU_basic_run_tests(); 1776 1777 num_failures = CU_get_number_of_failures(); 1778 CU_cleanup_registry(); 1779 1780 return num_failures; 1781 } 1782