Infineon: Add support for PSOC C3 family
diff --git a/boot/bootutil/include/bootutil/boot_record.h b/boot/bootutil/include/bootutil/boot_record.h
index e6aaa71..387fdf8 100644
--- a/boot/bootutil/include/bootutil/boot_record.h
+++ b/boot/bootutil/include/bootutil/boot_record.h
@@ -24,6 +24,16 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+/*
+ * User can redefine sw_module start id by passing SW_MODULE_START_ID value
+ * at compile time. This may be needed if mcuboot is a part of a system with
+ * several boot stages and previous stages are also fill measured boot data.
+ */ 
+#if defined(SW_MODULE_START_ID)
+#define GET_SW_MODULE_ID(sw_module) ((sw_module) + (SW_MODULE_START_ID))
+#else
+#define GET_SW_MODULE_ID(sw_module) sw_module
+#endif
 
 /**
  * @brief Add a data item to the shared data area between bootloader and
@@ -39,7 +49,8 @@
 int boot_add_data_to_shared_area(uint8_t        major_type,
                                  uint16_t       minor_type,
                                  size_t         size,
-                                 const uint8_t *data);
+                                 const uint8_t *data,
+                                 const struct flash_area *fap);
 
 /**
  * Add an image's all boot status information to the shared memory area
diff --git a/boot/bootutil/include/bootutil/crypto/aes_ctr.h b/boot/bootutil/include/bootutil/crypto/aes_ctr.h
index 3758ca8..90727f1 100644
--- a/boot/bootutil/include/bootutil/crypto/aes_ctr.h
+++ b/boot/bootutil/include/bootutil/crypto/aes_ctr.h
@@ -44,40 +44,141 @@
 extern "C" {
 #endif
 
-#if defined(MCUBOOT_USE_MBED_TLS)
+#if defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)
 typedef mbedtls_aes_context bootutil_aes_ctr_context;
 static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
 {
-    (void)mbedtls_aes_init(ctx);
+   (void)mbedtls_aes_init(ctx);
 }
 
 static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
 {
-    /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
-    /* (void)mbedtls_aes_free(ctx); */
-    (void)ctx;
+   /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
+   /* (void)mbedtls_aes_free(ctx); */
+   (void)ctx;
 }
 
 static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
 {
-    return mbedtls_aes_setkey_enc(ctx, k, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE * 8);
+   return mbedtls_aes_setkey_enc(ctx, k, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE * 8);
 }
 
 static inline int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c)
 {
-    uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
-    (void)memset(&stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
-    return mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c);
+   uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+   (void)memset(&stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+   return mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c);
 }
 
 static inline int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m)
 {
-    uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
-    (void)memset(&stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
-    return mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m);
+   uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+   (void)memset(&stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+   return mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m);
 }
 #endif /* MCUBOOT_USE_MBED_TLS */
 
+#if defined(MCUBOOT_USE_PSA_CRYPTO)
+#include "crypto.h"
+#include "crypto_values.h"
+
+typedef struct
+{
+    psa_key_handle_t key_handle;
+    psa_cipher_operation_t operation;
+} bootutil_aes_ctr_context;
+
+static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
+{
+    ctx->operation = psa_cipher_operation_init();
+}
+
+static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
+{
+    psa_cipher_abort(&ctx->operation);
+}
+
+static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *key)
+{
+    psa_status_t status;
+
+    psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_set_key_algorithm(&key_attributes, PSA_ALG_CTR);
+    psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
+    psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT);
+
+    status = psa_import_key(&key_attributes, key, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, &ctx->key_handle);
+
+    if (status != PSA_SUCCESS) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static inline int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c)
+{
+    (void)blk_off;
+
+    psa_status_t status;
+    size_t out_sz;
+    size_t f_sz;
+
+    ctx->operation = psa_cipher_operation_init();
+
+    status = psa_cipher_encrypt_setup(&ctx->operation, ctx->key_handle, PSA_ALG_CTR);
+
+    if (status == PSA_SUCCESS) {
+        status = psa_cipher_set_iv(&ctx->operation, counter, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE);
+    }
+
+    if (status == PSA_SUCCESS) {
+        status = psa_cipher_update(&ctx->operation, m, mlen, c, mlen, &out_sz);
+    }
+
+    if (status == PSA_SUCCESS) {
+        status = psa_cipher_finish(&ctx->operation, c + out_sz, sizeof(mlen) - out_sz, &f_sz);
+    }
+
+    if ((status != PSA_SUCCESS) || ((out_sz + f_sz) != mlen)) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static inline int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m)
+{
+    (void)blk_off;
+
+    psa_status_t status;
+    size_t out_sz;
+    size_t f_sz;
+
+    ctx->operation = psa_cipher_operation_init();
+
+    status = psa_cipher_decrypt_setup(&ctx->operation, ctx->key_handle, PSA_ALG_CTR);
+
+    if (status == PSA_SUCCESS) {
+        status = psa_cipher_set_iv(&ctx->operation, counter, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE);
+    }
+
+    if (status == PSA_SUCCESS) {
+        status = psa_cipher_update(&ctx->operation, c, clen, m, clen, &out_sz);
+    }
+
+    if (status == PSA_SUCCESS) {
+        status = psa_cipher_finish(&ctx->operation, m + out_sz, sizeof(clen) - out_sz, &f_sz);
+    }
+
+    if ((status != PSA_SUCCESS) || ((out_sz + f_sz) != clen)) {
+        return -1;
+    }
+
+    return 0;
+}
+#endif /* MCUBOOT_USE_PSA_CRYPTO */
+
 #if defined(MCUBOOT_USE_TINYCRYPT)
 typedef struct tc_aes_key_sched_struct bootutil_aes_ctr_context;
 static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
diff --git a/boot/bootutil/include/bootutil/crypto/ecdh_p256.h b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
index 3811037..e0f6abd 100644
--- a/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
+++ b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
@@ -67,7 +67,7 @@
 }
 #endif /* MCUBOOT_USE_TINYCRYPT */
 
-#if defined(MCUBOOT_USE_MBED_TLS)
+#if defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)
 #define NUM_ECC_BYTES 32
 
 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
@@ -147,6 +147,67 @@
 }
 #endif /* MCUBOOT_USE_MBED_TLS */
 
+
+#if defined(MCUBOOT_USE_PSA_CRYPTO)
+
+#include "crypto.h"
+#include "crypto_values.h"
+
+#define NUM_ECC_BYTES 32
+
+typedef void* bootutil_ecdh_p256_context;
+
+static inline void bootutil_ecdh_p256_init(bootutil_ecdh_p256_context *ctx)
+{
+    (void) ctx;
+}
+
+static inline void bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context *ctx)
+{
+    (void) ctx;
+}
+
+static inline int bootutil_ecdh_p256_shared_secret(bootutil_ecdh_p256_context *ctx, const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *shared)
+{
+    (void) ctx;
+
+    psa_status_t status;
+    psa_key_handle_t private_key_handle;
+
+    psa_key_attributes_t private_key_attributes = psa_key_attributes_init();
+
+    psa_set_key_usage_flags(&private_key_attributes, PSA_KEY_USAGE_DERIVE);
+    psa_set_key_algorithm(&private_key_attributes, PSA_ALG_ECDH);
+    psa_set_key_type(&private_key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+    psa_set_key_bits(&private_key_attributes, 256u);
+
+    status = psa_import_key(&private_key_attributes, priv_key, 32, &private_key_handle);
+
+    if (status == PSA_SUCCESS)
+    {
+        size_t res_len;
+
+        status = psa_raw_key_agreement(PSA_ALG_ECDH,
+                                    private_key_handle,
+                                    pub_key,
+                                    65,
+                                    shared,
+                                    32,
+                                    &res_len);
+    }
+
+    psa_destroy_key(private_key_handle);
+
+    if (status != PSA_SUCCESS)
+    {
+        return -1;
+    }
+    
+    return 0;
+}
+#endif /* MCUBOOT_USE_PSA_CRYPTO */
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boot/bootutil/include/bootutil/crypto/hmac_sha256.h b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
index e684018..d5aec15 100644
--- a/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
+++ b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
@@ -84,7 +84,7 @@
 }
 #endif /* MCUBOOT_USE_TINYCRYPT */
 
-#if defined(MCUBOOT_USE_MBED_TLS)
+#if defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)
 /**
  * The generic message-digest context.
  */
@@ -127,6 +127,78 @@
 }
 #endif /* MCUBOOT_USE_MBED_TLS */
 
+#if defined(MCUBOOT_USE_PSA_CRYPTO)
+/**
+ * The generic message-digest context.
+ */
+typedef struct
+{
+    psa_key_handle_t key_handle;
+    psa_mac_operation_t operation;
+} bootutil_hmac_sha256_context;
+
+static inline void bootutil_hmac_sha256_init(bootutil_hmac_sha256_context *ctx)
+{
+    ctx->operation = psa_mac_operation_init();
+}
+
+static inline void bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context *ctx)
+{
+    psa_mac_abort(&ctx->operation);
+    psa_destroy_key(ctx->key_handle);
+}
+
+static inline int bootutil_hmac_sha256_set_key(bootutil_hmac_sha256_context *ctx, const uint8_t *key, unsigned int key_size)
+{
+    psa_status_t status;
+    psa_key_attributes_t key_attributes = psa_key_attributes_init();
+
+    psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH);
+    psa_set_key_algorithm(&key_attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256));
+    psa_set_key_type(&key_attributes, PSA_KEY_TYPE_HMAC);
+    psa_set_key_bits(&key_attributes, 256u);
+    
+    status = psa_import_key(&key_attributes, key, key_size, &ctx->key_handle);
+
+    if (status == PSA_SUCCESS) {
+        status = psa_mac_sign_setup(&ctx->operation, ctx->key_handle, PSA_ALG_HMAC(PSA_ALG_SHA_256));
+    }
+
+    if (status != PSA_SUCCESS) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static inline int bootutil_hmac_sha256_update(bootutil_hmac_sha256_context *ctx, const void *data, unsigned int data_length)
+{
+    psa_status_t status;
+
+    status = psa_mac_update(&ctx->operation, data, data_length);
+    
+    if (status != PSA_SUCCESS) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static inline int bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context *ctx, uint8_t *tag, unsigned int taglen)
+{
+    size_t output_len;
+    psa_status_t status;
+
+    status = psa_mac_sign_finish(&ctx->operation, tag, taglen, &output_len);
+
+    if (status != PSA_SUCCESS) {
+        return -1;
+    }
+
+    return 0;
+}
+#endif /* MCUBOOT_USE_MBED_TLS */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boot/bootutil/include/bootutil/crypto/sha256.h b/boot/bootutil/include/bootutil/crypto/sha256.h
index b45cd63..82de07b 100644
--- a/boot/bootutil/include/bootutil/crypto/sha256.h
+++ b/boot/bootutil/include/bootutil/crypto/sha256.h
@@ -20,6 +20,10 @@
 
 #include "mcuboot_config/mcuboot_config.h"
 
+#if defined(MCUBOOT_SHA256_CUSTOM_INTERFACE)
+    #include "sha256_port.h"
+#else
+
 #if (defined(MCUBOOT_USE_MBED_TLS) + \
      defined(MCUBOOT_USE_TINYCRYPT) + \
      defined(MCUBOOT_USE_CC310)) != 1
@@ -143,4 +147,6 @@
 }
 #endif
 
+#endif /* MCUBOOT_SHA256_CUSTOM_INTERFACE */
+
 #endif /* __BOOTUTIL_CRYPTO_SHA256_H_ */
diff --git a/boot/bootutil/include/bootutil/fault_injection_hardening.h b/boot/bootutil/include/bootutil/fault_injection_hardening.h
index 8edf5ba..65b3023 100644
--- a/boot/bootutil/include/bootutil/fault_injection_hardening.h
+++ b/boot/bootutil/include/bootutil/fault_injection_hardening.h
@@ -83,8 +83,8 @@
 #define FIH_MISRA_BLOCK_END(MISRA)
 #endif /* CY_COVERITY_2012_CHECK */
 
