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;
}