mbedtls_mpi_random: check for invalid arguments
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index 7f718e6..5c92503 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -894,6 +894,8 @@
*
* \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 1cde6b0..9145a3d 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -2445,6 +2445,11 @@
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 a057dcd..fb2c553 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -1132,6 +1132,15 @@
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 8cf53b3..0ca6b64 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -1537,6 +1537,28 @@
}
/* 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( )
{