MPI random: add unit tests with a previously nonzero value

Add unit tests for mbedtls_mpi_fill_random() and mbedtls_mpi_random()
when the resulting MPI object previously had a nonzero value. I wrote
those to catch a bug that I introduced during the development of
mbedtls_mpi_random() (but does not appear in a committed version).

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 3488854..6cd62f1 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -992,46 +992,76 @@
 mbedtls_mpi_set_bit:16:"00":5:2:16:"00":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
 
 Fill random: 0 bytes
-mpi_fill_random:0:0:0
+mpi_fill_random:0:0:0:0
 
 Fill random: 1 byte, good
-mpi_fill_random:1:1:0
+mpi_fill_random:1:1:0:0
 
 Fill random: 2 bytes, good, no leading zero
-mpi_fill_random:2:2:0
+mpi_fill_random:2:2:0:0
 
 Fill random: 2 bytes, good, 1 leading zero
-mpi_fill_random:2:256:0
+mpi_fill_random:2:256:0:0
 
 Fill random: MAX_SIZE - 7, good
-mpi_fill_random:MBEDTLS_MPI_MAX_SIZE - 7:MBEDTLS_MPI_MAX_SIZE - 7:0
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE - 7:MBEDTLS_MPI_MAX_SIZE - 7:0:0
 
 Fill random: MAX_SIZE, good
-mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE:0
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE:0:0
+
+Fill random: 0 bytes, previously small >0
+mpi_fill_random:0:0:1:0
+
+Fill random: 0 bytes, previously small <0
+mpi_fill_random:0:0:-1:0
+
+Fill random: 0 bytes, previously large >0
+mpi_fill_random:0:0:65:0
+
+Fill random: 0 bytes, previously large <0
+mpi_fill_random:0:0:-65:0
+
+Fill random: 1 byte, previously small >0
+mpi_fill_random:1:1:1:0
+
+Fill random: 1 byte, previously small <0
+mpi_fill_random:1:1:-1:0
+
+Fill random: 1 byte, previously large >0
+mpi_fill_random:1:1:65:0
+
+Fill random: 1 byte, previously large <0
+mpi_fill_random:1:1:-65:0
+
+Fill random: 9 bytes, previously small >0
+mpi_fill_random:1:1:1:0
+
+Fill random: 9 bytes, previously small <0
+mpi_fill_random:1:1:-1:0
 
 Fill random: 1 byte, RNG failure
-mpi_fill_random:1:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:1:0:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 Fill random: 2 bytes, RNG failure after 1 byte
-mpi_fill_random:2:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:2:1:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 Fill random: 4 bytes, RNG failure after 3 bytes
-mpi_fill_random:4:3:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:4:3:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 Fill random: 8 bytes, RNG failure after 7 bytes
-mpi_fill_random:8:7:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:8:7:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 Fill random: 16 bytes, RNG failure after 1 bytes
-mpi_fill_random:16:1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:16:1:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 Fill random: 16 bytes, RNG failure after 8 bytes
-mpi_fill_random:16:8:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:16:8:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 Fill random: 16 bytes, RNG failure after 15 bytes
-mpi_fill_random:16:15:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:16:15:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 Fill random: MAX_SIZE bytes, RNG failure after MAX_SIZE-1 bytes
-mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE-1:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+mpi_fill_random:MBEDTLS_MPI_MAX_SIZE:MBEDTLS_MPI_MAX_SIZE-1:0:MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
 
 MPI random in range: 1..4
 mpi_random_many:1:"04":1000
@@ -1133,31 +1163,43 @@
 mpi_random_many:1:"04":1000
 
 MPI random in range: smaller result
-mpi_random_grown:1:"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb":1
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb":1:0
 
 MPI random in range: same size result (32-bit limbs)
-mpi_random_grown:1:"aaaaaaaaaaaaaaaa":2
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":2:0
 
 MPI random in range: same size result (64-bit limbs)
-mpi_random_grown:1:"aaaaaaaaaaaaaaaa":1
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":1:0
 
 MPI random in range: larger result
-mpi_random_grown:1:"aaaaaaaaaaaaaaaa":3
+mpi_random_sizes:1:"aaaaaaaaaaaaaaaa":3:0
 
 MPI random in range: leading 0 limb in upper bound #0
-mpi_random_grown:1:"00aaaaaaaaaaaaaaaa":0
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":0:0
 
 MPI random in range: leading 0 limb in upper bound #1
-mpi_random_grown:1:"00aaaaaaaaaaaaaaaa":1
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":1:0
 
 MPI random in range: leading 0 limb in upper bound #2
-mpi_random_grown:1:"00aaaaaaaaaaaaaaaa":2
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":2:0
 
 MPI random in range: leading 0 limb in upper bound #3
-mpi_random_grown:1:"00aaaaaaaaaaaaaaaa":3
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":3:0
 
 MPI random in range: leading 0 limb in upper bound #4
-mpi_random_grown:1:"00aaaaaaaaaaaaaaaa":4
+mpi_random_sizes:1:"00aaaaaaaaaaaaaaaa":4:0
+
+MPI random in range: previously small >0
+mpi_random_sizes:1:"1234567890":4:1
+
+MPI random in range: previously small <0
+mpi_random_sizes:1:"1234567890":4:-1
+
+MPI random in range: previously large >0
+mpi_random_sizes:1:"1234":4:65
+
+MPI random in range: previously large <0
+mpi_random_sizes:1:"1234":4:-65
 
 MPI random bad arguments: min < 0
 mpi_random_fail:-1:"04":MBEDTLS_ERR_MPI_BAD_INPUT_DATA
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index f3c9107..e82fe99 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -1400,13 +1400,23 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mpi_fill_random( int wanted_bytes, int rng_bytes, int expected_ret )
+void mpi_fill_random( int wanted_bytes, int rng_bytes,
+                      int before, int expected_ret )
 {
     mbedtls_mpi X;
     int ret;
     size_t bytes_left = rng_bytes;
     mbedtls_mpi_init( &X );
 
+    if( before != 0 )
+    {
+        /* Set X to sign(before) * 2^(|before|-1) */
+        TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
+        if( before < 0 )
+            before = - before;
+        TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
+    }
+
     ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
                                    f_rng_bytes_left, &bytes_left );
     TEST_ASSERT( ret == expected_ret );
@@ -1538,7 +1548,7 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void mpi_random_grown( int min, data_t *bound_bytes, int nlimbs )
+void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
 {
     mbedtls_mpi upper_bound;
     mbedtls_mpi result;
@@ -1546,6 +1556,15 @@
     mbedtls_mpi_init( &upper_bound );
     mbedtls_mpi_init( &result );
 
+    if( before != 0 )
+    {
+        /* Set result to sign(before) * 2^(|before|-1) */
+        TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
+        if( before < 0 )
+            before = - before;
+        TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
+    }
+
     TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
     TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
                                             bound_bytes->x, bound_bytes->len ) );