SSL test programs: move RNG common code to ssl_test_lib

This commit is deliberately arranged to minimize code changes.
Subsequent commits will clean up the resulting code.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index a19b297..9250b10 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -742,8 +742,7 @@
     mbedtls_ssl_config_init( &conf );
     memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) );
     rng_context_t *rng = &rng_context;
-    mbedtls_ctr_drbg_init( &rng->drbg );
-    mbedtls_entropy_init( &rng->entropy );
+    rng_init( rng );
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_init( &cacert );
     mbedtls_x509_crt_init( &clicert );
@@ -1536,30 +1535,8 @@
     fflush( stdout );
 
     int reproducible = opt.reproducible;
-    if ( reproducible )
-    {
-        srand( 1 );
-        if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy,
-                                           &rng->entropy, (const unsigned char *) pers,
-                                           strlen( pers ) ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
-                            (unsigned int) -ret );
-            goto exit;
-        }
-    }
-    else
-    {
-        if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func,
-                                           &rng->entropy, (const unsigned char *) pers,
-                                           strlen( pers ) ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
-                            (unsigned int) -ret );
-            goto exit;
-        }
-    }
-
+    if( rng_seed( rng, reproducible, pers ) != 0 )
+        goto exit;
     mbedtls_printf( " ok\n" );
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -3025,8 +3002,7 @@
     mbedtls_ssl_session_free( &saved_session );
     mbedtls_ssl_free( &ssl );
     mbedtls_ssl_config_free( &conf );
-    mbedtls_ctr_drbg_free( &rng->drbg );
-    mbedtls_entropy_free( &rng->entropy );
+    rng_free( rng );
     if( session_data != NULL )
         mbedtls_platform_zeroize( session_data, session_data_len );
     mbedtls_free( session_data );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index bceca54..0c4c77b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1377,8 +1377,7 @@
     mbedtls_ssl_init( &ssl );
     mbedtls_ssl_config_init( &conf );
     rng_context_t *rng = &rng_context;
-    mbedtls_ctr_drbg_init( &rng->drbg );
-    mbedtls_entropy_init( &rng->entropy );
+    rng_init( rng );
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
     mbedtls_x509_crt_init( &cacert );
     mbedtls_x509_crt_init( &srvcert );
@@ -2295,30 +2294,8 @@
     fflush( stdout );
 
     int reproducible = opt.reproducible;
-    if ( reproducible )
-    {
-        srand( 1 );
-        if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy,
-                                           &rng->entropy, (const unsigned char *) pers,
-                                           strlen( pers ) ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
-                            (unsigned int) -ret );
-            goto exit;
-        }
-    }
-    else
-    {
-        if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func,
-                                           &rng->entropy, (const unsigned char *) pers,
-                                           strlen( pers ) ) ) != 0 )
-        {
-            mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
-                            (unsigned int) -ret );
-            goto exit;
-        }
-    }
-
+    if( rng_seed( rng, reproducible, pers ) != 0 )
+        goto exit;
     mbedtls_printf( " ok\n" );
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -3999,8 +3976,7 @@
 
     mbedtls_ssl_free( &ssl );
     mbedtls_ssl_config_free( &conf );
-    mbedtls_ctr_drbg_free( &rng->drbg );
-    mbedtls_entropy_free( &rng->entropy );
+    rng_free( rng );
 
 #if defined(MBEDTLS_SSL_CACHE_C)
     mbedtls_ssl_cache_free( &cache );
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
index 22453c1..bbb4d4a 100644
--- a/programs/ssl/ssl_test_lib.c
+++ b/programs/ssl/ssl_test_lib.c
@@ -61,6 +61,52 @@
     return( ret );
 }
 
+void rng_init( rng_context_t *rng )
+{
+    mbedtls_ctr_drbg_init( &rng->drbg );
+    mbedtls_entropy_init( &rng->entropy );
+}
+
+int rng_seed( rng_context_t *rng, int reproducible, const char *pers )
+{
+    int ret = 0;
+
+    if ( reproducible )
+    {
+        srand( 1 );
+        if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy,
+                                           &rng->entropy, (const unsigned char *) pers,
+                                           strlen( pers ) ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
+                            (unsigned int) -ret );
+            goto exit;
+        }
+    }
+    else
+    {
+        if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func,
+                                           &rng->entropy, (const unsigned char *) pers,
+                                           strlen( pers ) ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
+                            (unsigned int) -ret );
+            goto exit;
+        }
+    }
+
+
+    return( 0 );
+exit:
+    return( 1 );
+}
+
+void rng_free( rng_context_t *rng )
+{
+    mbedtls_ctr_drbg_free( &rng->drbg );
+    mbedtls_entropy_free( &rng->entropy );
+}
+
 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
 int ca_callback( void *data, mbedtls_x509_crt const *child,
                  mbedtls_x509_crt **candidates )
diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h
index 9f22ee4..db08a46 100644
--- a/programs/ssl/ssl_test_lib.h
+++ b/programs/ssl/ssl_test_lib.h
@@ -128,7 +128,7 @@
 
 int dummy_entropy( void *data, unsigned char *output, size_t len );
 
-/** A context for random generation.
+/** A context for random number generation (RNG).
  */
 typedef struct
 {
@@ -136,6 +136,36 @@
     mbedtls_ctr_drbg_context drbg;
 } rng_context_t;
 
+/** Initialize the RNG.
+ *
+ * This function only initializes the memory used by the RNG context.
+ * Before using the RNG, it must be seeded with rng_seed().
+ */
+void rng_init( rng_context_t *rng );
+
+/* Seed the random number generator.
+ *
+ * \param rng           The RNG context to use. It must have been initialized
+ *                      with rng_init().
+ * \param reproducible  If zero, seed the RNG from entropy.
+ *                      If nonzero, use a fixed seed, so that the program
+ *                      will produce the same sequence of random numbers
+ *                      each time it is invoked.
+ * \param pers          A null-terminated string. Different values for this
+ *                      string cause the RNG to emit different output for
+ *                      the same seed.
+ *
+ * return 0 on success, a negative value on error.
+ */
+int rng_seed( rng_context_t *rng, int reproducible, const char *pers );
+
+/** Deinitialize the RNG. Free any embedded resource.
+ *
+ * \param rng           The RNG context to deinitialize. It must have been
+ *                      initialized with rng_init().
+ */
+void rng_free( rng_context_t *rng );
+
 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
 int ca_callback( void *data, mbedtls_x509_crt const *child,
                  mbedtls_x509_crt **candidates );