Skip to content

Conversation

@tomchy
Copy link
Collaborator

@tomchy tomchy commented Oct 21, 2025

Add a loader variant that is capable of booting images, based on a simple manifest.

Ideas:

  • The 1st Image (slot pair) is the main/lead image - it describes firmware bundle for the device. This image is manifest Image.
  • The firmware bundle description is provided in the protected TLV of the manifest image. Images relations are expressed as their hashes. Obviously hash of the manifest image is not in the TLV as it covers it as well.

@tomchy tomchy force-pushed the feature/mcuboot/NCSDK-NONE_Transaction_manifest_xip_upstream branch 3 times, most recently from 6ebfcaf to aaf2a5a Compare October 21, 2025 14:10
@tomchy tomchy force-pushed the feature/mcuboot/NCSDK-NONE_Transaction_manifest_xip_upstream branch from aaf2a5a to d8e62ff Compare October 22, 2025 09:00
@tomchy tomchy marked this pull request as ready for review October 22, 2025 15:13
@tomchy tomchy force-pushed the feature/mcuboot/NCSDK-NONE_Transaction_manifest_xip_upstream branch from d8e62ff to 3688d72 Compare October 23, 2025 12:07
Copy link
Contributor

@JarmouniA JarmouniA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have some documentation for this feature? Thanks!

Add a possibility to attach a basic manifest with expected digests to an
image.
Alter the image verification logic, so only digests specified by the
manifest are allowed on the device.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
Add a simple logic that allows to attach a manifest TLV to an image.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
Add a loader variant that is capable of booting images, based on a
simple manifest.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
@tomchy tomchy force-pushed the feature/mcuboot/NCSDK-NONE_Transaction_manifest_xip_upstream branch from 3688d72 to 8eca34c Compare October 24, 2025 09:02
return false;
}

if (manifest->image_count != BOOT_IMAGE_NUMBER - 1) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

() around arithmetic.

* @return 0 on success; nonzero on failure.
*/
static int
boot_select_or_erase(struct boot_loader_state *state)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: This should be executed only on the manifest image. If a manifest image is erased/not present, all other images will be rejected on the digest check.

Comment on lines +72 to +90
static inline const uint8_t *bootutil_get_image_hash(const struct mcuboot_manifest *manifest,
uint32_t image_index)
{
if (!bootutil_verify_manifest(manifest)) {
return NULL;
}

if (image_index >= BOOT_IMAGE_NUMBER) {
return NULL;
}

if (image_index < MCUBOOT_MANIFEST_IMAGE_NUMBER) {
return manifest->image_hash[image_index];
} else if (image_index > MCUBOOT_MANIFEST_IMAGE_NUMBER) {
return manifest->image_hash[image_index - 1];
}

return NULL;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this should be able to return NULL in any case.
This should panic on any parameter that is not expected.
Since the function is always called before boot_fih_memequal I think that both functions should be merged and the bootutil_get_image_hash should be changed to FIH return function that will be given enough parameter to compare a hash without pulling it out of the manifest object.
This should also reduce code size, since the boot_fih_memequal and will be combined here and no need for external null checks.


#if defined(MCUBOOT_MANIFEST_UPDATES)
struct mcuboot_manifest manifest[BOOT_NUM_SLOTS];
bool manifest_valid[BOOT_NUM_SLOTS];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move that into the mcuboot_manifest? We can have different structs for TLV and internal usage.

if (image_index == MCUBOOT_MANIFEST_IMAGE_NUMBER) {
if (!state->manifest_valid[slot]) {
/* Manifest TLV must be processed before any of the image's hash TLV. */
BOOT_LOG_INF("bootutil_img_validate: image rejected, manifest not found before image %d hash",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that at least warning? It ends up in rc = -1, so basically fails the function.


/* No matching manifest found. */
if (state->matching_manifest[image_index][slot] == BOOT_SLOT_NONE) {
BOOT_LOG_INF("bootutil_img_validate: image rejected, no valid manifest for image %d slot %d",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is either warning or error, we are failing function here.

{
uint32_t active_slot;

(void)state;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be used.

active_slot = find_slot_with_highest_version(state);
}
if (active_slot == BOOT_SLOT_NONE) {
BOOT_LOG_INF("No more manifest slots available");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error?


/* Check headers in all slots */
for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
hdr = boot_img_hdr(state, slot);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be moved into if under 231, there is only usage of this.


#ifdef MCUBOOT_MANIFEST_UPDATES
if (image_index == MCUBOOT_MANIFEST_IMAGE_NUMBER && (!manifest_found || !manifest_valid)) {
BOOT_LOG_INF("bootutil_img_validate: slot %d rejected, manifest missing or invalid", slot);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants