Boot: Add constant time memory equality function

Add boot_secure_memequal function which runs in constant time,
mitigating the risk of timing side channel attacks. Replace calls to
memcmp where applicable (where they test only equality).

Change-Id: I062a433a67a1a865d6e890ba06a75bfb6b13deb3
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
index ecd2874..9ce0ff1 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
@@ -101,10 +101,36 @@
 #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.
+ *
+ * @return      0 if memory regions are equal.
+ */
+uint32_t boot_secure_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;
+    uint32_t ret = 0;
+
+    for (i = 0; i < n; i++) {
+        ret |= (s1_p[i] ^ s2_p[i]);
+    }
+
+    return ret;
+}
+
 static int
 boot_magic_decode(const uint32_t *magic)
 {
-    if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0) {
+    if (boot_secure_memequal(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0) {
         return BOOT_MAGIC_GOOD;
     }
     return BOOT_MAGIC_BAD;
@@ -327,7 +353,7 @@
         goto out;
     }
 
-    if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) != 0) {
+    if (boot_secure_memequal(magic, boot_img_magic, BOOT_MAGIC_SZ) != 0) {
         /*
          * If the primary slot's magic is not valid, try scratch...
          */
@@ -346,7 +372,7 @@
             goto out;
         }
 
-        assert(memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0);
+        assert(boot_secure_memequal(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0);
     }
 
     off = boot_swap_size_off(fap);