Skip to content

Commit 8782a62

Browse files
committed
bootloader: Add basic UUID checks implementation
Provide an implementation for MCUboot UUID checks that specify a single, common vendor identifier and a unique class identifier for each image. Ref: NCSDK-34175 Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent beeb6b3 commit 8782a62

File tree

6 files changed

+220
-0
lines changed

6 files changed

+220
-0
lines changed

subsys/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_subdirectory_ifdef(CONFIG_IS_SECURE_BOOTLOADER bootloader)
1010
add_subdirectory_ifdef(CONFIG_SECURE_BOOT_CRYPTO bootloader/bl_crypto)
1111
add_subdirectory_ifdef(CONFIG_SECURE_BOOT_VALIDATION bootloader/bl_validation)
1212
add_subdirectory_ifdef(CONFIG_SECURE_BOOT_STORAGE bootloader/bl_storage)
13+
add_subdirectory(bootloader/bl_uuid)
1314

1415
add_subdirectory_ifdef(CONFIG_NRF_SECURITY nrf_security)
1516
add_subdirectory_ifdef(CONFIG_TRUSTED_STORAGE trusted_storage)

subsys/bootloader/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ config NRF53_ENFORCE_IMAGE_VERSION_EQUALITY
154154
rsource "bl_crypto/Kconfig"
155155
rsource "bl_validation/Kconfig"
156156
rsource "bl_storage/Kconfig"
157+
rsource "bl_uuid/Kconfig"
157158

158159
config MCUBOOT_COMPRESSED_IMAGE_SUPPORT_ENABLED
159160
bool "MCUboot compressed image support"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
if(CONFIG_NRF_MCUBOOT_UUID_SINGLE_VID)
8+
zephyr_library()
9+
10+
if(CONFIG_MCUBOOT_UUID_VID OR CONFIG_MCUBOOT_UUID_CID)
11+
zephyr_library_sources(
12+
bl_uuid.c
13+
)
14+
endif()
15+
16+
# Generate VID value and raw value definition
17+
if(CONFIG_MCUBOOT_UUID_VID OR CONFIG_MCUBOOT_UUID_CID)
18+
string(REGEX MATCHALL "^([0-9A-F][0-9A-F]|\-)+$" match_parts ${CONFIG_NRF_MCUBOOT_UUID_VID_VALUE})
19+
if("${match_parts}" STREQUAL "${CONFIG_NRF_MCUBOOT_UUID_VID_VALUE}")
20+
set(UUID_VID ${match_parts})
21+
else()
22+
set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
23+
string(
24+
UUID UUID_VID
25+
NAMESPACE ${UUID_DNS_NAMESPACE}
26+
NAME ${CONFIG_NRF_MCUBOOT_UUID_VID_VALUE}
27+
TYPE SHA1 UPPER
28+
)
29+
endif()
30+
31+
# Convert UUID into C array.
32+
string(REGEX REPLACE "([0-9A-F][0-9A-F])\-?" "0x\\1, " UUID_VID_RAW ${UUID_VID})
33+
add_compile_definitions(NRF_MCUBOOT_UUID_VID_VALUE=${UUID_VID_RAW})
34+
endif()
35+
36+
# Generate VID value(s) and raw value definition(s)
37+
if(CONFIG_MCUBOOT_UUID_CID)
38+
set(MCUBOOT_IMAGES_COUNT ${CONFIG_UPDATEABLE_IMAGE_NUMBER})
39+
foreach(image_id RANGE ${MCUBOOT_IMAGES_COUNT})
40+
if(CONFIG_NRF_MCUBOOT_UUID_CID_IMAGE_${image_id})
41+
# Check if RAW UUID format is used
42+
string(REGEX MATCHALL "^([0-9A-F][0-9A-F]|\-)+$" match_parts ${CONFIG_NRF_MCUBOOT_UUID_CID_IMAGE_${image_id}_VALUE})
43+
if("${match_parts}" STREQUAL "${CONFIG_NRF_MCUBOOT_UUID_CID_IMAGE_${image_id}_VALUE}")
44+
set(UUID_CID_IMAGE_${image_id} ${match_parts})
45+
else()
46+
# If not - generate UUID based on VID and CID values
47+
string(
48+
UUID UUID_CID_IMAGE_${image_id}
49+
NAMESPACE ${UUID_VID}
50+
NAME ${CONFIG_NRF_MCUBOOT_UUID_CID_IMAGE_${image_id}_VALUE}
51+
TYPE SHA1 UPPER
52+
)
53+
endif()
54+
55+
# Convert UUID into C array.
56+
string(REGEX REPLACE "([0-9A-F][0-9A-F])\-?" "0x\\1, " UUID_CID_IMAGE_${image_id}_RAW ${UUID_CID_IMAGE_${image_id}})
57+
add_compile_definitions(NRF_MCUBOOT_UUID_CID_IMAGE_${image_id}_VALUE=${UUID_CID_IMAGE_${image_id}_RAW})
58+
endif()
59+
endforeach()
60+
endif()
61+
endif()

