Merge remote-tracking branch 'public/pr/2870' into baremetal
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 7033af8..586f0d9 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -164,6 +164,80 @@
  */
 void mbedtls_platform_zeroize( void *buf, size_t len );
 
+/**
+ * \brief       Secure memset
+ *
+ *              This is a constant-time version of memset(). If
+ *              MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the buffer is
+ *              initialised with random data and the order is also
+ *              randomised using the hardware RNG in order to further harden
+ *              against side-channel attacks.
+ *
+ * \param ptr   Buffer to be set.
+ * \param value Value to be used when setting the buffer.
+ * \param num   The length of the buffer in bytes.
+ *
+ * \return      The value of \p ptr.
+ */
+void *mbedtls_platform_memset( void *ptr, int value, size_t num );
+
+/**
+ * \brief       Secure memcpy
+ *
+ *              This is a constant-time version of memcpy(). If
+ *              MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the buffer is
+ *              initialised with random data and the order is also
+ *              randomised using the hardware RNG in order to further harden
+ *              against side-channel attacks.
+ *
+ * \param dst   Destination buffer where the data is being copied to.
+ * \param src   Source buffer where the data is being copied from.
+ * \param num   The length of the buffers in bytes.
+ *
+ * \return      The value of \p dst.
+ */
+void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num );
+
+/**
+ * \brief       Secure memcmp
+ *
+ *              This is a constant-time version of memcmp(). If
+ *              MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the order is also
+ *              randomised using the hardware RNG in order to further harden
+ *              against side-channel attacks.
+ *
+ * \param buf1  First buffer to compare.
+ * \param buf2  Second buffer to compare against.
+ * \param num   The length of the buffers in bytes.
+ *
+ * \return      0 if the buffers were equal or an unspecified non-zero value
+ *              otherwise.
+ */
+int mbedtls_platform_memcmp( const void *buf1, const void *buf2, size_t num );
+
+/**
+ * \brief       RNG-function for getting a random in given range.
+ *
+ *              This function is meant to provide a global RNG to be used
+ *              throughout Mbed TLS for hardening the library. It is used
+ *              for generating a random delay, random data or random offset
+ *              for utility functions. It is not meant to be a
+ *              cryptographically secure RNG, but provide an RNG for utility
+ *              functions.
+ *
+ * \note        Currently the function is dependent of hardware providing an
+ *              rng with MBEDTLS_ENTROPY_HARDWARE_ALT. By default, 0 is
+ *              returned.
+ *
+ * \note        If the given range is [0, 0), 0 is returned.
+ *
+ * \param num   Max-value for the generated random number, exclusive.
+ *              The generated number will be on range [0, num).
+ *
+ * \return      The generated random number.
+ */
+uint32_t mbedtls_platform_random_in_range( size_t num );
+
 #if defined(MBEDTLS_HAVE_TIME_DATE)
 /**
  * \brief      Platform-specific implementation of gmtime_r()
diff --git a/library/platform_util.c b/library/platform_util.c
index 6f6d8b6..9461a9c 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -38,6 +38,10 @@
 #include "mbedtls/platform.h"
 #include "mbedtls/threading.h"
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+#include "mbedtls/entropy_poll.h"
+#endif
+
 #include <stddef.h>
 #include <string.h>
 
@@ -79,6 +83,87 @@
 }
 #endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
 
+void *mbedtls_platform_memset( void *ptr, int value, size_t num )
+{
+    /* Randomize start offset. */
+    size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
+    /* Randomize data */
+    uint32_t data = mbedtls_platform_random_in_range( 256 );
+
+    /* Perform a pair of memset operations from random locations with
+     * random data */
+    memset( (void *) ( (unsigned char *) ptr + start_offset ), data,
+            ( num - start_offset ) );
+    memset( (void *) ptr, data, start_offset );
+
+    /* Perform the original memset */
+    return( memset( ptr, value, num ) );
+}
+
+void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num )
+{
+    /* Randomize start offset. */
+    size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
+    /* Randomize initial data to prevent leakage while copying */
+    uint32_t data = mbedtls_platform_random_in_range( 256 );
+
+    memset( (void *) dst, data, num );
+    memcpy( (void *) ( (unsigned char *) dst + start_offset ),
+            (void *) ( (unsigned char *) src + start_offset ),
+            ( num - start_offset ) );
+    return( memcpy( (void *) dst, (void *) src, start_offset ) );
+}
+
+int mbedtls_platform_memcmp( const void *buf1, const void *buf2, size_t num )
+{
+    volatile const unsigned char *A = (volatile const unsigned char *) buf1;
+    volatile const unsigned char *B = (volatile const unsigned char *) buf2;
+    volatile unsigned char diff = 0;
+
+    size_t i = num;
+
+    size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
+
+    for( i = start_offset; i < num; i++ )
+    {
+        unsigned char x = A[i], y = B[i];
+        diff |= x ^ y;
+    }
+
+    for( i = 0; i < start_offset; i++ )
+    {
+        unsigned char x = A[i], y = B[i];
+        diff |= x ^ y;
+    }
+
+    return( diff );
+}
+
+uint32_t mbedtls_platform_random_in_range( size_t num )
+{
+#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+    (void) num;
+    return 0;
+#else
+    uint32_t result = 0;
+    size_t olen = 0;
+
+    mbedtls_hardware_poll( NULL, (unsigned char *) &result, sizeof( result ),
+                           &olen );
+
+    if( num == 0 )
+    {
+        result = 0;
+    }
+    else
+    {
+        result %= num;
+    }
+
+    return( result );
+#endif
+}
+
 #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
 #include <time.h>
 #if !defined(_WIN32) && (defined(unix) || \
