Force some compilers to respect volatile reads

Inspection of the generated assembly showed that before this commit, armcc 5
was optimizing away the successive reads to the volatile local variable that's
used for double-checks. Inspection also reveals that inserting a call to an
external function is enough to prevent it from doing that.

The tested versions of ARM-GCC, Clang and Armcc 6 (aka armclang) all keep the
double read, with our without a call to an external function in the middle.

The inserted function can also be changed to insert a random delay if
desired in the future, as it is appropriately places between the reads.
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 586f0d9..e20f1c3 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -238,6 +238,13 @@
  */
 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.
+ */
+void mbedtls_platform_enforce_volatile_reads( void );
+
 #if defined(MBEDTLS_HAVE_TIME_DATE)
 /**
  * \brief      Platform-specific implementation of gmtime_r()
diff --git a/library/pk.c b/library/pk.c
index eaaa371..9eddb61 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -598,6 +598,7 @@
 
     if( ret_fi == UECC_SUCCESS )
     {
+        mbedtls_platform_enforce_volatile_reads();
         if( ret_fi == UECC_SUCCESS )
             return( 0 );
         else
diff --git a/library/platform_util.c b/library/platform_util.c
index 1a0fefa..97dfe73 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -168,6 +168,15 @@
 #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 )
+{
+}
+
 #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
 #include <time.h>
 #if !defined(_WIN32) && (defined(unix) || \
diff --git a/tinycrypt/ecc_dsa.c b/tinycrypt/ecc_dsa.c
index 687ea98..6c171c3 100644
--- a/tinycrypt/ecc_dsa.c
+++ b/tinycrypt/ecc_dsa.c
@@ -67,6 +67,7 @@
 #if defined(MBEDTLS_USE_TINYCRYPT)
 #include <tinycrypt/ecc.h>
 #include <tinycrypt/ecc_dsa.h>
+#include "mbedtls/platform_util.h"
 
 #if default_RNG_defined
 static uECC_RNG_Function g_rng_function = &default_CSPRNG;
@@ -304,6 +305,7 @@
 	/* Accept only if v == r. */
 	diff = uECC_vli_equal(rx, r);
 	if (diff == 0) {
+		mbedtls_platform_enforce_volatile_reads();
 		if (diff == 0) {
 			return UECC_SUCCESS;
 		}