Boot: Harden critical path against fault attacks

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

Change-Id: Iea12a6eac9c3f516ed8c96a6df44b7a4086dd7f5
Signed-off-by: Raef Coles <raef.coles@arm.com>
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/bl2/ext/mcuboot/CMakeLists.txt b/bl2/ext/mcuboot/CMakeLists.txt
index 2e1e082..7b056e7 100644
--- a/bl2/ext/mcuboot/CMakeLists.txt
+++ b/bl2/ext/mcuboot/CMakeLists.txt
@@ -34,6 +34,8 @@
         ${MCUBOOT_PATH}/boot/bootutil/src/swap_move.c
         ${MCUBOOT_PATH}/boot/bootutil/src/swap_misc.c
         ${MCUBOOT_PATH}/boot/bootutil/src/encrypted.c
+        ${MCUBOOT_PATH}/boot/bootutil/src/fault_injection_hardening.c
+        ${MCUBOOT_PATH}/boot/bootutil/src/fault_injection_hardening_delay_rng_mbedtls.c
 )
 
 set(MCUBOOT_ALLOWED_LOG_LEVELS OFF ERROR WARNING INFO DEBUG)
diff --git a/bl2/ext/mcuboot/bl2_main.c b/bl2/ext/mcuboot/bl2_main.c
index d0f1577..ab77052 100644
--- a/bl2/ext/mcuboot/bl2_main.c
+++ b/bl2/ext/mcuboot/bl2_main.c
@@ -25,6 +25,7 @@
 #include "bootutil/image.h"
 #include "bootutil/bootutil.h"
 #include "bootutil/boot_record.h"
+#include "bootutil/fault_injection_hardening.h"
 #include "flash_map_backend/flash_map_backend.h"
 #include "boot_hal.h"
 #include "uart_stdout.h"
@@ -83,7 +84,7 @@
 int main(void)
 {
     struct boot_rsp rsp;
-    int rc;
+    fih_int fih_rc = FIH_FAILURE;
 
     /* Initialise the mbedtls static memory allocator so that mbedtls allocates
      * memory from the provided static buffer instead of from the heap.
@@ -97,24 +98,21 @@
     /* Perform platform specific initialization */
     if (boot_platform_init() != 0) {
         BOOT_LOG_ERR("Platform init failed");
-        while (1)
-            ;
+        FIH_PANIC;
     }
 
     BOOT_LOG_INF("Starting bootloader");
 
-    rc = boot_nv_security_counter_init();
-    if (rc != 0) {
+    FIH_CALL(boot_nv_security_counter_init, fih_rc);
+    if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
         BOOT_LOG_ERR("Error while initializing the security counter");
-        while (1)
-            ;
+        FIH_PANIC;
     }
 
-    rc = boot_go(&rsp);
-    if (rc != 0) {
+    FIH_CALL(boot_go, fih_rc, &rsp);
+    if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
         BOOT_LOG_ERR("Unable to find bootable image");
-        while (1)
-            ;
+        FIH_PANIC;
     }
 
     BOOT_LOG_INF("Bootloader chainload address offset: 0x%x",
@@ -123,6 +121,5 @@
     do_boot(&rsp);
 
     BOOT_LOG_ERR("Never should get here");
-    while (1)
-        ;
+    FIH_PANIC;
 }
diff --git a/bl2/src/security_cnt.c b/bl2/src/security_cnt.c
index 1359265..7fc6e4c 100644
--- a/bl2/src/security_cnt.c
+++ b/bl2/src/security_cnt.c
@@ -8,6 +8,7 @@
 #include "bootutil/security_cnt.h"
 #include "../../platform/include/tfm_plat_nv_counters.h"
 #include "../../platform/include/tfm_plat_defs.h"
+#include "bootutil/fault_injection_hardening.h"
 #include <stdint.h>
 
 #define TFM_BOOT_NV_COUNTER_0    PLAT_NV_COUNTER_3   /* NV counter of Image 0 */
@@ -33,41 +34,38 @@
     return (enum tfm_nv_counter_t)nv_counter;
 }
 
-int32_t boot_nv_security_counter_init(void)
+fih_int boot_nv_security_counter_init(void)
 {
-    enum tfm_plat_err_t err;
+    fih_int fih_rc = FIH_FAILURE;
 
-    err = tfm_plat_init_nv_counter();
-    if (err != TFM_PLAT_ERR_SUCCESS) {
-        return -1;
-    }
+    fih_rc = fih_int_encode_zero_equality(tfm_plat_init_nv_counter());
 
-    return 0;
+    FIH_RET(fih_rc);
 }
 
