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/image_rsa.c b/boot/bootutil/src/image_rsa.c
index a94de5c..1a1727e 100644
--- a/boot/bootutil/src/image_rsa.c
+++ b/boot/bootutil/src/image_rsa.c
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2017-2018 Linaro LTD
  * Copyright (c) 2017-2019 JUUL Labs
+ * Copyright (c) 2020 Arm Limited
  *
  * Original license:
  *
@@ -37,6 +38,7 @@
 #include "mbedtls/version.h"
 
 #include "bootutil_priv.h"
+#include "bootutil/fault_injection_hardening.h"
 
 /*
  * Constants for this particular constrained implementation of
@@ -157,7 +159,7 @@
  * v2.2, section 9.1.2, with many parameters required to have fixed
  * values.
  */
-static int
+static fih_int
 bootutil_cmp_rsasig(mbedtls_rsa_context *ctx, uint8_t *hash, uint32_t hlen,
   uint8_t *sig)
 {
@@ -166,17 +168,22 @@
     uint8_t db_mask[PSS_MASK_LEN];
     uint8_t h2[PSS_HLEN];
     int i;
+    int rc = 0;
+    fih_int fih_rc = FIH_FAILURE;
 
     if (ctx->len != PSS_EMLEN || PSS_EMLEN > MBEDTLS_MPI_MAX_SIZE) {
-        return -1;
+        rc = -1;
+        goto out;
     }
 
     if (hlen != PSS_HLEN) {
-        return -1;
+        rc = -1;
+        goto out;
     }
 
     if (mbedtls_rsa_public(ctx, sig, em)) {
-        return -1;
+        rc = -1;
+        goto out;
     }
 
     /*
@@ -204,7 +211,8 @@
      * 0xbc, output inconsistent and stop.
      */
     if (em[PSS_EMLEN - 1] != 0xbc) {
-        return -1;
+        rc = -1;
+        goto out;
     }
 
     /* Step 5.  Let maskedDB be the leftmost emLen - hLen - 1 octets
@@ -244,12 +252,14 @@
      * hexadecimal value 0x01, output "inconsistent" and stop. */
     for (i = 0; i < PSS_MASK_ZERO_COUNT; i++) {
         if (db_mask[i] != 0) {
-            return -1;
+            rc = -1;
+            goto out;
         }
     }
 
     if (db_mask[PSS_MASK_ONE_POS] != 1) {
-        return -1;
+        rc = -1;
+        goto out;
     }
 
     /* Step 11. Let salt be the last sLen octets of DB */
@@ -266,19 +276,23 @@
 
     /* Step 14.  If H = H', output "consistent".  Otherwise, output
      * "inconsistent". */
-    if (memcmp(h2, &em[PSS_HASH_OFFSET], PSS_HLEN) != 0) {
-        return -1;
+    FIH_CALL(boot_fih_memequal, fih_rc, h2, &em[PSS_HASH_OFFSET], PSS_HLEN);
+
+out:
+    if (rc) {
+        fih_rc = fih_int_encode(rc);
     }
 
-    return 0;
+    FIH_RET(fih_rc);
 }
 
-int
+fih_int
 bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen,
   uint8_t key_id)
 {
     mbedtls_rsa_context ctx;
     int rc;
+    fih_int fih_rc = FIH_FAILURE;
     uint8_t *cp;
     uint8_t *end;
 
@@ -290,11 +304,13 @@
     rc = bootutil_parse_rsakey(&ctx, &cp, end);
     if (rc || slen != ctx.len) {
         mbedtls_rsa_free(&ctx);
-        return rc;
+        goto out;
     }
-    rc = bootutil_cmp_rsasig(&ctx, hash, hlen, sig);
+    FIH_CALL(bootutil_cmp_rsasig, fih_rc, &ctx, hash, hlen, sig);
+
+out:
     mbedtls_rsa_free(&ctx);
 
-    return rc;
+    FIH_RET(fih_rc);
 }
 #endif /* MCUBOOT_SIGN_RSA */