Skip to content

Commit 94ad4d4

Browse files
tomchyde-nordic
authored andcommitted
boot: Add VID and CID checks
Add a possibility to express vendor ID and image class ID inside image's TLVs. Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent aa4fa2b commit 94ad4d4

File tree

7 files changed

+229
-17
lines changed

7 files changed

+229
-17
lines changed

boot/bootutil/include/bootutil/image.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ extern "C" {
132132
* signature
133133
*/
134134
#define IMAGE_TLV_COMP_DEC_SIZE 0x73 /* Compressed decrypted image size */
135+
#define IMAGE_TLV_UUID_VID 0x74 /* Vendor unique identifier */
136+
#define IMAGE_TLV_UUID_CID 0x75 /* Device class unique identifier */
135137
/*
136138
* vendor reserved TLVs at xxA0-xxFF,
137139
* where xx denotes the upper byte
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef __MCUBOOT_UUID_H__
8+
#define __MCUBOOT_UUID_H__
9+
10+
/**
11+
* @file mcuboot_uuid.h
12+
*
13+
* @note A vendor ID as well as class ID values may be statically generated
14+
* using CMake, based on the vendor domain name as well as product name.
15+
* It is advised to use vendor ID as an input while generating device
16+
* class ID to avoid collisions between UUIDs from two different vendors.
17+
*/
18+
19+
#include <stdint.h>
20+
#include "bootutil/fault_injection_hardening.h"
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
27+
/** The 128-bit UUID, used for identifying vendors as well as image classes. */
28+
struct image_uuid {
29+
uint8_t raw[16];
30+
};
31+
32+
/**
33+
* @brief Initialises the UUID module.
34+
*
35+
* @return FIH_SUCCESS on success
36+
*/
37+
fih_ret boot_uuid_init(void);
38+
39+
/**
40+
* @brief Check if the specified vendor UUID is allowed for a given image.
41+
*
42+
* @param[in] image_id Index of the image (from 0).
43+
* @param[in] uuid_vid The reference to the image's vendor ID value.
44+
*
45+
* @return FIH_SUCCESS on success.
46+
*/
47+
fih_ret boot_uuid_vid_match(uint32_t image_id, const struct image_uuid *uuid_vid);
48+
49+
/**
50+
* @brief Check if the specified image class UUID is allowed for a given image.
51+
*
52+
* @param[in] image_id Index of the image (from 0).
53+
* @param[in] uuid_cid The reference to the image's class ID value.
54+
*
55+
* @return FIH_SUCCESS on success
56+
*/
57+
fih_ret boot_uuid_cid_match(uint32_t image_id, const struct image_uuid *uuid_cid);
58+
59+
#ifdef __cplusplus
60+
}
61+
#endif
62+
63+
#endif /* __MCUBOOT_UUID_H__ */

boot/bootutil/src/image_validate.c

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
#include "bootutil/bootutil_log.h"
4747

4848
BOOT_LOG_MODULE_DECLARE(mcuboot);
49+
#if defined(MCUBOOT_UUID_VID) || defined(MCUBOOT_UUID_CID)
50+
#include "bootutil/mcuboot_uuid.h"
51+
#endif /* MCUBOOT_UUID_VID || MCUBOOT_UUID_CID */
4952

