From c0bb1337fabf2cabbd0470ff4533f0ff63189260 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Fri, 7 Mar 2025 10:06:39 +0100 Subject: [PATCH 001/204] boot: zephyr: boards: Add frdm-mcxn236 configuration Adds default configuration for the frdm-mcxn236 board. Signed-off-by: Andrej Butok --- boot/zephyr/boards/frdm_mcxn236.conf | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 boot/zephyr/boards/frdm_mcxn236.conf diff --git a/boot/zephyr/boards/frdm_mcxn236.conf b/boot/zephyr/boards/frdm_mcxn236.conf new file mode 100644 index 000000000..4b6b72f1e --- /dev/null +++ b/boot/zephyr/boards/frdm_mcxn236.conf @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +#MCXN236 does not support the MCUBoot swap mode. +CONFIG_BOOT_UPGRADE_ONLY=y From 4535ad98d10c5b724684378da12bbfef2bb00962 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 11 Mar 2025 14:03:33 +0000 Subject: [PATCH 002/204] boot: Additional flash_area_open removals Another set of flash_area_open removals where boot_loader_state is available to provide flash_area object's pointer. Signed-off-by: Dominik Ermel --- boot/bootutil/src/bootutil_misc.c | 14 +++----------- boot/bootutil/src/loader.c | 25 ++++++------------------- boot/bootutil/src/swap_misc.c | 12 +++--------- boot/bootutil/src/swap_move.c | 15 ++++----------- boot/bootutil/src/swap_scratch.c | 16 ++++++---------- 5 files changed, 22 insertions(+), 60 deletions(-) diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 476489e54..765fea25a 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -447,19 +447,12 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) struct image_tlv_info info; uint32_t off; uint32_t protect_tlv_size; - int area_id; int rc; -#if (BOOT_IMAGE_NUMBER == 1) - (void)state; -#endif + assert(slot == BOOT_PRIMARY_SLOT || slot == BOOT_SECONDARY_SLOT); - area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), slot); - rc = flash_area_open(area_id, &fap); - if (rc != 0) { - rc = BOOT_EFLASH; - goto done; - } + fap = BOOT_IMG_AREA(state, slot); + assert(fap != NULL); off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); @@ -493,7 +486,6 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) rc = 0; done: - flash_area_close(fap); return rc; } #endif /* !MCUBOOT_OVERWRITE_ONLY */ diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index cf6a388f8..5a723609e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -716,7 +716,6 @@ boot_write_status(const struct boot_loader_state *state, struct boot_status *bs) { const struct flash_area *fap; uint32_t off; - int area_id; int rc = 0; uint8_t buf[BOOT_MAX_ALIGN]; uint32_t align; @@ -731,20 +730,15 @@ boot_write_status(const struct boot_loader_state *state, struct boot_status *bs) #if MCUBOOT_SWAP_USING_SCRATCH if (bs->use_scratch) { /* Write to scratch. */ - area_id = FLASH_AREA_IMAGE_SCRATCH; + fap = state->scratch.area; } else { #endif /* Write to the primary slot. */ - area_id = FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state)); + fap = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); #if MCUBOOT_SWAP_USING_SCRATCH } #endif - rc = flash_area_open(area_id, &fap); - if (rc != 0) { - return BOOT_EFLASH; - } - off = boot_status_off(fap) + boot_status_internal_off(bs, BOOT_WRITE_SZ(state)); align = flash_area_align(fap); @@ -761,8 +755,6 @@ boot_write_status(const struct boot_loader_state *state, struct boot_status *bs) rc = BOOT_EFLASH; } - flash_area_close(fap); - return rc; } #endif /* !MCUBOOT_RAM_LOAD */ @@ -1470,13 +1462,11 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) BOOT_LOG_INF("Image %d upgrade secondary slot -> primary slot", image_index); BOOT_LOG_INF("Erasing the primary slot"); - rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), - &fap_primary_slot); - assert (rc == 0); + fap_primary_slot = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); + assert(fap_primary_slot != NULL); - rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), - &fap_secondary_slot); - assert (rc == 0); + fap_secondary_slot = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + assert(fap_secondary_slot != NULL); sect_count = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT); for (sect = 0, size = 0; sect < sect_count; sect++) { @@ -1590,9 +1580,6 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) last_sector)); assert(rc == 0); - flash_area_close(fap_primary_slot); - flash_area_close(fap_secondary_slot); - /* TODO: Perhaps verify the primary slot's signature again? */ return 0; diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c index 70e09767f..2c72beb8e 100644 --- a/boot/bootutil/src/swap_misc.c +++ b/boot/bootutil/src/swap_misc.c @@ -124,7 +124,6 @@ swap_read_status(struct boot_loader_state *state, struct boot_status *bs) const struct flash_area *fap; uint32_t off; uint8_t swap_info; - int area_id; int rc; bs->source = swap_status_source(state); @@ -134,12 +133,12 @@ swap_read_status(struct boot_loader_state *state, struct boot_status *bs) #if MCUBOOT_SWAP_USING_SCRATCH case BOOT_STATUS_SOURCE_SCRATCH: - area_id = FLASH_AREA_IMAGE_SCRATCH; + fap = state->scratch.area; break; #endif case BOOT_STATUS_SOURCE_PRIMARY_SLOT: - area_id = FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state)); + fap = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); break; default: @@ -147,10 +146,7 @@ swap_read_status(struct boot_loader_state *state, struct boot_status *bs) return BOOT_EBADARGS; } - rc = flash_area_open(area_id, &fap); - if (rc != 0) { - return BOOT_EFLASH; - } + assert(fap != NULL); rc = swap_read_status_bytes(fap, state, bs); if (rc == 0) { @@ -171,8 +167,6 @@ swap_read_status(struct boot_loader_state *state, struct boot_status *bs) } done: - flash_area_close(fap); - return rc; } diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index dd5b131a7..5cd598c2e 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -517,10 +517,8 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs, uint32_t trailer_sz; uint32_t first_trailer_idx; uint32_t last_idx; - uint8_t image_index; const struct flash_area *fap_pri; const struct flash_area *fap_sec; - int rc; BOOT_LOG_INF("Starting swap using move algorithm."); @@ -553,13 +551,11 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs, } } - image_index = BOOT_CURR_IMG(state); + fap_pri = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); + assert(fap_pri != NULL); - rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap_pri); - assert (rc == 0); - - rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap_sec); - assert (rc == 0); + fap_sec = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + assert(fap_sec != NULL); fixup_revert(state, bs, fap_sec); @@ -583,9 +579,6 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs, } idx++; } - - flash_area_close(fap_pri); - flash_area_close(fap_sec); } int app_max_size(struct boot_loader_state *state) diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 60751029d..173e51e5a 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -564,14 +564,14 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, image_index = BOOT_CURR_IMG(state); - rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap_primary_slot); - assert (rc == 0); + fap_primary_slot = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); + assert(fap_primary_slot != NULL); - rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap_secondary_slot); - assert (rc == 0); + fap_secondary_slot = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + assert(fap_secondary_slot != NULL); - rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap_scratch); - assert (rc == 0); + fap_scratch = state->scratch.area; + assert(fap_scratch != NULL); /* Calculate offset from start of image area. */ img_off = boot_img_sector_off(state, BOOT_PRIMARY_SLOT, idx); @@ -782,10 +782,6 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, assert(rc == 0); } } - - flash_area_close(fap_primary_slot); - flash_area_close(fap_secondary_slot); - flash_area_close(fap_scratch); } void From a01ca4cf946badfc409c490850c335f7152bc391 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 12 Mar 2025 16:06:32 +0000 Subject: [PATCH 003/204] bootutil: Fix ASN1 bypass not building One of includes is not available when bypassing ASN1 encoding as mbedTLS is no longer enabled for compilation. Discovered with zephyr, but common for other platforms, after recent changes in CMakeLists.txt. Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 01bef149d..90e8300de 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -18,10 +18,10 @@ #define MBEDTLS_ASN1_PARSE_C #include "mbedtls/oid.h" #include "mbedtls/asn1.h" +#include "bootutil/crypto/common.h" #endif #include "bootutil_priv.h" -#include "bootutil/crypto/common.h" #include "bootutil/crypto/sha.h" #define EDDSA_SIGNATURE_LENGTH 64 From ec86244ac150d87b46e41d948ce7b655be672f88 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 12 Mar 2025 16:09:12 +0000 Subject: [PATCH 004/204] zephyr: Do not compile ASN1 code when bypassed Commit removes files needed for ASN1 parsing from compilation, when ASN1 bypass is enabled. Signed-off-by: Dominik Ermel --- boot/zephyr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 209c61dbe..b916a030a 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -31,7 +31,7 @@ assert_exists(TINYCRYPT_SHA512_DIR) set(FIAT_DIR "${MCUBOOT_DIR}/ext/fiat") assert_exists(FIAT_DIR) # Path to mbed-tls' asn1 parser library. -if(NOT CONFIG_MBEDTLS_BUILTIN) +if(NOT CONFIG_MBEDTLS_BUILTIN AND NOT CONFIG_BOOT_KEY_IMPORT_BYPASS_ASN) set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls-asn1") assert_exists(MBEDTLS_ASN1_DIR) endif() From 0ba80ffb1a0a2514385de47da67ac19c17ff23de Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 12 Mar 2025 16:44:21 +0000 Subject: [PATCH 005/204] zephyr: Prevent selecting MBEDTLS_ASN1_PARSE_C when not needed Make selection of MBEDTLS_ASN1_PARSE_C, in BOOT_ED25519_MBEDTLS, depending on ASN1 parsing being enabled. Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index b366b26d9..581f10028 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -293,7 +293,7 @@ config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS select MBEDTLS - select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN + select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN && !BOOT_KEY_IMPORT_BYPASS_ASN select BOOT_AES_MBEDTLS_DEPENDENCIES if MBEDTLS_BUILTIN && BOOT_ENCRYPT_IMAGE config BOOT_ED25519_PSA From f523c60dbd60677557d192dcabd20af28a8470c3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 12 Mar 2025 16:13:28 +0000 Subject: [PATCH 006/204] zephyr: Fix ED25519 compilation with mbedTLS ED25519 with mbedTLS has not been linking due to missing SHA512, which is internally required by ED25519 implementation. Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 581f10028..fabd1bd5b 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -292,7 +292,9 @@ config BOOT_ED25519_TINYCRYPT config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS + select BOOT_IMG_HASH_ALG_SHA512_ALLOW select MBEDTLS + select MBEDTLS_SHA512 select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN && !BOOT_KEY_IMPORT_BYPASS_ASN select BOOT_AES_MBEDTLS_DEPENDENCIES if MBEDTLS_BUILTIN && BOOT_ENCRYPT_IMAGE From b0c7df9c7c9edaeff8e9996feca8dc1baeeaa304 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 13 Mar 2025 13:31:16 +0000 Subject: [PATCH 007/204] boot: bootutil: Fix usage of flash_area object Fixes directly accessing an element of this object with one of the helper functions Signed-off-by: Jamie McCrae --- boot/bootutil/src/bootutil_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 765fea25a..cf4ce15e6 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -173,7 +173,7 @@ boot_status_off(const struct flash_area *fap) elem_sz = flash_area_align(fap); #if MCUBOOT_SWAP_USING_SCRATCH - if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) { + if (flash_area_get_id(fap) == FLASH_AREA_IMAGE_SCRATCH) { off_from_end = boot_scratch_trailer_sz(elem_sz); } else { #endif From e5d8640cd49829a1d5916fbae04cb2c817fb6116 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 13 Mar 2025 15:07:09 +0000 Subject: [PATCH 008/204] zephyr: Add missing selection for allowed SHA algorithms All of ED25519 backends allow SHA512, together with SHA512. The ED25519 internally requires SHA512 for calculations, but image may be hashed with any SHA algorithm. The PSA has also been missing selecting of any SHA as allowed. Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index fabd1bd5b..7be8a480b 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -287,11 +287,13 @@ choice BOOT_ED25519_IMPLEMENTATION config BOOT_ED25519_TINYCRYPT bool "Use tinycrypt" select BOOT_USE_TINYCRYPT + select BOOT_IMG_HASH_ALG_SHA256_ALLOW select BOOT_IMG_HASH_ALG_SHA512_ALLOW config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS + select BOOT_IMG_HASH_ALG_SHA256_ALLOW select BOOT_IMG_HASH_ALG_SHA512_ALLOW select MBEDTLS select MBEDTLS_SHA512 @@ -302,10 +304,13 @@ config BOOT_ED25519_PSA bool "Use PSA crypto" select MBEDTLS select BOOT_USE_PSA_CRYPTO - select MBEDTLS_PSA_CRYPTO_C - select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN select PSA_CRYPTO_CLIENT select PSA_CRYPTO_C + select MBEDTLS_PSA_CRYPTO_C + select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN + select MBEDTLS_ENABLE_HEAP + select BOOT_IMG_HASH_ALG_SHA256_ALLOW + select BOOT_IMG_HASH_ALG_SHA512_ALLOW select BOOT_ED25519_PSA_DEPENDENCIES select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE From 1ead4a67aa956c9412e32511063173e329d9cae1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 14 Mar 2025 11:43:57 +0000 Subject: [PATCH 009/204] boot: zephyr: kconfig: Remove superflous default n lines Removes lines that have never done anything because this is already the default Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 21 --------------------- boot/zephyr/Kconfig.serial_recovery | 1 - 2 files changed, 22 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 7be8a480b..3140666b3 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -20,7 +20,6 @@ config MCUBOOT config BOOT_USE_MBEDTLS bool # Hidden option - default n help Use mbedTLS for crypto primitives. @@ -33,7 +32,6 @@ config BOOT_USE_PSA_CRYPTO config BOOT_USE_TINYCRYPT bool # Hidden option - default n # When building for ECDSA, we use our own copy of mbedTLS, so the # Zephyr one must not be enabled or the MBEDTLS_CONFIG_FILE macros # will collide. @@ -44,7 +42,6 @@ config BOOT_USE_TINYCRYPT config BOOT_USE_CC310 bool # Hidden option - default n # When building for ECDSA, we use our own copy of mbedTLS, so the # Zephyr one must not be enabled or the MBEDTLS_CONFIG_FILE macros # will collide. @@ -53,15 +50,12 @@ config BOOT_USE_CC310 config BOOT_USE_NRF_CC310_BL bool - default n config NRFXLIB_CRYPTO bool - default n config NRF_CC310_BL bool - default n if BOOT_USE_MBEDTLS && MBEDTLS_BUILTIN @@ -130,7 +124,6 @@ menu "MCUBoot settings" config SINGLE_APPLICATION_SLOT bool "Single slot bootloader" - default n help Single image area is used for application which means that uploading a new application overwrites the one that previously @@ -376,7 +369,6 @@ config MBEDTLS_CFG_FILE config BOOT_HW_KEY bool "Use HW key for image verification" - default n help Use HW key for image verification, otherwise the public key is embedded in MCUBoot. If enabled the public key is appended to the signed image @@ -395,7 +387,6 @@ config BOOT_VALIDATE_SLOT0 config BOOT_VALIDATE_SLOT0_ONCE bool "Validate image in the primary slot just once after after upgrade" depends on !BOOT_VALIDATE_SLOT0 && SINGLE_APPLICATION_SLOT - default n help If y, the bootloader attempts to validate the signature of the primary slot only once after an upgrade of the main slot. @@ -501,7 +492,6 @@ endchoice config BOOT_DIRECT_XIP_REVERT bool "Enable the revert mechanism in direct-xip mode" depends on BOOT_DIRECT_XIP - default n help If y, enables the revert mechanism in direct-xip similar to the one in swap mode. It requires the trailer magic to be added to the signed image. @@ -512,7 +502,6 @@ config BOOT_DIRECT_XIP_REVERT config BOOT_BOOTSTRAP bool "Bootstrap erased the primary slot from the secondary slot" - default n help If y, enables bootstraping support. Bootstrapping allows an erased primary slot to be initialized from a valid image in the secondary slot. @@ -520,7 +509,6 @@ config BOOT_BOOTSTRAP config BOOT_SWAP_SAVE_ENCTLV bool "Save encrypted key TLVs instead of plaintext keys in swap metadata" - default n depends on BOOT_ENCRYPT_IMAGE help If y, instead of saving the encrypted image keys in plaintext in the @@ -649,7 +637,6 @@ config BOOT_MAX_IMG_SECTORS config BOOT_SHARE_BACKEND_AVAILABLE bool - default n help Hidden open which indicates if there is a sharing backend available. @@ -658,7 +645,6 @@ DT_CHOSEN_BOOTLOADER_INFO := zephyr,bootloader-info config BOOT_SHARE_BACKEND_AVAILABLE bool - default n help Hidden open which indicates if there is a sharing backend available. @@ -693,7 +679,6 @@ endchoice menuconfig BOOT_SHARE_DATA bool "Save application specific data" - default n depends on BOOT_SHARE_BACKEND_AVAILABLE help This will allow data to be shared between MCUboot and an application, @@ -705,7 +690,6 @@ menuconfig BOOT_SHARE_DATA config BOOT_SHARE_DATA_BOOTINFO bool "Save boot information data" - default n depends on BOOT_SHARE_DATA help This will place information about the MCUboot configuration and @@ -713,7 +697,6 @@ config BOOT_SHARE_DATA_BOOTINFO menuconfig MEASURED_BOOT bool "Store the boot state/measurements in shared memory area" - default n depends on BOOT_SHARE_BACKEND_AVAILABLE help If enabled, the bootloader will store certain boot measurements such as @@ -830,7 +813,6 @@ config BOOT_USB_DFU_NO_APPLICATION config BOOT_USE_BENCH bool "Enable benchmark code" - default n help If y, adds support for simple benchmarking that can record time intervals between two calls. The time printed depends @@ -867,7 +849,6 @@ rsource "Kconfig.firmware_loader" config BOOT_INTR_VEC_RELOC bool "Relocate the interrupt vector to the application" - default n depends on SW_VECTOR_RELAY || CPU_CORTEX_M_HAS_VTOR help Relocate the interrupt vector to the application before it is started. @@ -1062,7 +1043,6 @@ config MCUBOOT_DEVICE_SETTINGS config MCUBOOT_DEVICE_CPU_CORTEX_M0 # Hidden selector for Cortex-M0 settings bool - default n select SW_VECTOR_RELAY if !CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP comment "Zephyr configuration options" @@ -1091,7 +1071,6 @@ config USB_DEVICE_PRODUCT # use MCUboot's own log configuration config MCUBOOT_BOOTUTIL_LIB_OWN_LOG bool - default n config MCUBOOT_VERIFY_IMG_ADDRESS bool "Verify reset address of image in secondary slot" diff --git a/boot/zephyr/Kconfig.serial_recovery b/boot/zephyr/Kconfig.serial_recovery index 72be5ccfb..45d252408 100644 --- a/boot/zephyr/Kconfig.serial_recovery +++ b/boot/zephyr/Kconfig.serial_recovery @@ -6,7 +6,6 @@ menuconfig MCUBOOT_SERIAL bool "MCUboot serial recovery" - default n select REBOOT select SERIAL select UART_INTERRUPT_DRIVEN From 2a2b562b7d1235f34a27ad8a82a71c546824d975 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Mon, 11 Nov 2024 14:31:57 +0100 Subject: [PATCH 010/204] bootutil: Add support for devices without erase and reduced erases The commit adds two MCUboot configuration options: - MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE - MCUBOOT_SUPPORT_DEV_WITH_ERASE - MCUBOOT_MINIMAL_SCRAMBLE The first one should be enabled to support devices that do not require erase. When such devices are used in system then MCUboot will avoid erasing such device, which is not needed by hardware, and will just write data to it. This allows to both improve device lifetime and reduce time of operations like swap. The second option is just bringing a configuration option for already existing support for deviceses with erase. The third option allows to reduce amount of removed data. When enabled, MCUboot will remove enough of data, depending on the purpose of the removal, to just fulfill the purpose; for example if removal of data is done to make image unrecognizable for MCUboot, with this option, it will only remove header. Signed-off-by: Dominik Ermel --- boot/boot_serial/src/boot_serial.c | 4 +- boot/boot_serial/src/boot_serial_encryption.c | 2 +- boot/bootutil/src/bootutil_misc.c | 68 ++++++ boot/bootutil/src/bootutil_priv.h | 36 +++ boot/bootutil/src/loader.c | 213 +++++++++++++++++- boot/bootutil/src/ram_load.c | 2 +- boot/bootutil/src/swap_misc.c | 84 ++++--- boot/bootutil/src/swap_move.c | 11 +- boot/bootutil/src/swap_offset.c | 12 +- boot/bootutil/src/swap_priv.h | 11 + boot/bootutil/src/swap_scratch.c | 10 +- 11 files changed, 401 insertions(+), 52 deletions(-) diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c index 9ddc712de..a9c0630c8 100644 --- a/boot/boot_serial/src/boot_serial.c +++ b/boot/boot_serial/src/boot_serial.c @@ -856,7 +856,7 @@ static off_t erase_range(const struct flash_area *fap, off_t start, off_t end) BOOT_LOG_DBG("Erasing range 0x%jx:0x%jx", (intmax_t)start, (intmax_t)(start + size - 1)); - rc = flash_area_erase(fap, start, size); + rc = boot_erase_region(fap, start, size); if (rc != 0) { BOOT_LOG_ERR("Error %d while erasing range", rc); return -EINVAL; @@ -1000,7 +1000,7 @@ bs_upload(char *buf, int len) /* Non-progressive erase erases entire image slot when first chunk of * an image is received. */ - rc = flash_area_erase(fap, 0, area_size); + rc = boot_erase_region(fap, 0, area_size); if (rc) { goto out_invalid_data; } diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 744b22312..81af6b850 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -187,7 +187,7 @@ decrypt_region_inplace(struct boot_loader_state *state, (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } - rc = flash_area_erase(fap, off + bytes_copied, chunk_sz); + rc = boot_erase_region(fap, off + bytes_copied, chunk_sz); if (rc != 0) { return BOOT_EFLASH; } diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index cf4ce15e6..f12562329 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -135,6 +135,74 @@ boot_trailer_sz(uint32_t min_write_sz) return boot_status_sz(min_write_sz) + boot_trailer_info_sz(); } +int boot_trailer_scramble_offset(const struct flash_area *fa, size_t alignment, + size_t *off) +{ + int ret = 0; + + /* Not allowed to enforce alignment smaller than device allows */ + if (alignment < flash_area_align(fa)) { + alignment = flash_area_align(fa); + } + + if (device_requires_erase(fa)) { + /* For device requiring erase align to erase unit */ + struct flash_sector sector; + + ret = flash_area_get_sector(fa, flash_area_get_size(fa) - boot_trailer_sz(alignment), + §or); + if (ret < 0) { + return ret; + } + + *off = flash_sector_get_off(§or); + } else { + /* For device not requiring erase align to write block */ + *off = flash_area_get_size(fa) - ALIGN_DOWN(boot_trailer_sz(alignment), alignment); + } + + return ret; +} + +int boot_header_scramble_off_sz(const struct flash_area *fa, int slot, size_t *off, + size_t *size) +{ + int ret = 0; + const size_t write_block = flash_area_align(fa); + size_t loff = 0; + struct flash_sector sector; + + (void)slot; +#if defined(MCUBOOT_SWAP_USING_OFFSET) + /* In case of swap offset, header of secondary slot image is positioned + * in second sector of slot. + */ + if (slot == BOOT_SECONDARY_SLOT) { + ret = flash_area_get_sector(fa, 0, §or); + if (ret < 0) { + return ret; + } + loff = flash_sector_get_off(§or); + } +#endif + + if (device_requires_erase(fa)) { + /* For device requiring erase align to erase unit */ + ret = flash_area_get_sector(fa, loff, §or); + if (ret < 0) { + return ret; + } + + *size = flash_sector_get_size(§or); + } else { + /* For device not requiring erase align to write block */ + *size = ALIGN_UP(sizeof(((struct image_header *)0)->ih_magic), write_block); + } + *off = loff; + + return ret; +} + #if MCUBOOT_SWAP_USING_SCRATCH /* * Similar to `boot_trailer_sz` but this function returns the space used to diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index b8be9122e..95f8f1732 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -302,6 +302,16 @@ const struct flash_area *boot_find_status(const struct boot_loader_state *state, int boot_magic_compatible_check(uint8_t tbl_val, uint8_t val); uint32_t boot_status_sz(uint32_t min_write_sz); uint32_t boot_trailer_sz(uint32_t min_write_sz); +/* Get offset of trailer aligned to either device erase unit or alignment + * depending on whether device has erase or not. + */ +int boot_trailer_scramble_offset(const struct flash_area *fa, size_t alignment, + size_t *off); +/* Get size of header aligned to device erase unit or write block, + * depending on whether device has erase or not. + */ +int boot_header_scramble_off_sz(const struct flash_area *fa, int slot, size_t *off, + size_t *size); int boot_status_entries(int image_index, const struct flash_area *fap); uint32_t boot_status_off(const struct flash_area *fap); int boot_read_swap_state(const struct flash_area *fap, @@ -333,7 +343,19 @@ int boot_copy_region(struct boot_loader_state *state, const struct flash_area *fap_dst, uint32_t off_src, uint32_t off_dst, uint32_t sz); #endif +/* Prepare for write device that requires erase prior to write. This will + * do nothing on devices without erase requirement. + */ int boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz); +/* Similar to boot_erase_region but will always remove data */ +int boot_scramble_region(const struct flash_area *fap, uint32_t off, uint32_t sz); +/* Similar to boot_scramble_region but works backwards */ +int boot_scramble_region_backwards(const struct flash_area *fap, uint32_t off, uint32_t sz); +/* Makes slot unbootable, either by scrambling header magic, header sector + * or entire slot, depending on settings. + * Note: slot is passed here becuase at this point there is no function + * matching flash_area object to slot */ +int boot_scramble_slot(const struct flash_area *fap, int slot); bool boot_status_is_reset(const struct boot_status *bs); #ifdef MCUBOOT_ENC_IMAGES @@ -529,6 +551,20 @@ uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct f int boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size); +/* Helper macro to avoid compile errors with systems that do not + * provide function to check device type. + * Note: it used to be inline, but somehow compiler would not + * optimize out branches that were impossible when this evaluated to + * just "true". + */ +#if defined(MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE) && defined(MCUBOOT_SUPPORT_DEV_WITH_ERASE) +#define device_requires_erase(fa) (flash_area_erase_required(fa)) +#elif defined(MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE) +#define device_requires_erase(fa) (false) +#else +#define device_requires_erase(fa) (true) +#endif + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 5a723609e..adc93b88b 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1026,7 +1026,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * is erased. */ if (slot != BOOT_PRIMARY_SLOT) { - swap_erase_trailer_sectors(state, fap); + swap_scramble_trailer_sectors(state, fap); #if defined(MCUBOOT_SWAP_USING_MOVE) if (bs->swap_type == BOOT_SWAP_TYPE_REVERT || @@ -1035,7 +1035,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, assert(fap_pri != NULL); - if (swap_erase_trailer_sectors(state, fap_pri) == 0) { + if (swap_scramble_trailer_sectors(state, fap_pri) == 0) { BOOT_LOG_INF("Cleared image %d primary slot trailer due to stuck revert", BOOT_CURR_IMG(state)); } @@ -1079,7 +1079,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); - flash_area_erase(fap, 0, flash_area_get_size(fap)); + boot_scramble_slot(fap, slot); /* Image in the secondary slot does not satisfy version requirement. * Erase the image and continue booting from the primary slot. */ @@ -1102,7 +1102,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #endif if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) { - flash_area_erase(fap, 0, flash_area_get_size(fap)); + boot_scramble_slot(fap, slot); /* Image is invalid, erase it to prevent further unnecessary * attempts to validate and boot it. */ @@ -1142,7 +1142,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * * Erase the image and continue booting from the primary slot. */ - flash_area_erase(fap, 0, fap->fa_size); + boot_scramble_slot(fap, slot); fih_rc = FIH_NO_BOOTABLE_IMAGE; goto out; } @@ -1229,11 +1229,12 @@ boot_validated_swap_type(struct boot_loader_state *state, #endif /** - * Erases a region of flash. + * Erases a region of device that requires erase prior to write; does + * nothing on devices without erase. * - * @param flash_area The flash_area containing the region to erase. + * @param fap The flash_area containing the region to erase. * @param off The offset within the flash area to start the - * erase. + * erase. * @param sz The number of bytes to erase. * * @return 0 on success; nonzero on failure. @@ -1241,7 +1242,197 @@ boot_validated_swap_type(struct boot_loader_state *state, int boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz) { - return flash_area_erase(fap, off, sz); + if (device_requires_erase(fap)) { + return flash_area_erase(fap, off, sz); + } + return 0; +} + +/** + * Removes data from specified region either by writing erase value in place of + * data or by doing erase, if device has such hardware requirement. + * Note that function will fail if off or size are not aligned to device + * write block size or erase block size. + * + * @param fa The flash_area containing the region to erase. + * @param off The offset within the flash area to start the + * erase. + * @param size The number of bytes to erase. + * + * @return 0 on success; nonzero on failure. + */ +int +boot_scramble_region(const struct flash_area *fa, uint32_t off, uint32_t size) +{ + int ret = 0; + + if (size == 0) { + return 0; + } + + if (device_requires_erase(fa)) { + return flash_area_erase(fa, off, size); + } else { + uint8_t buf[BOOT_MAX_ALIGN]; + size_t size_done = 0; + const size_t write_block = flash_area_align(fa); + + memset(buf, flash_area_erased_val(fa), sizeof(buf)); + + while (size_done < size) { + ret = flash_area_write(fa, size_done + off, buf, write_block); + if (ret != 0) { + break; + } + size_done += write_block; + } + } + return ret; +} + +/** + * Removes data from specified region backwards either by writing erase_value + * in place of data or by doing erase, if device has such hardware requirement. + * Note that function will fail if off or size are not aligned to device + * write block size or erase block size. + * + * @param fa The flash_area containing the region to erase. + * @param off The offset within the flash area to start the + * erase. + * @param size The number of bytes to erase. + * + * @return 0 on success; nonzero on failure. + */ +int boot_scramble_region_backwards(const struct flash_area *fa, uint32_t off, uint32_t size) +{ + int ret = 0; + uint32_t first_offset = 0; + + if (size == 0) { + return 0; + } + + if (off >= flash_area_get_size(fa) || (flash_area_get_size(fa) - off) < size) { + return -1; + } + + if (device_requires_erase(fa)) { + struct flash_sector sector; + + /* Get the lowest erased page offset first */ + ret = flash_area_get_sector(fa, off, §or); + if (ret < 0) { + return ret; + } + first_offset = flash_sector_get_off(§or); + + /* Set boundary condition, the highest probable offset to erase, within + * last sector to erase + */ + off += size - 1; + + while (true) { + /* Size to read in this iteration */ + size_t csize; + + /* Get current sector and, also, correct offset */ + ret = flash_area_get_sector(fa, off, §or); + if (ret < 0) { + return ret; + } + + /* Corrected offset and size of current sector to erase */ + off = flash_sector_get_off(§or); + csize = flash_sector_get_size(§or); + + ret = flash_area_erase(fa, off, csize); + if (ret < 0) { + return ret; + } + + if (first_offset >= off) { + /* Reached the first offsset in range and already erased it */ + break; + } + + /* Move down to previous sector, the flash_area_get_sector will + * correct the value to real page offset + */ + off -= 1; + } + } else { + uint8_t buf[BOOT_MAX_ALIGN]; + const size_t write_block = flash_area_align(fa); + uint32_t first_offset = ALIGN_DOWN(off, write_block); + + memset(buf, flash_area_erased_val(fa), sizeof(buf)); + + /* Starting at the last write block in range */ + off += size - write_block; + + while (true) { + /* Write over the area to scramble data that is there */ + ret = flash_area_write(fa, off, buf, write_block); + if (ret != 0) { + break; + } + + if (first_offset >= off) { + /* Reached the first offset in range and already scrambled it */ + break; + } + + off -= write_block; + } + } + return ret; +} + +/** + * Remove enough data from slot to mark is as unused + * Assumption: header and trailer are not overlapping on write block or + * erase block, if device has erase requirement. + * Note that this function is intended for removing data not preparing device + * for write. + * + * @param fa Pointer to flash area object for slot + * @param slot Slot the @p fa represents + * + * @return 0 on success; nonzero on failure. + */ +int +boot_scramble_slot(const struct flash_area *fa, int slot) +{ + size_t size; + int ret = 0; + + (void)slot; + + /* Without minimal entire area needs to be scrambled */ +#if !defined(MCUBOOT_MINIMAL_SCRAMBLE) + size = flash_area_get_size(fa); + ret = boot_scramble_region(fa, 0, size); +#else + size_t off = 0; + + ret = boot_header_scramble_off_sz(fa, slot, &off, &size); + if (ret < 0) { + return ret; + } + + ret = boot_scramble_region(fa, off, size); + if (ret < 0) { + return ret; + } + + ret = boot_trailer_scramble_offset(fa, 0, &off); + if (ret < 0) { + return ret; + } + + ret = boot_scramble_region_backwards(fa, off, flash_area_get_size(fa) - off); +#endif + return ret; } #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) @@ -1733,7 +1924,6 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) } #endif - /** * Performs a clean (not aborted) image update. * @@ -2196,8 +2386,7 @@ check_downgrade_prevention(struct boot_loader_state *state) if (rc < 0) { /* Image in slot 0 prevents downgrade, delete image in slot 1 */ BOOT_LOG_INF("Image %d in slot 1 erased due to downgrade prevention", BOOT_CURR_IMG(state)); - flash_area_erase(BOOT_IMG_AREA(state, 1), 0, - flash_area_get_size(BOOT_IMG_AREA(state, 1))); + boot_scramble_slot(BOOT_IMG_AREA(state, 1), BOOT_SECONDARY_SLOT); } else { rc = 0; } diff --git a/boot/bootutil/src/ram_load.c b/boot/bootutil/src/ram_load.c index 2aba3bf30..e3a75d635 100644 --- a/boot/bootutil/src/ram_load.c +++ b/boot/bootutil/src/ram_load.c @@ -415,7 +415,7 @@ boot_remove_image_from_flash(struct boot_loader_state *state, uint32_t slot) fap = BOOT_IMG_AREA(state, slot); assert(fap != NULL); - return flash_area_erase(fap, 0, flash_area_get_size(fap)); + return boot_scramble_slot(fap, slot); } int boot_load_image_from_flash_to_sram(struct boot_loader_state *state, diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c index 2c72beb8e..1244e475e 100644 --- a/boot/bootutil/src/swap_misc.c +++ b/boot/bootutil/src/swap_misc.c @@ -35,41 +35,73 @@ int swap_erase_trailer_sectors(const struct boot_loader_state *state, const struct flash_area *fap) { - uint8_t slot; - uint32_t sector; - uint32_t trailer_sz; - uint32_t total_sz; - uint32_t off; - uint32_t sz; - int rc; + int rc = 0; + + /* Intention is to prepare slot for write, if device does not require/support + * erase, there is nothing to do here. + */ + if (device_requires_erase(fap)) { + uint8_t slot = BOOT_PRIMARY_SLOT; + uint32_t sector; + uint32_t trailer_sz; + uint32_t total_sz; + + BOOT_LOG_DBG("Erasing trailer; fa_id=%d", flash_area_get_id(fap)); + + /* By default it is assumed that slot is primary */ + if (fap == BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) { + slot = BOOT_SECONDARY_SLOT; + } - BOOT_LOG_DBG("erasing trailer; fa_id=%d", flash_area_get_id(fap)); + /* Delete starting from last sector and moving to beginning */ + sector = boot_img_num_sectors(state, slot) - 1; + trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); + total_sz = 0; + do { + uint32_t sz = boot_img_sector_size(state, slot, sector); + uint32_t off = boot_img_sector_off(state, slot, sector); - if (fap == BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)) { - slot = BOOT_PRIMARY_SLOT; - } else if (fap == BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) { - slot = BOOT_SECONDARY_SLOT; + rc = boot_erase_region(fap, off, sz); + assert(rc == 0); + + sector--; + total_sz += sz; + } while (total_sz < trailer_sz); } else { - return BOOT_EFLASH; + BOOT_LOG_DBG("Erasing trailer not required; fa_id=%d", flash_area_get_id(fap)); } + return rc; +} - /* delete starting from last sector and moving to beginning */ - sector = boot_img_num_sectors(state, slot) - 1; - trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); - total_sz = 0; - do { - sz = boot_img_sector_size(state, slot, sector); - off = boot_img_sector_off(state, slot, sector); - rc = boot_erase_region(fap, off, sz); - assert(rc == 0); +int +swap_scramble_trailer_sectors(const struct boot_loader_state *state, + const struct flash_area *fap) +{ + size_t off; + int rc; - sector--; - total_sz += sz; - } while (total_sz < trailer_sz); + BOOT_LOG_DBG("Scrambling trailer; fa_id=%d", flash_area_get_id(fap)); - return rc; + /* Delete starting from last sector and moving to beginning */ + rc = boot_trailer_scramble_offset(fap, BOOT_WRITE_SZ(state), &off); + if (rc < 0) { + return BOOT_EFLASH; + } + rc = boot_scramble_region_backwards(fap, off, flash_area_get_size(fap) - off); + if (rc < 0) { + return BOOT_EFLASH; + } + + return 0; } +/* NOTE: There is often call made to swap_scramble_trailer_sectors followed + * by swap_status_init to initialize swap status: this is not efficient on + * devices that do not require erase; we need implementation of swap_status_init + * or swap_status_reinit, that will remove old status and initialize new one + * in a single call; the current approach writes certain parts of status + * twice on these devices. + */ int swap_status_init(const struct boot_loader_state *state, const struct flash_area *fap, diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 5cd598c2e..841cd4d34 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -396,14 +396,18 @@ boot_move_sector_up(int idx, uint32_t sz, struct boot_loader_state *state, if (bs->idx == BOOT_STATUS_IDX_0) { if (bs->source != BOOT_STATUS_SOURCE_PRIMARY_SLOT) { - rc = swap_erase_trailer_sectors(state, fap_pri); + /* Remove data and prepare for write on devices requiring erase */ + rc = swap_scramble_trailer_sectors(state, fap_pri); assert(rc == 0); rc = swap_status_init(state, fap_pri, bs); assert(rc == 0); } - rc = swap_erase_trailer_sectors(state, fap_sec); + /* Remove status from secondary slot trailer, in case of device with + * erase requirement this will also prepare traier for write. + */ + rc = swap_scramble_trailer_sectors(state, fap_sec); assert(rc == 0); } @@ -493,7 +497,8 @@ fixup_revert(const struct boot_loader_state *state, struct boot_status *bs, BOOT_LOG_SWAP_STATE("Secondary image", &swap_state); if (swap_state.magic == BOOT_MAGIC_UNSET) { - rc = swap_erase_trailer_sectors(state, fap_sec); + /* Remove trailer and prepare area for write on devices requiring erase */ + rc = swap_scramble_trailer_sectors(state, fap_sec); assert(rc == 0); rc = boot_write_image_ok(fap_sec); diff --git a/boot/bootutil/src/swap_offset.c b/boot/bootutil/src/swap_offset.c index ebef36df9..aecb16be3 100644 --- a/boot/bootutil/src/swap_offset.c +++ b/boot/bootutil/src/swap_offset.c @@ -596,7 +596,7 @@ void fixup_revert(const struct boot_loader_state *state, struct boot_status *bs, BOOT_LOG_SWAP_STATE("Secondary image", &swap_state); if (swap_state.magic == BOOT_MAGIC_UNSET) { - rc = swap_erase_trailer_sectors(state, fap_sec); + rc = swap_scramble_trailer_sectors(state, fap_sec); assert(rc == 0); rc = boot_write_copy_done(fap_sec); @@ -664,14 +664,14 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs, int rc; if (bs->source != BOOT_STATUS_SOURCE_PRIMARY_SLOT) { - rc = swap_erase_trailer_sectors(state, fap_pri); + rc = swap_scramble_trailer_sectors(state, fap_pri); assert(rc == 0); rc = swap_status_init(state, fap_pri, bs); assert(rc == 0); } - rc = swap_erase_trailer_sectors(state, fap_sec); + rc = swap_scramble_trailer_sectors(state, fap_sec); assert(rc == 0); } @@ -705,10 +705,10 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs, * status is not wrongly used as a valid header. Also erase the trailer in the secondary * to allow for a future update to be loaded */ - rc = boot_erase_region(fap_sec, boot_img_sector_off(state, BOOT_SECONDARY_SLOT, 0), - sector_sz); + rc = boot_scramble_region(fap_sec, boot_img_sector_off(state, BOOT_SECONDARY_SLOT, 0), + sector_sz); assert(rc == 0); - rc = swap_erase_trailer_sectors(state, fap_sec); + rc = swap_scramble_trailer_sectors(state, fap_sec); assert(rc == 0); } else { while (idx <= last_idx) { diff --git a/boot/bootutil/src/swap_priv.h b/boot/bootutil/src/swap_priv.h index 6fdf797e1..b564ea99e 100644 --- a/boot/bootutil/src/swap_priv.h +++ b/boot/bootutil/src/swap_priv.h @@ -26,10 +26,21 @@ /** * Calculates the amount of space required to store the trailer, and erases * all sectors required for this storage in the given flash_area. + * The erase will only happen on devices that require erase as a preparation + * for write. To just remove swap status, the swap_scramble_trailer_sectors + * should be called. */ int swap_erase_trailer_sectors(const struct boot_loader_state *state, const struct flash_area *fap); +/** + * Calculate the amount of space required to store the trailer and remove + * data from trailer. This is similar to swap_erase_trailer_sectors, but + * is intended to remove swap status not to prepare device with explicit + * erase requirements before write. + */ +int swap_scramble_trailer_sectors(const struct boot_loader_state *state, + const struct flash_area *fap); /** * Initialize the given flash_area with the metadata required to start a new * swap upgrade. diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 173e51e5a..03ccc028a 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -633,7 +633,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, * last sector is not being used by the image data so it's safe * to erase. */ - rc = swap_erase_trailer_sectors(state, fap_primary_slot); + rc = swap_scramble_trailer_sectors(state, fap_primary_slot); assert(rc == 0); rc = swap_status_init(state, fap_primary_slot, bs); @@ -691,6 +691,14 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, img_off, img_off, copy_sz); assert(rc == 0); + if (bs->idx == BOOT_STATUS_IDX_0 && !bs->use_scratch) { + /* If not all sectors of the slot are being swapped, + * guarantee here that only the primary slot will have the state. + */ + rc = swap_scramble_trailer_sectors(state, fap_secondary_slot); + assert(rc == 0); + } + rc = boot_write_status(state, bs); bs->state = BOOT_STATUS_STATE_2; BOOT_STATUS_ASSERT(rc == 0); From 2346d69ce080144a29b2a93a4cb4f439eeb72232 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 12 Nov 2024 21:23:29 +0100 Subject: [PATCH 011/204] zephyr: Add support for devices without erase and reduced erases Add Kconfig options: - CONFIG_MCUBOOT_STORAGE_WITHOUT_ERASE that enables MCUboot configuration MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE - CONFIG_MCUBOOT_STORAGE_WITH_ERASE that enables MCUboot configuration MCUBOOT_SUPPORT_DEV_WITH_ERASE - CONFIG_MCUBOOT_STORAGE_MINIMAL_SCRAMBLE that enables MCUboot configuration MCUBOOT_MINIMAL_SCRAMBLE Adds implementation of flash_area_erase_required, which is required when MCUBOOT_STORAGE_DEV_WITHOUT_ERASE is enabled. Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 38 +++++++++++++++++++ .../flash_map_backend/flash_map_backend.h | 17 +++++++++ .../include/mcuboot_config/mcuboot_config.h | 23 +++++++++++ 3 files changed, 78 insertions(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 3140666b3..988c329c8 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -1029,6 +1029,44 @@ endmenu endmenu +config MCUBOOT_STORAGE_WITHOUT_ERASE + bool "Support for devices without erase" + depends on FLASH_HAS_NO_EXPLICIT_ERASE + default y + help + Not all devices require erase before write and, depending on driver, + may emulate erase by write, as a way to scramble data rather then + by hardware requirement. This unfortunately means that code that + does erase before write, when not needed, will write device twice + which not only reduces device life time but also doubles time + of any write operation (one write for erase and one write for actual + write). + When this option is enabled, MCUboot will check for type of device + and will avoid erase where not needed. + +config MCUBOOT_STORAGE_WITH_ERASE + bool "Support for devices with erase" + depends on FLASH_HAS_EXPLICIT_ERASE + default y + help + Support for devices with erase + +config MCUBOOT_STORAGE_MINIMAL_SCRAMBLE + bool "Do minimal required work to remove data (EXPERIMENTAL)" + help + In some cases MCUboot has to remove data, which usually means make + it non-viable for MCUboot rather then completely destroyed. + For example when MCUboot does not want to bother with broken image, + in some slot, it will remove it. + The same can be achieved with just removal of header and footer, + leaving the rest of image untouched, as without header MCUboot will + not be able to recognize image in slot as bootable. + When this option is enabled, MCUboot will not attempt to erase + entire slot or image, instead it will just remove enough of + data from slot to not recognize it as image anymore. + Depending on type of device this may be done by erase of minimal + number of pages or overwrite of part of image. + config MCUBOOT_DEVICE_SETTINGS # Hidden selector for device-specific settings bool diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h index e5408a18a..81a183259 100644 --- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h +++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h @@ -106,6 +106,23 @@ static inline uint32_t flash_sector_get_size(const struct flash_sector *fs) int flash_area_get_sector(const struct flash_area *fa, off_t off, struct flash_sector *fs); + +#if defined(CONFIG_MCUBOOT) +static inline bool flash_area_erase_required(const struct flash_area *fa) +{ +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) + const struct flash_parameters *fp = flash_get_parameters(flash_area_get_device(fa)); + + return flash_params_get_erase_cap(flash_get_parameters(flash_area_get_device(fa))) & + FLASH_ERASE_C_EXPLICIT; +#elif defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) + return true; +#else + return false; +#endif +} +#endif + #ifdef __cplusplus } #endif diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 850a618b3..13a5683d2 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -307,6 +307,29 @@ #define MCUBOOT_ERASE_PROGRESSIVELY #endif +/* + * Devices that do not require erase prior to write or do not support + * erase should avoid emulation of erase by additional write. + * The emulation is also taking time which doubles required write time + * for such devices. + */ +#ifdef CONFIG_MCUBOOT_STORAGE_WITHOUT_ERASE +#define MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE +#endif + +#ifdef CONFIG_MCUBOOT_STORAGE_WITH_ERASE +#define MCUBOOT_SUPPORT_DEV_WITH_ERASE +#endif + +/* + * MCUboot often calls erase on device just to remove data or make application + * image not recognizable. In such instances it may be faster to just remove + * portion of data to make image unrecognizable. + */ +#ifdef CONFIG_MCUBOOT_STORAGE_MINIMAL_SCRAMBLE +#define MCUBOOT_MINIMAL_SCRAMBLE +#endif + /* * Enabling this option uses newer flash map APIs. This saves RAM and * avoids deprecated API usage. From 2f294d1f19adc6fc6fd4d4ed35317e1c554d08cb Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 12 Nov 2024 21:40:20 +0100 Subject: [PATCH 012/204] zephyr: Use flash_area_flatten in bs_custom_storage_erase The intention of bs_custom_storage_erase is to remove data from device; to support devices that do not require erase, without calling erase, so that devices that do not implement such functions could work, the flash_area_erase has been replaced with flash_area_flatten. Signed-off-by: Dominik Ermel --- boot/zephyr/boot_serial_extension_zephyr_basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/boot_serial_extension_zephyr_basic.c b/boot/zephyr/boot_serial_extension_zephyr_basic.c index b0c75f4a7..e0f978adf 100644 --- a/boot/zephyr/boot_serial_extension_zephyr_basic.c +++ b/boot/zephyr/boot_serial_extension_zephyr_basic.c @@ -47,7 +47,7 @@ static int bs_custom_storage_erase(const struct nmgr_hdr *hdr, if (rc < 0) { BOOT_LOG_ERR("failed to open flash area"); } else { - rc = flash_area_erase(fa, 0, flash_area_get_size(fa)); + rc = flash_area_flatten(fa, 0, flash_area_get_size(fa)); if (rc < 0) { BOOT_LOG_ERR("failed to erase flash area"); } From c8470fb145f8aff92696d05396fb77c3b8068b32 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 10 Dec 2024 20:21:58 +0100 Subject: [PATCH 013/204] boot: Enable MCUBOOT_DEV_WITH_ERASE in other systems By default enable all other systems to work with devices that require erase prior to write. Signed-off-by: Dominik Ermel --- boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h | 2 ++ boot/espressif/hal/include/mcuboot_config/mcuboot_config.h | 2 ++ boot/mbed/include/mcuboot_config/mcuboot_config.h | 2 ++ .../mcuboot_config/include/mcuboot_config/mcuboot_config.h | 2 ++ boot/nuttx/include/mcuboot_config/mcuboot_config.h | 2 ++ 5 files changed, 10 insertions(+) diff --git a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h index 7f8472b3d..9af2a7d27 100644 --- a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h +++ b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_config.h @@ -83,6 +83,8 @@ // TODO: FWSECURITY-755 #define MCUBOOT_USE_FLASH_AREA_GET_SECTORS +#define MCUBOOT_DEV_WITH_ERASE + /* Default number of separately updateable images; change in case of * multiple images. */ #ifndef MCUBOOT_IMAGE_NUMBER diff --git a/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h b/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h index 345ca57b8..2435172d8 100644 --- a/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h +++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_config.h @@ -126,6 +126,8 @@ * See the flash APIs for more details. */ #define MCUBOOT_USE_FLASH_AREA_GET_SECTORS +#define MCUBOOT_DEV_WITH_ERASE + /* Default maximum number of flash sectors per image slot; change * as desirable. */ #define MCUBOOT_MAX_IMG_SECTORS 512 diff --git a/boot/mbed/include/mcuboot_config/mcuboot_config.h b/boot/mbed/include/mcuboot_config/mcuboot_config.h index b57e8d651..4794d3db3 100644 --- a/boot/mbed/include/mcuboot_config/mcuboot_config.h +++ b/boot/mbed/include/mcuboot_config/mcuboot_config.h @@ -78,6 +78,8 @@ */ #define MCUBOOT_USE_FLASH_AREA_GET_SECTORS +#define MCUBOOT_DEV_WITH_ERASE + /* * No watchdog integration for now */ diff --git a/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h b/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h index 1ed162835..6ee2c2ad2 100644 --- a/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h +++ b/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h @@ -137,6 +137,8 @@ #define MCUBOOT_BOOT_MAX_ALIGN MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) #endif +#define MCUBOOT_DEV_WITH_ERASE + #if MYNEWT_VAL(BOOTUTIL_FEED_WATCHDOG) && MYNEWT_VAL(WATCHDOG_INTERVAL) #include #define MCUBOOT_WATCHDOG_FEED() \ diff --git a/boot/nuttx/include/mcuboot_config/mcuboot_config.h b/boot/nuttx/include/mcuboot_config/mcuboot_config.h index 41e7d6742..8a3383f5b 100644 --- a/boot/nuttx/include/mcuboot_config/mcuboot_config.h +++ b/boot/nuttx/include/mcuboot_config/mcuboot_config.h @@ -132,6 +132,8 @@ #define MCUBOOT_USE_FLASH_AREA_GET_SECTORS +#define MCUBOOT_DEV_WITH_ERASE + /* Default maximum number of flash sectors per image slot; change * as desirable. */ From 2d681da4891d995ea547c8355a0882c1c1016aa4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 18 Mar 2025 12:40:06 +0000 Subject: [PATCH 014/204] bootutil: Fix ed25519 pure signature verification Accidentally added check for size of blen against hash length, in bootutil_verify, was doubling check done in bootutli_verify_sig and prevented pure signature from working. Signed-off-by: Dominik Ermel --- boot/bootutil/src/image_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 90e8300de..ffb8cec3b 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -90,7 +90,7 @@ bootutil_verify(uint8_t *buf, uint32_t blen, uint8_t *pubkey; uint8_t *end; - if (blen != IMAGE_HASH_SIZE || slen != EDDSA_SIGNATURE_LENGTH) { + if (slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } From 9fa0c6b5506f27cedd67bbe254b7e0f95e4b380e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 18 Mar 2025 20:59:17 +0000 Subject: [PATCH 015/204] zephyr: Fix translation of PSA Kconfig to MCUboot config MCUBOOT_USE_PSA_CRYPTO should be set by CONFIG_BOOT_USE_PSA_CRYPTO instead of CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT. Signed-off-by: Dominik Ermel --- boot/zephyr/include/mcuboot_config/mcuboot_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 13a5683d2..d4d718c39 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -47,7 +47,7 @@ #ifdef CONFIG_BOOT_USE_NRF_CC310_BL #define MCUBOOT_USE_NRF_CC310_BL #endif -#elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) +#elif defined(CONFIG_BOOT_USE_PSA_CRYPTO) #define MCUBOOT_USE_PSA_CRYPTO #endif From b92d4dd716c11c5e1b3f6ffb6370ab68b565f25c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 26 Mar 2025 10:02:54 +0000 Subject: [PATCH 016/204] boot: zephyr: Only supply MBEDTLS config file path if set Fixes an issue where the variable might not be set and be empty, and would still be included which would cause a compiler include empty file error Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index b916a030a..39005b748 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -197,18 +197,18 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) ) endif() if(CONFIG_BOOT_USE_TINYCRYPT) - # When using ECDSA signatures, pull in our copy of the tinycrypt library. - zephyr_library_include_directories( - ${BOOT_DIR}/zephyr/include - ${TINYCRYPT_DIR}/include + # When using ECDSA signatures, pull in our copy of the tinycrypt library. + zephyr_library_include_directories( + ${BOOT_DIR}/zephyr/include + ${TINYCRYPT_DIR}/include ) - zephyr_include_directories(${TINYCRYPT_DIR}/include) + zephyr_include_directories(${TINYCRYPT_DIR}/include) - zephyr_library_sources( - ${TINYCRYPT_DIR}/source/ecc.c - ${TINYCRYPT_DIR}/source/ecc_dsa.c - ${TINYCRYPT_DIR}/source/sha256.c - ${TINYCRYPT_DIR}/source/utils.c + zephyr_library_sources( + ${TINYCRYPT_DIR}/source/ecc.c + ${TINYCRYPT_DIR}/source/ecc_dsa.c + ${TINYCRYPT_DIR}/source/sha256.c + ${TINYCRYPT_DIR}/source/utils.c ) elseif(CONFIG_BOOT_USE_NRF_CC310_BL) zephyr_library_sources(${NRF_DIR}/cc310_glue.c) @@ -216,12 +216,14 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_link_libraries(nrfxlib_crypto) endif() - # Since here we are not using Zephyr's mbedTLS but rather our own, we need - # to set MBEDTLS_CONFIG_FILE ourselves. When using Zephyr's copy, this - # variable is set by its Kconfig in the Zephyr codebase. - zephyr_library_compile_definitions( - MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}" + if(CONFIG_MBEDTLS_CFG_FILE) + # Since here we are not using Zephyr's mbedTLS but rather our own, we need + # to set MBEDTLS_CONFIG_FILE ourselves. When using Zephyr's copy, this + # variable is set by its Kconfig in the Zephyr codebase. + zephyr_library_compile_definitions( + MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}" ) + endif() elseif(CONFIG_BOOT_SIGNATURE_TYPE_NONE) zephyr_library_include_directories( ${BOOT_DIR}/zephyr/include From 8b7c7cc91e7105dba833a46729e2b65c4cad0325 Mon Sep 17 00:00:00 2001 From: Samuel Coleman Date: Wed, 26 Mar 2025 10:17:29 +0000 Subject: [PATCH 017/204] zephyr: flash map: fix comparison signedness This resolves a warning when building with `-Wsign-compare`. `struct flash_area.fa_size` is declared as `size_t` in the Zephyr source tree (in `include/zephyr/storage/flash_map.h`). Signed-off-by: Samuel Coleman --- boot/zephyr/flash_map_extended.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index 4a29750f7..1cc53f2f5 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -178,7 +178,7 @@ int flash_area_get_sector(const struct flash_area *fap, off_t off, struct flash_pages_info fpi; int rc; - if (off >= fap->fa_size) { + if (off < 0 || (size_t) off >= fap->fa_size) { return -ERANGE; } From b671a8f240c9625bd68e6343a0a53c88b691a434 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 26 Mar 2025 12:18:04 +0000 Subject: [PATCH 018/204] docs: compression_format: Fix tags Fixes tags for pygments Signed-off-by: Jamie McCrae --- docs/compression_format.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/compression_format.md b/docs/compression_format.md index ddb99d534..78397da7c 100644 --- a/docs/compression_format.md +++ b/docs/compression_format.md @@ -35,7 +35,7 @@ Compression parameters have the following default values: You can calculate the `dict_size` using the following method: -``` {.c} +```c unsigned int i = 0; for (i = 0; i < 40; i++) { @@ -103,14 +103,14 @@ The second byte of the `lzma2_header` carries the following parameters: These parameters are encoded with the following formula: - ``` {.c} + ```c pb_lp_lc = (uint8_t)((pb * 5 + lp) * 9 + lc); ``` To decode these values from the combined `pb_lp_lc` byte, run the following code: - ``` {.c} + ```c lc = pb_lp_lc % 9; pb_lp_lc /= 9; pb = pb_lp_lc / 5; @@ -132,13 +132,13 @@ steps: - Without an ARM thumb filter: - ``` {.bash} + ```bash unlzma --lzma2 --format=raw --suffix=.lzma raw.lzma ``` - With an ARM thumb filter: - ``` {.bash} + ```bash unlzma --armthumb --lzma2 --format=raw --suffix=.lzma raw.lzma ``` From 639a1ec4ceaca08804de066e502979832e17523f Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Sun, 23 Feb 2025 23:15:51 +0100 Subject: [PATCH 019/204] sim: Make TLV size for ECDSA signature constant ECDSA signatures are encoded as ASN.1 and the size of the ASN.1 representation can vary depending on the value of the two integers the signature is composed of. This means that when ECDSA is used, the size of the TLV area is not always equal to the size that was estimated by the simulator when attempting to determine the maximum image size. Indeed, the estimate gives the maximum possible size of the TLV area and depending on its actual size, the generated images might be in fact a bit smaller than expected. This is not a big issue but adds a bit of randomness in the simulation and make difficult to generate precisely oversized images when desired for example. This commit ensures an ECDSA signature with the largest possible size is always used, making the size of the corresponding TLV entry constant in the simulator. Signed-off-by: Thomas Altenbach --- sim/src/tlv.rs | 80 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs index ce6876e9d..d076eb237 100644 --- a/sim/src/tlv.rs +++ b/sim/src/tlv.rs @@ -579,20 +579,57 @@ impl ManifestGen for TlvGen { } if self.kinds.contains(&TlvKinds::ECDSASIG) { + let keyhash; + let key_bytes; + let sign_algo; + let key_pair; + let keyhash_size; + let max_sig_size; + + if self.kinds.contains(&TlvKinds::SHA384) { + keyhash = digest::digest(&digest::SHA384, ECDSAP384_PUB_KEY); + keyhash_size = 48; + key_bytes = pem::parse(include_bytes!("../../root-ec-p384-pkcs8.pem").as_ref()).unwrap(); + sign_algo = &ECDSA_P384_SHA384_ASN1_SIGNING; + key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); + max_sig_size = 104; // 96 bytes for "raw" r and s + at most 8 bytes for ASN.1 encoding + } else { + keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY); + keyhash_size = 32; + key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap(); + sign_algo = &ECDSA_P256_SHA256_ASN1_SIGNING; + key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); + max_sig_size = 72; // 64 bytes for "raw" r and s + at most 8 bytes for ASN.1 encoding + } + + // ECDSA signatures are encoded as ASN.1 with the r and s values stored as signed + // integers. As such, the size can vary depending on the value of the high bits of r and + // s. The maximum size is obtained when the high bit of both r and s is '1'. To generate + // the largest possible image, the size of the TLV area was estimated assuming the + // signature has the maximal size. To obtain a TLV area size exactly equal to the + // estimated size, the signing process is repeated multiple times until a signature + // having the largest possible size is obtained. This is taking advantage of the fact + // ECDSA signing uses a randomly-generated nonce and is therefore non-deterministic. + // Theoretically, four tries should be needed on average and the probability of not + // having obtained a signature of the desired size after 100 tries is lower than 10e-12. let rng = rand::SystemRandom::new(); - let (signature, keyhash, keyhash_size) = if self.kinds.contains(&TlvKinds::SHA384) { - let keyhash = digest::digest(&digest::SHA384, ECDSAP384_PUB_KEY); - let key_bytes = pem::parse(include_bytes!("../../root-ec-p384-pkcs8.pem").as_ref()).unwrap(); - let sign_algo = &ECDSA_P384_SHA384_ASN1_SIGNING; - let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); - (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash, 48) - } else { - let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY); - let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap(); - let sign_algo = &ECDSA_P256_SHA256_ASN1_SIGNING; - let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); - (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash, 32) - }; + let max_tries = 100; + let mut signature; + let mut tries = 0; + + loop { + signature = key_pair.sign(&rng, &sig_payload).unwrap(); + + if signature.as_ref().len() == max_sig_size { + break; + } + + tries += 1; + + if tries >= max_tries { + panic!("Failed to generate signature of correct size"); + } + } // Write public key let keyhash_slice = keyhash.as_ref(); @@ -781,23 +818,8 @@ impl ManifestGen for TlvGen { let mut size_buf = &mut result[npro_pos + 2 .. npro_pos + 4]; size_buf.write_u16::(size).unwrap(); - // ECDSA is stored as an ASN.1 integer. For a 128-bit value, this maximally results in 33 - // bytes of storage for each of the two values. If the high bit is zero, it will take 32 - // bytes, if the top 8 bits are zero, it will take 31 bits, and so on. The smaller size - // will occur with decreasing likelihood. We'll allow this to get a bit smaller, hopefully - // allowing the tests to pass with false failures rare. For this case, we'll handle up to - // the top 16 bits of both numbers being all zeros (1 in 2^32). - if !Caps::has_ecdsa() { - if size_estimate != result.len() { - panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len()); - } - } else { - if size_estimate < result.len() || size_estimate > result.len() + 6 { - panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len()); - } - } if size_estimate != result.len() { - log::warn!("Size off: {} actual {}", size_estimate, result.len()); + panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len()); } result From 66c21afc5e019319eed391f4dfda375aac74e443 Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Sun, 23 Feb 2025 23:18:03 +0100 Subject: [PATCH 020/204] sim: Generate smallest possible oversized image To generate oversized, the simulator needs to know the maximum image size. To obtain such size, the size of the TLV area is estimated and when using ECDSA, the actual size of the TLV area in the generated image was not always equal to the estimated size. This required to add a bit more data than what should be necessary when creating oversized images, to ensure the generated images will actually be oversized in most cases. Thanks to the previous commit, this is no more necessary and it is now possible to reliably generate oversized images with the smallest size. Signed-off-by: Thomas Altenbach --- sim/src/image.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sim/src/image.rs b/sim/src/image.rs index 0aafd1563..b8d121a13 100644 --- a/sim/src/image.rs +++ b/sim/src/image.rs @@ -1884,9 +1884,8 @@ fn install_image(flash: &mut SimMultiFlash, areadesc: &AreaDesc, slot: &SlotInfo info!("slot: 0x{:x}, HDR: 0x{:x}, trailer: 0x{:x}", slot_len, HDR_SIZE, trailer); - // the overflow size is rougly estimated to work for all - // configurations. It might be precise if tlv_len will be maked precise. - slot_len - HDR_SIZE - trailer - tlv_len - sector_offset + dev.align()*4 + + slot_len - HDR_SIZE - trailer - tlv_len - sector_offset + dev.align() } }; From 88294be188c25e4b7d02cc9c55fabfc9286c83b7 Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Sun, 23 Feb 2025 20:33:14 +0100 Subject: [PATCH 021/204] sim: Fix incorrect trailer size computation for overwrite-only For the overwrite-only upgrade strategy, the trailer size computed by the simulator and used to determine the maximum image size was not correct. This commit fixes the issue. Having an underestimated trailer size was causing the 'oversized_secondary_slot' to fail since the previous commit, because the oversized images are now generated to have the smallest possible size. Signed-off-by: Thomas Altenbach --- sim/src/image.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sim/src/image.rs b/sim/src/image.rs index b8d121a13..dcea8c577 100644 --- a/sim/src/image.rs +++ b/sim/src/image.rs @@ -1805,9 +1805,8 @@ fn image_largest_trailer(dev: &dyn Flash, areadesc: &AreaDesc, slot: &SlotInfo) // Using the header size we know, the trailer size, and the slot size, we can compute // the largest image possible. let trailer = if Caps::OverwriteUpgrade.present() { - // This computation is incorrect, and we need to figure out the correct size. - // c::boot_status_sz(dev.align() as u32) as usize - 16 + 4 * dev.align() + // magic + image-ok + copy-done + swap-info + c::boot_magic_sz() + 3 * c::boot_max_align() } else if Caps::SwapUsingOffset.present() || Caps::SwapUsingMove.present() { let sector_size = dev.sector_iter().next().unwrap().size as u32; align_up(c::boot_trailer_sz(dev.align() as u32), sector_size) as usize From 993c2ff8d2fe3fccfc2b7e93cf6e575ddeaa03bf Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 24 Mar 2025 20:36:21 -0700 Subject: [PATCH 022/204] boot/bootutil/ram_load: Add flash area pointer to bootloader state Since 1b2fc096d9a683a7481b13749d01ca8fa78e7afd, many places now reuse the flash area pointer from the bootloader state. Unfortunately, some RAM load usage (on single loader or runtime-source sample) didn't set up the flash area pointer on the bootloader state, so they were broken. This patch fixes that by adding the flash area pointer to the created bootloader states - directly or via a new parameter to boot_load_image_from_flash_to_sram(). Signed-off-by: Ederson de Souza --- boot/bootutil/include/bootutil/bootutil_public.h | 4 +++- boot/bootutil/src/ram_load.c | 4 +++- boot/zephyr/single_loader.c | 1 + samples/runtime-source/zephyr/hooks/hooks.c | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/include/bootutil/bootutil_public.h b/boot/bootutil/include/bootutil/bootutil_public.h index bbfb729a3..e2795ab3e 100644 --- a/boot/bootutil/include/bootutil/bootutil_public.h +++ b/boot/bootutil/include/bootutil/bootutil_public.h @@ -319,11 +319,13 @@ boot_image_load_header(const struct flash_area *fa_p, * * @param[in] state boot loader state * @param[in] hdr image header + * @param[in] fa flash area pointer * * @return 0 on success, error code otherwise */ int boot_load_image_from_flash_to_sram(struct boot_loader_state *state, - struct image_header *hdr); + struct image_header *hdr, + const struct flash_area *fa); /** * Removes an image from SRAM, by overwriting it with zeros. diff --git a/boot/bootutil/src/ram_load.c b/boot/bootutil/src/ram_load.c index e3a75d635..91d8a04a8 100644 --- a/boot/bootutil/src/ram_load.c +++ b/boot/bootutil/src/ram_load.c @@ -419,7 +419,8 @@ boot_remove_image_from_flash(struct boot_loader_state *state, uint32_t slot) } int boot_load_image_from_flash_to_sram(struct boot_loader_state *state, - struct image_header *hdr) + struct image_header *hdr, + const struct flash_area *fap) { int active_slot; @@ -428,6 +429,7 @@ int boot_load_image_from_flash_to_sram(struct boot_loader_state *state, */ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot; BOOT_IMG(state, active_slot).hdr = *hdr; + BOOT_IMG_AREA(state, active_slot) = fap; return boot_load_image_to_sram(state); } diff --git a/boot/zephyr/single_loader.c b/boot/zephyr/single_loader.c index 382f81eaa..28e9cdf15 100644 --- a/boot/zephyr/single_loader.c +++ b/boot/zephyr/single_loader.c @@ -121,6 +121,7 @@ boot_go(struct boot_rsp *rsp) #ifdef MCUBOOT_RAM_LOAD static struct boot_loader_state state; + BOOT_IMG_AREA(&state, 0) = _fa_p; state.imgs[0][0].hdr = _hdr; rc = boot_load_image_to_sram(&state); diff --git a/samples/runtime-source/zephyr/hooks/hooks.c b/samples/runtime-source/zephyr/hooks/hooks.c index 849ce8014..1bc88d094 100644 --- a/samples/runtime-source/zephyr/hooks/hooks.c +++ b/samples/runtime-source/zephyr/hooks/hooks.c @@ -72,7 +72,7 @@ fih_ret boot_go_hook(struct boot_rsp *rsp) #ifdef MCUBOOT_RAM_LOAD state = boot_get_loader_state(); - rc = boot_load_image_from_flash_to_sram(state, &_hdr); + rc = boot_load_image_from_flash_to_sram(state, &_hdr, _fa_p); if (rc != 0) { flash_area_close(_fa_p); continue; From 881608eb3ef222150adb90390536e8320d16fe31 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 24 Mar 2025 20:36:39 -0700 Subject: [PATCH 023/204] boot/zephyr: Use MCUBOOT_RAM_LOAD instead of CONFIG_BOOT_RAM_LOAD This will encompass both CONFIG_BOOT_RAM_LOAD and CONFIG_SINGLE_APPLICATION_SLOT_RAM_LOAD, which, at this point, should follow the same code path - load image to RAM. Signed-off-by: Ederson de Souza --- boot/zephyr/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 683b2f7f5..a46fc724c 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -154,7 +154,7 @@ static void do_boot(struct boot_rsp *rsp) * consecutively. Manually set the stack pointer and jump into the * reset vector */ -#ifdef CONFIG_BOOT_RAM_LOAD +#ifdef MCUBOOT_RAM_LOAD /* Get ram address for image */ vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr + rsp->br_hdr->ih_hdr_size); #else @@ -576,7 +576,7 @@ int main(void) FIH_PANIC; } -#ifdef CONFIG_BOOT_RAM_LOAD +#ifdef MCUBOOT_RAM_LOAD BOOT_LOG_INF("Bootloader chainload address offset: 0x%x", rsp.br_hdr->ih_load_addr); #else From 33ad4973a1505c2823b15e667ee0e8ca59bdd2c7 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Thu, 27 Mar 2025 12:56:36 -0400 Subject: [PATCH 024/204] boot: zephyr: add support for mcx_n9xx_evk Add default configuration for mcx_n9xx_evk. Signed-off-by: Derek Snell --- boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0.conf | 5 +++++ .../boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.conf | 4 ++++ .../boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay | 12 ++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0.conf create mode 100644 boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.conf create mode 100644 boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay diff --git a/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0.conf b/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0.conf new file mode 100644 index 000000000..ef44ad314 --- /dev/null +++ b/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0.conf @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +#MCXN94x does not support the MCUBoot swap mode. +CONFIG_BOOT_UPGRADE_ONLY=y diff --git a/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.conf b/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.conf new file mode 100644 index 000000000..638b3f72e --- /dev/null +++ b/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.conf @@ -0,0 +1,4 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BOOT_UPGRADE_ONLY=y diff --git a/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay b/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay new file mode 100644 index 000000000..bcc8bd98a --- /dev/null +++ b/boot/zephyr/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay @@ -0,0 +1,12 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &flash; + zephyr,code-partition = &boot_partition; + }; +}; From ed434f33d91a5f215cd318fc3dbdcba55f1151c7 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 31 Mar 2025 13:03:24 +0100 Subject: [PATCH 025/204] boot: bootutil: Fix clash of STRUCT_PACKED definition Fixes an issue whereby another module might have declared this by undefining it if it's already set Signed-off-by: Jamie McCrae --- boot/bootutil/include/bootutil/image.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index f5431b187..15de3e01a 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -36,10 +36,14 @@ extern "C" { #endif +#if defined(STRUCT_PACKED) +#undef STRUCT_PACKED +#endif + #if defined(__IAR_SYSTEMS_ICC__) - #define STRUCT_PACKED __packed struct +#define STRUCT_PACKED __packed struct #else - #define STRUCT_PACKED struct __attribute__((__packed__)) +#define STRUCT_PACKED struct __attribute__((__packed__)) #endif struct flash_area; From 091af82edb0c04e082c16846e6163d555b93101d Mon Sep 17 00:00:00 2001 From: Michal Kozikowski Date: Fri, 28 Mar 2025 15:18:38 +0100 Subject: [PATCH 026/204] boot/zephyr: nrf54h20dk adaptations Added basic adaptations needed for introducing nrf54h20dk board support in the future. Signed-off-by: Michal Kozikowski --- boot/zephyr/Kconfig | 1 + boot/zephyr/flash_map_extended.c | 6 ++++++ boot/zephyr/include/mcuboot_config/mcuboot_config.h | 3 +++ boot/zephyr/include/target.h | 4 +++- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 988c329c8..be6651557 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -924,6 +924,7 @@ config BOOT_WATCHDOG_FEED_NRFX_WDT imply NRFX_WDT1 imply NRFX_WDT30 imply NRFX_WDT31 + imply NRFX_WDT010 config BOOT_IMAGE_ACCESS_HOOKS bool "Enable hooks for overriding MCUboot's native routines" diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index 1cc53f2f5..f577c33a5 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -36,6 +36,12 @@ BOOT_LOG_MODULE_DECLARE(mcuboot); #define FLASH_DEVICE_BASE 0 #define FLASH_DEVICE_NODE DT_CHOSEN(zephyr_flash_controller) +#elif (defined(CONFIG_SOC_SERIES_NRF54HX) && DT_HAS_CHOSEN(zephyr_flash)) + +#define FLASH_DEVICE_ID SPI_FLASH_0_ID +#define FLASH_DEVICE_BASE CONFIG_FLASH_BASE_ADDRESS +#define FLASH_DEVICE_NODE DT_CHOSEN(zephyr_flash) + #else #error "FLASH_DEVICE_ID could not be determined" #endif diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index d4d718c39..fd003565a 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -422,6 +422,9 @@ #elif defined(CONFIG_NRFX_WDT31) #define MCUBOOT_WATCHDOG_FEED() \ FEED_WDT_INST(31); +#elif defined(CONFIG_NRFX_WDT010) +#define MCUBOOT_WATCHDOG_FEED() \ + FEED_WDT_INST(010); #else #error "No NRFX WDT instances enabled" #endif diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h index 9bbfd4b19..ea160752e 100644 --- a/boot/zephyr/include/target.h +++ b/boot/zephyr/include/target.h @@ -30,9 +30,11 @@ /* * Sanity check the target support. */ -#if (!defined(CONFIG_XTENSA) && !DT_HAS_CHOSEN(zephyr_flash_controller)) || \ +#if (!defined(CONFIG_XTENSA) && !defined(CONFIG_SOC_SERIES_NRF54HX) && \ + !DT_HAS_CHOSEN(zephyr_flash_controller)) || \ (defined(CONFIG_XTENSA) && !DT_NODE_EXISTS(DT_INST(0, jedec_spi_nor)) && \ !defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32)) || \ + (defined(CONFIG_SOC_SERIES_NRF54HX) && !DT_HAS_CHOSEN(zephyr_flash)) || \ !defined(FLASH_ALIGN) || \ !(FIXED_PARTITION_EXISTS(slot0_partition)) || \ !(FIXED_PARTITION_EXISTS(slot1_partition) || CONFIG_SINGLE_APPLICATION_SLOT) || \ From 6678c37cfcecd762b494628e50000d25ccccbf51 Mon Sep 17 00:00:00 2001 From: "Guillaume G." Date: Mon, 17 Mar 2025 13:28:22 +0100 Subject: [PATCH 027/204] imgtool: dumpinfo: Avoid exit and use return Signed-off-by: Guillaume G. --- scripts/imgtool/dumpinfo.py | 2 +- scripts/imgtool/main.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/imgtool/dumpinfo.py b/scripts/imgtool/dumpinfo.py index 55446574c..40ece79f1 100644 --- a/scripts/imgtool/dumpinfo.py +++ b/scripts/imgtool/dumpinfo.py @@ -251,7 +251,7 @@ def dump_imginfo(imgfile, outfile=None, silent=False): ############################################################################### if silent: - sys.exit(0) + return print("Printing content of signed image:", os.path.basename(imgfile), "\n") diff --git a/scripts/imgtool/main.py b/scripts/imgtool/main.py index 28caa8947..1cdb792a5 100755 --- a/scripts/imgtool/main.py +++ b/scripts/imgtool/main.py @@ -259,7 +259,8 @@ def verify(key, imgfile): 'of a signed image') def dumpinfo(imgfile, outfile, silent): dump_imginfo(imgfile, outfile, silent) - print("dumpinfo has run successfully") + if not silent: + print("dumpinfo has run successfully") def validate_version(ctx, param, value): From 572b8fb2cd5c6e8bf9e4a439e31f280cb9bde958 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 4 Apr 2025 08:50:17 +0100 Subject: [PATCH 028/204] boot: zephyr: flash_map_extended: Add pointless workaround for clang Clang wrongly throws a warning, which will be treated as an error in twister builds, add pointless workaround to set variable that is already set by the hook function to avoid this Signed-off-by: Jamie McCrae --- boot/zephyr/flash_map_extended.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index f577c33a5..b2e96cb3f 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -66,7 +66,8 @@ int flash_device_base(uint8_t fd_id, uintptr_t *ret) */ int flash_area_id_from_multi_image_slot(int image_index, int slot) { - int rc, id; + int rc; + int id = -1; rc = BOOT_HOOK_FLASH_AREA_CALL(flash_area_id_from_multi_image_slot_hook, BOOT_HOOK_REGULAR, image_index, slot, &id); From 6b272e209439375f141b0f9f4537ac8448b51437 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Sun, 6 Apr 2025 15:31:56 +0200 Subject: [PATCH 029/204] mynewt: Start watchdog when enable by syscfg Code implied that WATCHDOG_INTERVAL will enable watchdog in bootloader however it never did hal_watchdog_init sets up some watchdog data but for most mcu is does not start watchdog. Now hal_watchdog_enable() is called when WATCHDOG_INTERVAL is set to non zero as git history suggested . Signed-off-by: Jerzy Kasenberg --- boot/mynewt/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/mynewt/src/main.c b/boot/mynewt/src/main.c index 7a3fa2e10..9c92c019b 100755 --- a/boot/mynewt/src/main.c +++ b/boot/mynewt/src/main.c @@ -226,6 +226,7 @@ mynewt_main(void) #if !MYNEWT_VAL(OS_SCHEDULING) && MYNEWT_VAL(WATCHDOG_INTERVAL) rc = hal_watchdog_init(MYNEWT_VAL(WATCHDOG_INTERVAL)); assert(rc == 0); + hal_watchdog_enable(); #endif #if defined(MCUBOOT_SERIAL) || defined(MCUBOOT_HAVE_LOGGING) || \ From f2b076cb75c6631b046791c89200d939d9985919 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 24 Mar 2025 10:33:53 +0100 Subject: [PATCH 030/204] boot/mynewt: remove redundant mbedtls flag and enable CTR Now flag defining config file for MbedTLS is global (see https://github.com/apache/mynewt-core/pull/3394), so we do not have to include the same flag in bootutil package. This also enables MBEDTLS_CIPHER_MODE_CTR in boot_serial test package, as it is used in unit tests and it is disabled by default. Signed-off-by: Michal Gorecki --- boot/boot_serial/test/syscfg.yml | 3 +++ boot/bootutil/pkg.yml | 3 --- ci/mynewt_keys/enc_rsa/pkg.yml | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/boot/boot_serial/test/syscfg.yml b/boot/boot_serial/test/syscfg.yml index ff841d626..07baa9979 100644 --- a/boot/boot_serial/test/syscfg.yml +++ b/boot/boot_serial/test/syscfg.yml @@ -21,3 +21,6 @@ syscfg.vals: # This is here to work around the $notnull syscfg restriction. BOOT_SERIAL_DETECT_PIN: 0 + +syscfg.vals.BOOTUTIL_USE_MBED_TLS: + MBEDTLS_CIPHER_MODE_CTR: 1 diff --git a/boot/bootutil/pkg.yml b/boot/bootutil/pkg.yml index 4a7fabc1c..c5d713b69 100644 --- a/boot/bootutil/pkg.yml +++ b/boot/bootutil/pkg.yml @@ -31,9 +31,6 @@ pkg.apis: pkg.cflags: - "-DMCUBOOT_MYNEWT=1" -pkg.cflags.BOOTUTIL_USE_MBED_TLS: - - '-DMBEDTLS_USER_CONFIG_FILE="mbedtls/config_mynewt.h"' - pkg.deps: - "@mcuboot/boot/mynewt/mcuboot_config" - "@apache-mynewt-core/hw/hal" diff --git a/ci/mynewt_keys/enc_rsa/pkg.yml b/ci/mynewt_keys/enc_rsa/pkg.yml index 61918f1b4..619832c54 100644 --- a/ci/mynewt_keys/enc_rsa/pkg.yml +++ b/ci/mynewt_keys/enc_rsa/pkg.yml @@ -20,6 +20,3 @@ pkg.name: keys/enc_rsa pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" - -pkg.cflags: - - '-DMBEDTLS_USER_CONFIG_FILE="mbedtls/config_mynewt.h"' From 454c033fe7a54f0e97a8f2fce42c12c1aeec4ef1 Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Tue, 8 Apr 2025 13:33:22 +0200 Subject: [PATCH 031/204] bootutil: swap-scratch: Fix conflicts after support of devices w/o erase Before the PR #2206 fixing issues in the swap-scratch logic when the trailer is larger than the last sector was merged, the PR #2114 was reverted (see #2211). This changes made by #2211 were then reapplied (see #2216) after #2206 was merged, leading to some conflicts: a call to swap_erase_trailer_sectors was moved by #2206 but the old call to that function was added back by #2216 and a new call to swap_erase_trailer_sectors was added by #2206 but not converted to a call to swap_scramble_trailer_sectors by #2216. Signed-off-by: Thomas Altenbach --- boot/bootutil/src/swap_scratch.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 03ccc028a..af4be88a6 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -665,7 +665,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, * trailer since in case the trailer spreads over multiple sector erasing the [img_off, * img_off + sz) might not erase the entire trailer. */ - rc = swap_erase_trailer_sectors(state, fap_secondary_slot); + rc = swap_scramble_trailer_sectors(state, fap_secondary_slot); assert(rc == 0); if (bs->use_scratch) { @@ -691,14 +691,6 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, img_off, img_off, copy_sz); assert(rc == 0); - if (bs->idx == BOOT_STATUS_IDX_0 && !bs->use_scratch) { - /* If not all sectors of the slot are being swapped, - * guarantee here that only the primary slot will have the state. - */ - rc = swap_scramble_trailer_sectors(state, fap_secondary_slot); - assert(rc == 0); - } - rc = boot_write_status(state, bs); bs->state = BOOT_STATUS_STATE_2; BOOT_STATUS_ASSERT(rc == 0); @@ -713,7 +705,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, * able to write the new trailer. This is not always equivalent to erasing the [img_off, * img_off + sz) range when the trailer spreads across multiple sectors. */ - rc = swap_erase_trailer_sectors(state, fap_primary_slot); + rc = swap_scramble_trailer_sectors(state, fap_primary_slot); assert(rc == 0); /* Ensure the sector(s) containing the beginning of the trailer won't be erased twice */ From 5aed424531d178ad5a678ee0a760e8bc2c234a0e Mon Sep 17 00:00:00 2001 From: Robert Wolff Date: Tue, 8 Apr 2025 17:03:13 -0700 Subject: [PATCH 032/204] swap_move: correct appsize calcs and warning app_max_sectors() is always off by one in its calculation. This corrects that calculation as well as the warning which should only be comparing the two slot sector counts and checking to see if they are different by one sector for the swap sector. The size of the application is not relevant in that warning for optimal sector distribution. Additionally app_max_size() suffers similarly in that it is not taking into account the fact that the secondary slot does also contain a trailer. Finally makes a minor addition to the design document which further clarifies the primary and secondary partition size differences. Signed-off-by: Robert Wolff --- boot/bootutil/src/swap_move.c | 10 ++++++---- docs/design.md | 6 ++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 841cd4d34..42ba7a667 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -236,7 +236,8 @@ static int app_max_sectors(struct boot_loader_state *state) sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); - first_trailer_idx = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 1; + /* subtract 1 for swap and at least 1 for trailer */ + first_trailer_idx = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 2; while (1) { sz += sector_sz; @@ -276,9 +277,10 @@ boot_slots_compatible(struct boot_loader_state *state) return 0; } - if (num_usable_sectors_pri != (num_sectors_sec + 1)) { + /* Optimal says primary has one more than secondary. Always. Both have trailers. */ + if (num_sectors_pri != (num_sectors_sec + 1)) { BOOT_LOG_DBG("Non-optimal sector distribution, slot0 has %d usable sectors (%d assigned) " - "but slot1 has %d assigned", (int)(num_usable_sectors_pri - 1), + "but slot1 has %d assigned", (int)num_usable_sectors_pri, (int)num_sectors_pri, (int)num_sectors_sec); } @@ -598,7 +600,7 @@ int app_max_size(struct boot_loader_state *state) /* Account for image flags and move sector */ sz_primary = app_max_sectors(state) * sector_sz_primary - sector_sz_primary; - sz_secondary = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz_secondary; + sz_secondary = app_max_sectors(state) * sector_sz_secondary; return (sz_primary <= sz_secondary ? sz_primary : sz_secondary); } diff --git a/docs/design.md b/docs/design.md index 8b2e3ea2a..66fcd45f9 100755 --- a/docs/design.md +++ b/docs/design.md @@ -314,6 +314,12 @@ Where: is equal to 1056 B and the sector size is equal to 1024 B, then `image-trailer-sectors-size` will be equal to 2048 B. +This does imply, if there is any doubt, that the primary slot will be exactly +one sector larger than the secondary slot due to the swap sector alone. It is +the case that both the primary and secondary slots both have a trailer in +addition to the application payload and these trailers are identical in size +to one another. + The algorithm does two erase cycles on the primary slot and one on the secondary slot during each swap. Assuming that receiving a new image by the DFU application requires 1 erase cycle on the secondary slot, this should result in From de7a9dc59fd5d9266d901634c7edffdc8d144e34 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 9 Apr 2025 12:23:18 +0000 Subject: [PATCH 033/204] zephyr: Disable SPI_NOR by default for nrf7002dk/nrf5340/cpuapp The change allows to build MCUboot for nrf7002dk/nrf5340/cpuapp with default configuration. Co-authored-by: Sigurd Hellesvik Signed-off-by: Dominik Ermel --- boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf diff --git a/boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf b/boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 000000000..b37be6f10 --- /dev/null +++ b/boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,5 @@ +# By default no external SPI device is used for image storage, +# so SPI-NOR is not needed. This reduces size of MCUboot, remember +# though that when external image is needed the CONFIG_SPI_NOR +# has to be enabled. +CONFIG_SPI_NOR=n From 8a9627d9cfc77b154e221dbdb41c7993729b6449 Mon Sep 17 00:00:00 2001 From: Michal Kozikowski Date: Thu, 10 Apr 2025 11:40:33 +0200 Subject: [PATCH 034/204] boot/zephyr/boards: nrf54h20dk 'iron' board configuration Added configuration for the nRF54H20 DK 'iron' board variant. Signed-off-by: Michal Kozikowski --- .../boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf diff --git a/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf b/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf new file mode 100644 index 000000000..50d349255 --- /dev/null +++ b/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Ensure that the SPI NOR driver is disabled by default +CONFIG_SPI_NOR=n + +CONFIG_BOOT_WATCHDOG_FEED=n + +CONFIG_MULTITHREADING=y From 7a33bcaa7853b7a6b606ab0d5b49e48582e65cb3 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 11 Apr 2025 11:08:21 +0100 Subject: [PATCH 035/204] boot: bootutil: loader: Add include for flash function Adds an include which provides a definition for the flash_area_get_sector() function Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index adc93b88b..9c98da30c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -36,6 +36,7 @@ #include #include #include +#include "flash_map_backend/flash_map_backend.h" #include "bootutil/bootutil.h" #include "bootutil/bootutil_public.h" #include "bootutil/image.h" From 20f98e0a975c24864872e0df5701eb1082e9c957 Mon Sep 17 00:00:00 2001 From: David Brown Date: Fri, 4 Apr 2025 10:23:48 -0600 Subject: [PATCH 036/204] Updates for 2.2.0-rc1 release Consolidate the release notes, and update various release files. Signed-off-by: David Brown --- README.md | 2 +- docs/release-notes.d/bootutil-enc-hw-keys.md | 2 - .../bootutil-image-verification.md | 4 -- docs/release-notes.d/compatible-slots.md | 7 -- .../encrypted-scratch-partition.md | 3 - .../espressif-idf-version-checking.md | 3 - docs/release-notes.d/fix-nordic.md | 2 - .../fix-ram-load-zephyr-address.md | 2 - docs/release-notes.d/fix-stuck-revert.md | 3 - .../fix-zephyr-sysbuild-name.md | 2 - docs/release-notes.d/imgtool_sanity_test.md | 2 - docs/release-notes.d/max-app-size-changes.md | 4 -- docs/release-notes.d/serial-recovery-list.md | 3 - .../serial-recovery-slot-info.md | 1 - docs/release-notes.d/serial-recovery-var.md | 3 - docs/release-notes.d/swap-using-offset.md | 6 -- .../zephyr-auto-max-sectors.md | 5 -- docs/release-notes.d/zephyr-compression.md | 7 -- docs/release-notes.md | 64 +++++++++++++++++++ repository.yml | 5 +- scripts/imgtool/__init__.py | 2 +- 21 files changed, 69 insertions(+), 63 deletions(-) delete mode 100644 docs/release-notes.d/bootutil-enc-hw-keys.md delete mode 100644 docs/release-notes.d/bootutil-image-verification.md delete mode 100644 docs/release-notes.d/compatible-slots.md delete mode 100644 docs/release-notes.d/encrypted-scratch-partition.md delete mode 100644 docs/release-notes.d/espressif-idf-version-checking.md delete mode 100644 docs/release-notes.d/fix-nordic.md delete mode 100644 docs/release-notes.d/fix-ram-load-zephyr-address.md delete mode 100644 docs/release-notes.d/fix-stuck-revert.md delete mode 100644 docs/release-notes.d/fix-zephyr-sysbuild-name.md delete mode 100644 docs/release-notes.d/imgtool_sanity_test.md delete mode 100644 docs/release-notes.d/max-app-size-changes.md delete mode 100644 docs/release-notes.d/serial-recovery-list.md delete mode 100644 docs/release-notes.d/serial-recovery-slot-info.md delete mode 100644 docs/release-notes.d/serial-recovery-var.md delete mode 100644 docs/release-notes.d/swap-using-offset.md delete mode 100644 docs/release-notes.d/zephyr-auto-max-sectors.md delete mode 100644 docs/release-notes.d/zephyr-compression.md diff --git a/README.md b/README.md index 8473fc40c..e554ba488 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ [travis]: https://travis-ci.org/mcu-tools/mcuboot [license]: https://github.com/mcu-tools/mcuboot/blob/main/LICENSE -This is MCUboot version 2.1.0 +This is MCUboot version 2.2.0-rc1 MCUboot is a secure bootloader for 32-bits microcontrollers. It defines a common infrastructure for the bootloader and the system flash layout on diff --git a/docs/release-notes.d/bootutil-enc-hw-keys.md b/docs/release-notes.d/bootutil-enc-hw-keys.md deleted file mode 100644 index 2640b6772..000000000 --- a/docs/release-notes.d/bootutil-enc-hw-keys.md +++ /dev/null @@ -1,2 +0,0 @@ -- Added support for retrieving hw embed private keys for image encryption - (The private key can be retrieved from trusted sources like OTP, TPM.). diff --git a/docs/release-notes.d/bootutil-image-verification.md b/docs/release-notes.d/bootutil-image-verification.md deleted file mode 100644 index a1cc58842..000000000 --- a/docs/release-notes.d/bootutil-image-verification.md +++ /dev/null @@ -1,4 +0,0 @@ -- Changed bootutil's order of events to verify the image header - before checking the image. -- Added the bootloader state object to the bootutil - boot_is_header_valid() function diff --git a/docs/release-notes.d/compatible-slots.md b/docs/release-notes.d/compatible-slots.md deleted file mode 100644 index 4cbae1818..000000000 --- a/docs/release-notes.d/compatible-slots.md +++ /dev/null @@ -1,7 +0,0 @@ -- Added optional write block size checking to ensure expected - sizes match what is available on the hardware. -- Added optional erase size checking to ensure expected sizes - match what is available on the hardware. -- Added debug logs for zephyr to output discrepencies in erase - and write block sizes in dts vs actual hardware configuration - at run-time. diff --git a/docs/release-notes.d/encrypted-scratch-partition.md b/docs/release-notes.d/encrypted-scratch-partition.md deleted file mode 100644 index ea5160594..000000000 --- a/docs/release-notes.d/encrypted-scratch-partition.md +++ /dev/null @@ -1,3 +0,0 @@ -- When using swap with scratch, the image is now decrypted when copying from - the scratch partition to the primary slot. Therefore, the sratch partition - doesn't contain plaintext firmware data anymore. diff --git a/docs/release-notes.d/espressif-idf-version-checking.md b/docs/release-notes.d/espressif-idf-version-checking.md deleted file mode 100644 index ff12912c7..000000000 --- a/docs/release-notes.d/espressif-idf-version-checking.md +++ /dev/null @@ -1,3 +0,0 @@ -- Added verification for supported IDF-based HAL version. -- Fixed missing macro for XMC flash devices on ESP32-S3 -- Extended image loader header to include RTC/LP RAM, DROM and IROM segments. diff --git a/docs/release-notes.d/fix-nordic.md b/docs/release-notes.d/fix-nordic.md deleted file mode 100644 index 9706f8abc..000000000 --- a/docs/release-notes.d/fix-nordic.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fixed errors when building for ``thingy52``, ``thingy53`` and - ``nrf9160dk`` boards. diff --git a/docs/release-notes.d/fix-ram-load-zephyr-address.md b/docs/release-notes.d/fix-ram-load-zephyr-address.md deleted file mode 100644 index c636bc96b..000000000 --- a/docs/release-notes.d/fix-ram-load-zephyr-address.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fixed chain load address output log message for RAM load - mode in Zephyr diff --git a/docs/release-notes.d/fix-stuck-revert.md b/docs/release-notes.d/fix-stuck-revert.md deleted file mode 100644 index a49cd3bc8..000000000 --- a/docs/release-notes.d/fix-stuck-revert.md +++ /dev/null @@ -1,3 +0,0 @@ -- Fixed issue for swap using move whereby a device could get - stuck in a revert loop despite there being no image in the - secondary slot diff --git a/docs/release-notes.d/fix-zephyr-sysbuild-name.md b/docs/release-notes.d/fix-zephyr-sysbuild-name.md deleted file mode 100644 index 1e241b6d7..000000000 --- a/docs/release-notes.d/fix-zephyr-sysbuild-name.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fixed clash when using sysbuild with other - applications (i.e. tests) using the name sysbuild diff --git a/docs/release-notes.d/imgtool_sanity_test.md b/docs/release-notes.d/imgtool_sanity_test.md deleted file mode 100644 index 512392141..000000000 --- a/docs/release-notes.d/imgtool_sanity_test.md +++ /dev/null @@ -1,2 +0,0 @@ -- imgtool: added initial sanity tests for imgtool commands, -- imgtool: added and enabled unittests in GitGub workflow, diff --git a/docs/release-notes.d/max-app-size-changes.md b/docs/release-notes.d/max-app-size-changes.md deleted file mode 100644 index 21d25dbc1..000000000 --- a/docs/release-notes.d/max-app-size-changes.md +++ /dev/null @@ -1,4 +0,0 @@ -- Fixed wrong maximum application size calculation when - operating in swap using move mode -- Added additional images max size support to shared data - function diff --git a/docs/release-notes.d/serial-recovery-list.md b/docs/release-notes.d/serial-recovery-list.md deleted file mode 100644 index 4431441de..000000000 --- a/docs/release-notes.d/serial-recovery-list.md +++ /dev/null @@ -1,3 +0,0 @@ -- Fixed issue with serial recovery image list wrongly using - number of images as the number of slots and not returning - complete information for 1 updateable image diff --git a/docs/release-notes.d/serial-recovery-slot-info.md b/docs/release-notes.d/serial-recovery-slot-info.md deleted file mode 100644 index fbd333502..000000000 --- a/docs/release-notes.d/serial-recovery-slot-info.md +++ /dev/null @@ -1 +0,0 @@ -- Added slot info command support to serial recovery mode diff --git a/docs/release-notes.d/serial-recovery-var.md b/docs/release-notes.d/serial-recovery-var.md deleted file mode 100644 index e86477ca8..000000000 --- a/docs/release-notes.d/serial-recovery-var.md +++ /dev/null @@ -1,3 +0,0 @@ -- Fixed issue with serial recovery variables not being - correctly initialised to default values which could cause - some commands to do unexpected operations diff --git a/docs/release-notes.d/swap-using-offset.md b/docs/release-notes.d/swap-using-offset.md deleted file mode 100644 index c36dc350d..000000000 --- a/docs/release-notes.d/swap-using-offset.md +++ /dev/null @@ -1,6 +0,0 @@ -- Added a new swap using offset algorithm which is set with - `MCUBOOT_SWAP_USING_OFFSET`. This algorithm is similar to swap - using move but avoids moving the sectors in the primary slot - up by having the update image written in the second sector in - the update slot, which offers a faster update process and - requires a smaller swap status area diff --git a/docs/release-notes.d/zephyr-auto-max-sectors.md b/docs/release-notes.d/zephyr-auto-max-sectors.md deleted file mode 100644 index a45aeb03f..000000000 --- a/docs/release-notes.d/zephyr-auto-max-sectors.md +++ /dev/null @@ -1,5 +0,0 @@ -- Added support for automatically calculating the maximum number - of sectors that are needed for a build by checking the erase - sizes of the partitions using CMake for Zephyr. This behaviour - can be reverted to the old manual behaviour by disabling - ``CONFIG_BOOT_MAX_IMG_SECTORS_AUTO`` diff --git a/docs/release-notes.d/zephyr-compression.md b/docs/release-notes.d/zephyr-compression.md deleted file mode 100644 index ba9ec2a7a..000000000 --- a/docs/release-notes.d/zephyr-compression.md +++ /dev/null @@ -1,7 +0,0 @@ -- Added protected TLV size to image size check in bootutil -- Added Kconfig for decompression support in Zephyr -- Added compressed image flags and TLV to bootutil -- Added support for removing images with conflicting flags in - bootutil -- Added support for removing encrypted/compressed images when - MCUboot is compiled without support for them diff --git a/docs/release-notes.md b/docs/release-notes.md index 728a5b4b2..e5480b9a6 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,6 +3,70 @@ - Table of Contents {:toc} +## Version 2.2.0 + +- Added support for retrieving HW embedded private keys for image encryption + (The private key can be retrieved from trusted sources like OTP, TPM.). +- Changed bootutil's order of events to verify the image header + before checking the image. +- Added the bootloader state object to the bootutil + boot_is_header_valid() function +- Added optional write block size checking to ensure expected + sizes match what is available on the hardware. +- Added optional erase size checking to ensure expected sizes + match what is available on the hardware. +- Added debug logs for zephyr to output discrepencies in erase + and write block sizes in dts vs actual hardware configuration + at run-time. +- When using swap with scratch, the image is now decrypted when copying from + the scratch partition to the primary slot. Therefore, the scratch partition + doesn't contain plaintext firmware data anymore. +- Added verification for supported IDF-based HAL version. +- Fixed missing macro for XMC flash devices on ESP32-S3 +- Extended image loader header to include RTC/LP RAM, DROM and IROM segments. +- Fixed errors when building for `thingy52`, `thingy53` and + `nrf9160dk` boards. +- Fixed chain load address output log message for RAM load + mode in Zephyr +- Fixed issue for swap using move whereby a device could get + stuck in a revert loop despite there being no image in the + secondary slot +- Fixed clash when using sysbuild with other + applications (i.e. tests) using the name mcuboot +- imgtool: added initial sanity tests for imgtool commands, +- imgtool: added and enabled unittests in GitGub workflow, +- Fixed wrong maximum application size calculation when + operating in swap using move mode +- Added additional images max size support to shared data + function +- Fixed issue with serial recovery image list wrongly using + number of images as the number of slots and not returning + complete information for 1 updateable image +- Added slot info command support to serial recovery mode +- Fixed issue with serial recovery variables not being + correctly initialised to default values which could cause + some commands to do unexpected operations +- Added a new swap using offset algorithm which is set with + `MCUBOOT_SWAP_USING_OFFSET`. This algorithm is similar to swap + using move but avoids moving the sectors in the primary slot + up by having the update image written in the second sector in + the update slot, which offers a faster update process and + requires a smaller swap status area +- Added support for automatically calculating the maximum number + of sectors that are needed for a build by checking the erase + sizes of the partitions using CMake for Zephyr. This behaviour + can be reverted to the old manual behaviour by disabling + `CONFIG_BOOT_MAX_IMG_SECTORS_AUTO` +- Added protected TLV size to image size check in bootutil +- Added Kconfig for decompression support in Zephyr +- Added compressed image flags and TLV to bootutil +- Added support for removing images with conflicting flags in + bootutil +- Added support for removing encrypted/compressed images when + MCUboot is compiled without support for them +- Added support for devices that do not require erase prior to write operation. +- Add corrections to the max app size calculations. + ## Version 2.1.0 - Boot serial: Add response to echo command if support is not diff --git a/repository.yml b/repository.yml index f69b44978..61fd17bf8 100644 --- a/repository.yml +++ b/repository.yml @@ -38,11 +38,12 @@ repo.versions: "1.10.0": "v1.10.0" "2.0.0": "v2.0.0" "2.1.0": "v2.1.0" + "2.2.0": "v2.2.0" "0-dev": "0.0.0" # main "0-latest": "2.1.0" # latest stable release "1-latest": "1.11.0" - "2-latest": "2.1.0" + "2-latest": "2.2.0" "1.0-latest": "1.11.0" - "2.0-latest": "2.1.0" + "2.0-latest": "2.2.0" diff --git a/scripts/imgtool/__init__.py b/scripts/imgtool/__init__.py index 421af3e41..c822b8463 100644 --- a/scripts/imgtool/__init__.py +++ b/scripts/imgtool/__init__.py @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -imgtool_version = "2.1.0" +imgtool_version = "2.2.0rc1" From efa30399324b51fa8defe587b9c220a0b56a9cdb Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 17 Apr 2025 11:17:15 +0100 Subject: [PATCH 037/204] boot: bootutil: swap_move: Fix maximum application size Fixes this function as it was not updated after an earlier fix Signed-off-by: Jamie McCrae --- boot/bootutil/src/swap_move.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 42ba7a667..fd91ad488 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -591,18 +591,10 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs, int app_max_size(struct boot_loader_state *state) { uint32_t sector_sz_primary; - uint32_t sector_sz_secondary; - uint32_t sz_primary; - uint32_t sz_secondary; sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); - sector_sz_secondary = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 0); - /* Account for image flags and move sector */ - sz_primary = app_max_sectors(state) * sector_sz_primary - sector_sz_primary; - sz_secondary = app_max_sectors(state) * sector_sz_secondary; - - return (sz_primary <= sz_secondary ? sz_primary : sz_secondary); + return app_max_sectors(state) * sector_sz_primary; } #endif From 6cbea0a242561bc31cf85d49c5e9c9b8df276b83 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 17 Apr 2025 13:02:46 +0100 Subject: [PATCH 038/204] boot: boot_serial: Fix swap using offset Fixes an issue with swap using offser with serial recovery by changing an #ifdef Signed-off-by: Jamie McCrae --- boot/boot_serial/src/boot_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c index a9c0630c8..4c9df65bf 100644 --- a/boot/boot_serial/src/boot_serial.c +++ b/boot/boot_serial/src/boot_serial.c @@ -290,7 +290,7 @@ bs_list(char *buf, int len) zcbor_list_start_encode(cbor_state, 5); image_index = 0; IMAGES_ITER(image_index) { -#ifdef MCUBOOT_SERIAL_IMG_GRP_IMAGE_STATE +#if defined(MCUBOOT_SERIAL_IMG_GRP_IMAGE_STATE) || defined(MCUBOOT_SWAP_USING_OFFSET) int swap_status = boot_swap_type_multi(image_index); #endif From f9e4e529a12d0b890a4665e6756aa2c9157aae7d Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Mon, 21 Apr 2025 00:25:35 +0200 Subject: [PATCH 039/204] zephyr: Fix TLV area was included in trailer size when rounding up In order to determine the maximum image size, the size of the trailer is computed. When using swap-move or swap-offset, this trailer size has to be rounded up to the next multiple of the sector size. However, the current logic was rouding up the sum of the trailer size and the TLV area size, instead of only the trailer size. This commit fixes the issue. Signed-off-by: Thomas Altenbach --- boot/zephyr/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 39005b748..5a7f3a4d9 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -677,8 +677,10 @@ if(SYSBUILD) set(boot_status_data_size 0) endif() - math(EXPR required_size "${key_size} + ${boot_magic_size} + ${boot_swap_data_size} + ${boot_status_data_size} + ${boot_tlv_estimate}") - align_up(${required_size} ${erase_size} required_size) + math(EXPR trailer_size "${key_size} + ${boot_magic_size} + ${boot_swap_data_size} + ${boot_status_data_size}") + align_up(${trailer_size} ${erase_size} trailer_size) + + math(EXPR required_size "${trailer_size} + ${boot_tlv_estimate}") if(CONFIG_SINGLE_APPLICATION_SLOT OR CONFIG_BOOT_FIRMWARE_LOADER) set(required_upgrade_size "0") From d5d3359ee28a00441c6e5d15d0f45d91091a7856 Mon Sep 17 00:00:00 2001 From: Thomas Altenbach Date: Mon, 21 Apr 2025 00:31:33 +0200 Subject: [PATCH 040/204] zephyr: Fix trailer size computation for swap-scratch When swap-scratch is used, the trailer size doesn't have to be rounded up to the next multiple of the sector size. Indeed, the trailer only need to be sector-aligned for swap-move and swap-offset. Signed-off-by: Thomas Altenbach --- boot/zephyr/CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 5a7f3a4d9..159962543 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -678,7 +678,10 @@ if(SYSBUILD) endif() math(EXPR trailer_size "${key_size} + ${boot_magic_size} + ${boot_swap_data_size} + ${boot_status_data_size}") - align_up(${trailer_size} ${erase_size} trailer_size) + + if(CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_SWAP_USING_OFFSET) + align_up(${trailer_size} ${erase_size} trailer_size) + endif() math(EXPR required_size "${trailer_size} + ${boot_tlv_estimate}") @@ -686,7 +689,10 @@ if(SYSBUILD) set(required_upgrade_size "0") else() math(EXPR required_upgrade_size "${boot_magic_size} + ${boot_swap_data_size} + ${boot_status_data_size}") - align_up(${required_upgrade_size} ${erase_size} required_upgrade_size) + + if(CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_SWAP_USING_OFFSET) + align_up(${required_upgrade_size} ${erase_size} required_upgrade_size) + endif() endif() if(CONFIG_BOOT_SWAP_USING_MOVE) From 47d826e722c6a4fdeafddb1005ac774cab49a2f4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 17 Apr 2025 15:04:04 +0100 Subject: [PATCH 041/204] boot: bootutil: swap_offset: Fix maximum application size Fixes this functionality to have the maximum allowable application size Signed-off-by: Jamie McCrae --- boot/bootutil/src/swap_offset.c | 45 +++++++++++++++------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/boot/bootutil/src/swap_offset.c b/boot/bootutil/src/swap_offset.c index aecb16be3..6caedb377 100644 --- a/boot/bootutil/src/swap_offset.c +++ b/boot/bootutil/src/swap_offset.c @@ -307,23 +307,26 @@ static int app_max_sectors(struct boot_loader_state *state) uint32_t sz = 0; uint32_t sector_sz; uint32_t trailer_sz; - uint32_t first_trailer_idx; + uint32_t available_sectors_pri; + uint32_t available_sectors_sec; + uint32_t trailer_sectors = 0; sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); - first_trailer_idx = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT); while (1) { sz += sector_sz; + ++trailer_sectors; if (sz >= trailer_sz) { break; } - - first_trailer_idx--; } - return first_trailer_idx; + available_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - trailer_sectors; + available_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) - 1; + + return (available_sectors_pri < available_sectors_sec ? available_sectors_pri : available_sectors_sec); } int boot_slots_compatible(struct boot_loader_state *state) @@ -333,34 +336,35 @@ int boot_slots_compatible(struct boot_loader_state *state) size_t sector_sz_pri = 0; size_t sector_sz_sec = 0; size_t i; - size_t num_usable_sectors_pri; + size_t num_usable_sectors; num_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT); num_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT); - num_usable_sectors_pri = app_max_sectors(state); + num_usable_sectors = app_max_sectors(state); - if ((num_sectors_pri != num_sectors_sec) && - ((num_sectors_pri + 1) != num_sectors_sec) && - ((num_usable_sectors_pri + 1) != (num_sectors_sec))) { + if (num_sectors_pri != num_sectors_sec && + (num_sectors_pri + 1) != num_sectors_sec && + num_usable_sectors != (num_sectors_sec - 1)) { BOOT_LOG_WRN("Cannot upgrade: not a compatible amount of sectors"); - BOOT_LOG_DBG("slot0 sectors: %d, slot1 sectors: %d, usable slot0 sectors: %d", + BOOT_LOG_DBG("slot0 sectors: %d, slot1 sectors: %d, usable sectors: %d", (int)num_sectors_pri, (int)num_sectors_sec, - (int)(num_usable_sectors_pri - 1)); + (int)(num_usable_sectors)); return 0; } else if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) { BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed"); return 0; } - if ((num_usable_sectors_pri + 1) != num_sectors_sec) { + if ((num_usable_sectors + 1) != num_sectors_sec) { BOOT_LOG_DBG("Non-optimal sector distribution, slot0 has %d usable sectors " - "but slot1 has %d usable sectors", (int)(num_usable_sectors_pri), + "but slot1 has %d usable sectors", (int)(num_usable_sectors), ((int)num_sectors_sec - 1)); } - for (i = 0; i < num_sectors_pri; i++) { + for (i = 0; i < num_usable_sectors; i++) { sector_sz_pri = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, i); sector_sz_sec = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, i); + if (sector_sz_pri != sector_sz_sec) { BOOT_LOG_WRN("Cannot upgrade: not same sector layout"); return 0; @@ -726,19 +730,10 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs, int app_max_size(struct boot_loader_state *state) { uint32_t sector_sz_primary; - uint32_t sector_sz_secondary; - uint32_t sz_primary; - uint32_t sz_secondary; sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); - sector_sz_secondary = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 0); - - /* Account for image flags and move sector */ - sz_primary = app_max_sectors(state) * sector_sz_primary; - sz_secondary = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz_secondary - - sector_sz_primary; - return (sz_primary <= sz_secondary ? sz_primary : sz_secondary); + return app_max_sectors(state) * sector_sz_primary; } /* Compute the total size of the given image. Includes the size of the TLVs. */ From 81315483fcbdf1f1524c2b34a1fd4de6c77cd0f4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 23 Apr 2025 12:19:48 +0100 Subject: [PATCH 042/204] Revert "zephyr: arm: Update reading the flash image reset vector" This reverts commit 453096b17ddc3aac7bf6afb97c40591d5ea3aa9c. Signed-off-by: Jamie McCrae --- boot/zephyr/flash_map_extended.c | 13 ------------- boot/zephyr/main.c | 20 +++++--------------- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index b2e96cb3f..3b95b1fd7 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -155,21 +155,8 @@ int flash_area_sector_from_off(off_t off, struct flash_sector *sector) uint8_t flash_area_get_device_id(const struct flash_area *fa) { - uint8_t device_id; - int rc; - - rc = BOOT_HOOK_FLASH_AREA_CALL(flash_area_get_device_id_hook, - BOOT_HOOK_REGULAR, fa, &device_id); - if (rc != BOOT_HOOK_REGULAR) { - return device_id; - } - -#if defined(CONFIG_ARM) - return fa->fa_id; -#else (void)fa; return FLASH_DEVICE_ID; -#endif } #define ERASED_VAL 0xff diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index a46fc724c..8b18c1ba6 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -158,26 +158,16 @@ static void do_boot(struct boot_rsp *rsp) /* Get ram address for image */ vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr + rsp->br_hdr->ih_hdr_size); #else + uintptr_t flash_base; int rc; - const struct flash_area *fap; - static uint32_t dst[2]; /* Jump to flash image */ - rc = flash_area_open(rsp->br_flash_dev_id, &fap); - assert(rc == 0); - - rc = flash_area_read(fap, rsp->br_hdr->ih_hdr_size, dst, sizeof(dst)); + rc = flash_device_base(rsp->br_flash_dev_id, &flash_base); assert(rc == 0); -#ifndef CONFIG_ASSERT - /* Enter a lock up as asserts are disabled */ - if (rc != 0) { - while (1); - } -#endif - - flash_area_close(fap); - vt = (struct arm_vector_table *)dst; + vt = (struct arm_vector_table *)(flash_base + + rsp->br_image_off + + rsp->br_hdr->ih_hdr_size); #endif if (IS_ENABLED(CONFIG_SYSTEM_TIMER_HAS_DISABLE_SUPPORT)) { From bc18d7dacaac1483ebaecb20440270cc7e5c5cdf Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 25 Apr 2025 11:47:16 +0100 Subject: [PATCH 043/204] boot: boot_serial: Fix issue with CBOR and setting image state Fixes an issue whereby when canonical mode for ZCBOR was enabled, the state variables were not increased to handle the backup states, and a bug whereby only secondary slots were checked for status when setting image state, whilst generally this is the intended outcome, a user should also be able to mark a primary image as confirmed too for other modes such as direct-xip Signed-off-by: Jamie McCrae --- boot/boot_serial/src/boot_serial.c | 153 ++++++++++++++++------------- 1 file changed, 86 insertions(+), 67 deletions(-) diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c index 4c9df65bf..5ee08e117 100644 --- a/boot/boot_serial/src/boot_serial.c +++ b/boot/boot_serial/src/boot_serial.c @@ -177,12 +177,19 @@ static int boot_serial_get_hash(const struct image_header *hdr, #endif #endif -static zcbor_state_t cbor_state[2]; +#ifdef ZCBOR_CANONICAL +/* Allow 3 extra states for backup states for all commands */ +#define CBOR_EXTRA_STATES 3 +#else +#define CBOR_EXTRA_STATES 0 +#endif + +static zcbor_state_t cbor_state[2 + CBOR_EXTRA_STATES]; void reset_cbor_state(void) { - zcbor_new_encode_state(cbor_state, 2, (uint8_t *)bs_obuf, - sizeof(bs_obuf), 0); + zcbor_new_encode_state(cbor_state, ARRAY_SIZE(cbor_state), (uint8_t *)bs_obuf, + sizeof(bs_obuf), 0); } /** @@ -497,6 +504,7 @@ bs_set(char *buf, int len) * "hash": * } */ + uint32_t slot; uint8_t image_index = 0; size_t decoded = 0; uint8_t hash[IMAGE_HASH_SIZE]; @@ -509,8 +517,8 @@ bs_set(char *buf, int len) bool found = false; #endif - zcbor_state_t zsd[4]; - zcbor_new_state(zsd, sizeof(zsd) / sizeof(zcbor_state_t), (uint8_t *)buf, len, 1, NULL, 0); + zcbor_state_t zsd[4 + CBOR_EXTRA_STATES]; + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), (uint8_t *)buf, len, 1, NULL, 0); struct zcbor_map_decode_key_val image_set_state_decode[] = { ZCBOR_MAP_DECODE_KEY_DECODER("confirm", zcbor_bool_decode, &confirm), @@ -536,98 +544,106 @@ bs_set(char *buf, int len) } if (img_hash.len != 0) { - for (image_index = 0; image_index < BOOT_IMAGE_NUMBER; ++image_index) { - struct image_header hdr; - uint32_t area_id; - const struct flash_area *fap; - uint8_t tmpbuf[64]; + IMAGES_ITER(image_index) { +#ifdef MCUBOOT_SWAP_USING_OFFSET + int swap_status = boot_swap_type_multi(image_index); +#endif + + for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) { + struct image_header hdr; + uint32_t area_id; + const struct flash_area *fap; + uint8_t tmpbuf[64]; #ifdef MCUBOOT_SWAP_USING_OFFSET - uint32_t num_sectors = SWAP_USING_OFFSET_SECTOR_UPDATE_BEGIN; - struct flash_sector sector_data; - uint32_t start_off = 0; + uint32_t num_sectors = SWAP_USING_OFFSET_SECTOR_UPDATE_BEGIN; + struct flash_sector sector_data; + uint32_t start_off = 0; #endif - area_id = flash_area_id_from_multi_image_slot(image_index, 1); - if (flash_area_open(area_id, &fap)) { - BOOT_LOG_ERR("Failed to open flash area ID %d", area_id); - continue; - } + area_id = flash_area_id_from_multi_image_slot(image_index, slot); + if (flash_area_open(area_id, &fap)) { + BOOT_LOG_ERR("Failed to open flash area ID %d", area_id); + continue; + } #ifdef MCUBOOT_SWAP_USING_OFFSET - rc = flash_area_sectors(fap, &num_sectors, §or_data); + if (slot == BOOT_SECONDARY_SLOT && swap_status != BOOT_SWAP_TYPE_REVERT) { + rc = flash_area_sectors(fap, &num_sectors, §or_data); - if ((rc != 0 && rc != -ENOMEM) || - num_sectors != SWAP_USING_OFFSET_SECTOR_UPDATE_BEGIN) { - flash_area_close(fap); - continue; - } + if ((rc != 0 && rc != -ENOMEM) || + num_sectors != SWAP_USING_OFFSET_SECTOR_UPDATE_BEGIN) { + flash_area_close(fap); + continue; + } - start_off = sector_data.fs_size; + start_off = sector_data.fs_size; + } #endif - rc = BOOT_HOOK_CALL(boot_read_image_header_hook, - BOOT_HOOK_REGULAR, image_index, 1, &hdr); - if (rc == BOOT_HOOK_REGULAR) - { + rc = BOOT_HOOK_CALL(boot_read_image_header_hook, + BOOT_HOOK_REGULAR, image_index, 1, &hdr); + if (rc == BOOT_HOOK_REGULAR) + { #ifdef MCUBOOT_SWAP_USING_OFFSET - flash_area_read(fap, start_off, &hdr, sizeof(hdr)); + flash_area_read(fap, start_off, &hdr, sizeof(hdr)); #else - flash_area_read(fap, 0, &hdr, sizeof(hdr)); + flash_area_read(fap, 0, &hdr, sizeof(hdr)); #endif - } - - if (hdr.ih_magic == IMAGE_MAGIC) - { - FIH_DECLARE(fih_rc, FIH_FAILURE); + } - BOOT_HOOK_CALL_FIH(boot_image_check_hook, - FIH_BOOT_HOOK_REGULAR, - fih_rc, image_index, 1); - if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) + if (hdr.ih_magic == IMAGE_MAGIC) { + FIH_DECLARE(fih_rc, FIH_FAILURE); + + BOOT_HOOK_CALL_FIH(boot_image_check_hook, + FIH_BOOT_HOOK_REGULAR, + fih_rc, image_index, 1); + if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR)) + { #ifdef MCUBOOT_ENC_IMAGES - if (IS_ENCRYPTED(&hdr)) { + if (IS_ENCRYPTED(&hdr)) { #ifdef MCUBOOT_SWAP_USING_OFFSET - FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, - &hdr, tmpbuf, sizeof(tmpbuf), start_off); + FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + &hdr, tmpbuf, sizeof(tmpbuf), start_off); #else - FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, - &hdr, tmpbuf, sizeof(tmpbuf)); + FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + &hdr, tmpbuf, sizeof(tmpbuf)); #endif - } else { + } else { #endif #ifdef MCUBOOT_SWAP_USING_OFFSET - FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, - fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL, start_off); + FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, + fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL, start_off); #else - FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, - fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL); + FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, + fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL); #endif #ifdef MCUBOOT_ENC_IMAGES - } + } #endif - } + } - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { - continue; + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + continue; + } } - } #ifdef MCUBOOT_SERIAL_IMG_GRP_HASH - /* Retrieve hash of image for identification */ + /* Retrieve hash of image for identification */ #ifdef MCUBOOT_SWAP_USING_OFFSET - rc = boot_serial_get_hash(&hdr, fap, hash, start_off); + rc = boot_serial_get_hash(&hdr, fap, hash, start_off); #else - rc = boot_serial_get_hash(&hdr, fap, hash); + rc = boot_serial_get_hash(&hdr, fap, hash); #endif #endif - flash_area_close(fap); + flash_area_close(fap); - if (rc == 0 && memcmp(hash, img_hash.value, sizeof(hash)) == 0) { - /* Hash matches, set this slot for test or confirmation */ - found = true; - break; + if (rc == 0 && memcmp(hash, img_hash.value, sizeof(hash)) == 0) { + /* Hash matches, set this slot for test or confirmation */ + found = true; + goto set_image_state; + } } } @@ -640,6 +656,7 @@ bs_set(char *buf, int len) } #endif +set_image_state: rc = boot_set_pending_multi(image_index, confirm); out: @@ -683,6 +700,8 @@ bs_list_set(uint8_t op, char *buf, int len) bs_rc_rsp(MGMT_ERR_ENOTSUP); #endif } + + reset_cbor_state(); } #ifdef MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO @@ -901,8 +920,8 @@ bs_upload(char *buf, int len) static uint32_t start_off = 0; #endif - zcbor_state_t zsd[4]; - zcbor_new_state(zsd, sizeof(zsd) / sizeof(zcbor_state_t), (uint8_t *)buf, len, 1, NULL, 0); + zcbor_state_t zsd[4 + CBOR_EXTRA_STATES]; + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), (uint8_t *)buf, len, 1, NULL, 0); struct zcbor_map_decode_key_val image_upload_decode[] = { ZCBOR_MAP_DECODE_KEY_DECODER("image", zcbor_uint32_decode, &img_num_tmp), @@ -1210,8 +1229,8 @@ bs_echo(char *buf, int len) bool ok; uint32_t rc = MGMT_ERR_EINVAL; - zcbor_state_t zsd[4]; - zcbor_new_state(zsd, sizeof(zsd) / sizeof(zcbor_state_t), (uint8_t *)buf, len, 1, NULL, 0); + zcbor_state_t zsd[4 + CBOR_EXTRA_STATES]; + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), (uint8_t *)buf, len, 1, NULL, 0); if (!zcbor_map_start_decode(zsd)) { goto out; From 5ef87c797f74a9f1ea7e641c36c727d300a53a0f Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 29 Apr 2025 10:45:59 +0200 Subject: [PATCH 044/204] boot: zephyr: kconfig: Fix BOOT_SWAP_USING_MOVE description Fixes typo in the BOOT_SWAP_USING_MOVE configuration description. Signed-off-by: Andrej Butok --- boot/zephyr/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index be6651557..c2cb330fd 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -446,7 +446,7 @@ config BOOT_SWAP_USING_OFFSET the second sector in the second slot instead of the first. config BOOT_SWAP_USING_MOVE - bool "Swap using mode mode without scratch partition" + bool "Swap using move mode without scratch partition" help If y, the swap upgrade is done in two steps, where first every sector of the primary slot is moved up one sector, then for From f6e8e88aa693c376a7e71d44aa04bc9908f0e74e Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 11:08:45 +0100 Subject: [PATCH 045/204] boot: bootutil: Move erase function location Moves the erase function from loader to bootutil misc to account for MCUboot modes that do not include the main loader file Signed-off-by: Jamie McCrae --- boot/bootutil/src/bootutil_misc.c | 20 ++++++++++++++++++++ boot/bootutil/src/loader.c | 20 -------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index f12562329..2043cf493 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -557,3 +557,23 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) return rc; } #endif /* !MCUBOOT_OVERWRITE_ONLY */ + +/** + * Erases a region of device that requires erase prior to write; does + * nothing on devices without erase. + * + * @param fap The flash_area containing the region to erase. + * @param off The offset within the flash area to start the + * erase. + * @param sz The number of bytes to erase. + * + * @return 0 on success; nonzero on failure. + */ +int +boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz) +{ + if (device_requires_erase(fap)) { + return flash_area_erase(fap, off, sz); + } + return 0; +} diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9c98da30c..441240aae 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1229,26 +1229,6 @@ boot_validated_swap_type(struct boot_loader_state *state, } #endif -/** - * Erases a region of device that requires erase prior to write; does - * nothing on devices without erase. - * - * @param fap The flash_area containing the region to erase. - * @param off The offset within the flash area to start the - * erase. - * @param sz The number of bytes to erase. - * - * @return 0 on success; nonzero on failure. - */ -int -boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz) -{ - if (device_requires_erase(fap)) { - return flash_area_erase(fap, off, sz); - } - return 0; -} - /** * Removes data from specified region either by writing erase value in place of * data or by doing erase, if device has such hardware requirement. From 15b36f9137270f16ac0b37f5ace305bf7bb9c2e4 Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Tue, 29 Apr 2025 17:40:52 +0300 Subject: [PATCH 046/204] boot: zephyr: kconfig: enable dependencies of Mbed TLS Kconfig option In Zephyr `MBEDTLS_KEY_EXCHANGE_RSA_ENABLED` doesn't enable its dependencies anymore, so enable them along the enablement of this Kconfig option. Signed-off-by: Tomi Fontanilles --- boot/zephyr/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index c2cb330fd..21e12ec63 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -213,6 +213,10 @@ config BOOT_SIGNATURE_TYPE_RSA select BOOT_USE_MBEDTLS select MBEDTLS select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN + select MBEDTLS_MD if MBEDTLS_BUILTIN + select MBEDTLS_RSA_C if MBEDTLS_BUILTIN + select MBEDTLS_PKCS1_V15 if MBEDTLS_BUILTIN + select MBEDTLS_PKCS1_V21 if MBEDTLS_BUILTIN select MBEDTLS_KEY_EXCHANGE_RSA_ENABLED if MBEDTLS_BUILTIN select BOOT_ENCRYPTION_SUPPORT select BOOT_IMG_HASH_ALG_SHA256_ALLOW From 413eb3842047d5940b4ddd970f9164e9b31e00e0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 30 Apr 2025 15:11:36 +0100 Subject: [PATCH 047/204] boot: zephyr: flash_map: Fix missing include Adds an include file that is missing Signed-off-by: Jamie McCrae --- boot/zephyr/include/flash_map_backend/flash_map_backend.h | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h index 81a183259..dd2185b81 100644 --- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h +++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h @@ -9,6 +9,7 @@ #define __FLASH_MAP_BACKEND_H__ #include // the zephyr flash_map +#include #ifdef __cplusplus extern "C" { From 1b2d261d1111341a777f1804d712992ed92c81b4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 1 May 2025 08:00:38 +0100 Subject: [PATCH 048/204] boot: zephyr: flash_map: Fix unused argument Fixes an issue with an unused variable argument Signed-off-by: Jamie McCrae --- boot/zephyr/include/flash_map_backend/flash_map_backend.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h index dd2185b81..ed73811cd 100644 --- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h +++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h @@ -112,13 +112,15 @@ int flash_area_get_sector(const struct flash_area *fa, off_t off, static inline bool flash_area_erase_required(const struct flash_area *fa) { #if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) - const struct flash_parameters *fp = flash_get_parameters(flash_area_get_device(fa)); - return flash_params_get_erase_cap(flash_get_parameters(flash_area_get_device(fa))) & FLASH_ERASE_C_EXPLICIT; #elif defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) + (void)fa; + return true; #else + (void)fa; + return false; #endif } From a98bff9f11c075370465d6d041332c1101fac3bd Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 1 May 2025 07:57:01 +0100 Subject: [PATCH 049/204] boot: zephyr: kconfig: Fix issues and re-order Fixes issues with Kconfigs being placed outside of the MCUboot group and not selecting experimental symbols. Also fixes ordering to place USB DFU into a menu rather than being all over the place Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 93 ++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 21e12ec63..acc0314a6 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -759,6 +759,32 @@ config BOOT_FIH_PROFILE_HIGH endchoice +config BOOT_USE_BENCH + bool "Enable benchmark code" + help + If y, adds support for simple benchmarking that can record + time intervals between two calls. The time printed depends + on the particular Zephyr target, and is generally ticks of a + specific board-specific timer. + +module = MCUBOOT +module-str = MCUBoot bootloader +source "subsys/logging/Kconfig.template.log_config" + +config MCUBOOT_LOG_THREAD_STACK_SIZE + int "Stack size for the MCUBoot log processing thread" + depends on LOG && !LOG_IMMEDIATE + default 2048 if COVERAGE_GCOV + default 1024 if NO_OPTIMIZATIONS + default 1024 if XTENSA + default 4096 if (X86 && X86_64) + default 4096 if ARM64 + default 768 + help + Set the internal stack size for MCUBoot log processing thread. + +menu "USB DFU" + choice BOOT_USB_DFU prompt "USB DFU" default BOOT_USB_DFU_NO @@ -811,44 +837,24 @@ endif # BOOT_USB_DFU_GPIO config BOOT_USB_DFU_NO_APPLICATION bool "Stay in bootloader if no application" + depends on !BOOT_USB_DFU_NO help Allows for entering USB DFU recovery mode if there is no bootable application that the bootloader can jump to. -config BOOT_USE_BENCH - bool "Enable benchmark code" - help - If y, adds support for simple benchmarking that can record - time intervals between two calls. The time printed depends - on the particular Zephyr target, and is generally ticks of a - specific board-specific timer. - -module = MCUBOOT -module-str = MCUBoot bootloader -source "subsys/logging/Kconfig.template.log_config" +endmenu -config MCUBOOT_LOG_THREAD_STACK_SIZE - int "Stack size for the MCUBoot log processing thread" - depends on LOG && !LOG_IMMEDIATE - default 2048 if COVERAGE_GCOV - default 1024 if NO_OPTIMIZATIONS - default 1024 if XTENSA - default 4096 if (X86 && X86_64) - default 4096 if ARM64 - default 768 - help - Set the internal stack size for MCUBoot log processing thread. +rsource "Kconfig.serial_recovery" config MCUBOOT_INDICATION_LED bool "Turns on LED indication when device is in DFU" select GPIO + depends on MCUBOOT_SERIAL || !BOOT_USB_DFU_NO help Device device activates the LED while in bootloader mode. mcuboot-led0 alias must be set in the device's .dts definitions for this to work. -rsource "Kconfig.serial_recovery" - rsource "Kconfig.firmware_loader" config BOOT_INTR_VEC_RELOC @@ -1016,24 +1022,6 @@ endif # BOOT_DECOMPRESSION endif # BOOT_DECOMPRESSION_SUPPORT -menu "Defaults" - # Items in this menu should not be manually set. These options are for modules/sysbuild to - # set as defaults to allow MCUboot's default configuration to be set, but still allow it - # to be overridden by users. - -config BOOT_FIH_PROFILE_DEFAULT_LOW - bool "Default to low fault inject hardening level" - -config BOOT_FIH_PROFILE_DEFAULT_MEDIUM - bool "Default to medium fault inject hardening level" - -config BOOT_FIH_PROFILE_DEFAULT_HIGH - bool "Default to high fault inject hardening level" - -endmenu - -endmenu - config MCUBOOT_STORAGE_WITHOUT_ERASE bool "Support for devices without erase" depends on FLASH_HAS_NO_EXPLICIT_ERASE @@ -1057,7 +1045,8 @@ config MCUBOOT_STORAGE_WITH_ERASE Support for devices with erase config MCUBOOT_STORAGE_MINIMAL_SCRAMBLE - bool "Do minimal required work to remove data (EXPERIMENTAL)" + bool "Do minimal required work to remove data [EXPERIMENTAL]" + select EXPERIMENTAL help In some cases MCUboot has to remove data, which usually means make it non-viable for MCUboot rather then completely destroyed. @@ -1072,6 +1061,22 @@ config MCUBOOT_STORAGE_MINIMAL_SCRAMBLE Depending on type of device this may be done by erase of minimal number of pages or overwrite of part of image. +menu "Defaults" + # Items in this menu should not be manually set. These options are for modules/sysbuild to + # set as defaults to allow MCUboot's default configuration to be set, but still allow it + # to be overridden by users. + +config BOOT_FIH_PROFILE_DEFAULT_LOW + bool "Default to low fault inject hardening level" + +config BOOT_FIH_PROFILE_DEFAULT_MEDIUM + bool "Default to medium fault inject hardening level" + +config BOOT_FIH_PROFILE_DEFAULT_HIGH + bool "Default to high fault inject hardening level" + +endmenu + config MCUBOOT_DEVICE_SETTINGS # Hidden selector for device-specific settings bool @@ -1088,6 +1093,8 @@ config MCUBOOT_DEVICE_CPU_CORTEX_M0 bool select SW_VECTOR_RELAY if !CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP +endmenu + comment "Zephyr configuration options" # Disabling MULTITHREADING provides a code size advantage, but From 7253f01c06e19d2c5d7b146fedcf4473200b6b0d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 23 Apr 2025 11:35:44 +0100 Subject: [PATCH 050/204] boot: bootutil: Refactor erase functionality to fix watchdog feeding Refactors the erase functionality in bootutil so that it can be used alongside feeding the watchdog. This has also optimised some functions out. Signed-off-by: Jamie McCrae --- boot/boot_serial/src/boot_serial.c | 4 +- boot/boot_serial/src/boot_serial_encryption.c | 2 +- boot/bootutil/src/bootutil_misc.c | 98 ++++++++++- boot/bootutil/src/bootutil_priv.h | 6 +- boot/bootutil/src/loader.c | 155 ++++++------------ boot/bootutil/src/swap_misc.c | 4 +- boot/bootutil/src/swap_move.c | 6 +- boot/bootutil/src/swap_offset.c | 10 +- boot/bootutil/src/swap_scratch.c | 10 +- 9 files changed, 164 insertions(+), 131 deletions(-) diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c index 5ee08e117..82e1abddb 100644 --- a/boot/boot_serial/src/boot_serial.c +++ b/boot/boot_serial/src/boot_serial.c @@ -875,7 +875,7 @@ static off_t erase_range(const struct flash_area *fap, off_t start, off_t end) BOOT_LOG_DBG("Erasing range 0x%jx:0x%jx", (intmax_t)start, (intmax_t)(start + size - 1)); - rc = boot_erase_region(fap, start, size); + rc = boot_erase_region(fap, start, size, false); if (rc != 0) { BOOT_LOG_ERR("Error %d while erasing range", rc); return -EINVAL; @@ -1019,7 +1019,7 @@ bs_upload(char *buf, int len) /* Non-progressive erase erases entire image slot when first chunk of * an image is received. */ - rc = boot_erase_region(fap, 0, area_size); + rc = boot_erase_region(fap, 0, area_size, false); if (rc) { goto out_invalid_data; } diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 81af6b850..1f932ef60 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -187,7 +187,7 @@ decrypt_region_inplace(struct boot_loader_state *state, (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz, blk_off, &buf[idx]); } - rc = boot_erase_region(fap, off + bytes_copied, chunk_sz); + rc = boot_erase_region(fap, off + bytes_copied, chunk_sz, false); if (rc != 0) { return BOOT_EFLASH; } diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 2043cf493..e53715b65 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -4,6 +4,7 @@ * Copyright (c) 2017-2019 Linaro LTD * Copyright (c) 2016-2019 JUUL Labs * Copyright (c) 2019-2020 Arm Limited + * Copyright (c) 2025 Nordic Semiconductor ASA * * Original license: * @@ -562,18 +563,103 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) * Erases a region of device that requires erase prior to write; does * nothing on devices without erase. * - * @param fap The flash_area containing the region to erase. + * @param fa The flash_area containing the region to erase. * @param off The offset within the flash area to start the * erase. - * @param sz The number of bytes to erase. + * @param size The number of bytes to erase. + * @param backwards If set to true will erase from end to start + * addresses, otherwise erases from start to end + * addresses. * * @return 0 on success; nonzero on failure. */ int -boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz) +boot_erase_region(const struct flash_area *fa, uint32_t off, uint32_t size, bool backwards) { - if (device_requires_erase(fap)) { - return flash_area_erase(fap, off, sz); + int rc = 0; + + if (off >= flash_area_get_size(fa) || (flash_area_get_size(fa) - off) < size) { + rc = -1; + goto end; + } else if (device_requires_erase(fa)) { + uint32_t end_offset = 0; + struct flash_sector sector; + + if (backwards) { + /* Get the lowest page offset first */ + rc = flash_area_get_sector(fa, off, §or); + + if (rc < 0) { + goto end; + } + + end_offset = flash_sector_get_off(§or); + + /* Set boundary condition, the highest probable offset to erase, within + * last sector to erase + */ + off += size - 1; + } else { + /* Get the highest page offset first */ + rc = flash_area_get_sector(fa, (off + size - 1), §or); + + if (rc < 0) { + goto end; + } + + end_offset = flash_sector_get_off(§or); + } + + while (true) { + /* Size to read in this iteration */ + size_t csize; + + /* Get current sector and, also, correct offset */ + rc = flash_area_get_sector(fa, off, §or); + + if (rc < 0) { + goto end; + } + + /* Corrected offset and size of current sector to erase */ + off = flash_sector_get_off(§or); + csize = flash_sector_get_size(§or); + + rc = flash_area_erase(fa, off, csize); + + if (rc < 0) { + goto end; + } + + MCUBOOT_WATCHDOG_FEED(); + + if (backwards) { + if (end_offset >= off) { + /* Reached the first offset in range and already erased it */ + break; + } + + /* Move down to previous sector, the flash_area_get_sector will + * correct the value to real page offset + */ + off -= 1; + } else { + /* Move up to next sector */ + off += csize; + + if (off > end_offset) { + /* Reached the end offset in range and already erased it */ + break; + } + + /* Workaround for flash_sector_get_off() being broken in mynewt, hangs with + * infinite loop if this is not present, should be removed if bug is fixed. + */ + off += 1; + } + } } - return 0; + +end: + return rc; } diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index 95f8f1732..72e94aee9 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -346,11 +346,9 @@ int boot_copy_region(struct boot_loader_state *state, /* Prepare for write device that requires erase prior to write. This will * do nothing on devices without erase requirement. */ -int boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz); +int boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz, bool backwards); /* Similar to boot_erase_region but will always remove data */ -int boot_scramble_region(const struct flash_area *fap, uint32_t off, uint32_t sz); -/* Similar to boot_scramble_region but works backwards */ -int boot_scramble_region_backwards(const struct flash_area *fap, uint32_t off, uint32_t sz); +int boot_scramble_region(const struct flash_area *fap, uint32_t off, uint32_t sz, bool backwards); /* Makes slot unbootable, either by scrambling header magic, header sector * or entire slot, depending on settings. * Note: slot is passed here becuase at this point there is no function diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 441240aae..f47ec4e2a 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1239,36 +1239,70 @@ boot_validated_swap_type(struct boot_loader_state *state, * @param off The offset within the flash area to start the * erase. * @param size The number of bytes to erase. + * @param backwards If set to true will erase from end to start + * addresses, otherwise erases from start to end + * addresses. * * @return 0 on success; nonzero on failure. */ int -boot_scramble_region(const struct flash_area *fa, uint32_t off, uint32_t size) +boot_scramble_region(const struct flash_area *fa, uint32_t off, uint32_t size, bool backwards) { - int ret = 0; + int rc = 0; if (size == 0) { - return 0; + goto done; } if (device_requires_erase(fa)) { - return flash_area_erase(fa, off, size); + rc = boot_erase_region(fa, off, size, backwards); + } else if (off >= flash_area_get_size(fa) || (flash_area_get_size(fa) - off) < size) { + rc = -1; + goto done; } else { uint8_t buf[BOOT_MAX_ALIGN]; - size_t size_done = 0; const size_t write_block = flash_area_align(fa); + uint32_t end_offset; memset(buf, flash_area_erased_val(fa), sizeof(buf)); - while (size_done < size) { - ret = flash_area_write(fa, size_done + off, buf, write_block); - if (ret != 0) { + if (backwards) { + end_offset = ALIGN_DOWN(off, write_block); + /* Starting at the last write block in range */ + off += size - write_block; + } else { + end_offset = ALIGN_DOWN((off + size), write_block); + } + + while (true) { + /* Write over the area to scramble data that is there */ + rc = flash_area_write(fa, off, buf, write_block); + if (rc != 0) { break; } - size_done += write_block; + + MCUBOOT_WATCHDOG_FEED(); + + if (backwards) { + if (end_offset >= off) { + /* Reached the first offset in range and already scrambled it */ + break; + } + + off -= write_block; + } else { + if (end_offset < off) { + /* Reached the end offset in range and already scrambled it */ + break; + } + + off += write_block; + } } } - return ret; + +done: + return rc; } /** @@ -1284,90 +1318,6 @@ boot_scramble_region(const struct flash_area *fa, uint32_t off, uint32_t size) * * @return 0 on success; nonzero on failure. */ -int boot_scramble_region_backwards(const struct flash_area *fa, uint32_t off, uint32_t size) -{ - int ret = 0; - uint32_t first_offset = 0; - - if (size == 0) { - return 0; - } - - if (off >= flash_area_get_size(fa) || (flash_area_get_size(fa) - off) < size) { - return -1; - } - - if (device_requires_erase(fa)) { - struct flash_sector sector; - - /* Get the lowest erased page offset first */ - ret = flash_area_get_sector(fa, off, §or); - if (ret < 0) { - return ret; - } - first_offset = flash_sector_get_off(§or); - - /* Set boundary condition, the highest probable offset to erase, within - * last sector to erase - */ - off += size - 1; - - while (true) { - /* Size to read in this iteration */ - size_t csize; - - /* Get current sector and, also, correct offset */ - ret = flash_area_get_sector(fa, off, §or); - if (ret < 0) { - return ret; - } - - /* Corrected offset and size of current sector to erase */ - off = flash_sector_get_off(§or); - csize = flash_sector_get_size(§or); - - ret = flash_area_erase(fa, off, csize); - if (ret < 0) { - return ret; - } - - if (first_offset >= off) { - /* Reached the first offsset in range and already erased it */ - break; - } - - /* Move down to previous sector, the flash_area_get_sector will - * correct the value to real page offset - */ - off -= 1; - } - } else { - uint8_t buf[BOOT_MAX_ALIGN]; - const size_t write_block = flash_area_align(fa); - uint32_t first_offset = ALIGN_DOWN(off, write_block); - - memset(buf, flash_area_erased_val(fa), sizeof(buf)); - - /* Starting at the last write block in range */ - off += size - write_block; - - while (true) { - /* Write over the area to scramble data that is there */ - ret = flash_area_write(fa, off, buf, write_block); - if (ret != 0) { - break; - } - - if (first_offset >= off) { - /* Reached the first offset in range and already scrambled it */ - break; - } - - off -= write_block; - } - } - return ret; -} /** * Remove enough data from slot to mark is as unused @@ -1392,7 +1342,7 @@ boot_scramble_slot(const struct flash_area *fa, int slot) /* Without minimal entire area needs to be scrambled */ #if !defined(MCUBOOT_MINIMAL_SCRAMBLE) size = flash_area_get_size(fa); - ret = boot_scramble_region(fa, 0, size); + ret = boot_scramble_region(fa, 0, size, false); #else size_t off = 0; @@ -1401,7 +1351,7 @@ boot_scramble_slot(const struct flash_area *fa, int slot) return ret; } - ret = boot_scramble_region(fa, off, size); + ret = boot_scramble_region(fa, off, size, false); if (ret < 0) { return ret; } @@ -1411,7 +1361,7 @@ boot_scramble_slot(const struct flash_area *fa, int slot) return ret; } - ret = boot_scramble_region_backwards(fa, off, flash_area_get_size(fa) - off); + ret = boot_scramble_region(fa, off, (flash_area_get_size(fa) - off), true); #endif return ret; } @@ -1643,7 +1593,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) sect_count = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT); for (sect = 0, size = 0; sect < sect_count; sect++) { this_size = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, sect); - rc = boot_erase_region(fap_primary_slot, size, this_size); + rc = boot_erase_region(fap_primary_slot, size, this_size, false); assert(rc == 0); #if defined(MCUBOOT_OVERWRITE_ONLY_FAST) @@ -1667,7 +1617,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) sector--; } while (sz < trailer_sz); - rc = boot_erase_region(fap_primary_slot, off, sz); + rc = boot_erase_region(fap_primary_slot, off, sz, false); assert(rc == 0); #endif @@ -1739,7 +1689,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) BOOT_LOG_DBG("erasing secondary header"); rc = boot_erase_region(fap_secondary_slot, boot_img_sector_off(state, BOOT_SECONDARY_SLOT, 0), - boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 0)); + boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 0), false); assert(rc == 0); #endif @@ -1749,7 +1699,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) boot_img_sector_off(state, BOOT_SECONDARY_SLOT, last_sector), boot_img_sector_size(state, BOOT_SECONDARY_SLOT, - last_sector)); + last_sector), false); assert(rc == 0); /* TODO: Perhaps verify the primary slot's signature again? */ @@ -2917,9 +2867,8 @@ boot_select_or_erase(struct boot_loader_state *state) */ BOOT_LOG_DBG("Erasing faulty image in the %s slot.", (active_slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary"); - rc = flash_area_erase(fap, 0, flash_area_get_size(fap)); + rc = boot_scramble_region(fap, 0, flash_area_get_size(fap), false); assert(rc == 0); - rc = -1; } else { if (active_swap_state->copy_done != BOOT_FLAG_SET) { diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c index 1244e475e..ac9412b0f 100644 --- a/boot/bootutil/src/swap_misc.c +++ b/boot/bootutil/src/swap_misc.c @@ -61,7 +61,7 @@ swap_erase_trailer_sectors(const struct boot_loader_state *state, uint32_t sz = boot_img_sector_size(state, slot, sector); uint32_t off = boot_img_sector_off(state, slot, sector); - rc = boot_erase_region(fap, off, sz); + rc = boot_erase_region(fap, off, sz, false); assert(rc == 0); sector--; @@ -87,7 +87,7 @@ swap_scramble_trailer_sectors(const struct boot_loader_state *state, if (rc < 0) { return BOOT_EFLASH; } - rc = boot_scramble_region_backwards(fap, off, flash_area_get_size(fap) - off); + rc = boot_scramble_region(fap, off, (flash_area_get_size(fap) - off), true); if (rc < 0) { return BOOT_EFLASH; } diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index fd91ad488..9349cde37 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -413,7 +413,7 @@ boot_move_sector_up(int idx, uint32_t sz, struct boot_loader_state *state, assert(rc == 0); } - rc = boot_erase_region(fap_pri, new_off, sz); + rc = boot_erase_region(fap_pri, new_off, sz, false); assert(rc == 0); rc = boot_copy_region(state, fap_pri, fap_pri, old_off, new_off, sz); @@ -440,7 +440,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, sec_off = boot_img_sector_off(state, BOOT_SECONDARY_SLOT, idx - 1); if (bs->state == BOOT_STATUS_STATE_0) { - rc = boot_erase_region(fap_pri, pri_off, sz); + rc = boot_erase_region(fap_pri, pri_off, sz, false); assert(rc == 0); rc = boot_copy_region(state, fap_sec, fap_pri, sec_off, pri_off, sz); @@ -452,7 +452,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, } if (bs->state == BOOT_STATUS_STATE_1) { - rc = boot_erase_region(fap_sec, sec_off, sz); + rc = boot_erase_region(fap_sec, sec_off, sz, false); assert(rc == 0); rc = boot_copy_region(state, fap_pri, fap_sec, pri_up_off, sec_off, sz); diff --git a/boot/bootutil/src/swap_offset.c b/boot/bootutil/src/swap_offset.c index 6caedb377..dd991dab9 100644 --- a/boot/bootutil/src/swap_offset.c +++ b/boot/bootutil/src/swap_offset.c @@ -470,7 +470,7 @@ static void boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *st } else { /* Copy from slot 0 X to slot 1 X */ BOOT_LOG_DBG("Erasing secondary 0x%x of 0x%x", sec_off, sz); - rc = boot_erase_region(fap_sec, sec_off, sz); + rc = boot_erase_region(fap_sec, sec_off, sz, false); assert(rc == 0); BOOT_LOG_DBG("Copying primary 0x%x -> secondary 0x%x of 0x%x", pri_off, sec_off, sz); @@ -490,7 +490,7 @@ static void boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *st } else { /* Erase slot 0 X */ BOOT_LOG_DBG("Erasing primary 0x%x of 0x%x", pri_off, sz); - rc = boot_erase_region(fap_pri, pri_off, sz); + rc = boot_erase_region(fap_pri, pri_off, sz, false); assert(rc == 0); /* Copy from slot 1 (X + 1) to slot 0 X */ @@ -531,7 +531,7 @@ static void boot_swap_sectors_revert(int idx, uint32_t sz, struct boot_loader_st } else { /* Copy from slot 0 X to slot 1 X */ BOOT_LOG_DBG("Erasing secondary 0x%x of 0x%x", sec_off, sz); - rc = boot_erase_region(fap_sec, sec_off, sz); + rc = boot_erase_region(fap_sec, sec_off, sz, false); assert(rc == 0); BOOT_LOG_DBG("Copying primary 0x%x -> secondary 0x%x of 0x%x", pri_off, sec_off, sz); @@ -551,7 +551,7 @@ static void boot_swap_sectors_revert(int idx, uint32_t sz, struct boot_loader_st } else { /* Erase slot 0 X */ BOOT_LOG_DBG("Erasing primary 0x%x of 0x%x", pri_off, sz); - rc = boot_erase_region(fap_pri, pri_off, sz); + rc = boot_erase_region(fap_pri, pri_off, sz, false); assert(rc == 0); /* Copy from slot 1 (X + 1) to slot 0 X */ @@ -710,7 +710,7 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs, * to allow for a future update to be loaded */ rc = boot_scramble_region(fap_sec, boot_img_sector_off(state, BOOT_SECONDARY_SLOT, 0), - sector_sz); + sector_sz, false); assert(rc == 0); rc = swap_scramble_trailer_sectors(state, fap_sec); assert(rc == 0); diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index af4be88a6..7997f1d5c 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -617,7 +617,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, if (bs->state == BOOT_STATUS_STATE_0) { BOOT_LOG_DBG("erasing scratch area"); - rc = boot_erase_region(fap_scratch, 0, flash_area_get_size(fap_scratch)); + rc = boot_erase_region(fap_scratch, 0, flash_area_get_size(fap_scratch), false); assert(rc == 0); if (bs->idx == BOOT_STATUS_IDX_0) { @@ -641,7 +641,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, /* Erase the temporary trailer from the scratch area. */ rc = boot_erase_region(fap_scratch, 0, - flash_area_get_size(fap_scratch)); + flash_area_get_size(fap_scratch), false); assert(rc == 0); } } @@ -683,7 +683,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, } if (erase_sz > 0) { - rc = boot_erase_region(fap_secondary_slot, img_off, erase_sz); + rc = boot_erase_region(fap_secondary_slot, img_off, erase_sz, false); assert(rc == 0); } @@ -716,7 +716,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, } if (erase_sz > 0) { - rc = boot_erase_region(fap_primary_slot, img_off, erase_sz); + rc = boot_erase_region(fap_primary_slot, img_off, erase_sz, false); assert(rc == 0); } @@ -778,7 +778,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, BOOT_STATUS_ASSERT(rc == 0); if (erase_scratch) { - rc = boot_erase_region(fap_scratch, 0, flash_area_get_size(fap_scratch)); + rc = boot_erase_region(fap_scratch, 0, flash_area_get_size(fap_scratch), false); assert(rc == 0); } } From f76fba706a66ce08d733468b47f89e26d59b3de5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 30 Apr 2025 09:51:54 +0100 Subject: [PATCH 051/204] boot: bootutil: swap_scratch: Fix issue with bricking device Fixes an issue with the swap using scratch algorithm that would cause the image loaded into the primary slot to be corrupt and unbootable if a device was rebooted during an erase of the scratch section that had not completed Signed-off-by: Jamie McCrae --- boot/bootutil/src/swap_scratch.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 7997f1d5c..f9dbb7103 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -778,7 +778,12 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state, BOOT_STATUS_ASSERT(rc == 0); if (erase_scratch) { - rc = boot_erase_region(fap_scratch, 0, flash_area_get_size(fap_scratch), false); + /* Scratch trailers MUST be erased backwards, this is to avoid an issue whereby a + * device reboots in the process of erasing the scratch if it erased forwards, if that + * happens then the scratch which is partially erased would be wrote back to the + * primary slot, causing a corrupt unbootable image + */ + rc = boot_erase_region(fap_scratch, 0, flash_area_get_size(fap_scratch), true); assert(rc == 0); } } From 990b1fcb367e27056b282f183e819964fdbfe907 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 30 Apr 2025 09:57:20 +0100 Subject: [PATCH 052/204] docs: release-notes: Add additional fixes Adds some additional fixes that have been fixed for 2.2.0 Signed-off-by: Jamie McCrae --- docs/release-notes.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/release-notes.md b/docs/release-notes.md index e5480b9a6..1eebd41a0 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -66,6 +66,16 @@ MCUboot is compiled without support for them - Added support for devices that do not require erase prior to write operation. - Add corrections to the max app size calculations. +- Fixed issue with swap using scratch mode that would cause the + primary image to be corrupt and unbootable after an update if the + device was rebooted whilst the scratch area was being erased. +- Fixed issue with serial recovery if canonical CBOR mode was + enabled. +- Fixed issue with serial recovery set image state not checking + primary slot images. +- Fixed issue with watchdog not being fed during flash erase + operations, which could cause the watchdog to time out on long + erase operations and prevent firmware updates from being possible. ## Version 2.1.0 From 14667a5b309859cdf26ef8ecb8910bede6ec553f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 2 May 2025 07:50:07 +0100 Subject: [PATCH 053/204] Revert "[nrf noup] nrf_cleanup: nRF54h: fix missing peripheral cleanup" This reverts commit 9d9d524407df6da0815c79c5b9cf645f1ce25592. Signed-off-by: Jamie McCrae --- boot/zephyr/nrf_cleanup.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 39dfcbc41..f90a46af1 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ -#if defined(CONFIG_NRFX_CLOCK) +#if !defined(CONFIG_SOC_SERIES_NRF54HX) #include #endif #include @@ -13,9 +13,6 @@ #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif -#if defined(CONFIG_NRF_GRTC_TIMER) - #include -#endif #if defined(NRF_PPI) #include #endif @@ -51,13 +48,6 @@ static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) } #endif -#if defined(CONFIG_NRF_GRTC_TIMER) -static inline void nrf_cleanup_grtc(void) -{ - nrfx_grtc_uninit(); -} -#endif - #if defined(NRF_UARTE_CLEANUP) static NRF_UARTE_Type *nrf_uarte_to_clean[] = { #if defined(NRF_UARTE0) @@ -72,13 +62,10 @@ static NRF_UARTE_Type *nrf_uarte_to_clean[] = { #if defined(NRF_UARTE30) NRF_UARTE30, #endif -#if defined(NRF_UARTE136) - NRF_UARTE136, -#endif }; #endif -#if defined(CONFIG_NRFX_CLOCK) +#if !defined(CONFIG_SOC_SERIES_NRF54HX) static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); @@ -97,10 +84,6 @@ void nrf_cleanup_peripheral(void) nrf_cleanup_rtc(NRF_RTC2); #endif -#if defined(CONFIG_NRF_GRTC_TIMER) - nrf_cleanup_grtc(); -#endif - #if defined(NRF_UARTE_CLEANUP) for (int i = 0; i < sizeof(nrf_uarte_to_clean) / sizeof(nrf_uarte_to_clean[0]); ++i) { NRF_UARTE_Type *current = nrf_uarte_to_clean[i]; @@ -154,7 +137,7 @@ void nrf_cleanup_peripheral(void) nrf_dppi_channels_disable_all(NRF_DPPIC); #endif -#if defined(CONFIG_NRFX_CLOCK) +#if !defined(CONFIG_SOC_SERIES_NRF54HX) nrf_cleanup_clock(); #endif } From 7cca08d419b32f445504aef67fc4fd06d3ee3651 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 2 May 2025 07:50:10 +0100 Subject: [PATCH 054/204] Revert "[nrf noup] boot: bootutil: key revocation fix" This reverts commit 85ed722d00dc4e60804b34a066f642d80a6bc67f. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 6c74577ca..d19511be3 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -3000,8 +3000,7 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) fih_rc = FIH_SUCCESS; #if defined(CONFIG_BOOT_KEYS_REVOCATION) rc = revoke(); - if (rc != BOOT_KEY_REVOKE_OK && - rc != BOOT_KEY_REVOKE_NOT_READY) { + if (rc != BOOT_KEY_REVOKE_OK) { FIH_SET(fih_rc, FIH_FAILURE); } #endif /* CONFIG_BOOT_KEYS_REVOCATION */ From bf733359740907a1ca709b2655f365e5cc9e1a6d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 055/204] Revert "[nrf noup] boot: zephyr: boards: nrf54lm20apdk" This reverts commit ec525371393e9aa5985d918eae3e4679776fbd19. Signed-off-by: Jamie McCrae --- .../boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf diff --git a/boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf b/boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf deleted file mode 100644 index 4944f7b13..000000000 --- a/boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2025 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# -CONFIG_BOOT_MAX_IMG_SECTORS=256 - -# Ensure that the SPI NOR driver is disabled by default -CONFIG_SPI_NOR=n - -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - -CONFIG_BOOT_WATCHDOG_FEED=n - -CONFIG_PSA_CRYPTO_DRIVER_CRACEN=n -CONFIG_PSA_CRYPTO_DRIVER_OBERON=y From f1119aaa4e98b1bcd62a3c7564a06a74c4b23545 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 056/204] Revert "[nrf noup] zephyr: Fix issue with unpadded encrypted updates" This reverts commit 3443eae6a2dd630bd9b9e3ac2c784312b69c7e2f. Signed-off-by: Jamie McCrae --- boot/zephyr/decompression.c | 50 +++++-------------------------------- 1 file changed, 6 insertions(+), 44 deletions(-) diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c index 01810dcf8..f49898d55 100644 --- a/boot/zephyr/decompression.c +++ b/boot/zephyr/decompression.c @@ -37,9 +37,6 @@ #endif #define DECOMP_BUF_ALLOC_SIZE (DECOMP_BUF_SIZE + DECOMP_BUF_EXTRA_SIZE) -#define DECRYPTION_BLOCK_SIZE_AES128 16 -#define DECRYPTION_BLOCK_SIZE_AES256 32 - /* Number of times that consumed data by decompression system can be 0 in a row before aborting */ #define OFFSET_ZERO_CHECK_TIMES 3 @@ -190,7 +187,6 @@ int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_h struct enc_key_data *enc_state; int image_index; uint32_t comp_size = 0; - uint8_t decryption_block_size = 0; rc = bootutil_get_img_decrypted_comp_size(hdr, fap, &comp_size); @@ -213,18 +209,6 @@ int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_h !boot_enc_valid(enc_state, 1)) { return -1; } - - if (MUST_DECRYPT(fap, image_index, hdr)) { - if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) { - decryption_block_size = DECRYPTION_BLOCK_SIZE_AES128; - } else if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256) { - decryption_block_size = DECRYPTION_BLOCK_SIZE_AES256; - } else { - LOG_ERR("Unknown decryption block size"); - rc = BOOT_EBADIMAGE; - goto finish_end; - } - } #endif bootutil_sha_init(&sha_ctx); @@ -335,17 +319,11 @@ int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_h } #ifdef MCUBOOT_ENC_IMAGES - if (MUST_DECRYPT(fap, image_index, hdr)) { - uint8_t dummy_bytes = 0; - - if ((copy_size % decryption_block_size)) { - dummy_bytes = decryption_block_size - (copy_size % decryption_block_size); - memset(&tmp_buf[copy_size], 0x00, dummy_bytes); - } - - boot_enc_decrypt(enc_state, 1, read_pos, (copy_size + dummy_bytes), (read_pos & 0xf), - tmp_buf); - } + if (MUST_DECRYPT(fap, image_index, hdr)) { + boot_enc_decrypt(enc_state, 1, read_pos, + copy_size, (read_pos & 0xf), + tmp_buf); + } #endif /* Decompress data in chunks, writing it back with a larger write offset of the primary @@ -1012,7 +990,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl #ifdef MCUBOOT_ENC_IMAGES uint32_t comp_size = 0; - uint8_t decryption_block_size = 0; #endif hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); @@ -1025,14 +1002,6 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl rc = BOOT_EBADIMAGE; goto finish; } - - if (IS_ENCRYPTED(hdr)) { - if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) { - decryption_block_size = DECRYPTION_BLOCK_SIZE_AES128; - } else if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256) { - decryption_block_size = DECRYPTION_BLOCK_SIZE_AES256; - } - } #endif /* Setup decompression system */ @@ -1138,14 +1107,7 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(hdr)) { - uint8_t dummy_bytes = 0; - - if ((copy_size % decryption_block_size)) { - dummy_bytes = decryption_block_size - (copy_size % decryption_block_size); - memset(&buf[copy_size], 0x00, dummy_bytes); - } - - boot_enc_decrypt(BOOT_CURR_ENC(state), 1, pos, (copy_size + dummy_bytes), (pos & 0xf), buf); + boot_enc_decrypt(BOOT_CURR_ENC(state), 1, pos, copy_size, (pos & 0xf), buf); } #endif From 638332e17e0fe8fa1e77cda62abbf527df7c7eb9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 057/204] Revert "[nrf noup] nrf_cleanup: nRF54l: disable cleanup on UARTE pins" This reverts commit 81e6fc3041d028000bcc97ec99d1290cf6c172b6. Signed-off-by: Jamie McCrae --- boot/zephyr/nrf_cleanup.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index f90a46af1..1252334ca 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -97,12 +97,6 @@ void nrf_cleanup_peripheral(void) nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); nrfy_uarte_disable(current); -#ifndef CONFIG_SOC_SERIES_NRF54LX - /* Disconnect pins UARTE pins - * causes issues on nRF54l SoCs, - * could be enabled once fix to NCSDK-33039 will be implemented. - */ - uint32_t pin[4]; pin[0] = nrfy_uarte_tx_pin_get(current); @@ -117,7 +111,6 @@ void nrf_cleanup_peripheral(void) nrfy_gpio_cfg_default(pin[i]); } } -#endif #if defined(NRF_DPPIC) /* Clear all SUBSCRIBE configurations. */ From bd1014a7b0653f5ed258739d4816227f2b47d409 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 058/204] Revert "[nrf fromlist] zephyr: Disable SPI_NOR by default for nrf7002dk/nrf5340/cpuapp" This reverts commit 2d52426972382579577a72c41b6030d3316ba81e. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf diff --git a/boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf b/boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf deleted file mode 100644 index b37be6f10..000000000 --- a/boot/zephyr/boards/nrf7002dk_nrf5340_cpuapp.conf +++ /dev/null @@ -1,5 +0,0 @@ -# By default no external SPI device is used for image storage, -# so SPI-NOR is not needed. This reduces size of MCUboot, remember -# though that when external image is needed the CONFIG_SPI_NOR -# has to be enabled. -CONFIG_SPI_NOR=n From c41aad6e1f385ab39cb3cedf89d83d11f466c422 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 059/204] Revert "[nrf noup] boot/zephyr/Kconfig: fix MBEDTLS_CFG_FILE value" This reverts commit 3aa07448fe8cf371e0cfb885132c347e485ab364. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 89328349f..f9913530c 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -428,6 +428,7 @@ config MBEDTLS_CFG_FILE # is used, but the fact is that Mbed TLS' ASN1 parse module is used # also when TinyCrypt is used as crypto backend. default "mcuboot-mbedtls-cfg.h" if BOOT_USE_TINYCRYPT + default "config-tls-generic.h" if NRF_SECURITY && (MBEDTLS_BUILTIN || BOOT_USE_PSA_CRYPTO) default "mcuboot-mbedtls-cfg.h" if BOOT_USE_MBEDTLS && !MBEDTLS_BUILTIN config BOOT_HW_KEY From b463825125f5397d003cc5b6581b68964577b114 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 060/204] Revert "[nrf fromlist] boot: zephyr: flash_map_extended: Add pointless workaround for clang" This reverts commit 4a10c05b2a133333a301676ff87ec8ac02947448. Signed-off-by: Jamie McCrae --- boot/zephyr/flash_map_extended.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index b2712acff..46f22dc58 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -66,8 +66,7 @@ int flash_device_base(uint8_t fd_id, uintptr_t *ret) */ int flash_area_id_from_multi_image_slot(int image_index, int slot) { - int rc; - int id = -1; + int rc, id; rc = BOOT_HOOK_FLASH_AREA_CALL(flash_area_id_from_multi_image_slot_hook, BOOT_HOOK_REGULAR, image_index, slot, &id); From fff8be2935fdbc3fe04ad2d40e1cd3f6be82cd8a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 061/204] Revert "[nrf noup] boot/zephyr/nrf_cleanup: cleanup uarte pins" This reverts commit f134edd150992d0a951dcf294b6ffb840919bf1c. Signed-off-by: Jamie McCrae --- boot/zephyr/nrf_cleanup.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 1252334ca..72c601db3 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -9,7 +9,6 @@ #endif #include #include -#include #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif @@ -97,21 +96,6 @@ void nrf_cleanup_peripheral(void) nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); nrfy_uarte_disable(current); - uint32_t pin[4]; - - pin[0] = nrfy_uarte_tx_pin_get(current); - pin[1] = nrfy_uarte_rx_pin_get(current); - pin[2] = nrfy_uarte_rts_pin_get(current); - pin[3] = nrfy_uarte_cts_pin_get(current); - - nrfy_uarte_pins_disconnect(current); - - for (int j = 0; j < 4; j++) { - if (pin[j] != NRF_UARTE_PSEL_DISCONNECTED) { - nrfy_gpio_cfg_default(pin[i]); - } - } - #if defined(NRF_DPPIC) /* Clear all SUBSCRIBE configurations. */ memset((uint8_t *)current + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, From 2b3b1ef29dcd9f3ea9abeb5124f410a5b55b6a17 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 062/204] Revert "[nrf noup] bootutil: key revocation" This reverts commit 6df89a84be878d912dad5d7a5c6a9c82d2bdbab2. Signed-off-by: Jamie McCrae --- .../include/bootutil/key_revocation.h | 30 -------------- boot/bootutil/src/ed25519_psa.c | 41 ------------------- boot/bootutil/src/key_revocation.c | 24 ----------- boot/bootutil/src/loader.c | 15 ------- boot/zephyr/CMakeLists.txt | 6 --- boot/zephyr/Kconfig | 12 ------ 6 files changed, 128 deletions(-) delete mode 100644 boot/bootutil/include/bootutil/key_revocation.h delete mode 100644 boot/bootutil/src/key_revocation.c diff --git a/boot/bootutil/include/bootutil/key_revocation.h b/boot/bootutil/include/bootutil/key_revocation.h deleted file mode 100644 index d184c9579..000000000 --- a/boot/bootutil/include/bootutil/key_revocation.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef H_KEY_REVOCATION_ -#define H_KEY_REVOCATION_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define BOOT_KEY_REVOKE_OK 0 -#define BOOT_KEY_REVOKE_NOT_READY 1 -#define BOOT_KEY_REVOKE_INVALID 2 -#define BOOT_KEY_REVOKE_FAILED 2 - - -void allow_revoke(void); - -int revoke(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index c94d99e61..3e9cf2cbd 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -32,11 +32,6 @@ static psa_key_id_t kmu_key_ids[3] = { MAKE_PSA_KMU_KEY_ID(230) }; -#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) -#include -static psa_key_id_t *validated_with = NULL; -#endif - BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(kmu_key_ids), "Invalid number of KMU slots, up to 3 are supported on nRF54L15"); #endif @@ -119,9 +114,6 @@ int ED25519_verify(const uint8_t *message, size_t message_len, EDDSA_SIGNAGURE_LENGTH); if (status == PSA_SUCCESS) { ret = 1; -#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) - validated_with = kmu_key_ids + i; -#endif break; } @@ -130,37 +122,4 @@ int ED25519_verify(const uint8_t *message, size_t message_len, return ret; } -#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) -int exec_revoke(void) -{ - int ret = BOOT_KEY_REVOKE_OK; - psa_status_t status = psa_crypto_init(); - - if (!validated_with) { - ret = BOOT_KEY_REVOKE_INVALID; - goto out; - } - - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed with error %d", status); - ret = BOOT_KEY_REVOKE_FAILED; - goto out; - } - for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; i++) { - if ((kmu_key_ids + i) == validated_with) { - break; - } - BOOT_LOG_DBG("Invalidating key ID %d", i); - - status = psa_destroy_key(kmu_key_ids[i]); - if (status == PSA_SUCCESS) { - BOOT_LOG_DBG("Success on key ID %d", i); - } else { - BOOT_LOG_ERR("Key invalidation failed with: %d", status); - } - } -out: - return ret; -} -#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */ #endif diff --git a/boot/bootutil/src/key_revocation.c b/boot/bootutil/src/key_revocation.c deleted file mode 100644 index 0768a3188..000000000 --- a/boot/bootutil/src/key_revocation.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#include - -extern int exec_revoke(void); - -static uint8_t ready_to_revoke; - -void allow_revoke(void) -{ - ready_to_revoke = 1; -} - -int revoke(void) -{ - if (ready_to_revoke) { - return exec_revoke(); - } - return BOOT_KEY_REVOKE_NOT_READY; -} diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index d19511be3..cc6ada00f 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -76,10 +76,6 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); #include "mcuboot_config/mcuboot_config.h" -#if defined(CONFIG_BOOT_KEYS_REVOCATION) -#include "bootutil/key_revocation.h" -#endif - BOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; @@ -2888,11 +2884,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } } -#if defined(CONFIG_BOOT_KEYS_REVOCATION) - if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) { - allow_revoke(); - } -#endif /* Iterate over all the images. At this point all required update operations * have finished. By the end of the loop each image in the primary slot will * have been re-validated. @@ -2998,12 +2989,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) fill_rsp(state, rsp); fih_rc = FIH_SUCCESS; -#if defined(CONFIG_BOOT_KEYS_REVOCATION) - rc = revoke(); - if (rc != BOOT_KEY_REVOKE_OK) { - FIH_SET(fih_rc, FIH_FAILURE); - } -#endif /* CONFIG_BOOT_KEYS_REVOCATION */ out: /* * Since the boot_status struct stores plaintext encryption keys, reset diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 2673ac9eb..7b291a37b 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -99,12 +99,6 @@ if(DEFINED CONFIG_BOOT_SHARE_BACKEND_RETENTION) ) endif() -if(DEFINED CONFIG_BOOT_KEYS_REVOCATION) - zephyr_library_sources( - ${BOOT_DIR}/bootutil/src/key_revocation.c -) -endif() - # Generic bootutil sources and includes. zephyr_library_include_directories(${BOOT_DIR}/bootutil/include) zephyr_library_sources( diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index f9913530c..9c5735f03 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -360,18 +360,6 @@ config BOOT_SIGNATURE_KMU_SLOTS endif -config BOOT_KEYS_REVOCATION - bool "Auto revoke previous gen key" - help - Automatically revoke previous generation key upon new valid key usage. - -config BOOT_KMU_KEYS_REVOCATION - bool - depends on BOOT_KEYS_REVOCATION - default y if BOOT_SIGNATURE_USING_KMU - help - Enabling KMU key revocation backend. - if !BOOT_SIGNATURE_USING_KMU config BOOT_SIGNATURE_KEY_FILE From 85e1a34070305eca27dac0b8ab9b083c115b7719 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 063/204] Revert "[nrf noup] boot: bootutil: loader: Fix monotomic counter update issues" This reverts commit 3bd17963688423aa7a1e139ce54572fa2c7c700f. Signed-off-by: Jamie McCrae --- boot/bootutil/include/bootutil/security_cnt.h | 9 --- boot/bootutil/src/image_validate.c | 20 ------ boot/bootutil/src/loader.c | 67 +------------------ 3 files changed, 1 insertion(+), 95 deletions(-) diff --git a/boot/bootutil/include/bootutil/security_cnt.h b/boot/bootutil/include/bootutil/security_cnt.h index 7e1389618..e1562d2e9 100644 --- a/boot/bootutil/include/bootutil/security_cnt.h +++ b/boot/bootutil/include/bootutil/security_cnt.h @@ -39,15 +39,6 @@ extern "C" { */ fih_ret boot_nv_security_counter_init(void); -/** - * Checks if the specified image should have a security counter present on it or not - * - * @param image_index Index of the image to check (from 0). - * - * @return FIH_SUCCESS if security counter should be present; FIH_FAILURE if otherwise - */ -fih_ret boot_nv_image_should_have_security_counter(uint32_t image_index); - /** * Reads the stored value of a given image's security counter. * diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index f7118e3e7..bb7aec148 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -527,15 +527,6 @@ bootutil_img_validate(struct boot_loader_state *state, fih_int security_cnt = fih_int_encode(INT_MAX); uint32_t img_security_cnt = 0; FIH_DECLARE(security_counter_valid, FIH_FAILURE); - FIH_DECLARE(security_counter_should_be_present, FIH_FAILURE); - - FIH_CALL(boot_nv_image_should_have_security_counter, security_counter_should_be_present, - image_index); - if (FIH_NOT_EQ(security_counter_should_be_present, FIH_SUCCESS) && - FIH_NOT_EQ(security_counter_should_be_present, FIH_FAILURE)) { - rc = -1; - goto out; - } #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES @@ -782,10 +773,6 @@ bootutil_img_validate(struct boot_loader_state *state, goto out; } - if (FIH_EQ(security_counter_should_be_present, FIH_FAILURE)) { - goto skip_security_counter_read; - } - FIH_CALL(boot_nv_security_counter_get, fih_rc, image_index, &security_cnt); if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { @@ -805,7 +792,6 @@ bootutil_img_validate(struct boot_loader_state *state, /* The image's security counter has been successfully verified. */ security_counter_valid = fih_rc; -skip_security_counter_read: break; } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ @@ -825,16 +811,10 @@ bootutil_img_validate(struct boot_loader_state *state, FIH_SET(fih_rc, valid_signature); #endif #ifdef MCUBOOT_HW_ROLLBACK_PROT - if (FIH_EQ(security_counter_should_be_present, FIH_FAILURE)) { - goto skip_security_counter_check; - } - if (FIH_NOT_EQ(security_counter_valid, FIH_SUCCESS)) { rc = -1; goto out; } - -skip_security_counter_check: #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index cc6ada00f..ddfe3793b 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1303,38 +1303,6 @@ boot_validate_slot(struct boot_loader_state *state, int slot, } #ifdef MCUBOOT_HW_ROLLBACK_PROT -/** - * Checks if the specified image should have a security counter present on it or not - * - * @param image_index Index of the image to check. - * - * @return true if security counter should be present; false if otherwise - */ -fih_ret boot_nv_image_should_have_security_counter(uint32_t image_index) -{ -#if defined(PM_S1_ADDRESS) - if (owner_nsib[image_index]) { - /* - * Downgrade prevention on S0/S1 image is managed by NSIB, which is a software (not - * hardware) check - */ - return FIH_FAILURE; - } -#endif - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 - if (image_index == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { - /* - * Downgrade prevention on network core image is managed by NSIB which is a software (not - * hardware) check - */ - return FIH_FAILURE; - } -#endif - - return FIH_SUCCESS; -} - /** * Updates the stored security counter value with the image's security counter * value which resides in the given slot, only if it's greater than the stored @@ -1356,26 +1324,6 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ uint32_t img_security_cnt; int rc; -#if defined(PM_S1_ADDRESS) - if (owner_nsib[BOOT_CURR_IMG(state)]) { - /* - * Downgrade prevention on S0/S1 image is managed by NSIB which is a software (not - * hardware) check - */ - return 0; - } -#endif - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { - /* - * Downgrade prevention on network core image is managed by NSIB which is a software (not - * hardware) check - */ - return 0; - } -#endif - fap = BOOT_IMG_AREA(state, slot); assert(fap != NULL); @@ -2626,20 +2574,7 @@ check_downgrade_prevention(struct boot_loader_state *state) #if defined(PM_S1_ADDRESS) if (owner_nsib[BOOT_CURR_IMG(state)]) { - /* - * Downgrade prevention on S0/S1 image is managed by NSIB which is a software (not - * hardware) check - */ - return 0; - } -#endif - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { - /* - * Downgrade prevention on network core image is managed by NSIB which is a software (not - * hardware) check - */ + /* Downgrade prevention on S0/S1 image is managed by NSIB */ return 0; } #endif From 57db3021917d585d3e976590697bc9ba8011d056 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 064/204] Revert "[nrf noup] zephyr: Allow hash only for nrf54l devices" This reverts commit d4f3b7dc7bd78b936c34469396e3e088b943a932. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 9c5735f03..493af7e60 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -214,8 +214,7 @@ choice BOOT_SIGNATURE_TYPE config BOOT_SIGNATURE_TYPE_NONE bool "No signature; use only hash check" - select BOOT_USE_TINYCRYPT if !SOC_SERIES_NRF54LX - select BOOT_USE_PSA_CRYPTO if SOC_SERIES_NRF54LX + select BOOT_USE_TINYCRYPT select BOOT_IMG_HASH_ALG_SHA256_ALLOW config BOOT_SIGNATURE_TYPE_RSA From 0e99cc3cd2cbceb373f012db0c94119bf08d0c1d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 065/204] Revert "[nrf noup] boot/zephyr: nrf54h20dk cleanup adaptations" This reverts commit b014be20f0a7d59ef0b67f6a278b7fbde91684f4. Signed-off-by: Jamie McCrae --- boot/zephyr/nrf_cleanup.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 72c601db3..051705ec9 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -4,9 +4,7 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ -#if !defined(CONFIG_SOC_SERIES_NRF54HX) #include -#endif #include #include #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) @@ -64,12 +62,10 @@ static NRF_UARTE_Type *nrf_uarte_to_clean[] = { }; #endif -#if !defined(CONFIG_SOC_SERIES_NRF54HX) static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); } -#endif void nrf_cleanup_peripheral(void) { @@ -113,10 +109,7 @@ void nrf_cleanup_peripheral(void) #if defined(NRF_DPPIC) nrf_dppi_channels_disable_all(NRF_DPPIC); #endif - -#if !defined(CONFIG_SOC_SERIES_NRF54HX) nrf_cleanup_clock(); -#endif } #if USE_PARTITION_MANAGER \ From b7fa28106ddc76b8e04eea4cc0bfd358d72d5868 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 066/204] Revert "[nrf noup] boot/zephyr: nrf54h20dk board support" This reverts commit 27d206562dad0d2f9bbbec9cab7b5ba6583a1496. Signed-off-by: Jamie McCrae --- .../boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf diff --git a/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf b/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf deleted file mode 100644 index 9c71c1d7e..000000000 --- a/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2025 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Ensure that the SPI NOR driver is disabled by default -CONFIG_SPI_NOR=n - -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - -CONFIG_BOOT_WATCHDOG_FEED=n - -CONFIG_MULTITHREADING=y \ No newline at end of file From 3bda233f6b0833bbab9984a26370582b75a04a67 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 067/204] Revert "[nrf fromlist] boot/zephyr: nrf54h20dk adaptations" This reverts commit 35474b0869b62005e79348cb3958519f0313dd38. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 1 - boot/zephyr/flash_map_extended.c | 6 ------ boot/zephyr/include/mcuboot_config/mcuboot_config.h | 3 --- boot/zephyr/include/target.h | 4 +--- 4 files changed, 1 insertion(+), 13 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 493af7e60..fc06ed3c6 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -987,7 +987,6 @@ config BOOT_WATCHDOG_FEED_NRFX_WDT imply NRFX_WDT1 imply NRFX_WDT30 imply NRFX_WDT31 - imply NRFX_WDT010 config BOOT_IMAGE_ACCESS_HOOKS bool "Enable hooks for overriding MCUboot's native routines" diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index 46f22dc58..68ae4f3b2 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -36,12 +36,6 @@ BOOT_LOG_MODULE_DECLARE(mcuboot); #define FLASH_DEVICE_BASE 0 #define FLASH_DEVICE_NODE DT_CHOSEN(zephyr_flash_controller) -#elif (defined(CONFIG_SOC_SERIES_NRF54HX) && DT_HAS_CHOSEN(zephyr_flash)) - -#define FLASH_DEVICE_ID SPI_FLASH_0_ID -#define FLASH_DEVICE_BASE CONFIG_FLASH_BASE_ADDRESS -#define FLASH_DEVICE_NODE DT_CHOSEN(zephyr_flash) - #else #error "FLASH_DEVICE_ID could not be determined" #endif diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 2bd5f98df..49854c754 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -398,9 +398,6 @@ #elif defined(CONFIG_NRFX_WDT31) #define MCUBOOT_WATCHDOG_FEED() \ FEED_WDT_INST(31); -#elif defined(CONFIG_NRFX_WDT010) -#define MCUBOOT_WATCHDOG_FEED() \ - FEED_WDT_INST(010); #else #error "No NRFX WDT instances enabled" #endif diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h index 856686785..40287d515 100644 --- a/boot/zephyr/include/target.h +++ b/boot/zephyr/include/target.h @@ -32,11 +32,9 @@ /* * Sanity check the target support. */ -#if (!defined(CONFIG_XTENSA) && !defined(CONFIG_SOC_SERIES_NRF54HX) && \ - !DT_HAS_CHOSEN(zephyr_flash_controller)) || \ +#if (!defined(CONFIG_XTENSA) && !DT_HAS_CHOSEN(zephyr_flash_controller)) || \ (defined(CONFIG_XTENSA) && !DT_NODE_EXISTS(DT_INST(0, jedec_spi_nor)) && \ !defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32)) || \ - (defined(CONFIG_SOC_SERIES_NRF54HX) && !DT_HAS_CHOSEN(zephyr_flash)) || \ !defined(FLASH_ALIGN) || \ !(FIXED_PARTITION_EXISTS(slot0_partition)) || \ !(FIXED_PARTITION_EXISTS(slot1_partition) || CONFIG_SINGLE_APPLICATION_SLOT) || \ From a0266e64f3bb7d46a52452510ed06c18bf60cd5c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 068/204] Revert "[nrf fromtree] boot: bootutil: Fix clash of STRUCT_PACKED definition" This reverts commit 72bcf3861f526d4091e3c2bf44a52823da8e7a11. Signed-off-by: Jamie McCrae --- boot/bootutil/include/bootutil/image.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 15de3e01a..f5431b187 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -36,14 +36,10 @@ extern "C" { #endif -#if defined(STRUCT_PACKED) -#undef STRUCT_PACKED -#endif - #if defined(__IAR_SYSTEMS_ICC__) -#define STRUCT_PACKED __packed struct + #define STRUCT_PACKED __packed struct #else -#define STRUCT_PACKED struct __attribute__((__packed__)) + #define STRUCT_PACKED struct __attribute__((__packed__)) #endif struct flash_area; From 082d33980c95af47a7cfa7b23f1312aad3ae7a7e Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 069/204] Revert "[nrf fromlist] docs: compression_format: Fix tags" This reverts commit 14cbca413937c36a1b417a2ac1888d2027720933. Signed-off-by: Jamie McCrae --- docs/compression_format.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/compression_format.md b/docs/compression_format.md index 78397da7c..ddb99d534 100644 --- a/docs/compression_format.md +++ b/docs/compression_format.md @@ -35,7 +35,7 @@ Compression parameters have the following default values: You can calculate the `dict_size` using the following method: -```c +``` {.c} unsigned int i = 0; for (i = 0; i < 40; i++) { @@ -103,14 +103,14 @@ The second byte of the `lzma2_header` carries the following parameters: These parameters are encoded with the following formula: - ```c + ``` {.c} pb_lp_lc = (uint8_t)((pb * 5 + lp) * 9 + lc); ``` To decode these values from the combined `pb_lp_lc` byte, run the following code: - ```c + ``` {.c} lc = pb_lp_lc % 9; pb_lp_lc /= 9; pb = pb_lp_lc / 5; @@ -132,13 +132,13 @@ steps: - Without an ARM thumb filter: - ```bash + ``` {.bash} unlzma --lzma2 --format=raw --suffix=.lzma raw.lzma ``` - With an ARM thumb filter: - ```bash + ``` {.bash} unlzma --armthumb --lzma2 --format=raw --suffix=.lzma raw.lzma ``` From 91f14f229a13aff80625ed46f1f91fbc75404230 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 070/204] Revert "[nrf fromtree] boot: zephyr: Only supply MBEDTLS config file path if set" This reverts commit dd65770fad1cf23a20e07aeb44128149a665a8c4. Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 7b291a37b..97fba4096 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -200,18 +200,18 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) ) endif() if(CONFIG_BOOT_USE_TINYCRYPT) - # When using ECDSA signatures, pull in our copy of the tinycrypt library. - zephyr_library_include_directories( - ${BOOT_DIR}/zephyr/include - ${TINYCRYPT_DIR}/include + # When using ECDSA signatures, pull in our copy of the tinycrypt library. + zephyr_library_include_directories( + ${BOOT_DIR}/zephyr/include + ${TINYCRYPT_DIR}/include ) - zephyr_include_directories(${TINYCRYPT_DIR}/include) + zephyr_include_directories(${TINYCRYPT_DIR}/include) - zephyr_library_sources( - ${TINYCRYPT_DIR}/source/ecc.c - ${TINYCRYPT_DIR}/source/ecc_dsa.c - ${TINYCRYPT_DIR}/source/sha256.c - ${TINYCRYPT_DIR}/source/utils.c + zephyr_library_sources( + ${TINYCRYPT_DIR}/source/ecc.c + ${TINYCRYPT_DIR}/source/ecc_dsa.c + ${TINYCRYPT_DIR}/source/sha256.c + ${TINYCRYPT_DIR}/source/utils.c ) elseif(CONFIG_BOOT_USE_NRF_CC310_BL) zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) @@ -221,14 +221,12 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() - if(CONFIG_MBEDTLS_CFG_FILE) - # Since here we are not using Zephyr's mbedTLS but rather our own, we need - # to set MBEDTLS_CONFIG_FILE ourselves. When using Zephyr's copy, this - # variable is set by its Kconfig in the Zephyr codebase. - zephyr_library_compile_definitions( - MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}" + # Since here we are not using Zephyr's mbedTLS but rather our own, we need + # to set MBEDTLS_CONFIG_FILE ourselves. When using Zephyr's copy, this + # variable is set by its Kconfig in the Zephyr codebase. + zephyr_library_compile_definitions( + MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}" ) - endif() elseif(CONFIG_BOOT_SIGNATURE_TYPE_NONE) zephyr_library_include_directories( ${BOOT_DIR}/zephyr/include From bf8f26412fc0fc1e5fdc6ef1f8bb80b10d5389b8 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 071/204] Revert "[nrf noup] zephyr: Use mbedTLS specific C functions with RSA" This reverts commit 03d9b4fb8cac4232f61971c2961a40907a154eb4. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index fc06ed3c6..052ecc9a0 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -223,8 +223,6 @@ config BOOT_SIGNATURE_TYPE_RSA select MBEDTLS select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN select MBEDTLS_KEY_EXCHANGE_RSA_ENABLED if MBEDTLS_BUILTIN - select MBEDTLS_PLATFORM_NO_STD_FUNCTIONS if MBEDTLS_BUILTIN - select MBEDTLS_PLATFORM_SNPRINTF_ALT if MBEDTLS_BUILTIN select BOOT_ENCRYPTION_SUPPORT select BOOT_IMG_HASH_ALG_SHA256_ALLOW select BOOT_AES_MBEDTLS_DEPENDENCIES if MBEDTLS_BUILTIN && BOOT_ENCRYPT_IMAGE From caf6384fe090031f8e199129988da76ff187e3a7 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 072/204] Revert "[nrf noup] boot: bootutil: Allow configuring number of KMU keys" This reverts commit 59987a6aa2d4c95e6f02d6ec9f8f9af94ecd834d. Signed-off-by: Jamie McCrae --- boot/bootutil/src/ed25519_psa.c | 7 ++----- boot/zephyr/Kconfig | 12 ------------ 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index 3e9cf2cbd..b6153f9a4 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -12,7 +12,6 @@ #include #include -#include #if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #include #endif @@ -31,9 +30,7 @@ static psa_key_id_t kmu_key_ids[3] = { MAKE_PSA_KMU_KEY_ID(228), MAKE_PSA_KMU_KEY_ID(230) }; - -BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(kmu_key_ids), - "Invalid number of KMU slots, up to 3 are supported on nRF54L15"); +#define KMU_KEY_COUNT (sizeof(kmu_key_ids)/sizeof(kmu_key_ids[0])) #endif #if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) @@ -106,7 +103,7 @@ int ED25519_verify(const uint8_t *message, size_t message_len, status = PSA_ERROR_BAD_STATE; - for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; ++i) { + for (int i = 0; i < KMU_KEY_COUNT; ++i) { psa_key_id_t kid = kmu_key_ids[i]; status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 052ecc9a0..87313c22c 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -345,18 +345,6 @@ config BOOT_SIGNATURE_USING_KMU MCUboot will use keys provisioned to the device key management unit for signature verification instead of compiling in key data from a file. -if BOOT_SIGNATURE_USING_KMU - -config BOOT_SIGNATURE_KMU_SLOTS - int "KMU key slots" - range 1 3 - default 1 - help - Selects the number of KMU key slots (also known as generations) to use when verifying - an image. - -endif - if !BOOT_SIGNATURE_USING_KMU config BOOT_SIGNATURE_KEY_FILE From e30e27c0a1d5226d8c0aa5f466f0e128fdc6c9f9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 073/204] Revert "[nrf noup] boot: zephyr: Add experimental selection to compression" This reverts commit 1c9556a24ee3952b649e366b9d399fb554f65ab3. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 87313c22c..bec163153 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -1045,10 +1045,9 @@ config BOOT_DECOMPRESSION_SUPPORT if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION - bool "Decompression [EXPERIMENTAL]" + bool "Decompression" select NRF_COMPRESS_CLEANUP select PM_USE_CONFIG_SRAM_SIZE if SOC_NRF54L15_CPUAPP - select EXPERIMENTAL help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to From ecce88097b3f7c80b2c3cfb5cccd4afa750b25e4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 074/204] Revert "[nrf noup] bootutil: Add support for KMU stored ED25519 signature key" This reverts commit 2ae98d5637e2fae869744cd96066915a271d9070. Signed-off-by: Jamie McCrae --- boot/bootutil/src/ed25519_psa.c | 51 ------------------------------ boot/bootutil/src/image_ed25519.c | 9 +----- boot/bootutil/src/image_validate.c | 12 ++----- boot/zephyr/CMakeLists.txt | 2 +- boot/zephyr/Kconfig | 26 --------------- 5 files changed, 4 insertions(+), 96 deletions(-) diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index b6153f9a4..12ba20ac1 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -12,9 +12,6 @@ #include #include -#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) -#include -#endif BOOT_LOG_MODULE_REGISTER(ed25519_psa); @@ -22,18 +19,6 @@ BOOT_LOG_MODULE_REGISTER(ed25519_psa); #define EDDSA_KEY_LENGTH 32 #define EDDSA_SIGNAGURE_LENGTH 64 -#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) -/* List of KMU stored key ids available for MCUboot */ -#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id) -static psa_key_id_t kmu_key_ids[3] = { - MAKE_PSA_KMU_KEY_ID(226), - MAKE_PSA_KMU_KEY_ID(228), - MAKE_PSA_KMU_KEY_ID(230) -}; -#define KMU_KEY_COUNT (sizeof(kmu_key_ids)/sizeof(kmu_key_ids[0])) -#endif - -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], const uint8_t public_key[EDDSA_KEY_LENGTH]) @@ -84,39 +69,3 @@ int ED25519_verify(const uint8_t *message, size_t message_len, return ret; } -#else -int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], - const uint8_t public_key[EDDSA_KEY_LENGTH]) -{ - ARG_UNUSED(public_key); - /* Set to any error */ - psa_status_t status = PSA_ERROR_BAD_STATE; - int ret = 0; /* Fail by default */ - - /* Initialize PSA Crypto */ - status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d", status); - return 0; - } - - status = PSA_ERROR_BAD_STATE; - - for (int i = 0; i < KMU_KEY_COUNT; ++i) { - psa_key_id_t kid = kmu_key_ids[i]; - - status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, - message_len, signature, - EDDSA_SIGNAGURE_LENGTH); - if (status == PSA_SUCCESS) { - ret = 1; - break; - } - - BOOT_LOG_ERR("ED25519 signature verification failed %d", status); - } - - return ret; -} -#endif diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index d5aee65bc..ffb8cec3b 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -31,7 +31,6 @@ extern int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[EDDSA_SIGNATURE_LENGTH], const uint8_t public_key[NUM_ED25519_BYTES]); -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #if !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) /* * Parse the public key used for signing. @@ -74,7 +73,6 @@ bootutil_import_key(uint8_t **cp, uint8_t *end) return 0; } #endif /* !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) */ -#endif /* Signature verification base function. * The function takes buffer of specified length and tries to verify @@ -89,17 +87,14 @@ bootutil_verify(uint8_t *buf, uint32_t blen, { int rc; FIH_DECLARE(fih_rc, FIH_FAILURE); - uint8_t *pubkey = NULL; -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) + uint8_t *pubkey; uint8_t *end; -#endif if (slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) pubkey = (uint8_t *)bootutil_keys[key_id].key; end = pubkey + *bootutil_keys[key_id].len; @@ -121,8 +116,6 @@ bootutil_verify(uint8_t *buf, uint32_t blen, } pubkey = end - NUM_ED25519_BYTES; -#endif - #endif rc = ED25519_verify(buf, blen, sig, pubkey); diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index bb7aec148..40f0aa857 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -280,7 +280,6 @@ bootutil_img_hash(struct boot_loader_state *state, # define KEY_BUF_SIZE (SIG_BUF_SIZE + 24) #endif /* !MCUBOOT_HW_KEY */ -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #if !defined(MCUBOOT_HW_KEY) static int bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len) @@ -346,7 +345,6 @@ bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len) } #endif /* !MCUBOOT_HW_KEY */ #endif /* !MCUBOOT_BUILTIN_KEY */ -#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */ #endif /* EXPECTED_SIG_TLV */ /** @@ -689,7 +687,6 @@ bootutil_img_validate(struct boot_loader_state *state, break; } #endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */ -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #ifdef EXPECTED_KEY_TLV case EXPECTED_KEY_TLV: { @@ -720,17 +717,14 @@ bootutil_img_validate(struct boot_loader_state *state, break; } #endif /* EXPECTED_KEY_TLV */ -#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */ #ifdef EXPECTED_SIG_TLV case EXPECTED_SIG_TLV: { -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) /* Ignore this signature if it is out of bounds. */ if (key_id < 0 || key_id >= bootutil_key_cnt) { key_id = -1; continue; } -#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */ if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { rc = -1; goto out; @@ -876,7 +870,7 @@ bootutil_img_validate(struct boot_loader_state *state, } #ifdef EXPECTED_SIG_TLV -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) && defined(EXPECTED_KEY_TLV) +#ifdef EXPECTED_KEY_TLV rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); if (rc) { goto out; @@ -922,7 +916,7 @@ bootutil_img_validate(struct boot_loader_state *state, */ } } -#endif /* !CONFIG_BOOT_SIGNATURE_USING_KMU && EXPECTED_KEY_TLV */ +#endif /* EXPECTED_KEY_TLV */ rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true); if (rc) { @@ -945,12 +939,10 @@ bootutil_img_validate(struct boot_loader_state *state, if (type == IMAGE_TLV_DECOMP_SIGNATURE) { /* Ignore this signature if it is out of bounds. */ -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) if (key_id < 0 || key_id >= bootutil_key_cnt) { key_id = -1; continue; } -#endif if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { rc = -1; diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 97fba4096..b7876bc9a 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -339,7 +339,7 @@ if(CONFIG_MCUBOOT_SERIAL) endif() endif() -if(NOT CONFIG_BOOT_SIGNATURE_USING_KMU AND NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") +if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") # CONF_FILE points to the KConfig configuration files of the bootloader. foreach (filepath ${CONF_FILE}) file(READ ${filepath} temp_text) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index bec163153..967a57f6f 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -331,22 +331,6 @@ endif endchoice -config BOOT_SIGNATURE_USING_KMU - bool "Use KMU stored keys for signature verification" - depends on NRF_SECURITY - depends on CRACEN_LIB_KMU - select PSA_WANT_ALG_GCM - select PSA_WANT_KEY_TYPE_AES - select PSA_WANT_AES_KEY_SIZE_256 - select PSA_WANT_ALG_SP800_108_COUNTER_CMAC - select PSA_WANT_ALG_CMAC - select PSA_WANT_ALG_ECB_NO_PADDING - help - MCUboot will use keys provisioned to the device key management unit for signature - verification instead of compiling in key data from a file. - -if !BOOT_SIGNATURE_USING_KMU - config BOOT_SIGNATURE_KEY_FILE string "PEM key file" default "root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 @@ -364,8 +348,6 @@ config BOOT_SIGNATURE_KEY_FILE with the public key information will be written in a format expected by MCUboot. -endif - config MCUBOOT_CLEANUP_ARM_CORE bool "Perform core cleanup before chain-load the application" depends on CPU_CORTEX_M @@ -388,14 +370,6 @@ config MCUBOOT_CLEANUP_RAM help Sets contents of memory to 0 before jumping to application. -# Disable MBEDTLS from being selected if NRF_SECURITY is enabled, and use default NRF_SECURITY -# configuration file for MBEDTLS -config MBEDTLS - depends on !NRF_SECURITY - -config NRF_SECURITY - select MBEDTLS_PROMPTLESS - config MBEDTLS_CFG_FILE # It might be awkward to define an Mbed TLS header file when TinyCrypt # is used, but the fact is that Mbed TLS' ASN1 parse module is used From 32286a15e8a0eb85054a5c0d53a3c1db1dcbad4a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 075/204] Revert "[nrf noup] zephyr: Add support for compressed image updates" This reverts commit b2fc324ba916c718f64130bfd40513d4be003cf9. Signed-off-by: Jamie McCrae --- boot/bootutil/src/bootutil_misc.c | 80 +- boot/bootutil/src/image_validate.c | 228 +-- boot/bootutil/src/loader.c | 27 +- boot/zephyr/CMakeLists.txt | 6 - boot/zephyr/Kconfig | 9 +- boot/zephyr/decompression.c | 1410 ----------------- .../include/compression/decompression.h | 103 -- 7 files changed, 24 insertions(+), 1839 deletions(-) delete mode 100644 boot/zephyr/decompression.c delete mode 100644 boot/zephyr/include/compression/decompression.h diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index c459059a9..476489e54 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -42,11 +42,6 @@ #include "bootutil/enc_key.h" #endif -#if defined(MCUBOOT_DECOMPRESS_IMAGES) -#include -#include -#endif - BOOT_LOG_MODULE_DECLARE(mcuboot); /* Currently only used by imgmgr */ @@ -466,76 +461,35 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) goto done; } -#ifdef MCUBOOT_DECOMPRESS_IMAGES - if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), boot_img_hdr(state, slot))) { - uint32_t tmp_size = 0; - - rc = bootutil_get_img_decomp_size(boot_img_hdr(state, slot), fap, &tmp_size); - - if (rc) { - rc = BOOT_EBADIMAGE; - goto done; - } - - off = boot_img_hdr(state, slot)->ih_hdr_size + tmp_size; + off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); - rc = boot_size_protected_tlvs(boot_img_hdr(state, slot), fap, &tmp_size); - - if (rc) { - rc = BOOT_EBADIMAGE; - goto done; - } - - off += tmp_size; - - if (flash_area_read(fap, (BOOT_TLV_OFF(boot_img_hdr(state, slot)) + - boot_img_hdr(state, slot)->ih_protect_tlv_size), &info, - sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } + if (flash_area_read(fap, off, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; + if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { + if (protect_tlv_size != info.it_tlv_tot) { rc = BOOT_EBADIMAGE; goto done; } - *size = off + info.it_tlv_tot; - } else { -#else - if (1) { -#endif - off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); - - if (flash_area_read(fap, off, &info, sizeof(info))) { + if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { rc = BOOT_EFLASH; goto done; } + } else if (protect_tlv_size != 0) { + rc = BOOT_EBADIMAGE; + goto done; + } - protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; - if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { - if (protect_tlv_size != info.it_tlv_tot) { - rc = BOOT_EBADIMAGE; - goto done; - } - - if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } - } else if (protect_tlv_size != 0) { - rc = BOOT_EBADIMAGE; - goto done; - } - - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { - rc = BOOT_EBADIMAGE; - goto done; - } - - *size = off + protect_tlv_size + info.it_tlv_tot; + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; } + *size = off + protect_tlv_size + info.it_tlv_tot; rc = 0; done: diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 40f0aa857..61cbf4de0 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -42,15 +42,6 @@ #include "mcuboot_config/mcuboot_config.h" -#if defined(MCUBOOT_DECOMPRESS_IMAGES) -#include -#include -#endif - -#include "bootutil/bootutil_log.h" - -BOOT_LOG_MODULE_DECLARE(mcuboot); - #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -493,7 +484,7 @@ bootutil_img_validate(struct boot_loader_state *state, #endif ) { -#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT) || defined(MCUBOOT_DECOMPRESS_IMAGES) +#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT) int image_index = (state == NULL ? 0 : BOOT_CURR_IMG(state)); #endif uint32_t off; @@ -527,68 +518,6 @@ bootutil_img_validate(struct boot_loader_state *state, FIH_DECLARE(security_counter_valid, FIH_FAILURE); #endif -#ifdef MCUBOOT_DECOMPRESS_IMAGES - /* If the image is compressed, the integrity of the image must also be validated */ - if (MUST_DECOMPRESS(fap, image_index, hdr)) { - bool found_decompressed_size = false; - bool found_decompressed_sha = false; - bool found_decompressed_signature = false; - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(state, fap)) { - rc = -1; - goto out; - } - - while (true) { - uint16_t expected_size = 0; - bool *found_flag = NULL; - - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - break; - } - - switch (type) { - case IMAGE_TLV_DECOMP_SIZE: - expected_size = sizeof(size_t); - found_flag = &found_decompressed_size; - break; - case IMAGE_TLV_DECOMP_SHA: - expected_size = IMAGE_HASH_SIZE; - found_flag = &found_decompressed_sha; - break; - case IMAGE_TLV_DECOMP_SIGNATURE: - found_flag = &found_decompressed_signature; - break; - default: - continue; - }; - - if (type == IMAGE_TLV_DECOMP_SIGNATURE && !EXPECTED_SIG_LEN(len)) { - rc = -1; - goto out; - } else if (type != IMAGE_TLV_DECOMP_SIGNATURE && len != expected_size) { - rc = -1; - goto out; - } - - *found_flag = true; - } - - rc = (!found_decompressed_size || !found_decompressed_sha || !found_decompressed_signature); - if (rc) { - goto out; - } - } -#endif - #if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) #if defined(MCUBOOT_SWAP_USING_OFFSET) && defined(MCUBOOT_SERIAL_RECOVERY) rc = bootutil_img_hash(state, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len, @@ -811,161 +740,6 @@ bootutil_img_validate(struct boot_loader_state *state, } #endif -#ifdef MCUBOOT_DECOMPRESS_IMAGES - /* Only after all previous verifications have passed, perform a dry-run of the decompression - * and ensure the image is valid - */ - if (!rc && MUST_DECOMPRESS(fap, image_index, hdr)) { - image_hash_valid = 0; - FIH_SET(valid_signature, FIH_FAILURE); - - rc = bootutil_img_hash_decompress(state, hdr, fap, tmp_buf, tmp_buf_sz, - hash, seed, seed_len); - if (rc) { - goto out; - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SHA, true); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(state, fap)) { - rc = -1; - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - break; - } - - if (type == IMAGE_TLV_DECOMP_SHA) { - /* Verify the image hash. This must always be present. */ - if (len != sizeof(hash)) { - rc = -1; - goto out; - } - rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, sizeof(hash)); - if (rc) { - goto out; - } - - FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash)); - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; - } - - image_hash_valid = 1; - } - } - - rc = !image_hash_valid; - if (rc) { - goto out; - } - -#ifdef EXPECTED_SIG_TLV -#ifdef EXPECTED_KEY_TLV - rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(state, fap)) { - rc = -1; - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - break; - } - - if (type == EXPECTED_KEY_TLV) { - /* - * Determine which key we should be checking. - */ - if (len > KEY_BUF_SIZE) { - rc = -1; - goto out; - } -#ifndef MCUBOOT_HW_KEY - rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); - if (rc) { - goto out; - } - key_id = bootutil_find_key(buf, len); -#else - rc = LOAD_IMAGE_DATA(hdr, fap, off, key_buf, len); - if (rc) { - goto out; - } - key_id = bootutil_find_key(image_index, key_buf, len); -#endif /* !MCUBOOT_HW_KEY */ - /* - * The key may not be found, which is acceptable. There - * can be multiple signatures, each preceded by a key. - */ - } - } -#endif /* EXPECTED_KEY_TLV */ - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true); - if (rc) { - goto out; - } - - if (it.tlv_end > bootutil_max_image_size(state, fap)) { - rc = -1; - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIGNATURE) { - /* Ignore this signature if it is out of bounds. */ - if (key_id < 0 || key_id >= bootutil_key_cnt) { - key_id = -1; - continue; - } - - if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { - rc = -1; - goto out; - } - rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); - if (rc) { - goto out; - } - - FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), - buf, len, key_id); - key_id = -1; - } - } -#endif /* EXPECTED_SIG_TLV */ - } -#endif - -#ifdef EXPECTED_SIG_TLV - FIH_SET(fih_rc, valid_signature); -#endif - out: if (rc) { FIH_SET(fih_rc, FIH_FAILURE); diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index ddfe3793b..12674359e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,11 +49,6 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" -#if defined(MCUBOOT_DECOMPRESS_IMAGES) -#include -#include -#endif - #ifdef __ZEPHYR__ #include #endif @@ -956,10 +951,10 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } #else - if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { - if (!boot_is_compressed_header_valid(hdr, fap, state)) { - return false; - } + if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && + (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) + { + return false; } #endif @@ -1204,7 +1199,6 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * attempts to validate and boot it. */ } - #if !defined(__BOOTSIM__) BOOT_LOG_ERR("Image in the %s slot is not valid!", (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary"); @@ -1682,9 +1676,6 @@ boot_copy_region(struct boot_loader_state *state, #else (void)state; #endif -#if defined(MCUBOOT_DECOMPRESS_IMAGES) && !defined(MCUBOOT_ENC_IMAGES) - struct image_header *hdr; -#endif TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4))); @@ -1710,16 +1701,6 @@ boot_copy_region(struct boot_loader_state *state, } #endif -#ifdef MCUBOOT_DECOMPRESS_IMAGES - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - - if (MUST_DECOMPRESS(fap_src, BOOT_CURR_IMG(state), hdr)) { - /* Use alternative function for compressed images */ - return boot_copy_region_decompress(state, fap_src, fap_dst, off_src, off_dst, sz, buf, - BUF_SZ); - } -#endif - bytes_copied = 0; while (bytes_copied < sz) { if (sz - bytes_copied > sizeof buf) { diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index b7876bc9a..acdc3f568 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -312,12 +312,6 @@ if(CONFIG_BOOT_ENCRYPT_EC256) ) endif() -if(CONFIG_BOOT_DECOMPRESSION) - zephyr_library_sources( - decompression.c - ) -endif() - if(CONFIG_MCUBOOT_SERIAL) zephyr_sources(${BOOT_DIR}/zephyr/serial_adapter.c) zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 967a57f6f..9535d4b5a 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -1010,9 +1010,6 @@ config BOOT_BANNER_STRING config BOOT_DECOMPRESSION_SUPPORT bool - depends on NRF_COMPRESS && NRF_COMPRESS_DECOMPRESSION && (NRF_COMPRESS_LZMA_VERSION_LZMA1 || NRF_COMPRESS_LZMA_VERSION_LZMA2) - depends on !SINGLE_APPLICATION_SLOT && BOOT_UPGRADE_ONLY - default y help Hidden symbol which should be selected if a system provided decompression support. @@ -1020,8 +1017,6 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" - select NRF_COMPRESS_CLEANUP - select PM_USE_CONFIG_SRAM_SIZE if SOC_NRF54L15_CPUAPP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to @@ -1030,9 +1025,9 @@ menuconfig BOOT_DECOMPRESSION if BOOT_DECOMPRESSION config BOOT_DECOMPRESSION_BUFFER_SIZE - int + int "Write buffer size" range 16 16384 - default NRF_COMPRESS_CHUNK_SIZE + default 4096 help The size of a secondary buffer used for writing decompressed data to the storage device. diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c deleted file mode 100644 index f49898d55..000000000 --- a/boot/zephyr/decompression.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#include -#include "compression/decompression.h" -#include "bootutil/crypto/sha.h" -#include "bootutil/bootutil_log.h" - -#if !defined(__BOOTSIM__) -#define TARGET_STATIC static -#else -#define TARGET_STATIC -#endif - -#if defined(MCUBOOT_SIGN_RSA) -#if MCUBOOT_SIGN_RSA_LEN == 2048 -#define EXPECTED_SIG_TLV IMAGE_TLV_RSA2048_PSS -#elif MCUBOOT_SIGN_RSA_LEN == 3072 -#define EXPECTED_SIG_TLV IMAGE_TLV_RSA3072_PSS -#endif -#elif defined(MCUBOOT_SIGN_EC256) || \ - defined(MCUBOOT_SIGN_EC384) || \ - defined(MCUBOOT_SIGN_EC) -#define EXPECTED_SIG_TLV IMAGE_TLV_ECDSA_SIG -#elif defined(MCUBOOT_SIGN_ED25519) -#define EXPECTED_SIG_TLV IMAGE_TLV_ED25519 -#endif - -#define DECOMP_BUF_SIZE CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE -#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) -#define DECOMP_BUF_EXTRA_SIZE 2 -#else -#define DECOMP_BUF_EXTRA_SIZE 0 -#endif -#define DECOMP_BUF_ALLOC_SIZE (DECOMP_BUF_SIZE + DECOMP_BUF_EXTRA_SIZE) - -/* Number of times that consumed data by decompression system can be 0 in a row before aborting */ -#define OFFSET_ZERO_CHECK_TIMES 3 - -BOOT_LOG_MODULE_DECLARE(mcuboot); - -static int boot_sha_protected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, uint32_t protected_size, - uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx); - -bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, - struct boot_loader_state *state) -{ - /* Image is compressed in secondary slot, need to check if fits into the primary slot */ - bool opened_flash_area = false; - int primary_fa_id; - int rc; - int size_check; - int size; - uint32_t protected_tlvs_size; - uint32_t decompressed_size; - - primary_fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT); - - if (primary_fa_id == fap->fa_id) { - BOOT_LOG_ERR("Primary slots cannot be compressed, image: %d", BOOT_CURR_IMG(state)); - return false; - } - - if (BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT) == NULL) { - opened_flash_area = true; - } - - rc = flash_area_open(primary_fa_id, &BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); - assert(rc == 0); - - size_check = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); - - if (opened_flash_area) { - (void)flash_area_close(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); - } - - rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_size); - - if (rc) { - return false; - } - - if (!boot_u32_safe_add(&size, decompressed_size, hdr->ih_hdr_size)) { - return false; - } - - rc = boot_size_protected_tlvs(hdr, fap, &protected_tlvs_size); - - if (rc) { - return false; - } - - if (!boot_u32_safe_add(&size, size, protected_tlvs_size)) { - return false; - } - - if (size >= size_check) { - BOOT_LOG_ERR("Compressed image too large, decompressed image size: 0x%x, slot size: 0x%x", - size, size_check); - return false; - } - - return true; -} - -static bool is_compression_object_valid(struct nrf_compress_implementation *compression) -{ - if (compression == NULL || compression->init == NULL || compression->deinit == NULL || - compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { - return false; - } - - return true; -} - -#ifdef MCUBOOT_ENC_IMAGES -int bootutil_get_img_decrypted_comp_size(const struct image_header *hdr, - const struct flash_area *fap, uint32_t *img_comp_size) -{ - if (hdr == NULL || fap == NULL || img_comp_size == NULL) { - return BOOT_EBADARGS; - } else if (hdr->ih_protect_tlv_size == 0) { - return BOOT_EBADIMAGE; - } - - if (!IS_ENCRYPTED(hdr)) { - /* Update is not encrypted so use size from header */ - *img_comp_size = hdr->ih_img_size; - } else { - struct image_tlv_iter it; - uint32_t off; - uint16_t len; - int32_t rc; - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_COMP_DEC_SIZE, true); - - if (rc) { - return rc; - } - - rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); - - if (rc != 0) { - return -1; - } - - if (len != sizeof(*img_comp_size)) { - BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); - return BOOT_EBADIMAGE; - } - - rc = LOAD_IMAGE_DATA(hdr, fap, off, img_comp_size, len); - - if (rc) { - BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - off, len, fap->fa_id, rc); - return BOOT_EFLASH; - } - } - - return 0; -} -#endif - -int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_header *hdr, - const struct flash_area *fap, uint8_t *tmp_buf, - uint32_t tmp_buf_sz, uint8_t *hash_result, - uint8_t *seed, int seed_len) -{ - int rc; - uint32_t read_pos = 0; - uint32_t write_pos = 0; - uint32_t protected_tlv_size = 0; - uint32_t decompressed_image_size; - uint32_t output_size_total = 0; - struct nrf_compress_implementation *compression_lzma = NULL; - struct nrf_compress_implementation *compression_arm_thumb = NULL; - TARGET_STATIC struct image_header modified_hdr; - bootutil_sha_context sha_ctx; - uint8_t flash_erased_value; - -#ifdef MCUBOOT_ENC_IMAGES - struct enc_key_data *enc_state; - int image_index; - uint32_t comp_size = 0; - - rc = bootutil_get_img_decrypted_comp_size(hdr, fap, &comp_size); - - if (rc) { - BOOT_LOG_ERR("Invalid/missing image decrypted compressed size value"); - rc = BOOT_EBADIMAGE; - goto finish_end; - } - - if (state == NULL) { - enc_state = NULL; - image_index = 0; - } else { - enc_state = BOOT_CURR_ENC(state); - image_index = BOOT_CURR_IMG(state); - } - - /* Encrypted images only exist in the secondary slot */ - if (MUST_DECRYPT(fap, image_index, hdr) && - !boot_enc_valid(enc_state, 1)) { - return -1; - } -#endif - - bootutil_sha_init(&sha_ctx); - - /* Setup decompression system */ -#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { -#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { -#endif - /* Compressed image does not use the correct compression type which is supported by this - * build - */ - BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); - rc = BOOT_EBADIMAGE; - goto finish_without_clean; - } - - compression_lzma = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); - compression_arm_thumb = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_ARM_THUMB); - - if (!is_compression_object_valid(compression_lzma) || - !is_compression_object_valid(compression_arm_thumb)) { - /* Compression library missing or missing required function pointer */ - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - goto finish_without_clean; - } - - rc = compression_lzma->init(NULL); - rc = compression_arm_thumb->init(NULL); - - if (rc) { - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - goto finish_without_clean; - } - - /* We need a modified header which has the updated sizes, start with the original header */ - memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); - - /* Extract the decompressed image size from the protected TLV, set it and remove the - * compressed image flags - */ - rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_image_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; - modified_hdr.ih_img_size = decompressed_image_size; - - /* Calculate the protected TLV size, these will not include the decompressed - * sha/size/signature entries - */ - rc = boot_size_protected_tlvs(hdr, fap, &protected_tlv_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - modified_hdr.ih_protect_tlv_size = protected_tlv_size; - bootutil_sha_update(&sha_ctx, &modified_hdr, sizeof(modified_hdr)); - read_pos = sizeof(modified_hdr); - flash_erased_value = flash_area_erased_val(fap); - memset(tmp_buf, flash_erased_value, tmp_buf_sz); - - while (read_pos < modified_hdr.ih_hdr_size) { - uint32_t copy_size = tmp_buf_sz; - - if ((read_pos + copy_size) > modified_hdr.ih_hdr_size) { - copy_size = modified_hdr.ih_hdr_size - read_pos; - } - - bootutil_sha_update(&sha_ctx, tmp_buf, copy_size); - read_pos += copy_size; - } - - /* Read in compressed data, decompress and add to hash calculation */ - read_pos = 0; - -#ifdef MCUBOOT_ENC_IMAGES - while (read_pos < comp_size) { - uint32_t copy_size = comp_size - read_pos; -#else - while (read_pos < hdr->ih_img_size) { - uint32_t copy_size = hdr->ih_img_size - read_pos; -#endif - uint32_t tmp_off = 0; - uint8_t offset_zero_check = 0; - - if (copy_size > tmp_buf_sz) { - copy_size = tmp_buf_sz; - } - - rc = flash_area_read(fap, (hdr->ih_hdr_size + read_pos), tmp_buf, copy_size); - - if (rc != 0) { - BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (hdr->ih_hdr_size + read_pos), copy_size, fap->fa_id, rc); - rc = BOOT_EFLASH; - goto finish; - } - -#ifdef MCUBOOT_ENC_IMAGES - if (MUST_DECRYPT(fap, image_index, hdr)) { - boot_enc_decrypt(enc_state, 1, read_pos, - copy_size, (read_pos & 0xf), - tmp_buf); - } -#endif - - /* Decompress data in chunks, writing it back with a larger write offset of the primary - * slot than read size of the secondary slot - */ - while (tmp_off < copy_size) { - uint32_t offset = 0; - uint8_t *output = NULL; - uint32_t output_size = 0; - uint32_t chunk_size; - bool last_packet = false; - - chunk_size = compression_lzma->decompress_bytes_needed(NULL); - - if (chunk_size > (copy_size - tmp_off)) { - chunk_size = (copy_size - tmp_off); - } - -#ifdef MCUBOOT_ENC_IMAGES - if ((read_pos + tmp_off + chunk_size) >= comp_size) { -#else - if ((read_pos + tmp_off + chunk_size) >= hdr->ih_img_size) { -#endif - last_packet = true; - } - - rc = compression_lzma->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, - &offset, &output, &output_size); - - if (rc) { - BOOT_LOG_ERR("Decompression error: %d", rc); - rc = BOOT_EBADSTATUS; - goto finish; - } - - write_pos += output_size; - - if (write_pos > decompressed_image_size) { - BOOT_LOG_ERR("Decompressed image larger than claimed TLV size, at least: %d", - write_pos); - rc = BOOT_EBADIMAGE; - goto finish; - } - - /* Additional dry-run validity checks */ - if (last_packet == true && write_pos == 0) { - /* Last packet and we still have no output, this is a faulty update */ - BOOT_LOG_ERR("All compressed data consumed without any output, image not valid"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - if (offset == 0) { - /* If the decompression system continually consumes 0 bytes, then there is a - * problem with this update image, abort and mark image as bad - */ - if (offset_zero_check >= OFFSET_ZERO_CHECK_TIMES) { - BOOT_LOG_ERR("Decompression system returning no output data, image not valid"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - ++offset_zero_check; - - break; - } else { - offset_zero_check = 0; - } - - /* Copy data to secondary buffer for calculating hash */ - if (output_size > 0) { - if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { - /* Run this through the ARM thumb filter */ - uint32_t offset_arm_thumb = 0; - uint8_t *output_arm_thumb = NULL; - uint32_t processed_size = 0; - uint32_t output_size_arm_thumb = 0; - - while (processed_size < output_size) { - uint32_t current_size = output_size - processed_size; - bool arm_thumb_last_packet = false; - - if (current_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE) { - current_size = CONFIG_NRF_COMPRESS_CHUNK_SIZE; - } - - if (last_packet && (processed_size + current_size) == - output_size) { - arm_thumb_last_packet = true; - } - - rc = compression_arm_thumb->decompress(NULL, &output[processed_size], - current_size, arm_thumb_last_packet, - &offset_arm_thumb, - &output_arm_thumb, - &output_size_arm_thumb); - - if (rc) { - BOOT_LOG_ERR("Decompression error: %d", rc); - rc = BOOT_EBADSTATUS; - goto finish; - } - - bootutil_sha_update(&sha_ctx, output_arm_thumb, output_size_arm_thumb); - output_size_total += output_size_arm_thumb; - processed_size += current_size; - } - } else { - bootutil_sha_update(&sha_ctx, output, output_size); - output_size_total += output_size; - } - } - - tmp_off += offset; - } - - read_pos += copy_size; - } - - if (modified_hdr.ih_img_size != output_size_total) { - BOOT_LOG_ERR("Decompression expected output_size mismatch: %d vs %d", - modified_hdr.ih_img_size, output_size_total); - rc = BOOT_EBADSTATUS; - goto finish; - } - - /* If there are any protected TLVs present, add them after the main decompressed image */ - if (modified_hdr.ih_protect_tlv_size > 0) { - rc = boot_sha_protected_tlvs(hdr, fap, modified_hdr.ih_protect_tlv_size, tmp_buf, - tmp_buf_sz, &sha_ctx); - } - - bootutil_sha_finish(&sha_ctx, hash_result); - -finish: - /* Clean up decompression system */ - (void)compression_lzma->deinit(NULL); - (void)compression_arm_thumb->deinit(NULL); - -finish_without_clean: - bootutil_sha_drop(&sha_ctx); - -#ifdef MCUBOOT_ENC_IMAGES -finish_end: -#endif - return rc; -} - -static int boot_copy_protected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_dst, - uint32_t protected_size, uint8_t *buf, size_t buf_size, - uint16_t *buf_pos, uint32_t *written) -{ - int rc; - uint32_t off; - uint32_t write_pos = 0; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - struct image_tlv tlv_header; - struct image_tlv_info tlv_info_header = { - .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, - .it_tlv_tot = protected_size, - }; - uint16_t info_size_left = sizeof(tlv_info_header); - - while (info_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - - if (info_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; - - if (single_copy_size > info_size_left) { - single_copy_size = info_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - - info_size_left], single_copy_size); - *buf_pos += single_copy_size; - info_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { - /* Skip these TLVs as they are not needed */ - continue; - } else { - uint16_t header_size_left = sizeof(tlv_header); - uint16_t data_size_left = len; - - tlv_header.it_type = type; - tlv_header.it_len = len; - - while (header_size_left > 0 || data_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - uint8_t *tlv_header_address = (uint8_t *)&tlv_header; - - if (header_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - - if (single_copy_size > header_size_left) { - single_copy_size = header_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - - header_size_left], - single_copy_size); - *buf_pos += single_copy_size; - copy_size -= single_copy_size; - header_size_left -= single_copy_size; - } - - if (data_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - - if (single_copy_size > data_size_left) { - single_copy_size = data_size_left; - } - - rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + (len - data_size_left)), - &buf[*buf_pos], single_copy_size); - - if (rc) { - BOOT_LOG_ERR( - "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); - goto out; - } - - *buf_pos += single_copy_size; - data_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR( - "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - } - } - - *written = write_pos; - -out: - return rc; -} - -static int boot_sha_protected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, uint32_t protected_size, - uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx) -{ - int rc; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - struct image_tlv tlv_header; - struct image_tlv_info tlv_info_header = { - .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, - .it_tlv_tot = protected_size, - }; - - bootutil_sha_update(sha_ctx, &tlv_info_header, sizeof(tlv_info_header)); - - rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); - if (rc) { - goto out; - } - - while (true) { - uint32_t read_off = 0; - - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { - /* Skip these TLVs as they are not needed */ - continue; - } - - tlv_header.it_type = type; - tlv_header.it_len = len; - - bootutil_sha_update(sha_ctx, &tlv_header, sizeof(tlv_header)); - - while (read_off < len) { - uint32_t copy_size = buf_size; - - if (copy_size > (len - read_off)) { - copy_size = len - read_off; - } - - rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + read_off), buf, copy_size); - - if (rc) { - BOOT_LOG_ERR( - "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off + read_off), copy_size, fap_src->fa_id, rc); - goto out; - } - - bootutil_sha_update(sha_ctx, buf, copy_size); - read_off += copy_size; - } - } - -out: - return rc; -} - -int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *sz) -{ - int rc = 0; - uint32_t tlv_size; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - - *sz = 0; - tlv_size = hdr->ih_protect_tlv_size; - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - - if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || - type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { - /* Exclude these TLVs as they will be copied to the unprotected area */ - tlv_size -= len + sizeof(struct image_tlv); - } - } - - if (!rc) { - if (tlv_size == sizeof(struct image_tlv_info)) { - /* If there are no entries then omit protected TLV section entirely */ - tlv_size = 0; - } - - *sz = tlv_size; - } - -out: - return rc; -} - -int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *sz) -{ - int rc = 0; - uint32_t tlv_size; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - - *sz = 0; - tlv_size = sizeof(struct image_tlv_info); - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } else if (bootutil_tlv_iter_is_prot(&it, off) && type != IMAGE_TLV_DECOMP_SHA && - type != IMAGE_TLV_DECOMP_SIGNATURE) { - /* Include size of protected hash and signature as these will be replacing the - * original ones - */ - continue; - } else if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV || type == IMAGE_TLV_COMP_DEC_SIZE) { - /* Exclude the original unprotected TLVs for signature and hash, the length of the - * signature of the compressed data might not be the same size as the signaute of the - * decompressed data, as is the case when using ECDSA-P256 - */ - continue; - } - - tlv_size += len + sizeof(struct image_tlv); - } - - if (!rc) { - if (tlv_size == sizeof(struct image_tlv_info)) { - /* If there are no entries in the unprotected TLV section then there is something wrong - * with this image - */ - BOOT_LOG_ERR("No unprotected TLVs in post-decompressed image output, image is invalid"); - rc = BOOT_EBADIMAGE; - goto out; - } - - *sz = tlv_size; - } - -out: - return rc; -} - -static int boot_copy_unprotected_tlvs(const struct image_header *hdr, - const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_dst, - uint32_t unprotected_size, uint8_t *buf, size_t buf_size, - uint16_t *buf_pos, uint32_t *written) -{ - int rc; - uint32_t write_pos = 0; - uint32_t off; - uint16_t len; - uint16_t type; - struct image_tlv_iter it; - struct image_tlv_iter it_protected; - struct image_tlv tlv_header; - struct image_tlv_info tlv_info_header = { - .it_magic = IMAGE_TLV_INFO_MAGIC, - .it_tlv_tot = unprotected_size, - }; - uint16_t info_size_left = sizeof(tlv_info_header); - - while (info_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - - if (info_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; - - if (single_copy_size > info_size_left) { - single_copy_size = info_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - - info_size_left], single_copy_size); - *buf_pos += single_copy_size; - info_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, false); - if (rc) { - goto out; - } - - while (true) { - uint16_t header_size_left = sizeof(tlv_header); - uint16_t data_size_left; - - rc = bootutil_tlv_iter_next(&it, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } else if (bootutil_tlv_iter_is_prot(&it, off)) { - /* Skip protected TLVs */ - continue; - } - - /* Change the values of these fields from having the data in the compressed image - * unprotected TLV (which is valid only for the compressed image data) to having the - * fields in the protected TLV section (which is valid for the decompressed image data). - * The compressed data is no longer needed - */ - if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV) { - rc = bootutil_tlv_iter_begin(&it_protected, hdr, fap_src, (type == EXPECTED_HASH_TLV ? - IMAGE_TLV_DECOMP_SHA : - IMAGE_TLV_DECOMP_SIGNATURE), - true); - - if (rc) { - goto out; - } - - while (true) { - rc = bootutil_tlv_iter_next(&it_protected, &off, &len, &type); - if (rc < 0) { - goto out; - } else if (rc > 0) { - rc = 0; - break; - } - } - - if (type == IMAGE_TLV_DECOMP_SHA) { - type = EXPECTED_HASH_TLV; - } else { - type = EXPECTED_SIG_TLV; - } - } - - data_size_left = len; - tlv_header.it_type = type; - tlv_header.it_len = len; - - while (header_size_left > 0 || data_size_left > 0) { - uint16_t copy_size = buf_size - *buf_pos; - - if (header_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - uint8_t *tlv_header_address = (uint8_t *)&tlv_header; - - if (single_copy_size > header_size_left) { - single_copy_size = header_size_left; - } - - memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - header_size_left], - single_copy_size); - *buf_pos += single_copy_size; - copy_size -= single_copy_size; - header_size_left -= single_copy_size; - } - - if (data_size_left > 0 && copy_size > 0) { - uint16_t single_copy_size = copy_size; - - if (single_copy_size > data_size_left) { - single_copy_size = data_size_left; - } - - rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + len - data_size_left), - &buf[*buf_pos], single_copy_size); - - if (rc) { - BOOT_LOG_ERR( - "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); - goto out; - } - - *buf_pos += single_copy_size; - data_size_left -= single_copy_size; - } - - if (*buf_pos == buf_size) { - rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); - - if (rc != 0) { - BOOT_LOG_ERR( - "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto out; - } - - write_pos += *buf_pos; - *buf_pos = 0; - } - } - } - - *written = write_pos; - -out: - return rc; -} - -int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_src, - uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size) -{ - int rc; - uint32_t pos = 0; - uint16_t decomp_buf_size = 0; - uint16_t write_alignment; - uint32_t write_pos = 0; - uint32_t protected_tlv_size = 0; - uint32_t unprotected_tlv_size = 0; - uint32_t tlv_write_size = 0; - uint32_t decompressed_image_size; - struct nrf_compress_implementation *compression_lzma = NULL; - struct nrf_compress_implementation *compression_arm_thumb = NULL; - struct image_header *hdr; - TARGET_STATIC uint8_t decomp_buf[DECOMP_BUF_ALLOC_SIZE] __attribute__((aligned(4))); - TARGET_STATIC struct image_header modified_hdr; - -#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) - uint8_t excess_data_buffer[DECOMP_BUF_EXTRA_SIZE]; - bool excess_data_buffer_full = false; -#endif - -#ifdef MCUBOOT_ENC_IMAGES - uint32_t comp_size = 0; -#endif - - hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); - -#ifdef MCUBOOT_ENC_IMAGES - rc = bootutil_get_img_decrypted_comp_size(hdr, fap_src, &comp_size); - - if (rc) { - BOOT_LOG_ERR("Invalid/missing image decrypted compressed size value"); - rc = BOOT_EBADIMAGE; - goto finish; - } -#endif - - /* Setup decompression system */ -#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { -#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 - if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { -#endif - /* Compressed image does not use the correct compression type which is supported by this - * build - */ - BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - compression_lzma = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); - compression_arm_thumb = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_ARM_THUMB); - - if (!is_compression_object_valid(compression_lzma) || - !is_compression_object_valid(compression_arm_thumb)) { - /* Compression library missing or missing required function pointer */ - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - goto finish; - } - - rc = compression_lzma->init(NULL); - rc = compression_arm_thumb->init(NULL); - - if (rc) { - BOOT_LOG_ERR("Decompression library fatal error"); - rc = BOOT_EBADSTATUS; - goto finish; - } - - write_alignment = flash_area_align(fap_dst); - - memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); - - rc = bootutil_get_img_decomp_size(hdr, fap_src, &decompressed_image_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; - modified_hdr.ih_img_size = decompressed_image_size; - - /* Calculate protected TLV size for target image once items are removed */ - rc = boot_size_protected_tlvs(hdr, fap_src, &protected_tlv_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - modified_hdr.ih_protect_tlv_size = protected_tlv_size; - - rc = boot_size_unprotected_tlvs(hdr, fap_src, &unprotected_tlv_size); - - if (rc) { - BOOT_LOG_ERR("Unable to determine unprotected TLV size of compressed image"); - rc = BOOT_EBADIMAGE; - goto finish; - } - - /* Write out the image header first, this should be a multiple of the write size */ - rc = flash_area_write(fap_dst, off_dst, &modified_hdr, sizeof(modified_hdr)); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - off_dst, sizeof(modified_hdr), fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto finish; - } - - /* Read in, decompress and write out data */ -#ifdef MCUBOOT_ENC_IMAGES - while (pos < comp_size) { - uint32_t copy_size = comp_size - pos; -#else - while (pos < hdr->ih_img_size) { - uint32_t copy_size = hdr->ih_img_size - pos; -#endif - uint32_t tmp_off = 0; - - if (copy_size > buf_size) { - copy_size = buf_size; - } - - rc = flash_area_read(fap_src, off_src + hdr->ih_hdr_size + pos, buf, copy_size); - - if (rc != 0) { - BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_src + hdr->ih_hdr_size + pos), copy_size, fap_src->fa_id, rc); - rc = BOOT_EFLASH; - goto finish; - } - -#ifdef MCUBOOT_ENC_IMAGES - if (IS_ENCRYPTED(hdr)) { - boot_enc_decrypt(BOOT_CURR_ENC(state), 1, pos, copy_size, (pos & 0xf), buf); - } -#endif - - /* Decompress data in chunks, writing it back with a larger write offset of the primary - * slot than read size of the secondary slot - */ - while (tmp_off < copy_size) { - uint32_t offset = 0; - uint32_t output_size = 0; - uint32_t chunk_size; - uint32_t compression_buffer_pos = 0; - uint8_t *output = NULL; - bool last_packet = false; - - chunk_size = compression_lzma->decompress_bytes_needed(NULL); - - if (chunk_size > (copy_size - tmp_off)) { - chunk_size = (copy_size - tmp_off); - } - -#ifdef MCUBOOT_ENC_IMAGES - if ((pos + tmp_off + chunk_size) >= comp_size) { -#else - if ((pos + tmp_off + chunk_size) >= hdr->ih_img_size) { -#endif - last_packet = true; - } - - rc = compression_lzma->decompress(NULL, &buf[tmp_off], chunk_size, last_packet, - &offset, &output, &output_size); - - if (rc) { - BOOT_LOG_ERR("Decompression error: %d", rc); - rc = BOOT_EBADSTATUS; - goto finish; - } - - /* Copy data to secondary buffer for writing out */ - while (output_size > 0) { - uint32_t data_size = (DECOMP_BUF_SIZE - decomp_buf_size); - - if (data_size > output_size) { - data_size = output_size; - } - -#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) - if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { - memcpy(&decomp_buf[decomp_buf_size + DECOMP_BUF_EXTRA_SIZE], - &output[compression_buffer_pos], data_size); - } else -#endif - { - memcpy(&decomp_buf[decomp_buf_size], &output[compression_buffer_pos], - data_size); - } - - compression_buffer_pos += data_size; - - decomp_buf_size += data_size; - output_size -= data_size; - - /* Write data out from secondary buffer when it is full */ - if (decomp_buf_size == DECOMP_BUF_SIZE) { -#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) - if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { - uint32_t filter_writeback_pos = 0; - uint32_t processed_size = 0; - - /* Run this through the ARM thumb filter */ - while (processed_size < DECOMP_BUF_SIZE) { - uint32_t offset_arm_thumb = 0; - uint32_t output_size_arm_thumb = 0; - uint8_t *output_arm_thumb = NULL; - uint32_t current_size = DECOMP_BUF_SIZE; - bool arm_thumb_last_packet = false; - - if (current_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE) { - current_size = CONFIG_NRF_COMPRESS_CHUNK_SIZE; - } - - if (last_packet && (processed_size + current_size) == DECOMP_BUF_SIZE - && output_size == 0) { - arm_thumb_last_packet = true; - } - - rc = compression_arm_thumb->decompress(NULL, - &decomp_buf[processed_size + - DECOMP_BUF_EXTRA_SIZE], - current_size, - arm_thumb_last_packet, - &offset_arm_thumb, - &output_arm_thumb, - &output_size_arm_thumb); - - if (rc) { - BOOT_LOG_ERR("Decompression error: %d", rc); - rc = BOOT_EBADSTATUS; - goto finish; - } - - memcpy(&decomp_buf[filter_writeback_pos], output_arm_thumb, - output_size_arm_thumb); - filter_writeback_pos += output_size_arm_thumb; - processed_size += current_size; - } - - if (excess_data_buffer_full == true) - { - /* Restore extra data removed from previous iteration to the write - * buffer - */ - memmove(&decomp_buf[DECOMP_BUF_EXTRA_SIZE], decomp_buf, - filter_writeback_pos); - memcpy(decomp_buf, excess_data_buffer, DECOMP_BUF_EXTRA_SIZE); - excess_data_buffer_full = false; - filter_writeback_pos += DECOMP_BUF_EXTRA_SIZE; - } - - if ((filter_writeback_pos % sizeof(uint32_t)) != 0) - { - /* Since there are an extra 2 bytes here, remove them and stash for - * later usage to prevent flash write issues with non-word boundary - * writes - */ - memcpy(excess_data_buffer, &decomp_buf[filter_writeback_pos - - DECOMP_BUF_EXTRA_SIZE], - DECOMP_BUF_EXTRA_SIZE); - excess_data_buffer_full = true; - filter_writeback_pos -= DECOMP_BUF_EXTRA_SIZE; - } - - rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), - decomp_buf, filter_writeback_pos); - - if (rc != 0) { - BOOT_LOG_ERR( - "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + hdr->ih_hdr_size + write_pos), DECOMP_BUF_SIZE, - fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto finish; - } - - write_pos += filter_writeback_pos; - decomp_buf_size = 0; - filter_writeback_pos = 0; - } else -#endif - { - rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), - decomp_buf, DECOMP_BUF_SIZE); - - if (rc != 0) { - BOOT_LOG_ERR( - "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + hdr->ih_hdr_size + write_pos), DECOMP_BUF_SIZE, - fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto finish; - } - - write_pos += DECOMP_BUF_SIZE; - decomp_buf_size = 0; - } - } - } - - tmp_off += offset; - } - - pos += copy_size; - } - -#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) - if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT && decomp_buf_size > 0) { - /* Extra data that has not been written out that needs ARM thumb filter applied */ - uint32_t offset_arm_thumb = 0; - uint32_t output_size_arm_thumb = 0; - uint8_t *output_arm_thumb = NULL; - - rc = compression_arm_thumb->decompress(NULL, &decomp_buf[DECOMP_BUF_EXTRA_SIZE], - decomp_buf_size, true, &offset_arm_thumb, - &output_arm_thumb, &output_size_arm_thumb); - - if (rc) { - BOOT_LOG_ERR("Decompression error: %d", rc); - rc = BOOT_EBADSTATUS; - goto finish; - } - - memcpy(decomp_buf, output_arm_thumb, output_size_arm_thumb); - } -#endif - - /* Clean up decompression system */ - (void)compression_lzma->deinit(NULL); - (void)compression_arm_thumb->deinit(NULL); - - if (protected_tlv_size > 0) { - rc = boot_copy_protected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + - write_pos), protected_tlv_size, - decomp_buf, DECOMP_BUF_SIZE, &decomp_buf_size, - &tlv_write_size); - - if (rc) { - BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); - goto finish; - } - - write_pos += tlv_write_size; - } - - tlv_write_size = 0; - rc = boot_copy_unprotected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + - write_pos), unprotected_tlv_size, - decomp_buf, DECOMP_BUF_SIZE, &decomp_buf_size, - &tlv_write_size); - - if (rc) { - BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); - goto finish; - } - - write_pos += tlv_write_size; - - /* Check if we have unwritten data buffered up and, if so, write it out */ - if (decomp_buf_size > 0) { - uint32_t write_padding_size = write_alignment - (decomp_buf_size % write_alignment); - - /* Check if additional write padding should be applied to meet the minimum write size */ - if (write_alignment > 1 && write_padding_size) { - uint8_t flash_erased_value; - - flash_erased_value = flash_area_erased_val(fap_dst); - memset(&decomp_buf[decomp_buf_size], flash_erased_value, write_padding_size); - decomp_buf_size += write_padding_size; - } - - rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf, - decomp_buf_size); - - if (rc != 0) { - BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf_size, - fap_dst->fa_id, rc); - rc = BOOT_EFLASH; - goto finish; - } - - write_pos += decomp_buf_size; - decomp_buf_size = 0; - } - -finish: - memset(decomp_buf, 0, sizeof(decomp_buf)); - - return rc; -} - -int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *img_decomp_size) -{ - struct image_tlv_iter it; - uint32_t off; - uint16_t len; - int32_t rc; - - if (hdr == NULL || fap == NULL || img_decomp_size == NULL) { - return BOOT_EBADARGS; - } else if (hdr->ih_protect_tlv_size == 0) { - return BOOT_EBADIMAGE; - } - - rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIZE, true); - - if (rc) { - return rc; - } - - rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); - - if (rc != 0) { - return -1; - } - - if (len != sizeof(*img_decomp_size)) { - BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); - return BOOT_EBADIMAGE; - } - - rc = LOAD_IMAGE_DATA(hdr, fap, off, img_decomp_size, len); - - if (rc) { - BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", - off, len, fap->fa_id, rc); - return BOOT_EFLASH; - } - - return 0; -} diff --git a/boot/zephyr/include/compression/decompression.h b/boot/zephyr/include/compression/decompression.h deleted file mode 100644 index 2104c4eb6..000000000 --- a/boot/zephyr/include/compression/decompression.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef H_DECOMPRESSION_ -#define H_DECOMPRESSION_ - -#include -#include -#include -#include "bootutil/bootutil.h" -#include "bootutil/bootutil_public.h" -#include "bootutil/image.h" -#include "../src/bootutil_priv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Checks if a compressed image header is valid. - * - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param state Bootloader state object. - * - * @return true if valid; false if invalid. - */ -bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, - struct boot_loader_state *state); - -/** - * Reads in compressed image data from a slot, decompresses it and writes it out to a destination - * slot, including corresponding image headers and TLVs. - * - * @param state Bootloader state object. - * @param fap_src Flash area of the source slot. - * @param fap_dst Flash area of the destination slot. - * @param off_src Offset of the source slot to read from (should be 0). - * @param off_dst Offset of the destination slot to write to (should be 0). - * @param sz Size of the source slot data. - * @param buf Temporary buffer for reading data from. - * @param buf_size Size of temporary buffer. - * - * @return 0 on success; nonzero on failure. - */ -int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, - const struct flash_area *fap_dst, uint32_t off_src, - uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size); - -/** - * Gets the total data size (excluding headers and TLVs) of a compressed image when it is - * decompressed. - * - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param img_decomp_size Pointer to variable that will be updated with the decompressed image - * size. - * - * @return 0 on success; nonzero on failure. - */ -int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, - uint32_t *img_decomp_size); - -/** - * Calculate MCUboot-compatible image hash of compressed image slot. - * - * @param state MCUboot state. - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param tmp_buf Temporary buffer for reading data from. - * @param tmp_buf_sz Size of temporary buffer. - * @param hash_result Pointer to a variable that will be updated with the image hash. - * @param seed Not currently used, set to NULL. - * @param seed_len Not currently used, set to 0. - * - * @return 0 on success; nonzero on failure. - */ -int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_header *hdr, - const struct flash_area *fap, uint8_t *tmp_buf, - uint32_t tmp_buf_sz, uint8_t *hash_result, - uint8_t *seed, int seed_len); - -/** - * Calculates the size that the compressed image protected TLV section will occupy once the image - * has been decompressed. - * - * @param hdr Image header. - * @param fap Flash area of the slot. - * @param sz Pointer to variable that will be updated with the protected TLV size. - * - * @return 0 on success; nonzero on failure. - */ -int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap_src, - uint32_t *sz); - -#ifdef __cplusplus -} -#endif - -#endif /* H_DECOMPRESSION_ */ From 92e4d33b6227e574c89f14632aab0b3a4b055f52 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 076/204] Revert "[nrf noup] zephyr: Fix path variables" This reverts commit 5c886db89fdc8b13ff4879c3ee285913b899409b. Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index acdc3f568..1a6f86557 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -35,20 +35,21 @@ if(NOT CONFIG_MBEDTLS_BUILTIN AND NOT CONFIG_BOOT_KEY_IMPORT_BYPASS_ASN) set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls-asn1") assert_exists(MBEDTLS_ASN1_DIR) endif() -set(MCUBOOT_NRF_EXT_DIR "${MCUBOOT_DIR}/ext/nrf") +set(NRF_DIR "${MCUBOOT_DIR}/ext/nrf") if(CONFIG_BOOT_USE_NRF_CC310_BL) - if(NOT EXISTS ${ZEPHYR_NRFXLIB_MODULE_DIR}) - message(FATAL_ERROR " +set(NRFXLIB_DIR ${ZEPHYR_BASE}/../nrfxlib) +if(NOT EXISTS ${NRFXLIB_DIR}) + message(FATAL_ERROR " ------------------------------------------------------------------------ - No such file or directory: ${ZEPHYR_NRFXLIB_MODULE_DIR} + No such file or directory: ${NRFXLIB_DIR} The current configuration enables nRF CC310 crypto accelerator hardware with the `CONFIG_BOOT_USE_NRF_CC310_BL` option. Please follow `ext/nrf/README.md` guide to fix your setup or use tinycrypt instead of the HW accelerator. To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") - endif() +endif() endif() zephyr_library_include_directories( @@ -214,8 +215,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) ${TINYCRYPT_DIR}/source/utils.c ) elseif(CONFIG_BOOT_USE_NRF_CC310_BL) - zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) - zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) + zephyr_library_sources(${NRF_DIR}/cc310_glue.c) + zephyr_library_include_directories(${NRF_DIR}) zephyr_link_libraries(nrfxlib_crypto) elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) zephyr_include_directories(${BL_CRYPTO_DIR}/../include) From 016b73f780be65ae21834941da81e7149da4ef86 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 077/204] Revert "[nrf noup] zephyr: sdk-nrf specific overrides on PSA Kconfigs" This reverts commit fa89f7b8d1003afe48926214870772f9c718687b. Signed-off-by: Jamie McCrae --- boot/bootutil/zephyr/CMakeLists.txt | 2 +- boot/zephyr/Kconfig | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/boot/bootutil/zephyr/CMakeLists.txt b/boot/bootutil/zephyr/CMakeLists.txt index 44f78f395..f6d37441c 100644 --- a/boot/bootutil/zephyr/CMakeLists.txt +++ b/boot/bootutil/zephyr/CMakeLists.txt @@ -40,7 +40,7 @@ if(CONFIG_BOOT_USE_PSA_CRYPTO) ) endif() -if(CONFIG_BOOT_USE_MBEDTLS OR CONFIG_BOOT_USE_PSA_CRYPTO AND NOT CONFIG_NRF_SECURITY) +if(CONFIG_BOOT_USE_MBEDTLS OR CONFIG_BOOT_USE_PSA_CRYPTO) zephyr_link_libraries(mbedTLS) endif() endif() diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 9535d4b5a..21bfa5a3a 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -89,7 +89,8 @@ config BOOT_ED25519_PSA_DEPENDENCIES select PSA_WANT_ALG_SHA_256 select PSA_WANT_ALG_SHA_512 select PSA_WANT_ALG_PURE_EDDSA - select PSA_WANT_ECC_TWISTED_EDWARDS_255 + # Seems that upstream mbedTLS does not have TE + #select PSA_WANT_ECC_TWISTED_EDWARDS_255 select PSA_WANT_ECC_MONTGOMERY_255 select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT help @@ -284,7 +285,6 @@ config BOOT_SIGNATURE_TYPE_PURE choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" - default BOOT_ED25519_PSA if NRF_SECURITY default BOOT_ED25519_TINYCRYPT config BOOT_ED25519_TINYCRYPT @@ -305,7 +305,7 @@ config BOOT_ED25519_MBEDTLS config BOOT_ED25519_PSA bool "Use PSA crypto" - depends on NRF_SECURITY + select MBEDTLS select BOOT_USE_PSA_CRYPTO select PSA_CRYPTO_CLIENT select PSA_CRYPTO_C @@ -375,7 +375,6 @@ config MBEDTLS_CFG_FILE # is used, but the fact is that Mbed TLS' ASN1 parse module is used # also when TinyCrypt is used as crypto backend. default "mcuboot-mbedtls-cfg.h" if BOOT_USE_TINYCRYPT - default "config-tls-generic.h" if NRF_SECURITY && (MBEDTLS_BUILTIN || BOOT_USE_PSA_CRYPTO) default "mcuboot-mbedtls-cfg.h" if BOOT_USE_MBEDTLS && !MBEDTLS_BUILTIN config BOOT_HW_KEY From 24273bbf1e2e5c5829d42418f890ce1cd09f420d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 078/204] Revert "[nrf fromtree] bootutil: Fix ed25519 pure signature verification" This reverts commit e9d96780bdf7c997c0ca36ccb4d00a2dd7bc3b61. Signed-off-by: Jamie McCrae --- boot/bootutil/src/image_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index ffb8cec3b..90e8300de 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -90,7 +90,7 @@ bootutil_verify(uint8_t *buf, uint32_t blen, uint8_t *pubkey; uint8_t *end; - if (slen != EDDSA_SIGNATURE_LENGTH) { + if (blen != IMAGE_HASH_SIZE || slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } From 3f6391a464beeaf5b870ce4e9549c123ea187f61 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 079/204] Revert "[nrf fromtree] zephyr: Add missing selection for allowed SHA algorithms" This reverts commit 69a93364d74cfb0ecbe1f4d9a5ae2a22f0d02fbc. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 21bfa5a3a..2deb94841 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -290,13 +290,11 @@ choice BOOT_ED25519_IMPLEMENTATION config BOOT_ED25519_TINYCRYPT bool "Use tinycrypt" select BOOT_USE_TINYCRYPT - select BOOT_IMG_HASH_ALG_SHA256_ALLOW select BOOT_IMG_HASH_ALG_SHA512_ALLOW config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS - select BOOT_IMG_HASH_ALG_SHA256_ALLOW select BOOT_IMG_HASH_ALG_SHA512_ALLOW select MBEDTLS select MBEDTLS_SHA512 @@ -307,13 +305,10 @@ config BOOT_ED25519_PSA bool "Use PSA crypto" select MBEDTLS select BOOT_USE_PSA_CRYPTO - select PSA_CRYPTO_CLIENT - select PSA_CRYPTO_C select MBEDTLS_PSA_CRYPTO_C select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN - select MBEDTLS_ENABLE_HEAP - select BOOT_IMG_HASH_ALG_SHA256_ALLOW - select BOOT_IMG_HASH_ALG_SHA512_ALLOW + select PSA_CRYPTO_CLIENT + select PSA_CRYPTO_C select BOOT_ED25519_PSA_DEPENDENCIES select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE From bdfe4e73f876a003d6117df239645376176bf674 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 080/204] Revert "[nrf fromtree] zephyr: Fix ED25519 compilation with mbedTLS" This reverts commit f6ca88a8f0e7abcc53589fcbd2fc3766c0bf30dd. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 2deb94841..369f19969 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -295,9 +295,7 @@ config BOOT_ED25519_TINYCRYPT config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS - select BOOT_IMG_HASH_ALG_SHA512_ALLOW select MBEDTLS - select MBEDTLS_SHA512 select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN && !BOOT_KEY_IMPORT_BYPASS_ASN select BOOT_AES_MBEDTLS_DEPENDENCIES if MBEDTLS_BUILTIN && BOOT_ENCRYPT_IMAGE From 1e8ff8f6ea443c017248de74c229cce383aa165e Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 081/204] Revert "[nrf fromtree] zephyr: Prevent selecting MBEDTLS_ASN1_PARSE_C when not needed" This reverts commit c617eba5d633899f329df675a4092f1f64a20b6d. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 369f19969..b8c170a08 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -296,7 +296,7 @@ config BOOT_ED25519_MBEDTLS bool "Use mbedTLS" select BOOT_USE_MBEDTLS select MBEDTLS - select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN && !BOOT_KEY_IMPORT_BYPASS_ASN + select MBEDTLS_ASN1_PARSE_C if MBEDTLS_BUILTIN select BOOT_AES_MBEDTLS_DEPENDENCIES if MBEDTLS_BUILTIN && BOOT_ENCRYPT_IMAGE config BOOT_ED25519_PSA From 06f53ae302e7a8d0f837f37807d16f342b8ec155 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 082/204] Revert "[nrf fromtree] zephyr: Do not compile ASN1 code when bypassed" This reverts commit ff7f0defdfc054d7aac548d9f97278609544f8fb. Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 1a6f86557..3c2e19288 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -31,7 +31,7 @@ assert_exists(TINYCRYPT_SHA512_DIR) set(FIAT_DIR "${MCUBOOT_DIR}/ext/fiat") assert_exists(FIAT_DIR) # Path to mbed-tls' asn1 parser library. -if(NOT CONFIG_MBEDTLS_BUILTIN AND NOT CONFIG_BOOT_KEY_IMPORT_BYPASS_ASN) +if(NOT CONFIG_MBEDTLS_BUILTIN) set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls-asn1") assert_exists(MBEDTLS_ASN1_DIR) endif() From ae3f5ed00daaba0fb4dc239b12e878ee34426493 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 083/204] Revert "[nrf fromtree] bootutil: Fix ASN1 bypass not building" This reverts commit 5d9a95c8a8a6eabd9f1fd5750f542c7e276c8b3a. Signed-off-by: Jamie McCrae --- boot/bootutil/src/image_ed25519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index 90e8300de..01bef149d 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -18,10 +18,10 @@ #define MBEDTLS_ASN1_PARSE_C #include "mbedtls/oid.h" #include "mbedtls/asn1.h" -#include "bootutil/crypto/common.h" #endif #include "bootutil_priv.h" +#include "bootutil/crypto/common.h" #include "bootutil/crypto/sha.h" #define EDDSA_SIGNATURE_LENGTH 64 From 10b64c46951795b05620bed1c279024a7b86dc8d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 084/204] Revert "[nrf noup] partition_manager: Add support for internal flash netcore DFU" This reverts commit f3fedff247cb98559bb184088efd555521c9cf81. Signed-off-by: Jamie McCrae --- boot/zephyr/pm.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index eec62473c..ab8f6d1c3 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -78,17 +78,11 @@ mcuboot_pad: mcuboot_primary_1: region: ram_flash size: CONFIG_NRF53_RAM_FLASH_SIZE -#endif /* CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH */ +#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ #if (CONFIG_NRF53_MULTI_IMAGE_UPDATE) mcuboot_secondary_1: -#if defined(CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY) region: external_flash -#else - placement: - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} - after: mcuboot_secondary -#endif size: CONFIG_NRF53_RAM_FLASH_SIZE #endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ From 68795c914e90ecda4cf655b95470c84c2491989d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 085/204] Revert "[nrf noup] boot: zephyr: boards: Disabled NCS boot banner for thingy 53" This reverts commit 1027dd80a4de4a65e276af63543d37463fffcb03. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index c584aa911..e10656678 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -47,7 +47,6 @@ CONFIG_USB_CDC_ACM=y CONFIG_CBPRINTF_NANO=y CONFIG_TIMESLICING=n CONFIG_BOOT_BANNER=n -CONFIG_NCS_BOOT_BANNER=n CONFIG_CONSOLE=n CONFIG_CONSOLE_HANDLER=n CONFIG_UART_CONSOLE=n From 78e8751520846dcf6745329cc60722549d819166 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 086/204] Revert "[nrf noup] sysflash: Add missing _FLASH_0_ID definitions" This reverts commit b9578ab6f7537e7a58d5c3609cd0de5ca0c24ff1. Signed-off-by: Jamie McCrae --- boot/zephyr/include/sysflash/pm_sysflash.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index 0cb16292f..42f25182e 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -84,12 +84,4 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ -#ifndef SOC_FLASH_0_ID -#define SOC_FLASH_0_ID 0 -#endif - -#ifndef SPI_FLASH_0_ID -#define SPI_FLASH_0_ID 1 -#endif - #endif /* __PM_SYSFLASH_H__ */ From 9a023fca2f30e5c3ba9602a68eb9d6225ce08fd2 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 087/204] Revert "[nrf noup] boot: Remove child/parent references" This reverts commit b7a30ffbfd277f7e03cd63b35a5b300230ba6793. Signed-off-by: Jamie McCrae --- boot/bootutil/src/swap_priv.h | 2 +- boot/zephyr/pm.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/swap_priv.h b/boot/bootutil/src/swap_priv.h index ee7e44d55..0e6de790e 100644 --- a/boot/bootutil/src/swap_priv.h +++ b/boot/bootutil/src/swap_priv.h @@ -120,7 +120,7 @@ bool swap_write_block_size_check(struct boot_loader_state *state); int app_max_size(struct boot_loader_state *state); #if defined(PM_S1_ADDRESS) && !defined(MCUBOOT_OVERWRITE_ONLY) && \ -CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 +(CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED)) /** * Performs an NSIB update */ diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index ab8f6d1c3..13ffc44aa 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -4,7 +4,9 @@ mcuboot: size: CONFIG_PM_PARTITION_SIZE_MCUBOOT placement: before: [mcuboot_primary] +#if defined(CONFIG_HIDE_CHILD_PARENT_CONFIG) align: {end: 0x1000} +#endif mcuboot_primary_app: # All images to be placed in MCUboot's slot 0 should be placed in this From 26f1704c369b7958c7422da688732c50be615b82 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 088/204] Revert "[nrf noup] boot/zephyr/boards: configure fastest RRAM operations" This reverts commit d18f8fd39d037e5a85dda2d50610f49f54d1a024. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf index 12650a9ed..8fc12e074 100644 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf @@ -13,6 +13,3 @@ CONFIG_NORDIC_QSPI_NOR=n CONFIG_FPROTECT=n CONFIG_BOOT_WATCHDOG_FEED=n - -# Ensure the fastest RRAM write operations -CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE=32 From 884a2e386cc508b62de72501c6bf04cb428c58a8 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 089/204] Revert "[nrf noup] boot: zephyr: serial_recovery: Add nRF5340 Kconfig override" This reverts commit b1690156f6ad1bbf68b7526eb914d2f8aae9237f. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig.serial_recovery | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/boot/zephyr/Kconfig.serial_recovery b/boot/zephyr/Kconfig.serial_recovery index f5ee8945b..72be5ccfb 100644 --- a/boot/zephyr/Kconfig.serial_recovery +++ b/boot/zephyr/Kconfig.serial_recovery @@ -47,14 +47,9 @@ config BOOT_SERIAL_CDC_ACM endchoice -DT_COMPAT_SIM_FLASH:= zephyr,sim-flash -DT_SIM_FLASH_PATH := $(dt_nodelabel_path,flash_sim0) - config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD bool "Allow to select image number for DFU" - # Allow this option to be selected in cases where support for direct uploading to nRF5340 - # network core should be supported - depends on !SINGLE_APPLICATION_SLOT || (SINGLE_APPLICATION_SLOT && SOC_NRF5340_CPUAPP && BOOT_IMAGE_ACCESS_HOOK_NRF5340 && FLASH_SIMULATOR && $(dt_compat_enabled,$(DT_COMPAT_SIM_FLASH))) + depends on !SINGLE_APPLICATION_SLOT help With the option enabled, the mcuboot serial recovery will respect the "image" field in mcumgr image update frame From 52daf3c6542ef2ebf0dc27a7dfaada587f257a8f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 090/204] Revert "[nrf noup] boot/zephyr/Kconfig: conditionally disable BOOT_MAX_IMG_SECTORS_AUTO" This reverts commit b66e930b70e31ec76e0c1c2a7d4252221e810c26. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index b8c170a08..f110936ab 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -624,7 +624,7 @@ config BOOT_ENCRYPTION_KEY_FILE config BOOT_MAX_IMG_SECTORS_AUTO bool "Calculate maximum sectors automatically" - default y if !PARTITION_MANAGER_ENABLED + default y help If this option is enabled then the maximum number of supported sectors per image will be calculated automatically from the flash erase sizes and size of each partition for From f5972f6d521b2284e8301cc7142d22dab2533521 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 091/204] Revert "[nrf noup] boot/zephyr: add nrf54l15dk ext flash configs" This reverts commit 8e5297e9b9565b51a75a6d89926c3002231217d2. Signed-off-by: Jamie McCrae --- .../nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf | 15 ------ ...f54l15dk_nrf54l15_cpuapp_ext_flash.overlay | 47 ------------------- 2 files changed, 62 deletions(-) delete mode 100644 boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf delete mode 100644 boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf deleted file mode 100644 index 8fc12e074..000000000 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_MULTITHREADING=y -CONFIG_SPI=y -CONFIG_SPI_NOR=y -CONFIG_FLASH=y -CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 -CONFIG_MAIN_STACK_SIZE=20480 -CONFIG_BOOT_MAX_IMG_SECTORS=512 -CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 -# Ensure that the qspi driver is disabled by default -CONFIG_NORDIC_QSPI_NOR=n - -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - -CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay deleted file mode 100644 index 60ee6fe51..000000000 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay +++ /dev/null @@ -1,47 +0,0 @@ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - zephyr,code-partition = &boot_partition; - }; -}; - -/delete-node/ &boot_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/delete-node/ &slot0_ns_partition; -/delete-node/ &slot1_ns_partition; - -/delete-node/ &storage_partition; - -&cpuapp_rram { - reg = < 0x0 DT_SIZE_K(1524) >; - partitions { - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x000000000 0x00014000>; - }; - slot0_partition: partition@14000 { - label = "image-0"; - reg = <0x000014000 0x0015A000>; - }; - storage_partition: partition@16E000 { - label = "storage"; - reg = < 0x16E000 0x9000 >; - }; - }; -}; - -&mx25r64 { - status = "okay"; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - slot1_partition: partition@0 { - label = "image-1"; - reg = <0x000000000 0x0015A000>; - }; - }; -}; From dc59c670554b5e202d6297756ae77da89eb03d7f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 092/204] Revert "[nrf noup] workflows: Add a backport workflow" This reverts commit 22409c3e6c613a5c98692ee67a7706ca543c99c9. Signed-off-by: Jamie McCrae --- .github/workflows/backport.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/backport.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml deleted file mode 100644 index e986738ff..000000000 --- a/.github/workflows/backport.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Backport -on: - pull_request_target: - types: - - closed - - labeled - branches: - - main - -jobs: - backport: - name: Backport - runs-on: ubuntu-22.04 - # Only react to merged PRs for security reasons. - # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target. - if: > - github.event.pull_request.merged && - ( - github.event.action == 'closed' || - ( - github.event.action == 'labeled' && - contains(github.event.label.name, 'backport') - ) - ) - steps: - - name: Backport - uses: zephyrproject-rtos/action-backport@v2.0.3-3 - with: - github_token: ${{ secrets.NCS_GITHUB_TOKEN }} - issue_labels: Backport - labels_template: '["Backport"]' From f1459a2d51c999423204786172624877356edea7 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 093/204] Revert "[nrf noup] boards: Thingy:91 X release config" This reverts commit 52322e20de27c93aa102058fb9e2fb762b705f11. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf | 3 --- boot/zephyr/boards/thingy91x_nrf9151.conf | 6 +----- boot/zephyr/boards/thingy91x_nrf9151.overlay | 4 ---- 3 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 boot/zephyr/boards/thingy91x_nrf9151.overlay diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf index d3e253b65..37c7e95b1 100644 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -58,6 +58,3 @@ CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y # Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n - -CONFIG_BOOT_SERIAL_NO_APPLICATION=y -CONFIG_FW_INFO_FIRMWARE_VERSION=2 diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf index 7c2042de6..2efe1e170 100644 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -12,10 +12,6 @@ CONFIG_CONSOLE=n CONFIG_CONSOLE_HANDLER=n CONFIG_UART_CONSOLE=n CONFIG_MCUBOOT_SERIAL=y + CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y - -CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y -CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y - -CONFIG_FW_INFO_FIRMWARE_VERSION=2 diff --git a/boot/zephyr/boards/thingy91x_nrf9151.overlay b/boot/zephyr/boards/thingy91x_nrf9151.overlay deleted file mode 100644 index 7f2818c0d..000000000 --- a/boot/zephyr/boards/thingy91x_nrf9151.overlay +++ /dev/null @@ -1,4 +0,0 @@ -&uart0 { - status = "okay"; - current-speed = < 1000000 >; -}; From c5a54675759702a7e0348478a8c65a0f0398e438 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 094/204] Revert "[nrf noup] boot: bootutil: loader: Add s0/s1 checking of MCUboot image" This reverts commit 4738ae858d7dde54675aaa00b682e4b6697c35da. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 45 -------------------------------------- 1 file changed, 45 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 12674359e..18eaa0ea6 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -100,17 +100,6 @@ static struct sector_buffer_t sector_buffers; #endif #endif -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 && defined(MCUBOOT_OVERWRITE_ONLY) && \ - defined(MCUBOOT_DOWNGRADE_PREVENTION) -/* s0/s1 package version of the current MCUboot image */ -static const struct image_version mcuboot_s0_s1_image_version = { - .iv_major = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_MAJOR, - .iv_minor = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_MINOR, - .iv_revision = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_REVISION, - .iv_build_num = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_BUILD_NUMBER, -}; -#endif - #if (BOOT_IMAGE_NUMBER > 1) #define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x)) #else @@ -1129,45 +1118,11 @@ boot_validate_slot(struct boot_loader_state *state, int slot, rc = boot_version_cmp( &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); - -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 - if (rc >= 0 && BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { - /* Also check the new version of MCUboot against that of the current s0/s1 MCUboot - * trailer version to prevent downgrades - */ - int version_check; - - version_check = boot_version_cmp(&boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &mcuboot_s0_s1_image_version); - - /* Only update rc if the currently running version is newer */ - if (version_check < rc) { - rc = version_check; - } - } -#endif } #else rc = boot_version_cmp( &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); - -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 - if (rc >= 0 && BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { - /* Also check the new version of MCUboot against that of the current s0/s1 MCUboot - * trailer version to prevent downgrades - */ - int version_check; - - version_check = boot_version_cmp(&boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &mcuboot_s0_s1_image_version); - - /* Only update rc if the currently running version is newer */ - if (version_check < rc) { - rc = version_check; - } - } -#endif #endif if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); From 63ffd7ba9f1abddee47a2ac7b3d64add269ce036 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 095/204] Revert "[nrf noup] treewide: Add support for sysbuild assigned images" This reverts commit 3308732dfec501206b75825205643c72295ad4b3. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 176 ++++++++------------- boot/bootutil/src/swap_nsib.c | 70 -------- boot/bootutil/src/swap_priv.h | 8 - boot/zephyr/CMakeLists.txt | 6 - boot/zephyr/include/sysflash/pm_sysflash.h | 69 ++++---- 5 files changed, 104 insertions(+), 225 deletions(-) delete mode 100644 boot/bootutil/src/swap_nsib.c diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 18eaa0ea6..daa778b85 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -159,15 +159,15 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, * * Failure to read any headers is a fatal error. */ -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 +#ifdef PM_S1_ADDRESS /* Patch needed for NCS. The primary slot of the second image * (image 1) will not contain a valid image header until an upgrade * of mcuboot has happened (filling S1 with the new version). */ - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER && i == 0) { + if (BOOT_CURR_IMG(state) == 1 && i == 0) { continue; } -#endif /* CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 */ +#endif /* PM_S1_ADDRESS */ if (i > 0 && !require_all) { return 0; } else { @@ -1112,7 +1112,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { + if (BOOT_CURR_IMG(state) == 1) { rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); } else { rc = boot_version_cmp( @@ -1183,54 +1183,35 @@ boot_validate_slot(struct boot_loader_state *state, int slot, struct image_header *secondary_hdr = boot_img_hdr(state, slot); uint32_t reset_value = 0; uint32_t reset_addr = secondary_hdr->ih_hdr_size + sizeof(reset_value); - uint32_t min_addr, max_addr; - bool check_addresses = false; if (flash_area_read(fap, reset_addr, &reset_value, sizeof(reset_value)) != 0) { fih_rc = FIH_NO_BOOTABLE_IMAGE; goto out; } + uint32_t min_addr, max_addr; + #ifdef PM_CPUNET_APP_ADDRESS /* The primary slot for the network core is emulated in RAM. * Its flash_area hasn't got relevant boundaries. * Therfore need to override its boundaries for the check. */ - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { + if (BOOT_CURR_IMG(state) == 1) { min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; - check_addresses = true; - } else -#endif -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { -#if (CONFIG_NCS_IS_VARIANT_IMAGE) +#ifdef PM_S1_ADDRESS + } else if (BOOT_CURR_IMG(state) == 0) { min_addr = PM_S0_ADDRESS; - max_addr = (PM_S0_ADDRESS + PM_S0_SIZE); -#else - min_addr = PM_S1_ADDRESS; - max_addr = (PM_S1_ADDRESS + PM_S1_SIZE); + max_addr = pri_fa->fa_off + pri_fa->fa_size; #endif - check_addresses = true; } else #endif - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 -#if (CONFIG_NCS_IS_VARIANT_IMAGE) - min_addr = MIN(pri_fa->fa_off, PM_S0_ADDRESS); - max_addr = MAX((pri_fa->fa_off + pri_fa->fa_size), (PM_S0_ADDRESS + PM_S0_SIZE)); -#else - min_addr = MIN(pri_fa->fa_off, PM_S1_ADDRESS); - max_addr = MAX((pri_fa->fa_off + pri_fa->fa_size), (PM_S1_ADDRESS + PM_S1_SIZE)); -#endif -#else + { min_addr = pri_fa->fa_off; max_addr = pri_fa->fa_off + pri_fa->fa_size; -#endif - check_addresses = true; } - if (check_addresses == true && (reset_value < min_addr || reset_value > max_addr)) { + if (reset_value < min_addr || reset_value> (max_addr)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); BOOT_LOG_ERR("Erasing image from secondary slot"); @@ -1300,54 +1281,36 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ #define SEC_SLOT_TOUCHED 1 #define SEC_SLOT_ASSIGNED 2 -static uint8_t sec_slot_assignment[MCUBOOT_IMAGE_NUMBER] = {0}; - -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 -static inline void sec_slot_untouch(struct boot_loader_state *state) -{ - sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] = SEC_SLOT_VIRGIN; - sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] = SEC_SLOT_VIRGIN; -} +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +/* This configuration is peculiar - the one physical secondary slot is + * mocking two logical secondary + */ +#define SEC_SLOT_PHYSICAL_CNT 1 #else -static inline void sec_slot_untouch(struct boot_loader_state *state) -{ -} +#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER #endif +static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0}; + static inline void sec_slot_touch(struct boot_loader_state *state) { -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { - if (sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] == SEC_SLOT_VIRGIN) { - sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] = SEC_SLOT_TOUCHED; - } - } else if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { - if (sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] == SEC_SLOT_VIRGIN) { - sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] = SEC_SLOT_TOUCHED; - } - } -#endif + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); - if (sec_slot_assignment[BOOT_CURR_IMG(state)] == SEC_SLOT_VIRGIN) { - sec_slot_assignment[BOOT_CURR_IMG(state)] = SEC_SLOT_TOUCHED; + if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) { + sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED; } } static inline void sec_slot_mark_assigned(struct boot_loader_state *state) { -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { - sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] = SEC_SLOT_ASSIGNED; - } else if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { - sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] = SEC_SLOT_ASSIGNED; - } -#endif + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); - sec_slot_assignment[BOOT_CURR_IMG(state)] = SEC_SLOT_ASSIGNED; + sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED; } /** - * Cleanup up all secondary slot which couldn't be assigned to any primary slot. + * Cleanu up all secondary slot which couldn't be assigned to any primary slot. * * This function erases content of each secondary slot which contains valid * header but couldn't be assigned to any of supported primary images. @@ -1359,8 +1322,8 @@ static void sec_slot_cleanup_if_unusable(void) { uint8_t idx; - for (idx = 0; idx < MCUBOOT_IMAGE_NUMBER; idx++) { - if (SEC_SLOT_TOUCHED == sec_slot_assignment[idx]) { + for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) { + if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) { const struct flash_area *secondary_fa; int rc; @@ -1369,20 +1332,17 @@ static void sec_slot_cleanup_if_unusable(void) if (!rc) { rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); if (!rc) { - BOOT_LOG_ERR("Cleaned-up secondary slot of image %d", idx); + BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx); } } if (rc) { - BOOT_LOG_ERR("Failed to clean-up secondary slot of image %d: %d", idx, rc); + BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx); } } } } #else -static inline void sec_slot_untouch(struct boot_loader_state *state) -{ -} static inline void sec_slot_touch(struct boot_loader_state *state) { } @@ -1414,7 +1374,7 @@ boot_validated_swap_type(struct boot_loader_state *state, owner_nsib[BOOT_CURR_IMG(state)] = false; #endif -#if defined(PM_S1_ADDRESS) || defined(PM_CPUNET_B0N_ADDRESS) +#if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); struct image_header *hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); @@ -1452,31 +1412,31 @@ boot_validated_swap_type(struct boot_loader_state *state, } /* Check start and end of primary slot for current image */ -#if (CONFIG_NCS_IS_VARIANT_IMAGE) - if (reset_addr >= PM_S0_ADDRESS && reset_addr <= (PM_S0_ADDRESS + PM_S0_SIZE)) { -#else - if (reset_addr >= PM_S1_ADDRESS && reset_addr <= (PM_S1_ADDRESS + PM_S1_SIZE)) { -#endif - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { - /* This is not the s0/s1 upgrade image but the application image, pretend - * there is no image so the NSIB update can be loaded - */ - return BOOT_SWAP_TYPE_NONE; - } + if (reset_addr < primary_fa->fa_off) { +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + const struct flash_area *nsib_fa; - owner_nsib[BOOT_CURR_IMG(state)] = true; -#if (CONFIG_NCS_IS_VARIANT_IMAGE) - } else if (reset_addr >= PM_S1_ADDRESS && reset_addr <= (PM_S1_ADDRESS + PM_S1_SIZE)) { + /* NSIB upgrade slot */ + rc = flash_area_open((uint32_t)_image_1_primary_slot_id, + &nsib_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + + /* Image is placed before Primary and within the NSIB slot */ + if (reset_addr > nsib_fa->fa_off + && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { + /* Set primary to be NSIB upgrade slot */ + BOOT_IMG_AREA(state, 0) = nsib_fa; + owner_nsib[BOOT_CURR_IMG(state)] = true; + } #else - } else if (reset_addr >= PM_S0_ADDRESS && reset_addr <= (PM_S0_ADDRESS + PM_S0_SIZE)) { + return BOOT_SWAP_TYPE_NONE; + #endif - /* NSIB upgrade but for the wrong slot, must be erased */ - BOOT_LOG_ERR("Image in slot is for wrong s0/s1 image"); - flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); - sec_slot_untouch(state); - BOOT_LOG_ERR("Cleaned-up secondary slot of image %d", BOOT_CURR_IMG(state)); - return BOOT_SWAP_TYPE_FAIL; - } else if (reset_addr < primary_fa->fa_off || reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + + } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } @@ -1489,7 +1449,7 @@ boot_validated_swap_type(struct boot_loader_state *state, sec_slot_mark_assigned(state); } -#endif /* PM_S1_ADDRESS || PM_CPUNET_B0N_ADDRESS */ +#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -2039,22 +1999,7 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) flash_area_close(fap); } -#if defined(PM_S1_ADDRESS) && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 - if (owner_nsib[BOOT_CURR_IMG(state)]) { - if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { - /* For NSIB, move the image instead of swapping it */ - nsib_swap_run(state, bs); - -#if defined(CONFIG_REBOOT) - /* Should also reboot at this point so the new S0/S1 update is applied */ - sys_reboot(SYS_REBOOT_COLD); -#endif - } - } else -#endif - { - swap_run(state, bs, copy_size); - } + swap_run(state, bs, copy_size); #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT extern int boot_status_fails; @@ -2726,6 +2671,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); +#if defined(PM_S1_ADDRESS) && defined(CONFIG_REBOOT) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + sys_reboot(SYS_REBOOT_COLD); + + } +#endif break; case BOOT_SWAP_TYPE_FAIL: @@ -2799,8 +2750,7 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) * executing MCUBoot image, and is therefore already validated by NSIB and * does not need to also be validated by MCUBoot. */ - bool image_validated_by_nsib = BOOT_CURR_IMG(state) == - CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER; + bool image_validated_by_nsib = BOOT_CURR_IMG(state) == 1; if (!image_validated_by_nsib) #endif { diff --git a/boot/bootutil/src/swap_nsib.c b/boot/bootutil/src/swap_nsib.c deleted file mode 100644 index 39ed4c652..000000000 --- a/boot/bootutil/src/swap_nsib.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SPDX-License-Identifier: Apache-2.0 - * - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include "bootutil/bootutil.h" -#include "bootutil_priv.h" -#include "swap_priv.h" -#include "bootutil/bootutil_log.h" - -#include "mcuboot_config/mcuboot_config.h" - -BOOT_LOG_MODULE_DECLARE(mcuboot); - -void nsib_swap_run(struct boot_loader_state *state, struct boot_status *bs) -{ - uint32_t sector_sz; - uint8_t image_index; - const struct flash_area *fap_pri; - const struct flash_area *fap_sec; - int rc; - - BOOT_LOG_INF("Starting swap using nsib algorithm."); - - sector_sz = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 0); - -#if (CONFIG_NCS_IS_VARIANT_IMAGE) - rc = flash_area_open(PM_S0_ID, &fap_pri); -#else - rc = flash_area_open(PM_S1_ID, &fap_pri); -#endif - assert (rc == 0); - image_index = BOOT_CURR_IMG(state); - - rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap_sec); - assert (rc == 0); - - rc = boot_erase_region(fap_pri, 0, fap_pri->fa_size); - assert(rc == 0); - - rc = boot_copy_region(state, fap_sec, fap_pri, 0, 0, fap_pri->fa_size); - assert(rc == 0); - - rc = swap_erase_trailer_sectors(state, fap_sec); - assert(rc == 0); - - rc = boot_erase_region(fap_sec, 0, MIN((fap_pri->fa_size + sector_sz), fap_sec->fa_size)); - assert(rc == 0); - - flash_area_close(fap_pri); - flash_area_close(fap_sec); -} diff --git a/boot/bootutil/src/swap_priv.h b/boot/bootutil/src/swap_priv.h index 0e6de790e..6fdf797e1 100644 --- a/boot/bootutil/src/swap_priv.h +++ b/boot/bootutil/src/swap_priv.h @@ -119,12 +119,4 @@ bool swap_write_block_size_check(struct boot_loader_state *state); */ int app_max_size(struct boot_loader_state *state); -#if defined(PM_S1_ADDRESS) && !defined(MCUBOOT_OVERWRITE_ONLY) && \ -(CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED)) -/** - * Performs an NSIB update - */ -void nsib_swap_run(struct boot_loader_state *state, struct boot_status *bs); -#endif - #endif /* H_SWAP_PRIV_ */ diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 3c2e19288..15c4c2c06 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -181,12 +181,6 @@ else() ) endif() endif() - - if(NOT CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER EQUAL "-1" AND NOT CONFIG_BOOT_UPGRADE_ONLY) - zephyr_library_sources( - ${BOOT_DIR}/bootutil/src/swap_nsib.c - ) - endif() endif() if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index 42f25182e..db60ddd03 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -15,36 +15,48 @@ #ifndef CONFIG_SINGLE_APPLICATION_SLOT +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +extern uint32_t _image_1_primary_slot_id[]; +#endif /* (MCUBOOT_IMAGE_NUMBER == 2 && defined(PM_B0_ADDRESS) */ + +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) + +#else /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ + /* Each pair of slots is separated by , and there is no terminating character */ -#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID, -#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID, -#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID, -#define FLASH_AREA_IMAGE_3_SLOTS PM_MCUBOOT_PRIMARY_3_ID, PM_MCUBOOT_SECONDARY_3_ID, - -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 -#ifdef CONFIG_NCS_IS_VARIANT_IMAGE -#define MCUBOOT_S0_S1_SLOTS PM_S0_ID, PM_MCUBOOT_SECONDARY_ID, -#else -#define MCUBOOT_S0_S1_SLOTS PM_S1_ID, PM_MCUBOOT_SECONDARY_ID, -#endif -#else -#define MCUBOOT_S0_S1_SLOTS -#endif +#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID +#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID +#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID -#if (MCUBOOT_IMAGE_NUMBER == 1) || (MCUBOOT_IMAGE_NUMBER == 2 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) +#if (MCUBOOT_IMAGE_NUMBER == 1) #define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 2) || (MCUBOOT_IMAGE_NUMBER == 3 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ +#elif (MCUBOOT_IMAGE_NUMBER == 2) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ FLASH_AREA_IMAGE_1_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 3) || (MCUBOOT_IMAGE_NUMBER == 4 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ - FLASH_AREA_IMAGE_1_SLOTS \ +#elif (MCUBOOT_IMAGE_NUMBER == 3) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ + FLASH_AREA_IMAGE_1_SLOTS, \ FLASH_AREA_IMAGE_2_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 4) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ - FLASH_AREA_IMAGE_1_SLOTS \ - FLASH_AREA_IMAGE_2_SLOTS \ - FLASH_AREA_IMAGE_3_SLOTS #else #error Unsupported number of images #endif @@ -53,7 +65,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) { static const int all_slots[] = { ALL_AVAILABLE_SLOTS - MCUBOOT_S0_S1_SLOTS }; return all_slots[img * 2 + slot]; }; @@ -61,8 +72,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #undef FLASH_AREA_IMAGE_0_SLOTS #undef FLASH_AREA_IMAGE_1_SLOTS #undef FLASH_AREA_IMAGE_2_SLOTS -#undef FLASH_AREA_IMAGE_3_SLOTS -#undef MCUBOOT_S0_S1_SLOTS #undef ALL_AVAILABLE_SLOTS #define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0) @@ -72,6 +81,10 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #endif +#endif /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ + #else /* CONFIG_SINGLE_APPLICATION_SLOT */ #define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID From 8b6e9a2dfbfd486e70a927a13b35f8683dce38bf Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:49 +0100 Subject: [PATCH 096/204] Revert "[nrf noup] boot: zephyr: Do not lock PCD region with TF-M" This reverts commit 01f3b098410164beefb32ce13d3b1eca7f537fbb. Signed-off-by: Jamie McCrae --- boot/zephyr/main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 6dc1e6fc3..918a01f7a 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -652,11 +652,7 @@ int main(void) } #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) && defined(CONFIG_PCD_APP) -#if defined(PM_TFM_SECURE_ADDRESS) - pcd_lock_ram(false); -#else - pcd_lock_ram(true); -#endif + pcd_lock_ram(); #endif #endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ From e69d9ed62dd78501e4a8e429d1d6cb121885c13d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 097/204] Revert "[nrf noup] boot: Add shared crypto for ECDSA and SHA" This reverts commit 259eadb4dec22b62322243963c6312e7ed764782. Signed-off-by: Jamie McCrae --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 64 ++----------------- boot/bootutil/include/bootutil/crypto/sha.h | 32 ---------- boot/zephyr/CMakeLists.txt | 2 - boot/zephyr/external_crypto.conf | 20 ------ .../include/mcuboot_config/mcuboot_config.h | 5 +- 5 files changed, 9 insertions(+), 114 deletions(-) delete mode 100644 boot/zephyr/external_crypto.conf diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 85355f20c..3b0541072 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -34,7 +34,6 @@ #if (defined(MCUBOOT_USE_TINYCRYPT) + \ defined(MCUBOOT_USE_CC310) + \ - defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1 #error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO" #endif @@ -71,18 +70,12 @@ #include "bootutil/sign_key.h" #include "common.h" -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) - #include - #define NUM_ECC_BYTES (256 / 8) -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus extern "C" { #endif #if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \ - defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \ - && !defined(MCUBOOT_USE_PSA_CRYPTO) + defined(MCUBOOT_USE_CC310)) && !defined(MCUBOOT_USE_PSA_CRYPTO) /* * Declaring these like this adds NULL termination. */ @@ -134,6 +127,8 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) } #endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */ +#if defined(MCUBOOT_USE_TINYCRYPT) +#ifndef MCUBOOT_ECDSA_NEED_ASN1_SIG /* * cp points to ASN1 string containing an integer. * Verify the tag, and that the length is 32 bytes. Helper function. @@ -183,8 +178,8 @@ static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp } return 0; } +#endif /* not MCUBOOT_ECDSA_NEED_ASN1_SIG */ -#if defined(MCUBOOT_USE_TINYCRYPT) typedef uintptr_t bootutil_ecdsa_context; static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { @@ -253,12 +248,8 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, { (void)ctx; (void)pk_len; + (void)sig_len; (void)hash_len; - uint8_t dsig[2 * NUM_ECC_BYTES]; - - if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { - return -1; - } /* Only support uncompressed keys. */ if (pk[0] != 0x04) { @@ -266,7 +257,7 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, } pk++; - return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); + return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); } static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, @@ -622,49 +613,6 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) -typedef uintptr_t bootutil_ecdsa_context; -static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) -{ - (void)ctx; -} - -static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx) -{ - (void)ctx; -} - -static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, - uint8_t *pk, size_t pk_len, - uint8_t *hash, size_t hash_len, - uint8_t *sig, size_t sig_len) -{ - (void)ctx; - (void)pk_len; - (void)hash_len; - uint8_t dsig[2 * NUM_ECC_BYTES]; - - if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { - return -1; - } - - /* Only support uncompressed keys. */ - if (pk[0] != 0x04) { - return -1; - } - pk++; - - return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig); -} - -static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, - uint8_t **cp,uint8_t *end) -{ - (void)ctx; - return bootutil_import_key(cp, end); -} -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus } #endif diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index b83a3ec40..6a009ff95 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -30,7 +30,6 @@ #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \ defined(MCUBOOT_USE_TINYCRYPT) + \ - defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_CC310)) != 1 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif @@ -271,37 +270,6 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, } #endif /* MCUBOOT_USE_CC310 */ -#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) - -#include - -typedef bl_sha256_ctx_t bootutil_sha_context; - -static inline void bootutil_sha_init(bootutil_sha_context *ctx) -{ - bl_sha256_init(ctx); -} - -static inline void bootutil_sha_drop(bootutil_sha_context *ctx) -{ - (void)ctx; -} - -static inline int bootutil_sha_update(bootutil_sha_context *ctx, - const void *data, - uint32_t data_len) -{ - return bl_sha256_update(ctx, data, data_len); -} - -static inline int bootutil_sha_finish(bootutil_sha_context *ctx, - uint8_t *output) -{ - bl_sha256_finalize(ctx, output); - return 0; -} -#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ - #ifdef __cplusplus } #endif diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 15c4c2c06..1b4665050 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -212,8 +212,6 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_sources(${NRF_DIR}/cc310_glue.c) zephyr_library_include_directories(${NRF_DIR}) zephyr_link_libraries(nrfxlib_crypto) - elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) - zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() # Since here we are not using Zephyr's mbedTLS but rather our own, we need diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf deleted file mode 100644 index 8181ad51c..000000000 --- a/boot/zephyr/external_crypto.conf +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# These configurations should be used when using nrf/samples/bootloader -# as the immutable bootloader (B0), and MCUBoot as the second stage updateable -# bootloader. - -# Set ECDSA as signing mechanism -CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y - -# Use crypto backend from B0 -CONFIG_BOOT_NRF_EXTERNAL_CRYPTO=y -CONFIG_SECURE_BOOT_CRYPTO=y -CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y -CONFIG_SB_CRYPTO_CLIENT_SHA256=y -CONFIG_BL_SHA256_EXT_API_REQUIRED=y -CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 49854c754..850a618b3 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -44,10 +44,11 @@ #define MCUBOOT_USE_TINYCRYPT #elif defined(CONFIG_BOOT_USE_CC310) #define MCUBOOT_USE_CC310 +#ifdef CONFIG_BOOT_USE_NRF_CC310_BL +#define MCUBOOT_USE_NRF_CC310_BL +#endif #elif defined(CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT) #define MCUBOOT_USE_PSA_CRYPTO -#elif defined(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) -#define MCUBOOT_USE_NRF_EXTERNAL_CRYPTO #endif #ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 From 401adbd738f4c1b15bd08a67d7382526c199e886 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 098/204] Revert "[nrf noup] boards: nrf54l15dk: Disable FPROTECT" This reverts commit 243017cf6964dec4ea6af6fc64e72b176bda4f7c. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf index 1dbd7c1ab..c8fcd32c3 100644 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -7,9 +7,6 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - CONFIG_BOOT_WATCHDOG_FEED=n # Ensure the fastest RRAM write operations From 276ba1e57def75c31b64124cc90dd4c3146dc019 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 099/204] Revert "[nrf noup] bootutil: loader: Fix netcore address checking" This reverts commit a1864167e432fe95c2595647c4fdf56fdb855413. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index daa778b85..de8516e76 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1400,7 +1400,7 @@ boot_validated_swap_type(struct boot_loader_state *state, #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS - if(!(reset_addr >= PM_CPUNET_APP_ADDRESS && reset_addr < PM_CPUNET_APP_END_ADDRESS)) + if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif { const struct flash_area *primary_fa; @@ -1473,8 +1473,7 @@ boot_validated_swap_type(struct boot_loader_state *state, * update and indicate to the caller of this function that no update is * available */ - if (upgrade_valid && reset_addr >= PM_CPUNET_APP_ADDRESS && - reset_addr < PM_CPUNET_APP_END_ADDRESS) { + if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); From 4cb67bf0f985ff94b4306764b8f2bf08eca58ac4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 100/204] Revert "[nrf noup] boot/../loader: reboot after updating s0/s1" This reverts commit b6eb81897a018d4a09006054750d65e9505c710d. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 10 ---------- boot/zephyr/Kconfig | 1 - 2 files changed, 11 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index de8516e76..0a2b74626 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,10 +49,6 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" -#ifdef __ZEPHYR__ -#include -#endif - #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include #ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION @@ -2670,12 +2666,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); -#if defined(PM_S1_ADDRESS) && defined(CONFIG_REBOOT) - if (owner_nsib[BOOT_CURR_IMG(state)]) { - sys_reboot(SYS_REBOOT_COLD); - - } -#endif break; case BOOT_SWAP_TYPE_FAIL: diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index f110936ab..1e10e6284 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -18,7 +18,6 @@ config MCUBOOT select MPU_ALLOW_FLASH_WRITE if ARM_MPU select USE_DT_CODE_PARTITION if HAS_FLASH_LOAD_OFFSET select MCUBOOT_BOOTUTIL_LIB - select REBOOT if SECURE_BOOT config BOOT_USE_MBEDTLS bool From 8ef804f6f90d0a447eb9bad5789a7f4974f36758 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 101/204] Revert "[nrf noup] boot/../loader: skip downgrade prevention for s1/s0" This reverts commit 8e6e3c2b95893c21e320d87e88730e5918d468ab. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 0a2b74626..49ae5c21f 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -70,9 +70,6 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); BOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; -#ifdef PM_S1_ADDRESS -static bool owner_nsib[BOOT_IMAGE_NUMBER] = {false}; -#endif #if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) || defined(MCUBOOT_DATA_SHARING) static struct image_max_size image_max_sizes[BOOT_IMAGE_NUMBER] = {0}; @@ -1366,9 +1363,6 @@ boot_validated_swap_type(struct boot_loader_state *state, int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); bool upgrade_valid = false; -#if defined(PM_S1_ADDRESS) - owner_nsib[BOOT_CURR_IMG(state)] = false; -#endif #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = @@ -1425,7 +1419,6 @@ boot_validated_swap_type(struct boot_loader_state *state, && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { /* Set primary to be NSIB upgrade slot */ BOOT_IMG_AREA(state, 0) = nsib_fa; - owner_nsib[BOOT_CURR_IMG(state)] = true; } #else return BOOT_SWAP_TYPE_NONE; @@ -1436,10 +1429,6 @@ boot_validated_swap_type(struct boot_loader_state *state, /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } - - if ((primary_fa->fa_off == PM_S0_ADDRESS) || (primary_fa->fa_off == PM_S1_ADDRESS)) { - owner_nsib[BOOT_CURR_IMG(state)] = true; - } } #endif /* PM_S1_ADDRESS */ sec_slot_mark_assigned(state); @@ -2448,13 +2437,6 @@ check_downgrade_prevention(struct boot_loader_state *state) uint32_t security_counter[2]; int rc; -#if defined(PM_S1_ADDRESS) - if (owner_nsib[BOOT_CURR_IMG(state)]) { - /* Downgrade prevention on S0/S1 image is managed by NSIB */ - return 0; - } -#endif - if (MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER) { /* If there was security no counter in slot 0, allow swap */ rc = bootutil_get_img_security_cnt(state, BOOT_PRIMARY_SLOT, From dbb36bc09a2aa4eaa13c1d61a3cd9d12a44856c5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 102/204] Revert "[nrf noup] boot: zephyr: Add NCS boot banner" This reverts commit fe5f292599ef755f207096e148f3cc6ee02337ab. Signed-off-by: Jamie McCrae --- boot/zephyr/prj.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 9ff1ba274..6d538d1de 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -36,6 +36,3 @@ CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 - -# NCS boot banner -CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" From 7ca681b5d8bfeb175048d525c70a53dd8fc4f0c3 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 103/204] Revert "[nrf noup] zephyr/boards: fix nrf54l15pdk ext flash dts overlay" This reverts commit 466fe91e663c71463f35f7e2b4907401289fed2e. Signed-off-by: Jamie McCrae --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 60ee6fe51..ea024fcec 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -14,8 +14,7 @@ /delete-node/ &storage_partition; -&cpuapp_rram { - reg = < 0x0 DT_SIZE_K(1524) >; +&rram0 { partitions { boot_partition: partition@0 { label = "mcuboot"; From 2dfe89d34352acd456e0bfbe9cf44dca5f491439 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 104/204] Revert "[nrf noup] Revert of zephyr: arm: Update reading the flash image reset vector" This reverts commit 52c087af8d2ecfb20da35fc4139c25e0c3899885. Signed-off-by: Jamie McCrae --- boot/zephyr/flash_map_extended.c | 13 +++++++++++++ boot/zephyr/main.c | 20 +++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index 68ae4f3b2..4a29750f7 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -148,8 +148,21 @@ int flash_area_sector_from_off(off_t off, struct flash_sector *sector) uint8_t flash_area_get_device_id(const struct flash_area *fa) { + uint8_t device_id; + int rc; + + rc = BOOT_HOOK_FLASH_AREA_CALL(flash_area_get_device_id_hook, + BOOT_HOOK_REGULAR, fa, &device_id); + if (rc != BOOT_HOOK_REGULAR) { + return device_id; + } + +#if defined(CONFIG_ARM) + return fa->fa_id; +#else (void)fa; return FLASH_DEVICE_ID; +#endif } #define ERASED_VAL 0xff diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 918a01f7a..ab863f156 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -175,16 +175,26 @@ static void do_boot(struct boot_rsp *rsp) /* Get ram address for image */ vt = (struct arm_vector_table *)(rsp->br_hdr->ih_load_addr + rsp->br_hdr->ih_hdr_size); #else - uintptr_t flash_base; int rc; + const struct flash_area *fap; + static uint32_t dst[2]; /* Jump to flash image */ - rc = flash_device_base(rsp->br_flash_dev_id, &flash_base); + rc = flash_area_open(rsp->br_flash_dev_id, &fap); + assert(rc == 0); + + rc = flash_area_read(fap, rsp->br_hdr->ih_hdr_size, dst, sizeof(dst)); assert(rc == 0); +#ifndef CONFIG_ASSERT + /* Enter a lock up as asserts are disabled */ + if (rc != 0) { + while (1); + } +#endif + + flash_area_close(fap); - vt = (struct arm_vector_table *)(flash_base + - rsp->br_image_off + - rsp->br_hdr->ih_hdr_size); + vt = (struct arm_vector_table *)dst; #endif if (IS_ENABLED(CONFIG_SYSTEM_TIMER_HAS_DISABLE_SUPPORT)) { From 03f6c7ad08c82e7314eaeb938e16c6fca60653d8 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 105/204] Revert "[nrf noup] boot/zephyr: fix fw_info search" This reverts commit 09e1b9cf15af5e15e630d47feab64f9cf014604d. Signed-off-by: Jamie McCrae --- boot/zephyr/main.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index ab863f156..a8a231c3c 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -207,14 +207,7 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - uintptr_t fw_start_addr; - - rc = flash_device_base(rsp->br_flash_dev_id, &fw_start_addr); - assert(rc == 0); - - fw_start_addr += rsp->br_image_off + rsp->br_hdr->ih_hdr_size; - - const struct fw_info *firmware_info = fw_info_find(fw_start_addr); + const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS From 8729430e422375049c49405be1407e6e996b8d55 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 106/204] Revert "[nrf noup] boot: zephyr: Disable boot banner if NCS_BOOT_BANNER is used" This reverts commit 2f25a92e5984771dc36395de2b9c45e7deef6ae9. Signed-off-by: Jamie McCrae --- boot/zephyr/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 1e10e6284..1c38d2ba2 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -984,7 +984,6 @@ config BOOT_DISABLE_CACHES config MCUBOOT_BOOT_BANNER bool "Use MCUboot boot banner" depends on BOOT_BANNER - depends on !NCS_BOOT_BANNER depends on "$(APP_VERSION_EXTENDED_STRING)" != "" default y help From c9afc535e2d3ca48824ad3b3f43e21f1936c38b1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 107/204] Revert "[nrf noup] boards: thingy91x: enable serial recovery" This reverts commit bf1b0fa4d62f4bddcbc51ba76e45ccb2ee10e060. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf | 10 ++-------- boot/zephyr/boards/thingy91x_nrf9151.conf | 9 --------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf index 37c7e95b1..72dfa7fca 100644 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -32,7 +32,7 @@ CONFIG_USB_COMPOSITE_DEVICE=y CONFIG_USB_MASS_STORAGE=n CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x910A +CONFIG_USB_DEVICE_PID=0x520F CONFIG_BOOT_SERIAL_BOOT_MODE=y @@ -49,12 +49,6 @@ CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y CONFIG_FLASH_SIMULATOR_STATS=n CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y - -# Makes it possible to update the network core using the flash simulator -CONFIG_NRF53_RECOVERY_NETWORK_CORE=y - CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y -CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y -# Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 -CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n +CONFIG_NRF53_RECOVERY_NETWORK_CORE=y diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf index 2efe1e170..33cd3301c 100644 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -6,12 +6,3 @@ CONFIG_SPI_NOR=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_SPI_NOR_SFDP_DEVICETREE=y CONFIG_MULTITHREADING=y - -# Disable Zephyr console and use UART for MCUboot serial recovery instead -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n -CONFIG_MCUBOOT_SERIAL=y - -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y -CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y From 839adf98ebb2f3d97655265026eaed57af05ad92 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 108/204] Revert "[nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash update" This reverts commit a493f54798318e6a4e484525417cbc79a0bf7a75. Signed-off-by: Jamie McCrae --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 7 ------- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 1 - 2 files changed, 8 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf index 8fc12e074..841922dbd 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -6,10 +6,3 @@ CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 CONFIG_MAIN_STACK_SIZE=20480 CONFIG_BOOT_MAX_IMG_SECTORS=512 CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 -# Ensure that the qspi driver is disabled by default -CONFIG_NORDIC_QSPI_NOR=n - -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - -CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index ea024fcec..76b648903 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -1,7 +1,6 @@ / { chosen { nordic,pm-ext-flash = &mx25r64; - zephyr,code-partition = &boot_partition; }; }; From 8724defcf0207f26f643f185051b16db7250c84b Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 109/204] Revert "[nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash partition" This reverts commit cf16b826e8c699240a373048d69af4923cffee75. Signed-off-by: Jamie McCrae --- ...54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 76b648903..2341ffd26 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -4,42 +4,7 @@ }; }; -/delete-node/ &boot_partition; -/delete-node/ &slot0_partition; -/delete-node/ &slot1_partition; - -/delete-node/ &slot0_ns_partition; -/delete-node/ &slot1_ns_partition; - -/delete-node/ &storage_partition; - -&rram0 { - partitions { - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x000000000 0x00014000>; - }; - slot0_partition: partition@14000 { - label = "image-0"; - reg = <0x000014000 0x0015A000>; - }; - storage_partition: partition@16E000 { - label = "storage"; - reg = < 0x16E000 0x9000 >; - }; - }; -}; &mx25r64 { status = "okay"; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - slot1_partition: partition@0 { - label = "image-1"; - reg = <0x000000000 0x0015A000>; - }; - }; }; From 651d79f4f5621774020e553e09f89e9bda0a61a4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 110/204] Revert "[nrf noup] loader: remove cleanup for direct xip mode" This reverts commit ab602b19743c24a0cc54ddfd0d5e1ef47e58ab05. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 49ae5c21f..b822d2367 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1265,8 +1265,6 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ -#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) - #if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ (defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) @@ -1348,6 +1346,7 @@ static inline void sec_slot_cleanup_if_unusable(void) #endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ +#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined * that a swap operation is required, the image in the secondary slot is checked From e76e785c99139398aed00f6f70ae65c66bb627a0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 111/204] Revert "[nrf noup] boards: nrf54l15: Disable FPROTECT" This reverts commit ef7aad1cdd15f358bdf921f36647d5d4e50b05a8. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index 8d8eb845f..43d8cebe3 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -7,7 +7,4 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n -# TODO: below are not yet supported and need fixing -CONFIG_FPROTECT=n - CONFIG_BOOT_WATCHDOG_FEED=n From afa96bcf975c94cb0ce0381f5450c074f1fc4fa4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 112/204] Revert "[nrf noup] loader: introduced cleanup of unusable secondary slot" This reverts commit 154f4df0d4f76e123592993ddc932df8f37885bb. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 90 -------------------------------------- 1 file changed, 90 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index b822d2367..dbf27d5b0 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1265,87 +1265,6 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ -#if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ -(defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) - -#define SEC_SLOT_VIRGIN 0 -#define SEC_SLOT_TOUCHED 1 -#define SEC_SLOT_ASSIGNED 2 - -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -/* This configuration is peculiar - the one physical secondary slot is - * mocking two logical secondary - */ -#define SEC_SLOT_PHYSICAL_CNT 1 -#else -#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER -#endif - -static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0}; - -static inline void sec_slot_touch(struct boot_loader_state *state) -{ - uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); - - if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) { - sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED; - } -} - -static inline void sec_slot_mark_assigned(struct boot_loader_state *state) -{ - uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); - - sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED; -} - -/** - * Cleanu up all secondary slot which couldn't be assigned to any primary slot. - * - * This function erases content of each secondary slot which contains valid - * header but couldn't be assigned to any of supported primary images. - * - * This function is supposed to be called after boot_validated_swap_type() - * iterates over all the images in context_boot_go(). - */ -static void sec_slot_cleanup_if_unusable(void) -{ - uint8_t idx; - - for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) { - if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) { - const struct flash_area *secondary_fa; - int rc; - - rc = flash_area_open(flash_area_id_from_multi_image_slot(idx, BOOT_SECONDARY_SLOT), - &secondary_fa); - if (!rc) { - rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); - if (!rc) { - BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx); - } - } - - if (rc) { - BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx); - } - } - } -} -#else -static inline void sec_slot_touch(struct boot_loader_state *state) -{ -} -static inline void sec_slot_mark_assigned(struct boot_loader_state *state) -{ -} -static inline void sec_slot_cleanup_if_unusable(void) -{ -} -#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ - defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ - #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined @@ -1384,9 +1303,6 @@ boot_validated_swap_type(struct boot_loader_state *state, if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } - - sec_slot_touch(state); - #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) @@ -1421,7 +1337,6 @@ boot_validated_swap_type(struct boot_loader_state *state, } #else return BOOT_SWAP_TYPE_NONE; - #endif } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { @@ -1430,9 +1345,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } } #endif /* PM_S1_ADDRESS */ - sec_slot_mark_assigned(state); } - #endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); @@ -2574,9 +2487,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } } - /* cleanup secondary slots which were recognized unusable*/ - sec_slot_cleanup_if_unusable(); - #if (BOOT_IMAGE_NUMBER > 1) if (has_upgrade) { /* Iterate over all the images and verify whether the image dependencies From dba0e5c6f2d65778955e62c483d943bf018d8903 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 113/204] Revert "[nrf noup] sysflash: Add support for three images" This reverts commit 6f0279bf954c1a473a0f93244c867277cd073b41. Signed-off-by: Jamie McCrae --- boot/zephyr/include/sysflash/pm_sysflash.h | 82 ++++++++++------------ 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index db60ddd03..377291e8b 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -11,19 +11,37 @@ #include #include -#include #ifndef CONFIG_SINGLE_APPLICATION_SLOT -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ +#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; -#endif /* (MCUBOOT_IMAGE_NUMBER == 2 && defined(PM_B0_ADDRESS) */ +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ @@ -38,52 +56,26 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) - -#else /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - */ - -/* Each pair of slots is separated by , and there is no terminating character */ -#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID -#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID -#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID - -#if (MCUBOOT_IMAGE_NUMBER == 1) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 2) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ - FLASH_AREA_IMAGE_1_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 3) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ - FLASH_AREA_IMAGE_1_SLOTS, \ - FLASH_AREA_IMAGE_2_SLOTS #else -#error Unsupported number of images -#endif -static inline uint32_t __flash_area_ids_for_slot(int img, int slot) -{ - static const int all_slots[] = { - ALL_AVAILABLE_SLOTS - }; - return all_slots[img * 2 + slot]; -}; +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) -#undef FLASH_AREA_IMAGE_0_SLOTS -#undef FLASH_AREA_IMAGE_1_SLOTS -#undef FLASH_AREA_IMAGE_2_SLOTS -#undef ALL_AVAILABLE_SLOTS +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) -#define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0) -#define FLASH_AREA_IMAGE_SECONDARY(x) __flash_area_ids_for_slot(x, 1) +#endif /* PM_B0_ADDRESS */ -#if !defined(CONFIG_BOOT_SWAP_USING_MOVE) -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #endif - -#endif /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - */ +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #else /* CONFIG_SINGLE_APPLICATION_SLOT */ From 194e0dde3e3cc01a0cc36712f3fb1ec037492e63 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 114/204] Revert "[nrf noup] sysflash: Move partition manager definitions to pm_sysflash.h" This reverts commit 0117f67d27406ede222e0300fbd7e1c72eadb8ef. Signed-off-by: Jamie McCrae --- boot/zephyr/include/sysflash/pm_sysflash.h | 92 ---------------------- boot/zephyr/include/sysflash/sysflash.h | 90 +++++++++++++++++++-- 2 files changed, 85 insertions(+), 97 deletions(-) delete mode 100644 boot/zephyr/include/sysflash/pm_sysflash.h diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h deleted file mode 100644 index 377291e8b..000000000 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef __PM_SYSFLASH_H__ -#define __PM_SYSFLASH_H__ -/* Blocking the __SYSFLASH_H__ */ -#define __SYSFLASH_H__ - -#include -#include - -#ifndef CONFIG_SINGLE_APPLICATION_SLOT - -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -#if defined(PM_B0_ADDRESS) -extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) -#else - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) - -#endif /* PM_B0_ADDRESS */ - -#endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID - -#else /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID -/* NOTE: Scratch parition is not used by single image DFU but some of - * functions in common files reference it, so the definitions has been - * provided to allow compilation of common units. - */ -#define FLASH_AREA_IMAGE_SCRATCH 0 - -#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#endif /* __PM_SYSFLASH_H__ */ diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 3c3638d7f..f1ef4100e 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -4,15 +4,93 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if USE_PARTITION_MANAGER -/* Blocking the rest of the file */ +#ifndef __SYSFLASH_H__ #define __SYSFLASH_H__ -#include + +#if USE_PARTITION_MANAGER +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#if defined(PM_B0_ADDRESS) +extern uint32_t _image_1_primary_slot_id[]; #endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ -#ifndef __SYSFLASH_H__ -#define __SYSFLASH_H__ +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#else + +#include #include #include #include @@ -71,4 +149,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#endif /* USE_PARTITION_MANAGER */ + #endif /* __SYSFLASH_H__ */ From c946ae4ca285bbc5e0c5e40b25f4870eced86fb0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 115/204] Revert "[nrf noup] boot: Add support for NSIB and multi-image" This reverts commit 1f08c7930a316b62423b481ba62ff50c2ee2e8ac. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 44 ++++++------------------- boot/zephyr/include/sysflash/sysflash.h | 19 ++--------- 2 files changed, 12 insertions(+), 51 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index dbf27d5b0..2a5d49f8d 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1192,11 +1192,6 @@ boot_validate_slot(struct boot_loader_state *state, int slot, if (BOOT_CURR_IMG(state) == 1) { min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; -#ifdef PM_S1_ADDRESS - } else if (BOOT_CURR_IMG(state) == 0) { - min_addr = PM_S0_ADDRESS; - max_addr = pri_fa->fa_off + pri_fa->fa_size; -#endif } else #endif { @@ -1310,37 +1305,18 @@ boot_validated_swap_type(struct boot_loader_state *state, { const struct flash_area *primary_fa; rc = flash_area_open(flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), - &primary_fa); + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } - - /* Check start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off) { -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - const struct flash_area *nsib_fa; - - /* NSIB upgrade slot */ - rc = flash_area_open((uint32_t)_image_1_primary_slot_id, - &nsib_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - - /* Image is placed before Primary and within the NSIB slot */ - if (reset_addr > nsib_fa->fa_off - && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { - /* Set primary to be NSIB upgrade slot */ - BOOT_IMG_AREA(state, 0) = nsib_fa; - } -#else - return BOOT_SWAP_TYPE_NONE; -#endif - - } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for any */ + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ return BOOT_SWAP_TYPE_NONE; } } @@ -1635,7 +1611,7 @@ boot_copy_image(struct boot_loader_state *state, struct boot_status *bs) BOOT_LOG_INF("Image %d upgrade secondary slot -> primary slot", image_index); BOOT_LOG_INF("Erasing the primary slot"); - rc = flash_area_open(flash_area_get_id(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)), + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap_primary_slot); assert (rc == 0); diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index f1ef4100e..7112f9baa 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -23,24 +23,9 @@ /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#if defined(PM_B0_ADDRESS) -extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +#ifdef PM_B0_ADDRESS -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) +extern uint32_t _image_1_primary_slot_id[]; #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ From f6e93874c366a27588dad95caef85011bed83251 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 116/204] Revert "[nrf noup] loader: Fix missing PCD define check" This reverts commit 566af5ee1f6e925d1208c382fa7386e3f0a9d8c0. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 2a5d49f8d..d706719e1 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1341,7 +1341,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ - && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) && defined(CONFIG_PCD_APP) + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available @@ -1369,8 +1369,7 @@ boot_validated_swap_type(struct boot_loader_state *state, swap_type = BOOT_SWAP_TYPE_NONE; } } -#endif /* CONFIG_SOC_NRF5340_CPUAPP && PM_CPUNET_B0N_ADDRESS && - !CONFIG_NRF53_MULTI_IMAGE_UPDATE && CONFIG_PCD_APP */ +#endif /* CONFIG_SOC_NRF5340_CPUAPP */ } return swap_type; From 23e28859fa2405ac5ff48f4963e6a5a11702b83b Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 117/204] Revert "[nrf noup] loader: work-around for multi-image builds" This reverts commit 8c62ac94c953f93dbf80194f09b4bf0dd2c29a1f. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index d706719e1..8687db9c4 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -495,7 +495,7 @@ boot_verify_dependencies(struct boot_loader_state *state) if (rc == 0) { /* All dependencies've been satisfied, continue with next image. */ BOOT_CURR_IMG(state)++; - } else if (rc == BOOT_EBADIMAGE) { + } else { /* Cannot upgrade due to non-met dependencies, so disable all * image upgrades. */ @@ -504,10 +504,7 @@ boot_verify_dependencies(struct boot_loader_state *state) BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE; } break; - } else { - /* Other error happened, images are inconsistent */ - return rc; - } + } } return rc; } @@ -1886,6 +1883,7 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) } #endif + /** * Performs a clean (not aborted) image update. * From 6e006f1494f4d23ec231237a5a700d0f990d2097 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 118/204] Revert "[nrf noup] boot/zephyr/boards: nRF54l15pdk ext flash cfg" This reverts commit 8c73d8b51ebda556c5d2985fdf3c2ba60c0a6fd3. Signed-off-by: Jamie McCrae --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 8 -------- .../nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 10 ---------- 2 files changed, 18 deletions(-) delete mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf delete mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf deleted file mode 100644 index 841922dbd..000000000 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_MULTITHREADING=y -CONFIG_SPI=y -CONFIG_SPI_NOR=y -CONFIG_FLASH=y -CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 -CONFIG_MAIN_STACK_SIZE=20480 -CONFIG_BOOT_MAX_IMG_SECTORS=512 -CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay deleted file mode 100644 index 2341ffd26..000000000 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ /dev/null @@ -1,10 +0,0 @@ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; - - -&mx25r64 { - status = "okay"; -}; From 101090ec58f39e05f53188726bc97cb0a99f5944 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 119/204] Revert "[nrf noup] boards: thingy53: disable GPIO ISR support" This reverts commit fa084222682e185cb0c5be154ecaf310f5bd560e. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index e10656678..7d3bc0bec 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -21,7 +21,6 @@ CONFIG_UART_LINE_CTRL=y # MCUBoot serial CONFIG_GPIO=y -CONFIG_GPIO_NRFX_INTERRUPT=n CONFIG_MCUBOOT_SERIAL=y CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y CONFIG_BOOT_SERIAL_CDC_ACM=y From c1988ae66410c14ec3a058fb83ec94bd0da82f54 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 120/204] =?UTF-8?q?Revert=20"[nrf=20noup]=C2=A0loader:=20A?= =?UTF-8?q?dd=20firmware=20version=20check=20downgrade=20prevention"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit bb083baeaaed9eeded204e43cab53fef805ec4f7. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 8687db9c4..324d4b37b 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -51,10 +51,6 @@ #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include -#ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION -#include -int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); -#endif #endif #ifdef MCUBOOT_ENC_IMAGES @@ -1099,21 +1095,9 @@ boot_validate_slot(struct boot_loader_state *state, int slot, int rc; /* Check if version of secondary slot is sufficient */ - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ - && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) - if (BOOT_CURR_IMG(state) == 1) { - rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); - } else { - rc = boot_version_cmp( - &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); - } -#else - rc = boot_version_cmp( - &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); -#endif + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); flash_area_erase(fap, 0, flash_area_get_size(fap)); From 73899c34f6868584960488c83cd0b97af59639c6 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 121/204] Revert "[nrf noup] zephyr: Boot even if EXT_ABI is not provided" This reverts commit 79ca4781225a9aa6f8631fb01c9ca5c8218712ca. Signed-off-by: Jamie McCrae --- boot/zephyr/main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index a8a231c3c..880d62392 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -207,16 +207,13 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); - bool provided = fw_info_ext_api_provide(firmware_info, true); + bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); #ifdef PM_S0_ADDRESS /* Only fail if the immutable bootloader is present. */ if (!provided) { - if (firmware_info == NULL) { - BOOT_LOG_WRN("Unable to find firmware info structure in %p", vt); - } - BOOT_LOG_ERR("Failed to provide EXT_APIs to %p", vt); + BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); + return; } #endif #endif From 11a7be566fcb67a2560be89697e50a115d87c951 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 122/204] Revert "[nrf noup] zephyr: Add RAM flash configuration to cache for sysbuild" This reverts commit 5694ff5a65d06ec87901113fa333438be70bbc77. Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 1b4665050..03230f565 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -712,14 +712,3 @@ zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) endif() - -if(SYSBUILD AND CONFIG_PCD_APP) - # Sysbuild requires details of the RAM flash device are stored to the cache of MCUboot so - # that they can be read when running partition manager - dt_nodelabel(ram_flash_dev NODELABEL flash_sim0) - dt_reg_addr(ram_flash_addr PATH ${ram_flash_dev}) - dt_reg_size(ram_flash_size PATH ${ram_flash_dev}) - - set(RAM_FLASH_ADDR "${ram_flash_addr}" CACHE STRING "" FORCE) - set(RAM_FLASH_SIZE "${ram_flash_size}" CACHE STRING "" FORCE) -endif() From 922ee4b421edc76b105952faeb30039666ea0972 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 123/204] Revert "[nrf noup] loader: Do not check reset vector for XIP image" This reverts commit 78f267f479d4da6cfed6382c667f9a68fbec985f. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 324d4b37b..b131c0ff4 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1142,16 +1142,6 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * overwriting an application written to the incorrect slot. * This feature is only supported by ARM platforms. */ -#if MCUBOOT_IMAGE_NUMBER >= 3 - /* Currently the MCUboot can be configured for up to 3 image, where image number 2 is - * designated for XIP, where it is the second part of image stored in slots of image - * 0. This part of image is not bootable, as the XIP setup is done by the app in - * image 0 slot, and it does not carry the reset vector. - */ - if (fap == state->imgs[2][BOOT_SECONDARY_SLOT].area) { - goto out; - } -#endif if (fap == BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) { const struct flash_area *pri_fa = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); struct image_header *secondary_hdr = boot_img_hdr(state, slot); From 4cac6fe3ebec4abb0b0968c3b965265bf35228e5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 124/204] Revert "[nrf noup] loader: Fix reading reset addr to support ext flash" This reverts commit afd1f6f75e0c716900b31a026fa04086f0c7449c. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index b131c0ff4..e75bfd42a 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1251,9 +1251,10 @@ boot_validated_swap_type(struct boot_loader_state *state, #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = 0; + uint32_t *vtable = 0; uint32_t reset_addr = 0; - int rc = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1263,19 +1264,16 @@ boot_validated_swap_type(struct boot_loader_state *state, */ if (hdr->ih_magic == IMAGE_MAGIC) { - rc = flash_area_read(secondary_fa, hdr->ih_hdr_size + - sizeof(uint32_t), &reset_addr, - sizeof(reset_addr)); - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } + vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + vtable = (uint32_t *)(vtable_addr); + reset_addr = vtable[1]; #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif { const struct flash_area *primary_fa; - rc = flash_area_open(flash_area_id_from_multi_image_slot( + int rc = flash_area_open(flash_area_id_from_multi_image_slot( BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), &primary_fa); @@ -1311,19 +1309,16 @@ boot_validated_swap_type(struct boot_loader_state *state, upgrade_valid = true; } -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ - && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available */ if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { - struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; - uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); uint32_t fw_size = hdr->ih_img_size; + BOOT_LOG_INF("Starting network core update"); - rc = pcd_network_core_update(net_core_fw_addr, fw_size); + int rc = pcd_network_core_update(vtable, fw_size); if (rc != 0) { swap_type = BOOT_SWAP_TYPE_FAIL; From 0f4306d421fa44effbd6ff6e8a55ecf6b4769484 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 125/204] Revert "[nrf noup] zephyr: Clean up non-secure RAM if enabled" This reverts commit ed0ee1fd4fe3bc39b5cffbc0e6c75b37de364d15. Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 2 +- boot/zephyr/include/nrf_cleanup.h | 5 -- boot/zephyr/main.c | 5 +- boot/zephyr/nrf_cleanup.c | 79 ++++++++----------------------- 4 files changed, 22 insertions(+), 69 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 03230f565..d6d69cf7a 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -707,7 +707,7 @@ if(SYSBUILD) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() -if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL OR CONFIG_MCUBOOT_CLEANUP_NONSECURE_RAM) +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h index 9e87e13f5..6b04cedfe 100644 --- a/boot/zephyr/include/nrf_cleanup.h +++ b/boot/zephyr/include/nrf_cleanup.h @@ -16,9 +16,4 @@ */ void nrf_cleanup_peripheral(void); -/** - * Perform cleanup of non-secure RAM that may have been used by MCUBoot. - */ -void nrf_cleanup_ns_ram(void); - #endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 880d62392..08587c31e 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -143,7 +143,7 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL || CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL #include #endif @@ -220,9 +220,6 @@ static void do_boot(struct boot_rsp *rsp) #if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL nrf_cleanup_peripheral(); #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM && defined(PM_SRAM_NONSECURE_NAME) - nrf_cleanup_ns_ram(); -#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 051705ec9..5bab26b24 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -5,8 +5,9 @@ */ #include -#include -#include +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) + #include +#endif #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif @@ -19,15 +20,6 @@ #include -#if USE_PARTITION_MANAGER -#include -#endif - -#if defined(NRF_UARTE0) || defined(NRF_UARTE1) || defined(NRF_UARTE20) || \ - defined(NRF_UARTE30) -#define NRF_UARTE_CLEANUP -#endif - #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -45,23 +37,6 @@ static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) } #endif -#if defined(NRF_UARTE_CLEANUP) -static NRF_UARTE_Type *nrf_uarte_to_clean[] = { -#if defined(NRF_UARTE0) - NRF_UARTE0, -#endif -#if defined(NRF_UARTE1) - NRF_UARTE1, -#endif -#if defined(NRF_UARTE20) - NRF_UARTE20, -#endif -#if defined(NRF_UARTE30) - NRF_UARTE30, -#endif -}; -#endif - static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); @@ -78,31 +53,26 @@ void nrf_cleanup_peripheral(void) #if defined(NRF_RTC2) nrf_cleanup_rtc(NRF_RTC2); #endif - -#if defined(NRF_UARTE_CLEANUP) - for (int i = 0; i < sizeof(nrf_uarte_to_clean) / sizeof(nrf_uarte_to_clean[0]); ++i) { - NRF_UARTE_Type *current = nrf_uarte_to_clean[i]; - - nrfy_uarte_int_disable(current, 0xFFFFFFFF); - nrfy_uarte_int_uninit(current); - nrfy_uarte_task_trigger(current, NRF_UARTE_TASK_STOPRX); - - nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXSTARTED); - nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_ENDRX); - nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); - nrfy_uarte_disable(current); - +#if defined(NRF_UARTE0) + nrf_uarte_disable(NRF_UARTE0); + nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); #if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)current + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, - NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)current + NRF_UARTE_PUBLISH_CONF_OFFS, 0, - NRF_UARTE_PUBLISH_CONF_SIZE); + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_UARTE1) + nrf_uarte_disable(NRF_UARTE1); + nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); #endif - } #endif - #if defined(NRF_PPI) nrf_ppi_channels_disable_all(NRF_PPI); #endif @@ -111,12 +81,3 @@ void nrf_cleanup_peripheral(void) #endif nrf_cleanup_clock(); } - -#if USE_PARTITION_MANAGER \ - && defined(CONFIG_ARM_TRUSTZONE_M) \ - && defined(PM_SRAM_NONSECURE_NAME) -void nrf_cleanup_ns_ram(void) -{ - memset((void *) PM_SRAM_NONSECURE_ADDRESS, 0, PM_SRAM_NONSECURE_SIZE); -} -#endif From 4577b083909b660621e809daf648d30a2cded1c6 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 126/204] Revert "[nrf noup] zephyr: clean peripherals state before boot" This reverts commit f9432662129b508545cbf7d6b393e553552a778e. Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 6 --- boot/zephyr/include/nrf_cleanup.h | 19 ------- boot/zephyr/main.c | 8 +-- boot/zephyr/nrf_cleanup.c | 83 ------------------------------- 4 files changed, 1 insertion(+), 115 deletions(-) delete mode 100644 boot/zephyr/include/nrf_cleanup.h delete mode 100644 boot/zephyr/nrf_cleanup.c diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index d6d69cf7a..dc687c209 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -706,9 +706,3 @@ if(SYSBUILD) set(mcuboot_image_footer_size ${required_size} CACHE INTERNAL "Estimated MCUboot image trailer size" FORCE) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() - -if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) -zephyr_library_sources( - ${BOOT_DIR}/zephyr/nrf_cleanup.c -) -endif() diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h deleted file mode 100644 index 6b04cedfe..000000000 --- a/boot/zephyr/include/nrf_cleanup.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef H_NRF_CLEANUP_ -#define H_NRF_CLEANUP_ - -/** - * Perform cleanup on some peripheral resources used by MCUBoot prior chainload - * the application. - * - * This function disables all RTC instances and UARTE instances. - * It Disables their interrupts signals as well. - */ -void nrf_cleanup_peripheral(void); - -#endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 08587c31e..bef85ad9f 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -143,10 +143,6 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL -#include -#endif - BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -217,9 +213,7 @@ static void do_boot(struct boot_rsp *rsp) } #endif #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL - nrf_cleanup_peripheral(); -#endif + #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c deleted file mode 100644 index 5bab26b24..000000000 --- a/boot/zephyr/nrf_cleanup.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#include -#if defined(NRF_UARTE0) || defined(NRF_UARTE1) - #include -#endif -#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) - #include -#endif -#if defined(NRF_PPI) - #include -#endif -#if defined(NRF_DPPIC) - #include -#endif - -#include - -#define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) -#define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ - NRF_UARTE_SUBSCRIBE_CONF_OFFS) - -#define NRF_UARTE_PUBLISH_CONF_OFFS offsetof(NRF_UARTE_Type, PUBLISH_CTS) -#define NRF_UARTE_PUBLISH_CONF_SIZE (offsetof(NRF_UARTE_Type, SHORTS) -\ - NRF_UARTE_PUBLISH_CONF_OFFS) - -#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) -static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) -{ - nrf_rtc_task_trigger(rtc_reg, NRF_RTC_TASK_STOP); - nrf_rtc_event_disable(rtc_reg, 0xFFFFFFFF); - nrf_rtc_int_disable(rtc_reg, 0xFFFFFFFF); -} -#endif - -static void nrf_cleanup_clock(void) -{ - nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); -} - -void nrf_cleanup_peripheral(void) -{ -#if defined(NRF_RTC0) - nrf_cleanup_rtc(NRF_RTC0); -#endif -#if defined(NRF_RTC1) - nrf_cleanup_rtc(NRF_RTC1); -#endif -#if defined(NRF_RTC2) - nrf_cleanup_rtc(NRF_RTC2); -#endif -#if defined(NRF_UARTE0) - nrf_uarte_disable(NRF_UARTE0); - nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); -#if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); -#endif -#endif -#if defined(NRF_UARTE1) - nrf_uarte_disable(NRF_UARTE1); - nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); -#if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); -#endif -#endif -#if defined(NRF_PPI) - nrf_ppi_channels_disable_all(NRF_PPI); -#endif -#if defined(NRF_DPPIC) - nrf_dppi_channels_disable_all(NRF_DPPIC); -#endif - nrf_cleanup_clock(); -} From 14a6f38da1ade457d30f08764e276b8a1324db8c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 127/204] Revert "[nrf noup] boot: nrf53-specific customizations" This reverts commit ff0cc9c0ab4cf58aa926d2ef980f2c53821af997. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 96 +++++-------------- .../boards/thingy53_nrf5340_cpuapp.conf | 74 +------------- boot/zephyr/include/sysflash/sysflash.h | 23 ----- boot/zephyr/main.c | 7 -- boot/zephyr/pm.yml | 13 --- 5 files changed, 28 insertions(+), 185 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index e75bfd42a..907ec397e 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -49,10 +49,6 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) -#include -#endif - #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -1246,15 +1242,7 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); - bool upgrade_valid = false; - -#if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) - const struct flash_area *secondary_fa = - BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; - uint32_t vtable_addr = 0; - uint32_t *vtable = 0; - uint32_t reset_addr = 0; +#ifdef PM_S1_ADDRESS /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1262,36 +1250,34 @@ boot_validated_swap_type(struct boot_loader_state *state, * vector. Note that there are good reasons for not using img_num from * the swap info. */ + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = + (struct image_header *)secondary_fa->fa_off; if (hdr->ih_magic == IMAGE_MAGIC) { - vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - vtable = (uint32_t *)(vtable_addr); - reset_addr = vtable[1]; -#ifdef PM_S1_ADDRESS -#ifdef PM_CPUNET_B0N_ADDRESS - if(reset_addr < PM_CPUNET_B0N_ADDRESS) -#endif - { - const struct flash_area *primary_fa; - int rc = flash_area_open(flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ - return BOOT_SWAP_TYPE_NONE; - } - } -#endif /* PM_S1_ADDRESS */ + const struct flash_area *primary_fa; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *vtable = (uint32_t *)(vtable_addr); + uint32_t reset_addr = vtable[1]; + int rc = flash_area_open( + flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } } -#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ +#endif swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -1305,37 +1291,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } else { swap_type = BOOT_SWAP_TYPE_FAIL; } - } else { - upgrade_valid = true; - } - -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) - /* If the update is valid, and it targets the network core: perform the - * update and indicate to the caller of this function that no update is - * available - */ - if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { - uint32_t fw_size = hdr->ih_img_size; - - BOOT_LOG_INF("Starting network core update"); - int rc = pcd_network_core_update(vtable, fw_size); - - if (rc != 0) { - swap_type = BOOT_SWAP_TYPE_FAIL; - } else { - BOOT_LOG_INF("Done updating network core"); -#if defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE) - /* swap_erase_trailer_sectors is undefined if upgrade only - * method is used. There is no need to erase sectors, because - * the image cannot be reverted. - */ - rc = swap_erase_trailer_sectors(state, - secondary_fa); -#endif - swap_type = BOOT_SWAP_TYPE_NONE; - } } -#endif /* CONFIG_SOC_NRF5340_CPUAPP */ } return swap_type; diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index 7d3bc0bec..f2e42fd64 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -1,73 +1,3 @@ -CONFIG_SIZE_OPTIMIZATIONS=y - -CONFIG_SYSTEM_CLOCK_NO_WAIT=y -CONFIG_PM=n - -CONFIG_MAIN_STACK_SIZE=10240 -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -CONFIG_BOOT_MAX_IMG_SECTORS=2048 -CONFIG_BOOT_SIGNATURE_TYPE_RSA=y - -# Flash -CONFIG_FLASH=y -CONFIG_BOOT_ERASE_PROGRESSIVELY=y -CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y -CONFIG_FPROTECT=y - -# Serial -CONFIG_SERIAL=y -CONFIG_UART_LINE_CTRL=y - -# MCUBoot serial -CONFIG_GPIO=y -CONFIG_MCUBOOT_SERIAL=y -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y -CONFIG_BOOT_SERIAL_CDC_ACM=y - -# Required by QSPI -CONFIG_NORDIC_QSPI_NOR=y -CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 -CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 - -# Required by USB and QSPI -CONFIG_MULTITHREADING=y - -# USB -CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n -CONFIG_USB_DEVICE_REMOTE_WAKEUP=n -CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA" -CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53" -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x5300 -CONFIG_USB_CDC_ACM=y - -# Decrease memory footprint -CONFIG_CBPRINTF_NANO=y -CONFIG_TIMESLICING=n -CONFIG_BOOT_BANNER=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n -CONFIG_LOG=n -CONFIG_ERRNO=n -CONFIG_PRINTK=n -CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_NORDIC_QSPI_NOR=n CONFIG_SPI=n -CONFIG_I2C=n -CONFIG_UART_NRFX=n - -# The following configurations are required to support simultaneous multi image update -CONFIG_PCD_APP=y -CONFIG_UPDATEABLE_IMAGE_NUMBER=2 -CONFIG_BOOT_UPGRADE_ONLY=y -# The network core cannot access external flash directly. The flash simulator must be used to -# provide a memory region that is used to forward the new firmware to the network core. -CONFIG_FLASH_SIMULATOR=y -CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y -CONFIG_FLASH_SIMULATOR_STATS=n - -# Enable custom command to erase settings partition. -CONFIG_ENABLE_MGMT_PERUSER=y -CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y +CONFIG_MULTITHREADING=y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 7112f9baa..99cbf56b7 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -20,11 +20,6 @@ #elif (MCUBOOT_IMAGE_NUMBER == 2) -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -#ifdef PM_B0_ADDRESS - extern uint32_t _image_1_primary_slot_id[]; #define FLASH_AREA_IMAGE_PRIMARY(x) \ @@ -40,24 +35,6 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) -#else - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) - -#endif /* PM_B0_ADDRESS */ - #endif #define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index bef85ad9f..7353f3579 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -92,10 +92,6 @@ const struct boot_uart_funcs boot_funcs = { #include #endif -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) -#include -#endif - /* CONFIG_LOG_MINIMAL is the legacy Kconfig property, * replaced by CONFIG_LOG_MODE_MINIMAL. */ @@ -642,9 +638,6 @@ int main(void) ; } -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) && defined(CONFIG_PCD_APP) - pcd_lock_ram(); -#endif #endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ ZEPHYR_BOOT_LOG_STOP(); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index 13ffc44aa..5df9ae547 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -75,16 +75,3 @@ mcuboot_pad: #ifdef CONFIG_FPROTECT align: {start: CONFIG_FPROTECT_BLOCK_SIZE} #endif - -#if (CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH) -mcuboot_primary_1: - region: ram_flash - size: CONFIG_NRF53_RAM_FLASH_SIZE -#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ - -#if (CONFIG_NRF53_MULTI_IMAGE_UPDATE) -mcuboot_secondary_1: - region: external_flash - size: CONFIG_NRF53_RAM_FLASH_SIZE - -#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ From cc3c415e77e7af486b165359493765bf519859a5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 128/204] Revert "[nrf noup] treewide: add NCS partition manager support" This reverts commit 70d45f0a754e37708b14d441324a3da8545f0ad2. Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 95 +++---------------------- boot/bootutil/src/swap_move.c | 13 ---- boot/bootutil/src/swap_scratch.c | 13 ---- boot/zephyr/CMakeLists.txt | 7 -- boot/zephyr/Kconfig | 2 - boot/zephyr/include/sysflash/sysflash.h | 48 ------------- boot/zephyr/include/target.h | 4 -- boot/zephyr/main.c | 45 ------------ boot/zephyr/pm.yml | 77 -------------------- boot/zephyr/prj.conf | 1 - ext/nrf/cc310_glue.h | 2 +- zephyr/module.yml | 3 +- 12 files changed, 11 insertions(+), 299 deletions(-) delete mode 100644 boot/zephyr/pm.yml diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 907ec397e..cf6a388f8 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -144,15 +144,6 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, * * Failure to read any headers is a fatal error. */ -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. The primary slot of the second image - * (image 1) will not contain a valid image header until an upgrade - * of mcuboot has happened (filling S1 with the new version). - */ - if (BOOT_CURR_IMG(state) == 1 && i == 0) { - continue; - } -#endif /* PM_S1_ADDRESS */ if (i > 0 && !require_all) { return 0; } else { @@ -1149,24 +1140,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, goto out; } - uint32_t min_addr, max_addr; - -#ifdef PM_CPUNET_APP_ADDRESS - /* The primary slot for the network core is emulated in RAM. - * Its flash_area hasn't got relevant boundaries. - * Therfore need to override its boundaries for the check. - */ - if (BOOT_CURR_IMG(state) == 1) { - min_addr = PM_CPUNET_APP_ADDRESS; - max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; - } else -#endif - { - min_addr = pri_fa->fa_off; - max_addr = pri_fa->fa_off + pri_fa->fa_size; - } - - if (reset_value < min_addr || reset_value> (max_addr)) { + if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); BOOT_LOG_ERR("Erasing image from secondary slot"); @@ -1242,42 +1216,6 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other - * B1 slot S0 or S1) share the same secondary slot, we need to check - * whether the update candidate in the secondary slot is intended for - * image 0 or image 1 primary by looking at the address of the reset - * vector. Note that there are good reasons for not using img_num from - * the swap info. - */ - const struct flash_area *secondary_fa = - BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = - (struct image_header *)secondary_fa->fa_off; - - if (hdr->ih_magic == IMAGE_MAGIC) { - const struct flash_area *primary_fa; - uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - uint32_t *vtable = (uint32_t *)(vtable_addr); - uint32_t reset_addr = vtable[1]; - int rc = flash_area_open( - flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ - return BOOT_SWAP_TYPE_NONE; - } - } -#endif swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -2523,25 +2461,15 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. Image 1 primary is the currently - * executing MCUBoot image, and is therefore already validated by NSIB and - * does not need to also be validated by MCUBoot. + FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL, 0); + /* Check for all possible values is redundant in normal operation it + * is meant to prevent FI attack. */ - bool image_validated_by_nsib = BOOT_CURR_IMG(state) == 1; - if (!image_validated_by_nsib) -#endif - { - FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL, 0); - /* Check for all possible values is redundant in normal operation it - * is meant to prevent FI attack. - */ - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || - FIH_EQ(fih_rc, FIH_FAILURE) || - FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; - } + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || + FIH_EQ(fih_rc, FIH_FAILURE) || + FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; } #else /* Even if we're not re-validating the primary slot, we could be booting @@ -2558,16 +2486,11 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */ -#ifdef PM_S1_ADDRESS - if (!image_validated_by_nsib) -#endif - { rc = boot_update_hw_rollback_protection(state); if (rc != 0) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } - } rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT); if (rc != 0) { diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 276eba00e..dd5b131a7 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -252,18 +252,6 @@ static int app_max_sectors(struct boot_loader_state *state) int boot_slots_compatible(struct boot_loader_state *state) { -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. In this case, image 1 primary points to the other - * B1 slot (ie S0 or S1), and image 0 primary points to the app. - * With this configuration, image 0 and image 1 share the secondary slot. - * Hence, the primary slot of image 1 will be *smaller* than image 1's - * secondary slot. This is not allowed in upstream mcuboot, so we need - * this patch to allow it. Also, all of these checks are redundant when - * partition manager is in use, and since we have the same sector size - * in all of our flash. - */ - return 1; -#else size_t num_sectors_pri; size_t num_sectors_sec; size_t sector_sz_pri = 0; @@ -331,7 +319,6 @@ boot_slots_compatible(struct boot_loader_state *state) } return 1; -#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index 222d34b71..60751029d 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -141,18 +141,6 @@ boot_status_internal_off(const struct boot_status *bs, int elem_sz) int boot_slots_compatible(struct boot_loader_state *state) { -#ifdef PM_S1_ADDRESS - /* Patch needed for NCS. In this case, image 1 primary points to the other - * B1 slot (ie S0 or S1), and image 0 primary points to the app. - * With this configuration, image 0 and image 1 share the secondary slot. - * Hence, the primary slot of image 1 will be *smaller* than image 1's - * secondary slot. This is not allowed in upstream mcuboot, so we need - * this patch to allow it. Also, all of these checks are redundant when - * partition manager is in use, and since we have the same sector size - * in all of our flash. - */ - return 1; -#else size_t num_sectors_primary; size_t num_sectors_secondary; size_t sz0, sz1; @@ -250,7 +238,6 @@ boot_slots_compatible(struct boot_loader_state *state) #endif return 1; -#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index dc687c209..3a780e509 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -350,13 +350,6 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") endif() message("MCUBoot bootloader key file: ${KEY_FILE}") - set_property( - GLOBAL - PROPERTY - KEY_FILE - ${KEY_FILE} - ) - set(mcuboot_default_signature_files ${MCUBOOT_DIR}/root-ec-p256-pkcs8.pem ${MCUBOOT_DIR}/root-ec-p384.pem diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 1c38d2ba2..b366b26d9 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -9,8 +9,6 @@ mainmenu "MCUboot configuration" comment "MCUboot-specific configuration options" -source "$(ZEPHYR_NRF_MODULE_DIR)/modules/mcuboot/boot/zephyr/Kconfig" - # Hidden option to mark a project as MCUboot config MCUBOOT default y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 99cbf56b7..16d222280 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -7,52 +7,6 @@ #ifndef __SYSFLASH_H__ #define __SYSFLASH_H__ -#if USE_PARTITION_MANAGER -#include -#include - -#ifndef CONFIG_SINGLE_APPLICATION_SLOT - -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - -extern uint32_t _image_1_primary_slot_id[]; - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) -#endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID - -#else /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID -/* NOTE: Scratch parition is not used by single image DFU but some of - * functions in common files reference it, so the definitions has been - * provided to allow compilation of common units. - */ -#define FLASH_AREA_IMAGE_SCRATCH 0 - -#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#else - -#include #include #include #include @@ -111,6 +65,4 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ -#endif /* USE_PARTITION_MANAGER */ - #endif /* __SYSFLASH_H__ */ diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h index 40287d515..9bbfd4b19 100644 --- a/boot/zephyr/include/target.h +++ b/boot/zephyr/include/target.h @@ -8,8 +8,6 @@ #ifndef H_TARGETS_TARGET_ #define H_TARGETS_TARGET_ -#ifndef USE_PARTITION_MANAGER - #if defined(MCUBOOT_TARGET_CONFIG) /* * Target-specific definitions are permitted in legacy cases that @@ -47,6 +45,4 @@ #error "Target support is incomplete; cannot build mcuboot." #endif -#endif /* ifndef USE_PARTITION_MANAGER */ - #endif /* H_TARGETS_TARGET_ */ diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 7353f3579..683b2f7f5 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -70,10 +70,6 @@ #endif /* CONFIG_SOC_FAMILY_ESPRESSIF_ESP32 */ -#ifdef CONFIG_FW_INFO -#include -#endif - #ifdef CONFIG_MCUBOOT_SERIAL #include "boot_serial/boot_serial.h" #include "serial_adapter/serial_adapter.h" @@ -134,11 +130,6 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); * !defined(ZEPHYR_LOG_MODE_MINIMAL) */ -#if USE_PARTITION_MANAGER && CONFIG_FPROTECT -#include -#include -#endif - BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -197,19 +188,6 @@ static void do_boot(struct boot_rsp *rsp) /* Disable the USB to prevent it from firing interrupts */ usb_disable(); #endif - -#if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); - -#ifdef PM_S0_ADDRESS - /* Only fail if the immutable bootloader is present. */ - if (!provided) { - BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); - return; - } -#endif -#endif - #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ @@ -618,30 +596,7 @@ int main(void) mcuboot_status_change(MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND); -#if USE_PARTITION_MANAGER && CONFIG_FPROTECT - -#ifdef PM_S1_ADDRESS -/* MCUBoot is stored in either S0 or S1, protect both */ -#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_S0_ADDRESS) -#define PROTECT_ADDR PM_S0_ADDRESS -#else -/* There is only one instance of MCUBoot */ -#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_MCUBOOT_ADDRESS) -#define PROTECT_ADDR PM_MCUBOOT_ADDRESS -#endif - - rc = fprotect_area(PROTECT_ADDR, PROTECT_SIZE); - - if (rc != 0) { - BOOT_LOG_ERR("Protect mcuboot flash failed, cancel startup."); - while (1) - ; - } - -#endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ - ZEPHYR_BOOT_LOG_STOP(); - do_boot(&rsp); mcuboot_status_change(MCUBOOT_STATUS_BOOT_FAILED); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml deleted file mode 100644 index 5df9ae547..000000000 --- a/boot/zephyr/pm.yml +++ /dev/null @@ -1,77 +0,0 @@ -#include - -mcuboot: - size: CONFIG_PM_PARTITION_SIZE_MCUBOOT - placement: - before: [mcuboot_primary] -#if defined(CONFIG_HIDE_CHILD_PARENT_CONFIG) - align: {end: 0x1000} -#endif - -mcuboot_primary_app: - # All images to be placed in MCUboot's slot 0 should be placed in this - # partition - span: [app] - -mcuboot_primary: - span: [mcuboot_pad, mcuboot_primary_app] - -# Partition for secondary slot is not created if building in single application -# slot configuration. -#if !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) -mcuboot_secondary: - share_size: [mcuboot_primary] -#if defined(CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY) - region: external_flash - placement: - align: {start: 4} -#else - placement: - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} - align_next: CONFIG_FPROTECT_BLOCK_SIZE # Ensure that the next partition does not interfere with this image - after: mcuboot_primary -#endif /* CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY */ - -#endif /* !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) */ - -#if CONFIG_BOOT_DIRECT_XIP - -# Direct XIP is enabled, reserve area for metadata (padding) and name the -# partition so that its clear that it is not the secondary slot, but the direct -# XIP alternative. - -mcuboot_secondary_pad: - share_size: mcuboot_pad - placement: - after: mcuboot_primary - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} - -mcuboot_secondary_app: - share_size: mcuboot_primary_app - placement: - after: mcuboot_secondary_pad - -mcuboot_secondary: - span: [mcuboot_secondary_pad, mcuboot_secondary_app] - -#endif /* CONFIG_BOOT_DIRECT_XIP */ - -#if CONFIG_BOOT_SWAP_USING_SCRATCH -mcuboot_scratch: - size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_SCRATCH - placement: - after: app - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} -#endif /* CONFIG_BOOT_SWAP_USING_SCRATCH */ - -# Padding placed before image to boot. This reserves space for the MCUboot image header -# and it ensures that the boot image gets linked with the correct address offset in flash. -mcuboot_pad: - # MCUboot pad must be placed before the primary application partition. - # The primary application partition includes the secure firmware if present. - size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD - placement: - before: [mcuboot_primary_app] -#ifdef CONFIG_FPROTECT - align: {start: CONFIG_FPROTECT_BLOCK_SIZE} -#endif diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 6d538d1de..51dc99b27 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -18,7 +18,6 @@ CONFIG_BOOT_BOOTSTRAP=n # CONFIG_TINYCRYPT_SHA256 is not set CONFIG_FLASH=y -CONFIG_FPROTECT=y ### Various Zephyr boards enable features that we don't want. # CONFIG_BT is not set diff --git a/ext/nrf/cc310_glue.h b/ext/nrf/cc310_glue.h index 22eb94911..ed3ed5c00 100644 --- a/ext/nrf/cc310_glue.h +++ b/ext/nrf/cc310_glue.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* diff --git a/zephyr/module.yml b/zephyr/module.yml index b73ae2a0d..d2af55384 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,8 +1,7 @@ samples: - boot/zephyr build: - cmake-ext: True - kconfig-ext: True + cmake: ./boot/bootutil/zephyr sysbuild-cmake: boot/zephyr/sysbuild package-managers: pip: From 28cae54db17c4b41c6a1c625008d6c7fe2fe0452 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 129/204] Revert "[nrf noup] boards: thingy91x: add board config" This reverts commit 27d3de4e1ba5e6678d62fd6bd038c9f3e5454355. Signed-off-by: Jamie McCrae --- .../boards/thingy91x_nrf5340_cpuapp.conf | 54 ------------------- boot/zephyr/boards/thingy91x_nrf9151.conf | 8 --- 2 files changed, 62 deletions(-) delete mode 100644 boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf delete mode 100644 boot/zephyr/boards/thingy91x_nrf9151.conf diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf deleted file mode 100644 index 72dfa7fca..000000000 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ /dev/null @@ -1,54 +0,0 @@ -# MCUBoot settings -CONFIG_BOOT_MAX_IMG_SECTORS=110 - -# MCUboot serial recovery -CONFIG_MCUBOOT_SERIAL=y - -# Disable Zephyr console -CONFIG_LOG=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n - -# Serial -CONFIG_SERIAL=y -CONFIG_UART_NRFX=y -CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_UART_LINE_CTRL=y - -# MCUboot serial recovery -CONFIG_GPIO=y -CONFIG_MCUBOOT_SERIAL=y -CONFIG_BOOT_SERIAL_CDC_ACM=y - -# Required by USB -CONFIG_MULTITHREADING=y - -# USB -CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" -CONFIG_USB_CDC_ACM=y -CONFIG_USB_COMPOSITE_DEVICE=y -CONFIG_USB_MASS_STORAGE=n -CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x520F - -CONFIG_BOOT_SERIAL_BOOT_MODE=y - -CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x13E00 - -# The following configurations are required to support simultaneous multi image update -CONFIG_PCD_APP=y -CONFIG_UPDATEABLE_IMAGE_NUMBER=2 -CONFIG_BOOT_UPGRADE_ONLY=y -# The network core cannot access external flash directly. The flash simulator must be used to -# provide a memory region that is used to forward the new firmware to the network core. -CONFIG_FLASH_SIMULATOR=y -CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y -CONFIG_FLASH_SIMULATOR_STATS=n - -CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y - -CONFIG_NRF53_RECOVERY_NETWORK_CORE=y diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf deleted file mode 100644 index 33cd3301c..000000000 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ /dev/null @@ -1,8 +0,0 @@ -# MCUBoot settings -CONFIG_BOOT_MAX_IMG_SECTORS=512 - -CONFIG_SPI=y -CONFIG_SPI_NOR=y -CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 -CONFIG_SPI_NOR_SFDP_DEVICETREE=y -CONFIG_MULTITHREADING=y From ddeb2c97da4baa28eb0d26d0ea6dd9e3cca8a802 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 130/204] Revert "[nrf noup] zephyr: Restore default RTC user channel count" This reverts commit 072f69f72a253414b4396ae391c3e0ba94583a2f. Signed-off-by: Jamie McCrae --- boot/zephyr/prj.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 51dc99b27..119e07579 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -34,4 +34,3 @@ CONFIG_MCUBOOT_LOG_LEVEL_INF=y CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y -CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 From 9ca0c466adaf7abfba4e842eb83a01ca824064ef Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 131/204] Revert "[nrf noup] boards: add support for Thingy:91" This reverts commit 07076213a88525fcc13db56f0bc981690b6eb513. Signed-off-by: Jamie McCrae --- boot/zephyr/boards/thingy91_nrf52840.conf | 34 ----------------------- boot/zephyr/boards/thingy91_nrf9160.conf | 13 --------- 2 files changed, 47 deletions(-) delete mode 100644 boot/zephyr/boards/thingy91_nrf52840.conf delete mode 100644 boot/zephyr/boards/thingy91_nrf9160.conf diff --git a/boot/zephyr/boards/thingy91_nrf52840.conf b/boot/zephyr/boards/thingy91_nrf52840.conf deleted file mode 100644 index c0d183401..000000000 --- a/boot/zephyr/boards/thingy91_nrf52840.conf +++ /dev/null @@ -1,34 +0,0 @@ -# Disable Zephyr console -CONFIG_LOG=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n - -# The build won't fit on the partition allocated for it without size -# optimizations. -CONFIG_SIZE_OPTIMIZATIONS=y -CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x12000 - -# Serial -CONFIG_SERIAL=y -CONFIG_UART_NRFX=y -CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_UART_LINE_CTRL=y - -# MCUboot serial recovery -CONFIG_GPIO=y -CONFIG_MCUBOOT_SERIAL=y -CONFIG_BOOT_SERIAL_CDC_ACM=y - -# Required by USB -CONFIG_MULTITHREADING=y - -# USB -CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" -CONFIG_USB_CDC_ACM=y -CONFIG_USB_COMPOSITE_DEVICE=y -CONFIG_USB_MASS_STORAGE=n -CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" -CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x520F diff --git a/boot/zephyr/boards/thingy91_nrf9160.conf b/boot/zephyr/boards/thingy91_nrf9160.conf deleted file mode 100644 index 1bf2e424d..000000000 --- a/boot/zephyr/boards/thingy91_nrf9160.conf +++ /dev/null @@ -1,13 +0,0 @@ -# Disable Zephyr console -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_UART_CONSOLE=n - -# Disable Flash protection -CONFIG_FPROTECT=n - -# MCUBoot settings -CONFIG_BOOT_MAX_IMG_SECTORS=256 - -# MCUboot serial recovery -CONFIG_MCUBOOT_SERIAL=y From 327706075e22f06916613613c4ceb8ba81b1f43f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 132/204] Revert "[nrf noup] zephyr: add 'minimal' configuration files" This reverts commit cf7f4f67f5dec571c940910236b149f1a932fa3a. Signed-off-by: Jamie McCrae --- .../nrf5340dk_nrf5340_cpuapp_minimal.conf | 13 ------ boot/zephyr/prj_minimal.conf | 40 ------------------- 2 files changed, 53 deletions(-) delete mode 100644 boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf delete mode 100644 boot/zephyr/prj_minimal.conf diff --git a/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf deleted file mode 100644 index dd5468106..000000000 --- a/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -# CC3xx is currently not used for nrf53 -CONFIG_HW_CC3XX=n -CONFIG_NRF_CC3XX_PLATFORM=n - -# Required for kernel operation -CONFIG_CLOCK_CONTROL=y -CONFIG_SYS_CLOCK_EXISTS=y diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf deleted file mode 100644 index 55d4c6167..000000000 --- a/boot/zephyr/prj_minimal.conf +++ /dev/null @@ -1,40 +0,0 @@ -# -# Copyright (c) 2021 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -CONFIG_MAIN_STACK_SIZE=10240 -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -CONFIG_FLASH=y -CONFIG_FPROTECT=y -CONFIG_PM=n - -CONFIG_BOOT_SWAP_SAVE_ENCTLV=n -CONFIG_BOOT_ENCRYPT_IMAGE=n - -CONFIG_BOOT_BOOTSTRAP=n -CONFIG_BOOT_UPGRADE_ONLY=n - -### Minimal Configurations ### -CONFIG_BOOT_USE_MIN_PARTITION_SIZE=y -CONFIG_ASSERT=n -CONFIG_BOOT_BANNER=n -CONFIG_CLOCK_CONTROL=n -CONFIG_CONSOLE=n -CONFIG_CONSOLE_HANDLER=n -CONFIG_GPIO=n -CONFIG_KERNEL_MEM_POOL=n -CONFIG_LOG=n -CONFIG_MINIMAL_LIBC_CALLOC=n -CONFIG_MINIMAL_LIBC_MALLOC=n -CONFIG_MINIMAL_LIBC_REALLOCARRAY=n -CONFIG_NCS_SAMPLES_DEFAULTS=n -CONFIG_NO_RUNTIME_CHECKS=y -CONFIG_NRF_RTC_TIMER=n -CONFIG_PRINTK=n -CONFIG_SERIAL=n -CONFIG_SIZE_OPTIMIZATIONS=y -CONFIG_SYS_CLOCK_EXISTS=n -CONFIG_UART_CONSOLE=n From 3ec01d16cc94ab4b986c587f14b5e0856ac598a2 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 133/204] Revert "[nrf noup] zephyr: Remove duplication from cmake" This reverts commit 18db93f4af960663f5dbf77b70043aa9d071201e. Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 3a780e509..209c61dbe 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -50,6 +50,8 @@ if(NOT EXISTS ${NRFXLIB_DIR}) To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") endif() +# Don't include this if we are using west + add_subdirectory(${NRFXLIB_DIR} ${PROJECT_BINARY_DIR}/nrfxlib) endif() zephyr_library_include_directories( From 67260018b2eb04dd09dfa274fa0a4c6b86cf8f0b Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 28 Apr 2025 08:11:50 +0100 Subject: [PATCH 134/204] Revert "[nrf noup] github: Add a commit tags check workflow" This reverts commit 0912fcde815cd413a549bc759f7ea162b29b6d23. Signed-off-by: Jamie McCrae --- .github/workflows/commit-tags.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/commit-tags.yml diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml deleted file mode 100644 index 534ed5b58..000000000 --- a/.github/workflows/commit-tags.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Commit tags - -on: - pull_request: - types: [synchronize, opened, reopened, edited, labeled, unlabeled, - milestoned, demilestoned, assigned, unassigned, ready_for_review, - review_requested] - -jobs: - commit_tags: - runs-on: ubuntu-22.04 - name: Run commit tags checks on patch series (PR) - steps: - - name: Update PATH for west - run: | - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Checkout the code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Run the commit tags - uses: nrfconnect/action-commit-tags@main - with: - target: . - upstream: mcu-tools/mcuboot/main From 4daa1a0b8807e371688903799945fddbb2bb70c3 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Tue, 10 Oct 2023 15:51:54 +0200 Subject: [PATCH 135/204] [nrf noup] github: Add a commit tags check workflow Use the generic commit-tags action to provide sauce tag checks. Signed-off-by: Carles Cufi (cherry picked from commit 0912fcde815cd413a549bc759f7ea162b29b6d23) --- .github/workflows/commit-tags.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/commit-tags.yml diff --git a/.github/workflows/commit-tags.yml b/.github/workflows/commit-tags.yml new file mode 100644 index 000000000..534ed5b58 --- /dev/null +++ b/.github/workflows/commit-tags.yml @@ -0,0 +1,28 @@ +name: Commit tags + +on: + pull_request: + types: [synchronize, opened, reopened, edited, labeled, unlabeled, + milestoned, demilestoned, assigned, unassigned, ready_for_review, + review_requested] + +jobs: + commit_tags: + runs-on: ubuntu-22.04 + name: Run commit tags checks on patch series (PR) + steps: + - name: Update PATH for west + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Checkout the code + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Run the commit tags + uses: nrfconnect/action-commit-tags@main + with: + target: . + upstream: mcu-tools/mcuboot/main From fbd812f58387c36c0fce65498920d9a2e3619ef3 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 26 Mar 2019 15:42:38 +0100 Subject: [PATCH 136/204] [nrf noup] zephyr: Remove duplication from cmake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the `add_subdirectory` of nrfxlib it will still check that the nrfxlib is located outside the mcuboot directory. Signed-off-by: Sigvart Hovland Signed-off-by: Andrzej Puzdrowski Signed-off-by: Martí Bolívar Signed-off-by: Emil Obalski Signed-off-by: Andrzej Puzdrowski Signed-off-by: HÃ¥kon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 18db93f4af960663f5dbf77b70043aa9d071201e) --- boot/zephyr/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 159962543..49e9afa1e 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -50,8 +50,6 @@ if(NOT EXISTS ${NRFXLIB_DIR}) To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") endif() -# Don't include this if we are using west - add_subdirectory(${NRFXLIB_DIR} ${PROJECT_BINARY_DIR}/nrfxlib) endif() zephyr_library_include_directories( From b72ac7bf39f6d685efe0205b7e10989cad8a2930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Fri, 3 Sep 2021 14:38:54 -0700 Subject: [PATCH 137/204] [nrf noup] zephyr: add 'minimal' configuration files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add prj_minimal.conf, a Kconfig fragment to be used for minimally sized image production. The minimal fragment has been simplified for only external crypto. Move partition sizing into Kconfig to be consistent with the method used by b0. Using this fragment with prj_minimal.conf makes MCUboot < 16kB for all nRF devices (9160 still needs 32kB partition). Ref: NCSDK-6704 Signed-off-by: Stephen Stauts Signed-off-by: Martí Bolívar Signed-off-by: Sebastian Bøe Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit cf7f4f67f5dec571c940910236b149f1a932fa3a) --- .../nrf5340dk_nrf5340_cpuapp_minimal.conf | 13 ++++++ boot/zephyr/prj_minimal.conf | 40 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf create mode 100644 boot/zephyr/prj_minimal.conf diff --git a/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf new file mode 100644 index 000000000..dd5468106 --- /dev/null +++ b/boot/zephyr/boards/nrf5340dk_nrf5340_cpuapp_minimal.conf @@ -0,0 +1,13 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# CC3xx is currently not used for nrf53 +CONFIG_HW_CC3XX=n +CONFIG_NRF_CC3XX_PLATFORM=n + +# Required for kernel operation +CONFIG_CLOCK_CONTROL=y +CONFIG_SYS_CLOCK_EXISTS=y diff --git a/boot/zephyr/prj_minimal.conf b/boot/zephyr/prj_minimal.conf new file mode 100644 index 000000000..55d4c6167 --- /dev/null +++ b/boot/zephyr/prj_minimal.conf @@ -0,0 +1,40 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_FLASH=y +CONFIG_FPROTECT=y +CONFIG_PM=n + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_ENCRYPT_IMAGE=n + +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_BOOT_UPGRADE_ONLY=n + +### Minimal Configurations ### +CONFIG_BOOT_USE_MIN_PARTITION_SIZE=y +CONFIG_ASSERT=n +CONFIG_BOOT_BANNER=n +CONFIG_CLOCK_CONTROL=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_GPIO=n +CONFIG_KERNEL_MEM_POOL=n +CONFIG_LOG=n +CONFIG_MINIMAL_LIBC_CALLOC=n +CONFIG_MINIMAL_LIBC_MALLOC=n +CONFIG_MINIMAL_LIBC_REALLOCARRAY=n +CONFIG_NCS_SAMPLES_DEFAULTS=n +CONFIG_NO_RUNTIME_CHECKS=y +CONFIG_NRF_RTC_TIMER=n +CONFIG_PRINTK=n +CONFIG_SERIAL=n +CONFIG_SIZE_OPTIMIZATIONS=y +CONFIG_SYS_CLOCK_EXISTS=n +CONFIG_UART_CONSOLE=n From 94db98667d4760e887d9cb8c47d2f699d55f1df9 Mon Sep 17 00:00:00 2001 From: Bernt Johan Damslora Date: Fri, 20 Sep 2019 18:25:41 +0200 Subject: [PATCH 138/204] [nrf noup] boards: add support for Thingy:91 Adds project configurations for the two systems on the Thingy:91 (PCA-20035) board. The bootloader that is factory-programmed on thing91 does not support ECDSA signature type. Hence this commit also sets the signature type to RSA for applications built for Thingy:91. Signed-off-by: Bernt Johan Damslora Signed-off-by: Sigvart Hovland Signed-off-by: Jon Helge Nistad Signed-off-by: Balaji Srinivasan Signed-off-by: Robert Lubos Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Marek Pieta Signed-off-by: Dominik Ermel (cherry picked from commit 07076213a88525fcc13db56f0bc981690b6eb513) --- boot/zephyr/boards/thingy91_nrf52840.conf | 34 +++++++++++++++++++++++ boot/zephyr/boards/thingy91_nrf9160.conf | 13 +++++++++ 2 files changed, 47 insertions(+) create mode 100644 boot/zephyr/boards/thingy91_nrf52840.conf create mode 100644 boot/zephyr/boards/thingy91_nrf9160.conf diff --git a/boot/zephyr/boards/thingy91_nrf52840.conf b/boot/zephyr/boards/thingy91_nrf52840.conf new file mode 100644 index 000000000..c0d183401 --- /dev/null +++ b/boot/zephyr/boards/thingy91_nrf52840.conf @@ -0,0 +1,34 @@ +# Disable Zephyr console +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# The build won't fit on the partition allocated for it without size +# optimizations. +CONFIG_SIZE_OPTIMIZATIONS=y +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x12000 + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_NRFX=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_LINE_CTRL=y + +# MCUboot serial recovery +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by USB +CONFIG_MULTITHREADING=y + +# USB +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" +CONFIG_USB_CDC_ACM=y +CONFIG_USB_COMPOSITE_DEVICE=y +CONFIG_USB_MASS_STORAGE=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x520F diff --git a/boot/zephyr/boards/thingy91_nrf9160.conf b/boot/zephyr/boards/thingy91_nrf9160.conf new file mode 100644 index 000000000..1bf2e424d --- /dev/null +++ b/boot/zephyr/boards/thingy91_nrf9160.conf @@ -0,0 +1,13 @@ +# Disable Zephyr console +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# Disable Flash protection +CONFIG_FPROTECT=n + +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# MCUboot serial recovery +CONFIG_MCUBOOT_SERIAL=y From 600075ab6c4430e005eb4bd8e837ac6f32874149 Mon Sep 17 00:00:00 2001 From: Damian Krolik Date: Mon, 21 Mar 2022 13:44:27 +0100 Subject: [PATCH 139/204] [nrf noup] zephyr: Restore default RTC user channel count The default value of CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT for nRF52 SOCs has been changed from 0 to 3, but it makes MCUBoot get stuck on erasing flash pages when swapping two images. Restore the previous value until the RTC issue is resolved (see NCSDK-14427) Signed-off-by: Damian Krolik Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 072f69f72a253414b4396ae391c3e0ba94583a2f) --- boot/zephyr/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 119e07579..51dc99b27 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -34,3 +34,4 @@ CONFIG_MCUBOOT_LOG_LEVEL_INF=y CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 From b192beca7e4294aa401454ac0d45ced01753dcda Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Fri, 8 Dec 2023 13:18:12 +0100 Subject: [PATCH 140/204] [nrf noup] boards: thingy91x: add board config This patch adds board configuration for the Thingy:91 X. Signed-off-by: Maximilian Deubel (cherry picked from commit 27d3de4e1ba5e6678d62fd6bd038c9f3e5454355) --- .../boards/thingy91x_nrf5340_cpuapp.conf | 54 +++++++++++++++++++ boot/zephyr/boards/thingy91x_nrf9151.conf | 8 +++ 2 files changed, 62 insertions(+) create mode 100644 boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf create mode 100644 boot/zephyr/boards/thingy91x_nrf9151.conf diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf new file mode 100644 index 000000000..72dfa7fca --- /dev/null +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -0,0 +1,54 @@ +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=110 + +# MCUboot serial recovery +CONFIG_MCUBOOT_SERIAL=y + +# Disable Zephyr console +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_NRFX=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_UART_LINE_CTRL=y + +# MCUboot serial recovery +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by USB +CONFIG_MULTITHREADING=y + +# USB +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="MCUBOOT" +CONFIG_USB_CDC_ACM=y +CONFIG_USB_COMPOSITE_DEVICE=y +CONFIG_USB_MASS_STORAGE=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x520F + +CONFIG_BOOT_SERIAL_BOOT_MODE=y + +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x13E00 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y + +CONFIG_NRF53_RECOVERY_NETWORK_CORE=y diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf new file mode 100644 index 000000000..33cd3301c --- /dev/null +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -0,0 +1,8 @@ +# MCUBoot settings +CONFIG_BOOT_MAX_IMG_SECTORS=512 + +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_MULTITHREADING=y From 04b5af5dfce85c62b3f40fcc52adf7204b157e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Wed, 12 Dec 2018 08:59:47 +0100 Subject: [PATCH 141/204] [nrf noup] treewide: add NCS partition manager support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partition Manager is an nRF Connect SDK component which uses yaml files to resolve flash partition placement with a holistic view of the device. This component's MCUboot portions began life as upstream mcuboot PR#430. This added support for being built as a sub image from the downstream Nordic patch set for a zephyr multi image build system (mcuboot 430 was combined with effor submitted to upstream zephyr as PR#13672, which was ultimately reworked after being rejected for mainline at the ELCE 2019 conference in Lyon). It has since evolved over time. This is the version that will go into NCS v1.3. It features: - page size aligned partitions for all partitions used by mcuboot. - image swaps without scratch partitions Add support for configurations where there exists two primary slots but only one secondary slot, which is shared. These two primary slots are the regular application and B1. B1 can be either S0 or S1 depending on the state of the device. Decide where an upgrade should be stored by looking at the vector table. Provide update candidates for both s0 and s1. These candidates must be signed with mcuboot after being signed by b0. Additional notes: - we make update.hex without trailer data This is needed for serial recovery to work using hex files. Prior to this the update.hex got TLV data at the end of the partition, which caused many blank pages to be included, which made it hard to use in a serial recovery scheme. Instead, make update.hex without TLV data at the end, and provide a new file test_update.hex which contains the TLV data, and can be directly flashed to test the upgrade procedure. - we use a function for signing the application as future-proofing for when other components must be signed as well - this includes an update to single image applications that enables support for partition manager; when single image DFU is used, a scratch partition is not needed. - In NCS, image 1 primary slot is the upgrade bank for mcuboot (IE S0 or S1 depending on the active slot). It is not required that this slot contains any valid data. - The nRF boards all have a single flash page size, and partition manager deals with the size of the update partitions and so on, so we must skip a boot_slots_compatible() check to avoid getting an error. - There is no need to verify the target when using partition manager. - We lock mcuboot using fprotect before jumping, to enable the secure boot property of the system. - Call fw_info_ext_api_provide() before booting if EXT_API_PROVIDE EXT_API is enabled. This is relevant only when the immutable bootloader has booted mcuboot. Signed-off-by: HÃ¥kon Øye Amundsen Signed-off-by: Øyvind Rønningstad Signed-off-by: Sebastian Bøe Signed-off-by: Sigvart Hovland Signed-off-by: Martí Bolívar Signed-off-by: Torsten Rasmussen Signed-off-by: Andrzej Głąbek Signed-off-by: Robert Lubos Signed-off-by: Andrzej Puzdrowski Signed-off-by: Emil Obalski Signed-off-by: Pawel Dunaj Signed-off-by: Ioannis Glaropoulos Signed-off-by: Johann Fischer Signed-off-by: Vidar Berg Signed-off-by: Draus, Sebastian Signed-off-by: Trond Einar Snekvik Signed-off-by: Jamie McCrae Signed-off-by: Joakim Andersson Signed-off-by: Georgios Vasilakis Signed-off-by: Dominik Ermel (cherry picked from commit 70d45f0a754e37708b14d441324a3da8545f0ad2) --- boot/bootutil/src/loader.c | 95 ++++++++++++++++++++++--- boot/bootutil/src/swap_move.c | 13 ++++ boot/bootutil/src/swap_scratch.c | 13 ++++ boot/zephyr/CMakeLists.txt | 7 ++ boot/zephyr/Kconfig | 2 + boot/zephyr/include/sysflash/sysflash.h | 48 +++++++++++++ boot/zephyr/include/target.h | 4 ++ boot/zephyr/main.c | 45 ++++++++++++ boot/zephyr/pm.yml | 77 ++++++++++++++++++++ boot/zephyr/prj.conf | 1 + ext/nrf/cc310_glue.h | 2 +- zephyr/module.yml | 3 +- 12 files changed, 299 insertions(+), 11 deletions(-) create mode 100644 boot/zephyr/pm.yml diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index f47ec4e2a..2603e3472 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -145,6 +145,15 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, * * Failure to read any headers is a fatal error. */ +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. The primary slot of the second image + * (image 1) will not contain a valid image header until an upgrade + * of mcuboot has happened (filling S1 with the new version). + */ + if (BOOT_CURR_IMG(state) == 1 && i == 0) { + continue; + } +#endif /* PM_S1_ADDRESS */ if (i > 0 && !require_all) { return 0; } else { @@ -1133,7 +1142,24 @@ boot_validate_slot(struct boot_loader_state *state, int slot, goto out; } - if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) { + uint32_t min_addr, max_addr; + +#ifdef PM_CPUNET_APP_ADDRESS + /* The primary slot for the network core is emulated in RAM. + * Its flash_area hasn't got relevant boundaries. + * Therfore need to override its boundaries for the check. + */ + if (BOOT_CURR_IMG(state) == 1) { + min_addr = PM_CPUNET_APP_ADDRESS; + max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; + } else +#endif + { + min_addr = pri_fa->fa_off; + max_addr = pri_fa->fa_off + pri_fa->fa_size; + } + + if (reset_value < min_addr || reset_value> (max_addr)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); BOOT_LOG_ERR("Erasing image from secondary slot"); @@ -1209,6 +1235,42 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other + * B1 slot S0 or S1) share the same secondary slot, we need to check + * whether the update candidate in the secondary slot is intended for + * image 0 or image 1 primary by looking at the address of the reset + * vector. Note that there are good reasons for not using img_num from + * the swap info. + */ + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = + (struct image_header *)secondary_fa->fa_off; + + if (hdr->ih_magic == IMAGE_MAGIC) { + const struct flash_area *primary_fa; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *vtable = (uint32_t *)(vtable_addr); + uint32_t reset_addr = vtable[1]; + int rc = flash_area_open( + flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } + } +#endif swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -2568,15 +2630,25 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT - FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL, 0); - /* Check for all possible values is redundant in normal operation it - * is meant to prevent FI attack. +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. Image 1 primary is the currently + * executing MCUBoot image, and is therefore already validated by NSIB and + * does not need to also be validated by MCUBoot. */ - if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || - FIH_EQ(fih_rc, FIH_FAILURE) || - FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { - FIH_SET(fih_rc, FIH_FAILURE); - goto out; + bool image_validated_by_nsib = BOOT_CURR_IMG(state) == 1; + if (!image_validated_by_nsib) +#endif + { + FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, NULL, 0); + /* Check for all possible values is redundant in normal operation it + * is meant to prevent FI attack. + */ + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS) || + FIH_EQ(fih_rc, FIH_FAILURE) || + FIH_EQ(fih_rc, FIH_NO_BOOTABLE_IMAGE)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } } #else /* Even if we're not re-validating the primary slot, we could be booting @@ -2593,11 +2665,16 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT */ +#ifdef PM_S1_ADDRESS + if (!image_validated_by_nsib) +#endif + { rc = boot_update_hw_rollback_protection(state); if (rc != 0) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } + } rc = boot_add_shared_data(state, BOOT_PRIMARY_SLOT); if (rc != 0) { diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 9349cde37..07da2aa93 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -253,6 +253,18 @@ static int app_max_sectors(struct boot_loader_state *state) int boot_slots_compatible(struct boot_loader_state *state) { +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. In this case, image 1 primary points to the other + * B1 slot (ie S0 or S1), and image 0 primary points to the app. + * With this configuration, image 0 and image 1 share the secondary slot. + * Hence, the primary slot of image 1 will be *smaller* than image 1's + * secondary slot. This is not allowed in upstream mcuboot, so we need + * this patch to allow it. Also, all of these checks are redundant when + * partition manager is in use, and since we have the same sector size + * in all of our flash. + */ + return 1; +#else size_t num_sectors_pri; size_t num_sectors_sec; size_t sector_sz_pri = 0; @@ -321,6 +333,7 @@ boot_slots_compatible(struct boot_loader_state *state) } return 1; +#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index f9dbb7103..30837580a 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -141,6 +141,18 @@ boot_status_internal_off(const struct boot_status *bs, int elem_sz) int boot_slots_compatible(struct boot_loader_state *state) { +#ifdef PM_S1_ADDRESS + /* Patch needed for NCS. In this case, image 1 primary points to the other + * B1 slot (ie S0 or S1), and image 0 primary points to the app. + * With this configuration, image 0 and image 1 share the secondary slot. + * Hence, the primary slot of image 1 will be *smaller* than image 1's + * secondary slot. This is not allowed in upstream mcuboot, so we need + * this patch to allow it. Also, all of these checks are redundant when + * partition manager is in use, and since we have the same sector size + * in all of our flash. + */ + return 1; +#else size_t num_sectors_primary; size_t num_sectors_secondary; size_t sz0, sz1; @@ -238,6 +250,7 @@ boot_slots_compatible(struct boot_loader_state *state) #endif return 1; +#endif /* PM_S1_ADDRESS */ } #define BOOT_LOG_SWAP_STATE(area, state) \ diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 49e9afa1e..9ed74fe81 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -352,6 +352,13 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") endif() message("MCUBoot bootloader key file: ${KEY_FILE}") + set_property( + GLOBAL + PROPERTY + KEY_FILE + ${KEY_FILE} + ) + set(mcuboot_default_signature_files ${MCUBOOT_DIR}/root-ec-p256-pkcs8.pem ${MCUBOOT_DIR}/root-ec-p384.pem diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index acc0314a6..8de021439 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -9,6 +9,8 @@ mainmenu "MCUboot configuration" comment "MCUboot-specific configuration options" +source "$(ZEPHYR_NRF_MODULE_DIR)/modules/mcuboot/boot/zephyr/Kconfig" + # Hidden option to mark a project as MCUboot config MCUBOOT default y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 16d222280..99cbf56b7 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -7,6 +7,52 @@ #ifndef __SYSFLASH_H__ #define __SYSFLASH_H__ +#if USE_PARTITION_MANAGER +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +extern uint32_t _image_1_primary_slot_id[]; + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#else + +#include #include #include #include @@ -65,4 +111,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#endif /* USE_PARTITION_MANAGER */ + #endif /* __SYSFLASH_H__ */ diff --git a/boot/zephyr/include/target.h b/boot/zephyr/include/target.h index ea160752e..856686785 100644 --- a/boot/zephyr/include/target.h +++ b/boot/zephyr/include/target.h @@ -8,6 +8,8 @@ #ifndef H_TARGETS_TARGET_ #define H_TARGETS_TARGET_ +#ifndef USE_PARTITION_MANAGER + #if defined(MCUBOOT_TARGET_CONFIG) /* * Target-specific definitions are permitted in legacy cases that @@ -47,4 +49,6 @@ #error "Target support is incomplete; cannot build mcuboot." #endif +#endif /* ifndef USE_PARTITION_MANAGER */ + #endif /* H_TARGETS_TARGET_ */ diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 8b18c1ba6..4c376d102 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -70,6 +70,10 @@ #endif /* CONFIG_SOC_FAMILY_ESPRESSIF_ESP32 */ +#ifdef CONFIG_FW_INFO +#include +#endif + #ifdef CONFIG_MCUBOOT_SERIAL #include "boot_serial/boot_serial.h" #include "serial_adapter/serial_adapter.h" @@ -130,6 +134,11 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); * !defined(ZEPHYR_LOG_MODE_MINIMAL) */ +#if USE_PARTITION_MANAGER && CONFIG_FPROTECT +#include +#include +#endif + BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -178,6 +187,19 @@ static void do_boot(struct boot_rsp *rsp) /* Disable the USB to prevent it from firing interrupts */ usb_disable(); #endif + +#if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) + bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); + +#ifdef PM_S0_ADDRESS + /* Only fail if the immutable bootloader is present. */ + if (!provided) { + BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); + return; + } +#endif +#endif + #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ @@ -586,7 +608,30 @@ int main(void) mcuboot_status_change(MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND); +#if USE_PARTITION_MANAGER && CONFIG_FPROTECT + +#ifdef PM_S1_ADDRESS +/* MCUBoot is stored in either S0 or S1, protect both */ +#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_S0_ADDRESS) +#define PROTECT_ADDR PM_S0_ADDRESS +#else +/* There is only one instance of MCUBoot */ +#define PROTECT_SIZE (PM_MCUBOOT_PRIMARY_ADDRESS - PM_MCUBOOT_ADDRESS) +#define PROTECT_ADDR PM_MCUBOOT_ADDRESS +#endif + + rc = fprotect_area(PROTECT_ADDR, PROTECT_SIZE); + + if (rc != 0) { + BOOT_LOG_ERR("Protect mcuboot flash failed, cancel startup."); + while (1) + ; + } + +#endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ + ZEPHYR_BOOT_LOG_STOP(); + do_boot(&rsp); mcuboot_status_change(MCUBOOT_STATUS_BOOT_FAILED); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml new file mode 100644 index 000000000..5df9ae547 --- /dev/null +++ b/boot/zephyr/pm.yml @@ -0,0 +1,77 @@ +#include + +mcuboot: + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT + placement: + before: [mcuboot_primary] +#if defined(CONFIG_HIDE_CHILD_PARENT_CONFIG) + align: {end: 0x1000} +#endif + +mcuboot_primary_app: + # All images to be placed in MCUboot's slot 0 should be placed in this + # partition + span: [app] + +mcuboot_primary: + span: [mcuboot_pad, mcuboot_primary_app] + +# Partition for secondary slot is not created if building in single application +# slot configuration. +#if !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) +mcuboot_secondary: + share_size: [mcuboot_primary] +#if defined(CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY) + region: external_flash + placement: + align: {start: 4} +#else + placement: + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} + align_next: CONFIG_FPROTECT_BLOCK_SIZE # Ensure that the next partition does not interfere with this image + after: mcuboot_primary +#endif /* CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY */ + +#endif /* !defined(CONFIG_SINGLE_APPLICATION_SLOT) && !defined(CONFIG_BOOT_DIRECT_XIP) */ + +#if CONFIG_BOOT_DIRECT_XIP + +# Direct XIP is enabled, reserve area for metadata (padding) and name the +# partition so that its clear that it is not the secondary slot, but the direct +# XIP alternative. + +mcuboot_secondary_pad: + share_size: mcuboot_pad + placement: + after: mcuboot_primary + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} + +mcuboot_secondary_app: + share_size: mcuboot_primary_app + placement: + after: mcuboot_secondary_pad + +mcuboot_secondary: + span: [mcuboot_secondary_pad, mcuboot_secondary_app] + +#endif /* CONFIG_BOOT_DIRECT_XIP */ + +#if CONFIG_BOOT_SWAP_USING_SCRATCH +mcuboot_scratch: + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_SCRATCH + placement: + after: app + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} +#endif /* CONFIG_BOOT_SWAP_USING_SCRATCH */ + +# Padding placed before image to boot. This reserves space for the MCUboot image header +# and it ensures that the boot image gets linked with the correct address offset in flash. +mcuboot_pad: + # MCUboot pad must be placed before the primary application partition. + # The primary application partition includes the secure firmware if present. + size: CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD + placement: + before: [mcuboot_primary_app] +#ifdef CONFIG_FPROTECT + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} +#endif diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 51dc99b27..6d538d1de 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -18,6 +18,7 @@ CONFIG_BOOT_BOOTSTRAP=n # CONFIG_TINYCRYPT_SHA256 is not set CONFIG_FLASH=y +CONFIG_FPROTECT=y ### Various Zephyr boards enable features that we don't want. # CONFIG_BT is not set diff --git a/ext/nrf/cc310_glue.h b/ext/nrf/cc310_glue.h index ed3ed5c00..22eb94911 100644 --- a/ext/nrf/cc310_glue.h +++ b/ext/nrf/cc310_glue.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* diff --git a/zephyr/module.yml b/zephyr/module.yml index d2af55384..b73ae2a0d 100644 --- a/zephyr/module.yml +++ b/zephyr/module.yml @@ -1,7 +1,8 @@ samples: - boot/zephyr build: - cmake: ./boot/bootutil/zephyr + cmake-ext: True + kconfig-ext: True sysbuild-cmake: boot/zephyr/sysbuild package-managers: pip: From 1e440b155ccd78f11934a4bfd8569d57bffbf40a Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Thu, 27 Aug 2020 14:29:31 +0200 Subject: [PATCH 142/204] [nrf noup] boot: nrf53-specific customizations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add network core bootloader implementation Enables network core updates of nrf53 using MCUBoot by identifying images through their start addresses. Also implements the control and transfer using the PCD module. - Add support for multi image DFU using partition manager. - Add check for netcore addr if NSIB is enabled so netcore updates works - boot: zephyr: move thingy53_nrf5340_cpuapp.conf downstream Moved the board configuration for Thingy:53 Application Core to the nRF Connect SDK MCUboot downstream repository. The configuration file contains references to the Kconfig modules that are only available in the nRF Connect SDK. The current configuration is set up to work in the nRF Connect SDK environment and cannot be used upstream. - pm: enable ram flash partition using common flag This patch makes mcuboot_primary_1 ram-flash partition selectable using CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH property. This is needed since CONFIG_NRF53_MULTI_IMAGE_UPDATE become not only configuration which requires that partition. - MCUBoot configures USB CDC by its own. There is no need for BOARD_SERIAL_BACKEND_CDC_ACM option to configure anything which is later overwritten anyway. Jira: NCSDK-18596 Signed-off-by: Andrzej Puzdrowski Signed-off-by: Emil Obalski Signed-off-by: HÃ¥kon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Jamie McCrae Signed-off-by: Johann Fischer Signed-off-by: Kamil Piszczek Signed-off-by: Ole Sæther Signed-off-by: Sigvart Hovland Signed-off-by: Simon Iversen Signed-off-by: Torsten Rasmussen Signed-off-by: Trond Einar Snekvik Signed-off-by: Mateusz Kapala Signed-off-by: Dominik Ermel (cherry picked from commit ff0cc9c0ab4cf58aa926d2ef980f2c53821af997) --- boot/bootutil/src/loader.c | 96 ++++++++++++++----- .../boards/thingy53_nrf5340_cpuapp.conf | 74 +++++++++++++- boot/zephyr/include/sysflash/sysflash.h | 23 +++++ boot/zephyr/main.c | 7 ++ boot/zephyr/pm.yml | 13 +++ 5 files changed, 185 insertions(+), 28 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 2603e3472..c235afdd3 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -50,6 +50,10 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#include +#endif + #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -1235,7 +1239,15 @@ boot_validated_swap_type(struct boot_loader_state *state, { int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); -#ifdef PM_S1_ADDRESS + bool upgrade_valid = false; + +#if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) + const struct flash_area *secondary_fa = + BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = 0; + uint32_t *vtable = 0; + uint32_t reset_addr = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1243,34 +1255,36 @@ boot_validated_swap_type(struct boot_loader_state *state, * vector. Note that there are good reasons for not using img_num from * the swap info. */ - const struct flash_area *secondary_fa = - BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = - (struct image_header *)secondary_fa->fa_off; if (hdr->ih_magic == IMAGE_MAGIC) { - const struct flash_area *primary_fa; - uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - uint32_t *vtable = (uint32_t *)(vtable_addr); - uint32_t reset_addr = vtable[1]; - int rc = flash_area_open( - flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ - return BOOT_SWAP_TYPE_NONE; - } - } + vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + vtable = (uint32_t *)(vtable_addr); + reset_addr = vtable[1]; +#ifdef PM_S1_ADDRESS +#ifdef PM_CPUNET_B0N_ADDRESS + if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif + { + const struct flash_area *primary_fa; + int rc = flash_area_open(flash_area_id_from_multi_image_slot( + BOOT_CURR_IMG(state), + BOOT_PRIMARY_SLOT), + &primary_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + /* Get start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off || + reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for this image + */ + return BOOT_SWAP_TYPE_NONE; + } + } +#endif /* PM_S1_ADDRESS */ + } +#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -1284,7 +1298,37 @@ boot_validated_swap_type(struct boot_loader_state *state, } else { swap_type = BOOT_SWAP_TYPE_FAIL; } + } else { + upgrade_valid = true; + } + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) + /* If the update is valid, and it targets the network core: perform the + * update and indicate to the caller of this function that no update is + * available + */ + if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + uint32_t fw_size = hdr->ih_img_size; + + BOOT_LOG_INF("Starting network core update"); + int rc = pcd_network_core_update(vtable, fw_size); + + if (rc != 0) { + swap_type = BOOT_SWAP_TYPE_FAIL; + } else { + BOOT_LOG_INF("Done updating network core"); +#if defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE) + /* swap_erase_trailer_sectors is undefined if upgrade only + * method is used. There is no need to erase sectors, because + * the image cannot be reverted. + */ + rc = swap_erase_trailer_sectors(state, + secondary_fa); +#endif + swap_type = BOOT_SWAP_TYPE_NONE; + } } +#endif /* CONFIG_SOC_NRF5340_CPUAPP */ } return swap_type; diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index f2e42fd64..7d3bc0bec 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -1,3 +1,73 @@ -CONFIG_NORDIC_QSPI_NOR=n -CONFIG_SPI=n +CONFIG_SIZE_OPTIMIZATIONS=y + +CONFIG_SYSTEM_CLOCK_NO_WAIT=y +CONFIG_PM=n + +CONFIG_MAIN_STACK_SIZE=10240 +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_MAX_IMG_SECTORS=2048 +CONFIG_BOOT_SIGNATURE_TYPE_RSA=y + +# Flash +CONFIG_FLASH=y +CONFIG_BOOT_ERASE_PROGRESSIVELY=y +CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y +CONFIG_FPROTECT=y + +# Serial +CONFIG_SERIAL=y +CONFIG_UART_LINE_CTRL=y + +# MCUBoot serial +CONFIG_GPIO=y +CONFIG_MCUBOOT_SERIAL=y +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_CDC_ACM=y + +# Required by QSPI +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# Required by USB and QSPI CONFIG_MULTITHREADING=y + +# USB +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n +CONFIG_USB_DEVICE_REMOTE_WAKEUP=n +CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor ASA" +CONFIG_USB_DEVICE_PRODUCT="Bootloader Thingy:53" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x5300 +CONFIG_USB_CDC_ACM=y + +# Decrease memory footprint +CONFIG_CBPRINTF_NANO=y +CONFIG_TIMESLICING=n +CONFIG_BOOT_BANNER=n +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_LOG=n +CONFIG_ERRNO=n +CONFIG_PRINTK=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_SPI=n +CONFIG_I2C=n +CONFIG_UART_NRFX=n + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +# Enable custom command to erase settings partition. +CONFIG_ENABLE_MGMT_PERUSER=y +CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 99cbf56b7..7112f9baa 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -20,6 +20,11 @@ #elif (MCUBOOT_IMAGE_NUMBER == 2) +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#ifdef PM_B0_ADDRESS + extern uint32_t _image_1_primary_slot_id[]; #define FLASH_AREA_IMAGE_PRIMARY(x) \ @@ -35,6 +40,24 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ + #endif #define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 4c376d102..2e2b38df1 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -92,6 +92,10 @@ const struct boot_uart_funcs boot_funcs = { #include #endif +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#include +#endif + /* CONFIG_LOG_MINIMAL is the legacy Kconfig property, * replaced by CONFIG_LOG_MODE_MINIMAL. */ @@ -628,6 +632,9 @@ int main(void) ; } +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) && defined(CONFIG_PCD_APP) + pcd_lock_ram(); +#endif #endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ ZEPHYR_BOOT_LOG_STOP(); diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index 5df9ae547..13ffc44aa 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -75,3 +75,16 @@ mcuboot_pad: #ifdef CONFIG_FPROTECT align: {start: CONFIG_FPROTECT_BLOCK_SIZE} #endif + +#if (CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH) +mcuboot_primary_1: + region: ram_flash + size: CONFIG_NRF53_RAM_FLASH_SIZE +#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ + +#if (CONFIG_NRF53_MULTI_IMAGE_UPDATE) +mcuboot_secondary_1: + region: external_flash + size: CONFIG_NRF53_RAM_FLASH_SIZE + +#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ From 696915b4172dffb16a1213b4f328fd87743a6ce8 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 27 Feb 2020 12:48:56 +0100 Subject: [PATCH 143/204] [nrf noup] zephyr: clean peripherals state before boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do some cleanup of nRF peripherals. This is necessary since Zephyr doesn't have any driver deinitialization functionality, and we'd like to leave peripherals in a more predictable state before booting the Zephyr image. This should be re-worked when the zephyr driver model allows us to deinitialize devices cleanly before jumping to the chain-loaded image. Signed-off-by: Andrzej Puzdrowski Signed-off-by: Robert Lubos Signed-off-by: Torsten Rasmussen Signed-off-by: Øyvind Rønningstad Signed-off-by: Martí Bolívar Signed-off-by: HÃ¥kon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Johann Fischer Signed-off-by: Trond Einar Snekvik Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit f9432662129b508545cbf7d6b393e553552a778e) --- boot/zephyr/CMakeLists.txt | 6 +++ boot/zephyr/include/nrf_cleanup.h | 19 +++++++ boot/zephyr/main.c | 8 ++- boot/zephyr/nrf_cleanup.c | 83 +++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 boot/zephyr/include/nrf_cleanup.h create mode 100644 boot/zephyr/nrf_cleanup.c diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 9ed74fe81..b2129f446 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -716,3 +716,9 @@ if(SYSBUILD) set(mcuboot_image_footer_size ${required_size} CACHE INTERNAL "Estimated MCUboot image trailer size" FORCE) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() + +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) +zephyr_library_sources( + ${BOOT_DIR}/zephyr/nrf_cleanup.c +) +endif() diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h new file mode 100644 index 000000000..6b04cedfe --- /dev/null +++ b/boot/zephyr/include/nrf_cleanup.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef H_NRF_CLEANUP_ +#define H_NRF_CLEANUP_ + +/** + * Perform cleanup on some peripheral resources used by MCUBoot prior chainload + * the application. + * + * This function disables all RTC instances and UARTE instances. + * It Disables their interrupts signals as well. + */ +void nrf_cleanup_peripheral(void); + +#endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 2e2b38df1..b315ebc57 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -143,6 +143,10 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL +#include +#endif + BOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -203,7 +207,9 @@ static void do_boot(struct boot_rsp *rsp) } #endif #endif - +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL + nrf_cleanup_peripheral(); +#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c new file mode 100644 index 000000000..5bab26b24 --- /dev/null +++ b/boot/zephyr/nrf_cleanup.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) + #include +#endif +#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) + #include +#endif +#if defined(NRF_PPI) + #include +#endif +#if defined(NRF_DPPIC) + #include +#endif + +#include + +#define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) +#define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ + NRF_UARTE_SUBSCRIBE_CONF_OFFS) + +#define NRF_UARTE_PUBLISH_CONF_OFFS offsetof(NRF_UARTE_Type, PUBLISH_CTS) +#define NRF_UARTE_PUBLISH_CONF_SIZE (offsetof(NRF_UARTE_Type, SHORTS) -\ + NRF_UARTE_PUBLISH_CONF_OFFS) + +#if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) +static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) +{ + nrf_rtc_task_trigger(rtc_reg, NRF_RTC_TASK_STOP); + nrf_rtc_event_disable(rtc_reg, 0xFFFFFFFF); + nrf_rtc_int_disable(rtc_reg, 0xFFFFFFFF); +} +#endif + +static void nrf_cleanup_clock(void) +{ + nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); +} + +void nrf_cleanup_peripheral(void) +{ +#if defined(NRF_RTC0) + nrf_cleanup_rtc(NRF_RTC0); +#endif +#if defined(NRF_RTC1) + nrf_cleanup_rtc(NRF_RTC1); +#endif +#if defined(NRF_RTC2) + nrf_cleanup_rtc(NRF_RTC2); +#endif +#if defined(NRF_UARTE0) + nrf_uarte_disable(NRF_UARTE0); + nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_UARTE1) + nrf_uarte_disable(NRF_UARTE1); + nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); +#if defined(NRF_DPPIC) + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); +#endif +#endif +#if defined(NRF_PPI) + nrf_ppi_channels_disable_all(NRF_PPI); +#endif +#if defined(NRF_DPPIC) + nrf_dppi_channels_disable_all(NRF_DPPIC); +#endif + nrf_cleanup_clock(); +} From d184f5ef56b8f1be0bebac2d1d60b2800fc3ec45 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Fri, 6 Jan 2023 12:24:48 +0100 Subject: [PATCH 144/204] [nrf noup] zephyr: Clean up non-secure RAM if enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To ensure that MCUBoot does not leak keys or other material through memory to non-secure side we clear the memory before jumping to the next image. Signed-off-by: Sigvart Hovland Signed-off-by: Dominik Ermel Signed-off-by: Ole Sæther (cherry picked from commit ed0ee1fd4fe3bc39b5cffbc0e6c75b37de364d15) --- boot/zephyr/CMakeLists.txt | 2 +- boot/zephyr/include/nrf_cleanup.h | 5 ++ boot/zephyr/main.c | 5 +- boot/zephyr/nrf_cleanup.c | 79 +++++++++++++++++++++++-------- 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index b2129f446..de3b4f666 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -717,7 +717,7 @@ if(SYSBUILD) set(mcuboot_image_upgrade_footer_size ${required_upgrade_size} CACHE INTERNAL "Estimated MCUboot update image trailer size" FORCE) endif() -if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL) +if(CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL OR CONFIG_MCUBOOT_CLEANUP_NONSECURE_RAM) zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) diff --git a/boot/zephyr/include/nrf_cleanup.h b/boot/zephyr/include/nrf_cleanup.h index 6b04cedfe..9e87e13f5 100644 --- a/boot/zephyr/include/nrf_cleanup.h +++ b/boot/zephyr/include/nrf_cleanup.h @@ -16,4 +16,9 @@ */ void nrf_cleanup_peripheral(void); +/** + * Perform cleanup of non-secure RAM that may have been used by MCUBoot. + */ +void nrf_cleanup_ns_ram(void); + #endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index b315ebc57..403051d94 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -143,7 +143,7 @@ K_SEM_DEFINE(boot_log_sem, 1, 1); #include #endif -#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL +#if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL || CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM #include #endif @@ -210,6 +210,9 @@ static void do_boot(struct boot_rsp *rsp) #if CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL nrf_cleanup_peripheral(); #endif +#if CONFIG_MCUBOOT_NRF_CLEANUP_NONSECURE_RAM && defined(PM_SRAM_NONSECURE_NAME) + nrf_cleanup_ns_ram(); +#endif #if CONFIG_MCUBOOT_CLEANUP_ARM_CORE cleanup_arm_nvic(); /* cleanup NVIC registers */ diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 5bab26b24..051705ec9 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -5,9 +5,8 @@ */ #include -#if defined(NRF_UARTE0) || defined(NRF_UARTE1) - #include -#endif +#include +#include #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif @@ -20,6 +19,15 @@ #include +#if USE_PARTITION_MANAGER +#include +#endif + +#if defined(NRF_UARTE0) || defined(NRF_UARTE1) || defined(NRF_UARTE20) || \ + defined(NRF_UARTE30) +#define NRF_UARTE_CLEANUP +#endif + #define NRF_UARTE_SUBSCRIBE_CONF_OFFS offsetof(NRF_UARTE_Type, SUBSCRIBE_STARTRX) #define NRF_UARTE_SUBSCRIBE_CONF_SIZE (offsetof(NRF_UARTE_Type, EVENTS_CTS) -\ NRF_UARTE_SUBSCRIBE_CONF_OFFS) @@ -37,6 +45,23 @@ static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) } #endif +#if defined(NRF_UARTE_CLEANUP) +static NRF_UARTE_Type *nrf_uarte_to_clean[] = { +#if defined(NRF_UARTE0) + NRF_UARTE0, +#endif +#if defined(NRF_UARTE1) + NRF_UARTE1, +#endif +#if defined(NRF_UARTE20) + NRF_UARTE20, +#endif +#if defined(NRF_UARTE30) + NRF_UARTE30, +#endif +}; +#endif + static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); @@ -53,26 +78,31 @@ void nrf_cleanup_peripheral(void) #if defined(NRF_RTC2) nrf_cleanup_rtc(NRF_RTC2); #endif -#if defined(NRF_UARTE0) - nrf_uarte_disable(NRF_UARTE0); - nrf_uarte_int_disable(NRF_UARTE0, 0xFFFFFFFF); -#if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE0 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); -#endif -#endif -#if defined(NRF_UARTE1) - nrf_uarte_disable(NRF_UARTE1); - nrf_uarte_int_disable(NRF_UARTE1, 0xFFFFFFFF); + +#if defined(NRF_UARTE_CLEANUP) + for (int i = 0; i < sizeof(nrf_uarte_to_clean) / sizeof(nrf_uarte_to_clean[0]); ++i) { + NRF_UARTE_Type *current = nrf_uarte_to_clean[i]; + + nrfy_uarte_int_disable(current, 0xFFFFFFFF); + nrfy_uarte_int_uninit(current); + nrfy_uarte_task_trigger(current, NRF_UARTE_TASK_STOPRX); + + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXSTARTED); + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_ENDRX); + nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); + nrfy_uarte_disable(current); + #if defined(NRF_DPPIC) - /* Clear all SUBSCRIBE configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, NRF_UARTE_SUBSCRIBE_CONF_SIZE); - /* Clear all PUBLISH configurations. */ - memset((uint8_t *)NRF_UARTE1 + NRF_UARTE_PUBLISH_CONF_OFFS, 0, NRF_UARTE_PUBLISH_CONF_SIZE); + /* Clear all SUBSCRIBE configurations. */ + memset((uint8_t *)current + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, + NRF_UARTE_SUBSCRIBE_CONF_SIZE); + /* Clear all PUBLISH configurations. */ + memset((uint8_t *)current + NRF_UARTE_PUBLISH_CONF_OFFS, 0, + NRF_UARTE_PUBLISH_CONF_SIZE); #endif + } #endif + #if defined(NRF_PPI) nrf_ppi_channels_disable_all(NRF_PPI); #endif @@ -81,3 +111,12 @@ void nrf_cleanup_peripheral(void) #endif nrf_cleanup_clock(); } + +#if USE_PARTITION_MANAGER \ + && defined(CONFIG_ARM_TRUSTZONE_M) \ + && defined(PM_SRAM_NONSECURE_NAME) +void nrf_cleanup_ns_ram(void) +{ + memset((void *) PM_SRAM_NONSECURE_ADDRESS, 0, PM_SRAM_NONSECURE_SIZE); +} +#endif From 60e96e6729164655649ca0d2ebb98f4738e17f0e Mon Sep 17 00:00:00 2001 From: Christian Taedcke Date: Thu, 10 Feb 2022 15:37:49 +0100 Subject: [PATCH 145/204] [nrf noup] loader: Fix reading reset addr to support ext flash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When mcuboot_secondary is on external flash, the image header cannot dircetly be accessed via secondary_fa->fa_off. Instead the provided function boot_img_hdr() is used now. Additionally a similar issue is present when trying to read the address of the reset handler. For this flash_area_read() is used now. With this patch is possible to have the update partiton mcuboot_secondary on external flash and update a updatable bootloader (mcuboot) in s0 and/or s1. Signed-off-by: Christian Taedcke Signed-off-by: Ole Sæther Signed-off-by: Sigvart Hovland Signed-off-by: Dominik Ermel (cherry picked from commit afd1f6f75e0c716900b31a026fa04086f0c7449c) --- boot/bootutil/src/loader.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index c235afdd3..9dd175091 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1244,10 +1244,9 @@ boot_validated_swap_type(struct boot_loader_state *state, #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); - struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; - uint32_t vtable_addr = 0; - uint32_t *vtable = 0; + struct image_header *hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); uint32_t reset_addr = 0; + int rc = 0; /* Patch needed for NCS. Since image 0 (the app) and image 1 (the other * B1 slot S0 or S1) share the same secondary slot, we need to check * whether the update candidate in the secondary slot is intended for @@ -1257,16 +1256,19 @@ boot_validated_swap_type(struct boot_loader_state *state, */ if (hdr->ih_magic == IMAGE_MAGIC) { - vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; - vtable = (uint32_t *)(vtable_addr); - reset_addr = vtable[1]; + rc = flash_area_read(secondary_fa, hdr->ih_hdr_size + + sizeof(uint32_t), &reset_addr, + sizeof(reset_addr)); + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) #endif { const struct flash_area *primary_fa; - int rc = flash_area_open(flash_area_id_from_multi_image_slot( + rc = flash_area_open(flash_area_id_from_multi_image_slot( BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), &primary_fa); @@ -1302,16 +1304,19 @@ boot_validated_swap_type(struct boot_loader_state *state, upgrade_valid = true; } -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available */ if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; + uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; + uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); uint32_t fw_size = hdr->ih_img_size; - BOOT_LOG_INF("Starting network core update"); - int rc = pcd_network_core_update(vtable, fw_size); + rc = pcd_network_core_update(net_core_fw_addr, fw_size); if (rc != 0) { swap_type = BOOT_SWAP_TYPE_FAIL; From 891be04eed6379dd1b1d1d838c34a19675cc93ab Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 22 Sep 2023 21:31:08 +0000 Subject: [PATCH 146/204] [nrf noup] loader: Do not check reset vector for XIP image The XIP image, 2, does not have reset vector. Signed-off-by: Dominik Ermel (cherry picked from commit 78f267f479d4da6cfed6382c667f9a68fbec985f) --- boot/bootutil/src/loader.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9dd175091..70a8aa8bd 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1135,6 +1135,16 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * overwriting an application written to the incorrect slot. * This feature is only supported by ARM platforms. */ +#if MCUBOOT_IMAGE_NUMBER >= 3 + /* Currently the MCUboot can be configured for up to 3 image, where image number 2 is + * designated for XIP, where it is the second part of image stored in slots of image + * 0. This part of image is not bootable, as the XIP setup is done by the app in + * image 0 slot, and it does not carry the reset vector. + */ + if (fap == state->imgs[2][BOOT_SECONDARY_SLOT].area) { + goto out; + } +#endif if (fap == BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) { const struct flash_area *pri_fa = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT); struct image_header *secondary_hdr = boot_img_hdr(state, slot); From a7939cae4b194444b37f9f44528457c32093f75d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 18 Sep 2023 13:47:00 +0100 Subject: [PATCH 147/204] [nrf noup] zephyr: Add RAM flash configuration to cache for sysbuild Puts the flash simulation configurtion into cache variables that can be used by other applications and CMake code to know specifics on the simulated flash details Signed-off-by: Jamie McCrae (cherry picked from commit 5694ff5a65d06ec87901113fa333438be70bbc77) --- boot/zephyr/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index de3b4f666..4371f0404 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -722,3 +722,14 @@ zephyr_library_sources( ${BOOT_DIR}/zephyr/nrf_cleanup.c ) endif() + +if(SYSBUILD AND CONFIG_PCD_APP) + # Sysbuild requires details of the RAM flash device are stored to the cache of MCUboot so + # that they can be read when running partition manager + dt_nodelabel(ram_flash_dev NODELABEL flash_sim0) + dt_reg_addr(ram_flash_addr PATH ${ram_flash_dev}) + dt_reg_size(ram_flash_size PATH ${ram_flash_dev}) + + set(RAM_FLASH_ADDR "${ram_flash_addr}" CACHE STRING "" FORCE) + set(RAM_FLASH_SIZE "${ram_flash_size}" CACHE STRING "" FORCE) +endif() From f8b59782a954efe2b60da6e3e523075d5961e0f6 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 17 Oct 2023 11:28:09 +0200 Subject: [PATCH 148/204] [nrf noup] zephyr: Boot even if EXT_ABI is not provided This removes the `return;` to ensure that the application is booted even if EXT_ABI is not provided to the application because it does not include `FW_INFO`. Added a bit more description to the error messages when FW_INFO is not found and EXT_ABI is not able to be provided to the next image. Ref. NCSDK-24132 Signed-off-by: Sigvart Hovland (cherry picked from commit 79ca4781225a9aa6f8631fb01c9ca5c8218712ca) --- boot/zephyr/main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 403051d94..f311889ea 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -197,13 +197,16 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - bool provided = fw_info_ext_api_provide(fw_info_find((uint32_t)vt), true); + const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); + bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS /* Only fail if the immutable bootloader is present. */ if (!provided) { - BOOT_LOG_ERR("Failed to provide EXT_APIs\n"); - return; + if (firmware_info == NULL) { + BOOT_LOG_WRN("Unable to find firmware info structure in %p", vt); + } + BOOT_LOG_ERR("Failed to provide EXT_APIs to %p", vt); } #endif #endif From 3f5a65522568f817b16f7eb1a1be72e9e12a1d05 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Wed, 27 Sep 2023 15:18:04 +0200 Subject: [PATCH 149/204] =?UTF-8?q?[nrf=20noup]=C2=A0loader:=20Add=20firmw?= =?UTF-8?q?are=20version=20check=20downgrade=20prevention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For nRF53, the only existing version number metadata is stored in the `firmware_info` structure in the network core. This utilizes PCD to read out the version number and compares it against the version number found in the secondary slot for the network core. Ref. NCSDK-21379 Signed-off-by: Sigvart Hovland (cherry picked from commit bb083baeaaed9eeded204e43cab53fef805ec4f7) --- boot/bootutil/src/loader.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 70a8aa8bd..1ce2db785 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -52,6 +52,10 @@ #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include +#ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION +#include +int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); +#endif #endif #ifdef MCUBOOT_ENC_IMAGES @@ -1088,9 +1092,21 @@ boot_validate_slot(struct boot_loader_state *state, int slot, int rc; /* Check if version of secondary slot is sufficient */ - rc = boot_version_cmp( - &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, - &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ + && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) + if (BOOT_CURR_IMG(state) == 1) { + rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); + } else { + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + } +#else + rc = boot_version_cmp( + &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); +#endif if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); boot_scramble_slot(fap, slot); From b8ae9928ce6c12b585b8af2be4bc055a0fa906a3 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Mon, 9 Oct 2023 09:55:57 +0200 Subject: [PATCH 150/204] [nrf noup] boards: thingy53: disable GPIO ISR support Change disables GPIO interrupt support in Zephyr GPIO driver, which is not obligatory for MCUboot. This is needed to reduce memory footprint. Signed-off-by: Nikodem Kastelik (cherry picked from commit fa084222682e185cb0c5be154ecaf310f5bd560e) --- boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index 7d3bc0bec..e10656678 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -21,6 +21,7 @@ CONFIG_UART_LINE_CTRL=y # MCUBoot serial CONFIG_GPIO=y +CONFIG_GPIO_NRFX_INTERRUPT=n CONFIG_MCUBOOT_SERIAL=y CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y CONFIG_BOOT_SERIAL_CDC_ACM=y From c660b5b016fa44ad441a9a7acfd721679d783639 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 11 Apr 2024 17:26:50 +0200 Subject: [PATCH 151/204] [nrf noup] boot/zephyr/boards: nRF54l15pdk ext flash cfg Added configuration which allows to build MCUboot for nrf54l15pdk_nrf54l15_cpuapp with external flash used for the secondary slot. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 8c73d8b51ebda556c5d2985fdf3c2ba60c0a6fd3) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 8 ++++++++ .../nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf create mode 100644 boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf new file mode 100644 index 000000000..841922dbd --- /dev/null +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -0,0 +1,8 @@ +CONFIG_MULTITHREADING=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_FLASH=y +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 +CONFIG_MAIN_STACK_SIZE=20480 +CONFIG_BOOT_MAX_IMG_SECTORS=512 +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay new file mode 100644 index 000000000..2341ffd26 --- /dev/null +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -0,0 +1,10 @@ +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + + +&mx25r64 { + status = "okay"; +}; From 07cb819ad681a71cfc5104159a7c0d4f053e0f02 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Tue, 30 Mar 2021 22:45:17 +0200 Subject: [PATCH 152/204] [nrf noup] loader: work-around for multi-image builds Seems multi-image dependencies are not supported for multi-image in NCS yet. This is a workaround which reverts some lines to restore previous MCUboot behavior, so that Immutable bootloader + MCUBoot type builds will work. Ref. NCSDK-8681 Signed-off-by: Sigvart Hovland (cherry picked from commit 8c62ac94c953f93dbf80194f09b4bf0dd2c29a1f) --- boot/bootutil/src/loader.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 1ce2db785..fedb65c3b 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -496,7 +496,7 @@ boot_verify_dependencies(struct boot_loader_state *state) if (rc == 0) { /* All dependencies've been satisfied, continue with next image. */ BOOT_CURR_IMG(state)++; - } else { + } else if (rc == BOOT_EBADIMAGE) { /* Cannot upgrade due to non-met dependencies, so disable all * image upgrades. */ @@ -505,7 +505,10 @@ boot_verify_dependencies(struct boot_loader_state *state) BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE; } break; - } + } else { + /* Other error happened, images are inconsistent */ + return rc; + } } return rc; } From bdd93a3de7d4120818a8375be9397a1872449685 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 31 Aug 2023 08:58:31 +0100 Subject: [PATCH 153/204] [nrf noup] loader: Fix missing PCD define check Fixes a missing PCD define check, an image might have the network core partition layout set but if PCD support is not enabled then it should not assume that PCD support is part of mcuboot. Signed-off-by: Jamie McCrae (cherry picked from commit 566af5ee1f6e925d1208c382fa7386e3f0a9d8c0) --- boot/bootutil/src/loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index fedb65c3b..3e4141883 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1334,7 +1334,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) \ - && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + && !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) && defined(CONFIG_PCD_APP) /* If the update is valid, and it targets the network core: perform the * update and indicate to the caller of this function that no update is * available @@ -1362,7 +1362,8 @@ boot_validated_swap_type(struct boot_loader_state *state, swap_type = BOOT_SWAP_TYPE_NONE; } } -#endif /* CONFIG_SOC_NRF5340_CPUAPP */ +#endif /* CONFIG_SOC_NRF5340_CPUAPP && PM_CPUNET_B0N_ADDRESS && + !CONFIG_NRF53_MULTI_IMAGE_UPDATE && CONFIG_PCD_APP */ } return swap_type; From d936c858256af0c13e0bea1bdbd2f035e23c4054 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Wed, 31 May 2023 14:41:13 +0200 Subject: [PATCH 154/204] [nrf noup] boot: Add support for NSIB and multi-image This adds support for using both NSIB and the multi-image configuration in MCUboot. Before this was not possible due to upgradable bootloader support through NSIB was using the `UPDATEABLE_IMAGE_NUMBER` configuration to update the updateable bootloader. In this commit we change from using `FLASH_AREA_IMAGE_PRIMARY` to get the flash area ID to using the bootloader state where we set the flash area ID of the free updatable bootloader slot if the image is intended for this slot. Ref. NCSDK-19223 Ref. NCSDK-23305 Signed-off-by: Sigvart Hovland (cherry picked from commit 0bf9af473ffd1e0750b1eb3d4b2a3d3918811955) (cherry picked from commit 1f08c7930a316b62423b481ba62ff50c2ee2e8ac) --- boot/bootutil/src/loader.c | 42 +++++++++++++++++++------ boot/zephyr/include/sysflash/sysflash.h | 19 +++++++++-- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 3e4141883..7b700f4e3 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1185,6 +1185,11 @@ boot_validate_slot(struct boot_loader_state *state, int slot, if (BOOT_CURR_IMG(state) == 1) { min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; +#ifdef PM_S1_ADDRESS + } else if (BOOT_CURR_IMG(state) == 0) { + min_addr = PM_S0_ADDRESS; + max_addr = pri_fa->fa_off + pri_fa->fa_size; +#endif } else #endif { @@ -1298,18 +1303,37 @@ boot_validated_swap_type(struct boot_loader_state *state, { const struct flash_area *primary_fa; rc = flash_area_open(flash_area_id_from_multi_image_slot( - BOOT_CURR_IMG(state), - BOOT_PRIMARY_SLOT), - &primary_fa); - + BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT), + &primary_fa); if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } - /* Get start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off || - reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { - /* The image in the secondary slot is not intended for this image - */ + + /* Check start and end of primary slot for current image */ + if (reset_addr < primary_fa->fa_off) { +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + const struct flash_area *nsib_fa; + + /* NSIB upgrade slot */ + rc = flash_area_open((uint32_t)_image_1_primary_slot_id, + &nsib_fa); + + if (rc != 0) { + return BOOT_SWAP_TYPE_FAIL; + } + + /* Image is placed before Primary and within the NSIB slot */ + if (reset_addr > nsib_fa->fa_off + && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { + /* Set primary to be NSIB upgrade slot */ + BOOT_IMG_AREA(state, 0) = nsib_fa; + } +#else + return BOOT_SWAP_TYPE_NONE; +#endif + + } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } } diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 7112f9baa..f1ef4100e 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -23,9 +23,24 @@ /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#ifdef PM_B0_ADDRESS - +#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ From 3a2a1b95200bf97a0d57c7318bf1d8755a3e1b8b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 10 Aug 2023 17:32:48 +0000 Subject: [PATCH 155/204] [nrf noup] sysflash: Move partition manager definitions to pm_sysflash.h Making sysflash.h and pm_sysflash.h more readable. Signed-off-by: Dominik Ermel (cherry picked from commit 0117f67d27406ede222e0300fbd7e1c72eadb8ef) --- boot/zephyr/include/sysflash/pm_sysflash.h | 92 ++++++++++++++++++++++ boot/zephyr/include/sysflash/sysflash.h | 90 ++------------------- 2 files changed, 97 insertions(+), 85 deletions(-) create mode 100644 boot/zephyr/include/sysflash/pm_sysflash.h diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h new file mode 100644 index 000000000..377291e8b --- /dev/null +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef __PM_SYSFLASH_H__ +#define __PM_SYSFLASH_H__ +/* Blocking the __SYSFLASH_H__ */ +#define __SYSFLASH_H__ + +#include +#include + +#ifndef CONFIG_SINGLE_APPLICATION_SLOT + +#if (MCUBOOT_IMAGE_NUMBER == 1) + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID + +#elif (MCUBOOT_IMAGE_NUMBER == 2) + +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +#if defined(PM_B0_ADDRESS) +extern uint32_t _image_1_primary_slot_id[]; +#endif +#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) +#elif defined(PM_B0_ADDRESS) + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + (uint32_t)_image_1_primary_slot_id : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + 255 ) +#else + +#define FLASH_AREA_IMAGE_PRIMARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_PRIMARY_ID : \ + (x == 1) ? \ + PM_MCUBOOT_PRIMARY_1_ID : \ + 255 ) + +#define FLASH_AREA_IMAGE_SECONDARY(x) \ + ((x == 0) ? \ + PM_MCUBOOT_SECONDARY_ID: \ + (x == 1) ? \ + PM_MCUBOOT_SECONDARY_1_ID: \ + 255 ) + +#endif /* PM_B0_ADDRESS */ + +#endif +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#else /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID +#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID +/* NOTE: Scratch parition is not used by single image DFU but some of + * functions in common files reference it, so the definitions has been + * provided to allow compilation of common units. + */ +#define FLASH_AREA_IMAGE_SCRATCH 0 + +#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ + +#endif /* __PM_SYSFLASH_H__ */ diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index f1ef4100e..3c3638d7f 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -4,93 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __SYSFLASH_H__ -#define __SYSFLASH_H__ - #if USE_PARTITION_MANAGER -#include -#include - -#ifndef CONFIG_SINGLE_APPLICATION_SLOT - -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -#if defined(PM_B0_ADDRESS) -extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) -#else - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) - -#endif /* PM_B0_ADDRESS */ - +/* Blocking the rest of the file */ +#define __SYSFLASH_H__ +#include #endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID - -#else /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_PRIMARY_ID -/* NOTE: Scratch parition is not used by single image DFU but some of - * functions in common files reference it, so the definitions has been - * provided to allow compilation of common units. - */ -#define FLASH_AREA_IMAGE_SCRATCH 0 -#endif /* CONFIG_SINGLE_APPLICATION_SLOT */ - -#else +#ifndef __SYSFLASH_H__ +#define __SYSFLASH_H__ -#include #include #include #include @@ -149,6 +71,4 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ -#endif /* USE_PARTITION_MANAGER */ - #endif /* __SYSFLASH_H__ */ From e182d40eaab0143a60f22cdc74f8932d08fd441b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 11 Aug 2023 12:29:13 +0000 Subject: [PATCH 156/204] [nrf noup] sysflash: Add support for three images The commit modifies pm_sysflash.h to add support for three application images. Ref. NCSDK-19223 Signed-off-by: Dominik Ermel Signed-off-by: Sigvart Hovland (cherry picked from commit 6f0279bf954c1a473a0f93244c867277cd073b41) --- boot/zephyr/include/sysflash/pm_sysflash.h | 82 ++++++++++++---------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index 377291e8b..db60ddd03 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -11,37 +11,19 @@ #include #include +#include #ifndef CONFIG_SINGLE_APPLICATION_SLOT -#if (MCUBOOT_IMAGE_NUMBER == 1) - -#define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID -#define FLASH_AREA_IMAGE_SECONDARY(x) PM_MCUBOOT_SECONDARY_ID - -#elif (MCUBOOT_IMAGE_NUMBER == 2) - +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) /* If B0 is present then two bootloaders are present, and we must use * a single secondary slot for both primary slots. */ -#if defined(PM_B0_ADDRESS) extern uint32_t _image_1_primary_slot_id[]; -#endif -#if defined(PM_B0_ADDRESS) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +#endif /* (MCUBOOT_IMAGE_NUMBER == 2 && defined(PM_B0_ADDRESS) */ -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) -#elif defined(PM_B0_ADDRESS) +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) #define FLASH_AREA_IMAGE_PRIMARY(x) \ ((x == 0) ? \ @@ -56,26 +38,52 @@ extern uint32_t _image_1_primary_slot_id[]; (x == 1) ? \ PM_MCUBOOT_SECONDARY_ID: \ 255 ) + +#else /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ + +/* Each pair of slots is separated by , and there is no terminating character */ +#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID +#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID +#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID + +#if (MCUBOOT_IMAGE_NUMBER == 1) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS +#elif (MCUBOOT_IMAGE_NUMBER == 2) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ + FLASH_AREA_IMAGE_1_SLOTS +#elif (MCUBOOT_IMAGE_NUMBER == 3) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ + FLASH_AREA_IMAGE_1_SLOTS, \ + FLASH_AREA_IMAGE_2_SLOTS #else +#error Unsupported number of images +#endif -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - PM_MCUBOOT_PRIMARY_1_ID : \ - 255 ) +static inline uint32_t __flash_area_ids_for_slot(int img, int slot) +{ + static const int all_slots[] = { + ALL_AVAILABLE_SLOTS + }; + return all_slots[img * 2 + slot]; +}; -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_1_ID: \ - 255 ) +#undef FLASH_AREA_IMAGE_0_SLOTS +#undef FLASH_AREA_IMAGE_1_SLOTS +#undef FLASH_AREA_IMAGE_2_SLOTS +#undef ALL_AVAILABLE_SLOTS -#endif /* PM_B0_ADDRESS */ +#define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0) +#define FLASH_AREA_IMAGE_SECONDARY(x) __flash_area_ids_for_slot(x, 1) +#if !defined(CONFIG_BOOT_SWAP_USING_MOVE) +#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #endif -#define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID + +#endif /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + */ #else /* CONFIG_SINGLE_APPLICATION_SLOT */ From bbd8f48efbd796afa08038dedb5caa4e975fc5d3 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 15 Feb 2024 16:47:25 +0100 Subject: [PATCH 157/204] [nrf noup] loader: introduced cleanup of unusable secondary slot Added procedure which clean-up content of all the secondary slot which contains valid header but couldn't be assigned to any of supported primary images. This behavior is needed when configuration allows to use one secondary slot for collecting image for multiple primary slots. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 154f4df0d4f76e123592993ddc932df8f37885bb) --- boot/bootutil/src/loader.c | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 7b700f4e3..12e7a5758 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1258,6 +1258,87 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ +#if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ +(defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) + +#define SEC_SLOT_VIRGIN 0 +#define SEC_SLOT_TOUCHED 1 +#define SEC_SLOT_ASSIGNED 2 + +#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ + !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +/* This configuration is peculiar - the one physical secondary slot is + * mocking two logical secondary + */ +#define SEC_SLOT_PHYSICAL_CNT 1 +#else +#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER +#endif + +static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0}; + +static inline void sec_slot_touch(struct boot_loader_state *state) +{ + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); + + if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) { + sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED; + } +} + +static inline void sec_slot_mark_assigned(struct boot_loader_state *state) +{ + uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); + + sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED; +} + +/** + * Cleanu up all secondary slot which couldn't be assigned to any primary slot. + * + * This function erases content of each secondary slot which contains valid + * header but couldn't be assigned to any of supported primary images. + * + * This function is supposed to be called after boot_validated_swap_type() + * iterates over all the images in context_boot_go(). + */ +static void sec_slot_cleanup_if_unusable(void) +{ + uint8_t idx; + + for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) { + if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) { + const struct flash_area *secondary_fa; + int rc; + + rc = flash_area_open(flash_area_id_from_multi_image_slot(idx, BOOT_SECONDARY_SLOT), + &secondary_fa); + if (!rc) { + rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); + if (!rc) { + BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx); + } + } + + if (rc) { + BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx); + } + } + } +} +#else +static inline void sec_slot_touch(struct boot_loader_state *state) +{ +} +static inline void sec_slot_mark_assigned(struct boot_loader_state *state) +{ +} +static inline void sec_slot_cleanup_if_unusable(void) +{ +} +#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ + defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ + #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined @@ -1296,6 +1377,9 @@ boot_validated_swap_type(struct boot_loader_state *state, if (rc != 0) { return BOOT_SWAP_TYPE_FAIL; } + + sec_slot_touch(state); + #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS if(reset_addr < PM_CPUNET_B0N_ADDRESS) @@ -1330,6 +1414,7 @@ boot_validated_swap_type(struct boot_loader_state *state, } #else return BOOT_SWAP_TYPE_NONE; + #endif } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { @@ -1338,7 +1423,9 @@ boot_validated_swap_type(struct boot_loader_state *state, } } #endif /* PM_S1_ADDRESS */ + sec_slot_mark_assigned(state); } + #endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); @@ -2595,6 +2682,9 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } } + /* cleanup secondary slots which were recognized unusable*/ + sec_slot_cleanup_if_unusable(); + #if (BOOT_IMAGE_NUMBER > 1) if (has_upgrade) { /* Iterate over all the images and verify whether the image dependencies From 854cded99b88ee44934ec17814cc0a17709cec77 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Tue, 16 Apr 2024 16:10:55 +0200 Subject: [PATCH 158/204] [nrf noup] boards: nrf54l15: Disable FPROTECT FPROTECT is not suppored yet for nrf54l15. Signed-off-by: Grzegorz Chwierut Signed-off-by: Gerard Marull-Paretas (cherry picked from commit ef7aad1cdd15f358bdf921f36647d5d4e50b05a8) --- boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf index 43d8cebe3..8d8eb845f 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp.conf @@ -7,4 +7,7 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + CONFIG_BOOT_WATCHDOG_FEED=n From f4bea2f1d6101f32ecb94d2cade80bcb6fbc1e87 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 17 May 2024 18:25:07 +0200 Subject: [PATCH 159/204] [nrf noup] loader: remove cleanup for direct xip mode Move ifdefs just to not add code for cleanup unusable slot when direct xip mode is enabled to avoid warnings. Signed-off-by: Grzegorz Chwierut (cherry picked from commit ab602b19743c24a0cc54ddfd0d5e1ef47e58ab05) --- boot/bootutil/src/loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 12e7a5758..c81842178 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1258,6 +1258,8 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ +#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) + #if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ (defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP)) @@ -1339,7 +1341,6 @@ static inline void sec_slot_cleanup_if_unusable(void) #endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\ defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */ -#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Determines which swap operation to perform, if any. If it is determined * that a swap operation is required, the image in the secondary slot is checked From 91ddb139f33f65cf923364523f0a861cef8f16f5 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 15 Apr 2024 18:54:45 +0200 Subject: [PATCH 160/204] [nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash partition Added DTS with partitioning which involves external flash as place for slo1_partition. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit cf16b826e8c699240a373048d69af4923cffee75) --- ...54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 2341ffd26..76b648903 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -4,7 +4,42 @@ }; }; +/delete-node/ &boot_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/delete-node/ &slot0_ns_partition; +/delete-node/ &slot1_ns_partition; + +/delete-node/ &storage_partition; + +&rram0 { + partitions { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 0x00014000>; + }; + slot0_partition: partition@14000 { + label = "image-0"; + reg = <0x000014000 0x0015A000>; + }; + storage_partition: partition@16E000 { + label = "storage"; + reg = < 0x16E000 0x9000 >; + }; + }; +}; &mx25r64 { status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot1_partition: partition@0 { + label = "image-1"; + reg = <0x000000000 0x0015A000>; + }; + }; }; From d23fd6e422db23b492e82609c9804c5febc8036c Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 20 May 2024 15:48:33 +0200 Subject: [PATCH 161/204] [nrf noup] boot/zephyr/boards: nrf54l15pdk ext-flash update This patch supplements the configuration for external flash so MCUboot can be build with FILE_SUFFIX="ext_flash" for the nrf54l15pdk instead of explicitly configuration specification. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit a493f54798318e6a4e484525417cbc79a0bf7a75) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf | 7 +++++++ .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 1 + 2 files changed, 8 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf index 841922dbd..8fc12e074 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.conf @@ -6,3 +6,10 @@ CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 CONFIG_MAIN_STACK_SIZE=20480 CONFIG_BOOT_MAX_IMG_SECTORS=512 CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +# Ensure that the qspi driver is disabled by default +CONFIG_NORDIC_QSPI_NOR=n + +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + +CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index 76b648903..ea024fcec 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -1,6 +1,7 @@ / { chosen { nordic,pm-ext-flash = &mx25r64; + zephyr,code-partition = &boot_partition; }; }; From 3aee05c20a1f175543cfcc2587d779c8bff03bc3 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Tue, 12 Mar 2024 12:30:52 +0100 Subject: [PATCH 162/204] [nrf noup] boards: thingy91x: enable serial recovery This patch disbales MCUBoot logging and enables serial recovery for the Thingy:91. Signed-off-by: Maximilian Deubel Signed-off-by: Bernt Johan Damslora (cherry picked from commit bf1b0fa4d62f4bddcbc51ba76e45ccb2ee10e060) --- boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf | 10 ++++++++-- boot/zephyr/boards/thingy91x_nrf9151.conf | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf index 72dfa7fca..37c7e95b1 100644 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -32,7 +32,7 @@ CONFIG_USB_COMPOSITE_DEVICE=y CONFIG_USB_MASS_STORAGE=n CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x520F +CONFIG_USB_DEVICE_PID=0x910A CONFIG_BOOT_SERIAL_BOOT_MODE=y @@ -49,6 +49,12 @@ CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y CONFIG_FLASH_SIMULATOR_STATS=n CONFIG_BOOT_IMAGE_ACCESS_HOOKS=y -CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +# Makes it possible to update the network core using the flash simulator CONFIG_NRF53_RECOVERY_NETWORK_CORE=y + +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y + +# Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 +CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf index 33cd3301c..2efe1e170 100644 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -6,3 +6,12 @@ CONFIG_SPI_NOR=y CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 CONFIG_SPI_NOR_SFDP_DEVICETREE=y CONFIG_MULTITHREADING=y + +# Disable Zephyr console and use UART for MCUboot serial recovery instead +CONFIG_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_UART_CONSOLE=n +CONFIG_MCUBOOT_SERIAL=y + +CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y +CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y From a671bba4a80a9046eba755a1236f6ca6e887e8e9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 17 May 2024 14:14:54 +0200 Subject: [PATCH 163/204] [nrf noup] boot: zephyr: Disable boot banner if NCS_BOOT_BANNER is used Mcuboot's boot banner should not be used if NCS boot banner is enabled. Signed-off-by: Robert Lubos (cherry picked from commit 2f25a92e5984771dc36395de2b9c45e7deef6ae9) --- boot/zephyr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 8de021439..b1cfc6e5b 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -983,6 +983,7 @@ config BOOT_DISABLE_CACHES config MCUBOOT_BOOT_BANNER bool "Use MCUboot boot banner" depends on BOOT_BANNER + depends on !NCS_BOOT_BANNER depends on "$(APP_VERSION_EXTENDED_STRING)" != "" default y help From 09475ad0552d5e8d7e27df1079ba69d5ed63fa4f Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Mon, 27 May 2024 13:59:49 +0200 Subject: [PATCH 164/204] [nrf noup] boot/zephyr: fix fw_info search By the upstream patch the vt get now the pointer to the copy of the arm_vector instead of original. This patch fixes address of the firmware which is to be taken by the fw_info_find. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 09e1b9cf15af5e15e630d47feab64f9cf014604d) --- boot/zephyr/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index f311889ea..97db24c08 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -197,7 +197,14 @@ static void do_boot(struct boot_rsp *rsp) #endif #if defined(CONFIG_FW_INFO) && !defined(CONFIG_EXT_API_PROVIDE_EXT_API_UNUSED) - const struct fw_info *firmware_info = fw_info_find((uint32_t) vt); + uintptr_t fw_start_addr; + + rc = flash_device_base(rsp->br_flash_dev_id, &fw_start_addr); + assert(rc == 0); + + fw_start_addr += rsp->br_image_off + rsp->br_hdr->ih_hdr_size; + + const struct fw_info *firmware_info = fw_info_find(fw_start_addr); bool provided = fw_info_ext_api_provide(firmware_info, true); #ifdef PM_S0_ADDRESS From dfe2edca55349ff79a9146eb16b40d9740a0cdd1 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Wed, 5 Jun 2024 15:46:13 +0200 Subject: [PATCH 165/204] [nrf noup] zephyr/boards: fix nrf54l15pdk ext flash dts overlay Align to changes in DTS: renamed: rram0 -> cpuapp_rram sized up cpauapp_rram region szie as part of it was reserved for cpuflpr_rram (which is not used by this config). Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 466fe91e663c71463f35f7e2b4907401289fed2e) --- .../boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay index ea024fcec..60ee6fe51 100644 --- a/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay +++ b/boot/zephyr/boards/nrf54l15pdk_nrf54l15_cpuapp_ext_flash.overlay @@ -14,7 +14,8 @@ /delete-node/ &storage_partition; -&rram0 { +&cpuapp_rram { + reg = < 0x0 DT_SIZE_K(1524) >; partitions { boot_partition: partition@0 { label = "mcuboot"; From 33d25f8a42a420c555f0bd17bf3bbb0a77115409 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 11 Jun 2024 12:32:51 +0100 Subject: [PATCH 166/204] [nrf noup] boot: zephyr: Add NCS boot banner Adds a boot banner which shows as MCUboot Signed-off-by: Jamie McCrae (cherry picked from commit fe5f292599ef755f207096e148f3cc6ee02337ab) --- boot/zephyr/prj.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/prj.conf b/boot/zephyr/prj.conf index 6d538d1de..9ff1ba274 100644 --- a/boot/zephyr/prj.conf +++ b/boot/zephyr/prj.conf @@ -36,3 +36,6 @@ CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0 + +# NCS boot banner +CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="MCUboot" From 16239295f19f538199c231844eef9938df69d5be Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 13 Jun 2024 16:34:55 +0200 Subject: [PATCH 167/204] [nrf noup] boot/../loader: skip downgrade prevention for s1/s0 This patch introduces skip on checking downgrade for s1/s0 upgrade image (chain-loaded by NSIB). which is used for upgrade MCUboot instance itself. Reason is that sdk-mcuboot has not access to semantic version of its own image. I also shouldn't touch HW counter used for hardware downgrade prevention for the application image (which was the case). HW counters for s0/s1 image are owned by NSIB because its role is to prevnt dongrades of s0/s1 MCUboot. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 8e6e3c2b95893c21e320d87e88730e5918d468ab) --- boot/bootutil/src/loader.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index c81842178..95dd53d7f 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -71,6 +71,9 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); BOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; +#ifdef PM_S1_ADDRESS +static bool owner_nsib[BOOT_IMAGE_NUMBER] = {false}; +#endif #if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) || defined(MCUBOOT_DATA_SHARING) static struct image_max_size image_max_sizes[BOOT_IMAGE_NUMBER] = {0}; @@ -1356,6 +1359,9 @@ boot_validated_swap_type(struct boot_loader_state *state, int swap_type; FIH_DECLARE(fih_rc, FIH_FAILURE); bool upgrade_valid = false; +#if defined(PM_S1_ADDRESS) + owner_nsib[BOOT_CURR_IMG(state)] = false; +#endif #if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) const struct flash_area *secondary_fa = @@ -1412,6 +1418,7 @@ boot_validated_swap_type(struct boot_loader_state *state, && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { /* Set primary to be NSIB upgrade slot */ BOOT_IMG_AREA(state, 0) = nsib_fa; + owner_nsib[BOOT_CURR_IMG(state)] = true; } #else return BOOT_SWAP_TYPE_NONE; @@ -1422,6 +1429,10 @@ boot_validated_swap_type(struct boot_loader_state *state, /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } + + if ((primary_fa->fa_off == PM_S0_ADDRESS) || (primary_fa->fa_off == PM_S1_ADDRESS)) { + owner_nsib[BOOT_CURR_IMG(state)] = true; + } } #endif /* PM_S1_ADDRESS */ sec_slot_mark_assigned(state); @@ -2546,6 +2557,13 @@ check_downgrade_prevention(struct boot_loader_state *state) uint32_t security_counter[2]; int rc; +#if defined(PM_S1_ADDRESS) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + /* Downgrade prevention on S0/S1 image is managed by NSIB */ + return 0; + } +#endif + if (MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER) { /* If there was security no counter in slot 0, allow swap */ rc = bootutil_get_img_security_cnt(state, BOOT_PRIMARY_SLOT, From fe08e7fbfb4bfb0f9de21f919521a4a1c391a58f Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 18 Jun 2024 17:35:41 +0200 Subject: [PATCH 168/204] [nrf noup] boot/../loader: reboot after updating s0/s1 As this is MCUboot updating itself, it should reboot the device so NSIB will chainload the update MCUboot Signed-off-by: Andrzej Puzdrowski (cherry picked from commit b6eb81897a018d4a09006054750d65e9505c710d) --- boot/bootutil/src/loader.c | 10 ++++++++++ boot/zephyr/Kconfig | 1 + 2 files changed, 11 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 95dd53d7f..bbbca75fd 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -50,6 +50,10 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#ifdef __ZEPHYR__ +#include +#endif + #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) #include #ifdef CONFIG_PCD_READ_NETCORE_APP_VERSION @@ -2774,6 +2778,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); +#if defined(PM_S1_ADDRESS) && defined(CONFIG_REBOOT) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + sys_reboot(SYS_REBOOT_COLD); + + } +#endif break; case BOOT_SWAP_TYPE_FAIL: diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index b1cfc6e5b..81d4076d5 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -18,6 +18,7 @@ config MCUBOOT select MPU_ALLOW_FLASH_WRITE if ARM_MPU select USE_DT_CODE_PARTITION if HAS_FLASH_LOAD_OFFSET select MCUBOOT_BOOTUTIL_LIB + select REBOOT if SECURE_BOOT config BOOT_USE_MBEDTLS bool From 770f205f5a0af258b6c55244d8871f58084655a9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 29 Aug 2024 12:41:37 +0100 Subject: [PATCH 169/204] [nrf noup] bootutil: loader: Fix netcore address checking Fixes an issues with wrongly checking the network core reset address Signed-off-by: Jamie McCrae (cherry picked from commit a1864167e432fe95c2595647c4fdf56fdb855413) --- boot/bootutil/src/loader.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index bbbca75fd..9ebdc3be0 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1393,7 +1393,7 @@ boot_validated_swap_type(struct boot_loader_state *state, #ifdef PM_S1_ADDRESS #ifdef PM_CPUNET_B0N_ADDRESS - if(reset_addr < PM_CPUNET_B0N_ADDRESS) + if(!(reset_addr >= PM_CPUNET_APP_ADDRESS && reset_addr < PM_CPUNET_APP_END_ADDRESS)) #endif { const struct flash_area *primary_fa; @@ -1466,7 +1466,8 @@ boot_validated_swap_type(struct boot_loader_state *state, * update and indicate to the caller of this function that no update is * available */ - if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) { + if (upgrade_valid && reset_addr >= PM_CPUNET_APP_ADDRESS && + reset_addr < PM_CPUNET_APP_END_ADDRESS) { struct image_header *hdr = (struct image_header *)secondary_fa->fa_off; uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size; uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); From 06af3e26f5330bae574af73b1f076b1f1e0d6c31 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Wed, 18 Sep 2024 12:28:37 +0200 Subject: [PATCH 170/204] [nrf noup] boards: nrf54l15dk: Disable FPROTECT FPROTECT is not suppored for nrf54l15dk. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 243017cf6964dec4ea6af6fc64e72b176bda4f7c) --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf index c8fcd32c3..1dbd7c1ab 100644 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -7,6 +7,9 @@ CONFIG_BOOT_MAX_IMG_SECTORS=256 # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + CONFIG_BOOT_WATCHDOG_FEED=n # Ensure the fastest RRAM write operations From a24bb6ef9884fa10ff912af7ae615d54224d1051 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Thu, 14 Feb 2019 13:20:34 +0100 Subject: [PATCH 171/204] [nrf noup] boot: Add shared crypto for ECDSA and SHA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add functions for ecdsa_verify_secp256r1 and sha256 to use the shared crypto API * Add Kconfig and CMake variables for selecting shared crypto when using ecdsa * Add custom section to project for placing the API section in the correct location in flash * Add kconfig fragment for using external crypto Signed-off-by: Sigvart Hovland Signed-off-by: Martí Bolívar Signed-off-by: Emil Obalski Signed-off-by: Andrzej Puzdrowski Signed-off-by: HÃ¥kon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Trond Einar Snekvik Signed-off-by: Georgios Vasilakis Signed-off-by: Johann Fischer Signed-off-by: Torsten Rasmussen Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 049e896648b012a036bda2f451fbd279e396102b) (cherry picked from commit 259eadb4dec22b62322243963c6312e7ed764782) --- boot/bootutil/include/bootutil/crypto/ecdsa.h | 64 +++++++++++++++++-- boot/bootutil/include/bootutil/crypto/sha.h | 32 ++++++++++ boot/zephyr/CMakeLists.txt | 2 + boot/zephyr/external_crypto.conf | 20 ++++++ .../include/mcuboot_config/mcuboot_config.h | 2 + 5 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 boot/zephyr/external_crypto.conf diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa.h b/boot/bootutil/include/bootutil/crypto/ecdsa.h index 3b0541072..85355f20c 100644 --- a/boot/bootutil/include/bootutil/crypto/ecdsa.h +++ b/boot/bootutil/include/bootutil/crypto/ecdsa.h @@ -34,6 +34,7 @@ #if (defined(MCUBOOT_USE_TINYCRYPT) + \ defined(MCUBOOT_USE_CC310) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1 #error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO" #endif @@ -70,12 +71,18 @@ #include "bootutil/sign_key.h" #include "common.h" +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + #include + #define NUM_ECC_BYTES (256 / 8) +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus extern "C" { #endif #if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \ - defined(MCUBOOT_USE_CC310)) && !defined(MCUBOOT_USE_PSA_CRYPTO) + defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \ + && !defined(MCUBOOT_USE_PSA_CRYPTO) /* * Declaring these like this adds NULL termination. */ @@ -127,8 +134,6 @@ static int bootutil_import_key(uint8_t **cp, uint8_t *end) } #endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */ -#if defined(MCUBOOT_USE_TINYCRYPT) -#ifndef MCUBOOT_ECDSA_NEED_ASN1_SIG /* * cp points to ASN1 string containing an integer. * Verify the tag, and that the length is 32 bytes. Helper function. @@ -178,8 +183,8 @@ static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp } return 0; } -#endif /* not MCUBOOT_ECDSA_NEED_ASN1_SIG */ +#if defined(MCUBOOT_USE_TINYCRYPT) typedef uintptr_t bootutil_ecdsa_context; static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) { @@ -248,8 +253,12 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, { (void)ctx; (void)pk_len; - (void)sig_len; (void)hash_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } /* Only support uncompressed keys. */ if (pk[0] != 0x04) { @@ -257,7 +266,7 @@ static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, } pk++; - return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); + return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE); } static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, @@ -613,6 +622,49 @@ static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, #endif /* MCUBOOT_USE_MBED_TLS */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) +typedef uintptr_t bootutil_ecdsa_context; +static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx) +{ + (void)ctx; +} + +static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx, + uint8_t *pk, size_t pk_len, + uint8_t *hash, size_t hash_len, + uint8_t *sig, size_t sig_len) +{ + (void)ctx; + (void)pk_len; + (void)hash_len; + uint8_t dsig[2 * NUM_ECC_BYTES]; + + if (bootutil_decode_sig(dsig, sig, sig + sig_len)) { + return -1; + } + + /* Only support uncompressed keys. */ + if (pk[0] != 0x04) { + return -1; + } + pk++; + + return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig); +} + +static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx, + uint8_t **cp,uint8_t *end) +{ + (void)ctx; + return bootutil_import_key(cp, end); +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/include/bootutil/crypto/sha.h b/boot/bootutil/include/bootutil/crypto/sha.h index 6a009ff95..b83a3ec40 100644 --- a/boot/bootutil/include/bootutil/crypto/sha.h +++ b/boot/bootutil/include/bootutil/crypto/sha.h @@ -30,6 +30,7 @@ #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \ defined(MCUBOOT_USE_TINYCRYPT) + \ + defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \ defined(MCUBOOT_USE_CC310)) != 1 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO" #endif @@ -270,6 +271,37 @@ static inline int bootutil_sha_finish(bootutil_sha_context *ctx, } #endif /* MCUBOOT_USE_CC310 */ +#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + +#include + +typedef bl_sha256_ctx_t bootutil_sha_context; + +static inline void bootutil_sha_init(bootutil_sha_context *ctx) +{ + bl_sha256_init(ctx); +} + +static inline void bootutil_sha_drop(bootutil_sha_context *ctx) +{ + (void)ctx; +} + +static inline int bootutil_sha_update(bootutil_sha_context *ctx, + const void *data, + uint32_t data_len) +{ + return bl_sha256_update(ctx, data, data_len); +} + +static inline int bootutil_sha_finish(bootutil_sha_context *ctx, + uint8_t *output) +{ + bl_sha256_finalize(ctx, output); + return 0; +} +#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */ + #ifdef __cplusplus } #endif diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 4371f0404..267e84b88 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -212,6 +212,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) zephyr_library_sources(${NRF_DIR}/cc310_glue.c) zephyr_library_include_directories(${NRF_DIR}) zephyr_link_libraries(nrfxlib_crypto) + elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) + zephyr_include_directories(${BL_CRYPTO_DIR}/../include) endif() if(CONFIG_MBEDTLS_CFG_FILE) diff --git a/boot/zephyr/external_crypto.conf b/boot/zephyr/external_crypto.conf new file mode 100644 index 000000000..8181ad51c --- /dev/null +++ b/boot/zephyr/external_crypto.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# These configurations should be used when using nrf/samples/bootloader +# as the immutable bootloader (B0), and MCUBoot as the second stage updateable +# bootloader. + +# Set ECDSA as signing mechanism +CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y + +# Use crypto backend from B0 +CONFIG_BOOT_NRF_EXTERNAL_CRYPTO=y +CONFIG_SECURE_BOOT_CRYPTO=y +CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y +CONFIG_SB_CRYPTO_CLIENT_SHA256=y +CONFIG_BL_SHA256_EXT_API_REQUIRED=y +CONFIG_BL_SECP256R1_EXT_API_REQUIRED=y diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index fd003565a..9a29beaa6 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -49,6 +49,8 @@ #endif #elif defined(CONFIG_BOOT_USE_PSA_CRYPTO) #define MCUBOOT_USE_PSA_CRYPTO +#elif defined(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) +#define MCUBOOT_USE_NRF_EXTERNAL_CRYPTO #endif #ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 From 2bd560cf916fb03ccb19ea669ddbf58d24837c51 Mon Sep 17 00:00:00 2001 From: Markus Lassila Date: Fri, 30 Aug 2024 13:10:05 +0300 Subject: [PATCH 172/204] [nrf noup] boot: zephyr: Do not lock PCD region with TF-M Previously PCD memory was locked as read-only, non-secure in MCUboot. Given that TF-M also needs write to PCD to communicate with b0n, the memory is left unlocked and locked to read-only, non-secure in TF-M. Signed-off-by: Markus Lassila (cherry picked from commit 01f3b098410164beefb32ce13d3b1eca7f537fbb) --- boot/zephyr/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 97db24c08..f8d60010b 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -652,7 +652,11 @@ int main(void) } #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS) && defined(CONFIG_PCD_APP) - pcd_lock_ram(); +#if defined(PM_TFM_SECURE_ADDRESS) + pcd_lock_ram(false); +#else + pcd_lock_ram(true); +#endif #endif #endif /* USE_PARTITION_MANAGER && CONFIG_FPROTECT */ From fa1b64947530ba19dc4f7467498ab72cf00da3f9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 10 Sep 2024 13:41:30 +0100 Subject: [PATCH 173/204] [nrf noup] treewide: Add support for sysbuild assigned images Adds support for image IDs that are assigned by sysbuild, which allows for dynamically supporting different configurations without needing dummy images to support different modes. Also fixes multiple deficiencies with the previous code where things were not properly accounted for e.g. using the swap algorithm including all swap status parts when updating s0/s1 MCUboot image which could overwrite and corrupt the image data in the other slot Signed-off-by: Jamie McCrae (cherry picked from commit 3308732dfec501206b75825205643c72295ad4b3) --- boot/bootutil/src/loader.c | 176 +++++++++++++-------- boot/bootutil/src/swap_nsib.c | 70 ++++++++ boot/bootutil/src/swap_priv.h | 8 + boot/zephyr/CMakeLists.txt | 6 + boot/zephyr/include/sysflash/pm_sysflash.h | 69 ++++---- 5 files changed, 225 insertions(+), 104 deletions(-) create mode 100644 boot/bootutil/src/swap_nsib.c diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 9ebdc3be0..0b0b81be7 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -160,15 +160,15 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, * * Failure to read any headers is a fatal error. */ -#ifdef PM_S1_ADDRESS +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 /* Patch needed for NCS. The primary slot of the second image * (image 1) will not contain a valid image header until an upgrade * of mcuboot has happened (filling S1 with the new version). */ - if (BOOT_CURR_IMG(state) == 1 && i == 0) { + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER && i == 0) { continue; } -#endif /* PM_S1_ADDRESS */ +#endif /* CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 */ if (i > 0 && !require_all) { return 0; } else { @@ -1105,7 +1105,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) - if (BOOT_CURR_IMG(state) == 1) { + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); } else { rc = boot_version_cmp( @@ -1176,35 +1176,54 @@ boot_validate_slot(struct boot_loader_state *state, int slot, struct image_header *secondary_hdr = boot_img_hdr(state, slot); uint32_t reset_value = 0; uint32_t reset_addr = secondary_hdr->ih_hdr_size + sizeof(reset_value); + uint32_t min_addr, max_addr; + bool check_addresses = false; if (flash_area_read(fap, reset_addr, &reset_value, sizeof(reset_value)) != 0) { fih_rc = FIH_NO_BOOTABLE_IMAGE; goto out; } - uint32_t min_addr, max_addr; - #ifdef PM_CPUNET_APP_ADDRESS /* The primary slot for the network core is emulated in RAM. * Its flash_area hasn't got relevant boundaries. * Therfore need to override its boundaries for the check. */ - if (BOOT_CURR_IMG(state) == 1) { + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; -#ifdef PM_S1_ADDRESS - } else if (BOOT_CURR_IMG(state) == 0) { + check_addresses = true; + } else +#endif +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { +#if (CONFIG_NCS_IS_VARIANT_IMAGE) min_addr = PM_S0_ADDRESS; - max_addr = pri_fa->fa_off + pri_fa->fa_size; + max_addr = (PM_S0_ADDRESS + PM_S0_SIZE); +#else + min_addr = PM_S1_ADDRESS; + max_addr = (PM_S1_ADDRESS + PM_S1_SIZE); #endif + check_addresses = true; } else #endif - { + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 +#if (CONFIG_NCS_IS_VARIANT_IMAGE) + min_addr = MIN(pri_fa->fa_off, PM_S0_ADDRESS); + max_addr = MAX((pri_fa->fa_off + pri_fa->fa_size), (PM_S0_ADDRESS + PM_S0_SIZE)); +#else + min_addr = MIN(pri_fa->fa_off, PM_S1_ADDRESS); + max_addr = MAX((pri_fa->fa_off + pri_fa->fa_size), (PM_S1_ADDRESS + PM_S1_SIZE)); +#endif +#else min_addr = pri_fa->fa_off; max_addr = pri_fa->fa_off + pri_fa->fa_size; +#endif + check_addresses = true; } - if (reset_value < min_addr || reset_value> (max_addr)) { + if (check_addresses == true && (reset_value < min_addr || reset_value > max_addr)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); BOOT_LOG_ERR("Erasing image from secondary slot"); @@ -1274,36 +1293,54 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ #define SEC_SLOT_TOUCHED 1 #define SEC_SLOT_ASSIGNED 2 -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) -/* This configuration is peculiar - the one physical secondary slot is - * mocking two logical secondary - */ -#define SEC_SLOT_PHYSICAL_CNT 1 +static uint8_t sec_slot_assignment[MCUBOOT_IMAGE_NUMBER] = {0}; + +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 +static inline void sec_slot_untouch(struct boot_loader_state *state) +{ + sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] = SEC_SLOT_VIRGIN; + sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] = SEC_SLOT_VIRGIN; +} #else -#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER +static inline void sec_slot_untouch(struct boot_loader_state *state) +{ +} #endif -static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0}; - static inline void sec_slot_touch(struct boot_loader_state *state) { - uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { + if (sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] == SEC_SLOT_VIRGIN) { + sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] = SEC_SLOT_TOUCHED; + } + } else if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { + if (sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] == SEC_SLOT_VIRGIN) { + sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] = SEC_SLOT_TOUCHED; + } + } +#endif - if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) { - sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED; + if (sec_slot_assignment[BOOT_CURR_IMG(state)] == SEC_SLOT_VIRGIN) { + sec_slot_assignment[BOOT_CURR_IMG(state)] = SEC_SLOT_TOUCHED; } } static inline void sec_slot_mark_assigned(struct boot_loader_state *state) { - uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state); +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { + sec_slot_assignment[CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER] = SEC_SLOT_ASSIGNED; + } else if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { + sec_slot_assignment[CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER] = SEC_SLOT_ASSIGNED; + } +#endif - sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED; + sec_slot_assignment[BOOT_CURR_IMG(state)] = SEC_SLOT_ASSIGNED; } /** - * Cleanu up all secondary slot which couldn't be assigned to any primary slot. + * Cleanup up all secondary slot which couldn't be assigned to any primary slot. * * This function erases content of each secondary slot which contains valid * header but couldn't be assigned to any of supported primary images. @@ -1315,8 +1352,8 @@ static void sec_slot_cleanup_if_unusable(void) { uint8_t idx; - for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) { - if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) { + for (idx = 0; idx < MCUBOOT_IMAGE_NUMBER; idx++) { + if (SEC_SLOT_TOUCHED == sec_slot_assignment[idx]) { const struct flash_area *secondary_fa; int rc; @@ -1325,17 +1362,20 @@ static void sec_slot_cleanup_if_unusable(void) if (!rc) { rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); if (!rc) { - BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx); + BOOT_LOG_ERR("Cleaned-up secondary slot of image %d", idx); } } if (rc) { - BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx); + BOOT_LOG_ERR("Failed to clean-up secondary slot of image %d: %d", idx, rc); } } } } #else +static inline void sec_slot_untouch(struct boot_loader_state *state) +{ +} static inline void sec_slot_touch(struct boot_loader_state *state) { } @@ -1367,7 +1407,7 @@ boot_validated_swap_type(struct boot_loader_state *state, owner_nsib[BOOT_CURR_IMG(state)] = false; #endif -#if defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) +#if defined(PM_S1_ADDRESS) || defined(PM_CPUNET_B0N_ADDRESS) const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT); struct image_header *hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); @@ -1405,31 +1445,31 @@ boot_validated_swap_type(struct boot_loader_state *state, } /* Check start and end of primary slot for current image */ - if (reset_addr < primary_fa->fa_off) { -#if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - const struct flash_area *nsib_fa; - - /* NSIB upgrade slot */ - rc = flash_area_open((uint32_t)_image_1_primary_slot_id, - &nsib_fa); - - if (rc != 0) { - return BOOT_SWAP_TYPE_FAIL; - } - - /* Image is placed before Primary and within the NSIB slot */ - if (reset_addr > nsib_fa->fa_off - && reset_addr < (nsib_fa->fa_off + nsib_fa->fa_size)) { - /* Set primary to be NSIB upgrade slot */ - BOOT_IMG_AREA(state, 0) = nsib_fa; - owner_nsib[BOOT_CURR_IMG(state)] = true; - } +#if (CONFIG_NCS_IS_VARIANT_IMAGE) + if (reset_addr >= PM_S0_ADDRESS && reset_addr <= (PM_S0_ADDRESS + PM_S0_SIZE)) { #else - return BOOT_SWAP_TYPE_NONE; - + if (reset_addr >= PM_S1_ADDRESS && reset_addr <= (PM_S1_ADDRESS + PM_S1_SIZE)) { #endif + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { + /* This is not the s0/s1 upgrade image but the application image, pretend + * there is no image so the NSIB update can be loaded + */ + return BOOT_SWAP_TYPE_NONE; + } - } else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { + owner_nsib[BOOT_CURR_IMG(state)] = true; +#if (CONFIG_NCS_IS_VARIANT_IMAGE) + } else if (reset_addr >= PM_S1_ADDRESS && reset_addr <= (PM_S1_ADDRESS + PM_S1_SIZE)) { +#else + } else if (reset_addr >= PM_S0_ADDRESS && reset_addr <= (PM_S0_ADDRESS + PM_S0_SIZE)) { +#endif + /* NSIB upgrade but for the wrong slot, must be erased */ + BOOT_LOG_ERR("Image in slot is for wrong s0/s1 image"); + flash_area_erase(secondary_fa, 0, secondary_fa->fa_size); + sec_slot_untouch(state); + BOOT_LOG_ERR("Cleaned-up secondary slot of image %d", BOOT_CURR_IMG(state)); + return BOOT_SWAP_TYPE_FAIL; + } else if (reset_addr < primary_fa->fa_off || reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) { /* The image in the secondary slot is not intended for any */ return BOOT_SWAP_TYPE_NONE; } @@ -1442,7 +1482,7 @@ boot_validated_swap_type(struct boot_loader_state *state, sec_slot_mark_assigned(state); } -#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */ +#endif /* PM_S1_ADDRESS || PM_CPUNET_B0N_ADDRESS */ swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state)); if (BOOT_IS_UPGRADE(swap_type)) { @@ -2108,7 +2148,22 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) flash_area_close(fap); } - swap_run(state, bs, copy_size); +#if defined(PM_S1_ADDRESS) && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 + if (owner_nsib[BOOT_CURR_IMG(state)]) { + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { + /* For NSIB, move the image instead of swapping it */ + nsib_swap_run(state, bs); + +#if defined(CONFIG_REBOOT) + /* Should also reboot at this point so the new S0/S1 update is applied */ + sys_reboot(SYS_REBOOT_COLD); +#endif + } + } else +#endif + { + swap_run(state, bs, copy_size); + } #ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT extern int boot_status_fails; @@ -2779,12 +2834,6 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); -#if defined(PM_S1_ADDRESS) && defined(CONFIG_REBOOT) - if (owner_nsib[BOOT_CURR_IMG(state)]) { - sys_reboot(SYS_REBOOT_COLD); - - } -#endif break; case BOOT_SWAP_TYPE_FAIL: @@ -2858,7 +2907,8 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) * executing MCUBoot image, and is therefore already validated by NSIB and * does not need to also be validated by MCUBoot. */ - bool image_validated_by_nsib = BOOT_CURR_IMG(state) == 1; + bool image_validated_by_nsib = BOOT_CURR_IMG(state) == + CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER; if (!image_validated_by_nsib) #endif { diff --git a/boot/bootutil/src/swap_nsib.c b/boot/bootutil/src/swap_nsib.c new file mode 100644 index 000000000..39ed4c652 --- /dev/null +++ b/boot/bootutil/src/swap_nsib.c @@ -0,0 +1,70 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "bootutil/bootutil.h" +#include "bootutil_priv.h" +#include "swap_priv.h" +#include "bootutil/bootutil_log.h" + +#include "mcuboot_config/mcuboot_config.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot); + +void nsib_swap_run(struct boot_loader_state *state, struct boot_status *bs) +{ + uint32_t sector_sz; + uint8_t image_index; + const struct flash_area *fap_pri; + const struct flash_area *fap_sec; + int rc; + + BOOT_LOG_INF("Starting swap using nsib algorithm."); + + sector_sz = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 0); + +#if (CONFIG_NCS_IS_VARIANT_IMAGE) + rc = flash_area_open(PM_S0_ID, &fap_pri); +#else + rc = flash_area_open(PM_S1_ID, &fap_pri); +#endif + assert (rc == 0); + image_index = BOOT_CURR_IMG(state); + + rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap_sec); + assert (rc == 0); + + rc = boot_erase_region(fap_pri, 0, fap_pri->fa_size); + assert(rc == 0); + + rc = boot_copy_region(state, fap_sec, fap_pri, 0, 0, fap_pri->fa_size); + assert(rc == 0); + + rc = swap_erase_trailer_sectors(state, fap_sec); + assert(rc == 0); + + rc = boot_erase_region(fap_sec, 0, MIN((fap_pri->fa_size + sector_sz), fap_sec->fa_size)); + assert(rc == 0); + + flash_area_close(fap_pri); + flash_area_close(fap_sec); +} diff --git a/boot/bootutil/src/swap_priv.h b/boot/bootutil/src/swap_priv.h index b564ea99e..90e0b3742 100644 --- a/boot/bootutil/src/swap_priv.h +++ b/boot/bootutil/src/swap_priv.h @@ -130,4 +130,12 @@ bool swap_write_block_size_check(struct boot_loader_state *state); */ int app_max_size(struct boot_loader_state *state); +#if defined(PM_S1_ADDRESS) && !defined(MCUBOOT_OVERWRITE_ONLY) && \ +(CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED)) +/** + * Performs an NSIB update + */ +void nsib_swap_run(struct boot_loader_state *state, struct boot_status *bs); +#endif + #endif /* H_SWAP_PRIV_ */ diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 267e84b88..e834e561e 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -181,6 +181,12 @@ else() ) endif() endif() + + if(NOT CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER EQUAL "-1" AND NOT CONFIG_BOOT_UPGRADE_ONLY) + zephyr_library_sources( + ${BOOT_DIR}/bootutil/src/swap_nsib.c + ) + endif() endif() if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index db60ddd03..42f25182e 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -15,48 +15,36 @@ #ifndef CONFIG_SINGLE_APPLICATION_SLOT -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) -/* If B0 is present then two bootloaders are present, and we must use - * a single secondary slot for both primary slots. - */ -extern uint32_t _image_1_primary_slot_id[]; -#endif /* (MCUBOOT_IMAGE_NUMBER == 2 && defined(PM_B0_ADDRESS) */ - -#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - -#define FLASH_AREA_IMAGE_PRIMARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_PRIMARY_ID : \ - (x == 1) ? \ - (uint32_t)_image_1_primary_slot_id : \ - 255 ) - -#define FLASH_AREA_IMAGE_SECONDARY(x) \ - ((x == 0) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - (x == 1) ? \ - PM_MCUBOOT_SECONDARY_ID: \ - 255 ) - -#else /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - */ - /* Each pair of slots is separated by , and there is no terminating character */ -#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID -#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID -#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID +#define FLASH_AREA_IMAGE_0_SLOTS PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID, +#define FLASH_AREA_IMAGE_1_SLOTS PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID, +#define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID, +#define FLASH_AREA_IMAGE_3_SLOTS PM_MCUBOOT_PRIMARY_3_ID, PM_MCUBOOT_SECONDARY_3_ID, + +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 +#ifdef CONFIG_NCS_IS_VARIANT_IMAGE +#define MCUBOOT_S0_S1_SLOTS PM_S0_ID, PM_MCUBOOT_SECONDARY_ID, +#else +#define MCUBOOT_S0_S1_SLOTS PM_S1_ID, PM_MCUBOOT_SECONDARY_ID, +#endif +#else +#define MCUBOOT_S0_S1_SLOTS +#endif -#if (MCUBOOT_IMAGE_NUMBER == 1) +#if (MCUBOOT_IMAGE_NUMBER == 1) || (MCUBOOT_IMAGE_NUMBER == 2 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) #define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 2) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ +#elif (MCUBOOT_IMAGE_NUMBER == 2) || (MCUBOOT_IMAGE_NUMBER == 3 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ FLASH_AREA_IMAGE_1_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 3) -#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS, \ - FLASH_AREA_IMAGE_1_SLOTS, \ +#elif (MCUBOOT_IMAGE_NUMBER == 3) || (MCUBOOT_IMAGE_NUMBER == 4 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ + FLASH_AREA_IMAGE_1_SLOTS \ FLASH_AREA_IMAGE_2_SLOTS +#elif (MCUBOOT_IMAGE_NUMBER == 4) +#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ + FLASH_AREA_IMAGE_1_SLOTS \ + FLASH_AREA_IMAGE_2_SLOTS \ + FLASH_AREA_IMAGE_3_SLOTS #else #error Unsupported number of images #endif @@ -65,6 +53,7 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) { static const int all_slots[] = { ALL_AVAILABLE_SLOTS + MCUBOOT_S0_S1_SLOTS }; return all_slots[img * 2 + slot]; }; @@ -72,6 +61,8 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #undef FLASH_AREA_IMAGE_0_SLOTS #undef FLASH_AREA_IMAGE_1_SLOTS #undef FLASH_AREA_IMAGE_2_SLOTS +#undef FLASH_AREA_IMAGE_3_SLOTS +#undef MCUBOOT_S0_S1_SLOTS #undef ALL_AVAILABLE_SLOTS #define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0) @@ -81,10 +72,6 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #define FLASH_AREA_IMAGE_SCRATCH PM_MCUBOOT_SCRATCH_ID #endif -#endif /* MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \ - * !defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) - */ - #else /* CONFIG_SINGLE_APPLICATION_SLOT */ #define FLASH_AREA_IMAGE_PRIMARY(x) PM_MCUBOOT_PRIMARY_ID From 71d19a5896c8e8cb406bfdf79ad24efb2d3a0f30 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 15 Oct 2024 11:31:20 +0100 Subject: [PATCH 174/204] [nrf noup] boot: bootutil: loader: Add s0/s1 checking of MCUboot image Adds a check that will also check the s0/s1 package version of the currently running MCUboot against a MCUboot update image to ensure that an older version of MCUboot isn't loaded to the opposite slot Signed-off-by: Jamie McCrae (cherry picked from commit 4738ae858d7dde54675aaa00b682e4b6697c35da) --- boot/bootutil/src/loader.c | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 0b0b81be7..90e4b789a 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -101,6 +101,17 @@ static struct sector_buffer_t sector_buffers; #endif #endif +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 && defined(MCUBOOT_OVERWRITE_ONLY) && \ + defined(MCUBOOT_DOWNGRADE_PREVENTION) +/* s0/s1 package version of the current MCUboot image */ +static const struct image_version mcuboot_s0_s1_image_version = { + .iv_major = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_MAJOR, + .iv_minor = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_MINOR, + .iv_revision = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_REVISION, + .iv_build_num = CONFIG_MCUBOOT_MCUBOOT_S0_S1_VERSION_BUILD_NUMBER, +}; +#endif + #if (BOOT_IMAGE_NUMBER > 1) #define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x)) #else @@ -1111,11 +1122,45 @@ boot_validate_slot(struct boot_loader_state *state, int slot, rc = boot_version_cmp( &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 + if (rc >= 0 && BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { + /* Also check the new version of MCUboot against that of the current s0/s1 MCUboot + * trailer version to prevent downgrades + */ + int version_check; + + version_check = boot_version_cmp(&boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &mcuboot_s0_s1_image_version); + + /* Only update rc if the currently running version is newer */ + if (version_check < rc) { + rc = version_check; + } + } +#endif } #else rc = boot_version_cmp( &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver); + +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 + if (rc >= 0 && BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { + /* Also check the new version of MCUboot against that of the current s0/s1 MCUboot + * trailer version to prevent downgrades + */ + int version_check; + + version_check = boot_version_cmp(&boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver, + &mcuboot_s0_s1_image_version); + + /* Only update rc if the currently running version is newer */ + if (version_check < rc) { + rc = version_check; + } + } +#endif #endif if (rc < 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) { BOOT_LOG_ERR("insufficient version in secondary slot"); From f98ae0bdd3e1007e5b4376789778f7585bffca91 Mon Sep 17 00:00:00 2001 From: Maximilian Deubel Date: Wed, 23 Oct 2024 16:48:13 +0200 Subject: [PATCH 175/204] [nrf noup] boards: Thingy:91 X release config Update the configuration files for the Thingy:91 X targets to the ones used in production. Signed-off-by: Maximilian Deubel (cherry picked from commit 52322e20de27c93aa102058fb9e2fb762b705f11) --- boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf | 3 +++ boot/zephyr/boards/thingy91x_nrf9151.conf | 6 +++++- boot/zephyr/boards/thingy91x_nrf9151.overlay | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 boot/zephyr/boards/thingy91x_nrf9151.overlay diff --git a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf index 37c7e95b1..d3e253b65 100644 --- a/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy91x_nrf5340_cpuapp.conf @@ -58,3 +58,6 @@ CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y # Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n + +CONFIG_BOOT_SERIAL_NO_APPLICATION=y +CONFIG_FW_INFO_FIRMWARE_VERSION=2 diff --git a/boot/zephyr/boards/thingy91x_nrf9151.conf b/boot/zephyr/boards/thingy91x_nrf9151.conf index 2efe1e170..7c2042de6 100644 --- a/boot/zephyr/boards/thingy91x_nrf9151.conf +++ b/boot/zephyr/boards/thingy91x_nrf9151.conf @@ -12,6 +12,10 @@ CONFIG_CONSOLE=n CONFIG_CONSOLE_HANDLER=n CONFIG_UART_CONSOLE=n CONFIG_MCUBOOT_SERIAL=y - CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y + +CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y +CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y + +CONFIG_FW_INFO_FIRMWARE_VERSION=2 diff --git a/boot/zephyr/boards/thingy91x_nrf9151.overlay b/boot/zephyr/boards/thingy91x_nrf9151.overlay new file mode 100644 index 000000000..7f2818c0d --- /dev/null +++ b/boot/zephyr/boards/thingy91x_nrf9151.overlay @@ -0,0 +1,4 @@ +&uart0 { + status = "okay"; + current-speed = < 1000000 >; +}; From ae09b052a37c343009d5d96cc579185a607665c2 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 25 Oct 2024 09:37:44 +0200 Subject: [PATCH 176/204] [nrf noup] workflows: Add a backport workflow Enable backporting of PRs. Signed-off-by: Carles Cufi (cherry picked from commit 22409c3e6c613a5c98692ee67a7706ca543c99c9) --- .github/workflows/backport.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/backport.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 000000000..e986738ff --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,31 @@ +name: Backport +on: + pull_request_target: + types: + - closed + - labeled + branches: + - main + +jobs: + backport: + name: Backport + runs-on: ubuntu-22.04 + # Only react to merged PRs for security reasons. + # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target. + if: > + github.event.pull_request.merged && + ( + github.event.action == 'closed' || + ( + github.event.action == 'labeled' && + contains(github.event.label.name, 'backport') + ) + ) + steps: + - name: Backport + uses: zephyrproject-rtos/action-backport@v2.0.3-3 + with: + github_token: ${{ secrets.NCS_GITHUB_TOKEN }} + issue_labels: Backport + labels_template: '["Backport"]' From 95eca047ab47529f037ffa239e86b67074025d2b Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Thu, 7 Nov 2024 11:09:18 +0100 Subject: [PATCH 177/204] [nrf noup] boot/zephyr: add nrf54l15dk ext flash configs Moved configs from nrf54l15pdk. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 8e5297e9b9565b51a75a6d89926c3002231217d2) --- .../nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf | 15 ++++++ ...f54l15dk_nrf54l15_cpuapp_ext_flash.overlay | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf create mode 100644 boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf new file mode 100644 index 000000000..8fc12e074 --- /dev/null +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf @@ -0,0 +1,15 @@ +CONFIG_MULTITHREADING=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_FLASH=y +CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x14000 +CONFIG_MAIN_STACK_SIZE=20480 +CONFIG_BOOT_MAX_IMG_SECTORS=512 +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +# Ensure that the qspi driver is disabled by default +CONFIG_NORDIC_QSPI_NOR=n + +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + +CONFIG_BOOT_WATCHDOG_FEED=n diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay new file mode 100644 index 000000000..60ee6fe51 --- /dev/null +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.overlay @@ -0,0 +1,47 @@ +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + zephyr,code-partition = &boot_partition; + }; +}; + +/delete-node/ &boot_partition; +/delete-node/ &slot0_partition; +/delete-node/ &slot1_partition; + +/delete-node/ &slot0_ns_partition; +/delete-node/ &slot1_ns_partition; + +/delete-node/ &storage_partition; + +&cpuapp_rram { + reg = < 0x0 DT_SIZE_K(1524) >; + partitions { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x000000000 0x00014000>; + }; + slot0_partition: partition@14000 { + label = "image-0"; + reg = <0x000014000 0x0015A000>; + }; + storage_partition: partition@16E000 { + label = "storage"; + reg = < 0x16E000 0x9000 >; + }; + }; +}; + +&mx25r64 { + status = "okay"; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot1_partition: partition@0 { + label = "image-1"; + reg = <0x000000000 0x0015A000>; + }; + }; +}; From 136af052a7339673fac80bced9bc0a9066a47eec Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Thu, 19 Sep 2024 14:32:37 +0200 Subject: [PATCH 178/204] [nrf noup] boot/zephyr/Kconfig: conditionally disable BOOT_MAX_IMG_SECTORS_AUTO Automatic calculation are based on DTS data which are no the right source on partition layout in case Partition manager does the partitioning. Signed-off-by: Andrzej Puzdrowski Signed-off-by: Dominik Ermel (cherry picked from commit b66e930b70e31ec76e0c1c2a7d4252221e810c26) --- boot/zephyr/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 81d4076d5..3e44d779d 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -623,7 +623,7 @@ config BOOT_ENCRYPTION_KEY_FILE config BOOT_MAX_IMG_SECTORS_AUTO bool "Calculate maximum sectors automatically" - default y + default y if !PARTITION_MANAGER_ENABLED help If this option is enabled then the maximum number of supported sectors per image will be calculated automatically from the flash erase sizes and size of each partition for From d9d880f0d34778ed16e16bd112c1c22393784178 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 9 Dec 2024 12:27:38 +0000 Subject: [PATCH 179/204] [nrf noup] boot: zephyr: serial_recovery: Add nRF5340 Kconfig override Adds additional conditions that lets the direct upload option to be selected on nRF5340 to allow for uploading network core updates directly to the network core with the flash simulator Signed-off-by: Jamie McCrae (cherry picked from commit b1690156f6ad1bbf68b7526eb914d2f8aae9237f) --- boot/zephyr/Kconfig.serial_recovery | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig.serial_recovery b/boot/zephyr/Kconfig.serial_recovery index 45d252408..5b4ba3e11 100644 --- a/boot/zephyr/Kconfig.serial_recovery +++ b/boot/zephyr/Kconfig.serial_recovery @@ -46,9 +46,14 @@ config BOOT_SERIAL_CDC_ACM endchoice +DT_COMPAT_SIM_FLASH:= zephyr,sim-flash +DT_SIM_FLASH_PATH := $(dt_nodelabel_path,flash_sim0) + config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD bool "Allow to select image number for DFU" - depends on !SINGLE_APPLICATION_SLOT + # Allow this option to be selected in cases where support for direct uploading to nRF5340 + # network core should be supported + depends on !SINGLE_APPLICATION_SLOT || (SINGLE_APPLICATION_SLOT && SOC_NRF5340_CPUAPP && BOOT_IMAGE_ACCESS_HOOK_NRF5340 && FLASH_SIMULATOR && $(dt_compat_enabled,$(DT_COMPAT_SIM_FLASH))) help With the option enabled, the mcuboot serial recovery will respect the "image" field in mcumgr image update frame From 6f72d72e8bf44fd732c77c8145a39a0eacb31f7f Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 17 Dec 2024 15:54:01 +0100 Subject: [PATCH 180/204] [nrf noup] boot/zephyr/boards: configure fastest RRAM operations Configured CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE=32 Which ensure the fastest bulk RRAM write operations. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit d18f8fd39d037e5a85dda2d50610f49f54d1a024) --- boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf index 8fc12e074..12650a9ed 100644 --- a/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf +++ b/boot/zephyr/boards/nrf54l15dk_nrf54l15_cpuapp_ext_flash.conf @@ -13,3 +13,6 @@ CONFIG_NORDIC_QSPI_NOR=n CONFIG_FPROTECT=n CONFIG_BOOT_WATCHDOG_FEED=n + +# Ensure the fastest RRAM write operations +CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE=32 From 3b7753529674aafa9a1ff93a7dd235ccbb5b7ad3 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 5 Dec 2024 10:20:19 +0000 Subject: [PATCH 181/204] [nrf noup] boot: Remove child/parent references Removes stray child/parent references Signed-off-by: Jamie McCrae (cherry picked from commit b7a30ffbfd277f7e03cd63b35a5b300230ba6793) --- boot/bootutil/src/swap_priv.h | 2 +- boot/zephyr/pm.yml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/boot/bootutil/src/swap_priv.h b/boot/bootutil/src/swap_priv.h index 90e0b3742..10473a9cc 100644 --- a/boot/bootutil/src/swap_priv.h +++ b/boot/bootutil/src/swap_priv.h @@ -131,7 +131,7 @@ bool swap_write_block_size_check(struct boot_loader_state *state); int app_max_size(struct boot_loader_state *state); #if defined(PM_S1_ADDRESS) && !defined(MCUBOOT_OVERWRITE_ONLY) && \ -(CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED)) +CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 /** * Performs an NSIB update */ diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index 13ffc44aa..ab8f6d1c3 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -4,9 +4,7 @@ mcuboot: size: CONFIG_PM_PARTITION_SIZE_MCUBOOT placement: before: [mcuboot_primary] -#if defined(CONFIG_HIDE_CHILD_PARENT_CONFIG) align: {end: 0x1000} -#endif mcuboot_primary_app: # All images to be placed in MCUboot's slot 0 should be placed in this From a71254474491d849f3c0d9c29a3c68aa28d857fd Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 15 Jan 2025 15:09:55 +0000 Subject: [PATCH 182/204] [nrf noup] sysflash: Add missing _FLASH_0_ID definitions MCUboot uses SOC_FLASH_0_ID and SPI_FLASH_0_ID to distinguish between internal and external boot device. These IDs are provided by sysflash.h, but the pm_sysflash.h overrides entire file, and was lacking that definitions. Signed-off-by: Dominik Ermel (cherry picked from commit b9578ab6f7537e7a58d5c3609cd0de5ca0c24ff1) --- boot/zephyr/include/sysflash/pm_sysflash.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index 42f25182e..0cb16292f 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -84,4 +84,12 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot) #endif /* CONFIG_SINGLE_APPLICATION_SLOT */ +#ifndef SOC_FLASH_0_ID +#define SOC_FLASH_0_ID 0 +#endif + +#ifndef SPI_FLASH_0_ID +#define SPI_FLASH_0_ID 1 +#endif + #endif /* __PM_SYSFLASH_H__ */ From 491046b505d8cea31d14957e77c045724cd2c50a Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk Date: Fri, 24 Jan 2025 08:59:31 +0100 Subject: [PATCH 183/204] [nrf noup] boot: zephyr: boards: Disabled NCS boot banner for thingy 53 Disabled NCS BOOT BANNER to save some flash, as Thingy:53 stopped to fit in the mcuboot partition. The boot banner is not used anyway, as logs are disabled. Signed-off-by: Kamil Kasperczyk (cherry picked from commit 1027dd80a4de4a65e276af63543d37463fffcb03) --- boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf index e10656678..c584aa911 100644 --- a/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf +++ b/boot/zephyr/boards/thingy53_nrf5340_cpuapp.conf @@ -47,6 +47,7 @@ CONFIG_USB_CDC_ACM=y CONFIG_CBPRINTF_NANO=y CONFIG_TIMESLICING=n CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n CONFIG_CONSOLE=n CONFIG_CONSOLE_HANDLER=n CONFIG_UART_CONSOLE=n From 7069844625564553075d364b69c2ddf3f6b4db58 Mon Sep 17 00:00:00 2001 From: Sigurd Hellesvik Date: Thu, 6 Feb 2025 08:47:39 +0100 Subject: [PATCH 184/204] [nrf noup] partition_manager: Add support for internal flash netcore DFU Adds check to region of mcuboot_secondary_1 to put it in external flash only if CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY is set. This should allow for DFU from internal flash on the nRF5340 with dynamic partitioning. Also fixing a typo. Signed-off-by: Sigurd Hellesvik (cherry picked from commit f3fedff247cb98559bb184088efd555521c9cf81) --- boot/zephyr/pm.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/pm.yml b/boot/zephyr/pm.yml index ab8f6d1c3..eec62473c 100644 --- a/boot/zephyr/pm.yml +++ b/boot/zephyr/pm.yml @@ -78,11 +78,17 @@ mcuboot_pad: mcuboot_primary_1: region: ram_flash size: CONFIG_NRF53_RAM_FLASH_SIZE -#endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ +#endif /* CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH */ #if (CONFIG_NRF53_MULTI_IMAGE_UPDATE) mcuboot_secondary_1: +#if defined(CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY) region: external_flash +#else + placement: + align: {start: CONFIG_FPROTECT_BLOCK_SIZE} + after: mcuboot_secondary +#endif size: CONFIG_NRF53_RAM_FLASH_SIZE #endif /* CONFIG_NRF53_MULTI_IMAGE_UPDATE */ From 99486f85d6b68a06c3afcd7f10ee6a5cbea26cf6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 4 Mar 2025 17:31:33 +0000 Subject: [PATCH 185/204] [nrf noup] zephyr: sdk-nrf specific overrides on PSA Kconfigs Select proper configuration and disable mbedTLS selection, as we are using NRF Security enabled Oberon. Signed-off-by: Dominik Ermel (cherry picked from commit fa89f7b8d1003afe48926214870772f9c718687b) --- boot/bootutil/zephyr/CMakeLists.txt | 2 +- boot/zephyr/Kconfig | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/zephyr/CMakeLists.txt b/boot/bootutil/zephyr/CMakeLists.txt index f6d37441c..44f78f395 100644 --- a/boot/bootutil/zephyr/CMakeLists.txt +++ b/boot/bootutil/zephyr/CMakeLists.txt @@ -40,7 +40,7 @@ if(CONFIG_BOOT_USE_PSA_CRYPTO) ) endif() -if(CONFIG_BOOT_USE_MBEDTLS OR CONFIG_BOOT_USE_PSA_CRYPTO) +if(CONFIG_BOOT_USE_MBEDTLS OR CONFIG_BOOT_USE_PSA_CRYPTO AND NOT CONFIG_NRF_SECURITY) zephyr_link_libraries(mbedTLS) endif() endif() diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 3e44d779d..e19863572 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -83,8 +83,7 @@ config BOOT_ED25519_PSA_DEPENDENCIES select PSA_WANT_ALG_SHA_256 select PSA_WANT_ALG_SHA_512 select PSA_WANT_ALG_PURE_EDDSA - # Seems that upstream mbedTLS does not have TE - #select PSA_WANT_ECC_TWISTED_EDWARDS_255 + select PSA_WANT_ECC_TWISTED_EDWARDS_255 select PSA_WANT_ECC_MONTGOMERY_255 select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT help @@ -282,6 +281,7 @@ config BOOT_SIGNATURE_TYPE_PURE choice BOOT_ED25519_IMPLEMENTATION prompt "Ecdsa implementation" + default BOOT_ED25519_PSA if NRF_SECURITY default BOOT_ED25519_TINYCRYPT config BOOT_ED25519_TINYCRYPT @@ -302,7 +302,7 @@ config BOOT_ED25519_MBEDTLS config BOOT_ED25519_PSA bool "Use PSA crypto" - select MBEDTLS + depends on NRF_SECURITY select BOOT_USE_PSA_CRYPTO select PSA_CRYPTO_CLIENT select PSA_CRYPTO_C @@ -372,6 +372,7 @@ config MBEDTLS_CFG_FILE # is used, but the fact is that Mbed TLS' ASN1 parse module is used # also when TinyCrypt is used as crypto backend. default "mcuboot-mbedtls-cfg.h" if BOOT_USE_TINYCRYPT + default "config-tls-generic.h" if NRF_SECURITY && (MBEDTLS_BUILTIN || BOOT_USE_PSA_CRYPTO) default "mcuboot-mbedtls-cfg.h" if BOOT_USE_MBEDTLS && !MBEDTLS_BUILTIN config BOOT_HW_KEY From 70ebdf6451ddaca3ec294cb4ed664b11a0b6df1c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 11 Jul 2023 08:42:49 +0100 Subject: [PATCH 186/204] [nrf noup] zephyr: Fix path variables Fixes path variables to use the proper Zephyr module variables Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 5c886db89fdc8b13ff4879c3ee285913b899409b) --- boot/zephyr/CMakeLists.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index e834e561e..5b7615a3a 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -35,21 +35,20 @@ if(NOT CONFIG_MBEDTLS_BUILTIN AND NOT CONFIG_BOOT_KEY_IMPORT_BYPASS_ASN) set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls-asn1") assert_exists(MBEDTLS_ASN1_DIR) endif() -set(NRF_DIR "${MCUBOOT_DIR}/ext/nrf") +set(MCUBOOT_NRF_EXT_DIR "${MCUBOOT_DIR}/ext/nrf") if(CONFIG_BOOT_USE_NRF_CC310_BL) -set(NRFXLIB_DIR ${ZEPHYR_BASE}/../nrfxlib) -if(NOT EXISTS ${NRFXLIB_DIR}) - message(FATAL_ERROR " + if(NOT EXISTS ${ZEPHYR_NRFXLIB_MODULE_DIR}) + message(FATAL_ERROR " ------------------------------------------------------------------------ - No such file or directory: ${NRFXLIB_DIR} + No such file or directory: ${ZEPHYR_NRFXLIB_MODULE_DIR} The current configuration enables nRF CC310 crypto accelerator hardware with the `CONFIG_BOOT_USE_NRF_CC310_BL` option. Please follow `ext/nrf/README.md` guide to fix your setup or use tinycrypt instead of the HW accelerator. To use the tinycrypt set `CONFIG_BOOT_ECDSA_TINYCRYPT` to y. ------------------------------------------------------------------------") -endif() + endif() endif() zephyr_library_include_directories( @@ -215,8 +214,8 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256) ${TINYCRYPT_DIR}/source/utils.c ) elseif(CONFIG_BOOT_USE_NRF_CC310_BL) - zephyr_library_sources(${NRF_DIR}/cc310_glue.c) - zephyr_library_include_directories(${NRF_DIR}) + zephyr_library_sources(${MCUBOOT_NRF_EXT_DIR}/cc310_glue.c) + zephyr_library_include_directories(${MCUBOOT_NRF_EXT_DIR}) zephyr_link_libraries(nrfxlib_crypto) elseif(CONFIG_BOOT_USE_NRF_EXTERNAL_CRYPTO) zephyr_include_directories(${BL_CRYPTO_DIR}/../include) From 452a82b491be2d2dff8ab2a6a1ee0f4581cb74fa Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Aug 2024 14:17:46 +0100 Subject: [PATCH 187/204] [nrf noup] zephyr: Add support for compressed image updates Adds support for LZMA-compressed firmware updates which also supports encrypted images and supports more than 1 updateable image Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit b2fc324ba916c718f64130bfd40513d4be003cf9) --- boot/bootutil/src/bootutil_misc.c | 80 +- boot/bootutil/src/image_validate.c | 228 ++- boot/bootutil/src/loader.c | 27 +- boot/zephyr/CMakeLists.txt | 6 + boot/zephyr/Kconfig | 9 +- boot/zephyr/decompression.c | 1410 +++++++++++++++++ .../include/compression/decompression.h | 103 ++ 7 files changed, 1839 insertions(+), 24 deletions(-) create mode 100644 boot/zephyr/decompression.c create mode 100644 boot/zephyr/include/compression/decompression.h diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index e53715b65..91cfdf9c6 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -43,6 +43,11 @@ #include "bootutil/enc_key.h" #endif +#if defined(MCUBOOT_DECOMPRESS_IMAGES) +#include +#include +#endif + BOOT_LOG_MODULE_DECLARE(mcuboot); /* Currently only used by imgmgr */ @@ -523,35 +528,76 @@ boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size) fap = BOOT_IMG_AREA(state, slot); assert(fap != NULL); - off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); +#ifdef MCUBOOT_DECOMPRESS_IMAGES + if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), boot_img_hdr(state, slot))) { + uint32_t tmp_size = 0; - if (flash_area_read(fap, off, &info, sizeof(info))) { - rc = BOOT_EFLASH; - goto done; - } + rc = bootutil_get_img_decomp_size(boot_img_hdr(state, slot), fap, &tmp_size); + + if (rc) { + rc = BOOT_EBADIMAGE; + goto done; + } + + off = boot_img_hdr(state, slot)->ih_hdr_size + tmp_size; + + rc = boot_size_protected_tlvs(boot_img_hdr(state, slot), fap, &tmp_size); - protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; - if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { - if (protect_tlv_size != info.it_tlv_tot) { + if (rc) { rc = BOOT_EBADIMAGE; goto done; } - if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { + off += tmp_size; + + if (flash_area_read(fap, (BOOT_TLV_OFF(boot_img_hdr(state, slot)) + + boot_img_hdr(state, slot)->ih_protect_tlv_size), &info, + sizeof(info))) { rc = BOOT_EFLASH; goto done; } - } else if (protect_tlv_size != 0) { - rc = BOOT_EBADIMAGE; - goto done; - } - if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { - rc = BOOT_EBADIMAGE; - goto done; + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; + } + + *size = off + info.it_tlv_tot; + } else { +#else + if (1) { +#endif + off = BOOT_TLV_OFF(boot_img_hdr(state, slot)); + + if (flash_area_read(fap, off, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + + protect_tlv_size = boot_img_hdr(state, slot)->ih_protect_tlv_size; + if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) { + if (protect_tlv_size != info.it_tlv_tot) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (flash_area_read(fap, off + info.it_tlv_tot, &info, sizeof(info))) { + rc = BOOT_EFLASH; + goto done; + } + } else if (protect_tlv_size != 0) { + rc = BOOT_EBADIMAGE; + goto done; + } + + if (info.it_magic != IMAGE_TLV_INFO_MAGIC) { + rc = BOOT_EBADIMAGE; + goto done; + } + + *size = off + protect_tlv_size + info.it_tlv_tot; } - *size = off + protect_tlv_size + info.it_tlv_tot; rc = 0; done: diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 61cbf4de0..40f0aa857 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -42,6 +42,15 @@ #include "mcuboot_config/mcuboot_config.h" +#if defined(MCUBOOT_DECOMPRESS_IMAGES) +#include +#include +#endif + +#include "bootutil/bootutil_log.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot); + #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif @@ -484,7 +493,7 @@ bootutil_img_validate(struct boot_loader_state *state, #endif ) { -#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT) +#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT) || defined(MCUBOOT_DECOMPRESS_IMAGES) int image_index = (state == NULL ? 0 : BOOT_CURR_IMG(state)); #endif uint32_t off; @@ -518,6 +527,68 @@ bootutil_img_validate(struct boot_loader_state *state, FIH_DECLARE(security_counter_valid, FIH_FAILURE); #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + /* If the image is compressed, the integrity of the image must also be validated */ + if (MUST_DECOMPRESS(fap, image_index, hdr)) { + bool found_decompressed_size = false; + bool found_decompressed_sha = false; + bool found_decompressed_signature = false; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(state, fap)) { + rc = -1; + goto out; + } + + while (true) { + uint16_t expected_size = 0; + bool *found_flag = NULL; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + switch (type) { + case IMAGE_TLV_DECOMP_SIZE: + expected_size = sizeof(size_t); + found_flag = &found_decompressed_size; + break; + case IMAGE_TLV_DECOMP_SHA: + expected_size = IMAGE_HASH_SIZE; + found_flag = &found_decompressed_sha; + break; + case IMAGE_TLV_DECOMP_SIGNATURE: + found_flag = &found_decompressed_signature; + break; + default: + continue; + }; + + if (type == IMAGE_TLV_DECOMP_SIGNATURE && !EXPECTED_SIG_LEN(len)) { + rc = -1; + goto out; + } else if (type != IMAGE_TLV_DECOMP_SIGNATURE && len != expected_size) { + rc = -1; + goto out; + } + + *found_flag = true; + } + + rc = (!found_decompressed_size || !found_decompressed_sha || !found_decompressed_signature); + if (rc) { + goto out; + } + } +#endif + #if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) #if defined(MCUBOOT_SWAP_USING_OFFSET) && defined(MCUBOOT_SERIAL_RECOVERY) rc = bootutil_img_hash(state, hdr, fap, tmp_buf, tmp_buf_sz, hash, seed, seed_len, @@ -740,6 +811,161 @@ bootutil_img_validate(struct boot_loader_state *state, } #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + /* Only after all previous verifications have passed, perform a dry-run of the decompression + * and ensure the image is valid + */ + if (!rc && MUST_DECOMPRESS(fap, image_index, hdr)) { + image_hash_valid = 0; + FIH_SET(valid_signature, FIH_FAILURE); + + rc = bootutil_img_hash_decompress(state, hdr, fap, tmp_buf, tmp_buf_sz, + hash, seed, seed_len); + if (rc) { + goto out; + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SHA, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(state, fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + if (type == IMAGE_TLV_DECOMP_SHA) { + /* Verify the image hash. This must always be present. */ + if (len != sizeof(hash)) { + rc = -1; + goto out; + } + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, sizeof(hash)); + if (rc) { + goto out; + } + + FIH_CALL(boot_fih_memequal, fih_rc, hash, buf, sizeof(hash)); + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + + image_hash_valid = 1; + } + } + + rc = !image_hash_valid; + if (rc) { + goto out; + } + +#ifdef EXPECTED_SIG_TLV +#ifdef EXPECTED_KEY_TLV + rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(state, fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + break; + } + + if (type == EXPECTED_KEY_TLV) { + /* + * Determine which key we should be checking. + */ + if (len > KEY_BUF_SIZE) { + rc = -1; + goto out; + } +#ifndef MCUBOOT_HW_KEY + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); + if (rc) { + goto out; + } + key_id = bootutil_find_key(buf, len); +#else + rc = LOAD_IMAGE_DATA(hdr, fap, off, key_buf, len); + if (rc) { + goto out; + } + key_id = bootutil_find_key(image_index, key_buf, len); +#endif /* !MCUBOOT_HW_KEY */ + /* + * The key may not be found, which is acceptable. There + * can be multiple signatures, each preceded by a key. + */ + } + } +#endif /* EXPECTED_KEY_TLV */ + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true); + if (rc) { + goto out; + } + + if (it.tlv_end > bootutil_max_image_size(state, fap)) { + rc = -1; + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIGNATURE) { + /* Ignore this signature if it is out of bounds. */ + if (key_id < 0 || key_id >= bootutil_key_cnt) { + key_id = -1; + continue; + } + + if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { + rc = -1; + goto out; + } + rc = LOAD_IMAGE_DATA(hdr, fap, off, buf, len); + if (rc) { + goto out; + } + + FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash), + buf, len, key_id); + key_id = -1; + } + } +#endif /* EXPECTED_SIG_TLV */ + } +#endif + +#ifdef EXPECTED_SIG_TLV + FIH_SET(fih_rc, valid_signature); +#endif + out: if (rc) { FIH_SET(fih_rc, FIH_FAILURE); diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 90e4b789a..235f31325 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -50,6 +50,11 @@ #include "bootutil/boot_hooks.h" #include "bootutil/mcuboot_status.h" +#if defined(MCUBOOT_DECOMPRESS_IMAGES) +#include +#include +#endif + #ifdef __ZEPHYR__ #include #endif @@ -944,10 +949,10 @@ boot_is_header_valid(const struct image_header *hdr, const struct flash_area *fa return false; } #else - if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) && - (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) - { - return false; + if (MUST_DECOMPRESS(fap, BOOT_CURR_IMG(state), hdr)) { + if (!boot_is_compressed_header_valid(hdr, fap, state)) { + return false; + } } #endif @@ -1192,6 +1197,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * attempts to validate and boot it. */ } + #if !defined(__BOOTSIM__) BOOT_LOG_ERR("Image in the %s slot is not valid!", (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary"); @@ -1790,6 +1796,9 @@ boot_copy_region(struct boot_loader_state *state, #else (void)state; #endif +#if defined(MCUBOOT_DECOMPRESS_IMAGES) && !defined(MCUBOOT_ENC_IMAGES) + struct image_header *hdr; +#endif TARGET_STATIC uint8_t buf[BUF_SZ] __attribute__((aligned(4))); @@ -1815,6 +1824,16 @@ boot_copy_region(struct boot_loader_state *state, } #endif +#ifdef MCUBOOT_DECOMPRESS_IMAGES + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + + if (MUST_DECOMPRESS(fap_src, BOOT_CURR_IMG(state), hdr)) { + /* Use alternative function for compressed images */ + return boot_copy_region_decompress(state, fap_src, fap_dst, off_src, off_dst, sz, buf, + BUF_SZ); + } +#endif + bytes_copied = 0; while (bytes_copied < sz) { if (sz - bytes_copied > sizeof buf) { diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 5b7615a3a..b18c78934 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -314,6 +314,12 @@ if(CONFIG_BOOT_ENCRYPT_EC256) ) endif() +if(CONFIG_BOOT_DECOMPRESSION) + zephyr_library_sources( + decompression.c + ) +endif() + if(CONFIG_MCUBOOT_SERIAL) zephyr_sources(${BOOT_DIR}/zephyr/serial_adapter.c) zephyr_sources(${BOOT_DIR}/boot_serial/src/boot_serial.c) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index e19863572..90a354d20 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -1002,6 +1002,9 @@ config BOOT_BANNER_STRING config BOOT_DECOMPRESSION_SUPPORT bool + depends on NRF_COMPRESS && NRF_COMPRESS_DECOMPRESSION && (NRF_COMPRESS_LZMA_VERSION_LZMA1 || NRF_COMPRESS_LZMA_VERSION_LZMA2) + depends on !SINGLE_APPLICATION_SLOT && BOOT_UPGRADE_ONLY + default y help Hidden symbol which should be selected if a system provided decompression support. @@ -1009,6 +1012,8 @@ if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION bool "Decompression" + select NRF_COMPRESS_CLEANUP + select PM_USE_CONFIG_SRAM_SIZE if SOC_NRF54L15_CPUAPP help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to @@ -1017,9 +1022,9 @@ menuconfig BOOT_DECOMPRESSION if BOOT_DECOMPRESSION config BOOT_DECOMPRESSION_BUFFER_SIZE - int "Write buffer size" + int range 16 16384 - default 4096 + default NRF_COMPRESS_CHUNK_SIZE help The size of a secondary buffer used for writing decompressed data to the storage device. diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c new file mode 100644 index 000000000..f49898d55 --- /dev/null +++ b/boot/zephyr/decompression.c @@ -0,0 +1,1410 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include "compression/decompression.h" +#include "bootutil/crypto/sha.h" +#include "bootutil/bootutil_log.h" + +#if !defined(__BOOTSIM__) +#define TARGET_STATIC static +#else +#define TARGET_STATIC +#endif + +#if defined(MCUBOOT_SIGN_RSA) +#if MCUBOOT_SIGN_RSA_LEN == 2048 +#define EXPECTED_SIG_TLV IMAGE_TLV_RSA2048_PSS +#elif MCUBOOT_SIGN_RSA_LEN == 3072 +#define EXPECTED_SIG_TLV IMAGE_TLV_RSA3072_PSS +#endif +#elif defined(MCUBOOT_SIGN_EC256) || \ + defined(MCUBOOT_SIGN_EC384) || \ + defined(MCUBOOT_SIGN_EC) +#define EXPECTED_SIG_TLV IMAGE_TLV_ECDSA_SIG +#elif defined(MCUBOOT_SIGN_ED25519) +#define EXPECTED_SIG_TLV IMAGE_TLV_ED25519 +#endif + +#define DECOMP_BUF_SIZE CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE +#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) +#define DECOMP_BUF_EXTRA_SIZE 2 +#else +#define DECOMP_BUF_EXTRA_SIZE 0 +#endif +#define DECOMP_BUF_ALLOC_SIZE (DECOMP_BUF_SIZE + DECOMP_BUF_EXTRA_SIZE) + +/* Number of times that consumed data by decompression system can be 0 in a row before aborting */ +#define OFFSET_ZERO_CHECK_TIMES 3 + +BOOT_LOG_MODULE_DECLARE(mcuboot); + +static int boot_sha_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, uint32_t protected_size, + uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx); + +bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, + struct boot_loader_state *state) +{ + /* Image is compressed in secondary slot, need to check if fits into the primary slot */ + bool opened_flash_area = false; + int primary_fa_id; + int rc; + int size_check; + int size; + uint32_t protected_tlvs_size; + uint32_t decompressed_size; + + primary_fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT); + + if (primary_fa_id == fap->fa_id) { + BOOT_LOG_ERR("Primary slots cannot be compressed, image: %d", BOOT_CURR_IMG(state)); + return false; + } + + if (BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT) == NULL) { + opened_flash_area = true; + } + + rc = flash_area_open(primary_fa_id, &BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + assert(rc == 0); + + size_check = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + + if (opened_flash_area) { + (void)flash_area_close(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + } + + rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_size); + + if (rc) { + return false; + } + + if (!boot_u32_safe_add(&size, decompressed_size, hdr->ih_hdr_size)) { + return false; + } + + rc = boot_size_protected_tlvs(hdr, fap, &protected_tlvs_size); + + if (rc) { + return false; + } + + if (!boot_u32_safe_add(&size, size, protected_tlvs_size)) { + return false; + } + + if (size >= size_check) { + BOOT_LOG_ERR("Compressed image too large, decompressed image size: 0x%x, slot size: 0x%x", + size, size_check); + return false; + } + + return true; +} + +static bool is_compression_object_valid(struct nrf_compress_implementation *compression) +{ + if (compression == NULL || compression->init == NULL || compression->deinit == NULL || + compression->decompress_bytes_needed == NULL || compression->decompress == NULL) { + return false; + } + + return true; +} + +#ifdef MCUBOOT_ENC_IMAGES +int bootutil_get_img_decrypted_comp_size(const struct image_header *hdr, + const struct flash_area *fap, uint32_t *img_comp_size) +{ + if (hdr == NULL || fap == NULL || img_comp_size == NULL) { + return BOOT_EBADARGS; + } else if (hdr->ih_protect_tlv_size == 0) { + return BOOT_EBADIMAGE; + } + + if (!IS_ENCRYPTED(hdr)) { + /* Update is not encrypted so use size from header */ + *img_comp_size = hdr->ih_img_size; + } else { + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_COMP_DEC_SIZE, true); + + if (rc) { + return rc; + } + + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + + if (rc != 0) { + return -1; + } + + if (len != sizeof(*img_comp_size)) { + BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); + return BOOT_EBADIMAGE; + } + + rc = LOAD_IMAGE_DATA(hdr, fap, off, img_comp_size, len); + + if (rc) { + BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off, len, fap->fa_id, rc); + return BOOT_EFLASH; + } + } + + return 0; +} +#endif + +int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_header *hdr, + const struct flash_area *fap, uint8_t *tmp_buf, + uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len) +{ + int rc; + uint32_t read_pos = 0; + uint32_t write_pos = 0; + uint32_t protected_tlv_size = 0; + uint32_t decompressed_image_size; + uint32_t output_size_total = 0; + struct nrf_compress_implementation *compression_lzma = NULL; + struct nrf_compress_implementation *compression_arm_thumb = NULL; + TARGET_STATIC struct image_header modified_hdr; + bootutil_sha_context sha_ctx; + uint8_t flash_erased_value; + +#ifdef MCUBOOT_ENC_IMAGES + struct enc_key_data *enc_state; + int image_index; + uint32_t comp_size = 0; + + rc = bootutil_get_img_decrypted_comp_size(hdr, fap, &comp_size); + + if (rc) { + BOOT_LOG_ERR("Invalid/missing image decrypted compressed size value"); + rc = BOOT_EBADIMAGE; + goto finish_end; + } + + if (state == NULL) { + enc_state = NULL; + image_index = 0; + } else { + enc_state = BOOT_CURR_ENC(state); + image_index = BOOT_CURR_IMG(state); + } + + /* Encrypted images only exist in the secondary slot */ + if (MUST_DECRYPT(fap, image_index, hdr) && + !boot_enc_valid(enc_state, 1)) { + return -1; + } +#endif + + bootutil_sha_init(&sha_ctx); + + /* Setup decompression system */ +#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { +#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { +#endif + /* Compressed image does not use the correct compression type which is supported by this + * build + */ + BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); + rc = BOOT_EBADIMAGE; + goto finish_without_clean; + } + + compression_lzma = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + compression_arm_thumb = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_ARM_THUMB); + + if (!is_compression_object_valid(compression_lzma) || + !is_compression_object_valid(compression_arm_thumb)) { + /* Compression library missing or missing required function pointer */ + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + goto finish_without_clean; + } + + rc = compression_lzma->init(NULL); + rc = compression_arm_thumb->init(NULL); + + if (rc) { + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + goto finish_without_clean; + } + + /* We need a modified header which has the updated sizes, start with the original header */ + memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); + + /* Extract the decompressed image size from the protected TLV, set it and remove the + * compressed image flags + */ + rc = bootutil_get_img_decomp_size(hdr, fap, &decompressed_image_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; + modified_hdr.ih_img_size = decompressed_image_size; + + /* Calculate the protected TLV size, these will not include the decompressed + * sha/size/signature entries + */ + rc = boot_size_protected_tlvs(hdr, fap, &protected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + modified_hdr.ih_protect_tlv_size = protected_tlv_size; + bootutil_sha_update(&sha_ctx, &modified_hdr, sizeof(modified_hdr)); + read_pos = sizeof(modified_hdr); + flash_erased_value = flash_area_erased_val(fap); + memset(tmp_buf, flash_erased_value, tmp_buf_sz); + + while (read_pos < modified_hdr.ih_hdr_size) { + uint32_t copy_size = tmp_buf_sz; + + if ((read_pos + copy_size) > modified_hdr.ih_hdr_size) { + copy_size = modified_hdr.ih_hdr_size - read_pos; + } + + bootutil_sha_update(&sha_ctx, tmp_buf, copy_size); + read_pos += copy_size; + } + + /* Read in compressed data, decompress and add to hash calculation */ + read_pos = 0; + +#ifdef MCUBOOT_ENC_IMAGES + while (read_pos < comp_size) { + uint32_t copy_size = comp_size - read_pos; +#else + while (read_pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - read_pos; +#endif + uint32_t tmp_off = 0; + uint8_t offset_zero_check = 0; + + if (copy_size > tmp_buf_sz) { + copy_size = tmp_buf_sz; + } + + rc = flash_area_read(fap, (hdr->ih_hdr_size + read_pos), tmp_buf, copy_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (hdr->ih_hdr_size + read_pos), copy_size, fap->fa_id, rc); + rc = BOOT_EFLASH; + goto finish; + } + +#ifdef MCUBOOT_ENC_IMAGES + if (MUST_DECRYPT(fap, image_index, hdr)) { + boot_enc_decrypt(enc_state, 1, read_pos, + copy_size, (read_pos & 0xf), + tmp_buf); + } +#endif + + /* Decompress data in chunks, writing it back with a larger write offset of the primary + * slot than read size of the secondary slot + */ + while (tmp_off < copy_size) { + uint32_t offset = 0; + uint8_t *output = NULL; + uint32_t output_size = 0; + uint32_t chunk_size; + bool last_packet = false; + + chunk_size = compression_lzma->decompress_bytes_needed(NULL); + + if (chunk_size > (copy_size - tmp_off)) { + chunk_size = (copy_size - tmp_off); + } + +#ifdef MCUBOOT_ENC_IMAGES + if ((read_pos + tmp_off + chunk_size) >= comp_size) { +#else + if ((read_pos + tmp_off + chunk_size) >= hdr->ih_img_size) { +#endif + last_packet = true; + } + + rc = compression_lzma->decompress(NULL, &tmp_buf[tmp_off], chunk_size, last_packet, + &offset, &output, &output_size); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + goto finish; + } + + write_pos += output_size; + + if (write_pos > decompressed_image_size) { + BOOT_LOG_ERR("Decompressed image larger than claimed TLV size, at least: %d", + write_pos); + rc = BOOT_EBADIMAGE; + goto finish; + } + + /* Additional dry-run validity checks */ + if (last_packet == true && write_pos == 0) { + /* Last packet and we still have no output, this is a faulty update */ + BOOT_LOG_ERR("All compressed data consumed without any output, image not valid"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + if (offset == 0) { + /* If the decompression system continually consumes 0 bytes, then there is a + * problem with this update image, abort and mark image as bad + */ + if (offset_zero_check >= OFFSET_ZERO_CHECK_TIMES) { + BOOT_LOG_ERR("Decompression system returning no output data, image not valid"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + ++offset_zero_check; + + break; + } else { + offset_zero_check = 0; + } + + /* Copy data to secondary buffer for calculating hash */ + if (output_size > 0) { + if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { + /* Run this through the ARM thumb filter */ + uint32_t offset_arm_thumb = 0; + uint8_t *output_arm_thumb = NULL; + uint32_t processed_size = 0; + uint32_t output_size_arm_thumb = 0; + + while (processed_size < output_size) { + uint32_t current_size = output_size - processed_size; + bool arm_thumb_last_packet = false; + + if (current_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE) { + current_size = CONFIG_NRF_COMPRESS_CHUNK_SIZE; + } + + if (last_packet && (processed_size + current_size) == + output_size) { + arm_thumb_last_packet = true; + } + + rc = compression_arm_thumb->decompress(NULL, &output[processed_size], + current_size, arm_thumb_last_packet, + &offset_arm_thumb, + &output_arm_thumb, + &output_size_arm_thumb); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + goto finish; + } + + bootutil_sha_update(&sha_ctx, output_arm_thumb, output_size_arm_thumb); + output_size_total += output_size_arm_thumb; + processed_size += current_size; + } + } else { + bootutil_sha_update(&sha_ctx, output, output_size); + output_size_total += output_size; + } + } + + tmp_off += offset; + } + + read_pos += copy_size; + } + + if (modified_hdr.ih_img_size != output_size_total) { + BOOT_LOG_ERR("Decompression expected output_size mismatch: %d vs %d", + modified_hdr.ih_img_size, output_size_total); + rc = BOOT_EBADSTATUS; + goto finish; + } + + /* If there are any protected TLVs present, add them after the main decompressed image */ + if (modified_hdr.ih_protect_tlv_size > 0) { + rc = boot_sha_protected_tlvs(hdr, fap, modified_hdr.ih_protect_tlv_size, tmp_buf, + tmp_buf_sz, &sha_ctx); + } + + bootutil_sha_finish(&sha_ctx, hash_result); + +finish: + /* Clean up decompression system */ + (void)compression_lzma->deinit(NULL); + (void)compression_arm_thumb->deinit(NULL); + +finish_without_clean: + bootutil_sha_drop(&sha_ctx); + +#ifdef MCUBOOT_ENC_IMAGES +finish_end: +#endif + return rc; +} + +static int boot_copy_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_dst, + uint32_t protected_size, uint8_t *buf, size_t buf_size, + uint16_t *buf_pos, uint32_t *written) +{ + int rc; + uint32_t off; + uint32_t write_pos = 0; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, + .it_tlv_tot = protected_size, + }; + uint16_t info_size_left = sizeof(tlv_info_header); + + while (info_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (info_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; + + if (single_copy_size > info_size_left) { + single_copy_size = info_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - + info_size_left], single_copy_size); + *buf_pos += single_copy_size; + info_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { + /* Skip these TLVs as they are not needed */ + continue; + } else { + uint16_t header_size_left = sizeof(tlv_header); + uint16_t data_size_left = len; + + tlv_header.it_type = type; + tlv_header.it_len = len; + + while (header_size_left > 0 || data_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + uint8_t *tlv_header_address = (uint8_t *)&tlv_header; + + if (header_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > header_size_left) { + single_copy_size = header_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - + header_size_left], + single_copy_size); + *buf_pos += single_copy_size; + copy_size -= single_copy_size; + header_size_left -= single_copy_size; + } + + if (data_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > data_size_left) { + single_copy_size = data_size_left; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + (len - data_size_left)), + &buf[*buf_pos], single_copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); + goto out; + } + + *buf_pos += single_copy_size; + data_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + } + } + + *written = write_pos; + +out: + return rc; +} + +static int boot_sha_protected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, uint32_t protected_size, + uint8_t *buf, size_t buf_size, bootutil_sha_context *sha_ctx) +{ + int rc; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_PROT_INFO_MAGIC, + .it_tlv_tot = protected_size, + }; + + bootutil_sha_update(sha_ctx, &tlv_info_header, sizeof(tlv_info_header)); + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, true); + if (rc) { + goto out; + } + + while (true) { + uint32_t read_off = 0; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { + /* Skip these TLVs as they are not needed */ + continue; + } + + tlv_header.it_type = type; + tlv_header.it_len = len; + + bootutil_sha_update(sha_ctx, &tlv_header, sizeof(tlv_header)); + + while (read_off < len) { + uint32_t copy_size = buf_size; + + if (copy_size > (len - read_off)) { + copy_size = len - read_off; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + read_off), buf, copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + read_off), copy_size, fap_src->fa_id, rc); + goto out; + } + + bootutil_sha_update(sha_ctx, buf, copy_size); + read_off += copy_size; + } + } + +out: + return rc; +} + +int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *sz) +{ + int rc = 0; + uint32_t tlv_size; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + + *sz = 0; + tlv_size = hdr->ih_protect_tlv_size; + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + + if (type == IMAGE_TLV_DECOMP_SIZE || type == IMAGE_TLV_DECOMP_SHA || + type == IMAGE_TLV_DECOMP_SIGNATURE || type == IMAGE_TLV_COMP_DEC_SIZE) { + /* Exclude these TLVs as they will be copied to the unprotected area */ + tlv_size -= len + sizeof(struct image_tlv); + } + } + + if (!rc) { + if (tlv_size == sizeof(struct image_tlv_info)) { + /* If there are no entries then omit protected TLV section entirely */ + tlv_size = 0; + } + + *sz = tlv_size; + } + +out: + return rc; +} + +int boot_size_unprotected_tlvs(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *sz) +{ + int rc = 0; + uint32_t tlv_size; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + + *sz = 0; + tlv_size = sizeof(struct image_tlv_info); + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } else if (bootutil_tlv_iter_is_prot(&it, off) && type != IMAGE_TLV_DECOMP_SHA && + type != IMAGE_TLV_DECOMP_SIGNATURE) { + /* Include size of protected hash and signature as these will be replacing the + * original ones + */ + continue; + } else if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV || type == IMAGE_TLV_COMP_DEC_SIZE) { + /* Exclude the original unprotected TLVs for signature and hash, the length of the + * signature of the compressed data might not be the same size as the signaute of the + * decompressed data, as is the case when using ECDSA-P256 + */ + continue; + } + + tlv_size += len + sizeof(struct image_tlv); + } + + if (!rc) { + if (tlv_size == sizeof(struct image_tlv_info)) { + /* If there are no entries in the unprotected TLV section then there is something wrong + * with this image + */ + BOOT_LOG_ERR("No unprotected TLVs in post-decompressed image output, image is invalid"); + rc = BOOT_EBADIMAGE; + goto out; + } + + *sz = tlv_size; + } + +out: + return rc; +} + +static int boot_copy_unprotected_tlvs(const struct image_header *hdr, + const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_dst, + uint32_t unprotected_size, uint8_t *buf, size_t buf_size, + uint16_t *buf_pos, uint32_t *written) +{ + int rc; + uint32_t write_pos = 0; + uint32_t off; + uint16_t len; + uint16_t type; + struct image_tlv_iter it; + struct image_tlv_iter it_protected; + struct image_tlv tlv_header; + struct image_tlv_info tlv_info_header = { + .it_magic = IMAGE_TLV_INFO_MAGIC, + .it_tlv_tot = unprotected_size, + }; + uint16_t info_size_left = sizeof(tlv_info_header); + + while (info_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (info_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_info_header_address = (uint8_t *)&tlv_info_header; + + if (single_copy_size > info_size_left) { + single_copy_size = info_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_info_header_address[sizeof(tlv_info_header) - + info_size_left], single_copy_size); + *buf_pos += single_copy_size; + info_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap_src, IMAGE_TLV_ANY, false); + if (rc) { + goto out; + } + + while (true) { + uint16_t header_size_left = sizeof(tlv_header); + uint16_t data_size_left; + + rc = bootutil_tlv_iter_next(&it, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } else if (bootutil_tlv_iter_is_prot(&it, off)) { + /* Skip protected TLVs */ + continue; + } + + /* Change the values of these fields from having the data in the compressed image + * unprotected TLV (which is valid only for the compressed image data) to having the + * fields in the protected TLV section (which is valid for the decompressed image data). + * The compressed data is no longer needed + */ + if (type == EXPECTED_HASH_TLV || type == EXPECTED_SIG_TLV) { + rc = bootutil_tlv_iter_begin(&it_protected, hdr, fap_src, (type == EXPECTED_HASH_TLV ? + IMAGE_TLV_DECOMP_SHA : + IMAGE_TLV_DECOMP_SIGNATURE), + true); + + if (rc) { + goto out; + } + + while (true) { + rc = bootutil_tlv_iter_next(&it_protected, &off, &len, &type); + if (rc < 0) { + goto out; + } else if (rc > 0) { + rc = 0; + break; + } + } + + if (type == IMAGE_TLV_DECOMP_SHA) { + type = EXPECTED_HASH_TLV; + } else { + type = EXPECTED_SIG_TLV; + } + } + + data_size_left = len; + tlv_header.it_type = type; + tlv_header.it_len = len; + + while (header_size_left > 0 || data_size_left > 0) { + uint16_t copy_size = buf_size - *buf_pos; + + if (header_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + uint8_t *tlv_header_address = (uint8_t *)&tlv_header; + + if (single_copy_size > header_size_left) { + single_copy_size = header_size_left; + } + + memcpy(&buf[*buf_pos], &tlv_header_address[sizeof(tlv_header) - header_size_left], + single_copy_size); + *buf_pos += single_copy_size; + copy_size -= single_copy_size; + header_size_left -= single_copy_size; + } + + if (data_size_left > 0 && copy_size > 0) { + uint16_t single_copy_size = copy_size; + + if (single_copy_size > data_size_left) { + single_copy_size = data_size_left; + } + + rc = LOAD_IMAGE_DATA(hdr, fap_src, (off + len - data_size_left), + &buf[*buf_pos], single_copy_size); + + if (rc) { + BOOT_LOG_ERR( + "Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off + (len - data_size_left)), single_copy_size, fap_src->fa_id, rc); + goto out; + } + + *buf_pos += single_copy_size; + data_size_left -= single_copy_size; + } + + if (*buf_pos == buf_size) { + rc = flash_area_write(fap_dst, (off_dst + write_pos), buf, *buf_pos); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + write_pos), *buf_pos, fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto out; + } + + write_pos += *buf_pos; + *buf_pos = 0; + } + } + } + + *written = write_pos; + +out: + return rc; +} + +int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_src, + uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size) +{ + int rc; + uint32_t pos = 0; + uint16_t decomp_buf_size = 0; + uint16_t write_alignment; + uint32_t write_pos = 0; + uint32_t protected_tlv_size = 0; + uint32_t unprotected_tlv_size = 0; + uint32_t tlv_write_size = 0; + uint32_t decompressed_image_size; + struct nrf_compress_implementation *compression_lzma = NULL; + struct nrf_compress_implementation *compression_arm_thumb = NULL; + struct image_header *hdr; + TARGET_STATIC uint8_t decomp_buf[DECOMP_BUF_ALLOC_SIZE] __attribute__((aligned(4))); + TARGET_STATIC struct image_header modified_hdr; + +#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) + uint8_t excess_data_buffer[DECOMP_BUF_EXTRA_SIZE]; + bool excess_data_buffer_full = false; +#endif + +#ifdef MCUBOOT_ENC_IMAGES + uint32_t comp_size = 0; +#endif + + hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); + +#ifdef MCUBOOT_ENC_IMAGES + rc = bootutil_get_img_decrypted_comp_size(hdr, fap_src, &comp_size); + + if (rc) { + BOOT_LOG_ERR("Invalid/missing image decrypted compressed size value"); + rc = BOOT_EBADIMAGE; + goto finish; + } +#endif + + /* Setup decompression system */ +#if CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA1 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1)) { +#elif CONFIG_NRF_COMPRESS_LZMA_VERSION_LZMA2 + if (!(hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2)) { +#endif + /* Compressed image does not use the correct compression type which is supported by this + * build + */ + BOOT_LOG_ERR("Invalid image compression flags: no supported compression found"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + compression_lzma = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_LZMA); + compression_arm_thumb = nrf_compress_implementation_find(NRF_COMPRESS_TYPE_ARM_THUMB); + + if (!is_compression_object_valid(compression_lzma) || + !is_compression_object_valid(compression_arm_thumb)) { + /* Compression library missing or missing required function pointer */ + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + goto finish; + } + + rc = compression_lzma->init(NULL); + rc = compression_arm_thumb->init(NULL); + + if (rc) { + BOOT_LOG_ERR("Decompression library fatal error"); + rc = BOOT_EBADSTATUS; + goto finish; + } + + write_alignment = flash_area_align(fap_dst); + + memcpy(&modified_hdr, hdr, sizeof(modified_hdr)); + + rc = bootutil_get_img_decomp_size(hdr, fap_src, &decompressed_image_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine decompressed size of compressed image"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + modified_hdr.ih_flags &= ~COMPRESSIONFLAGS; + modified_hdr.ih_img_size = decompressed_image_size; + + /* Calculate protected TLV size for target image once items are removed */ + rc = boot_size_protected_tlvs(hdr, fap_src, &protected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine protected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + modified_hdr.ih_protect_tlv_size = protected_tlv_size; + + rc = boot_size_unprotected_tlvs(hdr, fap_src, &unprotected_tlv_size); + + if (rc) { + BOOT_LOG_ERR("Unable to determine unprotected TLV size of compressed image"); + rc = BOOT_EBADIMAGE; + goto finish; + } + + /* Write out the image header first, this should be a multiple of the write size */ + rc = flash_area_write(fap_dst, off_dst, &modified_hdr, sizeof(modified_hdr)); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off_dst, sizeof(modified_hdr), fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto finish; + } + + /* Read in, decompress and write out data */ +#ifdef MCUBOOT_ENC_IMAGES + while (pos < comp_size) { + uint32_t copy_size = comp_size - pos; +#else + while (pos < hdr->ih_img_size) { + uint32_t copy_size = hdr->ih_img_size - pos; +#endif + uint32_t tmp_off = 0; + + if (copy_size > buf_size) { + copy_size = buf_size; + } + + rc = flash_area_read(fap_src, off_src + hdr->ih_hdr_size + pos, buf, copy_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash read failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_src + hdr->ih_hdr_size + pos), copy_size, fap_src->fa_id, rc); + rc = BOOT_EFLASH; + goto finish; + } + +#ifdef MCUBOOT_ENC_IMAGES + if (IS_ENCRYPTED(hdr)) { + boot_enc_decrypt(BOOT_CURR_ENC(state), 1, pos, copy_size, (pos & 0xf), buf); + } +#endif + + /* Decompress data in chunks, writing it back with a larger write offset of the primary + * slot than read size of the secondary slot + */ + while (tmp_off < copy_size) { + uint32_t offset = 0; + uint32_t output_size = 0; + uint32_t chunk_size; + uint32_t compression_buffer_pos = 0; + uint8_t *output = NULL; + bool last_packet = false; + + chunk_size = compression_lzma->decompress_bytes_needed(NULL); + + if (chunk_size > (copy_size - tmp_off)) { + chunk_size = (copy_size - tmp_off); + } + +#ifdef MCUBOOT_ENC_IMAGES + if ((pos + tmp_off + chunk_size) >= comp_size) { +#else + if ((pos + tmp_off + chunk_size) >= hdr->ih_img_size) { +#endif + last_packet = true; + } + + rc = compression_lzma->decompress(NULL, &buf[tmp_off], chunk_size, last_packet, + &offset, &output, &output_size); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + goto finish; + } + + /* Copy data to secondary buffer for writing out */ + while (output_size > 0) { + uint32_t data_size = (DECOMP_BUF_SIZE - decomp_buf_size); + + if (data_size > output_size) { + data_size = output_size; + } + +#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) + if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { + memcpy(&decomp_buf[decomp_buf_size + DECOMP_BUF_EXTRA_SIZE], + &output[compression_buffer_pos], data_size); + } else +#endif + { + memcpy(&decomp_buf[decomp_buf_size], &output[compression_buffer_pos], + data_size); + } + + compression_buffer_pos += data_size; + + decomp_buf_size += data_size; + output_size -= data_size; + + /* Write data out from secondary buffer when it is full */ + if (decomp_buf_size == DECOMP_BUF_SIZE) { +#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) + if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT) { + uint32_t filter_writeback_pos = 0; + uint32_t processed_size = 0; + + /* Run this through the ARM thumb filter */ + while (processed_size < DECOMP_BUF_SIZE) { + uint32_t offset_arm_thumb = 0; + uint32_t output_size_arm_thumb = 0; + uint8_t *output_arm_thumb = NULL; + uint32_t current_size = DECOMP_BUF_SIZE; + bool arm_thumb_last_packet = false; + + if (current_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE) { + current_size = CONFIG_NRF_COMPRESS_CHUNK_SIZE; + } + + if (last_packet && (processed_size + current_size) == DECOMP_BUF_SIZE + && output_size == 0) { + arm_thumb_last_packet = true; + } + + rc = compression_arm_thumb->decompress(NULL, + &decomp_buf[processed_size + + DECOMP_BUF_EXTRA_SIZE], + current_size, + arm_thumb_last_packet, + &offset_arm_thumb, + &output_arm_thumb, + &output_size_arm_thumb); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + goto finish; + } + + memcpy(&decomp_buf[filter_writeback_pos], output_arm_thumb, + output_size_arm_thumb); + filter_writeback_pos += output_size_arm_thumb; + processed_size += current_size; + } + + if (excess_data_buffer_full == true) + { + /* Restore extra data removed from previous iteration to the write + * buffer + */ + memmove(&decomp_buf[DECOMP_BUF_EXTRA_SIZE], decomp_buf, + filter_writeback_pos); + memcpy(decomp_buf, excess_data_buffer, DECOMP_BUF_EXTRA_SIZE); + excess_data_buffer_full = false; + filter_writeback_pos += DECOMP_BUF_EXTRA_SIZE; + } + + if ((filter_writeback_pos % sizeof(uint32_t)) != 0) + { + /* Since there are an extra 2 bytes here, remove them and stash for + * later usage to prevent flash write issues with non-word boundary + * writes + */ + memcpy(excess_data_buffer, &decomp_buf[filter_writeback_pos - + DECOMP_BUF_EXTRA_SIZE], + DECOMP_BUF_EXTRA_SIZE); + excess_data_buffer_full = true; + filter_writeback_pos -= DECOMP_BUF_EXTRA_SIZE; + } + + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), + decomp_buf, filter_writeback_pos); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + hdr->ih_hdr_size + write_pos), DECOMP_BUF_SIZE, + fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto finish; + } + + write_pos += filter_writeback_pos; + decomp_buf_size = 0; + filter_writeback_pos = 0; + } else +#endif + { + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), + decomp_buf, DECOMP_BUF_SIZE); + + if (rc != 0) { + BOOT_LOG_ERR( + "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + hdr->ih_hdr_size + write_pos), DECOMP_BUF_SIZE, + fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto finish; + } + + write_pos += DECOMP_BUF_SIZE; + decomp_buf_size = 0; + } + } + } + + tmp_off += offset; + } + + pos += copy_size; + } + +#if defined(CONFIG_NRF_COMPRESS_ARM_THUMB) + if (hdr->ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT && decomp_buf_size > 0) { + /* Extra data that has not been written out that needs ARM thumb filter applied */ + uint32_t offset_arm_thumb = 0; + uint32_t output_size_arm_thumb = 0; + uint8_t *output_arm_thumb = NULL; + + rc = compression_arm_thumb->decompress(NULL, &decomp_buf[DECOMP_BUF_EXTRA_SIZE], + decomp_buf_size, true, &offset_arm_thumb, + &output_arm_thumb, &output_size_arm_thumb); + + if (rc) { + BOOT_LOG_ERR("Decompression error: %d", rc); + rc = BOOT_EBADSTATUS; + goto finish; + } + + memcpy(decomp_buf, output_arm_thumb, output_size_arm_thumb); + } +#endif + + /* Clean up decompression system */ + (void)compression_lzma->deinit(NULL); + (void)compression_arm_thumb->deinit(NULL); + + if (protected_tlv_size > 0) { + rc = boot_copy_protected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + + write_pos), protected_tlv_size, + decomp_buf, DECOMP_BUF_SIZE, &decomp_buf_size, + &tlv_write_size); + + if (rc) { + BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); + goto finish; + } + + write_pos += tlv_write_size; + } + + tlv_write_size = 0; + rc = boot_copy_unprotected_tlvs(hdr, fap_src, fap_dst, (off_dst + hdr->ih_hdr_size + + write_pos), unprotected_tlv_size, + decomp_buf, DECOMP_BUF_SIZE, &decomp_buf_size, + &tlv_write_size); + + if (rc) { + BOOT_LOG_ERR("Protected TLV copy failure: %d", rc); + goto finish; + } + + write_pos += tlv_write_size; + + /* Check if we have unwritten data buffered up and, if so, write it out */ + if (decomp_buf_size > 0) { + uint32_t write_padding_size = write_alignment - (decomp_buf_size % write_alignment); + + /* Check if additional write padding should be applied to meet the minimum write size */ + if (write_alignment > 1 && write_padding_size) { + uint8_t flash_erased_value; + + flash_erased_value = flash_area_erased_val(fap_dst); + memset(&decomp_buf[decomp_buf_size], flash_erased_value, write_padding_size); + decomp_buf_size += write_padding_size; + } + + rc = flash_area_write(fap_dst, (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf, + decomp_buf_size); + + if (rc != 0) { + BOOT_LOG_ERR("Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + (off_dst + hdr->ih_hdr_size + write_pos), decomp_buf_size, + fap_dst->fa_id, rc); + rc = BOOT_EFLASH; + goto finish; + } + + write_pos += decomp_buf_size; + decomp_buf_size = 0; + } + +finish: + memset(decomp_buf, 0, sizeof(decomp_buf)); + + return rc; +} + +int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *img_decomp_size) +{ + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + if (hdr == NULL || fap == NULL || img_decomp_size == NULL) { + return BOOT_EBADARGS; + } else if (hdr->ih_protect_tlv_size == 0) { + return BOOT_EBADIMAGE; + } + + rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIZE, true); + + if (rc) { + return rc; + } + + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + + if (rc != 0) { + return -1; + } + + if (len != sizeof(*img_decomp_size)) { + BOOT_LOG_ERR("Invalid decompressed image size TLV: %d", len); + return BOOT_EBADIMAGE; + } + + rc = LOAD_IMAGE_DATA(hdr, fap, off, img_decomp_size, len); + + if (rc) { + BOOT_LOG_ERR("Image data load failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d", + off, len, fap->fa_id, rc); + return BOOT_EFLASH; + } + + return 0; +} diff --git a/boot/zephyr/include/compression/decompression.h b/boot/zephyr/include/compression/decompression.h new file mode 100644 index 000000000..2104c4eb6 --- /dev/null +++ b/boot/zephyr/include/compression/decompression.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef H_DECOMPRESSION_ +#define H_DECOMPRESSION_ + +#include +#include +#include +#include "bootutil/bootutil.h" +#include "bootutil/bootutil_public.h" +#include "bootutil/image.h" +#include "../src/bootutil_priv.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Checks if a compressed image header is valid. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param state Bootloader state object. + * + * @return true if valid; false if invalid. + */ +bool boot_is_compressed_header_valid(const struct image_header *hdr, const struct flash_area *fap, + struct boot_loader_state *state); + +/** + * Reads in compressed image data from a slot, decompresses it and writes it out to a destination + * slot, including corresponding image headers and TLVs. + * + * @param state Bootloader state object. + * @param fap_src Flash area of the source slot. + * @param fap_dst Flash area of the destination slot. + * @param off_src Offset of the source slot to read from (should be 0). + * @param off_dst Offset of the destination slot to write to (should be 0). + * @param sz Size of the source slot data. + * @param buf Temporary buffer for reading data from. + * @param buf_size Size of temporary buffer. + * + * @return 0 on success; nonzero on failure. + */ +int boot_copy_region_decompress(struct boot_loader_state *state, const struct flash_area *fap_src, + const struct flash_area *fap_dst, uint32_t off_src, + uint32_t off_dst, uint32_t sz, uint8_t *buf, size_t buf_size); + +/** + * Gets the total data size (excluding headers and TLVs) of a compressed image when it is + * decompressed. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param img_decomp_size Pointer to variable that will be updated with the decompressed image + * size. + * + * @return 0 on success; nonzero on failure. + */ +int bootutil_get_img_decomp_size(const struct image_header *hdr, const struct flash_area *fap, + uint32_t *img_decomp_size); + +/** + * Calculate MCUboot-compatible image hash of compressed image slot. + * + * @param state MCUboot state. + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param tmp_buf Temporary buffer for reading data from. + * @param tmp_buf_sz Size of temporary buffer. + * @param hash_result Pointer to a variable that will be updated with the image hash. + * @param seed Not currently used, set to NULL. + * @param seed_len Not currently used, set to 0. + * + * @return 0 on success; nonzero on failure. + */ +int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_header *hdr, + const struct flash_area *fap, uint8_t *tmp_buf, + uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len); + +/** + * Calculates the size that the compressed image protected TLV section will occupy once the image + * has been decompressed. + * + * @param hdr Image header. + * @param fap Flash area of the slot. + * @param sz Pointer to variable that will be updated with the protected TLV size. + * + * @return 0 on success; nonzero on failure. + */ +int boot_size_protected_tlvs(const struct image_header *hdr, const struct flash_area *fap_src, + uint32_t *sz); + +#ifdef __cplusplus +} +#endif + +#endif /* H_DECOMPRESSION_ */ From c0e55426afb410f13019c50b5f6dd9d6d852d850 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 20 Sep 2024 16:34:00 +0000 Subject: [PATCH 188/204] [nrf noup] bootutil: Add support for KMU stored ED25519 signature key The commit adds verification of image using keys stored in KMU. Signed-off-by: Dominik Ermel (cherry picked from commit 2ae98d5637e2fae869744cd96066915a271d9070) --- boot/bootutil/src/ed25519_psa.c | 51 ++++++++++++++++++++++++++++++ boot/bootutil/src/image_ed25519.c | 9 +++++- boot/bootutil/src/image_validate.c | 12 +++++-- boot/zephyr/CMakeLists.txt | 2 +- boot/zephyr/Kconfig | 26 +++++++++++++++ 5 files changed, 96 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index 12ba20ac1..b6153f9a4 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -12,6 +12,9 @@ #include #include +#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) +#include +#endif BOOT_LOG_MODULE_REGISTER(ed25519_psa); @@ -19,6 +22,18 @@ BOOT_LOG_MODULE_REGISTER(ed25519_psa); #define EDDSA_KEY_LENGTH 32 #define EDDSA_SIGNAGURE_LENGTH 64 +#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) +/* List of KMU stored key ids available for MCUboot */ +#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id) +static psa_key_id_t kmu_key_ids[3] = { + MAKE_PSA_KMU_KEY_ID(226), + MAKE_PSA_KMU_KEY_ID(228), + MAKE_PSA_KMU_KEY_ID(230) +}; +#define KMU_KEY_COUNT (sizeof(kmu_key_ids)/sizeof(kmu_key_ids[0])) +#endif + +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], const uint8_t public_key[EDDSA_KEY_LENGTH]) @@ -69,3 +84,39 @@ int ED25519_verify(const uint8_t *message, size_t message_len, return ret; } +#else +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t public_key[EDDSA_KEY_LENGTH]) +{ + ARG_UNUSED(public_key); + /* Set to any error */ + psa_status_t status = PSA_ERROR_BAD_STATE; + int ret = 0; /* Fail by default */ + + /* Initialize PSA Crypto */ + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d", status); + return 0; + } + + status = PSA_ERROR_BAD_STATE; + + for (int i = 0; i < KMU_KEY_COUNT; ++i) { + psa_key_id_t kid = kmu_key_ids[i]; + + status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, + message_len, signature, + EDDSA_SIGNAGURE_LENGTH); + if (status == PSA_SUCCESS) { + ret = 1; + break; + } + + BOOT_LOG_ERR("ED25519 signature verification failed %d", status); + } + + return ret; +} +#endif diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index ffb8cec3b..d5aee65bc 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -31,6 +31,7 @@ extern int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[EDDSA_SIGNATURE_LENGTH], const uint8_t public_key[NUM_ED25519_BYTES]); +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #if !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) /* * Parse the public key used for signing. @@ -73,6 +74,7 @@ bootutil_import_key(uint8_t **cp, uint8_t *end) return 0; } #endif /* !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) */ +#endif /* Signature verification base function. * The function takes buffer of specified length and tries to verify @@ -87,14 +89,17 @@ bootutil_verify(uint8_t *buf, uint32_t blen, { int rc; FIH_DECLARE(fih_rc, FIH_FAILURE); - uint8_t *pubkey; + uint8_t *pubkey = NULL; +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) uint8_t *end; +#endif if (slen != EDDSA_SIGNATURE_LENGTH) { FIH_SET(fih_rc, FIH_FAILURE); goto out; } +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) pubkey = (uint8_t *)bootutil_keys[key_id].key; end = pubkey + *bootutil_keys[key_id].len; @@ -116,6 +121,8 @@ bootutil_verify(uint8_t *buf, uint32_t blen, } pubkey = end - NUM_ED25519_BYTES; +#endif + #endif rc = ED25519_verify(buf, blen, sig, pubkey); diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 40f0aa857..bb7aec148 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -280,6 +280,7 @@ bootutil_img_hash(struct boot_loader_state *state, # define KEY_BUF_SIZE (SIG_BUF_SIZE + 24) #endif /* !MCUBOOT_HW_KEY */ +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #if !defined(MCUBOOT_HW_KEY) static int bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len) @@ -345,6 +346,7 @@ bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len) } #endif /* !MCUBOOT_HW_KEY */ #endif /* !MCUBOOT_BUILTIN_KEY */ +#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */ #endif /* EXPECTED_SIG_TLV */ /** @@ -687,6 +689,7 @@ bootutil_img_validate(struct boot_loader_state *state, break; } #endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */ +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #ifdef EXPECTED_KEY_TLV case EXPECTED_KEY_TLV: { @@ -717,14 +720,17 @@ bootutil_img_validate(struct boot_loader_state *state, break; } #endif /* EXPECTED_KEY_TLV */ +#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */ #ifdef EXPECTED_SIG_TLV case EXPECTED_SIG_TLV: { +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) /* Ignore this signature if it is out of bounds. */ if (key_id < 0 || key_id >= bootutil_key_cnt) { key_id = -1; continue; } +#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */ if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { rc = -1; goto out; @@ -870,7 +876,7 @@ bootutil_img_validate(struct boot_loader_state *state, } #ifdef EXPECTED_SIG_TLV -#ifdef EXPECTED_KEY_TLV +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) && defined(EXPECTED_KEY_TLV) rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false); if (rc) { goto out; @@ -916,7 +922,7 @@ bootutil_img_validate(struct boot_loader_state *state, */ } } -#endif /* EXPECTED_KEY_TLV */ +#endif /* !CONFIG_BOOT_SIGNATURE_USING_KMU && EXPECTED_KEY_TLV */ rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true); if (rc) { @@ -939,10 +945,12 @@ bootutil_img_validate(struct boot_loader_state *state, if (type == IMAGE_TLV_DECOMP_SIGNATURE) { /* Ignore this signature if it is out of bounds. */ +#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) if (key_id < 0 || key_id >= bootutil_key_cnt) { key_id = -1; continue; } +#endif if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) { rc = -1; diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index b18c78934..7ca5c6e1d 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -341,7 +341,7 @@ if(CONFIG_MCUBOOT_SERIAL) endif() endif() -if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") +if(NOT CONFIG_BOOT_SIGNATURE_USING_KMU AND NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") # CONF_FILE points to the KConfig configuration files of the bootloader. foreach (filepath ${CONF_FILE}) file(READ ${filepath} temp_text) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 90a354d20..acbcf1a6a 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -328,6 +328,22 @@ endif endchoice +config BOOT_SIGNATURE_USING_KMU + bool "Use KMU stored keys for signature verification" + depends on NRF_SECURITY + depends on CRACEN_LIB_KMU + select PSA_WANT_ALG_GCM + select PSA_WANT_KEY_TYPE_AES + select PSA_WANT_AES_KEY_SIZE_256 + select PSA_WANT_ALG_SP800_108_COUNTER_CMAC + select PSA_WANT_ALG_CMAC + select PSA_WANT_ALG_ECB_NO_PADDING + help + MCUboot will use keys provisioned to the device key management unit for signature + verification instead of compiling in key data from a file. + +if !BOOT_SIGNATURE_USING_KMU + config BOOT_SIGNATURE_KEY_FILE string "PEM key file" default "root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256 @@ -345,6 +361,8 @@ config BOOT_SIGNATURE_KEY_FILE with the public key information will be written in a format expected by MCUboot. +endif + config MCUBOOT_CLEANUP_ARM_CORE bool "Perform core cleanup before chain-load the application" depends on CPU_CORTEX_M @@ -367,6 +385,14 @@ config MCUBOOT_CLEANUP_RAM help Sets contents of memory to 0 before jumping to application. +# Disable MBEDTLS from being selected if NRF_SECURITY is enabled, and use default NRF_SECURITY +# configuration file for MBEDTLS +config MBEDTLS + depends on !NRF_SECURITY + +config NRF_SECURITY + select MBEDTLS_PROMPTLESS + config MBEDTLS_CFG_FILE # It might be awkward to define an Mbed TLS header file when TinyCrypt # is used, but the fact is that Mbed TLS' ASN1 parse module is used From bc6a181dcc4a211a45b7323b75b3898a2a499012 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 7 Nov 2024 10:53:06 +0000 Subject: [PATCH 189/204] [nrf noup] boot: zephyr: Add experimental selection to compression Adds selecting the experimental Kconfig when compession is in use Signed-off-by: Jamie McCrae Signed-off-by: Dominik Ermel (cherry picked from commit 1c9556a24ee3952b649e366b9d399fb554f65ab3) --- boot/zephyr/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index acbcf1a6a..58cfb4ef4 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -1037,9 +1037,10 @@ config BOOT_DECOMPRESSION_SUPPORT if BOOT_DECOMPRESSION_SUPPORT menuconfig BOOT_DECOMPRESSION - bool "Decompression" + bool "Decompression [EXPERIMENTAL]" select NRF_COMPRESS_CLEANUP select PM_USE_CONFIG_SRAM_SIZE if SOC_NRF54L15_CPUAPP + select EXPERIMENTAL help If enabled, will include support for compressed images being loaded to the secondary slot which then get decompressed into the primary slot. This mode allows the secondary slot to From 4fa3bff8d56e57f6e828c1f3c2f7aecfc9ef1524 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 2 Dec 2024 10:51:41 +0000 Subject: [PATCH 190/204] [nrf noup] boot: bootutil: Allow configuring number of KMU keys Adds a new Kconfig CONFIG_BOOT_SIGNATURE_KMU_SLOTS which allows specifying how many KMU key IDs are supported, the default is set to 1 instead of 3 which was set before NCSDK-30743 Signed-off-by: Jamie McCrae (cherry picked from commit 59987a6aa2d4c95e6f02d6ec9f8f9af94ecd834d) --- boot/bootutil/src/ed25519_psa.c | 7 +++++-- boot/zephyr/Kconfig | 12 ++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index b6153f9a4..3e9cf2cbd 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -12,6 +12,7 @@ #include #include +#include #if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) #include #endif @@ -30,7 +31,9 @@ static psa_key_id_t kmu_key_ids[3] = { MAKE_PSA_KMU_KEY_ID(228), MAKE_PSA_KMU_KEY_ID(230) }; -#define KMU_KEY_COUNT (sizeof(kmu_key_ids)/sizeof(kmu_key_ids[0])) + +BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(kmu_key_ids), + "Invalid number of KMU slots, up to 3 are supported on nRF54L15"); #endif #if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) @@ -103,7 +106,7 @@ int ED25519_verify(const uint8_t *message, size_t message_len, status = PSA_ERROR_BAD_STATE; - for (int i = 0; i < KMU_KEY_COUNT; ++i) { + for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; ++i) { psa_key_id_t kid = kmu_key_ids[i]; status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 58cfb4ef4..584723997 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -342,6 +342,18 @@ config BOOT_SIGNATURE_USING_KMU MCUboot will use keys provisioned to the device key management unit for signature verification instead of compiling in key data from a file. +if BOOT_SIGNATURE_USING_KMU + +config BOOT_SIGNATURE_KMU_SLOTS + int "KMU key slots" + range 1 3 + default 1 + help + Selects the number of KMU key slots (also known as generations) to use when verifying + an image. + +endif + if !BOOT_SIGNATURE_USING_KMU config BOOT_SIGNATURE_KEY_FILE From ce12bdf1721f3d0dcd870308316852217885786f Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 14 Mar 2025 17:51:23 +0000 Subject: [PATCH 191/204] [nrf noup] zephyr: Use mbedTLS specific C functions with RSA Use snprinf, alloc, calloc and free from mbedTLS rather than from Zephyr. Signed-off-by: Dominik Ermel (cherry picked from commit 03d9b4fb8cac4232f61971c2961a40907a154eb4) --- boot/zephyr/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 584723997..86a5567b8 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -220,6 +220,8 @@ config BOOT_SIGNATURE_TYPE_RSA select MBEDTLS_PKCS1_V15 if MBEDTLS_BUILTIN select MBEDTLS_PKCS1_V21 if MBEDTLS_BUILTIN select MBEDTLS_KEY_EXCHANGE_RSA_ENABLED if MBEDTLS_BUILTIN + select MBEDTLS_PLATFORM_NO_STD_FUNCTIONS if MBEDTLS_BUILTIN + select MBEDTLS_PLATFORM_SNPRINTF_ALT if MBEDTLS_BUILTIN select BOOT_ENCRYPTION_SUPPORT select BOOT_IMG_HASH_ALG_SHA256_ALLOW select BOOT_AES_MBEDTLS_DEPENDENCIES if MBEDTLS_BUILTIN && BOOT_ENCRYPT_IMAGE From 3a19e629964f59f229cb0497e519f653dc71dfe8 Mon Sep 17 00:00:00 2001 From: Michal Kozikowski Date: Mon, 10 Mar 2025 17:23:37 +0100 Subject: [PATCH 192/204] [nrf noup] boot/zephyr: nrf54h20dk board support Added basic support for nrf54h20dk_nrf54h20_cpuapp_iron board. This commit turns off CONFIG_FPROTECT for this board build. Signed-off-by: Michal Kozikowski (cherry picked from commit 27d206562dad0d2f9bbbec9cab7b5ba6583a1496) --- boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf b/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf index 50d349255..63fd52e2d 100644 --- a/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf +++ b/boot/zephyr/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf @@ -6,6 +6,9 @@ # Ensure that the SPI NOR driver is disabled by default CONFIG_SPI_NOR=n +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + CONFIG_BOOT_WATCHDOG_FEED=n CONFIG_MULTITHREADING=y From eeced3fe5104a13a865f5fef7adec9eed9c604a1 Mon Sep 17 00:00:00 2001 From: Michal Kozikowski Date: Fri, 28 Mar 2025 17:46:28 +0100 Subject: [PATCH 193/204] [nrf noup] boot/zephyr: nrf54h20dk cleanup adaptations This commit removes NRF_CLOCK cleanup for this board build - for Lillium, there is no clock peripheral access from the app domain. Signed-off-by: Michal Kozikowski (cherry picked from commit b014be20f0a7d59ef0b67f6a278b7fbde91684f4) --- boot/zephyr/nrf_cleanup.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 051705ec9..72c601db3 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -4,7 +4,9 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ +#if !defined(CONFIG_SOC_SERIES_NRF54HX) #include +#endif #include #include #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) @@ -62,10 +64,12 @@ static NRF_UARTE_Type *nrf_uarte_to_clean[] = { }; #endif +#if !defined(CONFIG_SOC_SERIES_NRF54HX) static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); } +#endif void nrf_cleanup_peripheral(void) { @@ -109,7 +113,10 @@ void nrf_cleanup_peripheral(void) #if defined(NRF_DPPIC) nrf_dppi_channels_disable_all(NRF_DPPIC); #endif + +#if !defined(CONFIG_SOC_SERIES_NRF54HX) nrf_cleanup_clock(); +#endif } #if USE_PARTITION_MANAGER \ From d79dd4d9ca8680b8e4e361806bb6371e9fe8bcda Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 19 Mar 2025 18:01:43 +0000 Subject: [PATCH 194/204] [nrf noup] zephyr: Allow hash only for nrf54l devices nrf-squash! [nrf noup] zephyr: sdk-nrf specific overrides on PSA Kconfigs Allow hash only, instead of signature, for nrf54l when using PSA crypto. Signed-off-by: Dominik Ermel (cherry picked from commit d4f3b7dc7bd78b936c34469396e3e088b943a932) --- boot/zephyr/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 86a5567b8..79280974e 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -207,7 +207,8 @@ choice BOOT_SIGNATURE_TYPE config BOOT_SIGNATURE_TYPE_NONE bool "No signature; use only hash check" - select BOOT_USE_TINYCRYPT + select BOOT_USE_TINYCRYPT if !SOC_SERIES_NRF54LX + select BOOT_USE_PSA_CRYPTO if SOC_SERIES_NRF54LX select BOOT_IMG_HASH_ALG_SHA256_ALLOW config BOOT_SIGNATURE_TYPE_RSA From 640c33657f8b2e854bdd33a692b2a5fef9b991f5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 7 Mar 2025 10:02:40 +0000 Subject: [PATCH 195/204] [nrf noup] boot: bootutil: loader: Fix monotomic counter update issues nrf-squash! [nrf noup] boot/../loader: skip downgrade prevention for s1/s0 Fixes 4 issues with monotomic counter usage: 1. Where the NSIB update skipped the check but would then wrongly update the monotomic counter after 2. Where a network core update on nRF5340 used the monotonic counter which only supports a single image 3. Where an NSIB update used the monotonic counter which only supports a single image 4. Where security counter validation was wrongly performed on other images against the main image security counter Signed-off-by: Jamie McCrae (cherry picked from commit 3bd17963688423aa7a1e139ce54572fa2c7c700f) --- boot/bootutil/include/bootutil/security_cnt.h | 9 +++ boot/bootutil/src/image_validate.c | 20 ++++++ boot/bootutil/src/loader.c | 67 ++++++++++++++++++- 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/include/bootutil/security_cnt.h b/boot/bootutil/include/bootutil/security_cnt.h index e1562d2e9..7e1389618 100644 --- a/boot/bootutil/include/bootutil/security_cnt.h +++ b/boot/bootutil/include/bootutil/security_cnt.h @@ -39,6 +39,15 @@ extern "C" { */ fih_ret boot_nv_security_counter_init(void); +/** + * Checks if the specified image should have a security counter present on it or not + * + * @param image_index Index of the image to check (from 0). + * + * @return FIH_SUCCESS if security counter should be present; FIH_FAILURE if otherwise + */ +fih_ret boot_nv_image_should_have_security_counter(uint32_t image_index); + /** * Reads the stored value of a given image's security counter. * diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index bb7aec148..f7118e3e7 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -527,6 +527,15 @@ bootutil_img_validate(struct boot_loader_state *state, fih_int security_cnt = fih_int_encode(INT_MAX); uint32_t img_security_cnt = 0; FIH_DECLARE(security_counter_valid, FIH_FAILURE); + FIH_DECLARE(security_counter_should_be_present, FIH_FAILURE); + + FIH_CALL(boot_nv_image_should_have_security_counter, security_counter_should_be_present, + image_index); + if (FIH_NOT_EQ(security_counter_should_be_present, FIH_SUCCESS) && + FIH_NOT_EQ(security_counter_should_be_present, FIH_FAILURE)) { + rc = -1; + goto out; + } #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES @@ -773,6 +782,10 @@ bootutil_img_validate(struct boot_loader_state *state, goto out; } + if (FIH_EQ(security_counter_should_be_present, FIH_FAILURE)) { + goto skip_security_counter_read; + } + FIH_CALL(boot_nv_security_counter_get, fih_rc, image_index, &security_cnt); if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { @@ -792,6 +805,7 @@ bootutil_img_validate(struct boot_loader_state *state, /* The image's security counter has been successfully verified. */ security_counter_valid = fih_rc; +skip_security_counter_read: break; } #endif /* MCUBOOT_HW_ROLLBACK_PROT */ @@ -811,10 +825,16 @@ bootutil_img_validate(struct boot_loader_state *state, FIH_SET(fih_rc, valid_signature); #endif #ifdef MCUBOOT_HW_ROLLBACK_PROT + if (FIH_EQ(security_counter_should_be_present, FIH_FAILURE)) { + goto skip_security_counter_check; + } + if (FIH_NOT_EQ(security_counter_valid, FIH_SUCCESS)) { rc = -1; goto out; } + +skip_security_counter_check: #endif #ifdef MCUBOOT_DECOMPRESS_IMAGES diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 235f31325..388798e8c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -1296,6 +1296,38 @@ boot_validate_slot(struct boot_loader_state *state, int slot, } #ifdef MCUBOOT_HW_ROLLBACK_PROT +/** + * Checks if the specified image should have a security counter present on it or not + * + * @param image_index Index of the image to check. + * + * @return true if security counter should be present; false if otherwise + */ +fih_ret boot_nv_image_should_have_security_counter(uint32_t image_index) +{ +#if defined(PM_S1_ADDRESS) + if (owner_nsib[image_index]) { + /* + * Downgrade prevention on S0/S1 image is managed by NSIB, which is a software (not + * hardware) check + */ + return FIH_FAILURE; + } +#endif + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 + if (image_index == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { + /* + * Downgrade prevention on network core image is managed by NSIB which is a software (not + * hardware) check + */ + return FIH_FAILURE; + } +#endif + + return FIH_SUCCESS; +} + /** * Updates the stored security counter value with the image's security counter * value which resides in the given slot, only if it's greater than the stored @@ -1317,6 +1349,26 @@ boot_update_security_counter(struct boot_loader_state *state, int slot, int hdr_ uint32_t img_security_cnt; int rc; +#if defined(PM_S1_ADDRESS) + if (owner_nsib[BOOT_CURR_IMG(state)]) { + /* + * Downgrade prevention on S0/S1 image is managed by NSIB which is a software (not + * hardware) check + */ + return 0; + } +#endif + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { + /* + * Downgrade prevention on network core image is managed by NSIB which is a software (not + * hardware) check + */ + return 0; + } +#endif + fap = BOOT_IMG_AREA(state, slot); assert(fap != NULL); @@ -2683,7 +2735,20 @@ check_downgrade_prevention(struct boot_loader_state *state) #if defined(PM_S1_ADDRESS) if (owner_nsib[BOOT_CURR_IMG(state)]) { - /* Downgrade prevention on S0/S1 image is managed by NSIB */ + /* + * Downgrade prevention on S0/S1 image is managed by NSIB which is a software (not + * hardware) check + */ + return 0; + } +#endif + +#if defined(CONFIG_SOC_NRF5340_CPUAPP) && CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 + if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { + /* + * Downgrade prevention on network core image is managed by NSIB which is a software (not + * hardware) check + */ return 0; } #endif From 495616824be4cf697d9020f0797843ff6d4dd23b Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Mon, 17 Mar 2025 21:25:41 +0100 Subject: [PATCH 196/204] [nrf noup] bootutil: key revocation Disable previous generation key when update comes with new valid key and application is confirmed. Signed-off-by: Mateusz Michalek (cherry picked from commit 6df89a84be878d912dad5d7a5c6a9c82d2bdbab2) --- .../include/bootutil/key_revocation.h | 30 ++++++++++++++ boot/bootutil/src/ed25519_psa.c | 41 +++++++++++++++++++ boot/bootutil/src/key_revocation.c | 24 +++++++++++ boot/bootutil/src/loader.c | 15 +++++++ boot/zephyr/CMakeLists.txt | 6 +++ boot/zephyr/Kconfig | 12 ++++++ 6 files changed, 128 insertions(+) create mode 100644 boot/bootutil/include/bootutil/key_revocation.h create mode 100644 boot/bootutil/src/key_revocation.c diff --git a/boot/bootutil/include/bootutil/key_revocation.h b/boot/bootutil/include/bootutil/key_revocation.h new file mode 100644 index 000000000..d184c9579 --- /dev/null +++ b/boot/bootutil/include/bootutil/key_revocation.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef H_KEY_REVOCATION_ +#define H_KEY_REVOCATION_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOT_KEY_REVOKE_OK 0 +#define BOOT_KEY_REVOKE_NOT_READY 1 +#define BOOT_KEY_REVOKE_INVALID 2 +#define BOOT_KEY_REVOKE_FAILED 2 + + +void allow_revoke(void); + +int revoke(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index 3e9cf2cbd..c94d99e61 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -32,6 +32,11 @@ static psa_key_id_t kmu_key_ids[3] = { MAKE_PSA_KMU_KEY_ID(230) }; +#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) +#include +static psa_key_id_t *validated_with = NULL; +#endif + BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(kmu_key_ids), "Invalid number of KMU slots, up to 3 are supported on nRF54L15"); #endif @@ -114,6 +119,9 @@ int ED25519_verify(const uint8_t *message, size_t message_len, EDDSA_SIGNAGURE_LENGTH); if (status == PSA_SUCCESS) { ret = 1; +#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) + validated_with = kmu_key_ids + i; +#endif break; } @@ -122,4 +130,37 @@ int ED25519_verify(const uint8_t *message, size_t message_len, return ret; } +#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) +int exec_revoke(void) +{ + int ret = BOOT_KEY_REVOKE_OK; + psa_status_t status = psa_crypto_init(); + + if (!validated_with) { + ret = BOOT_KEY_REVOKE_INVALID; + goto out; + } + + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed with error %d", status); + ret = BOOT_KEY_REVOKE_FAILED; + goto out; + } + for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; i++) { + if ((kmu_key_ids + i) == validated_with) { + break; + } + BOOT_LOG_DBG("Invalidating key ID %d", i); + + status = psa_destroy_key(kmu_key_ids[i]); + if (status == PSA_SUCCESS) { + BOOT_LOG_DBG("Success on key ID %d", i); + } else { + BOOT_LOG_ERR("Key invalidation failed with: %d", status); + } + } +out: + return ret; +} +#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */ #endif diff --git a/boot/bootutil/src/key_revocation.c b/boot/bootutil/src/key_revocation.c new file mode 100644 index 000000000..0768a3188 --- /dev/null +++ b/boot/bootutil/src/key_revocation.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include + +extern int exec_revoke(void); + +static uint8_t ready_to_revoke; + +void allow_revoke(void) +{ + ready_to_revoke = 1; +} + +int revoke(void) +{ + if (ready_to_revoke) { + return exec_revoke(); + } + return BOOT_KEY_REVOKE_NOT_READY; +} diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 388798e8c..e6e0c8b14 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -77,6 +77,10 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr); #include "mcuboot_config/mcuboot_config.h" +#if defined(CONFIG_BOOT_KEYS_REVOCATION) +#include "bootutil/key_revocation.h" +#endif + BOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; @@ -2992,6 +2996,11 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } } +#if defined(CONFIG_BOOT_KEYS_REVOCATION) + if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) { + allow_revoke(); + } +#endif /* Iterate over all the images. At this point all required update operations * have finished. By the end of the loop each image in the primary slot will * have been re-validated. @@ -3097,6 +3106,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) fill_rsp(state, rsp); fih_rc = FIH_SUCCESS; +#if defined(CONFIG_BOOT_KEYS_REVOCATION) + rc = revoke(); + if (rc != BOOT_KEY_REVOKE_OK) { + FIH_SET(fih_rc, FIH_FAILURE); + } +#endif /* CONFIG_BOOT_KEYS_REVOCATION */ out: /* * Since the boot_status struct stores plaintext encryption keys, reset diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 7ca5c6e1d..84a4818d9 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -99,6 +99,12 @@ if(DEFINED CONFIG_BOOT_SHARE_BACKEND_RETENTION) ) endif() +if(DEFINED CONFIG_BOOT_KEYS_REVOCATION) + zephyr_library_sources( + ${BOOT_DIR}/bootutil/src/key_revocation.c +) +endif() + # Generic bootutil sources and includes. zephyr_library_include_directories(${BOOT_DIR}/bootutil/include) zephyr_library_sources( diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 79280974e..419866dc9 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -357,6 +357,18 @@ config BOOT_SIGNATURE_KMU_SLOTS endif +config BOOT_KEYS_REVOCATION + bool "Auto revoke previous gen key" + help + Automatically revoke previous generation key upon new valid key usage. + +config BOOT_KMU_KEYS_REVOCATION + bool + depends on BOOT_KEYS_REVOCATION + default y if BOOT_SIGNATURE_USING_KMU + help + Enabling KMU key revocation backend. + if !BOOT_SIGNATURE_USING_KMU config BOOT_SIGNATURE_KEY_FILE From 8eb3782e91dc448837dedf327cefcebe0989f86a Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 5 Mar 2024 18:44:13 +0100 Subject: [PATCH 197/204] [nrf noup] boot/zephyr/nrf_cleanup: cleanup uarte pins Added procedure which does configure UARTE pins to the default states. This allows to reduce power consumption if pin is floating. clean-up UARTE only if its driver was enabled Signed-off-by: Andrzej Puzdrowski (cherry picked from commit f134edd150992d0a951dcf294b6ffb840919bf1c) --- boot/zephyr/nrf_cleanup.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 72c601db3..1252334ca 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -9,6 +9,7 @@ #endif #include #include +#include #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif @@ -96,6 +97,21 @@ void nrf_cleanup_peripheral(void) nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); nrfy_uarte_disable(current); + uint32_t pin[4]; + + pin[0] = nrfy_uarte_tx_pin_get(current); + pin[1] = nrfy_uarte_rx_pin_get(current); + pin[2] = nrfy_uarte_rts_pin_get(current); + pin[3] = nrfy_uarte_cts_pin_get(current); + + nrfy_uarte_pins_disconnect(current); + + for (int j = 0; j < 4; j++) { + if (pin[j] != NRF_UARTE_PSEL_DISCONNECTED) { + nrfy_gpio_cfg_default(pin[i]); + } + } + #if defined(NRF_DPPIC) /* Clear all SUBSCRIBE configurations. */ memset((uint8_t *)current + NRF_UARTE_SUBSCRIBE_CONF_OFFS, 0, From 853a223626baaeaceb1439591f49daa9823a55bf Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 1 Apr 2025 19:30:57 +0200 Subject: [PATCH 198/204] [nrf noup] boot/zephyr/Kconfig: fix MBEDTLS_CFG_FILE value Zephyr provides "mcuboot-mbedtls-cfg.h" as glue interface for configure mbedts. "config-tls-generic.h" default value was erroneously introduced during a meta codebase synchronization. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 3aa07448fe8cf371e0cfb885132c347e485ab364) --- boot/zephyr/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 419866dc9..644c1b83c 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -425,7 +425,6 @@ config MBEDTLS_CFG_FILE # is used, but the fact is that Mbed TLS' ASN1 parse module is used # also when TinyCrypt is used as crypto backend. default "mcuboot-mbedtls-cfg.h" if BOOT_USE_TINYCRYPT - default "config-tls-generic.h" if NRF_SECURITY && (MBEDTLS_BUILTIN || BOOT_USE_PSA_CRYPTO) default "mcuboot-mbedtls-cfg.h" if BOOT_USE_MBEDTLS && !MBEDTLS_BUILTIN config BOOT_HW_KEY From f540b9900fda28b9453cc5e1edc2f309c27ef88a Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Fri, 11 Apr 2025 12:55:00 +0200 Subject: [PATCH 199/204] [nrf noup] nrf_cleanup: nRF54l: disable cleanup on UARTE pins Compile out code which does cleanup on UARTE pins as this cause issues on for some applications. ref.: NCSDK-33039 Signed-off-by: Andrzej Puzdrowski (cherry picked from commit 81e6fc3041d028000bcc97ec99d1290cf6c172b6) --- boot/zephyr/nrf_cleanup.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index 1252334ca..f90a46af1 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -97,6 +97,12 @@ void nrf_cleanup_peripheral(void) nrfy_uarte_event_clear(current, NRF_UARTE_EVENT_RXTO); nrfy_uarte_disable(current); +#ifndef CONFIG_SOC_SERIES_NRF54LX + /* Disconnect pins UARTE pins + * causes issues on nRF54l SoCs, + * could be enabled once fix to NCSDK-33039 will be implemented. + */ + uint32_t pin[4]; pin[0] = nrfy_uarte_tx_pin_get(current); @@ -111,6 +117,7 @@ void nrf_cleanup_peripheral(void) nrfy_gpio_cfg_default(pin[i]); } } +#endif #if defined(NRF_DPPIC) /* Clear all SUBSCRIBE configurations. */ From 95409440d3fdd2b111a64975636c90a145133c56 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 22 Apr 2025 12:11:29 +0100 Subject: [PATCH 200/204] [nrf noup] zephyr: Fix issue with unpadded encrypted updates nrf-squash! zephyr: Add support for compressed image updates Fixes an issue whereby compressed encrypted update images were not padded and the final part of decryption would fail due to not being a length of the block size Signed-off-by: Jamie McCrae (cherry picked from commit 3443eae6a2dd630bd9b9e3ac2c784312b69c7e2f) --- boot/zephyr/decompression.c | 50 ++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/boot/zephyr/decompression.c b/boot/zephyr/decompression.c index f49898d55..01810dcf8 100644 --- a/boot/zephyr/decompression.c +++ b/boot/zephyr/decompression.c @@ -37,6 +37,9 @@ #endif #define DECOMP_BUF_ALLOC_SIZE (DECOMP_BUF_SIZE + DECOMP_BUF_EXTRA_SIZE) +#define DECRYPTION_BLOCK_SIZE_AES128 16 +#define DECRYPTION_BLOCK_SIZE_AES256 32 + /* Number of times that consumed data by decompression system can be 0 in a row before aborting */ #define OFFSET_ZERO_CHECK_TIMES 3 @@ -187,6 +190,7 @@ int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_h struct enc_key_data *enc_state; int image_index; uint32_t comp_size = 0; + uint8_t decryption_block_size = 0; rc = bootutil_get_img_decrypted_comp_size(hdr, fap, &comp_size); @@ -209,6 +213,18 @@ int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_h !boot_enc_valid(enc_state, 1)) { return -1; } + + if (MUST_DECRYPT(fap, image_index, hdr)) { + if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) { + decryption_block_size = DECRYPTION_BLOCK_SIZE_AES128; + } else if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256) { + decryption_block_size = DECRYPTION_BLOCK_SIZE_AES256; + } else { + LOG_ERR("Unknown decryption block size"); + rc = BOOT_EBADIMAGE; + goto finish_end; + } + } #endif bootutil_sha_init(&sha_ctx); @@ -319,11 +335,17 @@ int bootutil_img_hash_decompress(struct boot_loader_state *state, struct image_h } #ifdef MCUBOOT_ENC_IMAGES - if (MUST_DECRYPT(fap, image_index, hdr)) { - boot_enc_decrypt(enc_state, 1, read_pos, - copy_size, (read_pos & 0xf), - tmp_buf); - } + if (MUST_DECRYPT(fap, image_index, hdr)) { + uint8_t dummy_bytes = 0; + + if ((copy_size % decryption_block_size)) { + dummy_bytes = decryption_block_size - (copy_size % decryption_block_size); + memset(&tmp_buf[copy_size], 0x00, dummy_bytes); + } + + boot_enc_decrypt(enc_state, 1, read_pos, (copy_size + dummy_bytes), (read_pos & 0xf), + tmp_buf); + } #endif /* Decompress data in chunks, writing it back with a larger write offset of the primary @@ -990,6 +1012,7 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl #ifdef MCUBOOT_ENC_IMAGES uint32_t comp_size = 0; + uint8_t decryption_block_size = 0; #endif hdr = boot_img_hdr(state, BOOT_SECONDARY_SLOT); @@ -1002,6 +1025,14 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl rc = BOOT_EBADIMAGE; goto finish; } + + if (IS_ENCRYPTED(hdr)) { + if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) { + decryption_block_size = DECRYPTION_BLOCK_SIZE_AES128; + } else if (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256) { + decryption_block_size = DECRYPTION_BLOCK_SIZE_AES256; + } + } #endif /* Setup decompression system */ @@ -1107,7 +1138,14 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(hdr)) { - boot_enc_decrypt(BOOT_CURR_ENC(state), 1, pos, copy_size, (pos & 0xf), buf); + uint8_t dummy_bytes = 0; + + if ((copy_size % decryption_block_size)) { + dummy_bytes = decryption_block_size - (copy_size % decryption_block_size); + memset(&buf[copy_size], 0x00, dummy_bytes); + } + + boot_enc_decrypt(BOOT_CURR_ENC(state), 1, pos, (copy_size + dummy_bytes), (pos & 0xf), buf); } #endif From 81b203976dace105bec653d4ad862b589a707bc0 Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Wed, 23 Apr 2025 09:05:24 +0200 Subject: [PATCH 201/204] [nrf noup] boot: zephyr: boards: nrf54lm20apdk adding default configs. Signed-off-by: Mateusz Michalek (cherry picked from commit ec525371393e9aa5985d918eae3e4679776fbd19) --- .../boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf diff --git a/boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf b/boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf new file mode 100644 index 000000000..4944f7b13 --- /dev/null +++ b/boot/zephyr/boards/nrf54lm20apdk_nrf54lm20a_cpuapp.conf @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# Ensure that the SPI NOR driver is disabled by default +CONFIG_SPI_NOR=n + +# TODO: below are not yet supported and need fixing +CONFIG_FPROTECT=n + +CONFIG_BOOT_WATCHDOG_FEED=n + +CONFIG_PSA_CRYPTO_DRIVER_CRACEN=n +CONFIG_PSA_CRYPTO_DRIVER_OBERON=y From 9ee3c52b9a5199c6c22de0d8e01a282ec7c3f363 Mon Sep 17 00:00:00 2001 From: Mateusz Michalek Date: Wed, 23 Apr 2025 19:20:29 +0200 Subject: [PATCH 202/204] [nrf noup] boot: bootutil: key revocation fix adds missing valid return state in key revocation procedure. nrf-squash! [nrf noup] bootutil: key revocation Signed-off-by: Mateusz Michalek (cherry picked from commit 85ed722d00dc4e60804b34a066f642d80a6bc67f) --- boot/bootutil/src/loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index e6e0c8b14..ff6a5d15a 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -3108,7 +3108,8 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) fih_rc = FIH_SUCCESS; #if defined(CONFIG_BOOT_KEYS_REVOCATION) rc = revoke(); - if (rc != BOOT_KEY_REVOKE_OK) { + if (rc != BOOT_KEY_REVOKE_OK && + rc != BOOT_KEY_REVOKE_NOT_READY) { FIH_SET(fih_rc, FIH_FAILURE); } #endif /* CONFIG_BOOT_KEYS_REVOCATION */ From 41c13118563b0388a4e749baa6d10240b66250c4 Mon Sep 17 00:00:00 2001 From: Artur Hadasz Date: Mon, 28 Apr 2025 14:17:35 +0200 Subject: [PATCH 203/204] [nrf noup] nrf_cleanup: nRF54h: fix missing peripheral cleanup This commit adds cleanup for GRTC and UARTE peripherals. ref: NCSDK-32966 Signed-off-by: Artur Hadasz (cherry picked from commit 9d9d524407df6da0815c79c5b9cf645f1ce25592) --- boot/zephyr/nrf_cleanup.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/boot/zephyr/nrf_cleanup.c b/boot/zephyr/nrf_cleanup.c index f90a46af1..39dfcbc41 100644 --- a/boot/zephyr/nrf_cleanup.c +++ b/boot/zephyr/nrf_cleanup.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ -#if !defined(CONFIG_SOC_SERIES_NRF54HX) +#if defined(CONFIG_NRFX_CLOCK) #include #endif #include @@ -13,6 +13,9 @@ #if defined(NRF_RTC0) || defined(NRF_RTC1) || defined(NRF_RTC2) #include #endif +#if defined(CONFIG_NRF_GRTC_TIMER) + #include +#endif #if defined(NRF_PPI) #include #endif @@ -48,6 +51,13 @@ static inline void nrf_cleanup_rtc(NRF_RTC_Type * rtc_reg) } #endif +#if defined(CONFIG_NRF_GRTC_TIMER) +static inline void nrf_cleanup_grtc(void) +{ + nrfx_grtc_uninit(); +} +#endif + #if defined(NRF_UARTE_CLEANUP) static NRF_UARTE_Type *nrf_uarte_to_clean[] = { #if defined(NRF_UARTE0) @@ -62,10 +72,13 @@ static NRF_UARTE_Type *nrf_uarte_to_clean[] = { #if defined(NRF_UARTE30) NRF_UARTE30, #endif +#if defined(NRF_UARTE136) + NRF_UARTE136, +#endif }; #endif -#if !defined(CONFIG_SOC_SERIES_NRF54HX) +#if defined(CONFIG_NRFX_CLOCK) static void nrf_cleanup_clock(void) { nrf_clock_int_disable(NRF_CLOCK, 0xFFFFFFFF); @@ -84,6 +97,10 @@ void nrf_cleanup_peripheral(void) nrf_cleanup_rtc(NRF_RTC2); #endif +#if defined(CONFIG_NRF_GRTC_TIMER) + nrf_cleanup_grtc(); +#endif + #if defined(NRF_UARTE_CLEANUP) for (int i = 0; i < sizeof(nrf_uarte_to_clean) / sizeof(nrf_uarte_to_clean[0]); ++i) { NRF_UARTE_Type *current = nrf_uarte_to_clean[i]; @@ -137,7 +154,7 @@ void nrf_cleanup_peripheral(void) nrf_dppi_channels_disable_all(NRF_DPPIC); #endif -#if !defined(CONFIG_SOC_SERIES_NRF54HX) +#if defined(CONFIG_NRFX_CLOCK) nrf_cleanup_clock(); #endif } From 7bdc0e1ebfd84bdbb06dd282e10deae3394442f2 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 2 May 2025 08:35:12 +0100 Subject: [PATCH 204/204] [nrf noup] boot: bootutil: swap_nsib: Update erase function nrf-squash! [nrf noup] treewide: Add support for sysbuild assigned images Updates the erase function as per upmerge changes Signed-off-by: Jamie McCrae --- boot/bootutil/src/swap_nsib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boot/bootutil/src/swap_nsib.c b/boot/bootutil/src/swap_nsib.c index 39ed4c652..410826c19 100644 --- a/boot/bootutil/src/swap_nsib.c +++ b/boot/bootutil/src/swap_nsib.c @@ -53,16 +53,16 @@ void nsib_swap_run(struct boot_loader_state *state, struct boot_status *bs) rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(image_index), &fap_sec); assert (rc == 0); - rc = boot_erase_region(fap_pri, 0, fap_pri->fa_size); + rc = boot_erase_region(fap_pri, 0, fap_pri->fa_size, false); assert(rc == 0); rc = boot_copy_region(state, fap_sec, fap_pri, 0, 0, fap_pri->fa_size); assert(rc == 0); - rc = swap_erase_trailer_sectors(state, fap_sec); + rc = swap_scramble_trailer_sectors(state, fap_sec); assert(rc == 0); - rc = boot_erase_region(fap_sec, 0, MIN((fap_pri->fa_size + sector_sz), fap_sec->fa_size)); + rc = boot_erase_region(fap_sec, 0, MIN((fap_pri->fa_size + sector_sz), fap_sec->fa_size), false); assert(rc == 0); flash_area_close(fap_pri);