Adapt programs / test suites
diff --git a/include/polarssl/havege.h b/include/polarssl/havege.h
index 5998903..536eb08 100644
--- a/include/polarssl/havege.h
+++ b/include/polarssl/havege.h
@@ -54,6 +54,13 @@
 void havege_init( havege_state *hs );
 
 /**
+ * \brief          Clear HAVEGE state
+ *
+ * \param hs       HAVEGE state to be cleared
+ */
+void havege_free( havege_state *hs );
+
+/**
  * \brief          HAVEGE rand function
  *
  * \param p_rng    A HAVEGE state
diff --git a/library/entropy.c b/library/entropy.c
index 04de07f..7f95317 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -83,6 +83,9 @@
 
 void entropy_free( entropy_context *ctx )
 {
+#if defined(POLARSSL_HAVEGE_C)
+    havege_free( &ctx->havege_data );
+#endif
     polarssl_zeroize( ctx, sizeof( entropy_context ) );
 #if defined(POLARSSL_THREADING_C)
     polarssl_mutex_free( &ctx->mutex );
diff --git a/library/havege.c b/library/havege.c
index de024de..3acd5bc 100644
--- a/library/havege.c
+++ b/library/havege.c
@@ -43,6 +43,11 @@
 
 #include <string.h>
 
+/* Implementation that should never be optimized out by the compiler */
+static void polarssl_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
 /* ------------------------------------------------------------------------
  * On average, one iteration accesses two 8-word blocks in the havege WALK
  * table, and generates 16 words in the RES array.
@@ -200,6 +205,14 @@
     havege_fill( hs );
 }
 
+void havege_free( havege_state *hs )
+{
+    if( hs == NULL )
+        return;
+
+    polarssl_zeroize( hs, sizeof( havege_state ) );
+}
+
 /*
  * HAVEGE rand function
  */
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index 92c5bca..5315eb9 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -82,8 +82,7 @@
     ((void) argv);
 
     memset( &rsa, 0, sizeof( rsa ) );
