Test mbedtls_mpi_random differentially from mbedtls_mpi_core_random

For good cases, test that mbedtls_mpi_random() produces the same output as
mbedtls_mpi_core_random().

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function
index 55bb2f5..cf54920 100644
--- a/tests/suites/test_suite_bignum.function
+++ b/tests/suites/test_suite_bignum.function
@@ -2,6 +2,7 @@
 #include "mbedtls/bignum.h"
 #include "mbedtls/entropy.h"
 #include "constant_time_internal.h"
+#include "bignum_core.h"
 #include "test/constant_flow.h"
 
 #if MBEDTLS_MPI_MAX_BITS > 792
@@ -1295,6 +1296,57 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mpi_random_values( int min, char *max_hex )
+{
+    mbedtls_test_rnd_pseudo_info rnd_core = {
+        {'T', 'h', 'i', 's', ' ', 'i', ',', 'a',
+         's', 'e', 'e', 'd', '!', 0},
+        0, 0};
+    mbedtls_test_rnd_pseudo_info rnd_legacy;
+    memcpy( &rnd_legacy, &rnd_core, sizeof( rnd_core ) );
+    mbedtls_mpi max_legacy;
+    mbedtls_mpi_init( &max_legacy );
+    mbedtls_mpi_uint *R_core = NULL;
+    mbedtls_mpi R_legacy;
+    mbedtls_mpi_init( &R_legacy );
+
+    TEST_EQUAL( 0, mbedtls_test_read_mpi( &max_legacy, max_hex ) );
+    size_t limbs = max_legacy.n;
+    ASSERT_ALLOC( R_core, limbs * ciL );
+
+    /* Call the legacy function and the core function with the same random
+     * stream. */
+    int core_ret = mbedtls_mpi_core_random( R_core, min, max_legacy.p, limbs,
+                                            mbedtls_test_rnd_pseudo_rand,
+                                            &rnd_core );
+    int legacy_ret = mbedtls_mpi_random( &R_legacy, min, &max_legacy,
+                                         mbedtls_test_rnd_pseudo_rand,
+                                         &rnd_legacy );
+
+    /* They must return the same status, and, on success, output the
+     * same number, with the same limb count. */
+    TEST_EQUAL( core_ret, legacy_ret );
+    if( core_ret == 0 )
+    {
+        ASSERT_COMPARE( R_core, limbs * ciL,
+                        R_legacy.p, R_legacy.n * ciL );
+    }
+
+    /* Also check that they have consumed the RNG in the same way. */
+    /* This may theoretically fail on rare platforms with padding in
+     * the structure! If this is a problem in practice, change to a
+     * field-by-field comparison. */
+    ASSERT_COMPARE( &rnd_core, sizeof( rnd_core ),
+                    &rnd_legacy, sizeof( rnd_legacy ) );
+
+exit:
+    mbedtls_mpi_free( &max_legacy );
+    mbedtls_free( R_core );
+    mbedtls_mpi_free( &R_legacy );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mpi_random_many( int min, data_t *bound_bytes, int iterations )
 {
     /* Generate numbers in the range 1..bound-1. Do it iterations times.
@@ -1481,7 +1533,6 @@
     mbedtls_mpi_init( &R );
     mbedtls_mpi_init( &X );
 
-    const size_t biL = 8 * sizeof( mbedtls_mpi_sint );
     mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << ( biL - 1 );
     const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
     const mbedtls_mpi_sint most_negative = - most_positive - 1;
diff --git a/tests/suites/test_suite_bignum.misc.data b/tests/suites/test_suite_bignum.misc.data
index dc6830e..bc659c1 100644
--- a/tests/suites/test_suite_bignum.misc.data
+++ b/tests/suites/test_suite_bignum.misc.data
@@ -1958,6 +1958,41 @@
 MPI random bad arguments: min > N = 1, 0 limb in upper bound
 mpi_random_fail:2:"000000000000000001":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
+MPI random legacy=core: 0..1
+mpi_random_values:0:"01"
+
+MPI random legacy=core: 0..2
+mpi_random_values:0:"02"
+
+MPI random legacy=core: 1..2
+mpi_random_values:1:"02"
+
+MPI random legacy=core: 2^30..2^31
+mpi_random_values:0x40000000:"80000000"
+
+MPI random legacy=core: 2^31-1..2^32-1
+mpi_random_values:0x7fffffff:"ffffffff"
+
+MPI random legacy=core: 0..2^256
+mpi_random_values:0:"010000000000000000000000000000000000000000000000000000000000000000"
+
+MPI random legacy=core: 0..2^256+1
+mpi_random_values:0:"010000000000000000000000000000000000000000000000000000000000000001"
+
+# The following test cases return MPI_NOT_ACCEPTABLE
+# (verified at the time of writing, not enforced at runtime)
+MPI random legacy=core: 2^28-1..2^28 (improbable)
+mpi_random_values:0x0fffffff:"10000000"
+
+MPI random legacy=core: 2^29-1..2^29 (improbable)
+mpi_random_values:0x1fffffff:"20000000"
+
+MPI random legacy=core: 2^30-1..2^30 (improbable)
+mpi_random_values:0x3fffffff:"40000000"
+
+MPI random legacy=core: 2^31-1..2^31 (improbable)
+mpi_random_values:0x7fffffff:"80000000"
+
 Most negative mbedtls_mpi_sint
 most_negative_mpi_sint: