Infineon: Add support for CYW89829 devices, improve swap with status algorithm speed
diff --git a/boot/bootutil/include/bootutil/fault_injection_hardening.h b/boot/bootutil/include/bootutil/fault_injection_hardening.h
index d067e7f..8edf5ba 100644
--- a/boot/bootutil/include/bootutil/fault_injection_hardening.h
+++ b/boot/bootutil/include/bootutil/fault_injection_hardening.h
@@ -123,7 +123,12 @@
  * it has reasonably high Hamming weight.
  */
 #define FIH_MASK_VALUE          0xA5C35A3CU
+#ifndef USE_IFX_SE_CRYPTO /* TODO: Remove this after TFM-1749 resolved */
 #define FIH_UINT_MASK_VALUE     0xB779A31CU
+#else
+#define FIH_UINT_MASK_VALUE     0xA5C35A3CU
+#endif /* USE_IFX_SE_CRYPTO */
+
 
 #define FIH_INT_VAL_MASK(val) ((int32_t)((val) ^ FIH_MASK_VALUE))
 #define FIH_UINT_VAL_MASK(val) ((val) ^ FIH_UINT_MASK_VALUE)
@@ -167,6 +172,7 @@
 #define FIH_SUCCESS     (fih_int_encode(FIH_POSITIVE_VALUE))
 #define FIH_FAILURE     (fih_int_encode(FIH_NEGATIVE_VALUE))
 #define FIH_UINT_ZERO   (fih_uint_encode(0U))
+#define FIH_INT_ZERO    (fih_int_encode((signed)0))
 #define FIH_UINT_MAX    (fih_uint_encode(0xFFFFFFFFU))
 
 #ifdef FIH_ENABLE_GLOBAL_FAIL
@@ -856,6 +862,36 @@
 }
 
 /**
+ * Standard logical OR for fih_int values.
+ *
+ * @param x  1st fih_int value to be ORed.
+ * @param y  2nd fih_int value to be ORed.
+ *
+ * @return   ORed value
+ */
+__attribute__((always_inline)) static inline
+fih_int fih_or(fih_int x, fih_int y)
+{
+    int32_t y_val, y_msk;
+    volatile fih_int rc = {0};
+
+    fih_int_validate(x);
+    fih_int_validate(y);
+
+    y_val = y.val;
+    rc.val = x.val | y_val;
+
+    fih_delay();
+
+    y_msk = y.msk;
+    rc.msk = FIH_INT_VAL_MASK(FIH_INT_VAL_MASK(x.msk) | FIH_INT_VAL_MASK(y_msk));
+
+    fih_int_validate(rc);
+
+    return rc;
+}
+
+/**
  * Standard logical AND for fih_uint values.
  *
  * @param x  1st fih_uint value to be ORed.
@@ -1234,6 +1270,28 @@
 }
 
 /**
+ * Standard logical OR for fih_int values.
+ *
+ * @param x  1st fih_int value to be ORed.
+ * @param y  2nd fih_int value to be ORed.
+ *
+ * @return   ORed value
+ */
+__attribute__((always_inline)) static inline
+fih_int fih_or(fih_int x, fih_int y)
+{
+    fih_int rc = {x.val | y.val};
+
+    fih_delay();
+
+    if (rc.val != (x.val | y.val)) {
+        FIH_PANIC;
+    }
+
+    return rc;
+}
+
+/**
  * Standard logical AND for fih_uint values.
  *
  * @param x  1st fih_uint value to be ORed.
@@ -1344,7 +1402,7 @@
  * number of the critical steps. It should be called before execution starts.
  */
 #define FIH_CFI_STEP_INIT(x) \
-        fih_int fih_cfi_step_saved_value = fih_cfi_get_and_increment(x)
+        fih_uint fih_cfi_step_saved_value = fih_cfi_get_and_increment(x)
 
 /*
  * FIH_CFI_STEP_DECREMENT() decrease the CFI counter by one. It can be called
@@ -1463,6 +1521,7 @@
 #define FIH_SUCCESS             (0)
 #define FIH_FAILURE            (-1)
 #define FIH_UINT_ZERO           (0UL)
+#define FIH_INT_ZERO            ((signed)0)
 #define FIH_UINT_MAX            (0xFFFFFFFFUL)
 
 #define FIH_TRUE                (1)
@@ -1497,6 +1556,7 @@
 #define fih_le(x, y)            ((x) <= (y))
 #define fih_uint_le(x, y)       ((x) <= (y))
 
+#define fih_or(x, y)            ((x) | (y))
 #define fih_uint_or(x, y)       ((x) | (y))
 #define fih_uint_and(x, y)      ((x) & (y))
 
diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h
index 7e19452..535e34e 100644
--- a/boot/bootutil/include/bootutil/image.h
+++ b/boot/bootutil/include/bootutil/image.h
@@ -172,6 +172,14 @@
 #define IS_RAM_BOOTABLE(hdr) (false)
 #endif
 
+/* boot_ram is outside of the define IS_RAM_BOOT_STAGE to avoid MISRA C-2012 Rule 8.5 violation */
+extern bool boot_ram;
+
+#define IS_RAM_BOOT_STAGE()   \
+    ({                        \
+        boot_ram;             \
+    })
+
 _Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE,
                "struct image_header not required size");
 
diff --git a/boot/bootutil/src/boot_record.c b/boot/bootutil/src/boot_record.c
index 5b7ec08..88b7573 100644
--- a/boot/bootutil/src/boot_record.c
+++ b/boot/bootutil/src/boot_record.c
@@ -23,6 +23,11 @@
 
 #include "mcuboot_config/mcuboot_config.h"
 
+#if defined USE_IFX_SE_CRYPTO
+#include "ifx_se_platform.h"
+#define SE_RT_SYSCALL_NOT_SUPPORTED (ifx_se_status_t) FIH_UINT_INIT(0xF7000001u)
+#endif
+
 #if defined(MCUBOOT_MEASURED_BOOT) || defined(MCUBOOT_DATA_SHARING)
 #include "bootutil/crypto/sha256.h"
 #include "bootutil/boot_record.h"
@@ -38,6 +43,73 @@
 #define SHARED_MEMORY_GEN_ERROR     (3)
 #define SHARED_MEMORY_CORRUPTED     (4)
 
+#if defined USE_IFX_SE_CRYPTO
+/* See in boot_record.h */
+int
+boot_add_data_to_shared_area(uint8_t        major_type,
+                             uint16_t       minor_type,
+                             size_t         size,
+                             const uint8_t *data)
+{
+    struct shared_data_tlv_entry tlv_entry = {0};
+    uint16_t type = SET_TLV_TYPE(major_type, minor_type);
+    uint8_t boot_data_arr[MCUBOOT_SHARED_DATA_SIZE] = {0};
+    struct shared_boot_data *boot_data = (struct shared_boot_data *)boot_data_arr;
+    uint16_t boot_data_size = 0;
+
+    ifx_se_status_t if_se_rc = IFX_SE_INVALID;
+
+    if (data == NULL) {
+        return SHARED_MEMORY_GEN_ERROR;
+    }
+    
+    /* Fill boot_data structure - tlv header portions */
+    boot_data->header.tlv_magic   = SHARED_DATA_TLV_INFO_MAGIC;
+    boot_data->header.tlv_tot_len = (uint16_t)SHARED_DATA_HEADER_SIZE;
+
+    /* Add TLV entry type portion */
+    tlv_entry.tlv_type = type;
+
+    if (size > (unsigned)UINT16_MAX - SHARED_DATA_ENTRY_HEADER_SIZE) {
+        return SHARED_MEMORY_GEN_ERROR;
+    }
+
+    /* Add TLV entry length portion */
+    tlv_entry.tlv_len = (uint16_t)size;
+    if (!boot_u16_safe_add(&boot_data_size, boot_data->header.tlv_tot_len,
+                            (uint16_t)SHARED_DATA_ENTRY_SIZE(size))) {
+        return SHARED_MEMORY_GEN_ERROR;
+    }
+
+    /* Verify overflow of shared area */
+    if (boot_data_size > MCUBOOT_SHARED_DATA_SIZE) {
+        return SHARED_MEMORY_OVERFLOW;
+    }
+
+    (void)memcpy((void *)boot_data + SHARED_DATA_HEADER_SIZE, (const void *)&tlv_entry, SHARED_DATA_ENTRY_HEADER_SIZE);
+    (void)memcpy((void *)boot_data + SHARED_DATA_HEADER_SIZE + SHARED_DATA_ENTRY_HEADER_SIZE, (const void *)data, size);
+
+    boot_data->header.tlv_tot_len = boot_data_size;
+
+    if_se_rc = ifx_se_set_shared_data(fih_ptr_encode(boot_data), fih_uint_encode(boot_data_size), IFX_SE_NULL_CTX);
+
+    if (fih_uint_eq(if_se_rc, SE_RT_SYSCALL_NOT_SUPPORTED)) {
+        /* return as okay, because syscall is not implemented in SE RT nowm but our job is done here */
+        return SHARED_MEMORY_OK;
+    }
+    else if (fih_uint_eq(if_se_rc, IFX_SE_SUCCESS)) {
+        /* return error if we get here and rc is supported */
+        return SHARED_MEMORY_GEN_ERROR;
+    }
+    else {
+        /* return success otherwise */
+        return SHARED_MEMORY_OK;
+    }
+    
+}
+
+#else /* USE_IFX_SE_CRYPTO */
+
 /**
  * @var shared_memory_init_done
  *
@@ -124,6 +196,7 @@
 
     return SHARED_MEMORY_OK;
 }
+#endif /* USE_IFX_SE_CRYPTO */
 #endif /* MCUBOOT_MEASURED_BOOT OR MCUBOOT_DATA_SHARING */
 
 #ifdef MCUBOOT_MEASURED_BOOT
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 75367d6..105237a 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -488,7 +488,7 @@
 #define LOAD_IMAGE_DATA(hdr, fap, start, output, size)                         \
     ({                                                                         \
         int rc;                                                                \
-        if (IS_RAM_BOOTABLE(hdr)) {                                            \
+        if (IS_RAM_BOOTABLE(hdr) && IS_RAM_BOOT_STAGE()) {                     \
             rc = LOAD_IMAGE_DATA_RAM((hdr), (fap), (start), (output), (size)); \
         } else {                                                               \
             rc = LOAD_IMAGE_DATA_FLASH((hdr), (fap), (start), (output),        \
diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c
index 152271f..02f8eef 100644
--- a/boot/bootutil/src/encrypted.c
+++ b/boot/bootutil/src/encrypted.c
@@ -506,6 +506,7 @@
     bootutil_aes_ctr_context aes_ctr;
     uint8_t salt[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
     uint8_t tag[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
+    uint8_t info[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE] = "MCUBoot_ECIES_v1";
     uint8_t shared[SHARED_KEY_LEN];
     uint8_t derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE + BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE * 2];
     uint8_t *cp;
@@ -640,7 +641,7 @@
     }
 
     out_len = len;
-    rc = hkdf(shared, SHARED_KEY_LEN, (const uint8_t *)"MCUBoot_ECIES_v1", BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE,
+    rc = hkdf(shared, SHARED_KEY_LEN, info, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE,
               my_salt, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE, derived_key, &out_len);
 
     if (rc != 0 || len != out_len) {
diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c
index 4807b48..d4cbade 100644
--- a/boot/bootutil/src/image_validate.c
+++ b/boot/bootutil/src/image_validate.c
@@ -126,7 +126,7 @@
     {      
 #if defined(MCUBOOT_RAM_LOAD)
 #if defined(MCUBOOT_MULTI_MEMORY_LOAD)
-        if (IS_RAM_BOOTABLE(hdr))
+        if (IS_RAM_BOOTABLE(hdr) && IS_RAM_BOOT_STAGE())
 #endif /* MCUBOOT_MULTI_MEMORY_LOAD */
         {
             bootutil_sha256_update(
@@ -227,6 +227,63 @@
 #    define SIG_BUF_SIZE 32 /* no signing, sha256 digest only */
 #endif
 
+/* Complex result masks for bootutil_img_validate() */
+#define SET_MASK_IMAGE_TLV_SHA256       ((signed)0x0000002E)
+fih_int FIH_MASK_IMAGE_TLV_SHA256 = FIH_INT_INIT(
+        SET_MASK_IMAGE_TLV_SHA256);
+
+#define SET_MASK_SIG_TLV_EXPECTED       ((signed)0x00007400)
+fih_int FIH_MASK_SIG_TLV_EXPECTED = FIH_INT_INIT(
+        SET_MASK_SIG_TLV_EXPECTED);
+
+#define SET_MASK_IMAGE_TLV_SEC_CNT      ((signed)0x005C0000)
+fih_int FIH_MASK_IMAGE_TLV_SEC_CNT = FIH_INT_INIT(
+        SET_MASK_IMAGE_TLV_SEC_CNT);
+
+#define CHK_MASK_IMAGE_TLV_SHA256       SET_MASK_IMAGE_TLV_SHA256
+
+#if defined MCUBOOT_SKIP_VALIDATE_SECONDARY_SLOT
+    #if defined MCUBOOT_VALIDATE_PRIMARY_SLOT
+        #error Boot slot validation cannot be enabled if upgrade slot validation is disabled
+    #endif
+#endif
+
+#if defined(MCUBOOT_SIGN_RSA)   || \
+    defined(MCUBOOT_SIGN_EC)    || \
+    defined(MCUBOOT_SIGN_EC256) || \
+    defined(MCUBOOT_SIGN_ED25519)
+    
+    #if defined MCUBOOT_SKIP_VALIDATE_SECONDARY_SLOT
+        #define CHK_MASK_SIG_TLV_EXPECTED       ((signed)0)
+    #else
+        #define CHK_MASK_SIG_TLV_EXPECTED       SET_MASK_SIG_TLV_EXPECTED
+    #endif /* MCUBOOT_SKIP_VALIDATE_SECONDARY_SLOT */
+#else
+    #define CHK_MASK_SIG_TLV_EXPECTED       ((signed)0)
+#endif /* defined(MCUBOOT_SIGN_RSA)   ||
+          defined(MCUBOOT_SIGN_EC)    ||
+          defined(MCUBOOT_SIGN_EC256) ||
+          defined(MCUBOOT_SIGN_ED25519) */
+
+#ifdef MCUBOOT_HW_ROLLBACK_PROT
+    #define CHK_MASK_IMAGE_TLV_SEC_CNT      SET_MASK_IMAGE_TLV_SEC_CNT
+#else
+    #define CHK_MASK_IMAGE_TLV_SEC_CNT      ((signed)0)
+#endif /* MCUBOOT_HW_ROLLBACK_PROT */
+
+fih_int FIH_IMG_VALIDATE_COMPLEX_OK = FIH_INT_INIT( \
+    CHK_MASK_IMAGE_TLV_SHA256  |                      \
+    CHK_MASK_SIG_TLV_EXPECTED  |                      \
+    CHK_MASK_IMAGE_TLV_SEC_CNT);
+
+#undef SET_MASK_IMAGE_TLV_SHA256
+#undef SET_MASK_SIG_TLV_EXPECTED
+#undef SET_MASK_IMAGE_TLV_SEC_CNT
+
+#undef CHK_MASK_IMAGE_TLV_SHA256
+#undef CHK_MASK_SIG_TLV_EXPECTED
+#undef CHK_MASK_IMAGE_TLV_SEC_CNT
+
 #ifdef EXPECTED_SIG_TLV
 #if !defined(MCUBOOT_HW_KEY)
 static int
@@ -449,7 +506,7 @@
     uint32_t off;
     uint16_t len;
     uint16_t type;
-    int sha256_valid = 0;
+
 #ifdef EXPECTED_SIG_TLV
     fih_int valid_signature = FIH_FAILURE;
     int key_id = -1;
@@ -458,11 +515,17 @@
     uint8_t key_buf[SIG_BUF_SIZE + 24];
 #endif
 #endif /* EXPECTED_SIG_TLV */
+
     struct image_tlv_iter it;
     uint8_t buf[SIG_BUF_SIZE];
     uint8_t hash[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
     int rc = 0;
     fih_int fih_rc = FIH_FAILURE;
+    /* fih_complex_result stores patterns of successful execution
+     * of required checks
+     */
+    fih_int fih_complex_result = FIH_INT_ZERO;
+
 #ifdef MCUBOOT_HW_ROLLBACK_PROT
     fih_uint security_cnt = FIH_UINT_MAX;
     uint32_t img_security_cnt = 0;
@@ -515,11 +578,18 @@
             }
 
             FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash));
-            if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+
+            if (fih_eq(fih_rc, FIH_SUCCESS) == FIH_TRUE) {
+                /* Encode succesful completion pattern to complex_result */
+                fih_complex_result = fih_or(fih_complex_result,
+                                                 FIH_MASK_IMAGE_TLV_SHA256);
+            }
+            else {
+                BOOT_LOG_DBG("IMAGE_TLV_SHA256 is invalid");
+                rc = -1;
                 goto out;
             }
 
-            sha256_valid = 1;
 #ifdef EXPECTED_SIG_TLV
 #ifndef MCUBOOT_HW_KEY
         } else if (type == IMAGE_TLV_KEYHASH) {
@@ -575,6 +645,18 @@
             FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash),
                                                            buf, len, key_id);
             key_id = -1;
+
+            if (FIH_TRUE == fih_eq(FIH_SUCCESS, valid_signature)) {
+                /* Encode succesful completion pattern to complex_result */
+                fih_complex_result = fih_or(fih_complex_result,
+                                                 FIH_MASK_SIG_TLV_EXPECTED);
+            } else {
+                BOOT_LOG_DBG("Invalid signature of bootable image %d",
+                             image_index);
+                rc = -1;
+                goto out;
+            }
+            
 #endif /* EXPECTED_SIG_TLV */
 #ifdef MCUBOOT_HW_ROLLBACK_PROT
         } else if (type == IMAGE_TLV_SEC_CNT) {
@@ -596,6 +678,7 @@
             FIH_CALL(boot_nv_security_counter_get, fih_rc, image_index,
                                                            &security_cnt);
             if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+                rc = -1;
                 goto out;
             }
 
@@ -609,6 +692,7 @@
 
             if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
                 /* The image's security counter exceeds registered value for this image */
+                rc = -1;
                 goto out;
             }
 
@@ -620,20 +704,21 @@
             /* Compare the new image's security counter value against the
              * stored security counter value.
              */
-            fih_rc = fih_int_encode_zero_equality( (int32_t)(img_security_cnt <
-                                    fih_uint_decode(security_cnt)) );
-
-            if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+            if (FIH_TRUE == fih_uint_ge(fih_uint_encode(img_security_cnt), security_cnt)) {
+                /* Encode succesful completion pattern to complex_result */
+                fih_complex_result = fih_or(fih_complex_result,
+                                                 FIH_MASK_IMAGE_TLV_SEC_CNT);
+#ifdef CYW20829
+                /* The image's security counter has been successfully verified. */
+                security_counter_valid = fih_int_encode(HW_ROLLBACK_CNT_VALID);
+#endif
+            } else {
                 /* The image's security counter is not accepted. */
+                rc = -1;
                 goto out;
             }
-#ifndef CYW20829
-            /* The image's security counter has been successfully verified. */
-            security_counter_valid = fih_rc;
-        }
-#else
-            /* The image's security counter has been successfully verified. */
-            security_counter_valid = fih_int_encode(HW_ROLLBACK_CNT_VALID);
+
+#ifdef CYW20829
         } else if (type == IMAGE_TLV_PROV_PACK) {
 
             if (FIH_TRUE == fih_eq(security_counter_valid, fih_int_encode(HW_ROLLBACK_CNT_VALID))) {
@@ -656,7 +741,8 @@
 
                 security_counter_valid = fih_int_encode(fih_int_decode(security_counter_valid) | REPROV_PACK_VALID);
             }
-            else{
+            else {
+                rc = -1;
                 goto out;
             }
 #endif /* CYW20829 */
@@ -664,32 +750,20 @@
         }
     }
 
-    rc = !sha256_valid;
-    if (rc) {
-        goto out;
-    }
-#ifdef EXPECTED_SIG_TLV
-    fih_rc = FIH_FAILURE;
-    if (FIH_TRUE == fih_eq(valid_signature, FIH_SUCCESS)) {
-        fih_rc = valid_signature;
-    }
-#endif
 #ifdef MCUBOOT_HW_ROLLBACK_PROT
 #ifdef CYW20829
     if (fih_eq(security_counter_valid, fih_int_encode(REPROV_PACK_VALID | HW_ROLLBACK_CNT_VALID)) != FIH_TRUE) {
         BOOT_LOG_DBG("Reprovisioning packet TLV 0x51 is not present image = %d", image_index);
-#else
-    if (fih_eq(security_counter_valid, FIH_SUCCESS) != FIH_TRUE) {
-#endif /* CYW20829 */
         rc = -1;
         goto out;
     }
-#endif
+#endif /* CYW20829 */
+#endif /* MCUBOOT_HW_ROLLBACK_PROT */
 
 out:
-    if (rc) {
-        fih_rc = fih_int_encode(rc);
+    if (rc < 0) {
+        fih_complex_result = FIH_FAILURE;
     }
 
-    FIH_RET(fih_rc);
+    FIH_RET(fih_complex_result);
 }
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index bb623e5..ddca260 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -57,8 +57,13 @@
 
 #include "mcuboot_config/mcuboot_config.h"
 
+#ifdef USE_IFX_SE_CRYPTO
+#include "ifx_se_utils.h"
+#endif /* USE_IFX_SE_CRYPTO */
+
 BOOT_LOG_MODULE_DECLARE(mcuboot);
 
+bool boot_ram = false;
 static struct boot_loader_state boot_data;
 
 #if (BOOT_IMAGE_NUMBER > 1)
@@ -413,7 +418,7 @@
     return 0;
 }
 
-void
+static void
 boot_status_reset(struct boot_status *bs)
 {
 #ifdef MCUBOOT_ENC_IMAGES
@@ -528,6 +533,14 @@
     uint8_t image_index;
     fih_int fih_rc = FIH_FAILURE;
 
+#ifdef USE_IFX_SE_CRYPTO
+    fih_uint fih_complex_result = FIH_UINT_ZERO;
+    extern fih_uint IFX_FIH_IMG_VALIDATE_COMPLEX_OK;
+#else
+    fih_int fih_complex_result = FIH_FAILURE;
+    extern fih_int FIH_IMG_VALIDATE_COMPLEX_OK;
+#endif /* USE_IFX_SE_CRYPTO */
+
 #if (BOOT_IMAGE_NUMBER == 1)
     (void)state;
 #endif
@@ -558,8 +571,44 @@
     }
 #endif
 
-    FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index,
+#ifdef USE_IFX_SE_CRYPTO
+    FIH_UCALL(bootutil_psa_img_validate, fih_complex_result, \
+              BOOT_CURR_ENC(state), image_index, hdr, fap,      \
+              tmpbuf, BOOT_TMPBUF_SZ, NULL, 0);
+
+    BOOT_LOG_DBG(" * bootutil_psa_img_validate expected = 0x%x, " \
+                 "returned = 0x%x",                                  \
+                 fih_uint_decode(IFX_FIH_IMG_VALIDATE_COMPLEX_OK),   \
+                 fih_uint_decode(fih_complex_result));
+
+    if (FIH_TRUE == fih_uint_eq(fih_complex_result,
+                                IFX_FIH_IMG_VALIDATE_COMPLEX_OK)) {
+        fih_rc = fih_int_encode_zero_equality(
+                            fih_uint_decode(IFX_FIH_IMG_VALIDATE_COMPLEX_OK) &
+                            ~fih_uint_decode(fih_complex_result));
+    }
+    else {
+        fih_rc = FIH_FAILURE;
+    }
+#else
+    FIH_CALL(bootutil_img_validate, fih_complex_result, BOOT_CURR_ENC(state), image_index,
              hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL);
+    BOOT_LOG_DBG(" * bootutil_img_validate expected = 0x%x, " \
+                 "returned = 0x%x",                                  \
+                 fih_int_decode(FIH_IMG_VALIDATE_COMPLEX_OK),   \
+                 fih_int_decode(fih_complex_result));
+
+    if (FIH_TRUE == fih_eq(fih_complex_result,
+                                FIH_IMG_VALIDATE_COMPLEX_OK)) {
+        fih_rc = fih_int_encode_zero_equality(
+                            fih_int_decode(FIH_IMG_VALIDATE_COMPLEX_OK) &
+                            ~fih_int_decode(fih_complex_result));
+    }
+    else {
+        fih_rc = FIH_FAILURE;
+    }
+
+#endif /* USE_IFX_SE_CRYPTO */
 
     FIH_RET(fih_rc);
 }
@@ -930,6 +979,20 @@
 #endif /* defined CYW20829 */
 
     rc = boot_nv_security_counter_update(image_index, img_security_cnt, custom_data);
+#ifdef USE_IFX_SE_CRYPTO
+    fih_uint img_security_check = FIH_UINT_ZERO;
+    FIH_CALL(boot_nv_security_counter_get, fih_rc, image_index, &img_security_check);
+    if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+        goto done;
+    }
+    else 
+    {
+        fih_rc = FIH_FAILURE;
+        BOOT_LOG_INF("[SUCCESS] security_counter_get called right after security_counter_update" \
+                        "to check if update is successful upd_cnt = %u, read_cnt = %u",
+                        fih_uint_decode(img_security_check), img_security_cnt);
+    }
+#endif /* IFX_SE_RT_CRYPTO */
 done:
     flash_area_close(fap);
     return rc;
@@ -1620,7 +1683,13 @@
      */
     fih_int fih_rc = FIH_FAILURE;
     rc = boot_check_header_erased(state, BOOT_PRIMARY_SLOT);
+
+#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
     FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, bs);
+#else
+    fih_rc = FIH_SUCCESS;
+#endif
+
     if (rc == 0 || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
         /* Initialize swap status partition for primary slot, because
          * in swap mode it is needed to properly complete copying the image
@@ -1873,24 +1942,29 @@
          */
 
         for (uint32_t i = 0; i < BOOT_NUM_SLOTS; i++) {
+            if ((&state->imgs[BOOT_CURR_IMG(state)][i].hdr)->ih_magic == IMAGE_MAGIC) {
+                rc = boot_read_image_size(state, i, &img_size);
 
-            rc = boot_read_image_size(state, i, &img_size);
+                if (rc == 0) {
+                    fap = BOOT_IMG(state, i).area;
+                    if (fap != NULL) {
 
-            if (rc == 0) {
-                fap = BOOT_IMG(state, i).area;
-                if (fap != NULL) {
+                        uint32_t trailer_sector_off = (BOOT_WRITE_SZ(state)) * boot_img_num_sectors(state, i) - BOOT_WRITE_SZ(state);
 
-                    uint32_t trailer_sector_off = (BOOT_WRITE_SZ(state)) * boot_img_num_sectors(state, i) - BOOT_WRITE_SZ(state);
+                        BOOT_LOG_DBG("Slot %u firmware + tlvs size = %u, "
+                                    "slot size = %u, write_size = %u, "
+                                    "img sectors num = %u, "
+                                    "write_size * sect_num - write_size = %u",
+                                    i , img_size, fap->fa_size, BOOT_WRITE_SZ(state),
+                                    (uint32_t)boot_img_num_sectors(state, i), trailer_sector_off);
 
-                    BOOT_LOG_DBG("Slot %u firmware + tlvs size = %u, slot size = %u, write_size = %u, write_size * sect_num - write_size = %u",
-                                        i , img_size, fap->fa_size, BOOT_WRITE_SZ(state), trailer_sector_off);
-
-                    if (img_size > trailer_sector_off) {
-                        BOOT_LOG_ERR("Firmware + tlvs in slot %u overlaps with last sector, which contains trailer, erasing this image", i);
-                        rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
-                    }
-                    else {
-                        /* image firmware + tlvs do not overlap with last sector of slot, continue */
+                        if (img_size > trailer_sector_off) {
+                            BOOT_LOG_ERR("Firmware + tlvs in slot %u overlaps with last sector, which contains trailer, erasing this image", i);
+                            rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
+                        }
+                        else {
+                            /* image firmware + tlvs do not overlap with last sector of slot, continue */
+                        }
                     }
                 }
             }
@@ -1905,7 +1979,7 @@
             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
             return;
         }
-#endif
+#endif /* ifndef MCUBOOT_OVERWRITE_ONLY */
 
 #if defined (MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_SCRATCH)
         /*
@@ -1928,7 +2002,7 @@
             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
             return;
         }
-#endif
+#endif /* (MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_SCRATCH) */
 
         /* Determine if we rebooted in the middle of an image swap
          * operation. If a partial swap was detected, complete it.
@@ -1988,9 +2062,12 @@
                  * sure it's not OK.
                  */
                 rc = boot_check_header_erased(state, BOOT_PRIMARY_SLOT);
+#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
                 FIH_CALL(boot_validate_slot, fih_rc,
                          state, BOOT_PRIMARY_SLOT, bs);
-
+#else
+                fih_rc = FIH_SUCCESS;
+#endif
                 if (rc == 0 || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
 
                     rc = (boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_magic == IMAGE_MAGIC) ? 1: 0;
@@ -2262,16 +2339,26 @@
              */
         }
 
-#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
-        FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, &bs);
-        if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
-            goto out;
+#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT 
+#if defined(MCUBOOT_RAM_LOAD) /* to fix Rule 14.3 violation */
+        if(IS_RAM_BOOTABLE(boot_img_hdr(state, BOOT_PRIMARY_SLOT)) == false) {
+#endif /* defined(MCUBOOT_RAM_LOAD) */
+            FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, &bs);
+            if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+                goto out;
+            }
+#if defined(MCUBOOT_RAM_LOAD) /* to fix Rule 14.3 violation */
         }
+#endif /* defined(MCUBOOT_RAM_LOAD) */
 #else
         /* Even if we're not re-validating the primary slot, we could be booting
          * onto an empty flash chip. At least do a basic sanity check that
          * the magic number on the image is OK.
          */
+
+        BOOT_LOG_INF("Since boot image validation was skipped, "\
+                        "at least IMAGE_MAGIC should be checked");
+
         if (BOOT_IMG(state, BOOT_PRIMARY_SLOT).hdr.ih_magic != IMAGE_MAGIC) {
             BOOT_LOG_ERR("bad image magic 0x%" PRIx32 "; Image=%u",
                          BOOT_IMG(state, BOOT_PRIMARY_SLOT).hdr.ih_magic,
@@ -3165,7 +3252,9 @@
 {
     uint32_t active_slot;
     int rc;
-    fih_int fih_rc;
+#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
+    fih_int fih_rc = FIH_FAILURE;
+#endif
 
     /* Go over all the images and try to load one */
     IMAGES_ITER(BOOT_CURR_IMG(state)) {
@@ -3231,7 +3320,7 @@
                 continue;
             }
 #endif /* MCUBOOT_RAM_LOAD */
-
+#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
             FIH_CALL(boot_validate_slot, fih_rc, state, active_slot, NULL);
             if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
                 /* Image is invalid. */
@@ -3242,7 +3331,7 @@
                 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
                 continue;
             }
-
+#endif
             /* Valid image loaded from a slot, go to next image. */
             break;
         }
@@ -3301,6 +3390,7 @@
 {
     int rc;
     fih_int fih_rc = FIH_FAILURE;
+    boot_ram = true;
 
     rc = boot_get_slot_usage(state);
     if (rc != 0) {
@@ -3360,6 +3450,8 @@
         fih_rc = fih_int_encode_zero_equality(rc);
     }
 
+    boot_ram = false;
+
     FIH_RET(fih_rc);
 }
 #endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
diff --git a/boot/bootutil/src/swap_status_misc.c b/boot/bootutil/src/swap_status_misc.c
index 6299c8a..ac6d231 100644
--- a/boot/bootutil/src/swap_status_misc.c
+++ b/boot/bootutil/src/swap_status_misc.c
@@ -305,6 +305,108 @@
     return rc;
 }
 
+static inline int
+boot_read_flag(const struct flash_area *fap, uint8_t *flag, uint32_t off)
+{
+    int rc;
+
+    do {
+        rc = flash_area_read(fap, off, flag, sizeof *flag);
+
+        if (rc != 0) {
+            break;
+        }
+
+        if (*flag == flash_area_erased_val(fap)) {
+            *flag = BOOT_FLAG_UNSET;
+        } else {
+            *flag = boot_flag_decode(*flag);
+        }
+
+    } while (false);
+
+    return rc;
+}
+
+static inline uint32_t
+boot_magic_off_trailer(const struct flash_area *fap)
+{
+    return flash_area_get_size(fap) - BOOT_MAGIC_SZ;
+}
+
+static inline uint32_t
+boot_image_ok_off_trailer(const struct flash_area *fap)
+{
+    return ALIGN_DOWN(boot_magic_off_trailer(fap) - BOOT_MAX_ALIGN, BOOT_MAX_ALIGN);
+}
+
+static inline uint32_t
+boot_copy_done_off_trailer(const struct flash_area *fap)
+{
+    return boot_image_ok_off_trailer(fap) - BOOT_MAX_ALIGN;
+}
+
+static inline uint32_t
+boot_swap_info_off_trailer(const struct flash_area *fap)
+{
+    return boot_copy_done_off_trailer(fap) - BOOT_MAX_ALIGN;
+}
+
+int
+boot_read_swap_state_trailer(const struct flash_area *fap,
+                     struct boot_swap_state *state)
+{
+    union boot_img_magic_t magic = {0U};
+    uint32_t off;
+    uint8_t swap_info;
+    int rc;
+
+    do {
+        off = boot_magic_off_trailer(fap);
+        rc = flash_area_read(fap, off, &magic, BOOT_MAGIC_SZ);
+
+        if (rc != 0) {
+            break;
+        }
+
+        if (bootutil_buffer_is_erased(fap, &magic, BOOT_MAGIC_SZ)) {
+            state->magic = BOOT_MAGIC_UNSET;
+        } else {
+            state->magic = boot_magic_decode(&magic);
+        }
+
+        off = boot_swap_info_off_trailer(fap);
+        rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
+
+        if (rc != 0) {
+            break;
+        }
+
+        /* Extract the swap type and image number */
+        state->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
+        state->image_num = BOOT_GET_IMAGE_NUM(swap_info);
+
+        if (swap_info == flash_area_erased_val(fap) ||
+            state->swap_type > BOOT_SWAP_TYPE_REVERT) {
+            state->swap_type = BOOT_SWAP_TYPE_NONE;
+            state->image_num = 0;
+        }
+
+        off = boot_copy_done_off_trailer(fap);
+        rc = boot_read_flag(fap, &state->copy_done, off);
+
+        if (rc != 0) {
+            break;
+        }
+
+        off = boot_image_ok_off_trailer(fap);
+        rc = boot_read_flag(fap, &state->image_ok, off);
+
+    } while (false);
+
+    return rc;
+}
+
 int
 boot_read_swap_state(const struct flash_area *fap,
                      struct boot_swap_state *state)
@@ -318,10 +420,40 @@
     bool buf_is_clean = false;
     bool is_primary = false;
     bool is_secondary = false;
+    bool is_scratch = fap->fa_id == FLASH_AREA_IMAGE_SCRATCH;
     uint32_t i;
 
     const struct flash_area *fap_stat = NULL;
 
+    for (i = 0u; i < (uint32_t)BOOT_IMAGE_NUMBER; i++) {
+        if (fap->fa_id == FLASH_AREA_IMAGE_PRIMARY(i)) {
+            is_primary = true;
+            break;
+        }
+        if (fap->fa_id == FLASH_AREA_IMAGE_SECONDARY(i)) {
+            is_secondary = true;
+            break;
+        }
+    }
+
+    rc = boot_read_swap_state_trailer(fap, state);
+
+    if (is_primary)
+    {
+        if (state->image_ok == BOOT_FLAG_SET && state->copy_done == BOOT_FLAG_SET && state->magic == BOOT_MAGIC_GOOD)
+        {
+            return 0;
+        }
+    }
+
+    if (is_secondary || is_scratch)
+    {
+        if (state->image_ok == BOOT_FLAG_UNSET && state->copy_done == BOOT_FLAG_UNSET && state->magic == BOOT_MAGIC_UNSET)
+        {
+            return 0;
+        }
+    }
+
     rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
     if (rc != 0) {
         return -1;
@@ -334,17 +466,6 @@
         return -1;
     }
 
-    for (i = 0u; i < (uint32_t)BOOT_IMAGE_NUMBER; i++) {
-        if (fap->fa_id == FLASH_AREA_IMAGE_PRIMARY(i)) {
-            is_primary = true;
-            break;
-        }
-        if (fap->fa_id == FLASH_AREA_IMAGE_SECONDARY(i)) {
-            is_secondary = true;
-            break;
-        }
-    }
-
     /* fill magic number value if equal to expected */
     if (bootutil_buffer_is_erased(fap_stat, &magic, BOOT_MAGIC_SZ)) {
         state->magic = BOOT_MAGIC_UNSET;
diff --git a/boot/bootutil/src/swap_status_part.c b/boot/bootutil/src/swap_status_part.c
index 0056577..9fb7420 100644
--- a/boot/bootutil/src/swap_status_part.c
+++ b/boot/bootutil/src/swap_status_part.c
@@ -36,6 +36,24 @@
 
 static uint8_t record_buff[BOOT_SWAP_STATUS_ROW_SZ];
 static uint8_t status_buff[BOOT_SWAP_STATUS_PAYLD_SZ];
+static const struct flash_area *last_fap_stat;
+static uint32_t last_fin_offset;
+
+static void status_buff_cache_inv(void) 
+{
+    last_fap_stat = NULL;
+}
+
+static void status_buff_cache_upd(const struct flash_area* fap, uint32_t offset) 
+{
+    last_fap_stat = fap;
+    last_fin_offset = offset;
+}
+
+static bool status_buff_cache_valid(const struct flash_area* fap, uint32_t offset) 
+{
+    return (last_fap_stat == fap) && (last_fin_offset == offset);
+}
 
 const uint32_t stat_part_magic[] = {
     BOOT_SWAP_STATUS_MAGIC
@@ -180,7 +198,10 @@
         *max_idx = BOOT_SWAP_STATUS_MULT - 1U;
         *copy_counter = 0;
         /* return all erased values */
-        (void)memset(data, (int32_t)flash_area_erased_val(fap_stat), BOOT_SWAP_STATUS_PAYLD_SZ);
+        if (status_buff_cache_valid(fap_stat, fin_offset) == false) {
+            (void)memset(data, (int32_t)flash_area_erased_val(fap_stat), BOOT_SWAP_STATUS_PAYLD_SZ);
+            status_buff_cache_upd(fap_stat, fin_offset);
+        }
     }
     else {
         /* no valid CRC found - status pre-read failure */
@@ -191,6 +212,7 @@
             *copy_counter = max_cnt;
             /* read payload data */
             rc = flash_area_read(fap_stat, data_offset, data, BOOT_SWAP_STATUS_PAYLD_SZ);
+            status_buff_cache_inv();
             if (rc != 0) {
                 rc = -1;
             }
@@ -330,6 +352,7 @@
         }
 
         (void)memcpy(status_buff + buff_idx, (const uint8_t *)data + data_idx, copy_sz);
+        status_buff_cache_inv();
         buff_idx = 0;
 
         /* write record back */