-FIH_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.1', 10, 'Signed integer bitwise operations');
-FIH_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.4', 10, 'Signed integer bitwise operations');
+FIH_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.1', 10, 'Signed integer bitwise operations')
+FIH_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.4', 10, 'Signed integer bitwise operations')
 
 #ifdef MCUBOOT_FIH_PROFILE_ON
 #if defined(MCUBOOT_FIH_PROFILE_LOW)
@@ -107,13 +107,13 @@
 #endif /* MCUBOOT_FIH_PROFILE */
 
 /* Where possible, glue the FIH_TRUE from two components. */
-#define FIH_TRUE_1              ((int32_t)0x300AUL)
-#define FIH_TRUE_2              ((int32_t)0x0C50UL)
-#define FIH_TRUE                ((int32_t)0x3C5AUL) /* i.e., FIH_TRUE_1 | FIH_TRUE_2 */
+#define FIH_TRUE_1              ((int32_t)0xC00AUL)
+#define FIH_TRUE_2              ((int32_t)0x0350UL)
+#define FIH_TRUE                ((int32_t)0xC35AUL) /* i.e., FIH_TRUE_1 | FIH_TRUE_2 */
 #define FIH_FALSE               ((int32_t)0xA5C3UL)
 
 #define FIH_POSITIVE_VALUE      ((int32_t) 0x5555AAAAUL)
-#define FIH_NEGATIVE_VALUE      ((int32_t)-0x5555AAABL)
+#define FIH_NEGATIVE_VALUE      ((int32_t) 0xAAAA5555UL)
 
 #ifdef FIH_ENABLE_DOUBLE_VARS
 /*
@@ -122,15 +122,10 @@
  * another xor. The mask value doesn't _really_ matter that much, as long as
  * 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_MASK_VALUE          0xA5C35A3C
 #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_INT_VAL_MASK(val) ((int32_t)((val) ^ (int32_t)FIH_MASK_VALUE))
 #define FIH_UINT_VAL_MASK(val) ((val) ^ FIH_UINT_MASK_VALUE)
 
 /*
@@ -142,14 +137,24 @@
     volatile int32_t msk;
 } fih_int;
 
-#define FIH_INT_INIT(x)         {(x), FIH_INT_VAL_MASK(x)}
+#define FIH_INT_INIT(x)                 ((fih_int){(x), FIH_INT_VAL_MASK(x)})
+
+/* FIH_INT_INIT_GLOBAL is created to declare global or static global veriables to 
+  avoid the compile time Error[Pe028]: expression must have a constant value
+  on IAR compiler */
+#define FIH_INT_INIT_GLOBAL(x)          {(x), FIH_INT_VAL_MASK(x)}
 
 typedef struct {
     volatile uint32_t val;
     volatile uint32_t msk;
 } fih_uint;
 
-#define FIH_UINT_INIT(x)        {(x), FIH_UINT_VAL_MASK(x)}
+#define FIH_UINT_INIT(x)                ((fih_uint){(x), FIH_UINT_VAL_MASK(x)})
+
+/* FIH_UINT_INIT_GLOBAL is created to declare global or static global veriables to 
+  avoid the compile time Error[Pe028]: expression must have a constant value
+  on IAR compiler */
+#define FIH_UINT_INIT_GLOBAL(x)         {(x), FIH_UINT_VAL_MASK(x)}
 
 #else /* FIH_ENABLE_DOUBLE_VARS */
 /*
@@ -165,15 +170,22 @@
     volatile uint32_t val;
 } fih_uint;
 
-#define FIH_INT_INIT(x)         {(x)}
-#define FIH_UINT_INIT(x)        {(x)}
+#define FIH_INT_INIT(x)                 ((fih_int){(x)})
+
+/* FIH_UINT_INIT_GLOBAL and FIH_INT_INIT_GLOBAL are created to declare global
+  or static global veriables to avoid the compile time Error[Pe028]: expression
+  must have a constant value on IAR compiler */
+#define FIH_INT_INIT_GLOBAL(x)          {(x)}
+#define FIH_UINT_INIT(x)                ((fih_uint){(x)})
+#define FIH_UINT_INIT_GLOBAL(x)         {(x)}
 #endif /* FIH_ENABLE_DOUBLE_VARS */
 
-#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))
+#define FIH_SUCCESS                     (FIH_INT_INIT(FIH_POSITIVE_VALUE))
+#define FIH_FAILURE                     (FIH_INT_INIT(FIH_NEGATIVE_VALUE))
+#define FIH_UINT_ZERO                   (FIH_UINT_INIT(0U))
+#define FIH_INT_ZERO                    (FIH_INT_INIT(0L))
+#define FIH_UINT_MAX                    (FIH_UINT_INIT(0xFFFFFFFFU))
+
 
 #ifdef FIH_ENABLE_GLOBAL_FAIL
 /**
@@ -207,48 +219,14 @@
  */
 void fih_delay_init(void);
 
-/**
- * Get a random uint8_t value from an RNG seeded with an entropy source.
- * NOTE: do not directly call this function!
- *
- * @return   random value.
- */
-uint8_t fih_delay_random(void);
+bool fih_delay(void);
 
-/**
- * Delaying logic, with randomness from a CSPRNG.
- */
-__attribute__((always_inline)) static inline
-void fih_delay(void)
-{
-    uint32_t i = 0;
-    volatile uint32_t delay = 10u; /* TODO: REMOVE */
-    volatile uint32_t counter = 0;
-
-#if 0
-    delay = fih_delay_random();
-
-    if (delay == FIH_NEGATIVE_VALUE) {
-        FIH_PANIC;
-    }
-
-    delay &= 0xFF;
-#endif
-
-    for (i = 0; i < delay; i++) {
-        counter++;
-    }
-
-    if (counter != delay) {
-        FIH_PANIC;
-    }
-}
 #else /* FIH_ENABLE_DELAY */
 /* NOOP */
 #define fih_delay_init()
 
 /* NOOP */
-#define fih_delay()
+#define fih_delay() (true)
 #endif /* FIH_ENABLE_DELAY */
 
 #ifdef FIH_ENABLE_DOUBLE_VARS
@@ -258,13 +236,15 @@
  * @param x  fih_int value to be validated.
  */
 __attribute__((always_inline)) static inline
-void fih_int_validate(fih_int x)
+bool fih_int_validate(fih_int x)
 {
     int32_t x_msk = x.msk;
 
     if (x.val != FIH_INT_VAL_MASK(x_msk)) {
         FIH_PANIC;
     }
+
+    return true;
 }
 
 /**
@@ -273,13 +253,15 @@
  * @param x  fih_uint value to be validated.
  */
 __attribute__((always_inline)) static inline
-void fih_uint_validate(fih_uint x)
+bool fih_uint_validate(fih_uint x)
 {
     uint32_t x_msk = x.msk;
 
     if (x.val != FIH_UINT_VAL_MASK(x_msk)) {
         FIH_PANIC;
     }
+
+    return true;
 }
 
 /**
@@ -292,7 +274,7 @@
 __attribute__((always_inline)) static inline
 int32_t fih_int_decode(fih_int x)
 {
-    fih_int_validate(x);
+    (void)fih_int_validate(x);
     return x.val;
 }
 
@@ -306,7 +288,7 @@
 __attribute__((always_inline)) static inline
 uint32_t fih_uint_decode(fih_uint x)
 {
-    fih_uint_validate(x);
+    (void)fih_uint_validate(x);
     return x.val;
 }
 
@@ -345,40 +327,17 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x == y, other otherwise.
+ * @return   true if x == y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_eq(fih_int x, fih_int y)
-{
-    int32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_int_validate(x);
-    fih_int_validate(y);
-
-    y_val = y.val;
-    if (x.val == y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (x.msk == y_msk) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val != y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_eq(x, y) \
+        ( fih_int_validate(x) && \
+          fih_int_validate(y) && \
+          ((x).val == (y).val) && \
+          fih_delay() && \
+          ((x).msk == (y).msk) && \
+          fih_delay() && \
+          ((x).val == FIH_INT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard equality for fih_uint values.
@@ -386,40 +345,17 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x == y, other otherwise.
+ * @return   true if x == y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_eq(fih_uint x, fih_uint y)
-{
-    uint32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
-    if (x.val == y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (x.msk == y_msk) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val != y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_uint_eq(x, y) \
+        ( fih_uint_validate(x) && \
+          fih_uint_validate(y) && \
+          ((x).val == (y).val) && \
+          fih_delay() && \
+          ((x).msk == (y).msk) && \
+          fih_delay() && \
+          ((x).val == FIH_UINT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard non-equality for fih_int values.
@@ -427,40 +363,17 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x != y, FIH_FALSE otherwise.
+ * @return   true if x != y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_not_eq(fih_int x, fih_int y)
-{
-    int32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_int_validate(x);
-    fih_int_validate(y);
-
-    y_val = y.val;
-    if (x.val != y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (x.msk != y_msk) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val == y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_not_eq(x, y) \
+        ( fih_int_validate(x) && \
+          fih_int_validate(y) && \
+          ((x).val != (y).val) && \
+          fih_delay() && \
+          ((x).msk != (y).msk) && \
+          fih_delay() && \
+          ((x).val != FIH_INT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard non-equality for fih_uint values.
@@ -468,40 +381,17 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x != y, FIH_FALSE otherwise.
+ * @return   true if x != y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_not_eq(fih_uint x, fih_uint y)
-{
-    uint32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
-    if (x.val != y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (x.msk != y_msk) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val == y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_uint_not_eq(x, y) \
+        ( fih_uint_validate(x) && \
+          fih_uint_validate(y) && \
+          ((x).val != (y).val) && \
+          fih_delay() && \
+          ((x).msk != (y).msk) && \
+          fih_delay() && \
+          ((x).val != FIH_UINT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard greater than comparison for fih_int values.
@@ -509,40 +399,17 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x > y, FIH_FALSE otherwise.
+ * @return   true if x > y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_gt(fih_int x, fih_int y)
-{
-    int32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_int_validate(x);
-    fih_int_validate(y);
-
-    y_val = y.val;
-    if (x.val > y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_INT_VAL_MASK(x.msk) > FIH_INT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val <= y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_gt(x, y) \
+        ( fih_int_validate(x)  && \
+          fih_int_validate(y) && \
+          ((x).val > (y).val) && \
+          fih_delay() && \
+          (FIH_INT_VAL_MASK((x).msk) > FIH_INT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val > FIH_INT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard greater than comparison for fih_uint values.
@@ -550,40 +417,17 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x > y, FIH_FALSE otherwise.
+ * @return   true if x > y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_gt(fih_uint x, fih_uint y)
-{
-    uint32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
-    if (x.val > y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_UINT_VAL_MASK(x.msk) > FIH_UINT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val <= y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_uint_gt(x, y) \
+        ( fih_uint_validate(x)  && \
+          fih_uint_validate(y) && \
+          ((x).val > (y).val) && \
+          fih_delay() && \
+          (FIH_UINT_VAL_MASK((x).msk) > FIH_UINT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val > FIH_UINT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard greater than or equal comparison for fih_int values.
@@ -591,40 +435,17 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x >= y, FIH_FALSE otherwise.
+ * @return   true if x >= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_ge(fih_int x, fih_int y)
-{
-    int32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_int_validate(x);
-    fih_int_validate(y);
-
-    y_val = y.val;
-    if (x.val >= y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_INT_VAL_MASK(x.msk) >= FIH_INT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val < y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_ge(x, y) \
+        ( fih_int_validate(x)  && \
+          fih_int_validate(y) && \
+          ((x).val >= (y).val) && \
+          fih_delay() && \
+          (FIH_INT_VAL_MASK((x).msk) >= FIH_INT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val >= FIH_INT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard greater than or equal comparison for fih_uint values.
@@ -632,40 +453,17 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x >= y, FIH_FALSE otherwise.
+ * @return   true if x >= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_ge(fih_uint x, fih_uint y)
-{
-    uint32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
-    if (x.val >= y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_UINT_VAL_MASK(x.msk) >= FIH_UINT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val < y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_uint_ge(x, y) \
+        ( fih_uint_validate(x)  && \
+          fih_uint_validate(y) && \
+          ((x).val >= (y).val) && \
+          fih_delay() && \
+          (FIH_UINT_VAL_MASK((x).msk) >= FIH_UINT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val >= FIH_UINT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard less than comparison for fih_int values.
@@ -673,40 +471,17 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x < y, FIH_FALSE otherwise.
+ * @return   true if x < y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_lt(fih_int x, fih_int y)
-{
-    int32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_int_validate(x);
-    fih_int_validate(y);
-
-    y_val = y.val;
-    if (x.val < y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_INT_VAL_MASK(x.msk) < FIH_INT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val >= y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_lt(x, y) \
+        ( fih_int_validate(x)  && \
+          fih_int_validate(y) && \
+          ((x).val < (y).val) && \
+          fih_delay() && \
+          (FIH_INT_VAL_MASK((x).msk) < FIH_INT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val < FIH_INT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard less than comparison for fih_uint values.
@@ -714,40 +489,17 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x < y, FIH_FALSE otherwise.
+ * @return   true if x < y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_lt(fih_uint x, fih_uint y)
-{
-    uint32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
-    if (x.val < y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_UINT_VAL_MASK(x.msk) < FIH_UINT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val >= y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_uint_lt(x, y) \
+        ( fih_uint_validate(x)  && \
+          fih_uint_validate(y) && \
+          ((x).val < (y).val) && \
+          fih_delay() && \
+          (FIH_UINT_VAL_MASK((x).msk) < FIH_UINT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val < FIH_UINT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard less than or equal comparison for fih_int values.
@@ -755,40 +507,17 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x <= y, FIH_FALSE otherwise.
+ * @return   true if x <= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_le(fih_int x, fih_int y)
-{
-    int32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_int_validate(x);
-    fih_int_validate(y);
-
-    y_val = y.val;
-    if (x.val <= y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_INT_VAL_MASK(x.msk) <= FIH_INT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val > y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_le(x, y) \
+        ( fih_int_validate(x)  && \
+          fih_int_validate(y) && \
+          ((x).val <= (y).val) && \
+          fih_delay() && \
+          (FIH_INT_VAL_MASK((x).msk) <= FIH_INT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val <= FIH_INT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard less than or equal comparison for fih_uint values.
@@ -796,40 +525,17 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x <= y, FIH_FALSE otherwise.
+ * @return   true if x <= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_le(fih_uint x, fih_uint y)
-{
-    uint32_t y_val, y_msk;
-    volatile int32_t rc = FIH_FALSE;
-
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
-    if (x.val <= y_val) {
-        rc = FIH_TRUE_1;
-    }
-
-    fih_delay();
-
-    y_msk = y.msk;
-    if (FIH_UINT_VAL_MASK(x.msk) <= FIH_UINT_VAL_MASK(y_msk)) {
-        rc |= FIH_TRUE_2;
-    }
-
-    fih_delay();
-
-    y_val = y.val;
-    if (x.val > y_val) {
-        if (rc == FIH_TRUE) {
-            FIH_PANIC;
-        }
-    }
-
-    return rc;
-}
+#define fih_uint_le(x, y) \
+        ( fih_uint_validate(x)  && \
+          fih_uint_validate(y) && \
+          ((x).val <= (y).val) && \
+          fih_delay() && \
+          (FIH_UINT_VAL_MASK((x).msk) <= FIH_UINT_VAL_MASK((y).msk)) && \
+          fih_delay() && \
+          ((x).val <= FIH_UINT_VAL_MASK((y).msk)) \
+        )
 
 /**
  * Standard logical OR for fih_uint values.
@@ -842,22 +548,16 @@
 __attribute__((always_inline)) static inline
 fih_uint fih_uint_or(fih_uint x, fih_uint y)
 {
-    uint32_t y_val, y_msk;
+    /* Use local variable to avoid persistent side effect MISRA violation
+     * in operations with volatile variables. */
+    uint32_t y_val = y.val;
+    uint32_t y_msk = y.msk;
     volatile fih_uint rc = {0};
 
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
     rc.val = x.val | y_val;
 
-    fih_delay();
-
-    y_msk = y.msk;
     rc.msk = FIH_UINT_VAL_MASK(FIH_UINT_VAL_MASK(x.msk) | FIH_UINT_VAL_MASK(y_msk));
 
-    fih_uint_validate(rc);
-
     return rc;
 }
 
@@ -872,22 +572,16 @@
 __attribute__((always_inline)) static inline
 fih_int fih_or(fih_int x, fih_int y)
 {
-    int32_t y_val, y_msk;
+    /* Use local variable to avoid persistent side effect MISRA violation
+     * in operations with volatile variables. */
+    int32_t y_val = y.val;
+    int32_t y_msk = 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;
 }
 
@@ -902,38 +596,32 @@
 __attribute__((always_inline)) static inline
 fih_uint fih_uint_and(fih_uint x, fih_uint y)
 {
-    uint32_t y_val, y_msk;
+    /* Use local variable to avoid persistent side effect MISRA violation
+     * in operations with volatile variables. */
+    uint32_t y_val = y.val;
+    uint32_t y_msk = y.msk;
     volatile fih_uint rc = {0};
 
-    fih_uint_validate(x);
-    fih_uint_validate(y);
-
-    y_val = y.val;
     rc.val = x.val & y_val;
 
-    fih_delay();
-
-    y_msk = y.msk;
     rc.msk = FIH_UINT_VAL_MASK(FIH_UINT_VAL_MASK(x.msk) & FIH_UINT_VAL_MASK(y_msk));
 
-    fih_uint_validate(rc);
-
     return rc;
 }
 
 #else /* FIH_ENABLE_DOUBLE_VARS */
 
 /* NOOP */
-#define fih_int_validate(x)
-#define fih_uint_validate(x)
+#define fih_int_validate(x)  (true)
+#define fih_uint_validate(x) (true)
 
 /* NOOP */
 #define fih_int_decode(x)       ((x).val)
 #define fih_uint_decode(x)      ((x).val)
 
 /* NOOP */
-#define fih_int_encode(x)       ((fih_int)FIH_INT_INIT(x))
-#define fih_uint_encode(x)      ((fih_uint)FIH_UINT_INIT(x))
+#define fih_int_encode(x)       (FIH_INT_INIT(x))
+#define fih_uint_encode(x)      (FIH_UINT_INIT(x))
 
 /**
  * Standard equality for fih_int values.
@@ -941,25 +629,13 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x == y, FIH_FALSE otherwise.
+ * @return   true if x == y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_eq(fih_int x, fih_int y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val == y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val != y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
+#define fih_eq(x, y) \
+        ( ((x).val == (y).val) && \
+          fih_delay() && \
+          !((x).val != (y).val) \
+        )
 
 /**
  * Standard equality for fih_uint values.
@@ -967,25 +643,13 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x == y, FIH_FALSE otherwise.
+ * @return   true if x == y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_eq(fih_uint x, fih_uint y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val == y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val != y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
+#define fih_uint_eq(x, y) \
+        ( ((x).val == (y).val) && \
+          fih_delay() && \
+          !((x).val != (y).val) \
+        )
 
 /**
  * Standard non-equality for fih_int values.
@@ -993,25 +657,13 @@
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x != y, FIH_FALSE otherwise.
+ * @return    true if x != y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_not_eq(fih_int x, fih_int y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val != y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val == y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
+#define fih_not_eq(x, y) \
+        ( ((x).val != (y).val) && \
+          fih_delay() && \
+          !((x).val == (y).val) \
+        )
 
 /**
  * Standard non-equality for fih_uint values.
@@ -1019,103 +671,52 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x != y, FIH_FALSE otherwise.
+ * @return    true if x != y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_not_eq(fih_uint x, fih_uint y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val != y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val == y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
-
+#define fih_uint_not_eq(x, y) \
+        ( ((x).val != (y).val) && \
+          fih_delay() && \
+          !((x).val == (y).val) \
+        )
 /**
  * Standard greater than comparison for fih_int values.
  *
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x > y, FIH_FALSE otherwise.
+ * @return   true if x > y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_gt(fih_int x, fih_int y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val > y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val <= y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
-
+#define fih_gt(x, y) \
+        ( ((x).val > (y).val) && \
+          fih_delay() && \
+          !((x).val <= (y).val) \
+        )
 /**
  * Standard greater than comparison for fih_uint values.
  *
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x > y, FIH_FALSE otherwise.
+ * @return   true if x > y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_gt(fih_uint x, fih_uint y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val > y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val <= y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
-
+#define fih_uint_gt(x, y) \
+        ( ((x).val > (y).val) && \
+          fih_delay() && \
+          !((x).val <= (y).val) \
+        )
 /**
  * Standard greater than or equal comparison for fih_int values.
  *
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x >= y, FIH_FALSE otherwise.
+ * @return   true if x >= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_ge(fih_int x, fih_int y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val >= y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val < y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
+#define fih_ge(x, y) \
+        ( ((x).val >= (y).val) && \
+          fih_delay() && \
+          !((x).val < (y).val) \
+        )
 
 /**
  * Standard greater than or equal comparison for fih_uint values.
@@ -1123,51 +724,26 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x >= y, FIH_FALSE otherwise.
+ * @return   true if x >= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_ge(fih_uint x, fih_uint y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val >= y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val < y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
-
+#define fih_uint_ge(x, y) \
+        ( ((x).val >= (y).val) && \
+          fih_delay() && \
+          !((x).val < (y).val) \
+        )
 /**
  * Standard less than comparison for fih_int values.
  *
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x < y, FIH_FALSE otherwise.
+ * @return   true if x < y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_lt(fih_int x, fih_int y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val < y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val >= y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
+#define fih_lt(x, y) \
+        ( ((x).val < (y).val) && \
+          fih_delay() && \
+          !((x).val >= (y).val) \
+        )
 
 /**
  * Standard less than comparison for fih_uint values.
@@ -1175,51 +751,26 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x < y, FIH_FALSE otherwise.
+ * @return   true if x < y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_lt(fih_uint x, fih_uint y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val < y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val >= y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
-
+#define fih_uint_lt(x, y) \
+        ( ((x).val < (y).val) && \
+          fih_delay() && \
+          !((x).val >= (y).val) \
+        )
 /**
  * Standard less than or equal comparison for fih_int values.
  *
  * @param x  1st fih_int value to be compared.
  * @param y  2nd fih_int value to be compared.
  *
- * @return   FIH_TRUE if x <= y, FIH_FALSE otherwise.
+ * @return   true if x <= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_le(fih_int x, fih_int y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val <= y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val > y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
+#define fih_le(x, y) \
+        ( ((x).val <= (y).val) && \
+          fih_delay() && \
+          !((x).val > (y).val) \
+        )
 
 /**
  * Standard less than or equal comparison for fih_uint values.
@@ -1227,25 +778,13 @@
  * @param x  1st fih_uint value to be compared.
  * @param y  2nd fih_uint value to be compared.
  *
- * @return   FIH_TRUE if x <= y, FIH_FALSE otherwise.
+ * @return   true if x <= y, false otherwise.
  */
-__attribute__((always_inline)) static inline
-int32_t fih_uint_le(fih_uint x, fih_uint y)
-{
-    volatile int32_t rc = FIH_FALSE;
-
-    if (x.val <= y.val) {
-        rc = FIH_TRUE;
-    }
-
-    fih_delay();
-
-    if (x.val > y.val) {
-        rc = FIH_FALSE;
-    }
-
-    return rc;
-}
+#define fih_uint_le(x, y) \
+        ( ((x).val <= (y).val) && \
+          fih_delay() && \
+          !((x).val > (y).val) \
+        )
 
 /**
  * Standard logical OR for fih_uint values.
@@ -1255,12 +794,13 @@
  *
  * @return   ORed value
  */
