diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index 1cd8b4081..c5ef62dde 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -5,6 +5,154 @@ #include "constant_time_internal.h" #include "test/constant_flow.h" +/** Verifies mbedtls_mpi_core_add(). + * + * \param[in] A Little-endian presentation of the left operand. + * \param[in] B Little-endian presentation of the right operand. + * \param limbs Number of limbs in each MPI (\p A, \p B, \p S and \p X). + * \param[in] S Little-endian presentation of the expected sum. + * \param carry Expected carry from the addition. + * \param[in,out] X Temporary storage to be used for results. + * + * \return 1 if mbedtls_mpi_core_add() passes this test, otherwise 0. + */ +static int mpi_core_verify_add( mbedtls_mpi_uint *A, + mbedtls_mpi_uint *B, + size_t limbs, + mbedtls_mpi_uint *S, + int carry, + mbedtls_mpi_uint *X ) +{ + int ret = 0; + + size_t bytes = limbs * sizeof( *A ); + + /* The test cases have A <= B to avoid repetition, so we test A + B then, + * if A != B, B + A. If A == B, we can test when A and B are aliased */ + + /* A + B */ + + /* A + B => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, B, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* A + B; alias output and first operand => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, B, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* A + B; alias output and second operand => correct result and carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + if ( memcmp( A, B, bytes ) == 0 ) + { + /* A == B, so test where A and B are aliased */ + + /* A + A => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* A + A, output aliased to both operands => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + else + { + /* A != B, so test B + A */ + + /* B + A => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* B + A; alias output and first operand => correct result and carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, A, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + /* B + A; alias output and second operand => correct result and carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, X, limbs ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + + ret = 1; + +exit: + return ret; +} + +/** Verifies mbedtls_mpi_core_add_if(). + * + * \param[in] A Little-endian presentation of the left operand. + * \param[in] B Little-endian presentation of the right operand. + * \param limbs Number of limbs in each MPI (\p A, \p B, \p S and \p X). + * \param[in] S Little-endian presentation of the expected sum. + * \param carry Expected carry from the addition. + * \param[in,out] X Temporary storage to be used for results. + * + * \return 1 if mbedtls_mpi_core_add_if() passes this test, otherwise 0. + */ +static int mpi_core_verify_add_if( mbedtls_mpi_uint *A, + mbedtls_mpi_uint *B, + size_t limbs, + mbedtls_mpi_uint *S, + int carry, + mbedtls_mpi_uint *X ) +{ + int ret = 0; + + size_t bytes = limbs * sizeof( *A ); + + /* The test cases have A <= B to avoid repetition, so we test A + B then, + * if A != B, B + A. If A == B, we can test when A and B are aliased */ + + /* A + B */ + + /* cond = 0 => X unchanged, no carry */ + memcpy( X, A, bytes ); + TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, B, limbs, 0 ) ); + ASSERT_COMPARE( X, bytes, A, bytes ); + + /* cond = 1 => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, B, limbs, 1 ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + + if ( memcmp( A, B, bytes ) == 0 ) + { + /* A == B, so test where A and B are aliased */ + + /* cond = 0 => X unchanged, no carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, X, limbs, 0 ) ); + ASSERT_COMPARE( X, bytes, B, bytes ); + + /* cond = 1 => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, X, limbs, 1 ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + else + { + /* A != B, so test B + A */ + + /* cond = 0 => d unchanged, no carry */ + memcpy( X, B, bytes ); + TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, A, limbs, 0 ) ); + ASSERT_COMPARE( X, bytes, B, bytes ); + + /* cond = 1 => correct result and carry */ + TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, A, limbs, 1 ) ); + ASSERT_COMPARE( X, bytes, S, bytes ); + } + + ret = 1; + +exit: + return ret; +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -375,88 +523,12 @@ void mpi_core_add_and_add_if( char * input_A, char * input_B, /* add and add_if expect all operands to be the same length */ TEST_EQUAL( A_limbs, B_limbs ); TEST_EQUAL( A_limbs, S_limbs ); - size_t limbs = A_limbs; - size_t bytes = limbs * sizeof( *A ); + size_t limbs = A_limbs; ASSERT_ALLOC( X, limbs ); - /* The test cases have A <= B to avoid repetition, so we test A + B then, - * if A != B, B + A. If A == B, we can test when A and B are aliased */ - - /* A + B */ - - /* add => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, B, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and first operand => correct result and carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, B, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and second operand => correct result and carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, X, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add_if: cond = 0 => X unchanged, no carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, B, limbs, 0 ) ); - ASSERT_COMPARE( X, bytes, A, bytes ); - - /* add_if: cond = 1 => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, B, limbs, 1 ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - if ( memcmp( A, B, bytes ) == 0 ) - { - /* A == B, so test where A and B are aliased */ - - /* add => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, A, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, output aliased to both operands => correct result and carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, X, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add_if: cond = 0 => X unchanged, no carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, X, limbs, 0 ) ); - ASSERT_COMPARE( X, bytes, B, bytes ); - - /* add_if: cond = 1 => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, X, limbs, 1 ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - } - else - { - /* A != B, so test B + A */ - - /* add => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, A, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and first operand => correct result and carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, A, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add, alias output and second operand => correct result and carry */ - memcpy( X, A, bytes ); - TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, X, limbs ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - - /* add_if: cond = 0 => d unchanged, no carry */ - memcpy( X, B, bytes ); - TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, A, limbs, 0 ) ); - ASSERT_COMPARE( X, bytes, B, bytes ); - - /* add_if: cond = 1 => correct result and carry */ - TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, A, limbs, 1 ) ); - ASSERT_COMPARE( X, bytes, S, bytes ); - } + TEST_ASSERT( mpi_core_verify_add( A, B, limbs, S, carry, X ) ); + TEST_ASSERT( mpi_core_verify_add_if( A, B, limbs, S, carry, X ) ); exit: mbedtls_free( A );