diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index 7f718e647..5c9250397 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -894,6 +894,8 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, * * \return \c 0 if successful. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p min or \p N is invalid + * or if they are incompatible. * \return Another negative error code on failure. */ int mbedtls_mpi_random( mbedtls_mpi *X, diff --git a/library/bignum.c b/library/bignum.c index 1cde6b0c2..9145a3d3c 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -2445,6 +2445,11 @@ int mbedtls_mpi_random( mbedtls_mpi *X, size_t n_bits = mbedtls_mpi_bitlen( N ); size_t n_bytes = ( n_bits + 7 ) / 8; + if( min < 0 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + if( mbedtls_mpi_cmp_int( N, min ) <= 0 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + /* * Match the procedure given in RFC 6979 ยง3.3 (deterministic ECDSA) * when f_rng is a suitably parametrized instance of HMAC_DRBG: diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data index a057dcd88..fb2c553d0 100644 --- a/tests/suites/test_suite_mpi.data +++ b/tests/suites/test_suite_mpi.data @@ -1132,6 +1132,15 @@ mpi_random_many:1:"04":1000 MPI random in range: 3..4 mpi_random_many:1:"04":1000 +MPI random bad arguments: min < 0 +mpi_random_fail:-1:"04":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +MPI random bad arguments: min = N = 0 +mpi_random_fail:0:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + +MPI random bad arguments: min = N = 1 +mpi_random_fail:1:"01":MBEDTLS_ERR_MPI_BAD_INPUT_DATA + MPI Selftest depends_on:MBEDTLS_SELF_TEST mpi_selftest: diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function index 8cf53b302..0ca6b6439 100644 --- a/tests/suites/test_suite_mpi.function +++ b/tests/suites/test_suite_mpi.function @@ -1537,6 +1537,28 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret ) +{ + mbedtls_mpi upper_bound; + mbedtls_mpi result; + int actual_ret; + + mbedtls_mpi_init( &upper_bound ); + mbedtls_mpi_init( &result ); + + TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound, + bound_bytes->x, bound_bytes->len ) ); + actual_ret = mbedtls_mpi_random( &result, min, &upper_bound, + mbedtls_test_rnd_std_rand, NULL ); + TEST_EQUAL( expected_ret, actual_ret ); + +exit: + mbedtls_mpi_free( &upper_bound ); + mbedtls_mpi_free( &result ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void mpi_selftest( ) {