+
 __attribute__((always_inline)) static inline
 fih_uint fih_uint_or(fih_uint x, fih_uint y)
 {
     fih_uint rc = {x.val | y.val};
 
-    fih_delay();
+    (void)fih_delay();
 
     if (rc.val != (x.val | y.val)) {
         FIH_PANIC;
@@ -1282,7 +822,7 @@
 {
     fih_int rc = {x.val | y.val};
 
-    fih_delay();
+    (void)fih_delay();
 
     if (rc.val != (x.val | y.val)) {
         FIH_PANIC;
@@ -1304,7 +844,7 @@
 {
     fih_uint rc = {x.val & y.val};
 
-    fih_delay();
+    (void)fih_delay();
 
     if (rc.val != (x.val & y.val)) {
         FIH_PANIC;
@@ -1421,7 +961,7 @@
 #define FIH_CFI_STEP_ERR_RESET() \
         do { \
             fih_cfi_ctr = fih_cfi_step_saved_value; \
-            fih_int_validate(fih_cfi_ctr); \
+            (void)fih_int_validate(fih_cfi_ctr); \
         } while(0)
 
 #else /* FIH_ENABLE_CFI */
@@ -1462,10 +1002,10 @@
         FIH_LABEL("FIH_CALL_START_" # f); \
         FIH_CFI_PRECALL_BLOCK; \
         (ret) = FIH_FAILURE; \
-        fih_delay(); \
+        (void)fih_delay(); \
         (ret) = (f)(__VA_ARGS__); \
         FIH_CFI_POSTCALL_BLOCK; \
-        fih_int_validate(ret); \
+        (void)fih_int_validate(ret); \
         FIH_LABEL("FIH_CALL_END"); \
     } while (false)
 
@@ -1475,7 +1015,7 @@
 #define FIH_VOID(f, ...) \
     do { \
         FIH_CFI_PRECALL_BLOCK; \
-        fih_delay(); \
+        (void)fih_delay(); \
         (void)(f)(__VA_ARGS__); \
         FIH_CFI_POSTCALL_BLOCK; \
         FIH_LABEL("FIH_CALL_END"); \
@@ -1490,10 +1030,10 @@
         FIH_LABEL("FIH_CALL_START_" # f); \
         FIH_CFI_PRECALL_BLOCK; \
         (ret) = FIH_UINT_ZERO; \
-        fih_delay(); \
+        (void)fih_delay(); \
         (ret) = (f)(__VA_ARGS__); \
         FIH_CFI_POSTCALL_BLOCK; \
-        fih_uint_validate(ret); \
+        (void)fih_uint_validate(ret); \
         FIH_LABEL("FIH_CALL_END"); \
     } while (false)
 
@@ -1515,8 +1055,14 @@
 typedef fih_int fih_int;
 typedef fih_uint fih_uint;
 
+
+/* FIH_UINT_INIT_GLOBAL and FIH_INT_INIT_GLOBAL are created to declare global 
+  or static global veriables to avoid the compile time Error[Pe028]: expression
+  must have a constant value on IAR compiler */
 #define FIH_INT_INIT(x)         (x)
+#define FIH_INT_INIT_GLOBAL(x)  (x)
 #define FIH_UINT_INIT(x)        (x)
+#define FIH_UINT_INIT_GLOBAL(x) (x)
 
 #define FIH_SUCCESS             (0)
 #define FIH_FAILURE            (-1)
@@ -1599,7 +1145,7 @@
 }
 #endif /* __cplusplus */
 
-FIH_MISRA_BLOCK_END('MISRA C-2012 Rule 10.1');
-FIH_MISRA_BLOCK_END('MISRA C-2012 Rule 10.4');
+FIH_MISRA_BLOCK_END('MISRA C-2012 Rule 10.1')
+FIH_MISRA_BLOCK_END('MISRA C-2012 Rule 10.4')
 
 #endif /* FAULT_INJECTION_HARDENING_H */
diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h
index 535e34e..906981d 100644
--- a/boot/bootutil/include/bootutil/image.h
+++ b/boot/bootutil/include/bootutil/image.h
@@ -97,6 +97,8 @@
 #define IMAGE_TLV_SEC_CNT           (0x50)   /* security counter */
 #define IMAGE_TLV_PROV_PACK         (0x51)   /* Reprovisioning packet */
 #define IMAGE_TLV_BOOT_RECORD       (0x60)   /* measured boot record */
+
+#define IMAGE_TLV_BUILT_IN_KEY_ID   (0x77)   /* ID if Built in keys in device key storage */
 					   /*
 					    * vendor reserved TLVs at xxA0-xxFF,
 					    * where xx denotes the upper byte
diff --git a/boot/bootutil/src/boot_record.c b/boot/bootutil/src/boot_record.c
index 88b7573..82ec800 100644
--- a/boot/bootutil/src/boot_record.c
+++ b/boot/bootutil/src/boot_record.c
@@ -23,11 +23,6 @@
 
 #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"
@@ -41,75 +36,8 @@
 #define SHARED_MEMORY_OVERFLOW      (1)
 #define SHARED_MEMORY_OVERWRITE     (2)
 #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 */
-
+#ifndef USE_PLATFORM_SHARED_DATA_STORAGE
 /**
  * @var shared_memory_init_done
  *
@@ -123,7 +51,8 @@
 boot_add_data_to_shared_area(uint8_t        major_type,
                              uint16_t       minor_type,
                              size_t         size,
-                             const uint8_t *data)
+                             const uint8_t *data,
+                             const struct flash_area *fap)
 {
     struct shared_data_tlv_entry tlv_entry = {0};
     uint16_t type = SET_TLV_TYPE(major_type, minor_type);
@@ -131,6 +60,8 @@
     uint16_t boot_data_size;
     uintptr_t tlv_end, offset;
 
+    (void)fap;
+
     if (data == NULL) {
         return SHARED_MEMORY_GEN_ERROR;
     }
@@ -196,7 +127,9 @@
 
     return SHARED_MEMORY_OK;
 }
-#endif /* USE_IFX_SE_CRYPTO */
+
+
+#endif /* USE_PLATFORM_SHARED_DATA_STORAGE */
 #endif /* MCUBOOT_MEASURED_BOOT OR MCUBOOT_DATA_SHARING */
 
 #ifdef MCUBOOT_MEASURED_BOOT
@@ -310,7 +243,8 @@
     rc = boot_add_data_to_shared_area(TLV_MAJOR_IAS,
                                       ias_minor,
                                       record_len,
-                                      buf);
+                                      buf,
+                                      fap);
     if (rc != SHARED_MEMORY_OK) {
         return rc;
     }
@@ -346,6 +280,27 @@
         }
     }
 
+/* Since the ram load active slot is chosen by the highest present 
+ * version we should compare not only with first slots of all images
+ * but with secondary slots also. So when there is no appropriate
+ * between first slots it searches in secondaries.
+*/
+#if defined(MCUBOOT_RAM_LOAD)
+    if ((uint8_t)MCUBOOT_IMAGE_NUMBER == i) {
+        for (i = 0; i < (uint8_t)MCUBOOT_IMAGE_NUMBER; i++) {
+            if (flash_area_open(FLASH_AREA_IMAGE_SECONDARY(i),
+                            &temp_fap) != 0) {
+                return -1;
+            }
+
+            if (fap == temp_fap) {
+                fwu_img_id = i;
+                break;
+            }
+        }
+    }
+#endif
+
     if ((uint8_t)MCUBOOT_IMAGE_NUMBER == i) {
         return -1;
     }
@@ -355,6 +310,7 @@
     return boot_add_data_to_shared_area(TLV_MAJOR_FWU,
                                         fwu_minor,
                                         sizeof(hdr->ih_ver),
-                                        (const uint8_t *)&hdr->ih_ver);
+                                        (const uint8_t *)&hdr->ih_ver,
+                                        fap);
 }
 #endif /* MCUBOOT_DATA_SHARING */
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 045cacf..04c61f9 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -50,7 +50,12 @@
 
 struct flash_area;
 
+#ifdef USE_IFX_SE_CRYPTO
+#define BOOT_TMPBUF_SZ  4096
+#else
 #define BOOT_TMPBUF_SZ  256
+#endif /* USE_IFX_SE_CRYPTO */
+
 
 /** Number of image slots in flash; currently limited to two. */
 #define BOOT_NUM_SLOTS                  2
@@ -309,6 +314,9 @@
 
 
 #ifdef MCUBOOT_ENC_IMAGES
+uint32_t boot_iv_offset(const struct flash_area *fap, uint8_t slot);
+int boot_read_iv(int image_index, uint8_t slot, uint8_t* dst);
+int boot_write_iv(const struct flash_area *fap, uint8_t* iv);
 int boot_write_enc_key(const struct flash_area *fap, uint8_t slot,
                        const struct boot_status *bs);
 int boot_read_enc_key(int image_index, uint8_t slot, struct boot_status *bs);
diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c
index 02f8eef..6d37ecb 100644
--- a/boot/bootutil/src/encrypted.c
+++ b/boot/bootutil/src/encrypted.c
@@ -48,6 +48,10 @@
 
 #include "bootutil_priv.h"
 
+#ifdef MCUBOOT_ENC_IMAGES_XIP_MULTI
+#include "xip_encryption.h"
+#endif /* MCUBOOT_ENC_IMAGES_XIP_MULTI */
+
 #if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
 #if defined(_compare)
 static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
@@ -158,8 +162,10 @@
 #endif
 
 #if defined(MCUBOOT_ENCRYPT_EC256)
+#if !defined(MCUBOOT_USE_PSA_CRYPTO)
 static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
 static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
+#endif
 
 #define SHARED_KEY_LEN NUM_ECC_BYTES
 #define PRIV_KEY_LEN   NUM_ECC_BYTES
@@ -195,6 +201,7 @@
         return -5;
     }
 
+#if !defined(MCUBOOT_USE_PSA_CRYPTO)
     if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
         memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
         return -6;
@@ -203,6 +210,7 @@
         memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
         return -7;
     }
+#endif
 
     if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
         return -8;
@@ -240,8 +248,10 @@
 
 #if defined(MCUBOOT_ENCRYPT_X25519)
 #define X25519_OID "\x6e"
+#if !defined(MCUBOOT_USE_PSA_CRYPTO)
 static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \
                                        MBEDTLS_OID_ORG_GOV X25519_OID;
+#endif
 
 #define SHARED_KEY_LEN 32
 #define PRIV_KEY_LEN   32
@@ -272,10 +282,12 @@
         return -4;
     }
 
+#if !defined(MCUBOOT_USE_PSA_CRYPTO)
     if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
         memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
         return -5;
     }
+#endif
 
     if (mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING) != 0) {
         return -6;
@@ -311,6 +323,7 @@
 hkdf(const uint8_t *ikm, uint16_t ikm_len, const uint8_t *info, uint16_t info_len,
         const uint8_t *salt, uint16_t salt_len, uint8_t *okm, uint16_t *okm_len)
 {
+#if !defined(MCUBOOT_USE_PSA_CRYPTO)
     bootutil_hmac_sha256_context hmac;
     uint8_t prk[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
     uint8_t T[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
@@ -399,6 +412,56 @@
 error:
     bootutil_hmac_sha256_drop(&hmac);
     return -1;
+#else
+    psa_status_t status;
+    psa_key_handle_t key_handle;
+    psa_key_derivation_operation_t operation = psa_key_derivation_operation_init();
+
+    {
+        psa_key_attributes_t key_attributes = psa_key_attributes_init();
+        psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
+        psa_set_key_algorithm(&key_attributes, PSA_ALG_HKDF(PSA_ALG_SHA_256));
+        psa_set_key_type(&key_attributes, PSA_KEY_TYPE_DERIVE);
+        psa_set_key_bits(&key_attributes, 256u);
+
+        status = psa_import_key(&key_attributes, ikm, ikm_len, &key_handle);
+    }
+
+    if (status == PSA_SUCCESS)
+    {
+        status = psa_key_derivation_setup(&operation, PSA_ALG_HKDF(PSA_ALG_SHA_256));
+    }
+
+    if (status == PSA_SUCCESS)
+    {
+        status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SALT, salt, salt_len);
+    }
+
+    if (status == PSA_SUCCESS)
+    {
+        status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_SECRET, key_handle);
+    }
+
+    if (status == PSA_SUCCESS)
+    {
+        status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_INFO, info, info_len);
+    }
+
+    if (status == PSA_SUCCESS)
+    {
+        status = psa_key_derivation_output_bytes(&operation, okm, *okm_len);
+    }
+
+    psa_key_derivation_abort(&operation);
+    psa_destroy_key(key_handle);
+
+    if (status != PSA_SUCCESS)
+    {
+        return -1;
+    }
+
+    return 0;
+#endif
 }
 #endif
 
