Skip to content

Commit 54856cf

Browse files
committed
[nrf noup] boot/bootutil/loader: image discovery by ih_load_address
Align all image's matching exercises to MCUBOOT_CHECK_HEADER_LOAD_ADDRES. This method uses ih_load_address field of the image header instead of reset vector address. This allows to match incoming image to the partition even when it is for instance encrypted, as the image header is always plain-text. Firmware need to be signed with imgtool.py sign --rom-fixed <partition_address> parameter in order to involve this feature. ref.: NCSIDB-1173 Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
1 parent d2b3671 commit 54856cf

1 file changed

Lines changed: 32 additions & 26 deletions

File tree

boot/bootutil/src/loader.c

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,43 +1043,49 @@ boot_validated_swap_type(struct boot_loader_state *state,
10431043
#if defined(MCUBOOT_IS_SECOND_STAGE) || CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1
10441044
const struct flash_area *secondary_fa = BOOT_IMG_AREA(state, BOOT_SLOT_SECONDARY);
10451045
struct image_header *hdr = boot_img_hdr(state, BOOT_SLOT_SECONDARY);
1046-
uint32_t reset_addr = 0;
1046+
uint32_t internal_img_addr = 0;
10471047
int rc = 0;
10481048
/* Patch needed for NCS. Since image 0 (the app) and image 1 (the other
10491049
* B1 slot S0 or S1) share the same secondary slot, we need to check
10501050
* whether the update candidate in the secondary slot is intended for
1051-
* image 0 or image 1 primary by looking at the address of the reset
1052-
* vector. Note that there are good reasons for not using img_num from
1053-
* the swap info.
1051+
* image 0 or image 1 primary. With MCUBOOT_CHECK_HEADER_LOAD_ADDRESS the
1052+
* image header load address is used; otherwise the reset vector is read
1053+
* from the image. Note that there are good reasons for not using img_num
1054+
* from the swap info.
10541055
*/
10551056
NSIB_OWNED_UNSET(BOOT_CURR_IMG(state));
10561057

10571058
if (hdr->ih_magic == IMAGE_MAGIC) {
1058-
rc = flash_area_read(secondary_fa, hdr->ih_hdr_size +
1059-
sizeof(uint32_t), &reset_addr,
1060-
sizeof(reset_addr));
1059+
#ifdef MCUBOOT_CHECK_HEADER_LOAD_ADDRESS
1060+
internal_img_addr = hdr->ih_load_addr;
1061+
#else
1062+
rc = flash_area_read(secondary_fa, hdr->ih_hdr_size + RESET_OFFSET,
1063+
&internal_img_addr, sizeof(internal_img_addr));
10611064
if (rc != 0) {
10621065
return BOOT_SWAP_TYPE_FAIL;
10631066
}
1067+
#endif
1068+
1069+
BOOT_LOG_DBG("boot_validated_swap_type: image %d addr 0x%x",
1070+
BOOT_CURR_IMG(state), internal_img_addr);
10641071

10651072
sec_slot_touch(state);
10661073

10671074
#ifdef MCUBOOT_IS_SECOND_STAGE
10681075
#if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1
1069-
if(!(reset_addr >= NETCPU_APP_SLOT_OFFSET && reset_addr < NETCPU_APP_SLOT_END))
1076+
if (!(internal_img_addr >= NETCPU_APP_SLOT_OFFSET &&
1077+
internal_img_addr < NETCPU_APP_SLOT_END))
10701078
#endif
10711079
{
1072-
const struct flash_area *primary_fa;
1073-
rc = flash_area_open(flash_area_id_from_multi_image_slot(
1074-
BOOT_CURR_IMG(state),
1075-
BOOT_SLOT_PRIMARY),
1076-
&primary_fa);
1077-
if (rc != 0) {
1078-
return BOOT_SWAP_TYPE_FAIL;
1079-
}
1080+
const struct flash_area *primary_fa =
1081+
BOOT_IMG_AREA(state, BOOT_SLOT_PRIMARY);
1082+
const uint32_t pri_off = flash_area_get_off(primary_fa);
1083+
const uint32_t pri_end = pri_off + flash_area_get_size(primary_fa);
1084+
10801085
/* Check start and end of primary slot for current image */
1081-
if (reset_addr >= SECOND_STAGE_INACTIVE_MCUBOOT_OFFSET &&
1082-
reset_addr <= (SECOND_STAGE_INACTIVE_MCUBOOT_OFFSET + SECOND_STAGE_INACTIVE_MCUBOOT_SIZE)) {
1086+
if (internal_img_addr >= SECOND_STAGE_INACTIVE_MCUBOOT_OFFSET &&
1087+
internal_img_addr < (SECOND_STAGE_INACTIVE_MCUBOOT_OFFSET +
1088+
SECOND_STAGE_INACTIVE_MCUBOOT_SIZE)) {
10831089
if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) {
10841090
/* This is not the s0/s1 upgrade image but the application image, pretend
10851091
* there is no image so the NSIB update can be loaded
@@ -1088,21 +1094,21 @@ boot_validated_swap_type(struct boot_loader_state *state,
10881094
}
10891095

10901096
NSIB_OWNED_SET(BOOT_CURR_IMG(state));
1091-
} else if (reset_addr >= SECOND_STAGE_ACTIVE_MCUBOOT_OFFSET &&
1092-
reset_addr <= (SECOND_STAGE_ACTIVE_MCUBOOT_OFFSET + SECOND_STAGE_ACTIVE_MCUBOOT_SIZE)) {
1097+
} else if (internal_img_addr >= SECOND_STAGE_ACTIVE_MCUBOOT_OFFSET &&
1098+
internal_img_addr < (SECOND_STAGE_ACTIVE_MCUBOOT_OFFSET +
1099+
SECOND_STAGE_ACTIVE_MCUBOOT_SIZE)) {
10931100
/* NSIB upgrade but for the wrong slot, must be erased */
10941101
BOOT_LOG_ERR("Image in slot is for wrong s0/s1 image");
1095-
flash_area_erase(secondary_fa, 0, secondary_fa->fa_size);
10961102
sec_slot_untouch(state);
10971103
BOOT_LOG_ERR("Cleaned-up secondary slot of image %d", BOOT_CURR_IMG(state));
10981104
return BOOT_SWAP_TYPE_FAIL;
1099-
} else if (reset_addr < primary_fa->fa_off || reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) {
1105+
} else if (internal_img_addr < pri_off || internal_img_addr >= pri_end) {
11001106
/* The image in the secondary slot is not intended for any */
11011107
return BOOT_SWAP_TYPE_NONE;
11021108
}
11031109

1104-
if ((primary_fa->fa_off == SECOND_STAGE_ACTIVE_MCUBOOT_OFFSET) ||
1105-
(primary_fa->fa_off == SECOND_STAGE_INACTIVE_MCUBOOT_OFFSET)) {
1110+
if ((pri_off == SECOND_STAGE_ACTIVE_MCUBOOT_OFFSET) ||
1111+
(pri_off == SECOND_STAGE_INACTIVE_MCUBOOT_OFFSET)) {
11061112
NSIB_OWNED_SET(BOOT_CURR_IMG(state));
11071113
}
11081114
}
@@ -1134,8 +1140,8 @@ boot_validated_swap_type(struct boot_loader_state *state,
11341140
* update and indicate to the caller of this function that no update is
11351141
* available
11361142
*/
1137-
if (upgrade_valid && reset_addr >= NETCPU_APP_SLOT_OFFSET &&
1138-
reset_addr < NETCPU_APP_SLOT_END) {
1143+
if (upgrade_valid && internal_img_addr >= NETCPU_APP_SLOT_OFFSET &&
1144+
internal_img_addr < NETCPU_APP_SLOT_END) {
11391145
struct image_header *hdr = (struct image_header *)secondary_fa->fa_off;
11401146
uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size;
11411147
uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr);

0 commit comments

Comments
 (0)