diff --git a/programs/aes/aescrypt2.c b/programs/aes/aescrypt2.c
index 8242ea7..70f0a1e 100644
--- a/programs/aes/aescrypt2.c
+++ b/programs/aes/aescrypt2.c
@@ -80,6 +80,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index 8d671ab..f9cf6b2 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -82,6 +82,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c
index ed5357f..d154e59 100644
--- a/programs/hash/generic_sum.c
+++ b/programs/hash/generic_sum.c
@@ -52,6 +52,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 static int generic_wrapper( mbedtls_md_handle_t md_info, char *filename, unsigned char *sum )
 {
diff --git a/programs/hash/hello.c b/programs/hash/hello.c
index 55a0c7e..7e3b20e 100644
--- a/programs/hash/hello.c
+++ b/programs/hash/hello.c
@@ -48,6 +48,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( void )
 {
diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c
index 86b260c..12f4de7 100644
--- a/programs/pkey/dh_client.c
+++ b/programs/pkey/dh_client.c
@@ -72,6 +72,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( void )
 {
diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c
index bf5482e..8431ae6 100644
--- a/programs/pkey/dh_genprime.c
+++ b/programs/pkey/dh_genprime.c
@@ -69,6 +69,18 @@
  */
 #define GENERATOR "4"
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char **argv )
 {
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index c011774..78efba1 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -72,6 +72,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( void )
 {
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index b851c31..4cde070 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -100,6 +100,18 @@
 #define dump_pubkey( a, b )
 #endif
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c
index 23e4e14..8fcfeb4 100644
--- a/programs/pkey/gen_key.c
+++ b/programs/pkey/gen_key.c
@@ -137,6 +137,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 /*
  * global options
diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c
index 7939309..a106dbb 100644
--- a/programs/pkey/key_app.c
+++ b/programs/pkey/key_app.c
@@ -74,6 +74,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 /*
  * global options
diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c
index 16dd1b6..315810d 100644
--- a/programs/pkey/key_app_writer.c
+++ b/programs/pkey/key_app_writer.c
@@ -99,6 +99,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 /*
  * global options
diff --git a/programs/pkey/mpi_demo.c b/programs/pkey/mpi_demo.c
index ecdcd32..2ae441c 100644
--- a/programs/pkey/mpi_demo.c
+++ b/programs/pkey/mpi_demo.c
@@ -50,6 +50,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( void )
 {
diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c
index bf42507..19ec2da 100644
--- a/programs/pkey/pk_decrypt.c
+++ b/programs/pkey/pk_decrypt.c
@@ -60,6 +60,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c
index a32b147..4ab2cac 100644
--- a/programs/pkey/pk_encrypt.c
+++ b/programs/pkey/pk_encrypt.c
@@ -61,6 +61,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c
index ba4f779..84a613b 100644
--- a/programs/pkey/pk_sign.c
+++ b/programs/pkey/pk_sign.c
@@ -61,6 +61,18 @@
 #include <stdio.h>
 #include <string.h>
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 /*
  * For the currently used signature algorithms the buffer to store any signature
diff --git a/programs/pkey/pk_verify.c b/programs/pkey/pk_verify.c
index f80bf64..ccfc149 100644
--- a/programs/pkey/pk_verify.c
+++ b/programs/pkey/pk_verify.c
@@ -57,6 +57,18 @@
 #include <stdio.h>
 #include <string.h>
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c
index ff71bd0..cde5f24 100644
--- a/programs/pkey/rsa_decrypt.c
+++ b/programs/pkey/rsa_decrypt.c
@@ -59,6 +59,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c
index 4a71c15..7210578 100644
--- a/programs/pkey/rsa_encrypt.c
+++ b/programs/pkey/rsa_encrypt.c
@@ -59,6 +59,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c
index d556c19..a8d5f05 100644
--- a/programs/pkey/rsa_genkey.c
+++ b/programs/pkey/rsa_genkey.c
@@ -64,6 +64,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( void )
 {
diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c
index 9bcd7a6..4db0528 100644
--- a/programs/pkey/rsa_sign.c
+++ b/programs/pkey/rsa_sign.c
@@ -56,6 +56,18 @@
 #include <stdio.h>
 #include <string.h>
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c
index 42209e2..2e25163 100644
--- a/programs/pkey/rsa_sign_pss.c
+++ b/programs/pkey/rsa_sign_pss.c
@@ -60,6 +60,18 @@
 #include <stdio.h>
 #include <string.h>
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c
index 94f0ef9..73f5473 100644
--- a/programs/pkey/rsa_verify.c
+++ b/programs/pkey/rsa_verify.c
@@ -55,6 +55,18 @@
 #include <stdio.h>
 #include <string.h>
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/pkey/rsa_verify_pss.c b/programs/pkey/rsa_verify_pss.c
index 148cd51..27533a8 100644
--- a/programs/pkey/rsa_verify_pss.c
+++ b/programs/pkey/rsa_verify_pss.c
@@ -60,6 +60,18 @@
 #include <stdio.h>
 #include <string.h>
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/random/gen_entropy.c b/programs/random/gen_entropy.c
index 6ae63b7..f2596f9 100644
--- a/programs/random/gen_entropy.c
+++ b/programs/random/gen_entropy.c
@@ -51,6 +51,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c
index 59df34b..4fc8086 100644
--- a/programs/random/gen_random_ctr_drbg.c
+++ b/programs/random/gen_random_ctr_drbg.c
@@ -54,6 +54,18 @@
 }
 #else
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c
index b31090f..336d695 100644
--- a/programs/ssl/dtls_client.c
+++ b/programs/ssl/dtls_client.c
@@ -109,6 +109,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret, len;
diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c
index 1dddf8e..8190f1e 100644
--- a/programs/ssl/dtls_server.c
+++ b/programs/ssl/dtls_server.c
@@ -118,6 +118,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( void )
 {
     int ret, len;
diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c
index 7d86854..3d15c60 100644
--- a/programs/ssl/mini_client.c
+++ b/programs/ssl/mini_client.c
@@ -180,6 +180,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( void )
 {
     int ret = exit_ok;
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index 9922a7e..1ab2e10 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -99,6 +99,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( void )
 {
     int ret = 1, len;
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 1a07c9d..e470f3b 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -925,6 +925,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 0, len, tail_len, i, written, frags, retry_left;
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index 7033b86..e9c220c 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -116,6 +116,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( void )
 {
     int ret = 1, len, cnt = 0, pid;
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 24000a2..6e728dc 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -375,6 +375,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 1, len;
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index e13af91..0ad63b1 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -111,6 +111,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( void )
 {
     int ret, len;
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index c0476dc..0470bf3 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1536,6 +1536,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 0, len, written, frags, exchanges_left;
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 88e3290..9c6aafb 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -258,6 +258,18 @@
          rsa, dhm, ecdsa, ecdh;
 } todo_list;
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
 
 int main( int argc, char *argv[] )
 {
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 727054e..82f08fa 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -279,6 +279,19 @@
 };
 #endif /* MBEDTLS_SELF_TEST */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
 #if defined(MBEDTLS_SELF_TEST)
diff --git a/programs/test/zeroize.c b/programs/test/zeroize.c
index 29cc0ac..54f7c62 100644
--- a/programs/test/zeroize.c
+++ b/programs/test/zeroize.c
@@ -99,3 +99,16 @@
 
     return( exit_code );
 }
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c
index b82f83f..bdc2017 100644
--- a/programs/x509/cert_app.c
+++ b/programs/x509/cert_app.c
@@ -165,6 +165,19 @@
 }
 #endif /* MBEDTLS_SSL_CONF_RNG */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 1;
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index f3d9157..33e4078 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -154,6 +154,19 @@
     return( 0 );
 }
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 1;
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index ef40447..a0ef2dd 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -214,6 +214,19 @@
     return( 0 );
 }
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 1;
diff --git a/programs/x509/crl_app.c b/programs/x509/crl_app.c
index fc22188..87793f7 100644
--- a/programs/x509/crl_app.c
+++ b/programs/x509/crl_app.c
@@ -72,6 +72,19 @@
     const char *filename;       /* filename of the certificate file     */
 } opt;
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 1;
diff --git a/programs/x509/req_app.c b/programs/x509/req_app.c
index ed80155..ddde3f6 100644
--- a/programs/x509/req_app.c
+++ b/programs/x509/req_app.c
@@ -72,6 +72,19 @@
     const char *filename;       /* filename of the certificate request  */
 } opt;
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    size_t i;
+    (void) data;
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+    *olen = len;
+    return( 0 );
+}
+#endif
+
 int main( int argc, char *argv[] )
 {
     int ret = 1;
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 365410e..a996dd6 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1591,6 +1591,16 @@
     if_build_succeeded tests/ssl-opt.sh --filter "^Default, DTLS$"
 }
 
+component_test_hardware_entropy () {
+    msg "build: default config + MBEDTLS_ENTROPY_HARDWARE_ALT"
+    scripts/config.pl set MBEDTLS_ENTROPY_HARDWARE_ALT
+    make CFLAGS='-Werror -O1'
+
+    msg "test: default config + MBEDTLS_ENTROPY_HARDWARE_ALT"
+    if_build_succeeded make test
+    if_build_succeeded tests/ssl-opt.sh --filter "^Default, DTLS$"
+}
+
 component_test_allow_sha1 () {
     msg "build: allow SHA1 in certificates by default"
     scripts/config.pl set MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 6ead2d3..43426f5 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -561,6 +561,16 @@
 }
 #endif /* MBEDTLS_USE_TINYCRYPT */
 
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+int mbedtls_hardware_poll( void *data, unsigned char *output,
+                           size_t len, size_t *olen )
+{
+    (void) data;
+    *olen = len;
+    return( rnd_std_rand( NULL, output, len ) );
+}
+#endif
+
 /**
  * This function only returns zeros
  *