@@ -464,6 +527,7 @@
 #if defined(MCUBOOT_ENCRYPT_RSA) || \
     (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS))
 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if !defined(MCUBOOT_USE_PSA_CRYPTO)
 static int fake_rng(void *p_rng, unsigned char *output, size_t len)
 {
     size_t i;
@@ -475,10 +539,10 @@
 
     return 0;
 }
+#endif /* MCUBOOT_USE_PSA_CRYPTO */
 #endif
 #endif /* defined(MCUBOOT_ENCRYPT_RSA) ||
           defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS) */
-
 /*
  * Decrypt an encryption key TLV.
  *
@@ -818,18 +882,18 @@
         }
     }
 
-    enc = &enc_state[rc];
-    assert(enc->valid == 1);
+   enc = &enc_state[rc];
+   assert(enc->valid == 1);
 
-    nonce = enc->aes_iv;
+   nonce = enc->aes_iv;
 
-    off >>= 4;
-    nonce[12] = (uint8_t)(off >> 24);
-    nonce[13] = (uint8_t)(off >> 16);
-    nonce[14] = (uint8_t)(off >> 8);
-    nonce[15] = (uint8_t)off;
+   off >>= 4;
+   nonce[12] = (uint8_t)(off >> 24);
+   nonce[13] = (uint8_t)(off >> 16);
+   nonce[14] = (uint8_t)(off >> 8);
+   nonce[15] = (uint8_t)off;
 
-    return bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf);
+   return bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf);
 }
 
 /**
@@ -846,3 +910,9 @@
 }
 
 #endif /* MCUBOOT_ENC_IMAGES */
+
+/*
+ * Avoid warning from -pedantic. This is included
+ * because ISO C forbids an empty translation unit.
+ */
+typedef int encrypted_iso_c_forbids_empty_translation_units;
\ No newline at end of file
diff --git a/boot/bootutil/src/fault_injection_hardening.c b/boot/bootutil/src/fault_injection_hardening.c
index 4dcbdd9..1b9397d 100644
--- a/boot/bootutil/src/fault_injection_hardening.c
+++ b/boot/bootutil/src/fault_injection_hardening.c
@@ -7,8 +7,14 @@
 
 #include "bootutil/fault_injection_hardening.h"
 
+#ifdef FIH_ENABLE_DELAY
+#include "boot_rng.h"
+
+#define FIH_DELAY_MSK 0x3FUL
+#endif /* FIH_ENABLE_DELAY */
+
 #ifdef FIH_ENABLE_CFI
-fih_uint fih_cfi_ctr = FIH_UINT_INIT(0u);
+fih_uint fih_cfi_ctr = FIH_UINT_INIT_GLOBAL(0u);
 
 fih_uint fih_cfi_get_and_increment(uint8_t cnt)
 {
@@ -21,18 +27,16 @@
 
     fih_cfi_ctr = fih_uint_encode(fih_uint_decode(fih_cfi_ctr) + cnt);
 
-    fih_uint_validate(fih_cfi_ctr);
-    fih_uint_validate(saved_ctr);
+    (void)fih_uint_validate(fih_cfi_ctr);
+    (void)fih_uint_validate(saved_ctr);
 
     return saved_ctr;
 }
 
 void fih_cfi_validate(fih_uint saved)
 {
-    volatile int32_t rc = FIH_FALSE;
-
-    rc = fih_uint_eq(saved, fih_cfi_ctr);
-    if (rc != FIH_TRUE) {
+    if (!fih_uint_eq(saved, fih_cfi_ctr))
+    {
         FIH_PANIC;
     }
 }
@@ -45,7 +49,7 @@
 
     fih_cfi_ctr = fih_uint_encode(fih_uint_decode(fih_cfi_ctr) - 1u);
 
-    fih_uint_validate(fih_cfi_ctr);
+    (void)fih_uint_validate(fih_cfi_ctr);
 }
 #endif /* FIH_ENABLE_CFI */
 
@@ -74,15 +78,61 @@
 #endif /* FIH_ENABLE_GLOBAL_FAIL */
 
 #ifdef FIH_ENABLE_DELAY
+
+/*******************************************************************************
+ * Function Name: fih_delay_init
+ *******************************************************************************
+ * \brief Initialize assets which are required for random delay generation.
+ *
+ ******************************************************************************/
 void fih_delay_init(void)
 {
-    /* Implement here */
+    if(!boot_rng_init())
+    {
+        FIH_PANIC;
+    }
 }
 
-uint8_t fih_delay_random(void)
+
+/*******************************************************************************
+ * Function Name: fih_delay_random
+ *******************************************************************************
+ * \brief Generate 8-bit random delay number masked with FIH_DELAY_MSK.
+ *
+ * \return  8-bit random delay number masked with FIH_DELAY_MSK.
+ *
+ ******************************************************************************/
+static uint8_t fih_delay_random(void)
 {
-    /* Implement here */
-
-    return 0xFF;
+    return (uint8_t)(boot_rng_random_generate() & FIH_DELAY_MSK);
 }
+
+
+/*******************************************************************************
+ * Function Name: fih_delay
+ *******************************************************************************
+ * \brief FIH delay execution.
+ *
+ * \return  status of execution. The return value is required by calling macros
+ *          like fih_uint_eq(). It always returns true or hang in FIH_PANIC.
+ *
+ ******************************************************************************/
+bool fih_delay(void)
+{
+    volatile uint8_t counter = 0U;
+    uint8_t delay = fih_delay_random();
+
+    for (uint8_t i = 0; i < delay; i++)
+    {
+        counter++;
+    }
+
+    if (counter != delay)
+    {
+        FIH_PANIC;
+    }
+
+    return true;
+}
+
 #endif /* FIH_ENABLE_DELAY */
diff --git a/boot/bootutil/src/image_ec256.c b/boot/bootutil/src/image_ec256.c
index e5c0cd6..4d67063 100644
--- a/boot/bootutil/src/image_ec256.c
+++ b/boot/bootutil/src/image_ec256.c
@@ -120,7 +120,7 @@
     if (mbedtls_asn1_get_alg(cp, end, &alg, &param)) {
         return -2;
     }
