test_suite_bignum_mod: Added tests for hight level IO

This patch adds the following tests for the high levet IO api:
* mpi_mod_io_neg
* mpi_mod_io

Manually generated test data has also been included.

Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
diff --git a/tests/suites/test_suite_bignum_mod.function b/tests/suites/test_suite_bignum_mod.function
index 1a2d0c1..00e8306 100644
--- a/tests/suites/test_suite_bignum_mod.function
+++ b/tests/suites/test_suite_bignum_mod.function
@@ -80,7 +80,149 @@
 /* END MERGE SLOT 6 */
 
 /* BEGIN MERGE SLOT 7 */
+/* BEGIN_CASE */
+void mpi_mod_io_neg( )
+{
+    #define IO_ZERO        0
+    #define IO_ONE         1
+    #define IO_MIN1        2
+    #define IO_MAX         3
+    #define IO_2LIMBS_MIN1 4
+    #define IO_2LIMBS      5
 
+    mbedtls_mpi_uint *N = NULL;
+    mbedtls_mpi_uint *R = NULL;
+    mbedtls_mpi_uint *N2 = NULL;
+    mbedtls_mpi_uint *R2 = NULL;
+    unsigned char *r_buff = NULL;
+
+    size_t n_limbs, r_limbs, n2_limbs, r2_limbs;
+
+    mbedtls_mpi_mod_modulus m;
+    mbedtls_mpi_mod_residue r;
+    mbedtls_mpi_mod_modulus m2;
+    mbedtls_mpi_mod_residue rn = { NULL, 0 };
+
+    const char * s_data[ 6 ] = { "00", "01", "fe", "ff",
+                                 "7ffffffffffffffff0" ,"7ffffffffffffffff1" };
+    const size_t buff_bytes = 1024;
+
+    /* Allocate the memory for intermediate data structures */
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, s_data[ IO_MIN1 ] ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &R, &r_limbs, s_data[ IO_ONE ] ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N2, &n2_limbs, s_data[ IO_2LIMBS ] ) );
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &R2, &r2_limbs, s_data[ IO_2LIMBS_MIN1 ] ) );
+
+    mbedtls_mpi_mod_modulus_init( &m );
+    mbedtls_mpi_mod_modulus_init( &m2 );
+
+    /* Allocate more than required space on buffer so we can test for input_r > mpi */
+    ASSERT_ALLOC( r_buff, buff_bytes );
+    memset( r_buff, 0x1, 1 );
+
+    TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
+                MBEDTLS_MPI_MOD_EXT_REP_LE, MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
+
+    TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R , n_limbs ) );
+
+    /* Pass for input_r < modulo */
+    TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r, &m, r_buff, 1 ) );
+
+    /* input_r == modulo -1 */
+    memset( r_buff, 0xfd, buff_bytes );
+    TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r, &m, r_buff, 1 ) );
+
+    /* modulo->p == NULL || residue->p == NULL ( m2 has not been set-up ) */
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_read( &r, &m2, r_buff, 1 ) );
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_read( &rn, &m, r_buff, 1 ) );
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_write( &r, &m2, r_buff, 1 ) );
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_write( &rn, &m, r_buff, 1 ) );
+
+    /* Fail for r_limbs < m->limbs */
+    r.limbs = m.limbs - 1;
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_read( &r, &m, r_buff, 1 ) );
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_write( &rn, &m, r_buff, 1 ) );
+    r.limbs = r_limbs;
+
+    /* Fail if input_r >= modulo m */
+    /* input_r = modulo */
+    memset( r_buff, 0xfe, buff_bytes );
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_read( &r, &m, r_buff, 1 ) );
+
+    /* input_r > modulo */
+    memset( r_buff, 0xff, buff_bytes );
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA, mbedtls_mpi_mod_read( &r, &m, r_buff, 1 ) );
+
+    /* Data too large to fit */
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL, mbedtls_mpi_mod_read( &r, &m, r_buff, buff_bytes ) );
+
+    /* Read the two limbs input data into a larger modulus and residue */
+    TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m2, N2, n2_limbs,
+                MBEDTLS_MPI_MOD_EXT_REP_LE, MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
+    rn.p = R2;
+    rn.limbs = r2_limbs;
+    TEST_EQUAL(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL, mbedtls_mpi_mod_write( &rn, &m2, r_buff, 1 ) );
+
+exit:
+    mbedtls_mpi_mod_modulus_free( &m );
+    mbedtls_mpi_mod_modulus_free( &m2 );
+    mbedtls_free( N );
+    mbedtls_free( R );
+    mbedtls_free( N2 );
+    mbedtls_free( R2 );
+    mbedtls_free( r_buff );
+
+    #undef IO_ZERO
+    #undef IO_ONE
+    #undef IO_MIN1
+    #undef IO_MAX
+    #undef IO_2LIMBS_MIN1
+    #undef IO_2LIMBS
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mpi_mod_io( char * input_N, data_t * input_A, int iendian )
+{
+    mbedtls_mpi_uint *N = NULL;
+    mbedtls_mpi_uint *R = NULL;
+    unsigned char *r_buff = NULL;
+    mbedtls_mpi_mod_modulus m;
+    mbedtls_mpi_mod_residue r;
+    size_t n_limbs, n_bytes, a_bytes;
+
+    /* Read inputs */
+    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
+    n_bytes = n_limbs * sizeof( mbedtls_mpi_uint );
+    a_bytes = input_A->len * sizeof( char );
+
+    /* Allocate the memory for intermediate data structures */
+    ASSERT_ALLOC( R, n_bytes );
+    ASSERT_ALLOC( r_buff, a_bytes );
+
+    /* Test that input's size is not greater to modulo's */
+    TEST_LE_U(a_bytes, n_bytes );
+
+    /* Init Structures */
+    mbedtls_mpi_mod_modulus_init( &m );
+    TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs, iendian,
+                MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
+
+    /* Enforcing p_limbs >= m->limbs */
+    TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R , n_limbs ) );
+
+    TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r, &m, input_A->x, input_A->len ) );
+
+    TEST_EQUAL( 0,mbedtls_mpi_mod_write( &r, &m, r_buff, a_bytes ) );
+
+    ASSERT_COMPARE( r_buff, a_bytes, input_A->x, a_bytes );
+exit:
+    mbedtls_mpi_mod_modulus_free( &m );
+    mbedtls_free( N );
+    mbedtls_free( R );
+    mbedtls_free( r_buff );
+}
+/* END_CASE */
 /* END MERGE SLOT 7 */
 
 /* BEGIN MERGE SLOT 8 */