Skip to content

Conversation

tomchy
Copy link
Collaborator

@tomchy tomchy commented Jul 31, 2025

According to the PSA Platform Security Boot Guide:

R20_PSBG_MANIFEST: Each image manifest must contain the properties specified in Figure 2. It is permitted for
additional information to be included.

The manifest (which can be interpreted as image header and additional metadata stored inside TLVs) must include:

  • Image type: Specifically identifies the boot stage or peripheral. Also known as a purpose identifier. This field is not required if only one type of image is supported.
  • Product class: This can refer to a vendor ID, product ID, or a more specific identifier, such as the
    Instance ID.

This PR introduces two identifiers to meet those requirements:

  • Image class ID, defined as RFC 9562 UUID Version 5, that may contain all: image type and product type values as input.
  • Image vendor ID, defined as RFC 9562 UUID Version 5, that provides the namespace for the image class ID, so two devices with the same type/product name will have different image class UUIDs.

@tomchy tomchy force-pushed the feature/bootutil/NCSDK-34175_Add_vid_cid_support_upstream branch from ab8fffa to fc4c042 Compare July 31, 2025 14:33
Comment on lines +771 to +501
if (len != sizeof(img_uuid_vid)) {
/* Vendor UUID is not valid. */
rc = -1;
goto out;
}

rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_vid.raw, len);
if (rc) {
goto out;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

If it was decided to wrap uuid in fih, these should probably also report fih failure; i do not understand a difference between a failure in uuid check and inability to perform the check. And I know that we are inconsistent here, and maybe that is a good point to discuss it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There is a translation logic, based on the rc value:

   if (rc) {
        FIH_SET(fih_rc, FIH_FAILURE);

and the default value of uuid_vid_valid and uuid_cid_valid will either way mask the other failure reasons.

The difference is just that - inability (if possible) can report "incompatible image format" and the uuid check can report "invalid UUID value".
There is though no way to distinguish between those error reasons as there is just a single FIH_FAILURE error code.

Copy link
Collaborator

Choose a reason for hiding this comment

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

out: seams can't mock success - it only could mock failure as a glith.

@@ -142,6 +142,8 @@ extern "C" {
* ...
* 0xffa0 - 0xfffe
*/
#define IMAGE_TLV_UUID_VID 0x80 /* Vendor unique identifier */
Copy link
Collaborator

Choose a reason for hiding this comment

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

These go above comment explaining vendor specific ids. If these are vendor specific ids, then they have in-proper codes.

Copy link
Collaborator

Choose a reason for hiding this comment

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

And should't really be here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What do you mean by "comment explaining vendor specific ids"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@tomchy move this just after #define IMAGE_TLV_COMP_DEC_SIZE 0x73 /* Compressed decrypted image size */ line.
@de-nordic Clarification: these are new MCUboot generic TLVs


static fih_ret boot_uuid_compare(const struct image_uuid *uuid1, const struct image_uuid *uuid2)
{
return fih_ret_encode_zero_equality(memcmp(uuid1->raw, uuid2->raw,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we sure we want to get fih heavy on uuid comparisons? What is the attack vector here? As far as i cen tell they are already protected tlvs and, as such, are signed with image, and why would you bypass uid check? You would have to bypass signature first.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The attack vector would be to install the FW not designed for a particular core as a result of glitching the UUID checks (skipping them or altering comparison results).

Honestly, I do not know where to draw a line between checks that should use FIH and checks that should not. The code was based on the way the security counter is implemented, thus by default it uses FIH routines.

@tomchy tomchy force-pushed the feature/bootutil/NCSDK-34175_Add_vid_cid_support_upstream branch from fc4c042 to 54dd37c Compare August 25, 2025 12:20
@tomchy tomchy requested a review from de-nordic August 25, 2025 12:24
@tomchy tomchy force-pushed the feature/bootutil/NCSDK-34175_Add_vid_cid_support_upstream branch from 54dd37c to 25b5c04 Compare August 28, 2025 10:56
@@ -142,6 +142,8 @@ extern "C" {
* ...
* 0xffa0 - 0xfffe
*/
#define IMAGE_TLV_UUID_VID 0x80 /* Vendor unique identifier */
Copy link
Collaborator

Choose a reason for hiding this comment

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

@tomchy move this just after #define IMAGE_TLV_COMP_DEC_SIZE 0x73 /* Compressed decrypted image size */ line.
@de-nordic Clarification: these are new MCUboot generic TLVs

Comment on lines +771 to +501
if (len != sizeof(img_uuid_vid)) {
/* Vendor UUID is not valid. */
rc = -1;
goto out;
}

rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_vid.raw, len);
if (rc) {
goto out;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

out: seams can't mock success - it only could mock failure as a glith.

@tomchy tomchy force-pushed the feature/bootutil/NCSDK-34175_Add_vid_cid_support_upstream branch from 25b5c04 to 09fa479 Compare August 29, 2025 15:54
@tomchy tomchy requested a review from nvlsianpu August 29, 2025 16:01
Copy link
Collaborator

@nordicjm nordicjm left a comment

Choose a reason for hiding this comment

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

very quick comment, need to review

@@ -612,6 +647,21 @@ def create(self, key, public_key_format, enckey, dependencies=None,
if compression_tlvs is not None:
for tag, value in compression_tlvs.items():
prot_tlv.add(tag, value)

if self.vid is not None:
vid = parse_uuid(uuid.NAMESPACE_DNS, self.vid)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is DNS used? What other options are there instead of DNS?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because it is the simplest thing with a registry to use to specify the vendor.
The python package includes the following namespaces:

  • DNS: When this namespace is specified, the name string is a fully qualified domain name.
  • URL: When this namespace is specified, the name string is a URL.
  • OID: When this namespace is specified, the name string is an ISO OID.
  • X500: When this namespace is specified, the name string is an X.500 DN in DER or a text output format.

It also aligns with the values used in SUIT:

The RECOMMENDED method to create a vendor ID is:
The "IANA UUID Namespace ID for DNS" is:
6ba7b810-9dad-11d1-80b4-00c04fd430c8
Vendor ID = UUID5(, vendor domain name)

Comment on lines +658 to +664
namespace = uuid.UUID(bytes=vid)
else:
namespace = None
Copy link
Collaborator

Choose a reason for hiding this comment

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

why does the above use DNS and this either use the above or nothing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because it is easy to provide unique VIDs, based on DNS.
It is not easy to provide unique arbitrary CIDs, thus it is safer to use unique VID value as the namespace to calculate CID, thus providing unique, vendor-specific CIDs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The None option is valid if and only if the user provides RAW CID UUID value.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It also aligns with the recommendations in SUIT specification:

If the Vendor ID is a UUID, the RECOMMENDED method to create a Class ID is:
Class ID = UUID5(Vendor ID, Class-Specific-Information)

Comment on lines 132 to 137
# Include the sample implementation.
if(CONFIG_MCUBOOT_UUID_VID OR CONFIG_MCUBOOT_UUID_CID)
zephyr_library_sources(
mcuboot_uuid.c
)
endif()
Copy link
Collaborator

Choose a reason for hiding this comment

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

sample? If this is for a sample it should be added specifically by the sample, it should not be in the cmake file and it should not be added for all builds when these Kconfigs are enabled

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

After second though - you're right: I cannot guarantee that this implementation will be sufficient for all use cases, thus it should not be placed inside MCUboot repository.

Comment on lines 140 to 141
if(CONFIG_MCUBOOT_UUID_VID OR CONFIG_MCUBOOT_UUID_CID)
string(REGEX MATCHALL "^([0-9A-F][0-9A-F]|\-)+$" match_parts ${CONFIG_MCUBOOT_UUID_VID_VALUE})
Copy link
Collaborator

Choose a reason for hiding this comment

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

this runs if either is set, then assumes VID is the one that is set? Also make - optional

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Correct, the MCUBOOT_UUID_VID_VALUE symbol is available if either CONFIG_MCUBOOT_UUID_VID or CONFIG_MCUBOOT_UUID_CID is enabled.
The use case is pretty simple: you want a simplified check (only CID), but still want to generate UUID values, based on the VID namespace.


# Generate VID value(s) and raw value definition(s)
if(CONFIG_MCUBOOT_UUID_CID)
set(MCUBOOT_IMAGES_COUNT 4)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is this using 4 images?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll try to use UPDATEABLE_IMAGE_NUMBER instead.

*/
#include <bootutil/mcuboot_uuid.h>

#define IMAGE_ID_COUNT 5
Copy link
Collaborator

Choose a reason for hiding this comment

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

as above, if this is a sample it should be moved to a sample

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll move it outside of the MCUboot repo too.

@nordicjm
Copy link
Collaborator

nordicjm commented Sep 1, 2025

Also, this feature should be added to the simulator for testing

Add a possibility to express vendor ID and image class ID inside image's TLVs.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
@tomchy tomchy force-pushed the feature/bootutil/NCSDK-34175_Add_vid_cid_support_upstream branch from 09fa479 to 7717a1c Compare September 2, 2025 12:22
Allow to specify VID and CID for an image.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
@tomchy tomchy force-pushed the feature/bootutil/NCSDK-34175_Add_vid_cid_support_upstream branch from 7717a1c to ee67a90 Compare September 2, 2025 12:56
@tomchy tomchy requested a review from nordicjm September 2, 2025 12:57
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