-    /* id-ecPublicKey (RFC5480) */
+
     if (alg.MBEDTLS_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
         memcmp(alg.MBEDTLS_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
         return -3;
@@ -130,6 +130,7 @@
         memcmp(param.MBEDTLS_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
         return -4;
     }
+
     /* ECPoint (RFC5480) */
     if (mbedtls_asn1_get_bitstring_null(cp, end, &len)) {
         return -6;
diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c
index d4cbade..79dc2fd 100644
--- a/boot/bootutil/src/image_validate.c
+++ b/boot/bootutil/src/image_validate.c
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <inttypes.h>
 #include <string.h>
+#include <assert.h>
 
 #include <flash_map_backend/flash_map_backend.h>
 
@@ -123,7 +124,7 @@
     size += hdr->ih_protect_tlv_size;
 
     do
-    {      
+    {
 #if defined(MCUBOOT_RAM_LOAD)
 #if defined(MCUBOOT_MULTI_MEMORY_LOAD)
         if (IS_RAM_BOOTABLE(hdr) && IS_RAM_BOOT_STAGE())
@@ -229,15 +230,15 @@
 
 /* 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(
+fih_int FIH_MASK_IMAGE_TLV_SHA256 = FIH_INT_INIT_GLOBAL(
         SET_MASK_IMAGE_TLV_SHA256);
 
 #define SET_MASK_SIG_TLV_EXPECTED       ((signed)0x00007400)
-fih_int FIH_MASK_SIG_TLV_EXPECTED = FIH_INT_INIT(
+fih_int FIH_MASK_SIG_TLV_EXPECTED = FIH_INT_INIT_GLOBAL(
         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(
+fih_int FIH_MASK_IMAGE_TLV_SEC_CNT = FIH_INT_INIT_GLOBAL(
         SET_MASK_IMAGE_TLV_SEC_CNT);
 
 #define CHK_MASK_IMAGE_TLV_SHA256       SET_MASK_IMAGE_TLV_SHA256
@@ -271,7 +272,7 @@
     #define CHK_MASK_IMAGE_TLV_SEC_CNT      ((signed)0)
 #endif /* MCUBOOT_HW_ROLLBACK_PROT */
 
-fih_int FIH_IMG_VALIDATE_COMPLEX_OK = FIH_INT_INIT( \
+fih_int FIH_IMG_VALIDATE_COMPLEX_OK = FIH_INT_INIT_GLOBAL( \
     CHK_MASK_IMAGE_TLV_SHA256  |                      \
     CHK_MASK_SIG_TLV_EXPECTED  |                      \
     CHK_MASK_IMAGE_TLV_SEC_CNT);
@@ -340,7 +341,7 @@
      *   HW) a fault is injected to accept the public key as valid one.
      */
     FIH_CALL(boot_fih_memequal, fih_rc, hash, key_hash, key_hash_size);
-    if (FIH_TRUE == fih_eq(fih_rc, FIH_SUCCESS)) {
+    if (fih_eq(fih_rc, FIH_SUCCESS)) {
         bootutil_keys[0].key = key;
         pub_key_len = key_len;
         return 0;
@@ -419,8 +420,7 @@
         goto out;
     }
 
-    if (FIH_TRUE == fih_uint_eq(fih_uint_encode(img_chk_cnt),
-                                *img_security_cnt)) {
+    if (fih_uint_eq(fih_uint_encode(img_chk_cnt), *img_security_cnt)) {
 
         if (img_sec_cnt == img_chk_cnt) {
             fih_rc = FIH_SUCCESS;
@@ -529,11 +529,11 @@
 #ifdef MCUBOOT_HW_ROLLBACK_PROT
     fih_uint security_cnt = FIH_UINT_MAX;
     uint32_t img_security_cnt = 0;
+#ifdef CYW20829
     uint8_t reprov_packet[REPROV_PACK_SIZE];
     fih_int security_counter_valid = FIH_FAILURE;
-    #ifdef CYW20829
     fih_uint extracted_img_cnt = FIH_UINT_MAX;
-    #endif /* CYW20829 */
+#endif /* CYW20829 */
 #endif /* MCUBOOT_HW_ROLLBACK_PROT */
 
     rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf,
@@ -579,7 +579,7 @@
 
             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)) {
                 /* Encode succesful completion pattern to complex_result */
                 fih_complex_result = fih_or(fih_complex_result,
                                                  FIH_MASK_IMAGE_TLV_SHA256);
@@ -646,7 +646,7 @@
                                                            buf, len, key_id);
             key_id = -1;
 
-            if (FIH_TRUE == fih_eq(FIH_SUCCESS, valid_signature)) {
+            if (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);
@@ -677,7 +677,7 @@
 
             FIH_CALL(boot_nv_security_counter_get, fih_rc, image_index,
                                                            &security_cnt);
-            if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+            if (!fih_eq(fih_rc, FIH_SUCCESS)) {
                 rc = -1;
                 goto out;
             }
@@ -690,7 +690,7 @@
             FIH_CALL(platform_security_counter_check_extract, fih_rc, 
                     (uint32_t)image_index, fih_uint_encode(img_security_cnt), &extracted_img_cnt);
 
-            if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+            if (!fih_eq(fih_rc, FIH_SUCCESS)) {
                 /* The image's security counter exceeds registered value for this image */
                 rc = -1;
                 goto out;
@@ -704,13 +704,13 @@
             /* Compare the new image's security counter value against the
              * stored security counter value.
              */
-            if (FIH_TRUE == fih_uint_ge(fih_uint_encode(img_security_cnt), security_cnt)) {
+            if (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);
+                security_counter_valid = FIH_INT_INIT(HW_ROLLBACK_CNT_VALID);
 #endif
             } else {
                 /* The image's security counter is not accepted. */
@@ -721,7 +721,7 @@
 #ifdef CYW20829
         } else if (type == IMAGE_TLV_PROV_PACK) {
 
-            if (FIH_TRUE == fih_eq(security_counter_valid, fih_int_encode(HW_ROLLBACK_CNT_VALID))) {
+            if (fih_eq(security_counter_valid, FIH_INT_INIT(HW_ROLLBACK_CNT_VALID))) {
                 /*
                 * Verify the image reprovisioning packet.
                 * This must always be present.
@@ -752,7 +752,7 @@
 
 #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) {
+    if (!fih_eq(security_counter_valid, FIH_INT_INIT(REPROV_PACK_VALID | HW_ROLLBACK_CNT_VALID))) {
         BOOT_LOG_DBG("Reprovisioning packet TLV 0x51 is not present image = %d", image_index);
         rc = -1;
         goto out;
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 8ede0f1..ba5350e 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -49,7 +49,10 @@
 
 #ifdef MCUBOOT_ENC_IMAGES
 #include "bootutil/enc_key.h"
-#endif
+#ifdef MCUBOOT_ENC_IMAGES_XIP_MULTI
+#include "xip_encryption.h"
+#endif /* MCUBOOT_ENC_IMAGES_XIP_MULTI */
+#endif /* MCUBOOT_ENC_IMAGES */
 
 #if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || defined(MCUBOOT_MULTI_MEMORY_LOAD)
 #include <os/os_malloc.h>
@@ -91,7 +94,7 @@
 #define BUF_SZ 1024U
 #endif
 
-static fih_int FIH_SWAP_TYPE_NONE = FIH_INT_INIT(0x3A5C742E);
+static fih_int FIH_SWAP_TYPE_NONE = FIH_INT_INIT_GLOBAL(0x3A5C742E);
 
 static int
 boot_read_image_headers(struct boot_loader_state *state, bool require_all,
@@ -141,13 +144,16 @@
     int rc;
 
 #ifdef MCUBOOT_MEASURED_BOOT
-    rc = boot_save_boot_status(BOOT_CURR_IMG(state),
+    rc = boot_save_boot_status(GET_SW_MODULE_ID(BOOT_CURR_IMG(state)),
                                 boot_img_hdr(state, active_slot),
                                 BOOT_IMG_AREA(state, active_slot));
     if (rc != 0) {
         BOOT_LOG_ERR("Failed to add image data to shared area");
         return rc;
     }
+    else {
+        BOOT_LOG_INF("Successfully added image data to shared area");
+    }
 #endif /* MCUBOOT_MEASURED_BOOT */
 
 #ifdef MCUBOOT_DATA_SHARING
@@ -567,9 +573,13 @@
             if (0 == rc && boot_enc_set_key(BOOT_CURR_ENC(state), slot, bs)) {
                 FIH_RET(fih_rc);
             }
+#ifdef MCUBOOT_ENC_IMAGES_XIP_MULTI
+            ifx_epb_set_xip_crypto_params((uint32_t *)bs->enckey[slot],
+                                        (uint32_t *)BOOT_CURR_ENC(state)[slot].aes_iv);
+#endif /* MCUBOOT_ENC_IMAGES_XIP_MULTI */
         }
     }
-#endif
+#endif /* MCUBOOT_ENC_IMAGES */
 
 #ifdef USE_IFX_SE_CRYPTO
     FIH_UCALL(bootutil_psa_img_validate, fih_complex_result, \
@@ -581,8 +591,7 @@
                  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)) {
+    if (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));
@@ -598,8 +607,7 @@
                  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)) {
+    if (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));
@@ -619,9 +627,10 @@
                   struct image_header *loader_hdr,
                   const struct flash_area *loader_fap)
 {
+    fih_int fih_rc = FIH_FAILURE;
+#if !defined USE_IFX_SE_CRYPTO
     static void *tmpbuf;
     uint8_t loader_hash[32];
-    fih_int fih_rc = FIH_FAILURE;
 
     if (!tmpbuf) {
         tmpbuf = malloc(BOOT_TMPBUF_SZ);
@@ -632,12 +641,22 @@
 
     FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, loader_hdr, loader_fap,
              tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, loader_hash);
-    if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+    if (!fih_eq(fih_rc, FIH_SUCCESS)) {
         FIH_RET(fih_rc);
     }
 
     FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, app_hdr, app_fap,
              tmpbuf, BOOT_TMPBUF_SZ, loader_hash, 32, NULL);
+#else
+    /*  Not implemented for USE_IFX_SE_CRYPTO
+        The code below is just to avoid warnings
+    */
+    (void)app_hdr;
+    (void)app_fap;
+    (void)loader_hdr;
+    (void)loader_fap;
+    goto out;
+#endif
 
 out:
     FIH_RET(fih_rc);
@@ -711,9 +730,8 @@
     return 0;
 }
 
-#if (BOOT_IMAGE_NUMBER > 1) || \
+#if (BOOT_IMAGE_NUMBER > 1 && defined(MCUBOOT_DEPENDENCY_CHECK)) || \
     defined(MCUBOOT_DIRECT_XIP) || \
-    defined(MCUBOOT_RAM_LOAD) || \
     (defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION))
 /**
  * Compare image version numbers not including the build number
@@ -820,6 +838,17 @@
 
     hdr = boot_img_hdr(state, slot);
 
+#ifdef MCUBOOT_ENC_IMAGES_XIP_MULTI
+/* In the XIP encryption multi image case if XIP encryption is turned on then 
+ * the boot_check_header_erased() can't detect erased header correctly for the second and next images
+ * because erased value is not read as 0xFF.
+ * So, the bootloader has one option only to detect correctness of image header: it is
+ * to check header magic */
+    if (hdr->ih_magic != IMAGE_MAGIC) {
+        FIH_RET(fih_rc);
+    }
+#endif /* MCUBOOT_ENC_IMAGES_XIP_MULTI */
+
     if (boot_check_header_erased(state, slot) == 0 ||
         (hdr->ih_flags & IMAGE_F_NON_BOOTABLE)) {
 
@@ -864,13 +893,13 @@
         }
     }
 #endif
-    BOOT_HOOK_CALL_FIH(boot_image_check_hook, fih_int_encode(BOOT_HOOK_REGULAR),
+    BOOT_HOOK_CALL_FIH(boot_image_check_hook, FIH_INT_INIT(BOOT_HOOK_REGULAR),
                        fih_rc, BOOT_CURR_IMG(state), slot);
-    if (FIH_TRUE == fih_eq(fih_rc, fih_int_encode(BOOT_HOOK_REGULAR)))
+    if (fih_eq(fih_rc, FIH_INT_INIT(BOOT_HOOK_REGULAR)))
     {
         FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs);
     }
-    if (!boot_is_header_valid(hdr, fap) || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+    if (!boot_is_header_valid(hdr, fap) || !fih_eq(fih_rc, FIH_SUCCESS)) {
         if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) {
             BOOT_LOG_DBG(" * Image in the secondary slot is invalid. Erase the image");
             flash_area_erase(fap, 0, flash_area_get_size(fap));
@@ -900,7 +929,7 @@
 
         rc = flash_area_read(fap, reset_addr, &reset_value, sizeof(reset_value));
         if (rc != 0) {
-            fih_rc = fih_int_encode(1);
+            fih_rc = FIH_INT_INIT(1);
             goto out;
         }
 
@@ -915,7 +944,7 @@
              * Erase the image and continue booting from the primary slot.
              */
             flash_area_erase(fap, 0, fap->fa_size);
-            fih_rc = fih_int_encode(1);
+            fih_rc = FIH_INT_INIT(1);
             goto out;
         }
     }
@@ -963,7 +992,7 @@
 
     rc = -1;
     FIH_CALL(bootutil_get_img_security_cnt, fih_rc, hdr, fap, &img_security_cnt);
-    if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+    if (!fih_eq(fih_rc, FIH_SUCCESS)) {
         goto done;
     }
     else 
@@ -982,7 +1011,7 @@
 #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) {
+    if (!fih_eq(fih_rc, FIH_SUCCESS)) {
         goto done;
     }
     else 
@@ -1020,8 +1049,8 @@
          * Ensure image is valid.
          */
         FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_SECONDARY_SLOT, bs);
-        if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
-            if (FIH_TRUE == fih_eq(fih_rc, FIH_SWAP_TYPE_NONE)) {
+        if (!fih_eq(fih_rc, FIH_SUCCESS)) {
+            if (fih_eq(fih_rc, FIH_SWAP_TYPE_NONE)) {
                 swap_type = BOOT_SWAP_TYPE_NONE;
             } else {
                 swap_type = BOOT_SWAP_TYPE_FAIL;
@@ -1071,7 +1100,8 @@
     uint32_t bytes_copied;
     int chunk_sz;
     int rc;
-#if defined (MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+#if (defined (MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)) || \
+    (defined (MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_ENC_IMAGES_XIP) && defined(MCUBOOT_ENC_IMAGES_XIP_MULTI))
     uint32_t off;
     uint32_t tlv_off;
     size_t blk_off;
@@ -1079,7 +1109,8 @@
     uint16_t idx;
     uint32_t blk_sz;
     uint8_t image_index;
-#endif
+#endif /* (defined (MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)) || \
+          (defined (MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_ENC_IMAGES_XIP) && defined(MCUBOOT_ENC_IMAGES_XIP_MULTI)) */
 
 /* NOTE:
  * Default value 1024 is not suitable for platforms with larger erase size.
@@ -1111,7 +1142,8 @@
             return BOOT_EFLASH;
         }
 
-#if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+#if (defined (MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)) || \
+    (defined (MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_ENC_IMAGES_XIP) && defined(MCUBOOT_ENC_IMAGES_XIP_MULTI))
         image_index = BOOT_CURR_IMG(state);
         if ((flash_area_get_id(fap_src) == FLASH_AREA_IMAGE_PRIMARY(image_index) ||
              flash_area_get_id(fap_dst) == FLASH_AREA_IMAGE_PRIMARY(image_index)) &&
@@ -1166,18 +1198,41 @@
                             blk_sz = tlv_off - abs_off;
                         }
                     }
+#ifndef MCUBOOT_ENC_IMAGES_XIP_MULTI
                     rc = boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
                                       (abs_off + idx) - hdr->ih_hdr_size, blk_sz,
                                       blk_off, &buf[idx]);
+#else /* MCUBOOT_ENC_IMAGES_XIP_MULTI */
+                    rc = boot_encrypt_xip(fap_src, fap_dst,
+                        (abs_off + idx), blk_sz, &buf[idx]);
+#endif
                     if (rc != 0) {
                         return rc;
                     }
                 }
+#ifdef MCUBOOT_ENC_IMAGES_XIP_MULTI
+                rc = flash_area_write(fap_dst, off_dst + bytes_copied, buf, chunk_sz);
+            }
+            else {
+                (void)blk_off;
+                rc = boot_encrypt_xip(fap_src, fap_dst,
+                                        off_dst + bytes_copied,
+                                        chunk_sz, buf);
+
+                rc = flash_area_write(fap_dst, off_dst + bytes_copied, buf, chunk_sz);
+                SMIF_SET_CRYPTO_MODE(Enable);
             }
         }
-#endif
-
+#else
+        	}
+        }
         rc = flash_area_write(fap_dst, off_dst + bytes_copied, buf, chunk_sz);
+#endif /* MCUBOOT_ENC_IMAGES_XIP_MULTI */
+#else
+        rc = flash_area_write(fap_dst, off_dst + bytes_copied, buf, chunk_sz);
+#endif /* (defined (MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_ENC_IMAGES_XIP)) || \
+          (defined (MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_ENC_IMAGES_XIP) && defined(MCUBOOT_ENC_IMAGES_XIP_MULTI)) */
+
         if (rc != 0) {
             return BOOT_EFLASH;
         }
@@ -1466,6 +1521,10 @@
                 assert(rc == 0);
             }
         }
+#if defined(MCUBOOT_SAVE_ENC_IV)
+        rc = boot_read_iv(image_index, 1, state->enc[image_index][1].aes_iv);
+        assert(rc == 0);
+#endif
 #endif
     }
 
@@ -1484,6 +1543,7 @@
 #endif
 
 #if (BOOT_IMAGE_NUMBER > 1)
+#if defined(MCUBOOT_DEPENDENCY_CHECK)
 /**
  * Check the image dependency whether it is satisfied and modify
  * the swap type if necessary.
@@ -1509,6 +1569,7 @@
 
     rc = boot_version_cmp(dep_version, &dep->image_min_version);
     if (rc < 0) {
+#ifndef MCUBOOT_OVERWRITE_ONLY
         /* Dependency not satisfied.
          * Modify the swap type to decrease the version number of the image
          * (which will be located in the primary slot after the boot process),
@@ -1518,14 +1579,20 @@
         switch (BOOT_SWAP_TYPE(state)) {
         case BOOT_SWAP_TYPE_TEST:
         case BOOT_SWAP_TYPE_PERM:
-            BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
+            /* BOOT_SWAP_TYPE_NONE has been changed to BOOT_SWAP_TYPE_FAIL to avoid 
+             * reversion again after device reset */
+            BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_FAIL;
             break;
         case BOOT_SWAP_TYPE_NONE:
+            BOOT_LOG_DBG("Dependency is unsatisfied. Slot will be reverted.");
             BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_REVERT;
             break;
         default:
             break;
         }
+#else
+        BOOT_LOG_DBG("Dependency is unsatisfied.");
+#endif
     } else {
         /* Dependency satisfied. */
         rc = 0;
@@ -1646,7 +1713,13 @@
              */
             for (int idx = 0; idx < BOOT_IMAGE_NUMBER; idx++) {
                 BOOT_CURR_IMG(state) = idx;
-                BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
+                /*When dependency is not satisfied, the boot_verify_slot_dependencies_flash 
+                changes swap type to BOOT_SWAP_TYPE_REVERT to have ability of reversion of a
+                dependent image. That's why BOOT_SWAP_TYPE_REVERT must not be changed to 
+                BOOT_SWAP_TYPE_NONE */
+                if (BOOT_SWAP_TYPE(state) != BOOT_SWAP_TYPE_REVERT) {
+                    BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
+                }
             }
             break;
 #endif /* (USE_SHARED_SLOT == 1) */
@@ -1654,6 +1727,7 @@
     }
     return rc;
 }
+#endif /* (MCUBOOT_DEPENDENCY_CHECK) */
 #endif /* (BOOT_IMAGE_NUMBER > 1) */
 
 /**
@@ -1690,7 +1764,7 @@
     fih_rc = FIH_SUCCESS;
 #endif
 
-    if (rc == 0 || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+    if (rc == 0 || !fih_eq(fih_rc, FIH_SUCCESS)) {
         /* Initialize swap status partition for primary slot, because
          * in swap mode it is needed to properly complete copying the image
          * to the primary slot.
@@ -2045,7 +2119,7 @@
             } else {
                 FIH_CALL(boot_validate_slot, fih_rc,
                          state, BOOT_SECONDARY_SLOT, bs);
-                if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+                if (!fih_eq(fih_rc, FIH_SUCCESS)) {
                     BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_FAIL;
                 } else {
                     BOOT_SWAP_TYPE(state) = bs->swap_type;
@@ -2071,13 +2145,13 @@
 #else
                 fih_rc = FIH_SUCCESS;
 #endif
-                if (rc == 0 || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+                if (rc == 0 || !fih_eq(fih_rc, FIH_SUCCESS)) {
 
                     rc = (boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_magic == IMAGE_MAGIC) ? 1: 0;
                     FIH_CALL(boot_validate_slot, fih_rc,
                              state, BOOT_SECONDARY_SLOT, bs);
 
-                    if (rc == 1 && FIH_TRUE == fih_eq(fih_rc, FIH_SUCCESS)) {
+                    if (rc == 1 && fih_eq(fih_rc, FIH_SUCCESS)) {
                         /* Set swap type to REVERT to overwrite the primary
                          * slot with the image contained in secondary slot
                          * and to trigger the explicit setting of the
@@ -2149,7 +2223,6 @@
     fih_int fih_rc = FIH_FAILURE;
     int fa_id;
     int image_index;
-    bool has_upgrade;
 
     /* The array of slot sectors are defined here (as opposed to file scope) so
      * that they don't get allocated for non-boot-loader apps.  This is
@@ -2165,22 +2238,18 @@
     TARGET_STATIC boot_sector_t status_sectors[BOOT_MAX_SWAP_STATUS_SECTORS];
 #endif
 
-    has_upgrade = false;
-
-#if (BOOT_IMAGE_NUMBER == 1)
-    (void)has_upgrade;
-#endif
-
     /* Iterate over all the images. By the end of the loop the swap type has
      * to be determined for each image and all aborted swaps have to be
      * completed.
      */
     IMAGES_ITER(BOOT_CURR_IMG(state)) {
+#if !defined(MCUBOOT_DEPENDENCY_CHECK)
 #if BOOT_IMAGE_NUMBER > 1
         if (state->img_mask[BOOT_CURR_IMG(state)]) {
             continue;
         }
 #endif
+#endif
 #if defined(MCUBOOT_ENC_IMAGES) && (BOOT_IMAGE_NUMBER > 1)
         /* The keys used for encryption may no longer be valid (could belong to
          * another images). Therefore, mark them as invalid to force their reload
@@ -2220,13 +2289,10 @@
         /* Determine swap type and complete swap if it has been aborted. */
         boot_prepare_image_for_update(state, &bs);
 
-        if (BOOT_IS_UPGRADE(BOOT_SWAP_TYPE(state))) {
-            has_upgrade = true;
-        }
     }
 
 #if (BOOT_IMAGE_NUMBER > 1)
-    if (has_upgrade) {
+#if defined(MCUBOOT_DEPENDENCY_CHECK)
         /* Iterate over all the images and verify whether the image dependencies
          * are all satisfied and update swap type if necessary.
          */
@@ -2240,8 +2306,8 @@
              */
             rc = 0;
         }
-    }
-#endif
+#endif /* (MCUBOOT_DEPENDENCY_CHECK) */
+#endif /* (BOOT_IMAGE_NUMBER > 1) */
 
     /* Iterate over all the images. At this point there are no aborted swaps
      * and the swap types are determined for each image. By the end of the loop
@@ -2347,7 +2413,7 @@
         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) {
+            if (!fih_eq(fih_rc, FIH_SUCCESS)) {
                 goto out;
             }
 #if defined(MCUBOOT_RAM_LOAD) /* to fix Rule 14.3 violation */
@@ -2386,9 +2452,11 @@
             goto out;
         }
 
-        rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT);
-        if (rc != 0) {
-            goto out;
+        if(IS_RAM_BOOTABLE(boot_img_hdr(state, BOOT_PRIMARY_SLOT)) == false) {
+            rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT);
+            if (rc != 0) {
+                goto out;
+            }
         }
     }
 
@@ -2413,6 +2481,10 @@
 out:
     close_all_flash_areas(state);
 
+#ifdef MCUBOOT_ENC_IMAGES_XIP_MULTI
+    SMIF_SET_CRYPTO_MODE(Enable);
+#endif /* MCUBOOT_ENC_IMAGES_XIP_MULTI */
+
     if (rc) {
         fih_rc = fih_int_encode(rc);
     }
@@ -2471,7 +2543,7 @@
              BOOT_IMG_AREA(&boot_data, split_slot),
              boot_img_hdr(&boot_data, loader_slot),
              BOOT_IMG_AREA(&boot_data, loader_slot));
-    if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+    if (!fih_eq(fih_rc, FIH_SUCCESS)) {
         goto done;
     }
 
