Introduce polarssl_zeroize() instead of memset() for zeroization
diff --git a/ChangeLog b/ChangeLog
index 6486ba3..83613b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,8 @@
    * Improvements to tests/Makefile, contributed by Oden Eriksson.
    * Use UTC time to check certificate validity.
    * Reject certificates with times not in UTC, per RFC 5280.
+   * Migrate zeroizing of data to polarssl_zeroize() instead of memset()
+     against unwanted compiler optimizations
 
 Security
    * Forbid change of server certificate during renegotiation to prevent
diff --git a/library/aes.c b/library/aes.c
index 6456c54..8b67cbb 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -40,6 +40,11 @@
 
 #if !defined(POLARSSL_AES_ALT)
 
+/* 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;
+}
+
 /*
  * 32-bit integer manipulation macros (little endian)
  */
@@ -611,7 +616,7 @@
     *RK++ = *SK++;
     *RK++ = *SK++;
 
-    memset( &cty, 0, sizeof( aes_context ) );
+    polarssl_zeroize( &cty, sizeof( aes_context ) );
 
     return( 0 );
 }
diff --git a/library/bignum.c b/library/bignum.c
index eb0fb51..5f61d13 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -39,6 +39,11 @@
 
 #include <stdlib.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;
+}
+
 #define ciL    (sizeof(t_uint))         /* chars in limb  */
 #define biL    (ciL << 3)               /* bits  in limb  */
 #define biH    (ciL << 2)               /* half limb size */
@@ -72,7 +77,7 @@
 
     if( X->p != NULL )
     {
-        memset( X->p, 0, X->n * ciL );
+        polarssl_zeroize( X->p, X->n * ciL );
         free( X->p );
     }
 
@@ -101,7 +106,7 @@
         if( X->p != NULL )
         {
             memcpy( p, X->p, X->n * ciL );
-            memset( X->p, 0, X->n * ciL );
+            polarssl_zeroize( X->p, X->n * ciL );
             free( X->p );
         }
 
diff --git a/library/camellia.c b/library/camellia.c
index bb87875..48fc3e6 100644
--- a/library/camellia.c
+++ b/library/camellia.c
@@ -37,6 +37,11 @@
 
 #if !defined(POLARSSL_CAMELLIA_ALT)
 
