Improve testing strategy
- reference handshake tests that we get the right values (not much now, but
much more later when we get to deriving the PMS)
- random handshake in addition tests our generate/write functions against our
read functions, that are tested by the reference handshake, and will be
further tested in the test suite later against invalid inputs
diff --git a/library/ecjpake.c b/library/ecjpake.c
index b80ca1a..95be8a3 100644
--- a/library/ecjpake.c
+++ b/library/ecjpake.c
@@ -578,6 +578,35 @@
}
#else
+static const unsigned char ecjpake_test_password[] = {
+ 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
+ 0x65, 0x73, 0x74
+};
+
+static const unsigned char ecjpake_test_x1[] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+ 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
+};
+
+static const unsigned char ecjpake_test_x2[] = {
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
+ 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
+};
+
+static const unsigned char ecjpake_test_x3[] = {
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
+ 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
+};
+
+static const unsigned char ecjpake_test_x4[] = {
+ 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
+ 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
+ 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
+};
+
static const unsigned char ecjpake_test_cli_ext[] = {
0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
@@ -657,7 +686,6 @@
0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
};
-#if 0
/* For tests we don't need a secure RNG;
* use the LGC from Numerical Recipes for simplicity */
static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
@@ -676,7 +704,6 @@
return( 0 );
}
-#endif
#define TEST_ASSERT( x ) \
do { \
@@ -695,33 +722,80 @@
int mbedtls_ecjpake_self_test( int verbose )
{
int ret;
- mbedtls_ecjpake_context ctx;
- char secret[] = "test passphrase";
+ mbedtls_ecjpake_context cli;
+ mbedtls_ecjpake_context srv;
+ unsigned char buf[512];
+ size_t len;
- mbedtls_ecjpake_init( &ctx );
-
- /* Common to all tests */
- TEST_ASSERT( mbedtls_ecjpake_setup( &ctx,
- MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
- (const unsigned char *) secret,
- sizeof( secret ) - 1 ) == 0 );
+ mbedtls_ecjpake_init( &cli );
+ mbedtls_ecjpake_init( &srv );
if( verbose != 0 )
- mbedtls_printf( " ECJPAKE test #1 (read in sequence): " );
+ mbedtls_printf( " ECJPAKE test #0 (setup): " );
- /* This is not realistic because it uses the same context for client and
- * server, but it ensures the context has all of X1 to X4 when reading the
- * key exchange message, so this is convenient for a quick test */
+ TEST_ASSERT( mbedtls_ecjpake_setup( &cli,
+ MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
+ ecjpake_test_password,
+ sizeof( ecjpake_test_password ) ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_tls_read_client_ext( &ctx,
+ TEST_ASSERT( mbedtls_ecjpake_setup( &srv,
+ MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
+ ecjpake_test_password,
+ sizeof( ecjpake_test_password ) ) == 0 );
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+
+ if( verbose != 0 )
+ mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
+
+ TEST_ASSERT( mbedtls_ecjpake_tls_write_client_ext( &cli,
+ buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+ TEST_ASSERT( mbedtls_ecjpake_tls_read_client_ext( &srv, buf, len ) == 0 );
+
+ TEST_ASSERT( mbedtls_ecjpake_tls_write_server_ext( &srv,
+ buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+ TEST_ASSERT( mbedtls_ecjpake_tls_read_server_ext( &cli, buf, len ) == 0 );
+
+ if( verbose != 0 )
+ mbedtls_printf( "passed\n" );
+
+ if( verbose != 0 )
+ mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
+
+ /* Simulate key generation on client, skip writing client_ext */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &cli.xa,
+ ecjpake_test_x1, sizeof( ecjpake_test_x1 ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &cli.xb,
+ ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &cli.grp, &cli.X1, &cli.xa,
+ &cli.grp.G, NULL, NULL ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &cli.grp, &cli.X2, &cli.xb,
+ &cli.grp.G, NULL, NULL ) );
+
+ /* Server reads client ext */
+ TEST_ASSERT( mbedtls_ecjpake_tls_read_client_ext( &srv,
ecjpake_test_cli_ext,
sizeof( ecjpake_test_cli_ext ) ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_tls_read_server_ext( &ctx,
+ /* Simulate key generation on server, skip writing server_ext */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &srv.xa,
+ ecjpake_test_x3, sizeof( ecjpake_test_x3 ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &srv.xb,
+ ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &srv.grp, &srv.X3, &srv.xa,
+ &srv.grp.G, NULL, NULL ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &srv.grp, &srv.X4, &srv.xb,
+ &srv.grp.G, NULL, NULL ) );
+
+ /* Client reads server ext and key exchange */
+ TEST_ASSERT( mbedtls_ecjpake_tls_read_server_ext( &cli,
ecjpake_test_srv_ext,
sizeof( ecjpake_test_srv_ext ) ) == 0 );
- TEST_ASSERT( mbedtls_ecjpake_tls_read_server_params( &ctx,
+ TEST_ASSERT( mbedtls_ecjpake_tls_read_server_params( &cli,
ecjpake_test_srv_kx,
sizeof( ecjpake_test_srv_kx ) ) == 0 );
@@ -729,7 +803,8 @@
mbedtls_printf( "passed\n" );
cleanup:
- mbedtls_ecjpake_free( &ctx );
+ mbedtls_ecjpake_free( &cli );
+ mbedtls_ecjpake_free( &srv );
if( ret != 0 )
{