-    memset( &dhm, 0, sizeof( dhm ) );
-
+    dhm_init( &dhm );
     aes_init( &aes );
 
     /*
@@ -284,6 +283,7 @@
     aes_free( &aes );
     rsa_free( &rsa );
     dhm_free( &dhm );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index e75b338..598940e 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -154,6 +154,7 @@
 exit:
 
     mpi_free( &G ); mpi_free( &P ); mpi_free( &Q );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index 8bb184f..976da4c 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -83,7 +83,7 @@
     ((void) argv);
 
     memset( &rsa, 0, sizeof( rsa ) );
-    memset( &dhm, 0, sizeof( dhm ) );
+    dhm_init( &dhm );
     aes_init( &aes );
 
     /*
@@ -284,6 +284,7 @@
     aes_free( &aes );
     rsa_free( &rsa );
     dhm_free( &dhm );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index 40d67da..67fc710 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -229,6 +229,7 @@
 
     ecdsa_free( &ctx_verify );
     ecdsa_free( &ctx_sign );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
     return( ret );
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 2f3ba35..67e3747 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -388,6 +388,7 @@
     }
 
     pk_free( &key );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index 8088c8f..2ecb1d8 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -140,6 +140,7 @@
     ret = 0;
 
 exit:
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(POLARSSL_ERROR_C)
diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c
index ad00573..2eb139c 100644
--- a/programs/pkey/pk_encrypt.c
+++ b/programs/pkey/pk_encrypt.c
@@ -140,6 +140,7 @@
     printf( "\n  . Done (created \"%s\")\n\n", "result-enc.txt" );
 
 exit:
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(POLARSSL_ERROR_C)
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index 2c355d9..d80cbd7 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -151,6 +151,7 @@
 
 exit:
     pk_free( &pk );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(POLARSSL_ERROR_C)
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index c77d210..c79f1e4 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -164,6 +164,7 @@
     ret = 0;
 
 exit:
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index 51a5ddb..677ce76 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -152,6 +152,7 @@
     printf( "\n  . Done (created \"%s\")\n\n", "result-enc.txt" );
 
 exit:
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c
index 861e2c7..48d8c5e 100644
--- a/programs/pkey/rsa_genkey.c
+++ b/programs/pkey/rsa_genkey.c
@@ -154,6 +154,7 @@
         fclose( fpriv );
 
     rsa_free( &rsa );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index 890a0b6..e3e56c6 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -161,6 +161,7 @@
 
 exit:
     pk_free( &pk );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c
index ddd7737..94e200d 100644
--- a/programs/random/gen_random_ctr_drbg.c
+++ b/programs/random/gen_random_ctr_drbg.c
@@ -115,6 +115,7 @@
     printf("\n");
 
     fclose( f );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
     return( ret );
diff --git a/programs/random/gen_random_havege.c b/programs/random/gen_random_havege.c
index fd39411..e9152fa 100644
--- a/programs/random/gen_random_havege.c
+++ b/programs/random/gen_random_havege.c
@@ -48,7 +48,7 @@
 {
     FILE *f;
     time_t t;
-    int i, k;
+    int i, k, ret = 0;
     havege_state hs;
     unsigned char buf[1024];
 
@@ -73,8 +73,9 @@
         if( havege_random( &hs, buf, sizeof( buf ) ) != 0 )
         {
             printf( "Failed to get random from source.\n" );
-            fclose( f );
-            return( 1 );
+
+            ret = 1;
+            goto exit;
         }
 
         fwrite( buf, sizeof( buf ), 1, f );
@@ -89,7 +90,9 @@
 
     printf(" \n ");
 
+exit:
+    havege_free( &hs );
     fclose( f );
-    return( 0 );
+    return( ret );
 }
 #endif /* POLARSSL_HAVEGE_C */
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index e5a68e2..1b369a6 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -290,6 +290,7 @@
 
     x509_crt_free( &cacert );
     ssl_free( &ssl );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
     memset( &ssl, 0, sizeof( ssl ) );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 87eadf8..0d4d592 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1209,6 +1209,7 @@
 #endif
     ssl_session_free( &saved_session );
     ssl_free( &ssl );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
     memset( &ssl, 0, sizeof( ssl ) );
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index d10a9e6..706cdd4 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -376,6 +376,7 @@
     x509_crt_free( &srvcert );
     pk_free( &pkey );
     ssl_free( &ssl );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 792e166..06d6b89 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -816,6 +816,7 @@
     x509_crt_free( &cacert );
     pk_free( &pkey );
     ssl_free( &ssl );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index 3f39071..cc6ad89 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -492,6 +492,7 @@
 #if defined(POLARSSL_SSL_CACHE_C)
     ssl_cache_free( &cache );
 #endif
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
     polarssl_mutex_free( &debug_mutex );
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 545243d..9e09799 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -373,6 +373,7 @@
 #if defined(POLARSSL_SSL_CACHE_C)
     ssl_cache_free( &cache );
 #endif
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 371c909..e58099f 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -626,7 +626,7 @@
     pk_init( &pkey2 );
 #endif
 #if defined(POLARSSL_DHM_C) && defined(POLARSSL_FS_IO)
-    memset( &dhm, 0, sizeof( dhm_context ) );
+    dhm_init( &dhm );
 #endif
 #if defined(POLARSSL_SSL_CACHE_C)
     ssl_cache_init( &cache );
@@ -1655,6 +1655,9 @@
     if( client_fd != -1 )
         net_close( client_fd );
 
+#if defined(POLARSSL_DHM_C) && defined(POLARSSL_FS_IO)
+    dhm_free( &dhm );
+#endif
 #if defined(POLARSSL_X509_CRT_PARSE_C)
     x509_crt_free( &cacert );
     x509_crt_free( &srvcert );
@@ -1673,6 +1676,7 @@
 #endif
 
     ssl_free( &ssl );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(POLARSSL_SSL_CACHE_C)
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index a17d690..4462357 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -414,6 +414,7 @@
         havege_state hs;
         havege_init( &hs );
         TIME_AND_TSC( "HAVEGE", havege_random( &hs, buf, BUFSIZE ) );
+        havege_free( &hs );
     }
 #endif
 
@@ -434,6 +435,7 @@
         TIME_AND_TSC( "CTR_DRBG (PR)",
                 if( ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
                 exit(1) );
+        ctr_drbg_free( &ctr_drbg );
     }
 #endif
 