+/* 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;
+}
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -456,7 +461,7 @@
     *RK++ = *SK++;
     *RK++ = *SK++;
 
-    memset( &cty, 0, sizeof( camellia_context ) );
+    polarssl_zeroize( &cty, sizeof( camellia_context ) );
 
     return( 0 );
 }
diff --git a/library/cipher.c b/library/cipher.c
index e8dae3a..b4fca9a 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -40,6 +40,11 @@
 #define strcasecmp _stricmp
 #endif
 
+/* 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;
+}
+
 static const int supported_ciphers[] = {
 
 #if defined(POLARSSL_AES_C)
@@ -320,6 +325,7 @@
         return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
 
     ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
+    polarssl_zeroize( ctx, sizeof(cipher_context_t) );
 
     return 0;
 }
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 9437212..a927e29 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -51,6 +51,11 @@
 
 #include <stdlib.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;
+}
+
 #if defined(POLARSSL_AES_C)
 
 int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
@@ -114,6 +119,7 @@
 
 static void aes_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( aes_context ) );
     free( ctx );
 }
 
@@ -287,6 +293,7 @@
 
 static void camellia_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( camellia_context ) );
     free( ctx );
 }
 
@@ -495,6 +502,13 @@
 
 static void des_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( des_context ) );
+    free( ctx );
+}
+
+static void des3_ctx_free( void *ctx )
+{
+    polarssl_zeroize( ctx, sizeof( des3_context ) );
     free( ctx );
 }
 
@@ -527,7 +541,7 @@
     des3_set2key_enc_wrap,
     des3_set2key_dec_wrap,
     des3_ctx_alloc,
-    des_ctx_free
+    des3_ctx_free
 };
 
 const cipher_info_t des_ede_cbc_info = {
@@ -548,7 +562,7 @@
     des3_set3key_enc_wrap,
     des3_set3key_dec_wrap,
     des3_ctx_alloc,
-    des_ctx_free
+    des3_ctx_free
 };
 
 const cipher_info_t des_ede3_cbc_info = {
@@ -625,6 +639,7 @@
 
 static void blowfish_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( blowfish_context ) );
     free( ctx );
 }
 
diff --git a/library/des.c b/library/des.c
index 0cf4b3d..37fd345 100644
--- a/library/des.c
+++ b/library/des.c
@@ -37,6 +37,11 @@
 
 #if !defined(POLARSSL_DES_ALT)
 
+/* 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;
+}
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -508,7 +513,7 @@
     uint32_t sk[96];
 
     des3_set2key( ctx->sk, sk, key );
-    memset( sk,  0, sizeof( sk ) );
+    polarssl_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
@@ -521,7 +526,7 @@
     uint32_t sk[96];
 
     des3_set2key( sk, ctx->sk, key );
-    memset( sk,  0, sizeof( sk ) );
+    polarssl_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
@@ -557,7 +562,7 @@
     uint32_t sk[96];
 
     des3_set3key( ctx->sk, sk, key );
-    memset( sk, 0, sizeof( sk ) );
+    polarssl_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
@@ -570,7 +575,7 @@
     uint32_t sk[96];
 
     des3_set3key( sk, ctx->sk, key );
-    memset( sk, 0, sizeof( sk ) );
+    polarssl_zeroize( sk,  sizeof( sk ) );
 
     return( 0 );
 }
diff --git a/library/dhm.c b/library/dhm.c
index b6f9b9d..97d6c7a 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -34,6 +34,11 @@
 
 #include "polarssl/dhm.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;
+}
+
 /*
  * helper to validate the mpi size and import it
  */
@@ -286,6 +291,8 @@
     mpi_free( &ctx->RP ); mpi_free( &ctx->K ); mpi_free( &ctx->GY );
     mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G );
     mpi_free( &ctx->P );
+
+    polarssl_zeroize( ctx, sizeof( dhm_context ) );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/gcm.c b/library/gcm.c
index ba42fd0..e9c37fe 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -54,6 +54,11 @@
 }
 #endif
 
