test_suite_bignum_core.function (43216B)
1 /* BEGIN_HEADER */ 2 #include "mbedtls/bignum.h" 3 #include "mbedtls/entropy.h" 4 #include "bignum_core.h" 5 #include "constant_time_internal.h" 6 #include "test/constant_flow.h" 7 #include "test/bignum_codepath_check.h" 8 9 /** Verifies mbedtls_mpi_core_add(). 10 * 11 * \param[in] A Little-endian presentation of the left operand. 12 * \param[in] B Little-endian presentation of the right operand. 13 * \param limbs Number of limbs in each MPI (\p A, \p B, \p S and \p X). 14 * \param[in] S Little-endian presentation of the expected sum. 15 * \param carry Expected carry from the addition. 16 * \param[in,out] X Temporary storage to be used for results. 17 * 18 * \return 1 if mbedtls_mpi_core_add() passes this test, otherwise 0. 19 */ 20 static int mpi_core_verify_add(mbedtls_mpi_uint *A, 21 mbedtls_mpi_uint *B, 22 size_t limbs, 23 mbedtls_mpi_uint *S, 24 int carry, 25 mbedtls_mpi_uint *X) 26 { 27 int ret = 0; 28 29 size_t bytes = limbs * sizeof(*A); 30 31 /* The test cases have A <= B to avoid repetition, so we test A + B then, 32 * if A != B, B + A. If A == B, we can test when A and B are aliased */ 33 34 /* A + B */ 35 36 /* A + B => correct result and carry */ 37 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, A, B, limbs)); 38 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 39 40 /* A + B; alias output and first operand => correct result and carry */ 41 memcpy(X, A, bytes); 42 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, X, B, limbs)); 43 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 44 45 /* A + B; alias output and second operand => correct result and carry */ 46 memcpy(X, B, bytes); 47 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, A, X, limbs)); 48 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 49 50 if (memcmp(A, B, bytes) == 0) { 51 /* A == B, so test where A and B are aliased */ 52 53 /* A + A => correct result and carry */ 54 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, A, A, limbs)); 55 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 56 57 /* A + A, output aliased to both operands => correct result and carry */ 58 memcpy(X, A, bytes); 59 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, X, X, limbs)); 60 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 61 } else { 62 /* A != B, so test B + A */ 63 64 /* B + A => correct result and carry */ 65 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, B, A, limbs)); 66 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 67 68 /* B + A; alias output and first operand => correct result and carry */ 69 memcpy(X, B, bytes); 70 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, X, A, limbs)); 71 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 72 73 /* B + A; alias output and second operand => correct result and carry */ 74 memcpy(X, A, bytes); 75 TEST_EQUAL(carry, mbedtls_mpi_core_add(X, B, X, limbs)); 76 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 77 } 78 79 ret = 1; 80 81 exit: 82 return ret; 83 } 84 85 /** Verifies mbedtls_mpi_core_add_if(). 86 * 87 * \param[in] A Little-endian presentation of the left operand. 88 * \param[in] B Little-endian presentation of the right operand. 89 * \param limbs Number of limbs in each MPI (\p A, \p B, \p S and \p X). 90 * \param[in] S Little-endian presentation of the expected sum. 91 * \param carry Expected carry from the addition. 92 * \param[in,out] X Temporary storage to be used for results. 93 * 94 * \return 1 if mbedtls_mpi_core_add_if() passes this test, otherwise 0. 95 */ 96 static int mpi_core_verify_add_if(mbedtls_mpi_uint *A, 97 mbedtls_mpi_uint *B, 98 size_t limbs, 99 mbedtls_mpi_uint *S, 100 int carry, 101 mbedtls_mpi_uint *X) 102 { 103 int ret = 0; 104 105 size_t bytes = limbs * sizeof(*A); 106 107 /* The test cases have A <= B to avoid repetition, so we test A + B then, 108 * if A != B, B + A. If A == B, we can test when A and B are aliased */ 109 110 /* A + B */ 111 112 /* cond = 0 => X unchanged, no carry */ 113 memcpy(X, A, bytes); 114 TEST_EQUAL(0, mbedtls_mpi_core_add_if(X, B, limbs, 0)); 115 TEST_MEMORY_COMPARE(X, bytes, A, bytes); 116 117 /* cond = 1 => correct result and carry */ 118 TEST_EQUAL(carry, mbedtls_mpi_core_add_if(X, B, limbs, 1)); 119 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 120 121 if (memcmp(A, B, bytes) == 0) { 122 /* A == B, so test where A and B are aliased */ 123 124 /* cond = 0 => X unchanged, no carry */ 125 memcpy(X, B, bytes); 126 TEST_EQUAL(0, mbedtls_mpi_core_add_if(X, X, limbs, 0)); 127 TEST_MEMORY_COMPARE(X, bytes, B, bytes); 128 129 /* cond = 1 => correct result and carry */ 130 TEST_EQUAL(carry, mbedtls_mpi_core_add_if(X, X, limbs, 1)); 131 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 132 } else { 133 /* A != B, so test B + A */ 134 135 /* cond = 0 => d unchanged, no carry */ 136 memcpy(X, B, bytes); 137 TEST_EQUAL(0, mbedtls_mpi_core_add_if(X, A, limbs, 0)); 138 TEST_MEMORY_COMPARE(X, bytes, B, bytes); 139 140 /* cond = 1 => correct result and carry */ 141 TEST_EQUAL(carry, mbedtls_mpi_core_add_if(X, A, limbs, 1)); 142 TEST_MEMORY_COMPARE(X, bytes, S, bytes); 143 } 144 145 ret = 1; 146 147 exit: 148 return ret; 149 } 150 151 /* END_HEADER */ 152 153 /* BEGIN_DEPENDENCIES 154 * depends_on:MBEDTLS_BIGNUM_C 155 * END_DEPENDENCIES 156 */ 157 158 /* BEGIN_CASE */ 159 void mpi_core_io_null() 160 { 161 mbedtls_mpi_uint X = 0; 162 int ret; 163 164 ret = mbedtls_mpi_core_read_be(&X, 1, NULL, 0); 165 TEST_EQUAL(ret, 0); 166 ret = mbedtls_mpi_core_write_be(&X, 1, NULL, 0); 167 TEST_EQUAL(ret, 0); 168 169 ret = mbedtls_mpi_core_read_be(NULL, 0, NULL, 0); 170 TEST_EQUAL(ret, 0); 171 ret = mbedtls_mpi_core_write_be(NULL, 0, NULL, 0); 172 TEST_EQUAL(ret, 0); 173 174 ret = mbedtls_mpi_core_read_le(&X, 1, NULL, 0); 175 TEST_EQUAL(ret, 0); 176 ret = mbedtls_mpi_core_write_le(&X, 1, NULL, 0); 177 TEST_EQUAL(ret, 0); 178 179 ret = mbedtls_mpi_core_read_le(NULL, 0, NULL, 0); 180 TEST_EQUAL(ret, 0); 181 ret = mbedtls_mpi_core_write_le(NULL, 0, NULL, 0); 182 TEST_EQUAL(ret, 0); 183 184 exit: 185 ; 186 } 187 /* END_CASE */ 188 189 /* BEGIN_CASE */ 190 void mpi_core_io_be(data_t *input, int nb_int, int nx_32_int, int iret, 191 int oret) 192 { 193 if (iret != 0) { 194 TEST_ASSERT(oret == 0); 195 } 196 197 TEST_LE_S(0, nb_int); 198 size_t nb = nb_int; 199 200 unsigned char buf[1024]; 201 TEST_LE_U(nb, sizeof(buf)); 202 203 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need 204 * to halve the number of limbs to have the same size. */ 205 size_t nx; 206 TEST_LE_S(0, nx_32_int); 207 if (sizeof(mbedtls_mpi_uint) == 8) { 208 nx = nx_32_int / 2 + nx_32_int % 2; 209 } else { 210 nx = nx_32_int; 211 } 212 213 mbedtls_mpi_uint X[sizeof(buf) / sizeof(mbedtls_mpi_uint)]; 214 TEST_LE_U(nx, sizeof(X) / sizeof(X[0])); 215 216 int ret = mbedtls_mpi_core_read_be(X, nx, input->x, input->len); 217 TEST_EQUAL(ret, iret); 218 219 if (iret == 0) { 220 ret = mbedtls_mpi_core_write_be(X, nx, buf, nb); 221 TEST_EQUAL(ret, oret); 222 } 223 224 if ((iret == 0) && (oret == 0)) { 225 if (nb > input->len) { 226 size_t leading_zeroes = nb - input->len; 227 TEST_ASSERT(memcmp(buf + nb - input->len, input->x, input->len) == 0); 228 for (size_t i = 0; i < leading_zeroes; i++) { 229 TEST_EQUAL(buf[i], 0); 230 } 231 } else { 232 size_t leading_zeroes = input->len - nb; 233 TEST_ASSERT(memcmp(input->x + input->len - nb, buf, nb) == 0); 234 for (size_t i = 0; i < leading_zeroes; i++) { 235 TEST_EQUAL(input->x[i], 0); 236 } 237 } 238 } 239 240 exit: 241 ; 242 } 243 /* END_CASE */ 244 245 /* BEGIN_CASE */ 246 void mpi_core_io_le(data_t *input, int nb_int, int nx_32_int, int iret, 247 int oret) 248 { 249 if (iret != 0) { 250 TEST_ASSERT(oret == 0); 251 } 252 253 TEST_LE_S(0, nb_int); 254 size_t nb = nb_int; 255 256 unsigned char buf[1024]; 257 TEST_LE_U(nb, sizeof(buf)); 258 259 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need 260 * to halve the number of limbs to have the same size. */ 261 size_t nx; 262 TEST_LE_S(0, nx_32_int); 263 if (sizeof(mbedtls_mpi_uint) == 8) { 264 nx = nx_32_int / 2 + nx_32_int % 2; 265 } else { 266 nx = nx_32_int; 267 } 268 269 mbedtls_mpi_uint X[sizeof(buf) / sizeof(mbedtls_mpi_uint)]; 270 TEST_LE_U(nx, sizeof(X) / sizeof(X[0])); 271 272 int ret = mbedtls_mpi_core_read_le(X, nx, input->x, input->len); 273 TEST_EQUAL(ret, iret); 274 275 if (iret == 0) { 276 ret = mbedtls_mpi_core_write_le(X, nx, buf, nb); 277 TEST_EQUAL(ret, oret); 278 } 279 280 if ((iret == 0) && (oret == 0)) { 281 if (nb > input->len) { 282 TEST_ASSERT(memcmp(buf, input->x, input->len) == 0); 283 for (size_t i = input->len; i < nb; i++) { 284 TEST_EQUAL(buf[i], 0); 285 } 286 } else { 287 TEST_ASSERT(memcmp(input->x, buf, nb) == 0); 288 for (size_t i = nb; i < input->len; i++) { 289 TEST_EQUAL(input->x[i], 0); 290 } 291 } 292 } 293 294 exit: 295 ; 296 } 297 /* END_CASE */ 298 299 /* BEGIN_CASE */ 300 void mpi_core_bitlen(char *input_X, int nr_bits) 301 { 302 mbedtls_mpi_uint *X = NULL; 303 size_t limbs; 304 305 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs, input_X), 0); 306 TEST_EQUAL(mbedtls_mpi_core_bitlen(X, limbs), nr_bits); 307 308 exit: 309 mbedtls_free(X); 310 } 311 /* END_CASE */ 312 313 314 /* BEGIN_CASE */ 315 void mpi_core_clz(int leading_zeros, int trailing_zeros) 316 { 317 if ((size_t) (leading_zeros + trailing_zeros) >= (sizeof(mbedtls_mpi_uint) * 8)) { 318 // can't fit required number of leading and trailing zeros - skip test 319 goto exit; 320 } 321 322 // Construct a test input value where the count of leading zeros and 323 // trailing zeros is given in the test case, and we add ones to fill 324 // the gap. 325 mbedtls_mpi_uint x; 326 if ((leading_zeros + trailing_zeros) > 0) { 327 // some zero bits 328 uint32_t s = (sizeof(mbedtls_mpi_uint) * 8 - leading_zeros - trailing_zeros); 329 x = ((((mbedtls_mpi_uint) 1) << s) - 1) << trailing_zeros; 330 } else { 331 // all bits set 332 x = ~((mbedtls_mpi_uint) 0); 333 } 334 335 size_t n = mbedtls_mpi_core_clz(x); 336 TEST_EQUAL(n, leading_zeros); 337 exit: 338 ; 339 } 340 /* END_CASE */ 341 342 343 /* BEGIN_CASE */ 344 void mpi_core_lt_ct(char *input_X, char *input_Y, int exp_ret) 345 { 346 mbedtls_mpi_uint *X = NULL; 347 size_t X_limbs; 348 mbedtls_mpi_uint *Y = NULL; 349 size_t Y_limbs; 350 int ret; 351 352 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X)); 353 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&Y, &Y_limbs, input_Y)); 354 355 /* We need two same-length limb arrays */ 356 TEST_EQUAL(X_limbs, Y_limbs); 357 358 TEST_CF_SECRET(X, X_limbs * sizeof(mbedtls_mpi_uint)); 359 TEST_CF_SECRET(Y, X_limbs * sizeof(mbedtls_mpi_uint)); 360 361 ret = mbedtls_mpi_core_lt_ct(X, Y, X_limbs); 362 TEST_EQUAL(!!ret, exp_ret); 363 364 exit: 365 mbedtls_free(X); 366 mbedtls_free(Y); 367 } 368 /* END_CASE */ 369 370 /* BEGIN_CASE */ 371 void mpi_core_uint_le_mpi(char *input_A) 372 { 373 mbedtls_mpi_uint *A = NULL; 374 size_t A_limbs = 0; 375 376 TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &A_limbs, input_A), 0); 377 378 int is_large = 0; /* nonzero limbs beyond the lowest-order one? */ 379 for (size_t i = 1; i < A_limbs; i++) { 380 if (A[i] != 0) { 381 is_large = 1; 382 break; 383 } 384 } 385 386 TEST_CF_SECRET(A, A_limbs * sizeof(*A)); 387 388 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(0, A, A_limbs), 1); 389 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(A[0], A, A_limbs), 1); 390 391 if (is_large) { 392 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(A[0] + 1, 393 A, A_limbs), 1); 394 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1) >> 1, 395 A, A_limbs), 1); 396 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1), 397 A, A_limbs), 1); 398 } else { 399 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(A[0] + 1, 400 A, A_limbs), 401 A[0] + 1 <= A[0]); 402 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1) >> 1, 403 A, A_limbs), 404 (mbedtls_mpi_uint) (-1) >> 1 <= A[0]); 405 TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1), 406 A, A_limbs), 407 (mbedtls_mpi_uint) (-1) <= A[0]); 408 } 409 410 exit: 411 mbedtls_free(A); 412 } 413 /* END_CASE */ 414 415 /* BEGIN_CASE */ 416 void mpi_core_cond_assign(char *input_X, 417 char *input_Y, 418 int input_bytes) 419 { 420 mbedtls_mpi_uint *X = NULL; 421 mbedtls_mpi_uint *Y = NULL; 422 size_t limbs_X; 423 size_t limbs_Y; 424 425 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0); 426 TEST_EQUAL(mbedtls_test_read_mpi_core(&Y, &limbs_Y, input_Y), 0); 427 428 size_t limbs = limbs_X; 429 size_t copy_limbs = CHARS_TO_LIMBS(input_bytes); 430 size_t bytes = limbs * sizeof(mbedtls_mpi_uint); 431 size_t copy_bytes = copy_limbs * sizeof(mbedtls_mpi_uint); 432 433 TEST_EQUAL(limbs_X, limbs_Y); 434 TEST_ASSERT(copy_limbs <= limbs); 435 436 /* condition is false */ 437 TEST_CF_SECRET(X, bytes); 438 TEST_CF_SECRET(Y, bytes); 439 440 mbedtls_mpi_core_cond_assign(X, Y, copy_limbs, 0); 441 442 TEST_CF_PUBLIC(X, bytes); 443 TEST_CF_PUBLIC(Y, bytes); 444 445 TEST_ASSERT(memcmp(X, Y, bytes) != 0); 446 447 /* condition is true */ 448 TEST_CF_SECRET(X, bytes); 449 TEST_CF_SECRET(Y, bytes); 450 451 mbedtls_mpi_core_cond_assign(X, Y, copy_limbs, mbedtls_ct_bool(1)); 452 453 TEST_CF_PUBLIC(X, bytes); 454 TEST_CF_PUBLIC(Y, bytes); 455 456 /* Check if the given length is copied even it is smaller 457 than the length of the given MPIs. */ 458 if (copy_limbs < limbs) { 459 TEST_CF_PUBLIC(X, bytes); 460 TEST_CF_PUBLIC(Y, bytes); 461 462 TEST_MEMORY_COMPARE(X, copy_bytes, Y, copy_bytes); 463 TEST_ASSERT(memcmp(X, Y, bytes) != 0); 464 } else { 465 TEST_MEMORY_COMPARE(X, bytes, Y, bytes); 466 } 467 468 exit: 469 mbedtls_free(X); 470 mbedtls_free(Y); 471 } 472 /* END_CASE */ 473 474 /* BEGIN_CASE */ 475 void mpi_core_cond_swap(char *input_X, 476 char *input_Y, 477 int input_bytes) 478 { 479 mbedtls_mpi_uint *tmp_X = NULL; 480 mbedtls_mpi_uint *tmp_Y = NULL; 481 mbedtls_mpi_uint *X = NULL; 482 mbedtls_mpi_uint *Y = NULL; 483 size_t limbs_X; 484 size_t limbs_Y; 485 486 TEST_EQUAL(mbedtls_test_read_mpi_core(&tmp_X, &limbs_X, input_X), 0); 487 TEST_EQUAL(mbedtls_test_read_mpi_core(&tmp_Y, &limbs_Y, input_Y), 0); 488 489 size_t limbs = limbs_X; 490 size_t copy_limbs = CHARS_TO_LIMBS(input_bytes); 491 size_t bytes = limbs * sizeof(mbedtls_mpi_uint); 492 size_t copy_bytes = copy_limbs * sizeof(mbedtls_mpi_uint); 493 494 TEST_EQUAL(limbs_X, limbs_Y); 495 TEST_ASSERT(copy_limbs <= limbs); 496 497 TEST_CALLOC(X, limbs); 498 memcpy(X, tmp_X, bytes); 499 500 TEST_CALLOC(Y, limbs); 501 memcpy(Y, tmp_Y, bytes); 502 503 /* condition is false */ 504 TEST_CF_SECRET(X, bytes); 505 TEST_CF_SECRET(Y, bytes); 506 507 mbedtls_mpi_core_cond_swap(X, Y, copy_limbs, 0); 508 509 TEST_CF_PUBLIC(X, bytes); 510 TEST_CF_PUBLIC(Y, bytes); 511 512 TEST_MEMORY_COMPARE(X, bytes, tmp_X, bytes); 513 TEST_MEMORY_COMPARE(Y, bytes, tmp_Y, bytes); 514 515 /* condition is true */ 516 TEST_CF_SECRET(X, bytes); 517 TEST_CF_SECRET(Y, bytes); 518 519 mbedtls_mpi_core_cond_swap(X, Y, copy_limbs, mbedtls_ct_bool(1)); 520 521 TEST_CF_PUBLIC(X, bytes); 522 TEST_CF_PUBLIC(Y, bytes); 523 524 /* Check if the given length is copied even it is smaller 525 than the length of the given MPIs. */ 526 if (copy_limbs < limbs) { 527 TEST_MEMORY_COMPARE(X, copy_bytes, tmp_Y, copy_bytes); 528 TEST_MEMORY_COMPARE(Y, copy_bytes, tmp_X, copy_bytes); 529 TEST_ASSERT(memcmp(X, tmp_X, bytes) != 0); 530 TEST_ASSERT(memcmp(X, tmp_Y, bytes) != 0); 531 TEST_ASSERT(memcmp(Y, tmp_X, bytes) != 0); 532 TEST_ASSERT(memcmp(Y, tmp_Y, bytes) != 0); 533 } else { 534 TEST_MEMORY_COMPARE(X, bytes, tmp_Y, bytes); 535 TEST_MEMORY_COMPARE(Y, bytes, tmp_X, bytes); 536 } 537 538 exit: 539 mbedtls_free(tmp_X); 540 mbedtls_free(tmp_Y); 541 mbedtls_free(X); 542 mbedtls_free(Y); 543 } 544 /* END_CASE */ 545 546 /* BEGIN_CASE */ 547 void mpi_core_shift_r(char *input, int count, char *result) 548 { 549 mbedtls_mpi_uint *X = NULL; 550 mbedtls_mpi_uint *Y = NULL; 551 size_t limbs, n; 552 553 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &limbs, input)); 554 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&Y, &n, result)); 555 TEST_EQUAL(limbs, n); 556 557 mbedtls_mpi_core_shift_r(X, limbs, count); 558 TEST_MEMORY_COMPARE(X, limbs * ciL, Y, limbs * ciL); 559 560 exit: 561 mbedtls_free(X); 562 mbedtls_free(Y); 563 } 564 /* END_CASE */ 565 566 /* BEGIN_CASE */ 567 void mpi_core_shift_l(char *input, int count, char *result) 568 { 569 mbedtls_mpi_uint *X = NULL; 570 mbedtls_mpi_uint *Y = NULL; 571 size_t limbs, n; 572 573 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &limbs, input)); 574 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&Y, &n, result)); 575 TEST_EQUAL(limbs, n); 576 577 mbedtls_mpi_core_shift_l(X, limbs, count); 578 TEST_MEMORY_COMPARE(X, limbs * ciL, Y, limbs * ciL); 579 580 exit: 581 mbedtls_free(X); 582 mbedtls_free(Y); 583 } 584 /* END_CASE */ 585 586 /* BEGIN_CASE */ 587 void mpi_core_add_and_add_if(char *input_A, char *input_B, 588 char *input_S, int carry) 589 { 590 mbedtls_mpi_uint *A = NULL; /* first value to add */ 591 mbedtls_mpi_uint *B = NULL; /* second value to add */ 592 mbedtls_mpi_uint *S = NULL; /* expected result */ 593 mbedtls_mpi_uint *X = NULL; /* destination - the in/out first operand */ 594 size_t A_limbs, B_limbs, S_limbs; 595 596 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A)); 597 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&B, &B_limbs, input_B)); 598 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&S, &S_limbs, input_S)); 599 600 /* add and add_if expect all operands to be the same length */ 601 TEST_EQUAL(A_limbs, B_limbs); 602 TEST_EQUAL(A_limbs, S_limbs); 603 604 size_t limbs = A_limbs; 605 TEST_CALLOC(X, limbs); 606 607 TEST_ASSERT(mpi_core_verify_add(A, B, limbs, S, carry, X)); 608 TEST_ASSERT(mpi_core_verify_add_if(A, B, limbs, S, carry, X)); 609 610 exit: 611 mbedtls_free(A); 612 mbedtls_free(B); 613 mbedtls_free(S); 614 mbedtls_free(X); 615 } 616 /* END_CASE */ 617 618 /* BEGIN_CASE */ 619 void mpi_core_sub(char *input_A, char *input_B, 620 char *input_X, int carry) 621 { 622 mbedtls_mpi A, B, X; 623 mbedtls_mpi_uint *a = NULL; 624 mbedtls_mpi_uint *b = NULL; 625 mbedtls_mpi_uint *x = NULL; /* expected */ 626 mbedtls_mpi_uint *r = NULL; /* result */ 627 628 mbedtls_mpi_init(&A); 629 mbedtls_mpi_init(&B); 630 mbedtls_mpi_init(&X); 631 632 TEST_EQUAL(0, mbedtls_test_read_mpi(&A, input_A)); 633 TEST_EQUAL(0, mbedtls_test_read_mpi(&B, input_B)); 634 TEST_EQUAL(0, mbedtls_test_read_mpi(&X, input_X)); 635 636 /* All of the inputs are +ve (or zero) */ 637 TEST_EQUAL(1, A.s); 638 TEST_EQUAL(1, B.s); 639 TEST_EQUAL(1, X.s); 640 641 /* Get the number of limbs we will need */ 642 size_t limbs = MAX(A.n, B.n); 643 size_t bytes = limbs * sizeof(mbedtls_mpi_uint); 644 645 /* The result shouldn't have more limbs than the longest input */ 646 TEST_LE_U(X.n, limbs); 647 648 /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */ 649 650 /* TEST_CALLOC() uses calloc() under the hood, so these do get zeroed */ 651 TEST_CALLOC(a, bytes); 652 TEST_CALLOC(b, bytes); 653 TEST_CALLOC(x, bytes); 654 TEST_CALLOC(r, bytes); 655 656 /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as 657 * processed by mbedtls_mpi_core_sub()) are little endian, we can just 658 * copy what we have as long as MSBs are 0 (which they are from TEST_CALLOC()) 659 */ 660 memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint)); 661 memcpy(b, B.p, B.n * sizeof(mbedtls_mpi_uint)); 662 memcpy(x, X.p, X.n * sizeof(mbedtls_mpi_uint)); 663 664 /* 1a) r = a - b => we should get the correct carry */ 665 TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, a, b, limbs)); 666 667 /* 1b) r = a - b => we should get the correct result */ 668 TEST_MEMORY_COMPARE(r, bytes, x, bytes); 669 670 /* 2 and 3 test "r may be aliased to a or b" */ 671 /* 2a) r = a; r -= b => we should get the correct carry (use r to avoid clobbering a) */ 672 memcpy(r, a, bytes); 673 TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, r, b, limbs)); 674 675 /* 2b) r -= b => we should get the correct result */ 676 TEST_MEMORY_COMPARE(r, bytes, x, bytes); 677 678 /* 3a) r = b; r = a - r => we should get the correct carry (use r to avoid clobbering b) */ 679 memcpy(r, b, bytes); 680 TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, a, r, limbs)); 681 682 /* 3b) r = a - b => we should get the correct result */ 683 TEST_MEMORY_COMPARE(r, bytes, x, bytes); 684 685 /* 4 tests "r may be aliased to [...] both" */ 686 if (A.n == B.n && memcmp(A.p, B.p, bytes) == 0) { 687 memcpy(r, b, bytes); 688 TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, r, r, limbs)); 689 TEST_MEMORY_COMPARE(r, bytes, x, bytes); 690 } 691 692 exit: 693 mbedtls_free(a); 694 mbedtls_free(b); 695 mbedtls_free(x); 696 mbedtls_free(r); 697 698 mbedtls_mpi_free(&A); 699 mbedtls_mpi_free(&B); 700 mbedtls_mpi_free(&X); 701 } 702 /* END_CASE */ 703 704 /* BEGIN_CASE */ 705 void mpi_core_mla(char *input_A, char *input_B, char *input_S, 706 char *input_X4, char *input_cy4, 707 char *input_X8, char *input_cy8) 708 { 709 /* We are testing A += B * s; A, B are MPIs, s is a scalar. 710 * 711 * However, we encode s as an MPI in the .data file as the test framework 712 * currently only supports `int`-typed scalars, and that doesn't cover the 713 * full range of `mbedtls_mpi_uint`. 714 * 715 * We also have the different results for sizeof(mbedtls_mpi_uint) == 4 or 8. 716 */ 717 mbedtls_mpi A, B, S, X4, X8, cy4, cy8; 718 mbedtls_mpi_uint *a = NULL; 719 mbedtls_mpi_uint *x = NULL; 720 721 mbedtls_mpi_init(&A); 722 mbedtls_mpi_init(&B); 723 mbedtls_mpi_init(&S); 724 mbedtls_mpi_init(&X4); 725 mbedtls_mpi_init(&X8); 726 mbedtls_mpi_init(&cy4); 727 mbedtls_mpi_init(&cy8); 728 729 TEST_EQUAL(0, mbedtls_test_read_mpi(&A, input_A)); 730 TEST_EQUAL(0, mbedtls_test_read_mpi(&B, input_B)); 731 TEST_EQUAL(0, mbedtls_test_read_mpi(&S, input_S)); 732 TEST_EQUAL(0, mbedtls_test_read_mpi(&X4, input_X4)); 733 TEST_EQUAL(0, mbedtls_test_read_mpi(&cy4, input_cy4)); 734 TEST_EQUAL(0, mbedtls_test_read_mpi(&X8, input_X8)); 735 TEST_EQUAL(0, mbedtls_test_read_mpi(&cy8, input_cy8)); 736 737 /* The MPI encoding of scalar s must be only 1 limb */ 738 TEST_EQUAL(1, S.n); 739 740 /* We only need to work with X4 or X8, and cy4 or cy8, depending on sizeof(mbedtls_mpi_uint) */ 741 mbedtls_mpi *X = (sizeof(mbedtls_mpi_uint) == 4) ? &X4 : &X8; 742 mbedtls_mpi *cy = (sizeof(mbedtls_mpi_uint) == 4) ? &cy4 : &cy8; 743 744 /* The carry should only have one limb */ 745 TEST_EQUAL(1, cy->n); 746 747 /* All of the inputs are +ve (or zero) */ 748 TEST_EQUAL(1, A.s); 749 TEST_EQUAL(1, B.s); 750 TEST_EQUAL(1, S.s); 751 TEST_EQUAL(1, X->s); 752 TEST_EQUAL(1, cy->s); 753 754 /* Get the (max) number of limbs we will need */ 755 size_t limbs = MAX(A.n, B.n); 756 size_t bytes = limbs * sizeof(mbedtls_mpi_uint); 757 758 /* The result shouldn't have more limbs than the longest input */ 759 TEST_LE_U(X->n, limbs); 760 761 /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */ 762 763 /* TEST_CALLOC() uses calloc() under the hood, so these do get zeroed */ 764 TEST_CALLOC(a, bytes); 765 TEST_CALLOC(x, bytes); 766 767 /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as 768 * processed by mbedtls_mpi_core_mla()) are little endian, we can just 769 * copy what we have as long as MSBs are 0 (which they are from TEST_CALLOC()). 770 */ 771 memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint)); 772 memcpy(x, X->p, X->n * sizeof(mbedtls_mpi_uint)); 773 774 /* 1a) A += B * s => we should get the correct carry */ 775 TEST_EQUAL(mbedtls_mpi_core_mla(a, limbs, B.p, B.n, *S.p), *cy->p); 776 777 /* 1b) A += B * s => we should get the correct result */ 778 TEST_MEMORY_COMPARE(a, bytes, x, bytes); 779 780 if (A.n == B.n && memcmp(A.p, B.p, bytes) == 0) { 781 /* Check when A and B are aliased */ 782 memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint)); 783 TEST_EQUAL(mbedtls_mpi_core_mla(a, limbs, a, limbs, *S.p), *cy->p); 784 TEST_MEMORY_COMPARE(a, bytes, x, bytes); 785 } 786 787 exit: 788 mbedtls_free(a); 789 mbedtls_free(x); 790 791 mbedtls_mpi_free(&A); 792 mbedtls_mpi_free(&B); 793 mbedtls_mpi_free(&S); 794 mbedtls_mpi_free(&X4); 795 mbedtls_mpi_free(&X8); 796 mbedtls_mpi_free(&cy4); 797 mbedtls_mpi_free(&cy8); 798 } 799 /* END_CASE */ 800 801 802 /* BEGIN_CASE */ 803 void mpi_montg_init(char *input_N, char *input_mm) 804 { 805 mbedtls_mpi N, mm; 806 807 mbedtls_mpi_init(&N); 808 mbedtls_mpi_init(&mm); 809 810 TEST_EQUAL(0, mbedtls_test_read_mpi(&N, input_N)); 811 TEST_EQUAL(0, mbedtls_test_read_mpi(&mm, input_mm)); 812 813 /* The MPI encoding of mm should be 1 limb (sizeof(mbedtls_mpi_uint) == 8) or 814 * 2 limbs (sizeof(mbedtls_mpi_uint) == 4). 815 * 816 * The data file contains the expected result for sizeof(mbedtls_mpi_uint) == 8; 817 * for sizeof(mbedtls_mpi_uint) == 4 it's just the LSW of this. 818 */ 819 TEST_ASSERT(mm.n == 1 || mm.n == 2); 820 821 /* All of the inputs are +ve (or zero) */ 822 TEST_EQUAL(1, N.s); 823 TEST_EQUAL(1, mm.s); 824 825 /* mbedtls_mpi_core_montmul_init() only returns a result, no error possible */ 826 mbedtls_mpi_uint result = mbedtls_mpi_core_montmul_init(N.p); 827 828 /* Check we got the correct result */ 829 TEST_EQUAL(result, mm.p[0]); 830 831 exit: 832 mbedtls_mpi_free(&N); 833 mbedtls_mpi_free(&mm); 834 } 835 /* END_CASE */ 836 837 /* BEGIN_CASE */ 838 void mpi_core_montmul(int limbs_AN4, int limbs_B4, 839 int limbs_AN8, int limbs_B8, 840 char *input_A, 841 char *input_B, 842 char *input_N, 843 char *input_X4, 844 char *input_X8) 845 { 846 mbedtls_mpi A, B, N, X4, X8, T, R; 847 848 mbedtls_mpi_init(&A); 849 mbedtls_mpi_init(&B); 850 mbedtls_mpi_init(&N); 851 mbedtls_mpi_init(&X4); /* expected result, sizeof(mbedtls_mpi_uint) == 4 */ 852 mbedtls_mpi_init(&X8); /* expected result, sizeof(mbedtls_mpi_uint) == 8 */ 853 mbedtls_mpi_init(&T); 854 mbedtls_mpi_init(&R); /* for the result */ 855 856 TEST_EQUAL(0, mbedtls_test_read_mpi(&A, input_A)); 857 TEST_EQUAL(0, mbedtls_test_read_mpi(&B, input_B)); 858 TEST_EQUAL(0, mbedtls_test_read_mpi(&N, input_N)); 859 TEST_EQUAL(0, mbedtls_test_read_mpi(&X4, input_X4)); 860 TEST_EQUAL(0, mbedtls_test_read_mpi(&X8, input_X8)); 861 862 mbedtls_mpi *X = (sizeof(mbedtls_mpi_uint) == 4) ? &X4 : &X8; 863 864 int limbs_AN = (sizeof(mbedtls_mpi_uint) == 4) ? limbs_AN4 : limbs_AN8; 865 int limbs_B = (sizeof(mbedtls_mpi_uint) == 4) ? limbs_B4 : limbs_B8; 866 867 TEST_LE_U(A.n, (size_t) limbs_AN); 868 TEST_LE_U(X->n, (size_t) limbs_AN); 869 TEST_LE_U(B.n, (size_t) limbs_B); 870 TEST_LE_U(limbs_B, limbs_AN); 871 872 /* All of the inputs are +ve (or zero) */ 873 TEST_EQUAL(1, A.s); 874 TEST_EQUAL(1, B.s); 875 TEST_EQUAL(1, N.s); 876 TEST_EQUAL(1, X->s); 877 878 TEST_EQUAL(0, mbedtls_mpi_grow(&A, limbs_AN)); 879 TEST_EQUAL(0, mbedtls_mpi_grow(&N, limbs_AN)); 880 TEST_EQUAL(0, mbedtls_mpi_grow(X, limbs_AN)); 881 TEST_EQUAL(0, mbedtls_mpi_grow(&B, limbs_B)); 882 883 size_t working_limbs = mbedtls_mpi_core_montmul_working_limbs(limbs_AN); 884 TEST_EQUAL(working_limbs, limbs_AN * 2 + 1); 885 TEST_EQUAL(0, mbedtls_mpi_grow(&T, working_limbs)); 886 887 /* Calculate the Montgomery constant (this is unit tested separately) */ 888 mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N.p); 889 890 TEST_EQUAL(0, mbedtls_mpi_grow(&R, limbs_AN)); /* ensure it's got the right number of limbs */ 891 892 mbedtls_mpi_core_montmul(R.p, A.p, B.p, B.n, N.p, N.n, mm, T.p); 893 size_t bytes = N.n * sizeof(mbedtls_mpi_uint); 894 TEST_MEMORY_COMPARE(R.p, bytes, X->p, bytes); 895 896 /* The output (R, above) may be aliased to A - use R to save the value of A */ 897 898 memcpy(R.p, A.p, bytes); 899 900 mbedtls_mpi_core_montmul(A.p, A.p, B.p, B.n, N.p, N.n, mm, T.p); 901 TEST_MEMORY_COMPARE(A.p, bytes, X->p, bytes); 902 903 memcpy(A.p, R.p, bytes); /* restore A */ 904 905 /* The output may be aliased to N - use R to save the value of N */ 906 907 memcpy(R.p, N.p, bytes); 908 909 mbedtls_mpi_core_montmul(N.p, A.p, B.p, B.n, N.p, N.n, mm, T.p); 910 TEST_MEMORY_COMPARE(N.p, bytes, X->p, bytes); 911 912 memcpy(N.p, R.p, bytes); 913 914 if (limbs_AN == limbs_B) { 915 /* Test when A aliased to B (requires A == B on input values) */ 916 if (memcmp(A.p, B.p, bytes) == 0) { 917 /* Test with A aliased to B and output, since this is permitted - 918 * don't bother with yet another test with only A and B aliased */ 919 920 mbedtls_mpi_core_montmul(B.p, B.p, B.p, B.n, N.p, N.n, mm, T.p); 921 TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes); 922 923 memcpy(B.p, A.p, bytes); /* restore B from equal value A */ 924 } 925 926 /* The output may be aliased to B - last test, so we don't save B */ 927 928 mbedtls_mpi_core_montmul(B.p, A.p, B.p, B.n, N.p, N.n, mm, T.p); 929 TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes); 930 } 931 932 exit: 933 mbedtls_mpi_free(&A); 934 mbedtls_mpi_free(&B); 935 mbedtls_mpi_free(&N); 936 mbedtls_mpi_free(&X4); 937 mbedtls_mpi_free(&X8); 938 mbedtls_mpi_free(&T); 939 mbedtls_mpi_free(&R); 940 } 941 /* END_CASE */ 942 943 /* BEGIN_CASE */ 944 void mpi_core_get_mont_r2_unsafe_neg() 945 { 946 mbedtls_mpi N, RR; 947 mbedtls_mpi_init(&N); 948 mbedtls_mpi_init(&RR); 949 const char *n = "7ffffffffffffff1"; 950 951 /* Test for zero divisor */ 952 TEST_EQUAL(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO, 953 mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N)); 954 955 /* Test for negative input */ 956 TEST_EQUAL(0, mbedtls_test_read_mpi(&N, n)); 957 N.s = -1; 958 TEST_EQUAL(MBEDTLS_ERR_MPI_NEGATIVE_VALUE, 959 mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N)); 960 N.s = 1; 961 962 exit: 963 mbedtls_mpi_free(&N); 964 mbedtls_mpi_free(&RR); 965 } 966 /* END_CASE */ 967 968 /* BEGIN_CASE */ 969 void mpi_core_get_mont_r2_unsafe(char *input_N, 970 char *input_RR_X4, 971 char *input_RR_X8) 972 { 973 mbedtls_mpi N, RR, RR_REF; 974 975 /* Select the appropriate output */ 976 char *input_rr = (sizeof(mbedtls_mpi_uint) == 4) ? input_RR_X4 : input_RR_X8; 977 978 mbedtls_mpi_init(&N); 979 mbedtls_mpi_init(&RR); 980 mbedtls_mpi_init(&RR_REF); 981 982 /* Read inputs */ 983 TEST_EQUAL(0, mbedtls_test_read_mpi(&N, input_N)); 984 TEST_EQUAL(0, mbedtls_test_read_mpi(&RR_REF, input_rr)); 985 986 /* All of the inputs are +ve (or zero) */ 987 TEST_EQUAL(1, N.s); 988 TEST_EQUAL(1, RR_REF.s); 989 990 /* Test valid input */ 991 TEST_EQUAL(0, mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N)); 992 993 /* Test that the moduli is odd */ 994 TEST_EQUAL(N.p[0] ^ 1, N.p[0] - 1); 995 996 /* Output is +ve (or zero) */ 997 TEST_EQUAL(1, RR_REF.s); 998 999 /* rr is updated to a valid pointer */ 1000 TEST_ASSERT(RR.p != NULL); 1001 1002 /* Calculated rr matches expected value */ 1003 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&RR, &RR_REF) == 0); 1004 1005 exit: 1006 mbedtls_mpi_free(&N); 1007 mbedtls_mpi_free(&RR); 1008 mbedtls_mpi_free(&RR_REF); 1009 } 1010 /* END_CASE */ 1011 1012 /* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */ 1013 void mpi_core_ct_uint_table_lookup(int bitlen, int window_size) 1014 { 1015 size_t limbs = BITS_TO_LIMBS(bitlen); 1016 size_t count = ((size_t) 1) << window_size; 1017 1018 mbedtls_mpi_uint *table = NULL; 1019 mbedtls_mpi_uint *dest = NULL; 1020 1021 TEST_CALLOC(table, limbs * count); 1022 TEST_CALLOC(dest, limbs); 1023 1024 /* 1025 * Fill the table with a unique counter so that differences are easily 1026 * detected. (And have their relationship to the index relatively non-trivial just 1027 * to be sure.) 1028 */ 1029 for (size_t i = 0; i < count * limbs; i++) { 1030 table[i] = ~i - 1; 1031 } 1032 1033 for (size_t i = 0; i < count; i++) { 1034 mbedtls_mpi_uint *current = table + i * limbs; 1035 memset(dest, 0x00, limbs * sizeof(*dest)); 1036 1037 /* 1038 * We shouldn't leak anything through timing. 1039 * We need to set these in every loop as we need to make the loop 1040 * variable public for the loop head and the buffers for comparison. 1041 */ 1042 TEST_CF_SECRET(&i, sizeof(i)); 1043 TEST_CF_SECRET(dest, limbs * sizeof(*dest)); 1044 TEST_CF_SECRET(table, count * limbs * sizeof(*table)); 1045 1046 mbedtls_mpi_core_ct_uint_table_lookup(dest, table, limbs, count, i); 1047 1048 TEST_CF_PUBLIC(dest, limbs * sizeof(*dest)); 1049 TEST_CF_PUBLIC(table, count * limbs * sizeof(*table)); 1050 TEST_MEMORY_COMPARE(dest, limbs * sizeof(*dest), 1051 current, limbs * sizeof(*current)); 1052 TEST_CF_PUBLIC(&i, sizeof(i)); 1053 } 1054 1055 exit: 1056 mbedtls_free(table); 1057 mbedtls_free(dest); 1058 } 1059 /* END_CASE */ 1060 1061 /* BEGIN_CASE */ 1062 void mpi_core_fill_random(int wanted_bytes_arg, int extra_rng_bytes, 1063 int extra_limbs, int before, int expected_ret) 1064 { 1065 size_t wanted_bytes = wanted_bytes_arg; 1066 mbedtls_mpi_uint *X = NULL; 1067 size_t X_limbs = CHARS_TO_LIMBS(wanted_bytes) + extra_limbs; 1068 size_t rng_bytes = wanted_bytes + extra_rng_bytes; 1069 unsigned char *rnd_data = NULL; 1070 mbedtls_test_rnd_buf_info rnd_info = { NULL, rng_bytes, NULL, NULL }; 1071 int ret; 1072 1073 /* Prepare an RNG with known output, limited to rng_bytes. */ 1074 TEST_CALLOC(rnd_data, rng_bytes); 1075 TEST_EQUAL(0, mbedtls_test_rnd_std_rand(NULL, rnd_data, rng_bytes)); 1076 rnd_info.buf = rnd_data; 1077 1078 /* Allocate an MPI with room for wanted_bytes plus extra_limbs. 1079 * extra_limbs may be negative but the total limb count must be positive. 1080 * Fill the MPI with the byte value in before. */ 1081 TEST_LE_U(1, X_limbs); 1082 TEST_CALLOC(X, X_limbs); 1083 memset(X, before, X_limbs * sizeof(*X)); 1084 1085 ret = mbedtls_mpi_core_fill_random(X, X_limbs, wanted_bytes, 1086 mbedtls_test_rnd_buffer_rand, 1087 &rnd_info); 1088 TEST_EQUAL(expected_ret, ret); 1089 1090 if (expected_ret == 0) { 1091 /* mbedtls_mpi_core_fill_random is documented to use bytes from the 1092 * RNG as a big-endian representation of the number. We used an RNG 1093 * with known output, so check that the output contains the 1094 * expected value. Bytes above wanted_bytes must be zero. */ 1095 for (size_t i = 0; i < wanted_bytes; i++) { 1096 mbedtls_test_set_step(i); 1097 TEST_EQUAL(GET_BYTE(X, i), rnd_data[wanted_bytes - 1 - i]); 1098 } 1099 for (size_t i = wanted_bytes; i < X_limbs * ciL; i++) { 1100 mbedtls_test_set_step(i); 1101 TEST_EQUAL(GET_BYTE(X, i), 0); 1102 } 1103 } 1104 1105 exit: 1106 mbedtls_free(rnd_data); 1107 mbedtls_free(X); 1108 } 1109 /* END_CASE */ 1110 1111 /* BEGIN_CASE */ 1112 void mpi_core_mul(char *input_A, 1113 char *input_B, 1114 char *result) 1115 { 1116 mbedtls_mpi_uint *A = NULL; 1117 mbedtls_mpi_uint *A_orig = NULL; 1118 mbedtls_mpi_uint *B = NULL; 1119 mbedtls_mpi_uint *B_orig = NULL; 1120 mbedtls_mpi_uint *R = NULL; 1121 mbedtls_mpi_uint *X = NULL; 1122 size_t A_limbs, B_limbs, R_limbs; 1123 1124 TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &A_limbs, input_A), 0); 1125 TEST_EQUAL(mbedtls_test_read_mpi_core(&B, &B_limbs, input_B), 0); 1126 TEST_EQUAL(mbedtls_test_read_mpi_core(&R, &R_limbs, result), 0); 1127 1128 TEST_EQUAL(R_limbs, A_limbs + B_limbs); 1129 1130 const size_t X_limbs = A_limbs + B_limbs; 1131 const size_t X_bytes = X_limbs * sizeof(mbedtls_mpi_uint); 1132 TEST_CALLOC(X, X_limbs); 1133 1134 const size_t A_bytes = A_limbs * sizeof(mbedtls_mpi_uint); 1135 TEST_CALLOC(A_orig, A_limbs); 1136 memcpy(A_orig, A, A_bytes); 1137 1138 const size_t B_bytes = B_limbs * sizeof(mbedtls_mpi_uint); 1139 TEST_CALLOC(B_orig, B_limbs); 1140 memcpy(B_orig, B, B_bytes); 1141 1142 /* Set result to something that is unlikely to be correct */ 1143 memset(X, '!', X_bytes); 1144 1145 /* 1. X = A * B - result should be correct, A and B unchanged */ 1146 mbedtls_mpi_core_mul(X, A, A_limbs, B, B_limbs); 1147 TEST_MEMORY_COMPARE(X, X_bytes, R, X_bytes); 1148 TEST_MEMORY_COMPARE(A, A_bytes, A_orig, A_bytes); 1149 TEST_MEMORY_COMPARE(B, B_bytes, B_orig, B_bytes); 1150 1151 /* 2. A == B: alias A and B - result should be correct, A and B unchanged */ 1152 if (A_bytes == B_bytes && memcmp(A, B, A_bytes) == 0) { 1153 memset(X, '!', X_bytes); 1154 mbedtls_mpi_core_mul(X, A, A_limbs, A, A_limbs); 1155 TEST_MEMORY_COMPARE(X, X_bytes, R, X_bytes); 1156 TEST_MEMORY_COMPARE(A, A_bytes, A_orig, A_bytes); 1157 } 1158 /* 3. X = B * A - result should be correct, A and B unchanged */ 1159 else { 1160 memset(X, '!', X_bytes); 1161 mbedtls_mpi_core_mul(X, B, B_limbs, A, A_limbs); 1162 TEST_MEMORY_COMPARE(X, X_bytes, R, X_bytes); 1163 TEST_MEMORY_COMPARE(A, A_bytes, A_orig, A_bytes); 1164 TEST_MEMORY_COMPARE(B, B_bytes, B_orig, B_bytes); 1165 } 1166 1167 exit: 1168 mbedtls_free(A); 1169 mbedtls_free(A_orig); 1170 mbedtls_free(B); 1171 mbedtls_free(B_orig); 1172 mbedtls_free(R); 1173 mbedtls_free(X); 1174 } 1175 /* END_CASE */ 1176 1177 /* BEGIN_CASE */ 1178 void mpi_core_exp_mod(char *input_N, char *input_A, 1179 char *input_E, char *input_X) 1180 { 1181 mbedtls_mpi_uint *A = NULL; 1182 mbedtls_mpi_uint *A_copy = NULL; 1183 mbedtls_mpi_uint *E = NULL; 1184 mbedtls_mpi_uint *N = NULL; 1185 mbedtls_mpi_uint *X = NULL; 1186 size_t A_limbs, E_limbs, N_limbs, X_limbs; 1187 const mbedtls_mpi_uint *R2 = NULL; 1188 mbedtls_mpi_uint *Y = NULL; 1189 mbedtls_mpi_uint *T = NULL; 1190 /* Legacy MPIs for computing R2 */ 1191 mbedtls_mpi N_mpi; 1192 mbedtls_mpi_init(&N_mpi); 1193 mbedtls_mpi R2_mpi; 1194 mbedtls_mpi_init(&R2_mpi); 1195 1196 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A)); 1197 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&E, &E_limbs, input_E)); 1198 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &N_limbs, input_N)); 1199 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X)); 1200 TEST_CALLOC(Y, N_limbs); 1201 1202 TEST_EQUAL(A_limbs, N_limbs); 1203 TEST_EQUAL(X_limbs, N_limbs); 1204 1205 TEST_EQUAL(0, mbedtls_mpi_grow(&N_mpi, N_limbs)); 1206 memcpy(N_mpi.p, N, N_limbs * sizeof(*N)); 1207 N_mpi.n = N_limbs; 1208 TEST_EQUAL(0, 1209 mbedtls_mpi_core_get_mont_r2_unsafe(&R2_mpi, &N_mpi)); 1210 TEST_EQUAL(0, mbedtls_mpi_grow(&R2_mpi, N_limbs)); 1211 R2 = R2_mpi.p; 1212 1213 size_t working_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N_limbs, 1214 E_limbs); 1215 1216 /* No point exactly duplicating the code in mbedtls_mpi_core_exp_mod_working_limbs() 1217 * to see if the output is correct, but we can check that it's in a 1218 * reasonable range. The current calculation works out as 1219 * `1 + N_limbs * (welem + 3)`, where welem is the number of elements in 1220 * the window (1 << 1 up to 1 << 6). 1221 */ 1222 size_t min_expected_working_limbs = 1 + N_limbs * 4; 1223 size_t max_expected_working_limbs = 1 + N_limbs * 67; 1224 1225 TEST_LE_U(min_expected_working_limbs, working_limbs); 1226 TEST_LE_U(working_limbs, max_expected_working_limbs); 1227 1228 /* Should also be at least mbedtls_mpi_core_montmul_working_limbs() */ 1229 TEST_LE_U(mbedtls_mpi_core_montmul_working_limbs(N_limbs), 1230 working_limbs); 1231 1232 TEST_CALLOC(T, working_limbs); 1233 1234 /* Test the safe variant */ 1235 1236 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1237 mbedtls_codepath_reset(); 1238 #endif 1239 mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T); 1240 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1241 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET); 1242 #endif 1243 TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); 1244 1245 /* Test the unsafe variant */ 1246 1247 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1248 mbedtls_codepath_reset(); 1249 #endif 1250 mbedtls_mpi_core_exp_mod_unsafe(Y, A, N, N_limbs, E, E_limbs, R2, T); 1251 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1252 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_PUBLIC); 1253 #endif 1254 TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint))); 1255 1256 /* Check both with output aliased to input */ 1257 1258 TEST_CALLOC(A_copy, A_limbs); 1259 memcpy(A_copy, A, sizeof(*A_copy) * A_limbs); 1260 1261 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1262 mbedtls_codepath_reset(); 1263 #endif 1264 mbedtls_mpi_core_exp_mod(A, A, N, N_limbs, E, E_limbs, R2, T); 1265 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1266 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET); 1267 #endif 1268 TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); 1269 1270 memcpy(A, A_copy, sizeof(*A) * A_limbs); 1271 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1272 mbedtls_codepath_reset(); 1273 #endif 1274 mbedtls_mpi_core_exp_mod_unsafe(A, A, N, N_limbs, E, E_limbs, R2, T); 1275 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C) 1276 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_PUBLIC); 1277 #endif 1278 TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint))); 1279 1280 exit: 1281 mbedtls_free(T); 1282 mbedtls_free(A); 1283 mbedtls_free(A_copy); 1284 mbedtls_free(E); 1285 mbedtls_free(N); 1286 mbedtls_free(X); 1287 mbedtls_free(Y); 1288 mbedtls_mpi_free(&N_mpi); 1289 mbedtls_mpi_free(&R2_mpi); 1290 // R2 doesn't need to be freed as it is only aliasing R2_mpi 1291 } 1292 /* END_CASE */ 1293 1294 /* BEGIN_CASE */ 1295 void mpi_core_sub_int(char *input_A, char *input_B, 1296 char *input_X, int borrow) 1297 { 1298 /* We are testing A - b, where A is an MPI and b is a scalar, expecting 1299 * result X with borrow borrow. However, for ease of handling we encode b 1300 * as a 1-limb MPI (B) in the .data file. */ 1301 1302 mbedtls_mpi_uint *A = NULL; 1303 mbedtls_mpi_uint *B = NULL; 1304 mbedtls_mpi_uint *X = NULL; 1305 mbedtls_mpi_uint *R = NULL; 1306 size_t A_limbs, B_limbs, X_limbs; 1307 1308 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A)); 1309 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&B, &B_limbs, input_B)); 1310 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X)); 1311 1312 /* The MPI encoding of scalar b must be only 1 limb */ 1313 TEST_EQUAL(B_limbs, 1); 1314 1315 /* The subtraction is fixed-width, so A and X must have the same number of limbs */ 1316 TEST_EQUAL(A_limbs, X_limbs); 1317 size_t limbs = A_limbs; 1318 1319 TEST_CALLOC(R, limbs); 1320 1321 #define TEST_COMPARE_CORE_MPIS(A, B, limbs) \ 1322 TEST_MEMORY_COMPARE(A, (limbs) * sizeof(mbedtls_mpi_uint), \ 1323 B, (limbs) * sizeof(mbedtls_mpi_uint)) 1324 1325 /* 1. R = A - b. Result and borrow should be correct */ 1326 TEST_EQUAL(mbedtls_mpi_core_sub_int(R, A, B[0], limbs), borrow); 1327 TEST_COMPARE_CORE_MPIS(R, X, limbs); 1328 1329 /* 2. A = A - b. Result and borrow should be correct */ 1330 TEST_EQUAL(mbedtls_mpi_core_sub_int(A, A, B[0], limbs), borrow); 1331 TEST_COMPARE_CORE_MPIS(A, X, limbs); 1332 1333 exit: 1334 mbedtls_free(A); 1335 mbedtls_free(B); 1336 mbedtls_free(X); 1337 mbedtls_free(R); 1338 } 1339 /* END_CASE */ 1340 1341 /* BEGIN_CASE */ 1342 void mpi_core_check_zero_ct(char *input_X, int expected_is_zero) 1343 { 1344 mbedtls_mpi_uint *X = NULL; 1345 size_t X_limbs; 1346 1347 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X)); 1348 1349 TEST_CF_SECRET(X, X_limbs * sizeof(mbedtls_mpi_uint)); 1350 1351 mbedtls_mpi_uint check = mbedtls_mpi_core_check_zero_ct(X, X_limbs); 1352 int is_zero = (check == 0); 1353 TEST_EQUAL(is_zero, expected_is_zero); 1354 1355 exit: 1356 mbedtls_free(X); 1357 } 1358 /* END_CASE */