@@ -2511,11 +2583,13 @@
     struct image_header *hdr = NULL;
 
     IMAGES_ITER(BOOT_CURR_IMG(state)) {
+#if !defined(MCUBOOT_DEPENDENCY_CHECK)
 #if BOOT_IMAGE_NUMBER > 1
         if (state->img_mask[BOOT_CURR_IMG(state)]) {
             continue;
         }
 #endif
+#endif
         /* Open all the slots */
         for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
             fa_id = flash_area_id_from_multi_image_slot(
@@ -2555,13 +2629,16 @@
 
 /**
  * Finds the slot containing the image with the highest version number for the
- * current image.
+ * current image. Also dependency check feature verifies version of the first
+ * slot of dependent image and assumes to load from the first slot. In order to
+ * avoid conflicts dependency ckeck feature is disabled.
  *
  * @param  state        Boot loader status information.
  *
  * @return              NO_ACTIVE_SLOT if no available slot found, number of
  *                      the found slot otherwise.
  */
+#if !defined(MCUBOOT_DEPENDENCY_CHECK) && !defined(MCUBOOT_RAM_LOAD)
 static uint32_t
 find_slot_with_highest_version(struct boot_loader_state *state)
 {
@@ -2589,6 +2666,7 @@
 
     return candidate_slot;
 }
+#endif /* !defined(MCUBOOT_DEPENDENCY_CHECK) && !defined(MCUBOOT_RAM_LOAD) */
 
 #ifdef MCUBOOT_HAVE_LOGGING
 /**
@@ -2979,7 +3057,7 @@
     uint32_t active_slot;
     struct image_header *hdr = NULL;
     uint32_t img_dst;
-    uint32_t img_sz;
+    uint32_t img_sz = 0;
     int rc = 0;
 
     active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
@@ -3099,6 +3177,7 @@
 #endif /* MCUBOOT_RAM_LOAD */
 
 #if (BOOT_IMAGE_NUMBER > 1)
+#if defined(MCUBOOT_DEPENDENCY_CHECK)
 /**
  * Checks the image dependency whether it is satisfied.
  *
@@ -3241,6 +3320,7 @@
 
     return rc;
 }
+#endif /* (MCUBOOT_DEPENDENCY_CHECK) */
 #endif /* (BOOT_IMAGE_NUMBER > 1) */
 
 /**
@@ -3271,8 +3351,25 @@
                 /* A slot is already active, go to next image. */
                 break;
             }
+            
+            /* Ram load assumes to find the highest version of available slots
+             * and load it. Also dependency check feature verifies version
+             * of first slot of dependent image and assumes to load from the
+             * first slot. So logic is separated into two cases to avoid conflicts,
+             * where the first is when dependency check is disabled,
+             * and the second is when it is enabled.
+             * Notation: to avoid situations when reverted image with higher version is
+             * ram-loaded, the current logic is changed to loading 'BOOT_PRIMARY_SLOT'
+             * on a constant basis.
+             * */
 
+#if !defined(MCUBOOT_DEPENDENCY_CHECK) && !defined(MCUBOOT_RAM_LOAD)
+            /* Go over all slots and find the highest version. */
             active_slot = find_slot_with_highest_version(state);
+#else
+            /* Dependecy check feature assumes to load from the first slot */
+            active_slot = BOOT_PRIMARY_SLOT;
+#endif
             if (active_slot == NO_ACTIVE_SLOT) {
                 BOOT_LOG_INF("No slot to load for image %u",
                              (unsigned)BOOT_CURR_IMG(state));
@@ -3320,19 +3417,27 @@
                 boot_remove_image_from_flash(state, active_slot);
                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
                 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
-                continue;
+                /* Since active_slot is set BOOT_PRIMARY_SLOT only, then after its deletion
+                 * no sense to check BOOT_SECONDARY_SLOT. So go outside with an error */
+                BOOT_LOG_ERR("BOOT slot of image %u has been removed from flash",
+                                                          (unsigned)BOOT_CURR_IMG(state));
+                FIH_RET(FIH_FAILURE);
             }
 #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) {
+            if (!fih_eq(fih_rc, FIH_SUCCESS)) {
                 /* Image is invalid. */
 #ifdef MCUBOOT_RAM_LOAD
                 boot_remove_image_from_sram(state);
 #endif /* MCUBOOT_RAM_LOAD */
                 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
                 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
-                continue;
+                /* Since active_slot is set BOOT_PRIMARY_SLOT only, then after its deletion
+                 * no sense to check BOOT_SECONDARY_SLOT. So go outside with an error */
+                BOOT_LOG_ERR("BOOT slot of image %u has been removed from SRAM",
+                                                           (unsigned)BOOT_CURR_IMG(state));
+                FIH_RET(FIH_FAILURE);
             }
 #endif
             /* Valid image loaded from a slot, go to next image. */
@@ -3404,23 +3509,24 @@
     while (true) {
 #endif
         FIH_CALL(boot_load_and_validate_images, fih_rc, state);
-        if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+        if (!fih_eq(fih_rc, FIH_SUCCESS)) {
             goto out;
         }
 
 #if (BOOT_IMAGE_NUMBER > 1)
+#if defined(MCUBOOT_DEPENDENCY_CHECK)
         rc = boot_verify_dependencies_ram(state);
         if (rc != 0) {
             /* Dependency check failed for an image, it has been removed from
              * SRAM in case of MCUBOOT_RAM_LOAD strategy, and set to
-             * unavailable. Try to load an image from another slot.
-             */
-            continue;
+             * unavailable. */
+            goto out;
         }
         /* Dependency check was successful. */
+#endif /* defined(MCUBOOT_DEPENDENCY_CHECK) */
         break;
     }
-#endif
+#endif /* (BOOT_IMAGE_NUMBER > 1) */
 
     IMAGES_ITER(BOOT_CURR_IMG(state)) {
 #if BOOT_IMAGE_NUMBER > 1
@@ -3449,7 +3555,7 @@
 out:
     close_all_flash_areas(state);
 
-    if (FIH_TRUE == fih_eq(fih_rc, FIH_SUCCESS)) {
+    if (fih_eq(fih_rc, FIH_SUCCESS)) {
         fih_rc = fih_int_encode_zero_equality(rc);
     }
 
diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c
index 17d0255..8b55d2a 100644
--- a/boot/bootutil/src/swap_scratch.c
+++ b/boot/bootutil/src/swap_scratch.c
@@ -685,6 +685,11 @@
                               img_off, 0, copy_sz);
         assert(rc == 0);
 
+#if defined(MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_SAVE_ENC_IV)
+        rc = boot_write_iv(fap_primary_slot, state->enc[image_index][1].aes_iv);
+        assert(rc == 0);
+#endif
+
         rc = boot_write_status(state, bs);
         bs->state = BOOT_STATUS_STATE_1;
         BOOT_STATUS_ASSERT(rc == 0);
@@ -706,6 +711,11 @@
             assert(rc == 0);
         }
 
+#if defined(MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_SAVE_ENC_IV)
+        rc = boot_write_iv(fap_primary_slot, state->enc[image_index][1].aes_iv);
+        assert(rc == 0);
+#endif
+
         rc = boot_write_status(state, bs);
         bs->state = BOOT_STATUS_STATE_2;
         BOOT_STATUS_ASSERT(rc == 0);
@@ -767,6 +777,11 @@
         erase_scratch = bs->use_scratch;
         bs->use_scratch = 0;
 
+#if defined(MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_SAVE_ENC_IV)
+        rc = boot_write_iv(fap_primary_slot, state->enc[image_index][1].aes_iv);
+        assert(rc == 0);
+#endif
+
         rc = boot_write_status(state, bs);
         bs->idx++;
         bs->state = BOOT_STATUS_STATE_0;
diff --git a/boot/bootutil/src/swap_status_misc.c b/boot/bootutil/src/swap_status_misc.c
index bc44feb..2794a6f 100644
--- a/boot/bootutil/src/swap_status_misc.c
+++ b/boot/bootutil/src/swap_status_misc.c
@@ -140,17 +140,23 @@
  *
  * @returns 0 on success, -1 on error.
  */
-int
-boot_write_trailer(const struct flash_area *fap, uint32_t off,
-        const uint8_t *inbuf, uint8_t inlen)
+int boot_write_trailer(const struct flash_area *fap, uint32_t off,
+                       const uint8_t *inbuf, uint8_t inlen)
 {
     int rc;
 
-    /* copy status part trailer to primary image before set copy_done flag */
-    if (boot_copy_done_off(fap) == off &&
-        fap->fa_id == FLASH_AREA_IMAGE_PRIMARY(0u) &&
-        BOOT_SWAP_STATUS_COPY_DONE_SZ == inlen) {
+    bool is_primary = false;
 
+    for (uint32_t i = 0u; i < BOOT_IMAGE_NUMBER; i++) {
+        if (fap->fa_id == FLASH_AREA_IMAGE_PRIMARY(i)) {
+            is_primary = true;
+            break;
+        }
+    }
+
+    /* copy status part trailer to primary image before set copy_done flag */
+    if (boot_copy_done_off(fap) == off && is_primary &&
+        BOOT_SWAP_STATUS_COPY_DONE_SZ == inlen) {
         BOOT_LOG_DBG("copy status part trailer to primary image slot");
         rc = swap_status_to_image_trailer(fap);
         if (rc != 0) {
@@ -168,6 +174,43 @@
 }
 
 #ifdef MCUBOOT_ENC_IMAGES
+uint32_t boot_iv_offset(const struct flash_area *fap, uint8_t slot)
+{
+    (void)(slot);
+
+    return boot_enc_key_off(fap, 0) - 32;
+}
+
+int
+boot_read_iv(int image_index, uint8_t slot, uint8_t* dst)
+{
+    uint32_t off;
+    const struct flash_area *fap;
+    int rc;
+
+    rc = boot_find_status(image_index, &fap);
+
+    if (0 == rc) {
+        off = boot_iv_offset(fap, slot);
+
+        rc = swap_status_retrieve(fap->fa_id, off, dst, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+    }
+
+    return rc;
+}
+
+int
+boot_write_iv(const struct flash_area *fap, uint8_t* iv)
+{
+    int rc;
+    uint32_t off = boot_iv_offset(fap, 0);
+
+    rc = swap_status_update(fap->fa_id, off,
+                            iv, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+
+    return rc;
+}
+
 int
 boot_write_enc_key(const struct flash_area *fap, uint8_t slot,
         const struct boot_status *bs)
@@ -249,9 +292,9 @@
 int
 boot_clear_magic(const struct flash_area *fap)
 {
-    uint32_t off;
-    int rc;
-    uint8_t tmp[BOOT_MAGIC_SZ];
+    uint32_t off = 0;
+    int rc = -1;
+    uint8_t tmp[BOOT_MAGIC_SZ] = {0};
 
     off = fap->fa_size - BOOT_MAGIC_SZ;
 
@@ -324,110 +367,6 @@
     return rc;
 }
 
-#if defined (MCUBOOT_SWAP_STATUS_FAST_BOOT)
-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;
-}
-#endif
-
 int
 boot_read_swap_state(const struct flash_area *fap,
                      struct boot_swap_state *state)
@@ -445,36 +384,6 @@
 
     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;
-        }
-    }
-
-#if defined(MCUBOOT_SWAP_STATUS_FAST_BOOT)
-    {
-        bool is_scratch = fap->fa_id == FLASH_AREA_IMAGE_SCRATCH;
-        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;
-            }
-        }
-    }
-#endif
-
     rc = flash_area_open(FLASH_AREA_IMAGE_SWAP_STATUS, &fap_stat);
     if (rc != 0) {
         return -1;
@@ -487,6 +396,17 @@
         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 9fb7420..6498787 100644
--- a/boot/bootutil/src/swap_status_part.c
+++ b/boot/bootutil/src/swap_status_part.c
@@ -152,46 +152,49 @@
     if (rc != 0) {
         return -1;
     }
-    else {
-        /* loop over copies/duplicates */
-        for (uint32_t i = 0; i < BOOT_SWAP_STATUS_MULT; i++) {
-            /* calculate final duplicate offset */
-            fin_offset = rec_offset + i * BOOT_SWAP_STATUS_D_SIZE;
 
+    /* loop over copies/duplicates */
+    for (uint32_t i = 0; i < BOOT_SWAP_STATUS_MULT; i++) {
+        /* calculate final duplicate offset */
+        fin_offset = rec_offset + i * BOOT_SWAP_STATUS_D_SIZE;
+
+        rc = flash_area_read(fap_stat, fin_offset + BOOT_SWAP_STATUS_PAYLD_SZ, &magic, sizeof(magic));
+        if (rc != 0) {
+            return -1;
+        }
+
+        if (magic == BOOT_SWAP_STATUS_MAGIC) {
             rc = flash_area_read(fap_stat, fin_offset, record_buff, sizeof(record_buff));
             if (rc != 0) {
                 return -1;
             }
-            else {
-                /* read magic value to know if area was pre-erased */
-                magic = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_PAYLD_SZ]);
-                if (magic == BOOT_SWAP_STATUS_MAGIC) {   /* read CRC */
-                    crc = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_ROW_SZ -
-                                            BOOT_SWAP_STATUS_CRC_SZ]);
-                    /* check record data integrity first */
-                    if (crc == calc_record_crc(record_buff, BOOT_SWAP_STATUS_ROW_SZ-BOOT_SWAP_STATUS_CRC_SZ)) {
-                        /* look for counter */
-                        counter = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_ROW_SZ -
-                                                    BOOT_SWAP_STATUS_CNT_SZ -
-                                                    BOOT_SWAP_STATUS_CRC_SZ]);
-                        /* find out counter max */
-                        if (counter >= max_cnt) {
-                            max_cnt = counter;
-                            *max_idx = i;
-                            data_offset = fin_offset;
-                        }
-                    }
-                    /* if crc != calculated() */
-                    else {
-                        crc_fail++;
-                    }
-                }
-                else {
-                    magic_fail++;
+
+            crc = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_ROW_SZ -
+                                              BOOT_SWAP_STATUS_CRC_SZ]);
+            /* check record data integrity first */
+            if (crc == calc_record_crc(record_buff, BOOT_SWAP_STATUS_ROW_SZ - BOOT_SWAP_STATUS_CRC_SZ)) {
+                /* look for counter */
+                counter = pack_bytes_u32(&record_buff[BOOT_SWAP_STATUS_ROW_SZ -
+                                                      BOOT_SWAP_STATUS_CNT_SZ -
+                                                      BOOT_SWAP_STATUS_CRC_SZ]);
+                /* find out counter max */
+                if (counter >= max_cnt) {
+                    max_cnt = counter;
+                    *max_idx = i;
+                    data_offset = fin_offset;
                 }
             }
+            /* if crc != calculated() */
+            else {
+                (void) flash_area_erase(fap_stat, fin_offset, sizeof(record_buff));
+                crc_fail++;
+            }
+
+        } else {
+            magic_fail++;
         }
     }
+
     /* no magic found - status area is pre-erased, start from scratch */
     if (magic_fail == BOOT_SWAP_STATUS_MULT) {
         /* emulate last index was received, so next will start from beginning */
@@ -228,10 +231,11 @@
 { /* it receives explicitly BOOT_SWAP_STATUS_PAYLD_SZ of data */
     int rc = -1;
 
-    uint32_t fin_offset;
+    uint32_t fin_offset, fin_offset_prev;
     /* increment counter field */
     uint32_t next_counter = copy_counter + 1U;
     uint32_t next_crc;
+    uint32_t copy_num_prev;
 
     const struct flash_area *fap_stat = NULL;
 
@@ -260,12 +264,15 @@
     /* we already know what copy number was last and correct */
     /* increment duplicate index */
     /* calculate final duplicate offset */
+    copy_num_prev = copy_num;
+
     if (copy_num == (BOOT_SWAP_STATUS_MULT - 1U)) {
         copy_num = 0;
     }
     else {
         copy_num++;
     }
+    fin_offset_prev = rec_offset + copy_num_prev*BOOT_SWAP_STATUS_D_SIZE;
     fin_offset = rec_offset + copy_num*BOOT_SWAP_STATUS_D_SIZE;
 
     /* erase obsolete status record before write */
@@ -276,6 +283,11 @@
 
     /* write prepared record into flash */
     rc = flash_area_write(fap_stat, fin_offset, record_buff, sizeof(record_buff));
+    if (rc != 0) {
+        return -1;
+    }
+
+    rc = flash_area_erase(fap_stat, fin_offset_prev, sizeof(record_buff));
 
     flash_area_close(fap_stat);