Add tests for restartable ECDH
diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data
index f7119de..98c4f60 100644
--- a/tests/suites/test_suite_ecdh.data
+++ b/tests/suites/test_suite_ecdh.data
@@ -37,3 +37,7 @@
ECDH exchange #2
depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED
ecdh_exchange:MBEDTLS_ECP_DP_SECP521R1
+
+ECDH restartable rfc 5903 p256 restart disabled
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecdh_restart:MBEDTLS_ECP_DP_SECP256R1:"C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D1433":"C6EF9C5D78AE012A011164ACB397CE2088685D8F06BF9BE0B283AB46476BEE53":"D6840F6B42F6EDAFD13116E0E12565202FEF8E9ECE7DCE03812464D04B9442DE":0:0:0
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 4c6a97b..911464a 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -158,3 +158,113 @@
mbedtls_ecdh_free( &cli );
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
+void ecdh_restart( int id, char *dA_str, char *dB_str, char *z_str,
+ int max_ops, int min_restart, int max_restart )
+{
+ int ret;
+ mbedtls_ecdh_context srv, cli;
+ unsigned char buf[1000];
+ const unsigned char *vbuf;
+ size_t len;
+ unsigned char z[MBEDTLS_ECP_MAX_BYTES];
+ size_t z_len;
+ unsigned char rnd_buf_A[MBEDTLS_ECP_MAX_BYTES];
+ unsigned char rnd_buf_B[MBEDTLS_ECP_MAX_BYTES];
+ rnd_buf_info rnd_info_A, rnd_info_B;
+ int cnt_restart;
+
+ mbedtls_ecdh_init( &srv );
+ mbedtls_ecdh_init( &cli );
+
+ z_len = unhexify( z, z_str );
+
+ rnd_info_A.buf = rnd_buf_A;
+ rnd_info_A.length = unhexify( rnd_buf_A, dA_str );
+
+ rnd_info_B.buf = rnd_buf_B;
+ rnd_info_B.length = unhexify( rnd_buf_B, dB_str );
+
+ TEST_ASSERT( mbedtls_ecp_group_load( &srv.grp, id ) == 0 );
+
+ /* otherwise we would have to fix the random buffer,
+ * as in ecdh_primitive_test_vec */
+ TEST_ASSERT( srv.grp.nbits % 8 == 0 );
+
+ mbedtls_ecp_set_max_ops( max_ops );
+
+ /* server writes its paramaters */
+ memset( buf, 0x00, sizeof( buf ) );
+ len = 0;
+
+ cnt_restart = 0;
+ do {
+ ret = mbedtls_ecdh_make_params( &srv, &len, buf, sizeof( buf ),
+ rnd_buffer_rand, &rnd_info_A );
+ } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
+
+ TEST_ASSERT( ret == 0 );
+ TEST_ASSERT( cnt_restart >= min_restart );
+ TEST_ASSERT( cnt_restart <= max_restart );
+
+ /* client read server params */
+ vbuf = buf;
+ TEST_ASSERT( mbedtls_ecdh_read_params( &cli, &vbuf, buf + len ) == 0 );
+
+ /* client writes its key share */
+ memset( buf, 0x00, sizeof( buf ) );
+ len = 0;
+
+ cnt_restart = 0;
+ do {
+ ret = mbedtls_ecdh_make_public( &cli, &len, buf, sizeof( buf ),
+ rnd_buffer_rand, &rnd_info_B );
+ } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
+
+ TEST_ASSERT( ret == 0 );
+ TEST_ASSERT( cnt_restart >= min_restart );
+ TEST_ASSERT( cnt_restart <= max_restart );
+
+ /* server reads client key share */
+ TEST_ASSERT( mbedtls_ecdh_read_public( &srv, buf, len ) == 0 );
+
+ /* server computes shared secret */
+ memset( buf, 0, sizeof( buf ) );
+ len = 0;
+
+ cnt_restart = 0;
+ do {
+ ret = mbedtls_ecdh_calc_secret( &srv, &len, buf, sizeof( buf ),
+ NULL, NULL );
+ } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
+
+ TEST_ASSERT( ret == 0 );
+ TEST_ASSERT( cnt_restart >= min_restart );
+ TEST_ASSERT( cnt_restart <= max_restart );
+
+ TEST_ASSERT( len == z_len );
+ TEST_ASSERT( memcmp( buf, z, len ) == 0 );
+
+ /* client computes shared secret */
+ memset( buf, 0, sizeof( buf ) );
+ len = 0;
+
+ cnt_restart = 0;
+ do {
+ ret = mbedtls_ecdh_calc_secret( &cli, &len, buf, sizeof( buf ),
+ NULL, NULL );
+ } while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
+
+ TEST_ASSERT( ret == 0 );
+ TEST_ASSERT( cnt_restart >= min_restart );
+ TEST_ASSERT( cnt_restart <= max_restart );
+
+ TEST_ASSERT( len == z_len );
+ TEST_ASSERT( memcmp( buf, z, len ) == 0 );
+
+exit:
+ mbedtls_ecdh_free( &srv );
+ mbedtls_ecdh_free( &cli );
+}
+/* END_CASE */