1/* BEGIN_HEADER */ 2#include "mbedtls/bignum.h" 3#include "mbedtls/entropy.h" 4#include "bignum_mod.h" 5#include "bignum_mod_raw.h" 6#include "constant_time_internal.h" 7#include "test/constant_flow.h" 8 9#define TEST_COMPARE_MPI_RESIDUES(a, b) \ 10 TEST_MEMORY_COMPARE((a).p, (a).limbs * sizeof(mbedtls_mpi_uint), \ 11 (b).p, (b).limbs * sizeof(mbedtls_mpi_uint)) 12 13static int test_read_residue(mbedtls_mpi_mod_residue *r, 14 const mbedtls_mpi_mod_modulus *m, 15 char *input, 16 int skip_limbs_and_value_checks) 17{ 18 mbedtls_mpi_uint *p = NULL; 19 size_t limbs; 20 21 int ret = mbedtls_test_read_mpi_core(&p, &limbs, input); 22 if (ret != 0) { 23 return ret; 24 } 25 26 if (skip_limbs_and_value_checks) { 27 r->p = p; 28 r->limbs = limbs; 29 return 0; 30 } 31 32 /* mbedtls_mpi_mod_residue_setup() checks limbs, and that value < m */ 33 return mbedtls_mpi_mod_residue_setup(r, m, p, limbs); 34} 35/* END_HEADER */ 36 37/* BEGIN_DEPENDENCIES 38 * depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_ECP_WITH_MPI_UINT 39 * END_DEPENDENCIES 40 */ 41 42/* BEGIN_CASE */ 43void mpi_mod_setup(int int_rep, int iret) 44{ 45 #define MLIMBS 8 46 mbedtls_mpi_uint mp[MLIMBS]; 47 mbedtls_mpi_mod_modulus m; 48 int ret; 49 50 memset(mp, 0xFF, sizeof(mp)); 51 52 mbedtls_mpi_mod_modulus_init(&m); 53 54 switch (int_rep) { 55 case MBEDTLS_MPI_MOD_REP_MONTGOMERY: 56 ret = mbedtls_mpi_mod_modulus_setup(&m, mp, MLIMBS); 57 break; 58 case MBEDTLS_MPI_MOD_REP_OPT_RED: 59 ret = mbedtls_mpi_mod_optred_modulus_setup(&m, mp, MLIMBS, NULL); 60 break; 61 default: 62 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 63 break; 64 } 65 66 TEST_EQUAL(ret, iret); 67 68 /* Only test if the constants have been set-up */ 69 if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { 70 /* Test that the consts have been calculated */ 71 TEST_ASSERT(m.rep.mont.rr != NULL); 72 TEST_ASSERT(m.rep.mont.mm != 0); 73 74 } 75 76 /* Address sanitiser should catch if we try to free mp */ 77 mbedtls_mpi_mod_modulus_free(&m); 78 79 /* Make sure that the modulus doesn't have reference to mp anymore */ 80 TEST_ASSERT(m.p != mp); 81 82 /* Only test if the constants have been set-up */ 83 if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { 84 /* Verify the data and pointers allocated have been properly wiped */ 85 TEST_ASSERT(m.rep.mont.rr == NULL); 86 TEST_ASSERT(m.rep.mont.mm == 0); 87 } 88exit: 89 /* It should be safe to call an mbedtls free several times */ 90 mbedtls_mpi_mod_modulus_free(&m); 91 92 #undef MLIMBS 93} 94/* END_CASE */ 95 96/* BEGIN_CASE */ 97void mpi_mod_mul(char *input_A, 98 char *input_B, 99 char *input_N, 100 char *result) 101{ 102 mbedtls_mpi_uint *X = NULL; 103 104 mbedtls_mpi_mod_residue rA = { NULL, 0 }; 105 mbedtls_mpi_mod_residue rB = { NULL, 0 }; 106 mbedtls_mpi_mod_residue rR = { NULL, 0 }; 107 mbedtls_mpi_mod_residue rX = { NULL, 0 }; 108 109 mbedtls_mpi_mod_modulus m; 110 mbedtls_mpi_mod_modulus_init(&m); 111 112 TEST_EQUAL(mbedtls_test_read_mpi_modulus(&m, input_N, 113 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0); 114 115 TEST_EQUAL(test_read_residue(&rA, &m, input_A, 0), 0); 116 TEST_EQUAL(test_read_residue(&rB, &m, input_B, 0), 0); 117 TEST_EQUAL(test_read_residue(&rR, &m, result, 0), 0); 118 119 const size_t limbs = m.limbs; 120 const size_t bytes = limbs * sizeof(mbedtls_mpi_uint); 121 122 TEST_EQUAL(rA.limbs, limbs); 123 TEST_EQUAL(rB.limbs, limbs); 124 TEST_EQUAL(rR.limbs, limbs); 125 126 TEST_CALLOC(X, limbs); 127 128 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0); 129 130 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), 0); 131 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 132 133 /* alias X to A */ 134 memcpy(rX.p, rA.p, bytes); 135 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rB, &m), 0); 136 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 137 138 /* alias X to B */ 139 memcpy(rX.p, rB.p, bytes); 140 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rX, &m), 0); 141 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 142 143 /* A == B: alias A and B */ 144 if (memcmp(rA.p, rB.p, bytes) == 0) { 145 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA, &m), 0); 146 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 147 148 /* X, A, B all aliased together */ 149 memcpy(rX.p, rA.p, bytes); 150 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rX, &m), 0); 151 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 152 } 153 /* A != B: test B * A */ 154 else { 155 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rA, &m), 0); 156 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 157 158 /* B * A: alias X to A */ 159 memcpy(rX.p, rA.p, bytes); 160 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rX, &m), 0); 161 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 162 163 /* B + A: alias X to B */ 164 memcpy(rX.p, rB.p, bytes); 165 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rA, &m), 0); 166 TEST_MEMORY_COMPARE(rX.p, bytes, rR.p, bytes); 167 } 168 169exit: 170 mbedtls_free(rA.p); 171 mbedtls_free(rB.p); 172 mbedtls_free(rR.p); 173 mbedtls_free(X); 174 mbedtls_free((mbedtls_mpi_uint *) m.p); 175 176 mbedtls_mpi_mod_modulus_free(&m); 177} 178/* END_CASE */ 179 180/* BEGIN_CASE */ 181void mpi_mod_mul_neg(char *input_A, 182 char *input_B, 183 char *input_N, 184 char *result, 185 int exp_ret) 186{ 187 mbedtls_mpi_uint *X = NULL; 188 189 mbedtls_mpi_mod_residue rA = { NULL, 0 }; 190 mbedtls_mpi_mod_residue rB = { NULL, 0 }; 191 mbedtls_mpi_mod_residue rR = { NULL, 0 }; 192 mbedtls_mpi_mod_residue rX = { NULL, 0 }; 193 194 mbedtls_mpi_mod_modulus m; 195 mbedtls_mpi_mod_modulus_init(&m); 196 197 mbedtls_mpi_mod_modulus fake_m; 198 mbedtls_mpi_mod_modulus_init(&fake_m); 199 200 TEST_EQUAL(mbedtls_test_read_mpi_modulus(&m, input_N, 201 MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0); 202 203 TEST_EQUAL(test_read_residue(&rA, &m, input_A, 1), 0); 204 TEST_EQUAL(test_read_residue(&rB, &m, input_B, 1), 0); 205 TEST_EQUAL(test_read_residue(&rR, &m, result, 1), 0); 206 207 const size_t limbs = m.limbs; 208 209 TEST_CALLOC(X, limbs); 210 211 TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0); 212 rX.limbs = rR.limbs; 213 214 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), exp_ret); 215 216 /* Check when m is not initialized */ 217 TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &fake_m), 218 MBEDTLS_ERR_MPI_BAD_INPUT_DATA); 219 220exit: 221 mbedtls_free(rA.p); 222 mbedtls_free(rB.p); 223 mbedtls_free(rR.p); 224 mbedtls_free(X); 225 mbedtls_free((mbedtls_mpi_uint *) m.p); 226 227 mbedtls_mpi_mod_modulus_free(&m); 228 mbedtls_mpi_mod_modulus_free(&fake_m); 229} 230/* END_CASE */ 231 232/* BEGIN_CASE */ 233void mpi_mod_sub(char *input_N, 234 char *input_A, char *input_B, 235 char *input_D, int expected_ret) 236{ 237 mbedtls_mpi_mod_residue a = { NULL, 0 }; 238 mbedtls_mpi_mod_residue b = { NULL, 0 }; 239 mbedtls_mpi_mod_residue d = { NULL, 0 }; 240 mbedtls_mpi_mod_residue x = { NULL, 0 }; 241 mbedtls_mpi_uint *X_raw = NULL; 242 243 mbedtls_mpi_mod_modulus m; 244 mbedtls_mpi_mod_modulus_init(&m); 245 246 TEST_EQUAL(0, 247 mbedtls_test_read_mpi_modulus(&m, input_N, 248 MBEDTLS_MPI_MOD_REP_MONTGOMERY)); 249 250 /* test_read_residue() normally checks that inputs have the same number of 251 * limbs as the modulus. For negative testing we can ask it to skip this 252 * with a non-zero final parameter. */ 253 TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0)); 254 TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0)); 255 TEST_EQUAL(0, test_read_residue(&d, &m, input_D, expected_ret != 0)); 256 257 size_t limbs = m.limbs; 258 size_t bytes = limbs * sizeof(*X_raw); 259 260 if (expected_ret == 0) { 261 /* Negative test with too many limbs in output */ 262 TEST_CALLOC(X_raw, limbs + 1); 263 264 x.p = X_raw; 265 x.limbs = limbs + 1; 266 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 267 mbedtls_mpi_mod_sub(&x, &a, &b, &m)); 268 269 mbedtls_free(X_raw); 270 X_raw = NULL; 271 272 /* Negative test with too few limbs in output */ 273 if (limbs > 1) { 274 TEST_CALLOC(X_raw, limbs - 1); 275 276 x.p = X_raw; 277 x.limbs = limbs - 1; 278 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 279 mbedtls_mpi_mod_sub(&x, &a, &b, &m)); 280 281 mbedtls_free(X_raw); 282 X_raw = NULL; 283 } 284 285 /* Negative testing with too many/too few limbs in a and b is covered by 286 * manually-written test cases with expected_ret != 0. */ 287 } 288 289 TEST_CALLOC(X_raw, limbs); 290 291 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs)); 292 293 /* a - b => Correct result, or expected error */ 294 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_sub(&x, &a, &b, &m)); 295 if (expected_ret != 0) { 296 goto exit; 297 } 298 299 TEST_COMPARE_MPI_RESIDUES(x, d); 300 301 /* a - b: alias x to a => Correct result */ 302 memcpy(x.p, a.p, bytes); 303 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &b, &m)); 304 TEST_COMPARE_MPI_RESIDUES(x, d); 305 306 /* a - b: alias x to b => Correct result */ 307 memcpy(x.p, b.p, bytes); 308 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &x, &m)); 309 TEST_COMPARE_MPI_RESIDUES(x, d); 310 311 if (memcmp(a.p, b.p, bytes) == 0) { 312 /* a == b: alias a and b */ 313 314 /* a - a => Correct result */ 315 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &a, &m)); 316 TEST_COMPARE_MPI_RESIDUES(x, d); 317 318 /* a - a: x, a, b all aliased together => Correct result */ 319 memcpy(x.p, a.p, bytes); 320 TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &x, &m)); 321 TEST_COMPARE_MPI_RESIDUES(x, d); 322 } 323 324exit: 325 mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */ 326 mbedtls_mpi_mod_modulus_free(&m); 327 328 mbedtls_free(a.p); 329 mbedtls_free(b.p); 330 mbedtls_free(d.p); 331 mbedtls_free(X_raw); 332} 333/* END_CASE */ 334 335/* BEGIN_CASE */ 336void mpi_mod_inv_mont(char *input_N, 337 char *input_A, char *input_I, 338 int expected_ret) 339{ 340 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */ 341 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */ 342 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */ 343 mbedtls_mpi_uint *X_raw = NULL; 344 345 mbedtls_mpi_mod_modulus N; 346 mbedtls_mpi_mod_modulus_init(&N); 347 348 TEST_EQUAL(0, 349 mbedtls_test_read_mpi_modulus(&N, input_N, 350 MBEDTLS_MPI_MOD_REP_MONTGOMERY)); 351 352 /* test_read_residue() normally checks that inputs have the same number of 353 * limbs as the modulus. For negative testing we can ask it to skip this 354 * with a non-zero final parameter. */ 355 TEST_EQUAL(0, test_read_residue(&a, &N, input_A, expected_ret != 0)); 356 TEST_EQUAL(0, test_read_residue(&i, &N, input_I, expected_ret != 0)); 357 358 size_t limbs = N.limbs; 359 size_t bytes = limbs * sizeof(*X_raw); 360 361 TEST_CALLOC(X_raw, limbs); 362 363 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &N, X_raw, limbs)); 364 365 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_inv(&x, &a, &N)); 366 if (expected_ret == 0) { 367 TEST_COMPARE_MPI_RESIDUES(x, i); 368 369 /* a^-1: alias x to a => Correct result */ 370 memcpy(x.p, a.p, bytes); 371 TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N)); 372 TEST_COMPARE_MPI_RESIDUES(x, i); 373 } 374 375exit: 376 mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */ 377 mbedtls_mpi_mod_modulus_free(&N); 378 379 mbedtls_free(a.p); 380 mbedtls_free(i.p); 381 mbedtls_free(X_raw); 382} 383/* END_CASE */ 384 385/* BEGIN_CASE */ 386void mpi_mod_inv_non_mont(char *input_N, 387 char *input_A, char *input_I, 388 int expected_ret) 389{ 390 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */ 391 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */ 392 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */ 393 mbedtls_mpi_uint *X_raw = NULL; 394 395 mbedtls_mpi_mod_modulus N; 396 mbedtls_mpi_mod_modulus_init(&N); 397 398 TEST_EQUAL(0, 399 mbedtls_test_read_mpi_modulus(&N, input_N, 400 MBEDTLS_MPI_MOD_REP_OPT_RED)); 401 402 /* test_read_residue() normally checks that inputs have the same number of 403 * limbs as the modulus. For negative testing we can ask it to skip this 404 * with a non-zero final parameter. */ 405 TEST_EQUAL(0, test_read_residue(&a, &N, input_A, expected_ret != 0)); 406 TEST_EQUAL(0, test_read_residue(&i, &N, input_I, expected_ret != 0)); 407 408 size_t limbs = N.limbs; 409 size_t bytes = limbs * sizeof(*X_raw); 410 411 TEST_CALLOC(X_raw, limbs); 412 413 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &N, X_raw, limbs)); 414 415 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_inv(&x, &a, &N)); 416 if (expected_ret == 0) { 417 TEST_COMPARE_MPI_RESIDUES(x, i); 418 419 /* a^-1: alias x to a => Correct result */ 420 memcpy(x.p, a.p, bytes); 421 TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N)); 422 TEST_COMPARE_MPI_RESIDUES(x, i); 423 } 424 425exit: 426 mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */ 427 mbedtls_mpi_mod_modulus_free(&N); 428 429 mbedtls_free(a.p); 430 mbedtls_free(i.p); 431 mbedtls_free(X_raw); 432} 433/* END_CASE */ 434 435/* BEGIN_CASE */ 436void mpi_mod_add(char *input_N, 437 char *input_A, char *input_B, 438 char *input_S, int expected_ret) 439{ 440 mbedtls_mpi_mod_residue a = { NULL, 0 }; 441 mbedtls_mpi_mod_residue b = { NULL, 0 }; 442 mbedtls_mpi_mod_residue s = { NULL, 0 }; 443 mbedtls_mpi_mod_residue x = { NULL, 0 }; 444 mbedtls_mpi_uint *X_raw = NULL; 445 446 mbedtls_mpi_mod_modulus m; 447 mbedtls_mpi_mod_modulus_init(&m); 448 449 TEST_EQUAL(0, 450 mbedtls_test_read_mpi_modulus(&m, input_N, 451 MBEDTLS_MPI_MOD_REP_MONTGOMERY)); 452 453 /* test_read_residue() normally checks that inputs have the same number of 454 * limbs as the modulus. For negative testing we can ask it to skip this 455 * with a non-zero final parameter. */ 456 TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0)); 457 TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0)); 458 TEST_EQUAL(0, test_read_residue(&s, &m, input_S, expected_ret != 0)); 459 460 size_t limbs = m.limbs; 461 size_t bytes = limbs * sizeof(*X_raw); 462 463 if (expected_ret == 0) { 464 /* Negative test with too many limbs in output */ 465 TEST_CALLOC(X_raw, limbs + 1); 466 467 x.p = X_raw; 468 x.limbs = limbs + 1; 469 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 470 mbedtls_mpi_mod_add(&x, &a, &b, &m)); 471 472 mbedtls_free(X_raw); 473 X_raw = NULL; 474 475 /* Negative test with too few limbs in output */ 476 if (limbs > 1) { 477 TEST_CALLOC(X_raw, limbs - 1); 478 479 x.p = X_raw; 480 x.limbs = limbs - 1; 481 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 482 mbedtls_mpi_mod_add(&x, &a, &b, &m)); 483 484 mbedtls_free(X_raw); 485 X_raw = NULL; 486 } 487 488 /* Negative testing with too many/too few limbs in a and b is covered by 489 * manually-written test cases with oret != 0. */ 490 } 491 492 /* Allocate correct number of limbs for X_raw */ 493 TEST_CALLOC(X_raw, limbs); 494 495 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs)); 496 497 /* A + B => Correct result or expected error */ 498 TEST_EQUAL(expected_ret, mbedtls_mpi_mod_add(&x, &a, &b, &m)); 499 if (expected_ret != 0) { 500 goto exit; 501 } 502 503 TEST_COMPARE_MPI_RESIDUES(x, s); 504 505 /* a + b: alias x to a => Correct result */ 506 memcpy(x.p, a.p, bytes); 507 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &b, &m)); 508 TEST_COMPARE_MPI_RESIDUES(x, s); 509 510 /* a + b: alias x to b => Correct result */ 511 memcpy(x.p, b.p, bytes); 512 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &x, &m)); 513 TEST_COMPARE_MPI_RESIDUES(x, s); 514 515 if (memcmp(a.p, b.p, bytes) == 0) { 516 /* a == b: alias a and b */ 517 518 /* a + a => Correct result */ 519 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &a, &m)); 520 TEST_COMPARE_MPI_RESIDUES(x, s); 521 522 /* a + a: x, a, b all aliased together => Correct result */ 523 memcpy(x.p, a.p, bytes); 524 TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &x, &m)); 525 TEST_COMPARE_MPI_RESIDUES(x, s); 526 } 527 528exit: 529 mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */ 530 mbedtls_mpi_mod_modulus_free(&m); 531 532 mbedtls_free(a.p); 533 mbedtls_free(b.p); 534 mbedtls_free(s.p); 535 mbedtls_free(X_raw); 536} 537/* END_CASE */ 538 539/* BEGIN_CASE */ 540void mpi_residue_setup(char *input_N, char *input_R, int ret) 541{ 542 mbedtls_mpi_uint *N = NULL; 543 mbedtls_mpi_uint *R = NULL; 544 size_t n_limbs, r_limbs; 545 mbedtls_mpi_mod_modulus m; 546 mbedtls_mpi_mod_residue r; 547 548 mbedtls_mpi_mod_modulus_init(&m); 549 550 /* Allocate the memory for intermediate data structures */ 551 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N)); 552 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&R, &r_limbs, input_R)); 553 554 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs)); 555 556 TEST_EQUAL(ret, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs)); 557 558 if (ret == 0) { 559 TEST_EQUAL(r.limbs, r_limbs); 560 TEST_ASSERT(r.p == R); 561 } 562 563exit: 564 mbedtls_mpi_mod_modulus_free(&m); 565 mbedtls_free(N); 566 mbedtls_free(R); 567} 568/* END_CASE */ 569 570/* BEGIN_CASE */ 571void mpi_mod_io_neg(char *input_N, data_t *buf, int ret) 572{ 573 mbedtls_mpi_uint *N = NULL; 574 mbedtls_mpi_uint *R = NULL; 575 576 mbedtls_mpi_mod_modulus m; 577 mbedtls_mpi_mod_residue r = { NULL, 0 }; 578 mbedtls_mpi_mod_ext_rep endian = MBEDTLS_MPI_MOD_EXT_REP_LE; 579 580 mbedtls_mpi_mod_modulus_init(&m); 581 582 size_t n_limbs; 583 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N)); 584 size_t r_limbs = n_limbs; 585 TEST_CALLOC(R, r_limbs); 586 587 /* modulus->p == NULL || residue->p == NULL ( m has not been set-up ) */ 588 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 589 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian)); 590 591 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 592 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian)); 593 594 /* Set up modulus and test with residue->p == NULL */ 595 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs)); 596 597 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 598 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian)); 599 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 600 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian)); 601 602 /* Do the rest of the tests with a residue set up with the input data */ 603 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs)); 604 605 /* Fail for r_limbs < m->limbs */ 606 r.limbs--; 607 TEST_ASSERT(r.limbs < m.limbs); 608 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 609 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian)); 610 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 611 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian)); 612 r.limbs++; 613 614 /* Fail for r_limbs > m->limbs */ 615 m.limbs--; 616 TEST_ASSERT(r.limbs > m.limbs); 617 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 618 mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian)); 619 TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, 620 mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian)); 621 m.limbs++; 622 623 /* Test the read */ 624 TEST_EQUAL(ret, mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian)); 625 626 /* Test write overflow only when the representation is large and read is successful */ 627 if (r.limbs > 1 && ret == 0) { 628 TEST_EQUAL(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL, 629 mbedtls_mpi_mod_write(&r, &m, buf->x, 1, endian)); 630 } 631 632exit: 633 mbedtls_mpi_mod_residue_release(&r); 634 mbedtls_mpi_mod_modulus_free(&m); 635 mbedtls_free(N); 636 mbedtls_free(R); 637} 638/* END_CASE */ 639 640/* BEGIN_CASE */ 641void mpi_mod_io(char *input_N, data_t *input_A, int endian) 642{ 643 mbedtls_mpi_uint *N = NULL; 644 mbedtls_mpi_uint *R = NULL; 645 mbedtls_mpi_uint *R_COPY = NULL; 646 unsigned char *obuf = NULL; 647 unsigned char *ref_buf = NULL; 648 mbedtls_mpi_mod_modulus m; 649 mbedtls_mpi_mod_residue r; 650 mbedtls_mpi_mod_residue r_copy; 651 size_t n_limbs, n_bytes, a_bytes; 652 653 mbedtls_mpi_mod_modulus_init(&m); 654 655 /* Read inputs */ 656 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N)); 657 n_bytes = n_limbs * sizeof(mbedtls_mpi_uint); 658 a_bytes = input_A->len; 659 660 /* Allocate the memory for intermediate data structures */ 661 TEST_CALLOC(R, n_bytes); 662 TEST_CALLOC(R_COPY, n_bytes); 663 664 /* Test that input's size is not greater to modulo's */ 665 TEST_LE_U(a_bytes, n_bytes); 666 667 /* Init Structures */ 668 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs)); 669 670 /* Enforcing p_limbs >= m->limbs */ 671 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, n_limbs)); 672 673 TEST_EQUAL(0, mbedtls_mpi_mod_read(&r, &m, input_A->x, input_A->len, 674 endian)); 675 676 /* Read a copy for checking that writing didn't change the value of r */ 677 TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r_copy, &m, 678 R_COPY, n_limbs)); 679 TEST_EQUAL(0, mbedtls_mpi_mod_read(&r_copy, &m, input_A->x, input_A->len, 680 endian)); 681 682 /* Get number of bytes without leading zeroes */ 683 size_t a_bytes_trimmed = a_bytes; 684 while (a_bytes_trimmed > 0) { 685 unsigned char *r_byte_array = (unsigned char *) r.p; 686 if (r_byte_array[--a_bytes_trimmed] != 0) { 687 break; 688 } 689 } 690 a_bytes_trimmed++; 691 692 /* Test write with three output buffer sizes: tight, same as input and 693 * longer than the input */ 694 size_t obuf_sizes[3]; 695 const size_t obuf_sizes_len = sizeof(obuf_sizes) / sizeof(obuf_sizes[0]); 696 obuf_sizes[0] = a_bytes_trimmed; 697 obuf_sizes[1] = a_bytes; 698 obuf_sizes[2] = a_bytes + 8; 699 700 for (size_t i = 0; i < obuf_sizes_len; i++) { 701 TEST_CALLOC(obuf, obuf_sizes[i]); 702 TEST_EQUAL(0, mbedtls_mpi_mod_write(&r, &m, obuf, obuf_sizes[i], endian)); 703 704 /* Make sure that writing didn't corrupt the value of r */ 705 TEST_MEMORY_COMPARE(r.p, r.limbs, r_copy.p, r_copy.limbs); 706 707 /* Set up reference output for checking the result */ 708 TEST_CALLOC(ref_buf, obuf_sizes[i]); 709 switch (endian) { 710 case MBEDTLS_MPI_MOD_EXT_REP_LE: 711 memcpy(ref_buf, input_A->x, a_bytes_trimmed); 712 break; 713 case MBEDTLS_MPI_MOD_EXT_REP_BE: 714 { 715 size_t a_offset = input_A->len - a_bytes_trimmed; 716 size_t ref_offset = obuf_sizes[i] - a_bytes_trimmed; 717 memcpy(ref_buf + ref_offset, input_A->x + a_offset, 718 a_bytes_trimmed); 719 } 720 break; 721 default: 722 TEST_ASSERT(0); 723 } 724 725 /* Check the result */ 726 TEST_MEMORY_COMPARE(obuf, obuf_sizes[i], ref_buf, obuf_sizes[i]); 727 728 mbedtls_free(ref_buf); 729 ref_buf = NULL; 730 mbedtls_free(obuf); 731 obuf = NULL; 732 } 733 734exit: 735 mbedtls_mpi_mod_modulus_free(&m); 736 mbedtls_free(N); 737 mbedtls_free(R); 738 mbedtls_free(R_COPY); 739 mbedtls_free(obuf); 740 mbedtls_free(ref_buf); 741} 742/* END_CASE */ 743