boot: Harden critical path against fault attacks

Add fault attack mitigation measures to code vital for the correct
validation of images.

Change-Id: If6eb1110a8c2966faf105d07ad2e95482a80a8d9
Signed-off-by: Raef Coles <raef.coles@arm.com>
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index d9dd352..a8b6b47 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2017-2019 Linaro LTD
  * Copyright (c) 2016-2019 JUUL Labs
- * Copyright (c) 2019 Arm Limited
+ * Copyright (c) 2019-2020 Arm Limited
  *
  * Original license:
  *
@@ -36,6 +36,7 @@
 #include "bootutil/bootutil.h"
 #include "bootutil_priv.h"
 #include "bootutil/bootutil_log.h"
+#include "bootutil/fault_injection_hardening.h"
 #ifdef MCUBOOT_ENC_IMAGES
 #include "bootutil/enc_key.h"
 #endif
@@ -106,6 +107,49 @@
 #define BOOT_SWAP_TABLES_COUNT \
     (sizeof boot_swap_tables / sizeof boot_swap_tables[0])
 
+/**
+ * @brief Determine if the data at two memory addresses is equal
+ *
+ * @param s1    The first  memory region to compare.
+ * @param s2    The second memory region to compare.
+ * @param n     The amount of bytes to compare.
+ *
+ * @note        This function does not comply with the specification of memcmp,
+ *              so should not be considered a drop-in replacement. It has no
+ *              constant time execution. The point is to make sure that all the
+ *              bytes are compared and detect if loop was abused and some cycles
+ *              was skipped due to fault injection.
+ *
+ * @return      FIH_SUCCESS if memory regions are equal, otherwise FIH_FAILURE
+ */
+#ifdef MCUBOOT_FIH_PROFILE_OFF
+inline
+fih_int boot_fih_memequal(const void *s1, const void *s2, size_t n)
+{
+    return memcmp(s1, s2, n);
+}
+#else
+fih_int boot_fih_memequal(const void *s1, const void *s2, size_t n)
+{
+    size_t i;
+    uint8_t *s1_p = (uint8_t*) s1;
+    uint8_t *s2_p = (uint8_t*) s2;
+    fih_int ret = FIH_FAILURE;
+
+    for (i = 0; i < n; i++) {
+        if (s1_p[i] != s2_p[i]) {
+            goto out;
+        }
+    }
+    if (i == n) {
+        ret = FIH_SUCCESS;
+    }
+
+out:
+    FIH_RET(ret);
+}
+#endif
+
 static int
 boot_magic_decode(const uint32_t *magic)
 {