diff --git a/boot/boot_serial/include/boot_serial/boot_serial_encryption.h b/boot/boot_serial/include/boot_serial/boot_serial_encryption.h index 890f0cb1..9e0cc202 100644 --- a/boot/boot_serial/include/boot_serial/boot_serial_encryption.h +++ b/boot/boot_serial/include/boot_serial/boot_serial_encryption.h @@ -11,6 +11,7 @@ /** * Validate hash of a primary boot image doing on the fly decryption as well * + * @param[in] state bootloader state * @param[in] fa_p flash area pointer * @param[in] hdr boot image header pointer * @param[in] buf buffer which is used for validating data @@ -20,7 +21,8 @@ * @return FIH_SUCCESS on success, error code otherwise */ fih_ret -boot_image_validate_encrypted(const struct flash_area *fa_p, +boot_image_validate_encrypted(struct boot_loader_state *state, + const struct flash_area *fa_p, struct image_header *hdr, uint8_t *buf, uint16_t buf_size #ifdef MCUBOOT_SWAP_USING_OFFSET diff --git a/boot/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c index fd1871b5..61fd547b 100644 --- a/boot/boot_serial/src/boot_serial.c +++ b/boot/boot_serial/src/boot_serial.c @@ -288,7 +288,7 @@ bs_list_img_ver(char *dst, int maxlen, struct image_version *ver) * List images. */ static void -bs_list(char *buf, int len) +bs_list(struct boot_loader_state *state, char *buf, int len) { struct image_header hdr; uint32_t slot, area_id; @@ -301,11 +301,13 @@ bs_list(char *buf, int len) zcbor_map_start_encode(cbor_state, 1); zcbor_tstr_put_lit_cast(cbor_state, "images"); zcbor_list_start_encode(cbor_state, 5); - image_index = 0; - IMAGES_ITER(image_index) { + + IMAGES_ITER(BOOT_CURR_IMG(state)) { #if defined(MCUBOOT_SERIAL_IMG_GRP_IMAGE_STATE) || defined(MCUBOOT_SWAP_USING_OFFSET) - int swap_status = boot_swap_type_multi(image_index); + int swap_status = boot_swap_type_multi(BOOT_CURR_IMG(state)); #endif + image_index = BOOT_CURR_IMG(state); + (void) image_index; /* Might be unused depending on the configuration */ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) { FIH_DECLARE(fih_rc, FIH_FAILURE); @@ -367,10 +369,10 @@ bs_list(char *buf, int len) #if !defined(MCUBOOT_SINGLE_APPLICATION_SLOT) if (IS_ENCRYPTED(&hdr) && MUST_DECRYPT(fap, image_index, &hdr)) { #ifdef MCUBOOT_SWAP_USING_OFFSET - FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + FIH_CALL(boot_image_validate_encrypted, fih_rc, state, fap, &hdr, tmpbuf, sizeof(tmpbuf), start_off); #else - FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + FIH_CALL(boot_image_validate_encrypted, fih_rc, state, fap, &hdr, tmpbuf, sizeof(tmpbuf)); #endif } else { @@ -386,10 +388,10 @@ bs_list(char *buf, int len) #endif #ifdef MCUBOOT_SWAP_USING_OFFSET - FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, + FIH_CALL(bootutil_img_validate, fih_rc, state, &hdr, fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL, start_off); #else - FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, + FIH_CALL(bootutil_img_validate, fih_rc, state, &hdr, fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL); #endif #if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_SINGLE_APPLICATION_SLOT) @@ -501,7 +503,7 @@ bs_list(char *buf, int len) * Set image state. */ static void -bs_set(char *buf, int len) +bs_set(struct boot_loader_state *state, char *buf, int len) { /* * Expected data format. @@ -550,10 +552,12 @@ bs_set(char *buf, int len) } if (img_hash.len != 0) { - IMAGES_ITER(image_index) { + IMAGES_ITER(BOOT_CURR_IMG(state)) { #ifdef MCUBOOT_SWAP_USING_OFFSET - int swap_status = boot_swap_type_multi(image_index); + int swap_status = boot_swap_type_multi(BOOT_CURR_IMG(state)); #endif + image_index = BOOT_CURR_IMG(state); + (void) image_index; /* Might be unused depending on the configuration */ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) { struct image_header hdr; @@ -610,19 +614,19 @@ bs_set(char *buf, int len) #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(&hdr)) { #ifdef MCUBOOT_SWAP_USING_OFFSET - FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + FIH_CALL(boot_image_validate_encrypted, fih_rc, state, fap, &hdr, tmpbuf, sizeof(tmpbuf), start_off); #else - FIH_CALL(boot_image_validate_encrypted, fih_rc, fap, + FIH_CALL(boot_image_validate_encrypted, fih_rc, state, fap, &hdr, tmpbuf, sizeof(tmpbuf)); #endif } else { #endif #ifdef MCUBOOT_SWAP_USING_OFFSET - FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, + FIH_CALL(bootutil_img_validate, fih_rc, state, &hdr, fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL, start_off); #else - FIH_CALL(bootutil_img_validate, fih_rc, NULL, &hdr, + FIH_CALL(bootutil_img_validate, fih_rc, state, &hdr, fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL); #endif #ifdef MCUBOOT_ENC_IMAGES @@ -648,7 +652,10 @@ bs_set(char *buf, int len) 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; + if (slot != BOOT_PRIMARY_SLOT) + goto set_image_state; + else + goto out; } } } @@ -668,7 +675,7 @@ set_image_state: out: if (rc == 0) { /* Success - return updated list of images */ - bs_list(buf, len); + bs_list(state, buf, len); } else { /* Error code, only return the error */ zcbor_map_start_encode(cbor_state, 10); @@ -697,16 +704,52 @@ bs_rc_rsp(int rc_code) static void bs_list_set(uint8_t op, char *buf, int len) { + int rc; + struct boot_loader_state *state; + bool area_opened = false; + + state = boot_get_loader_state(); + boot_state_clear(state); + + rc = boot_open_all_flash_areas(state); + if (rc != 0) { + BOOT_LOG_ERR("Failed to open flash areas: %d", rc); + rc = MGMT_ERR_EUNKNOWN; + goto out; + } + + area_opened = true; + +#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) + IMAGES_ITER(BOOT_CURR_IMG(state)) { + rc = boot_read_sectors(state); + if (rc != 0) { + BOOT_LOG_ERR("Failed to read sectors: %d", rc); + rc = MGMT_ERR_EUNKNOWN; + goto out; + } + } +#endif + if (op == NMGR_OP_READ) { - bs_list(buf, len); + bs_list(state, buf, len); } else { #ifdef MCUBOOT_SERIAL_IMG_GRP_IMAGE_STATE - bs_set(buf, len); + bs_set(state, buf, len); #else - bs_rc_rsp(MGMT_ERR_ENOTSUP); + rc = MGMT_ERR_ENOTSUP; #endif } +out: + if (area_opened) { + boot_close_all_flash_areas(state); + } + + if (rc != 0) { + bs_rc_rsp(rc); + } + reset_cbor_state(); } diff --git a/boot/boot_serial/src/boot_serial_encryption.c b/boot/boot_serial/src/boot_serial_encryption.c index 60ad587c..51588d49 100644 --- a/boot/boot_serial/src/boot_serial_encryption.c +++ b/boot/boot_serial/src/boot_serial_encryption.c @@ -19,7 +19,8 @@ BOOT_LOG_MODULE_DECLARE(serial_encryption); fih_ret -boot_image_validate_encrypted(const struct flash_area *fa_p, +boot_image_validate_encrypted(struct boot_loader_state *state, + const struct flash_area *fa_p, struct image_header *hdr, uint8_t *buf, uint16_t buf_size #ifdef MCUBOOT_SWAP_USING_OFFSET @@ -29,14 +30,12 @@ boot_image_validate_encrypted(const struct flash_area *fa_p, { FIH_DECLARE(fih_rc, FIH_FAILURE); - struct boot_loader_state boot_data; - struct boot_loader_state *state = &boot_data; struct boot_status _bs; struct boot_status *bs = &_bs; int rc; memset(&boot_data, 0, sizeof(struct boot_loader_state)); - if(IS_ENCRYPTED(hdr)) { + if (MUST_DECRYPT(fa_p, BOOT_CURR_IMG(state), hdr)) { #ifdef MCUBOOT_SWAP_USING_OFFSET rc = boot_enc_load(state, 1, hdr, fa_p, bs, start_off); #else @@ -59,6 +58,8 @@ boot_image_validate_encrypted(const struct flash_area *fa_p, hdr, fa_p, buf, buf_size, NULL, 0, NULL); #endif + boot_enc_zeroize(BOOT_CURR_ENC(state)); + FIH_RET(fih_rc); } @@ -241,7 +242,7 @@ decrypt_image_inplace(const struct flash_area *fa_p, #if 0 //Skip this step?, the image will just not boot if it's not decrypted properly static uint8_t tmpbuf[BOOT_TMPBUF_SZ]; /* First check if the encrypted image is a good image before decrypting */ - FIH_CALL(boot_image_validate_encrypted,fih_rc,fa_p,&_hdr,tmpbuf,BOOT_TMPBUF_SZ); + FIH_CALL(boot_image_validate_encrypted, fih_rc, state, fa_p, &_hdr, tmpbuf, BOOT_TMPBUF_SZ); if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { FIH_RET(fih_rc); } diff --git a/boot/bootutil/include/bootutil/bootutil_public.h b/boot/bootutil/include/bootutil/bootutil_public.h index 421d854b..7ff238b1 100644 --- a/boot/bootutil/include/bootutil/bootutil_public.h +++ b/boot/bootutil/include/bootutil/bootutil_public.h @@ -310,6 +310,36 @@ int boot_image_load_header(const struct flash_area *fa_p, struct image_header *hdr); +/** + * Opens the flash areas of all images. + * + * @note This function opens all areas for all images, including scratch area if + * MCUBOOT_SWAP_USING_SCRATCH is defined. + * + * @param state Bootloader state. + * + * @return 0 on success; nonzero on failure. + */ +int boot_open_all_flash_areas(struct boot_loader_state *state); + +/** + * Closes the flash areas of all images. + * + * @note This function closes all areas for all images, including scratch area if + * MCUBOOT_SWAP_USING_SCRATCH is defined. + * + * @param state Bootloader state. + */ +void boot_close_all_flash_areas(struct boot_loader_state *state); + +/** + * Determines the sector layout of both image slots and the scratch area. + * This information is necessary for calculating the number of bytes to erase + * and copy during an image swap. The information collected during this + * function is used to populate the state. + */ +int boot_read_sectors(struct boot_loader_state *state); + #ifdef MCUBOOT_RAM_LOAD /** * Loads image with given header to RAM. diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 23a65d1e..94e7d886 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -748,13 +748,37 @@ boot_write_sz(struct boot_loader_state *state) return elem_sz; } -/** - * Determines the sector layout of both image slots and the scratch area. - * This information is necessary for calculating the number of bytes to erase - * and copy during an image swap. The information collected during this - * function is used to populate the state. - */ -static int +int +boot_open_all_flash_areas(struct boot_loader_state *state) +{ + int rc; + int fa_id; + + IMAGES_ITER(BOOT_CURR_IMG(state)) { + BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors = + sector_buffers.primary[BOOT_CURR_IMG(state)]; + BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors = + sector_buffers.secondary[BOOT_CURR_IMG(state)]; + fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_PRIMARY_SLOT); + rc = flash_area_open(fa_id, &BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + assert(rc == 0); + fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), BOOT_SECONDARY_SLOT); + rc = flash_area_open(fa_id, &BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)); + assert(rc == 0); + } + return 0; +} + +void +boot_close_all_flash_areas(struct boot_loader_state *state) +{ + IMAGES_ITER(BOOT_CURR_IMG(state)) { + flash_area_close(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)); + flash_area_close(BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)); + } +} + +int boot_read_sectors(struct boot_loader_state *state) { uint8_t image_index;