-int32_t boot_nv_security_counter_get(uint32_t image_id, uint32_t *security_cnt)
+fih_int boot_nv_security_counter_get(uint32_t image_id, fih_int *security_cnt)
 {
     enum tfm_nv_counter_t nv_counter;
-    enum tfm_plat_err_t err;
+    fih_int fih_rc = FIH_FAILURE;
+    uint32_t security_cnt_soft;
 
     /* Check if it's a null-pointer. */
     if (!security_cnt) {
-        return -1;
+        FIH_RET(FIH_FAILURE);
     }
 
     nv_counter = get_nv_counter_from_image_id(image_id);
     if (nv_counter == TFM_BOOT_NV_COUNTER_MAX) {
-        return -1;
+        FIH_RET(FIH_FAILURE);
     }
 
-    err = tfm_plat_read_nv_counter(nv_counter,
-                                   sizeof(*security_cnt),
-                                   (uint8_t *)security_cnt);
-    if (err != TFM_PLAT_ERR_SUCCESS) {
-        return -1;
-    }
+    fih_rc = fih_int_encode_zero_equality(
+             tfm_plat_read_nv_counter(nv_counter,
+                                      sizeof(security_cnt_soft),
+                                      (uint8_t *)&security_cnt_soft));
+    *security_cnt = fih_int_encode(security_cnt_soft);
 
-    return 0;
+    FIH_RET(fih_rc);
 }
 
 int32_t boot_nv_security_counter_update(uint32_t image_id,
diff --git a/config/config_default.cmake b/config/config_default.cmake
index f522e25..e5ad040 100644
--- a/config/config_default.cmake
+++ b/config/config_default.cmake
@@ -33,6 +33,7 @@
 set(MCUBOOT_HW_ROLLBACK_PROT            ON          CACHE BOOL      "Enable security counter validation against non-volatile HW counters")
 set(MCUBOOT_ENC_IMAGES                  OFF         CACHE BOOL      "Enable encrypted image upgrade support")
 set(MCUBOOT_ENCRYPT_RSA                 OFF         CACHE BOOL      "Use RSA for encrypted image upgrade support")
+set(MCUBOOT_FIH_PROFILE                 OFF         CACHE STRING    "Fault injection hardening profile [OFF, LOW, MEDIUM, HIGH]")
 
 # Note - If either SIGNATURE_TYPE or KEY_LEN are changed, the entries for KEY_S
 # and KEY_NS will either have to be updated manually or removed from the cache.
@@ -125,7 +126,7 @@
 set(CMSIS_5_PATH                        "DOWNLOAD"  CACHE PATH      "Path to CMSIS_5 (or DOWNLOAD to fetch automatically")
 
 set(MCUBOOT_PATH                        "DOWNLOAD"  CACHE PATH      "Path to MCUboot (or DOWNLOAD to fetch automatically")
-set(MCUBOOT_VERSION                     "b2a1a48"   CACHE STRING    "The version of MCUboot to use")
+set(MCUBOOT_VERSION                     "e8fe6cf"   CACHE STRING    "The version of MCUboot to use")
 
 set(PSA_ARCH_TESTS_PATH                 "DOWNLOAD"  CACHE PATH      "Path to PSA arch tests (or DOWNLOAD to fetch automatically")
 set(PSA_ARCH_TESTS_VERSION              "master"    CACHE STRING    "The version of PSA arch tests to use")
diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt
index 701f719..de11459 100644
--- a/platform/CMakeLists.txt
+++ b/platform/CMakeLists.txt
@@ -134,6 +134,7 @@
             MCUBOOT_${MCUBOOT_UPGRADE_STRATEGY}
             $<$<BOOL:${SYMMETRIC_INITIAL_ATTESTATION}>:SYMMETRIC_INITIAL_ATTESTATION>
             $<$<BOOL:${MCUBOOT_HW_KEY}>:MCUBOOT_HW_KEY>
+            MCUBOOT_FIH_PROFILE_${MCUBOOT_FIH_PROFILE}
         )
 endif()
 
diff --git a/platform/ext/target/musca_b1/boot_hal.c b/platform/ext/target/musca_b1/boot_hal.c
index de99b34..f49d7e7 100644
--- a/platform/ext/target/musca_b1/boot_hal.c
+++ b/platform/ext/target/musca_b1/boot_hal.c
@@ -101,6 +101,8 @@
     if (result) {
         while (1);
     }
+
+    (void)fih_delay_init();
 #endif /* CRYPTO_HW_ACCELERATOR */
 
     result = FLASH_DEV_NAME.Uninitialize();
diff --git a/platform/ext/target/musca_s1/boot_hal.c b/platform/ext/target/musca_s1/boot_hal.c
index 4b600d4..cdc77a9 100644
--- a/platform/ext/target/musca_s1/boot_hal.c
+++ b/platform/ext/target/musca_s1/boot_hal.c
@@ -63,6 +63,8 @@
     if (result) {
         return 1;
     }
+
+    (void)fih_delay_init();
 #endif /* CRYPTO_HW_ACCELERATOR */
 
 /* This is a workaround to program the TF-M related cryptographic keys