5053
#ifdef MCUBOOT_ENC_IMAGES
5154
#include "bootutil/enc_key.h"
@@ -201,7 +204,8 @@ bootutil_img_validate(struct boot_loader_state *state,
201204
int seed_len, uint8_t *out_hash
202205
)
203206
{
204-
#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT)
207+
#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT) \
208+
|| defined(MCUBOOT_UUID_VID) || defined(MCUBOOT_UUID_CID)
205209
int image_index = (state == NULL ? 0 : BOOT_CURR_IMG(state));
206210
#endif
207211
uint32_t off;
@@ -238,6 +242,14 @@ bootutil_img_validate(struct boot_loader_state *state,
238242
uint32_t img_security_cnt = 0;
239243
FIH_DECLARE(security_counter_valid, FIH_FAILURE);
240244
#endif
245+
#ifdef MCUBOOT_UUID_VID
246+
struct image_uuid img_uuid_vid = {0x00};
247+
FIH_DECLARE(uuid_vid_valid, FIH_FAILURE);
248+
#endif
249+
#ifdef MCUBOOT_UUID_CID
250+
struct image_uuid img_uuid_cid = {0x00};
251+
FIH_DECLARE(uuid_cid_valid, FIH_FAILURE);
252+
#endif
241253

242254
BOOT_LOG_DBG("bootutil_img_validate: flash area %p", fap);
243255

@@ -470,6 +482,64 @@ bootutil_img_validate(struct boot_loader_state *state,
470482
break;
471483
}
472484
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
485+
#ifdef MCUBOOT_UUID_VID
486+
case IMAGE_TLV_UUID_VID:
487+
{
488+
/*
489+
* Verify the image's vendor ID length.
490+
* This must always be present.
491+
*/
492+
if (len != sizeof(img_uuid_vid)) {
493+
/* Vendor UUID is not valid. */
494+
rc = -1;
495+
goto out;
496+
}
497+
498+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_vid.raw, len);
499+
if (rc) {
500+
goto out;
501+
}
502+
503+
FIH_CALL(boot_uuid_vid_match, fih_rc, image_index, &img_uuid_vid);
504+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
505+
FIH_SET(uuid_vid_valid, FIH_FAILURE);
506+
goto out;
507+
}
508+
509+
/* The image's vendor identifier has been successfully verified. */
510+
uuid_vid_valid = fih_rc;
511+
break;
512+
}
513+
#endif
514+
#ifdef MCUBOOT_UUID_CID
515+
case IMAGE_TLV_UUID_CID:
516+
{
517+
/*
518+
* Verify the image's class ID length.
519+
* This must always be present.
520+
*/
521+
if (len != sizeof(img_uuid_cid)) {
522+
/* Image class UUID is not valid. */
523+
rc = -1;
524+
goto out;
525+
}
526+
527+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_cid.raw, len);
528+
if (rc) {
529+
goto out;
530+
}
531+
532+
FIH_CALL(boot_uuid_cid_match, fih_rc, image_index, &img_uuid_cid);
533+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
534+
FIH_SET(uuid_cid_valid, FIH_FAILURE);
535+
goto out;
536+
}
537+
538+
/* The image's class identifier has been successfully verified. */
539+
uuid_cid_valid = fih_rc;
540+
break;
541+
}
542+
#endif
473543
}
474544
}
475545

@@ -492,6 +562,19 @@ bootutil_img_validate(struct boot_loader_state *state,
492562
}
493563
#endif
494564