subsys/bootloader/bl_uuid/Kconfig

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
if MCUBOOT_UUID_VID || MCUBOOT_UUID_CID
8+
9+
menu "Vendor and image Class UUIDs"
10+
11+
choice NRF_MCUBOOT_UUID_IMPLEMENTATION
12+
prompt "UUID checks implementation"
13+
default NRF_MCUBOOT_UUID_SINGLE_VID
14+
15+
config NRF_MCUBOOT_UUID_SINGLE_VID
16+
bool "Single VID and one CID per image"
17+
help
18+
This implementation allows to specify a single, common Vendor UUID
19+
(VID) for all images and a unique Class UUID (CID) for each image.
20+
21+
endchoice # NRF_MCUBOOT_UUID_IMPLEMENTATION
22+
23+
if NRF_MCUBOOT_UUID_SINGLE_VID
24+
25+
config NRF_MCUBOOT_UUID_VID_VALUE
26+
string "Vendor name"
27+
default ""
28+
help
29+
The vendor unique identifier.
30+
The following formats are supported:
31+
- Domain name (i.e. amce.corp) used to generate RFC 9562 UUID5
32+
identifier.
33+
- Raw UUID (i.e. 12345678-1234-5678-1234-567812345678)
34+
- Raw HEX UUID (i.e. 12345678123456781234567812345678)
35+
36+
if MCUBOOT_UUID_CID
37+
38+
image=0
39+
rsource "Kconfig.uuid.template"
40+
image=1
41+
rsource "Kconfig.uuid.template"
42+
image=2
43+
rsource "Kconfig.uuid.template"
44+
image=3
45+
rsource "Kconfig.uuid.template"
46+
image=4
47+
rsource "Kconfig.uuid.template"
48+
49+
endif # MCUBOOT_UUID_CID
50+
51+
endif # NRF_MCUBOOT_UUID_SINGLE_VID
52+
53+
endmenu
54+
55+
endif # MCUBOOT_UUID_VID || MCUBOOT_UUID_CID
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
if UPDATEABLE_IMAGE_NUMBER > $(image)
8+
9+
config NRF_MCUBOOT_UUID_CID_IMAGE_$(image)_VALUE
10+
string "Image class name (image $(image))"
11+
default ""
12+
help
13+
The image class unique identifier.
14+
The following formats are supported:
15+
- Image class name (i.e. nRF5340_door_lock_btperipheral).
16+
This format requires NRF_MCUBOOT_UUID_VID_VALUE to be defined
17+
as the VID UUID is used as the namespace for generating RFC 9562
18+
UUID5 identifier.
19+
- Raw UUID (i.e. 12345678-1234-5678-1234-567812345678)
20+
- Raw HEX UUID (i.e. 12345678123456781234567812345678)
21+
22+
config NRF_MCUBOOT_UUID_CID_IMAGE_$(image)
23+
bool
24+
default y
25+
depends on NRF_MCUBOOT_UUID_CID_IMAGE_$(image)_VALUE != ""
26+
help
27+
Helper symbol to simplify the active CId list generation.
28+
29+
endif # UPDATEABLE_IMAGE_NUMBER > $(image)