+/* 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;
+}
+
 static void gcm_gen_table( gcm_context *ctx )
 {
     int i, j;
@@ -322,7 +327,7 @@
     if( memcmp( check_tag, tag, tag_len ) == 0 )
         return( 0 );
 
-    memset( output, 0, length );
+    polarssl_zeroize( output, length );
 
     return( POLARSSL_ERR_GCM_AUTH_FAILED );
 }
diff --git a/library/md.c b/library/md.c
index 96065c9..9e6aaaa 100644
--- a/library/md.c
+++ b/library/md.c
@@ -40,6 +40,11 @@
 #define strcasecmp _stricmp
 #endif
 
+/* 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;
+}
+
 static const int supported_digests[] = {
 
 #if defined(POLARSSL_MD2_C)
@@ -173,7 +178,8 @@
         return POLARSSL_ERR_MD_BAD_INPUT_DATA;
 
     ctx->md_info->ctx_free_func( ctx->md_ctx );
-    ctx->md_ctx = NULL;
+
+    polarssl_zeroize( ctx, sizeof( md_context_t ) );
 
     return 0;
 }
diff --git a/library/md2.c b/library/md2.c
index 2c8754a..8646f66 100644
--- a/library/md2.c
+++ b/library/md2.c
@@ -39,6 +39,11 @@
 #include <stdio.h>
 #endif
 
+/* 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;
+}
+
 #if !defined(POLARSSL_MD2_ALT)
 
 static const unsigned char PI_SUBST[256] =
@@ -178,7 +183,7 @@
     md2_update( &ctx, input, ilen );
     md2_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md2_context ) );
+    polarssl_zeroize( &ctx, sizeof( md2_context ) );
 }
 
 #if defined(POLARSSL_FS_IO)
@@ -202,7 +207,7 @@
 
     md2_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md2_context ) );
+    polarssl_zeroize( &ctx, sizeof( md2_context ) );
 
     if( ferror( f ) != 0 )
     {
@@ -242,7 +247,7 @@
     md2_starts( ctx );
     md2_update( ctx, ctx->ipad, 16 );
 
-    memset( sum, 0, sizeof( sum ) );
+    polarssl_zeroize( sum, sizeof( sum ) );
 }
 
 /*
@@ -266,7 +271,7 @@
     md2_update( ctx, tmpbuf, 16 );
     md2_finish( ctx, output );
 
-    memset( tmpbuf, 0, sizeof( tmpbuf ) );
+    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
 }
 
 /*
@@ -291,7 +296,7 @@
     md2_hmac_update( &ctx, input, ilen );
     md2_hmac_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md2_context ) );
+    polarssl_zeroize( &ctx, sizeof( md2_context ) );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/md4.c b/library/md4.c
index 980f5e4..597e5f4 100644
--- a/library/md4.c
+++ b/library/md4.c
@@ -39,6 +39,11 @@
 #include <stdio.h>
 #endif
 
+/* 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;
+}
+
 #if !defined(POLARSSL_MD4_ALT)
 
 /*
@@ -274,7 +279,7 @@
     md4_update( &ctx, input, ilen );
     md4_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md4_context ) );
+    polarssl_zeroize( &ctx, sizeof( md4_context ) );
 }
 
 #if defined(POLARSSL_FS_IO)
@@ -298,7 +303,7 @@
 
     md4_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md4_context ) );
+    polarssl_zeroize( &ctx, sizeof( md4_context ) );
 
     if( ferror( f ) != 0 )
     {
@@ -338,7 +343,7 @@
     md4_starts( ctx );
     md4_update( ctx, ctx->ipad, 64 );
 
-    memset( sum, 0, sizeof( sum ) );
+    polarssl_zeroize( sum, sizeof( sum ) );
 }
 
 /*
@@ -362,7 +367,7 @@
     md4_update( ctx, tmpbuf, 16 );
     md4_finish( ctx, output );
 
-    memset( tmpbuf, 0, sizeof( tmpbuf ) );
+    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
 }
 
 /*
@@ -387,7 +392,7 @@
     md4_hmac_update( &ctx, input, ilen );
     md4_hmac_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md4_context ) );
+    polarssl_zeroize( &ctx, sizeof( md4_context ) );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/md5.c b/library/md5.c
index b28461e..1d38ba3 100644
--- a/library/md5.c
+++ b/library/md5.c
@@ -38,6 +38,11 @@
 #include <stdio.h>
 #endif
 
+/* 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;
+}
+
 #if !defined(POLARSSL_MD5_ALT)
 
 /*
@@ -291,7 +296,7 @@
     md5_update( &ctx, input, ilen );
     md5_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md5_context ) );
+    polarssl_zeroize( &ctx, sizeof( md5_context ) );
 }
 
 #if defined(POLARSSL_FS_IO)
@@ -315,7 +320,7 @@
 
     md5_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md5_context ) );
+    polarssl_zeroize( &ctx, sizeof( md5_context ) );
 
     if( ferror( f ) != 0 )
     {
@@ -355,7 +360,7 @@
     md5_starts( ctx );
     md5_update( ctx, ctx->ipad, 64 );
 
-    memset( sum, 0, sizeof( sum ) );
+    polarssl_zeroize( sum, sizeof( sum ) );
 }
 
 /*
@@ -379,7 +384,7 @@
     md5_update( ctx, tmpbuf, 16 );
     md5_finish( ctx, output );
 
-    memset( tmpbuf, 0, sizeof( tmpbuf ) );
+    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
 }
 
 /*
@@ -404,7 +409,7 @@
     md5_hmac_update( &ctx, input, ilen );
     md5_hmac_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( md5_context ) );
+    polarssl_zeroize( &ctx, sizeof( md5_context ) );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/md_wrap.c b/library/md_wrap.c
index f276db5..92d04f9 100644
--- a/library/md_wrap.c
+++ b/library/md_wrap.c
@@ -59,6 +59,11 @@
 
 #include <stdlib.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;
+}
+
 #if defined(POLARSSL_MD2_C)
 
 static void md2_starts_wrap( void *ctx )
@@ -114,6 +119,7 @@
 
 static void md2_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( md2_context ) );
     free( ctx );
 }
 
@@ -192,6 +198,7 @@
 
 void md4_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( md4_context ) );
     free( ctx );
 }
 
@@ -270,6 +277,7 @@
 
 static void md5_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( md5_context ) );
     free( ctx );
 }
 
@@ -348,6 +356,7 @@
 
 void sha1_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( sha1_context ) );
     free( ctx );
 }
 
@@ -442,6 +451,7 @@
 
 void sha224_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( sha2_context ) );
     free( ctx );
 }
 
@@ -529,6 +539,7 @@
 
 void sha256_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( sha2_context ) );
     free( ctx );
 }
 
@@ -620,6 +631,7 @@
 
 void sha384_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( sha4_context ) );
     free( ctx );
 }
 
@@ -707,6 +719,7 @@
 
 void sha512_ctx_free( void *ctx )
 {
+    polarssl_zeroize( ctx, sizeof( sha4_context ) );
     free( ctx );
 }
 
diff --git a/library/pem.c b/library/pem.c
index e2e3998..bc4af25 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -36,6 +36,11 @@
 
 #include <stdlib.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;
+}
+
 void pem_init( pem_context *ctx )
 {
     memset( ctx, 0, sizeof( pem_context ) );
@@ -86,8 +91,8 @@
     {
         memcpy( key, md5sum, keylen );
 
-        memset( &md5_ctx, 0, sizeof(  md5_ctx ) );
-        memset( md5sum, 0, 16 );
+        polarssl_zeroize( &md5_ctx, sizeof(  md5_ctx ) );
+        polarssl_zeroize( md5sum, 16 );
         return;
     }
 
@@ -108,8 +113,8 @@
 
     memcpy( key + 16, md5sum, use_len );
 
-    memset( &md5_ctx, 0, sizeof(  md5_ctx ) );
-    memset( md5sum, 0, 16 );
+    polarssl_zeroize( &md5_ctx, sizeof(  md5_ctx ) );
+    polarssl_zeroize( md5sum, 16 );
 }
 
 #if defined(POLARSSL_DES_C)
@@ -129,8 +134,8 @@
     des_crypt_cbc( &des_ctx, DES_DECRYPT, buflen,
                      des_iv, buf, buf );
 
-    memset( &des_ctx, 0, sizeof( des_ctx ) );
-    memset( des_key, 0, 8 );
+    polarssl_zeroize( &des_ctx, sizeof( des_ctx ) );
+    polarssl_zeroize( des_key, 8 );
 }
 
 /*
@@ -149,8 +154,8 @@
     des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
                      des3_iv, buf, buf );
 
-    memset( &des3_ctx, 0, sizeof( des3_ctx ) );
-    memset( des3_key, 0, 24 );
+    polarssl_zeroize( &des3_ctx, sizeof( des3_ctx ) );
+    polarssl_zeroize( des3_key, 24 );
 }
 #endif /* POLARSSL_DES_C */
 