565+
#ifdef MCUBOOT_UUID_VID
566+
if (FIH_NOT_EQ(uuid_vid_valid, FIH_SUCCESS)) {
567+
rc = -1;
568+
goto out;
569+
}
570+
#endif
571+
#ifdef MCUBOOT_UUID_CID
572+
if (FIH_NOT_EQ(uuid_cid_valid, FIH_SUCCESS)) {
573+
rc = -1;
574+
goto out;
575+
}
576+
#endif
577+
495578
out:
496579
if (rc) {
497580
FIH_SET(fih_rc, FIH_FAILURE);

boot/zephyr/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,18 @@ config MCUBOOT_HW_DOWNGRADE_PREVENTION_COUNTER_LIMITED
10711071

10721072
endchoice
10731073

1074+
config MCUBOOT_UUID_VID
1075+
bool "Expect vendor unique identifier in image's TLV"
1076+
help
1077+
Provide a vendor identification scheme to prevent processing images
1078+
generated by a different vendor.
1079+
1080+
config MCUBOOT_UUID_CID
1081+
bool "Expect image class unique identifier in image's TLV"
1082+
help
1083+
Provide an image class identification scheme to prevent processing
1084+
images for a different CPU or device produced by the same vendor.
1085+
10741086
config BOOT_WATCHDOG_FEED
10751087
bool "Feed the watchdog while doing swap"
10761088
default y if WATCHDOG

boot/zephyr/include/mcuboot_config/mcuboot_config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,14 @@
232232
#define MCUBOOT_HW_ROLLBACK_PROT_COUNTER_LIMITED
233233
#endif
234234

235+
#ifdef CONFIG_MCUBOOT_UUID_VID
236+
#define MCUBOOT_UUID_VID
237+
#endif
238+
239+
#ifdef CONFIG_MCUBOOT_UUID_CID
240+
#define MCUBOOT_UUID_CID
241+
#endif
242+
235243
#ifdef CONFIG_MEASURED_BOOT
236244
#define MCUBOOT_MEASURED_BOOT
237245
#endif

boot/zephyr/main.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
#include "bootutil/mcuboot_status.h"
4949
#include "flash_map_backend/flash_map_backend.h"
5050

51+
#if defined(CONFIG_MCUBOOT_UUID_VID) || defined(CONFIG_MCUBOOT_UUID_CID)
52+
#include "bootutil/mcuboot_uuid.h"
53+
#endif /* CONFIG_MCUBOOT_UUID_VID || CONFIG_MCUBOOT_UUID_CID */
54+
5155
/* Check if Espressif target is supported */
5256
#ifdef CONFIG_SOC_FAMILY_ESPRESSIF_ESP32
5357

@@ -521,6 +525,14 @@ int main(void)
521525

522526
mcuboot_status_change(MCUBOOT_STATUS_STARTUP);
523527

528+
#if defined(CONFIG_MCUBOOT_UUID_VID) || defined(CONFIG_MCUBOOT_UUID_CID)
529+
FIH_CALL(boot_uuid_init, fih_rc);
530+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
531+
BOOT_LOG_ERR("Unable to initialize UUID module: %d", fih_rc);
532+
FIH_PANIC;
533+
}
534+
#endif /* CONFIG_MCUBOOT_UUID_VID || CONFIG_MCUBOOT_UUID_CID */
535+
524536
#ifdef CONFIG_BOOT_SERIAL_ENTRANCE_GPIO
525537
BOOT_LOG_DBG("Checking GPIO for serial recovery");
526538
if (io_detect_pin() &&

docs/design.md

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,54 @@ struct image_tlv {
104104
/*
105105
* Image trailer TLV types.
106106
*/
107-
#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
108-
#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
109-
#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
110-
#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output - Not supported anymore */
111-
#define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */
112-
#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
113-
#define IMAGE_TLV_ED25519 0x24 /* ED25519 of hash output */
114-
#define IMAGE_TLV_SIG_PURE 0x25 /* If true then any signature found has been
115-
calculated over image directly. */
116-
#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
117-
#define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW-128 or
118-
256 */
119-
#define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-P256 */
120-
#define IMAGE_TLV_ENC_X25519 0x33 /* Key encrypted with ECIES-X25519 */
121-
#define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */
122-
#define IMAGE_TLV_SEC_CNT 0x50 /* security counter */
107+
#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
108+
#define IMAGE_TLV_PUBKEY 0x02 /* public key */
109+
#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
110+
#define IMAGE_TLV_SHA384 0x11 /* SHA384 of image hdr and body */
111+
#define IMAGE_TLV_SHA512 0x12 /* SHA512 of image hdr and body */
112+
#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
113+
#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output - Not supported anymore */
114+
#define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */
115+
#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
116+
#define IMAGE_TLV_ED25519 0x24 /* ed25519 of hash output */
117+
#define IMAGE_TLV_SIG_PURE 0x25 /* Indicator that attached signature has been prepared
118+
* over image rather than its digest.
119+
*/
120+
#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
121+
#define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW 128 or 256*/
122+
#define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-EC256 */
123+
#define IMAGE_TLV_ENC_X25519 0x33 /* Key encrypted with ECIES-X25519 */
124+
#define IMAGE_TLV_ENC_X25519_SHA512 0x34 /* Key exchange using ECIES-X25519 and SHA512 for MAC
125+
* tag and HKDF in key derivation process
126+
*/
127+
#define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */
128+
#define IMAGE_TLV_SEC_CNT 0x50 /* security counter */
129+
#define IMAGE_TLV_BOOT_RECORD 0x60 /* measured boot record */
130+
/* The following flags relate to compressed images and are for the decompressed image data */
131+
#define IMAGE_TLV_DECOMP_SIZE 0x70 /* Decompressed image size excluding header/TLVs */
132+
#define IMAGE_TLV_DECOMP_SHA 0x71 /*
133+
* Decompressed image shaX hash, this field must match
134+
* the format and size of the raw slot (compressed)
135+
* shaX hash
136+
*/
137+
#define IMAGE_TLV_DECOMP_SIGNATURE 0x72 /*
138+
* Decompressed image signature, this field must match
139+
* the format and size of the raw slot (compressed)
140+
* signature
141+
*/
142+
#define IMAGE_TLV_COMP_DEC_SIZE 0x73 /* Compressed decrypted image size */
143+
/*
144+
* vendor reserved TLVs at xxA0-xxFF,
145+
* where xx denotes the upper byte
146+
* range. Examples:
147+
* 0x00a0 - 0x00ff
148+
* 0x01a0 - 0x01ff
149+
* 0x02a0 - 0x02ff
150+
* ...
151+
* 0xffa0 - 0xfffe
152+
*/
153+
#define IMAGE_TLV_UUID_VID 0x80 /* Vendor unique identifier */
154+
#define IMAGE_TLV_UUID_CID 0x81 /* Device class unique identifier */
123155
```
124156
125157
Optional type-length-value records (TLVs) containing image metadata are placed

0 commit comments

Comments
 (0)