@@ -531,7 +533,7 @@
         size_t olen;
         for( i = 0; i < DHM_SIZES; i++ )
         {
-            memset( &dhm, 0, sizeof( dhm_context ) );
+            dhm_init( &dhm );
 
             if( mpi_read_string( &dhm.P, 16, dhm_P[i] ) != 0 ||
                 mpi_read_string( &dhm.G, 16, dhm_G[i] ) != 0 )
diff --git a/programs/test/o_p_test.c b/programs/test/o_p_test.c
index 1478940..e5047e5 100644
--- a/programs/test/o_p_test.c
+++ b/programs/test/o_p_test.c
@@ -258,6 +258,7 @@
     printf( "String value (PolarSSL Private Encrypt, OpenSSL Public Decrypt): '%s'\n", o_priv_decrypted );
 
 exit:
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #ifdef WIN32
diff --git a/programs/test/ssl_test.c b/programs/test/ssl_test.c
index 7dcdcae..ab7b812 100644
--- a/programs/test/ssl_test.c
+++ b/programs/test/ssl_test.c
@@ -417,6 +417,7 @@
     x509_crt_free( &srvcert );
     pk_free( &pkey );
     ssl_free( &ssl );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
     if( client_fd != -1 )
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index fae00d2..5f8636b 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -492,6 +492,7 @@
     x509_crl_free( &cacrl );
 #endif
     pk_free( &pkey );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index 6a0467a..f229e0b 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -329,6 +329,7 @@
 
     x509write_csr_free( &req );
     pk_free( &key );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index e50a99d..8f0616c 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -652,6 +652,7 @@
     pk_free( &loaded_subject_key );
     pk_free( &loaded_issuer_key );
     mpi_free( &serial );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 
 #if defined(_WIN32)
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 5690675..b3790a2 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -45,6 +45,8 @@
     TEST_ASSERT( ctr_drbg_random_with_add( &ctx, buf, 16, add2, add2_len ) == 0 );
     hexify( output_str, buf, 16 );
     TEST_ASSERT( strcmp( (char *) output_str, result_str ) == 0 );
+
+    ctr_drbg_free( &ctx );
 }
 /* END_CASE */
 
@@ -79,6 +81,8 @@
     TEST_ASSERT( ctr_drbg_random_with_add( &ctx, buf, 16, add2, add2_len ) == 0 );
     hexify( output_str, buf, 16 );
     TEST_ASSERT( strcmp( (char *) output_str, result_str ) == 0 );
+
+    ctr_drbg_free( &ctx );
 }
 /* END_CASE */
 
@@ -150,6 +154,8 @@
     last_idx = test_offset_idx;
     TEST_ASSERT( ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
     TEST_ASSERT( test_offset_idx - last_idx == 13 );
+
+    ctr_drbg_free( &ctx );
 }
 /* END_CASE */
 
@@ -161,6 +167,8 @@
     TEST_ASSERT( ctr_drbg_init( &ctx, rnd_std_rand, NULL, NULL, 0 ) == 0 );
     TEST_ASSERT( ctr_drbg_write_seed_file( &ctx, path ) == ret );
     TEST_ASSERT( ctr_drbg_update_seed_file( &ctx, path ) == ret );
+
+    ctr_drbg_free( &ctx );
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index b0df9fd..8c85517 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -25,8 +25,8 @@
     int x_size, i;
     rnd_pseudo_info rnd_info;
 
-    memset( &ctx_srv, 0x00, sizeof( dhm_context ) );
-    memset( &ctx_cli, 0x00, sizeof( dhm_context ) );
+    dhm_init( &ctx_srv );
+    dhm_init( &ctx_cli );
     memset( ske, 0x00, 1000 );
     memset( pub_cli, 0x00, 1000 );
     memset( sec_srv, 0x00, 1000 );
@@ -103,7 +103,7 @@
     dhm_context ctx;
     mpi P, G;
 
-    memset( &ctx, 0, sizeof ctx );
+    dhm_init( &ctx );
     mpi_init( &P ); mpi_init( &G );
 
     TEST_ASSERT( mpi_read_string( &P, 16, p ) == 0 );
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index a01b217..a762e04 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -597,6 +597,7 @@
     }
 
     rsa_free( &ctx );
+    ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
 }
 /* END_CASE */