Merge pull request #3336 from piotr-now/baremetal_flowmon

Increasing resistance to fault injection attacks related with memory operations.
diff --git a/library/platform_util.c b/library/platform_util.c
index 2c22b3c..3869f30 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -111,6 +111,9 @@
     /* Randomize initial data to prevent leakage while copying */
     uint32_t data = mbedtls_platform_random_in_range( 256 );
 
+    /* Use memset with random value at first to increase security - memset is
+       not normally part of the memcpy function and here can be useed
+       with regular, unsecured implementation */
     memset( (void *) dst, data, num );
     memcpy( (void *) ( (unsigned char *) dst + start_offset ),
             (void *) ( (unsigned char *) src + start_offset ),
@@ -124,23 +127,26 @@
     volatile const unsigned char *B = (volatile const unsigned char *) buf2;
     volatile unsigned char diff = 0;
 
-    size_t i = num;
-
+    /* Start from a random location and check the correct number of iterations */
+    size_t i, flow_counter = 0;
     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];
+        flow_counter++;
         diff |= x ^ y;
     }
 
     for( i = 0; i < start_offset; i++ )
     {
         unsigned char x = A[i], y = B[i];
+        flow_counter++;
         diff |= x ^ y;
     }
 
-    return( diff );
+    /* Return 0 only when diff is 0 and flow_counter is equal to num */
+    return( (int) diff | (int) ( flow_counter ^ num ) );
 }
 
 uint32_t mbedtls_platform_random_in_range( size_t num )
diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c
index c6c722a..ba36267 100644
--- a/tinycrypt/ecc.c
+++ b/tinycrypt/ecc.c
@@ -286,20 +286,32 @@
 {
 
 	uECC_word_t diff = 0;
+	uECC_word_t flow_monitor = 0;
 	uECC_word_t tmp1, tmp2;
 	volatile int i;
 
-	for (i = NUM_ECC_WORDS - 1; i >= 0; --i) {
+	/* Start from a random location and check the correct number of iterations */
+	int start_offset = mbedtls_platform_random_in_range(NUM_ECC_WORDS);
+
+	for (i = start_offset; i < NUM_ECC_WORDS; ++i) {
 		tmp1 = left[i];
 		tmp2 = right[i];
+		flow_monitor++;
 		diff |= (tmp1 ^ tmp2);
 	}
 
-	/* i should be -1 now */
-	mbedtls_platform_random_delay();
-	diff |= i ^ -1;
+	for (i = 0; i < start_offset; ++i) {
+		tmp1 = left[i];
+		tmp2 = right[i];
+		flow_monitor++;
+		diff |= (tmp1 ^ tmp2);
+	}
 
-	return diff;
+	/* Random delay to increase security */
+	mbedtls_platform_random_delay();
+
+	/* Return 0 only when diff is 0 and flow_counter is equal to NUM_ECC_WORDS */
+	return (diff | (flow_monitor ^ NUM_ECC_WORDS));
 }
 
 uECC_word_t cond_set(uECC_word_t p_true, uECC_word_t p_false, unsigned int cond)
@@ -848,7 +860,7 @@
 		}
 		while (carry < 0);
 	} else  {
-		while (carry || 
+		while (carry ||
 		       uECC_vli_cmp_unsafe(curve_p, result) != 1) {
 			carry -= uECC_vli_sub(result, result, curve_p);
 		}