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