subsys/bootloader/bl_uuid/bl_uuid.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <bootutil/mcuboot_uuid.h>
7+
8+
#define IMAGE_ID_COUNT CONFIG_UPDATEABLE_IMAGE_NUMBER
9+
#define CID_INIT(index, label) \
10+
static const struct image_uuid label = {{ \
11+
NRF_MCUBOOT_UUID_CID_IMAGE_## index ##_VALUE \
12+
}}
13+
#define CID_CONFIG(index) UTIL_CAT(CONFIG_NRF_MCUBOOT_UUID_CID_IMAGE_, index)
14+
#define CID_DEFINE(index, prefix) \
15+
IF_ENABLED(CID_CONFIG(index), (CID_INIT(index, prefix##index)))
16+
17+
#define CID_CONDITION(index, label) \
18+
if (image_id == index) { \
19+
*uuid_cid = &label; \
20+
FIH_RET(FIH_SUCCESS); \
21+
}
22+
#define CID_CHECK(index, prefix) \
23+
IF_ENABLED(CID_CONFIG(index), (CID_CONDITION(index, prefix##index)))
24+
25+
static fih_ret boot_uuid_compare(const struct image_uuid *uuid1, const struct image_uuid *uuid2)
26+
{
27+
return fih_ret_encode_zero_equality(memcmp(uuid1->raw, uuid2->raw,
28+
ARRAY_SIZE(uuid1->raw)));
29+
}
30+
31+
#ifdef CONFIG_MCUBOOT_UUID_CID
32+
LISTIFY(IMAGE_ID_COUNT, CID_DEFINE, (;), uuid_cid_image_);
33+
34+
static fih_ret boot_uuid_cid_get(uint32_t image_id, const struct image_uuid **uuid_cid)
35+
{
36+
if (uuid_cid != NULL) {
37+
LISTIFY(IMAGE_ID_COUNT, CID_CHECK, (), uuid_cid_image_)
38+
}
39+
40+
FIH_RET(FIH_FAILURE);
41+
}
42+
#endif /* CONFIG_MCUBOOT_UUID_CID */
43+
44+
fih_ret boot_uuid_init(void)
45+
{
46+
FIH_RET(FIH_SUCCESS);
47+
}
48+
49+
#ifdef CONFIG_MCUBOOT_UUID_VID
50+
fih_ret boot_uuid_vid_match(uint32_t image_id, const struct image_uuid *uuid_vid)
51+
{
52+
const struct image_uuid uuid_vid_c = {{
53+
NRF_MCUBOOT_UUID_VID_VALUE
54+
}};
55+
56+
return boot_uuid_compare(uuid_vid, &uuid_vid_c);
57+
}
58+
#endif /* CONFIG_MCUBOOT_UUID_VID */
59+
60+
#ifdef CONFIG_MCUBOOT_UUID_CID
61+
fih_ret boot_uuid_cid_match(uint32_t image_id, const struct image_uuid *uuid_cid)
62+
{
63+
FIH_DECLARE(ret_code, FIH_FAILURE);
64+
const struct image_uuid *exp_uuid_cid = NULL;
65+
66+
FIH_CALL(boot_uuid_cid_get, ret_code, image_id, &exp_uuid_cid);
67+
if (FIH_NOT_EQ(ret_code, FIH_SUCCESS) && FIH_NOT_EQ(ret_code, FIH_FAILURE)) {
68+
FIH_RET(FIH_FAILURE);
69+
}
70+
71+
return boot_uuid_compare(uuid_cid, exp_uuid_cid);
72+
}
73+
#endif /* CONFIG_MCUBOOT_UUID_CID */

0 commit comments

Comments
 (0)