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