-
Notifications
You must be signed in to change notification settings - Fork 801
Add vendor and image class UUID support #2409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright (c) 2025 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef __MCUBOOT_UUID_H__ | ||
#define __MCUBOOT_UUID_H__ | ||
|
||
/** | ||
* @file uuid.h | ||
* | ||
* @note A vendor ID as well as class ID values may be statically generated | ||
* using CMake, based on the vendor domain name as well as product name. | ||
* It is advised to use vendor ID as an input while generating device | ||
* class ID to avoid collisions between UUIDs from two different vendors. | ||
*/ | ||
|
||
#include <stdint.h> | ||
#include "bootutil/fault_injection_hardening.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
|
||
/** The 128-bit UUID, used for identifying vendors as well as image classes. */ | ||
struct image_uuid { | ||
uint8_t raw[16]; | ||
}; | ||
|
||
/** | ||
* @brief Initialises the UUID module. | ||
* | ||
* @return FIH_SUCCESS on success | ||
*/ | ||
fih_ret boot_uuid_init(void); | ||
|
||
/** | ||
* @brief Check if the specified vendor UUID is allowed for a given image. | ||
* | ||
* @param[in] image_id Index of the image (from 0). | ||
* @param[in] uuid_vid The reference to the image's vendor ID value. | ||
* | ||
* @return FIH_SUCCESS on success. | ||
*/ | ||
fih_ret boot_uuid_vid_match(uint32_t image_id, const struct image_uuid *uuid_vid); | ||
|
||
/** | ||
* @brief Check if the specified image class UUID is allowed for a given image. | ||
* | ||
* @param[in] image_id Index of the image (from 0). | ||
* @param[in] uuid_cid The reference to the image's class ID value. | ||
* | ||
* @return FIH_SUCCESS on success | ||
*/ | ||
fih_ret boot_uuid_cid_match(uint32_t image_id, const struct image_uuid *uuid_cid); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* __MCUBOOT_UUID_H__ */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,9 @@ | |
#include "bootutil/bootutil_log.h" | ||
|
||
BOOT_LOG_MODULE_DECLARE(mcuboot); | ||
#if defined(MCUBOOT_UUID_VID) || defined(MCUBOOT_UUID_CID) | ||
#include "bootutil/mcuboot_uuid.h" | ||
#endif /* MCUBOOT_UUID_VID || MCUBOOT_UUID_CID */ | ||
|
||
#ifdef MCUBOOT_ENC_IMAGES | ||
#include "bootutil/enc_key.h" | ||
|
@@ -198,7 +201,8 @@ bootutil_img_validate(struct boot_loader_state *state, | |
int seed_len, uint8_t *out_hash | ||
) | ||
{ | ||
#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_UUID_VID) || defined(MCUBOOT_UUID_CID) | ||
int image_index = (state == NULL ? 0 : BOOT_CURR_IMG(state)); | ||
#endif | ||
uint32_t off; | ||
|
@@ -235,6 +239,14 @@ bootutil_img_validate(struct boot_loader_state *state, | |
uint32_t img_security_cnt = 0; | ||
FIH_DECLARE(security_counter_valid, FIH_FAILURE); | ||
#endif | ||
#ifdef MCUBOOT_UUID_VID | ||
struct image_uuid img_uuid_vid = {0x00}; | ||
FIH_DECLARE(uuid_vid_valid, FIH_FAILURE); | ||
#endif | ||
#ifdef MCUBOOT_UUID_CID | ||
struct image_uuid img_uuid_cid = {0x00}; | ||
FIH_DECLARE(uuid_cid_valid, FIH_FAILURE); | ||
#endif | ||
|
||
BOOT_LOG_DBG("bootutil_img_validate: flash area %p", fap); | ||
|
||
|
@@ -463,6 +475,64 @@ bootutil_img_validate(struct boot_loader_state *state, | |
break; | ||
} | ||
#endif /* MCUBOOT_HW_ROLLBACK_PROT */ | ||
#ifdef MCUBOOT_UUID_VID | ||
case IMAGE_TLV_UUID_VID: | ||
{ | ||
/* | ||
* Verify the image's vendor ID length. | ||
* This must always be present. | ||
*/ | ||
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; | ||
} | ||
Comment on lines
+485
to
+494
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a translation logic, based on the rc value:
and the default value of The difference is just that - inability (if possible) can report "incompatible image format" and the uuid check can report "invalid UUID value". |
||
|
||
FIH_CALL(boot_uuid_vid_match, fih_rc, image_index, &img_uuid_vid); | ||
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { | ||
FIH_SET(uuid_vid_valid, FIH_FAILURE); | ||
goto out; | ||
} | ||
|
||
/* The image's vendor identifier has been successfully verified. */ | ||
uuid_vid_valid = fih_rc; | ||
break; | ||
} | ||
#endif | ||
#ifdef MCUBOOT_UUID_CID | ||
case IMAGE_TLV_UUID_CID: | ||
{ | ||
/* | ||
* Verify the image's class ID length. | ||
* This must always be present. | ||
*/ | ||
if (len != sizeof(img_uuid_cid)) { | ||
/* Image class UUID is not valid. */ | ||
rc = -1; | ||
goto out; | ||
} | ||
|
||
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_cid.raw, len); | ||
if (rc) { | ||
goto out; | ||
} | ||
|
||
FIH_CALL(boot_uuid_cid_match, fih_rc, image_index, &img_uuid_cid); | ||
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { | ||
FIH_SET(uuid_cid_valid, FIH_FAILURE); | ||
goto out; | ||
} | ||
|
||
/* The image's class identifier has been successfully verified. */ | ||
uuid_cid_valid = fih_rc; | ||
break; | ||
} | ||
#endif | ||
} | ||
} | ||
|
||
|
@@ -485,6 +555,19 @@ bootutil_img_validate(struct boot_loader_state *state, | |
} | ||
#endif | ||
|
||
#ifdef MCUBOOT_UUID_VID | ||
if (FIH_NOT_EQ(uuid_vid_valid, FIH_SUCCESS)) { | ||
rc = -1; | ||
goto out; | ||
} | ||
#endif | ||
#ifdef MCUBOOT_UUID_CID | ||
if (FIH_NOT_EQ(uuid_cid_valid, FIH_SUCCESS)) { | ||
rc = -1; | ||
goto out; | ||
} | ||
#endif | ||
|
||
out: | ||
if (rc) { | ||
FIH_SET(fih_rc, FIH_FAILURE); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
config MCUBOOT_UUID_CID_IMAGE_$(image)_VALUE | ||
string "Image class name (image $(image))" | ||
default "" | ||
help | ||
The image class unique identifier. | ||
The following formats are supported: | ||
- Image class name (i.e. nRF5340_door_lock_btperipheral). | ||
This format requires MCUBOOT_UUID_VID_VALUE to be defined | ||
as the VID UUID is used as the namespace for generating RFC 9562 | ||
UUID5 identifier. | ||
- Raw UUID (i.e. 12345678-1234-5678-1234-567812345678) | ||
|
||
config MCUBOOT_UUID_CID_IMAGE_$(image) | ||
bool | ||
default y | ||
depends on MCUBOOT_UUID_CID_IMAGE_$(image)_VALUE != "" | ||
help | ||
Helper symbol to simplify the active CId list generation. | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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"?