Merge remote-tracking branch 'upstream/pr/2982' into baremetal

* upstream/pr/2982:
  Use mbedtls_platform_memset in data_randomize
  Protect get/put on secret data on AES-module
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index e20f1c3..fa9f326 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -239,11 +239,18 @@
 uint32_t mbedtls_platform_random_in_range( size_t num );
 
 /**
- * \brief       This function does nothing, but can be inserted between
- *              successive reads to a volatile local variable to prevent
- *              compilers from optimizing them away.
+ * \brief       Random delay function.
+ *
+ *              Function implements a random delay by incrementing a local
+ *              variable randomized number of times (busy-looping).
+ *
+ *              Duration of the delay is random as number of variable increments
+ *              is randomized.
+ *
+ * \note        Currently the function is dependent of hardware providing an
+ *              rng with MBEDTLS_ENTROPY_HARDWARE_ALT.
  */
-void mbedtls_platform_enforce_volatile_reads( void );
+void mbedtls_platform_random_delay( void );
 
 #if defined(MBEDTLS_HAVE_TIME_DATE)
 /**
diff --git a/library/entropy.c b/library/entropy.c
index b4d1f29..6656ee8 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -273,7 +273,7 @@
         volatile int strong_fi = ctx->source[i].strong;
         if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
         {
-            mbedtls_platform_enforce_volatile_reads();
+            mbedtls_platform_random_delay();
 
             if( strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
                 have_one_strong_fi = MBEDTLS_ENTROPY_SOURCE_STRONG;
@@ -305,7 +305,7 @@
 
     if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( have_one_strong_fi == MBEDTLS_ENTROPY_SOURCE_STRONG )
         {
             return( ret );
diff --git a/library/pk.c b/library/pk.c
index 27276a8..caa5e17 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -597,7 +597,7 @@
 
     if( ret_fi == UECC_SUCCESS )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ret_fi == UECC_SUCCESS )
             return( 0 );
         else
@@ -1553,7 +1553,7 @@
 
     if( verify_ret == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( verify_ret == 0 )
         {
             return( verify_ret );
diff --git a/library/platform_util.c b/library/platform_util.c
index 16867aa..2c22b3c 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -45,6 +45,9 @@
 #include <stddef.h>
 #include <string.h>
 
+/* Max number of loops for mbedtls_platform_random_delay */
+#define MAX_RAND_DELAY  100
+
 #if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
 /*
  * This implementation should never be optimized out by the compiler
@@ -165,13 +168,32 @@
 #endif
 }
 
-/* Some compilers (armcc 5 for example) optimize away successive reads from a
- * volatile local variable (which we use as a counter-measure to fault
- * injection attacks), unless there is a call to an external function between
- * them. This functions doesn't need to do anything, it just needs to be
- * in another compilation unit. So here's a function that does nothing. */
-void mbedtls_platform_enforce_volatile_reads( void )
+void mbedtls_platform_random_delay( void )
 {
+#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+    return;
+#else
+    size_t rn_1, rn_2, rn_3;
+    volatile size_t i = 0;
+    uint8_t shift;
+
+    rn_1 = mbedtls_platform_random_in_range( MAX_RAND_DELAY );
+    rn_2 = mbedtls_platform_random_in_range( 0xffffffff ) + 1;
+    rn_3 = mbedtls_platform_random_in_range( 0xffffffff ) + 1;
+
+    do
+    {
+        i++;
+        shift = rn_2 & 0x07;
+        if ( i % 2 )
+            rn_2 = (uint32_t)( rn_2 >> shift | rn_2 << ( 32 - shift ) );
+        else
+            rn_3 = (uint32_t)( rn_3 << shift | rn_3 >> ( 32 - shift ) );
+        rn_2 ^= rn_3;
+    } while( i < rn_1 || rn_2 == 0 || rn_3 == 0 );
+
+    return;
+#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT */
 }
 
 #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
diff --git a/library/sha256.c b/library/sha256.c
index 785e28b..4dcec89 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -196,11 +196,23 @@
         A[i] = ctx->state[i];
 
 #if defined(MBEDTLS_SHA256_SMALLER)
+    {
+        uint32_t offset = mbedtls_platform_random_in_range(16);
+        mbedtls_platform_memset( W, 0, sizeof( W ) );
+
+        for( i = offset; i < 16; i++ )
+        {
+            W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
+        }
+        for( i = 0; i < offset; i++ )
+        {
+            W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
+        }
+    }
+
     for( i = 0; i < 64; i++ )
     {
-        if( i < 16 )
-            W[i] = (uint32_t)mbedtls_platform_get_uint32_be( &data[4 * i] );
-        else
+        if( i >= 16 )
             R( i );
 
         P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
@@ -323,6 +335,7 @@
     int ret, s_pos, o_pos;
     uint32_t used;
     uint32_t high, low;
+    uint32_t offset = 0;
 
     SHA256_VALIDATE_RET( ctx != NULL );
     SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
@@ -366,11 +379,15 @@
     /*
      * Output final state
      */
+    offset = mbedtls_platform_random_in_range(7);
 
-    for( s_pos = 0, o_pos = 0; s_pos < 7; s_pos++, o_pos += 4 )
+    mbedtls_platform_memset( output, 0, 32 );
+
+    for( s_pos = offset, o_pos = offset * 4; s_pos < 7;
+            s_pos++, o_pos += 4 )
     {
         (void)mbedtls_platform_put_uint32_be( &output[o_pos],
-                                              ctx->state[s_pos] );
+                                            ctx->state[s_pos] );
     }
 
 #if !defined(MBEDTLS_SHA256_NO_SHA224)
@@ -378,6 +395,11 @@
 #endif
         (void)mbedtls_platform_put_uint32_be( &output[28], ctx->state[7] );
 
