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