1/* BEGIN_HEADER */ 2#include "mbedtls/bignum.h" 3#include "mbedtls/entropy.h" 4#include "bignum_core.h" 5#include "bignum_mod_raw.h" 6#include "constant_time_internal.h" 7#include "test/constant_flow.h" 8 9/* END_HEADER */ 10 11/* BEGIN_DEPENDENCIES 12 * depends_on:MBEDTLS_BIGNUM_C 13 * END_DEPENDENCIES 14 */ 15 16/* BEGIN_CASE */ 17void mpi_mod_raw_io( data_t *input, int nb_int, int nx_32_int, 18 int iendian, int iret, int oret ) 19{ 20 mbedtls_mpi_mod_modulus m; 21 mbedtls_mpi_mod_modulus_init( &m ); 22 23 if( iret != 0 ) 24 TEST_ASSERT( oret == 0 ); 25 26 TEST_LE_S( 0, nb_int ); 27 size_t nb = nb_int; 28 29 unsigned char buf[1024]; 30 TEST_LE_U( nb, sizeof( buf ) ); 31 32 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need 33 * to halve the number of limbs to have the same size. */ 34 size_t nx; 35 TEST_LE_S( 0, nx_32_int ); 36 if( sizeof( mbedtls_mpi_uint ) == 8 ) 37 nx = nx_32_int / 2 + nx_32_int % 2; 38 else 39 nx = nx_32_int; 40 41 mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )]; 42 TEST_LE_U( nx, sizeof( X ) / sizeof( X[0] ) ); 43 44 int endian; 45 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID ) 46 endian = MBEDTLS_MPI_MOD_EXT_REP_LE; 47 else 48 endian = iendian; 49 50 mbedtls_mpi_uint init[sizeof( X ) / sizeof( X[0] )]; 51 memset( init, 0xFF, sizeof( init ) ); 52 int ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx, 53 MBEDTLS_MPI_MOD_REP_MONTGOMERY ); 54 TEST_EQUAL( ret, 0 ); 55 56 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 ) 57 endian = MBEDTLS_MPI_MOD_EXT_REP_INVALID; 58 59 ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len, endian ); 60 TEST_EQUAL( ret, iret ); 61 62 if( iret == 0 ) 63 { 64 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 ) 65 endian = MBEDTLS_MPI_MOD_EXT_REP_INVALID; 66 67 ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb, endian ); 68 TEST_EQUAL( ret, oret ); 69 } 70 71 if( ( iret == 0 ) && ( oret == 0 ) ) 72 { 73 if( nb > input->len ) 74 { 75 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE ) 76 { 77 size_t leading_zeroes = nb - input->len; 78 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 ); 79 for( size_t i = 0; i < leading_zeroes; i++ ) 80 TEST_EQUAL( buf[i], 0 ); 81 } 82 else 83 { 84 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 ); 85 for( size_t i = input->len; i < nb; i++ ) 86 TEST_EQUAL( buf[i], 0 ); 87 } 88 } 89 else 90 { 91 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE ) 92 { 93 size_t leading_zeroes = input->len - nb; 94 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 ); 95 for( size_t i = 0; i < leading_zeroes; i++ ) 96 TEST_EQUAL( input->x[i], 0 ); 97 } 98 else 99 { 100 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 ); 101 for( size_t i = nb; i < input->len; i++ ) 102 TEST_EQUAL( input->x[i], 0 ); 103 } 104 } 105 } 106 107exit: 108 mbedtls_mpi_mod_modulus_free( &m ); 109} 110/* END_CASE */ 111 112/* BEGIN_CASE */ 113void mpi_mod_raw_cond_assign( char * input_X, 114 char * input_Y, 115 int input_bytes ) 116{ 117 mbedtls_mpi_uint *X = NULL; 118 mbedtls_mpi_uint *Y = NULL; 119 mbedtls_mpi_uint *buff_m = NULL; 120 size_t limbs_X; 121 size_t limbs_Y; 122 123 mbedtls_mpi_mod_modulus m; 124 mbedtls_mpi_mod_modulus_init( &m ); 125 126 TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs_X, input_X ), 0 ); 127 TEST_EQUAL( mbedtls_test_read_mpi_core( &Y, &limbs_Y, input_Y ), 0 ); 128 129 size_t limbs = limbs_X; 130 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes ); 131 size_t bytes = limbs * sizeof( mbedtls_mpi_uint ); 132 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint ); 133 134 TEST_EQUAL( limbs_X, limbs_Y ); 135 TEST_ASSERT( copy_limbs <= limbs ); 136 137 ASSERT_ALLOC( buff_m, copy_limbs ); 138 memset( buff_m, 0xFF, copy_limbs ); 139 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup( 140 &m, buff_m, copy_limbs, 141 MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 ); 142 143 /* condition is false */ 144 TEST_CF_SECRET( X, bytes ); 145 TEST_CF_SECRET( Y, bytes ); 146 147 mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 0 ); 148 149 TEST_CF_PUBLIC( X, bytes ); 150 TEST_CF_PUBLIC( Y, bytes ); 151 152 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 ); 153 154 /* condition is true */ 155 TEST_CF_SECRET( X, bytes ); 156 TEST_CF_SECRET( Y, bytes ); 157 158 mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 1 ); 159 160 TEST_CF_PUBLIC( X, bytes ); 161 TEST_CF_PUBLIC( Y, bytes ); 162 163 /* Check if the given length is copied even it is smaller 164 than the length of the given MPIs. */ 165 if( copy_limbs <limbs ) 166 { 167 ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes ); 168 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 ); 169 } 170 else 171 ASSERT_COMPARE( X, bytes, Y, bytes ); 172 173exit: 174 mbedtls_free( X ); 175 mbedtls_free( Y ); 176 177 mbedtls_mpi_mod_modulus_free( &m ); 178 mbedtls_free( buff_m ); 179} 180/* END_CASE */ 181 182/* BEGIN_CASE */ 183void mpi_mod_raw_cond_swap( char * input_X, 184 char * input_Y, 185 int input_bytes ) 186{ 187 mbedtls_mpi_uint *tmp_X = NULL; 188 mbedtls_mpi_uint *tmp_Y = NULL; 189 mbedtls_mpi_uint *X = NULL; 190 mbedtls_mpi_uint *Y = NULL; 191 mbedtls_mpi_uint *buff_m = NULL; 192 size_t limbs_X; 193 size_t limbs_Y; 194 195 mbedtls_mpi_mod_modulus m; 196 mbedtls_mpi_mod_modulus_init( &m ); 197 198 TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_X, &limbs_X, input_X ), 0 ); 199 TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_Y, &limbs_Y, input_Y ), 0 ); 200 201 size_t limbs = limbs_X; 202 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes ); 203 size_t bytes = limbs * sizeof( mbedtls_mpi_uint ); 204 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint ); 205 206 TEST_EQUAL( limbs_X, limbs_Y ); 207 TEST_ASSERT( copy_limbs <= limbs ); 208 209 ASSERT_ALLOC( buff_m, copy_limbs ); 210 memset( buff_m, 0xFF, copy_limbs ); 211 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup( 212 &m, buff_m, copy_limbs, 213 MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 ); 214 215 ASSERT_ALLOC( X, limbs ); 216 memcpy( X, tmp_X, bytes ); 217 218 ASSERT_ALLOC( Y, bytes ); 219 memcpy( Y, tmp_Y, bytes ); 220 221 /* condition is false */ 222 TEST_CF_SECRET( X, bytes ); 223 TEST_CF_SECRET( Y, bytes ); 224 225 mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 0 ); 226 227 TEST_CF_PUBLIC( X, bytes ); 228 TEST_CF_PUBLIC( Y, bytes ); 229 230 ASSERT_COMPARE( X, bytes, tmp_X, bytes ); 231 ASSERT_COMPARE( Y, bytes, tmp_Y, bytes ); 232 233 /* condition is true */ 234 TEST_CF_SECRET( X, bytes ); 235 TEST_CF_SECRET( Y, bytes ); 236 237 mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 1 ); 238 239 TEST_CF_PUBLIC( X, bytes ); 240 TEST_CF_PUBLIC( Y, bytes ); 241 242 /* Check if the given length is copied even it is smaller 243 than the length of the given MPIs. */ 244 if( copy_limbs < limbs ) 245 { 246 ASSERT_COMPARE( X, copy_bytes, tmp_Y, copy_bytes ); 247 ASSERT_COMPARE( Y, copy_bytes, tmp_X, copy_bytes ); 248 TEST_ASSERT( memcmp( X, tmp_X, bytes ) != 0 ); 249 TEST_ASSERT( memcmp( X, tmp_Y, bytes ) != 0 ); 250 TEST_ASSERT( memcmp( Y, tmp_X, bytes ) != 0 ); 251 TEST_ASSERT( memcmp( Y, tmp_Y, bytes ) != 0 ); 252 } 253 else 254 { 255 ASSERT_COMPARE( X, bytes, tmp_Y, bytes ); 256 ASSERT_COMPARE( Y, bytes, tmp_X, bytes ); 257 } 258 259exit: 260 mbedtls_free( tmp_X ); 261 mbedtls_free( tmp_Y ); 262 mbedtls_free( X ); 263 mbedtls_free( Y ); 264 265 mbedtls_mpi_mod_modulus_free( &m ); 266 mbedtls_free( buff_m ); 267} 268/* END_CASE */ 269 270/* BEGIN MERGE SLOT 1 */ 271 272/* END MERGE SLOT 1 */ 273 274/* BEGIN MERGE SLOT 2 */ 275 276/* BEGIN_CASE */ 277void mpi_mod_raw_sub( char * input_A, 278 char * input_B, 279 char * input_N, 280 char * result ) 281{ 282 mbedtls_mpi_uint *A = NULL; 283 mbedtls_mpi_uint *B = NULL; 284 mbedtls_mpi_uint *N = NULL; 285 mbedtls_mpi_uint *X = NULL; 286 mbedtls_mpi_uint *res = NULL; 287 size_t limbs_A; 288 size_t limbs_B; 289 size_t limbs_N; 290 size_t limbs_res; 291 292 mbedtls_mpi_mod_modulus m; 293 mbedtls_mpi_mod_modulus_init( &m ); 294 295 TEST_EQUAL( mbedtls_test_read_mpi_core( &A, &limbs_A, input_A ), 0 ); 296 TEST_EQUAL( mbedtls_test_read_mpi_core( &B, &limbs_B, input_B ), 0 ); 297 TEST_EQUAL( mbedtls_test_read_mpi_core( &N, &limbs_N, input_N ), 0 ); 298 TEST_EQUAL( mbedtls_test_read_mpi_core( &res, &limbs_res, result ), 0 ); 299 300 size_t limbs = limbs_N; 301 size_t bytes = limbs * sizeof( mbedtls_mpi_uint ); 302 303 TEST_EQUAL( limbs_A, limbs ); 304 TEST_EQUAL( limbs_B, limbs ); 305 TEST_EQUAL( limbs_res, limbs ); 306 307 ASSERT_ALLOC( X, limbs ); 308 309 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup( 310 &m, N, limbs, 311 MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 ); 312 313 mbedtls_mpi_mod_raw_sub( X, A, B, &m ); 314 ASSERT_COMPARE( X, bytes, res, bytes ); 315 316 /* alias X to A */ 317 memcpy( X, A, bytes ); 318 mbedtls_mpi_mod_raw_sub( X, X, B, &m ); 319 ASSERT_COMPARE( X, bytes, res, bytes ); 320 321 /* alias X to B */ 322 memcpy( X, B, bytes ); 323 mbedtls_mpi_mod_raw_sub( X, A, X, &m ); 324 ASSERT_COMPARE( X, bytes, res, bytes ); 325 326 /* A == B: alias A and B */ 327 if( memcmp( A, B, bytes ) == 0 ) 328 { 329 mbedtls_mpi_mod_raw_sub( X, A, A, &m ); 330 ASSERT_COMPARE( X, bytes, res, bytes ); 331 332 /* X, A, B all aliased together */ 333 memcpy( X, A, bytes ); 334 mbedtls_mpi_mod_raw_sub( X, X, X, &m ); 335 ASSERT_COMPARE( X, bytes, res, bytes ); 336 } 337exit: 338 mbedtls_free( A ); 339 mbedtls_free( B ); 340 mbedtls_free( X ); 341 mbedtls_free( res ); 342 343 mbedtls_mpi_mod_modulus_free( &m ); 344 mbedtls_free( N ); 345} 346/* END_CASE */ 347 348/* END MERGE SLOT 2 */ 349 350/* BEGIN MERGE SLOT 3 */ 351 352/* END MERGE SLOT 3 */ 353 354/* BEGIN MERGE SLOT 4 */ 355 356/* END MERGE SLOT 4 */ 357 358/* BEGIN MERGE SLOT 5 */ 359 360/* BEGIN_CASE */ 361void mpi_mod_raw_add( char * input_N, 362 char * input_A, char * input_B, 363 char * input_S ) 364{ 365 mbedtls_mpi_uint *A = NULL; 366 mbedtls_mpi_uint *B = NULL; 367 mbedtls_mpi_uint *S = NULL; 368 mbedtls_mpi_uint *N = NULL; 369 mbedtls_mpi_uint *X = NULL; 370 size_t A_limbs, B_limbs, N_limbs, S_limbs; 371 372 mbedtls_mpi_mod_modulus m; 373 mbedtls_mpi_mod_modulus_init( &m ); 374 375 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) ); 376 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &B, &B_limbs, input_B ) ); 377 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &N_limbs, input_N ) ); 378 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &S, &S_limbs, input_S ) ); 379 380 /* Modulus gives the number of limbs; all inputs must have the same. */ 381 size_t limbs = N_limbs; 382 size_t bytes = limbs * sizeof( *A ); 383 384 TEST_EQUAL( A_limbs, limbs ); 385 TEST_EQUAL( B_limbs, limbs ); 386 TEST_EQUAL( S_limbs, limbs ); 387 388 ASSERT_ALLOC( X, limbs ); 389 390 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup( 391 &m, N, limbs, 392 MBEDTLS_MPI_MOD_REP_MONTGOMERY 393 ), 0 ); 394 395 /* A + B => Correct result */ 396 mbedtls_mpi_mod_raw_add( X, A, B, &m ); 397 ASSERT_COMPARE( X, bytes, S, bytes ); 398 399 /* A + B: alias X to A => Correct result */ 400 memcpy( X, A, bytes ); 401 mbedtls_mpi_mod_raw_add( X, X, B, &m ); 402 ASSERT_COMPARE( X, bytes, S, bytes ); 403 404 /* A + B: alias X to B => Correct result */ 405 memcpy( X, B, bytes ); 406 mbedtls_mpi_mod_raw_add( X, A, X, &m ); 407 ASSERT_COMPARE( X, bytes, S, bytes ); 408 409 if ( memcmp(A, B, bytes ) == 0 ) 410 { 411 /* A == B: alias A and B */ 412 413 /* A + A => Correct result */ 414 mbedtls_mpi_mod_raw_add( X, A, A, &m ); 415 ASSERT_COMPARE( X, bytes, S, bytes ); 416 417 /* A + A: X, A, B all aliased together => Correct result */ 418 memcpy( X, A, bytes ); 419 mbedtls_mpi_mod_raw_add( X, X, X, &m ); 420 ASSERT_COMPARE( X, bytes, S, bytes ); 421 } 422 else 423 { 424 /* A != B: test B + A */ 425 426 /* B + A => Correct result */ 427 mbedtls_mpi_mod_raw_add( X, B, A, &m ); 428 ASSERT_COMPARE( X, bytes, S, bytes ); 429 430 /* B + A: alias X to A => Correct result */ 431 memcpy( X, A, bytes ); 432 mbedtls_mpi_mod_raw_add( X, B, X, &m ); 433 ASSERT_COMPARE( X, bytes, S, bytes ); 434 435 /* B + A: alias X to B => Correct result */ 436 memcpy( X, B, bytes ); 437 mbedtls_mpi_mod_raw_add( X, X, A, &m ); 438 ASSERT_COMPARE( X, bytes, S, bytes ); 439 } 440 441exit: 442 mbedtls_mpi_mod_modulus_free( &m ); 443 444 mbedtls_free( A ); 445 mbedtls_free( B ); 446 mbedtls_free( S ); 447 mbedtls_free( N ); 448 mbedtls_free( X ); 449} 450/* END_CASE */ 451/* END MERGE SLOT 5 */ 452 453/* BEGIN MERGE SLOT 6 */ 454 455/* END MERGE SLOT 6 */ 456 457/* BEGIN MERGE SLOT 7 */ 458/* BEGIN_CASE */ 459void mpi_mod_raw_to_mont_rep( char * input_N, char * input_A, char * input_X ) 460{ 461 mbedtls_mpi_uint *N = NULL; 462 mbedtls_mpi_uint *A = NULL; 463 mbedtls_mpi_uint *X = NULL; 464 size_t n_limbs, a_limbs, x_limbs, x_bytes; 465 466 mbedtls_mpi_mod_modulus m; 467 mbedtls_mpi_mod_modulus_init( &m ); 468 469 /* Read inputs */ 470 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) ); 471 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &a_limbs, input_A ) ); 472 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &x_limbs, input_X ) ); 473 x_bytes = x_limbs * sizeof(mbedtls_mpi_uint); 474 475 /* Test that input does not require more limbs than modulo */ 476 TEST_LE_U(a_limbs, n_limbs); 477 478 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs, 479 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) ); 480 481 /* Convert from cannonical into Montgomery representation */ 482 TEST_EQUAL(0, mbedtls_mpi_mod_raw_to_mont_rep( A, &m ) ); 483 484 /* The result matches expected value */ 485 ASSERT_COMPARE( A, x_bytes, X, x_bytes ); 486exit: 487 mbedtls_mpi_mod_modulus_free( &m ); 488 mbedtls_free( N ); 489 mbedtls_free( A ); 490 mbedtls_free( X ); 491} 492/* END_CASE */ 493 494/* BEGIN_CASE */ 495void mpi_mod_raw_from_mont_rep( char * input_N, char * input_A, char * input_X ) 496{ 497 mbedtls_mpi_uint *N = NULL; 498 mbedtls_mpi_uint *A = NULL; 499 mbedtls_mpi_uint *X = NULL; 500 size_t n_limbs, a_limbs, x_limbs, x_bytes; 501 502 mbedtls_mpi_mod_modulus m; 503 mbedtls_mpi_mod_modulus_init( &m ); 504 505 /* Read inputs */ 506 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) ); 507 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &a_limbs, input_A ) ); 508 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &x_limbs, input_X ) ); 509 x_bytes = x_limbs * sizeof(mbedtls_mpi_uint); 510 511 /* Test that input does not require more limbs than modulo */ 512 TEST_LE_U(a_limbs, n_limbs); 513 514 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs, 515 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) ); 516 517 /* Convert from Montgomery into cannonical representation */ 518 TEST_EQUAL(0, mbedtls_mpi_mod_raw_from_mont_rep( A, &m ) ); 519 520 /* The result matches expected value */ 521 ASSERT_COMPARE( A, x_bytes, X, x_bytes ); 522exit: 523 mbedtls_mpi_mod_modulus_free( &m ); 524 mbedtls_free( N ); 525 mbedtls_free( A ); 526 mbedtls_free( X ); 527} 528/* END_CASE */ 529/* END MERGE SLOT 7 */ 530 531/* BEGIN MERGE SLOT 8 */ 532 533/* END MERGE SLOT 8 */ 534 535/* BEGIN MERGE SLOT 9 */ 536 537/* END MERGE SLOT 9 */ 538 539/* BEGIN MERGE SLOT 10 */ 540 541/* END MERGE SLOT 10 */ 542