@@ -171,8 +176,8 @@
     aes_crypt_cbc( &aes_ctx, AES_DECRYPT, buflen,
                      aes_iv, buf, buf );
 
-    memset( &aes_ctx, 0, sizeof( aes_ctx ) );
-    memset( aes_key, 0, keylen );
+    polarssl_zeroize( &aes_ctx, sizeof( aes_ctx ) );
+    polarssl_zeroize( aes_key, keylen );
 }
 #endif /* POLARSSL_AES_C */
 
@@ -349,7 +354,7 @@
     if( ctx->info )
         free( ctx->info );
 
-    memset( ctx, 0, sizeof( pem_context ) );
+    polarssl_zeroize( ctx, sizeof( pem_context ) );
 }
 
 #endif
diff --git a/library/sha1.c b/library/sha1.c
index b301b09..c685133 100644
--- a/library/sha1.c
+++ b/library/sha1.c
@@ -38,6 +38,11 @@
 #include <stdio.h>
 #endif
 
+/* 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;
+}
+
 #if !defined(POLARSSL_SHA1_ALT)
 
 /*
@@ -324,7 +329,7 @@
     sha1_update( &ctx, input, ilen );
     sha1_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha1_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha1_context ) );
 }
 
 #if defined(POLARSSL_FS_IO)
@@ -348,7 +353,7 @@
 
     sha1_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha1_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha1_context ) );
 
     if( ferror( f ) != 0 )
     {
@@ -388,7 +393,7 @@
     sha1_starts( ctx );
     sha1_update( ctx, ctx->ipad, 64 );
 
-    memset( sum, 0, sizeof( sum ) );
+    polarssl_zeroize( sum, sizeof( sum ) );
 }
 
 /*
@@ -412,7 +417,7 @@
     sha1_update( ctx, tmpbuf, 20 );
     sha1_finish( ctx, output );
 
-    memset( tmpbuf, 0, sizeof( tmpbuf ) );
+    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
 }
 
 /*
@@ -437,7 +442,7 @@
     sha1_hmac_update( &ctx, input, ilen );
     sha1_hmac_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha1_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha1_context ) );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/sha2.c b/library/sha2.c
index 20772ec..f8bbb7a 100644
--- a/library/sha2.c
+++ b/library/sha2.c
@@ -38,6 +38,11 @@
 #include <stdio.h>
 #endif
 
+/* 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;
+}
+
 #if !defined(POLARSSL_SHA2_ALT)
 
 /*
@@ -326,7 +331,7 @@
     sha2_update( &ctx, input, ilen );
     sha2_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha2_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha2_context ) );
 }
 
 #if defined(POLARSSL_FS_IO)
@@ -350,7 +355,7 @@
 
     sha2_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha2_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha2_context ) );
 
     if( ferror( f ) != 0 )
     {
@@ -391,7 +396,7 @@
     sha2_starts( ctx, is224 );
     sha2_update( ctx, ctx->ipad, 64 );
 
-    memset( sum, 0, sizeof( sum ) );
+    polarssl_zeroize( sum, sizeof( sum ) );
 }
 
 /*
@@ -419,7 +424,7 @@
     sha2_update( ctx, tmpbuf, hlen );
     sha2_finish( ctx, output );
 
-    memset( tmpbuf, 0, sizeof( tmpbuf ) );
+    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
 }
 
 /*
@@ -444,7 +449,7 @@
     sha2_hmac_update( &ctx, input, ilen );
     sha2_hmac_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha2_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha2_context ) );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/sha4.c b/library/sha4.c
index 466420a..a0f87ec 100644
--- a/library/sha4.c
+++ b/library/sha4.c
@@ -38,6 +38,11 @@
 #include <stdio.h>
 #endif
 
+/* 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;
+}
+
 #if !defined(POLARSSL_SHA4_ALT)
 
 /*
@@ -324,7 +329,7 @@
     sha4_update( &ctx, input, ilen );
     sha4_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha4_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha4_context ) );
 }
 
 #if defined(POLARSSL_FS_IO)
@@ -348,7 +353,7 @@
 
     sha4_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha4_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha4_context ) );
 
     if( ferror( f ) != 0 )
     {
@@ -389,7 +394,7 @@
     sha4_starts( ctx, is384 );
     sha4_update( ctx, ctx->ipad, 128 );
 
-    memset( sum, 0, sizeof( sum ) );
+    polarssl_zeroize( sum, sizeof( sum ) );
 }
 
 /*
@@ -418,7 +423,7 @@
     sha4_update( ctx, tmpbuf, hlen );
     sha4_finish( ctx, output );
 
-    memset( tmpbuf, 0, sizeof( tmpbuf ) );
+    polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
 }
 
 /*
@@ -443,7 +448,7 @@
     sha4_hmac_update( &ctx, input, ilen );
     sha4_hmac_finish( &ctx, output );
 
-    memset( &ctx, 0, sizeof( sha4_context ) );
+    polarssl_zeroize( &ctx, sizeof( sha4_context ) );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 6e37836..4add6a2 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -54,6 +54,11 @@
 #define strcasecmp _stricmp
 #endif
 
+/* 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;
+}
+
 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
 int (*ssl_hw_record_init)(ssl_context *ssl,
                        const unsigned char *key_enc, const unsigned char *key_dec,
@@ -127,11 +132,11 @@
         md5_finish( &md5, dstbuf + i * 16 );
     }
 
-    memset( &md5,  0, sizeof( md5  ) );
-    memset( &sha1, 0, sizeof( sha1 ) );
+    polarssl_zeroize( &md5,  sizeof( md5  ) );
+    polarssl_zeroize( &sha1, sizeof( sha1 ) );
 
-    memset( padding, 0, sizeof( padding ) );
-    memset( sha1sum, 0, sizeof( sha1sum ) );
+    polarssl_zeroize( padding, sizeof( padding ) );
+    polarssl_zeroize( sha1sum, sizeof( sha1sum ) );
 
     return( 0 );
 }
@@ -190,8 +195,8 @@
             dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
     }
 
-    memset( tmp, 0, sizeof( tmp ) );
-    memset( h_i, 0, sizeof( h_i ) );
+    polarssl_zeroize( tmp, sizeof( tmp ) );
+    polarssl_zeroize( h_i, sizeof( h_i ) );
 
     return( 0 );
 }
@@ -229,8 +234,8 @@
             dstbuf[i + j]  = h_i[j];
     }
 
-    memset( tmp, 0, sizeof( tmp ) );
-    memset( h_i, 0, sizeof( h_i ) );
+    polarssl_zeroize( tmp, sizeof( tmp ) );
+    polarssl_zeroize( h_i, sizeof( h_i ) );
 
     return( 0 );
 }
@@ -269,8 +274,8 @@
             dstbuf[i + j]  = h_i[j];
     }
 
-    memset( tmp, 0, sizeof( tmp ) );
-    memset( h_i, 0, sizeof( h_i ) );
+    polarssl_zeroize( tmp, sizeof( tmp ) );
+    polarssl_zeroize( h_i, sizeof( h_i ) );
 
     return( 0 );
 }
@@ -357,7 +362,7 @@
                             "master secret",
                             handshake->randbytes, 64, session->master, 48 );
 
-        memset( handshake->premaster, 0, sizeof( handshake->premaster ) );
+        polarssl_zeroize( handshake->premaster, sizeof(handshake->premaster) );
     }
     else
         SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
@@ -368,7 +373,7 @@
     memcpy( tmp, handshake->randbytes, 64 );
     memcpy( handshake->randbytes, tmp + 32, 32 );
     memcpy( handshake->randbytes + 32, tmp, 32 );
-    memset( tmp, 0, sizeof( tmp ) );
+    polarssl_zeroize( tmp, sizeof( tmp ) );
 
     /*
      *  SSLv3:
@@ -391,7 +396,7 @@
     SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
     SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
 
-    memset( handshake->randbytes, 0, sizeof( handshake->randbytes ) );
+    polarssl_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) );
 
     /*
      * Determine the appropriate key, IV and MAC length.
@@ -680,7 +685,7 @@
             return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
     }
 
-    memset( keyblk, 0, sizeof( keyblk ) );
+    polarssl_zeroize( keyblk, sizeof( keyblk ) );
 
 #if defined(POLARSSL_ZLIB_SUPPORT)
     // Initialize compression
@@ -2654,12 +2659,12 @@
 
     SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
 
-    memset(  &md5, 0, sizeof(  md5_context ) );
-    memset( &sha1, 0, sizeof( sha1_context ) );
+    polarssl_zeroize(  &md5, sizeof(  md5_context ) );
+    polarssl_zeroize( &sha1, sizeof( sha1_context ) );
 
-    memset(  padbuf, 0, sizeof(  padbuf ) );
-    memset(  md5sum, 0, sizeof(  md5sum ) );
-    memset( sha1sum, 0, sizeof( sha1sum ) );
+    polarssl_zeroize(  padbuf, sizeof(  padbuf ) );
+    polarssl_zeroize(  md5sum, sizeof(  md5sum ) );
+    polarssl_zeroize( sha1sum, sizeof( sha1sum ) );
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -2710,10 +2715,10 @@
 
     SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
 
-    memset(  &md5, 0, sizeof(  md5_context ) );
-    memset( &sha1, 0, sizeof( sha1_context ) );
+    polarssl_zeroize(  &md5, sizeof(  md5_context ) );
+    polarssl_zeroize( &sha1, sizeof( sha1_context ) );
 
-    memset(  padbuf, 0, sizeof(  padbuf ) );
+    polarssl_zeroize(  padbuf, sizeof(  padbuf ) );
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -2756,9 +2761,8 @@
 
     SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
 
-    memset( &sha2, 0, sizeof( sha2_context ) );
-
-    memset(  padbuf, 0, sizeof(  padbuf ) );
+    polarssl_zeroize( &sha2, sizeof( sha2_context ) );
+    polarssl_zeroize( padbuf, sizeof( padbuf ) );
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -2802,9 +2806,8 @@
 
     SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
 
-    memset( &sha4, 0, sizeof( sha4_context ) );
-
-    memset(  padbuf, 0, sizeof(  padbuf ) );
+    polarssl_zeroize( &sha4, sizeof( sha4_context ) );
+    polarssl_zeroize( padbuf, sizeof( padbuf ) );
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
@@ -4019,7 +4022,7 @@
     inflateEnd( &transform->ctx_inflate );
 #endif
 
-    memset( transform, 0, sizeof( ssl_transform ) );
+    polarssl_zeroize( transform, sizeof( ssl_transform ) );
 }
 
 void ssl_handshake_free( ssl_handshake_params *handshake )
@@ -4027,7 +4030,7 @@
 #if defined(POLARSSL_DHM_C)
     dhm_free( &handshake->dhm_ctx );
 #endif
-    memset( handshake, 0, sizeof( ssl_handshake_params ) );
+    polarssl_zeroize( handshake, sizeof( ssl_handshake_params ) );
 }
 
 void ssl_session_free( ssl_session *session )
@@ -4038,7 +4041,7 @@
         free( session->peer_cert );
     }
 
-    memset( session, 0, sizeof( ssl_session ) );
+    polarssl_zeroize( session, sizeof( ssl_session ) );
 }
 
 /*
@@ -4052,14 +4055,14 @@
 
     if( ssl->out_ctr != NULL )
     {
-        memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
-          free( ssl->out_ctr );
+        polarssl_zeroize( ssl->out_ctr, SSL_BUFFER_LEN );
+        free( ssl->out_ctr );
     }
 
     if( ssl->in_ctr != NULL )
     {
-        memset( ssl->in_ctr, 0, SSL_BUFFER_LEN );
-          free( ssl->in_ctr );
+        polarssl_zeroize( ssl->in_ctr, SSL_BUFFER_LEN );
+        free( ssl->in_ctr );
     }
 
 #if defined(POLARSSL_DHM_C)
@@ -4092,7 +4095,7 @@
 
     if ( ssl->hostname != NULL)
     {
-        memset( ssl->hostname, 0, ssl->hostname_len );
+        polarssl_zeroize( ssl->hostname, ssl->hostname_len );
         free( ssl->hostname );
         ssl->hostname_len = 0;
     }
@@ -4108,7 +4111,7 @@
     SSL_DEBUG_MSG( 2, ( "<= free" ) );
 
     /* Actually clear after last debug message */
-    memset( ssl, 0, sizeof( ssl_context ) );
+    polarssl_zeroize( ssl, sizeof( ssl_context ) );
 }
 
 #endif