+    for( s_pos = 0, o_pos = 0; s_pos < (int)offset; s_pos++, o_pos += 4 )
+    {
+        (void)mbedtls_platform_put_uint32_be( &output[o_pos],
+                                            ctx->state[s_pos] );
+    }
     return( 0 );
 }
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 479554d..3c59923 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -717,7 +717,7 @@
             ( mbedtls_ssl_conf_get_prng( ssl->conf ), p, 28 );
     if( ret == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ret == 0 )
         {
             ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
@@ -2369,7 +2369,7 @@
 
     if( ret == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ret == 0 )
         {
             ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET;
@@ -2442,7 +2442,7 @@
 
     if( ret == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ret == 0 )
         {
             ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET;
@@ -3071,7 +3071,7 @@
 
         if( ret == 0 )
         {
-            mbedtls_platform_enforce_volatile_reads();
+            mbedtls_platform_random_delay();
 
             if( ret == 0 )
             {
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 92d1da0..bab8f00 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -4064,7 +4064,7 @@
 
     if( pmscounter == ssl->handshake->pmslen )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( pmscounter == ssl->handshake->pmslen )
         {
             ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET;
@@ -4651,7 +4651,7 @@
 
     if( ret == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
 
         if( ret == 0 )
         {
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 165cd85..1d5503b 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1938,7 +1938,7 @@
                   ssl );
     if( ret == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ret == 0 )
         {
             ssl->handshake->key_derivation_done = MBEDTLS_SSL_FI_FLAG_SET;
@@ -2020,7 +2020,7 @@
                                       mbedtls_ssl_conf_get_prng( ssl->conf ) );
         if( ret == 0 )
         {
-            mbedtls_platform_enforce_volatile_reads();
+            mbedtls_platform_random_delay();
             if( ret == 0 )
             {
                 ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET;
@@ -2063,7 +2063,7 @@
                                        mbedtls_ssl_conf_get_prng( ssl->conf ) );
         if( ret == 0 )
         {
-            mbedtls_platform_enforce_volatile_reads();
+            mbedtls_platform_random_delay();
             if( ret == 0 )
             {
                 ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET;
@@ -2094,7 +2094,7 @@
             mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) );
         if( ret == 0 )
         {
-            mbedtls_platform_enforce_volatile_reads();
+            mbedtls_platform_random_delay();
             if( ret == 0 )
             {
                 ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET;
@@ -2123,7 +2123,7 @@
                 mbedtls_ssl_conf_get_prng( ssl->conf ) );
         if( ret == 0 )
         {
-            mbedtls_platform_enforce_volatile_reads();
+            mbedtls_platform_random_delay();
             if( ret == 0 )
             {
                 ssl->handshake->premaster_generated = MBEDTLS_SSL_FI_FLAG_SET;
@@ -7355,7 +7355,7 @@
 
     if( verify_ret == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( verify_ret == 0 )
         {
             flow_counter++;
@@ -7445,7 +7445,7 @@
         ( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
           verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
             ( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
               verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
@@ -7511,7 +7511,7 @@
         flow_counter == 4 )
 #endif
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( verify_ret == 0 &&
 #if defined(MBEDTLS_ECP_C) || defined(MBEDTLS_USE_TINYCRYPT)
             flow_counter == 5 )
@@ -7998,7 +7998,7 @@
         1 )
 #endif
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( authmode == MBEDTLS_SSL_VERIFY_NONE ||
             authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ||
 #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
@@ -8019,7 +8019,7 @@
 #if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION)
     if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ssl->handshake->resume == MBEDTLS_SSL_FI_FLAG_SET )
         {
             /* When doing session resume, no premaster or peer authentication */
@@ -8036,7 +8036,7 @@
 
     if( ssl->handshake->peer_authenticated == MBEDTLS_SSL_FI_FLAG_SET )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ssl->handshake->peer_authenticated == MBEDTLS_SSL_FI_FLAG_SET )
         {
             ret = 0;
@@ -8057,7 +8057,7 @@
         ssl->handshake->key_derivation_done == MBEDTLS_SSL_FI_FLAG_SET &&
         ssl->handshake->premaster_generated == MBEDTLS_SSL_FI_FLAG_SET )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( ssl->handshake->hello_random_set == MBEDTLS_SSL_FI_FLAG_SET &&
             ssl->handshake->key_derivation_done == MBEDTLS_SSL_FI_FLAG_SET &&
             ssl->handshake->premaster_generated == MBEDTLS_SSL_FI_FLAG_SET )
diff --git a/library/x509_crt.c b/library/x509_crt.c
index fd3fa1a..af8f1d6 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -3043,7 +3043,7 @@
 
         if( ret_fi == 0 )
         {
-            mbedtls_platform_enforce_volatile_reads();
+            mbedtls_platform_random_delay();
             if( ret_fi == 0 )
                 signature_is_good = X509_SIGNATURE_IS_GOOD;
         }
@@ -3549,7 +3549,7 @@
         if( signature_is_good_fi != X509_SIGNATURE_IS_GOOD )
             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED | X509_BADCERT_FI_EXTRA;
 
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( signature_is_good_fi != X509_SIGNATURE_IS_GOOD )
             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED | X509_BADCERT_FI_EXTRA;
 
@@ -3861,7 +3861,7 @@
     flags_fi = *flags;
     if( flags_fi == 0 )
     {
-        mbedtls_platform_enforce_volatile_reads();
+        mbedtls_platform_random_delay();
         if( flags_fi == 0 )
             return( 0 );
     }
diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c
index 0447cba..c6c722a 100644
--- a/tinycrypt/ecc.c
+++ b/tinycrypt/ecc.c
@@ -168,7 +168,7 @@
 	}
 
 	/* i should be 32 */
-	mbedtls_platform_enforce_volatile_reads();
+	mbedtls_platform_random_delay();
 	diff |= (unsigned char) i ^ 32;
 
 	return diff;
@@ -296,7 +296,7 @@
 	}
 
 	/* i should be -1 now */
-	mbedtls_platform_enforce_volatile_reads();
+	mbedtls_platform_random_delay();
 	diff |= i ^ -1;
 
 	return diff;
@@ -1043,7 +1043,7 @@
 	if (problem != 0) {
 		return UECC_FAULT_DETECTED;
 	}
-	mbedtls_platform_enforce_volatile_reads();
+	mbedtls_platform_random_delay();
 	if (problem != 0) {
 		return UECC_FAULT_DETECTED;
 	}
@@ -1055,7 +1055,7 @@
 		/* invalid input, can happen without fault */
 		return UECC_FAILURE;
 	}
-	mbedtls_platform_enforce_volatile_reads();
+	mbedtls_platform_random_delay();
 	if (problem != 0) {
 		/* failure on second check means fault, though */
 		return UECC_FAULT_DETECTED;
@@ -1085,7 +1085,7 @@
 		r = UECC_FAULT_DETECTED;
 		goto clear_and_out;
 	}
-	mbedtls_platform_enforce_volatile_reads();
+	mbedtls_platform_random_delay();
 	if (problem != 0) {
 		r = UECC_FAULT_DETECTED;
 		goto clear_and_out;
@@ -1098,7 +1098,7 @@
 		r = UECC_FAULT_DETECTED;
 		goto clear_and_out;
 	}
-	mbedtls_platform_enforce_volatile_reads();
+	mbedtls_platform_random_delay();
 	if (problem != 0) {
 		r = UECC_FAULT_DETECTED;
 		goto clear_and_out;
@@ -1195,7 +1195,7 @@
 	/* Make sure that y^2 == x^3 + ax + b */
 	diff = uECC_vli_equal(tmp1, tmp2);
 	if (diff == 0) {
-		mbedtls_platform_enforce_volatile_reads();
+	    mbedtls_platform_random_delay();
 		if (diff == 0) {
 			return 0;
 		}
diff --git a/tinycrypt/ecc_dsa.c b/tinycrypt/ecc_dsa.c
index 8fa8509..660c5e9 100644
--- a/tinycrypt/ecc_dsa.c
+++ b/tinycrypt/ecc_dsa.c
@@ -279,7 +279,7 @@
 	/* Accept only if v == r. */
 	diff = uECC_vli_equal(rx, r);
 	if (diff == 0) {
-		mbedtls_platform_enforce_volatile_reads();
+	    mbedtls_platform_random_delay();
 		if (diff == 0) {
 			return UECC_SUCCESS;
 		}