Skip to content

Commit 670dac4

Browse files
committed
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 2bc36d0 commit 670dac4

File tree

4 files changed

+199
-17
lines changed

4 files changed

+199
-17
lines changed

boot/bootutil/include/bootutil/image.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ extern "C" {
142142
* ...
143143
* 0xffa0 - 0xfffe
144144
*/
145+
#define IMAGE_TLV_UUID_VID 0x80 /* Vendor unique identifier */
146+
#define IMAGE_TLV_UUID_CID 0x81 /* Device class unique identifier */
145147
#define IMAGE_TLV_ANY 0xffff /* Used to iterate over all TLV */
146148

147149
#define VERSION_DEP_SLOT_ACTIVE 0x00 /* Check dependency against active slot. */
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 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: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
#include "bootutil/bootutil_log.h"
4545

4646
BOOT_LOG_MODULE_DECLARE(mcuboot);
47+
#if defined(MCUBOOT_UUID_VID) || defined(MCUBOOT_UUID_CID)
48+
#include "bootutil/mcuboot_uuid.h"
49+
#endif /* MCUBOOT_UUID_VID || MCUBOOT_UUID_CID */
4750

4851
#ifdef MCUBOOT_ENC_IMAGES
4952
#include "bootutil/enc_key.h"
@@ -507,7 +510,8 @@ bootutil_img_validate(struct boot_loader_state *state,
507510
int seed_len, uint8_t *out_hash
508511
)
509512
{
510-
#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT)
513+
#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT) \
514+
|| defined(MCUBOOT_UUID_VID) || defined(MCUBOOT_UUID_CID)
511515
int image_index = (state == NULL ? 0 : BOOT_CURR_IMG(state));
512516
#endif
513517
uint32_t off;
@@ -541,6 +545,14 @@ bootutil_img_validate(struct boot_loader_state *state,
541545
uint32_t img_security_cnt = 0;
542546
FIH_DECLARE(security_counter_valid, FIH_FAILURE);
543547
#endif
548+
#ifdef MCUBOOT_UUID_VID
549+
struct image_uuid img_uuid_vid = {0x00};
550+
FIH_DECLARE(uuid_vid_valid, FIH_FAILURE);
551+
#endif
552+
#ifdef MCUBOOT_UUID_CID
553+
struct image_uuid img_uuid_cid = {0x00};
554+
FIH_DECLARE(uuid_cid_valid, FIH_FAILURE);
555+
#endif
544556

545557
BOOT_LOG_DBG("bootutil_img_validate: flash area %p", fap);
546558

@@ -749,6 +761,66 @@ bootutil_img_validate(struct boot_loader_state *state,
749761
break;
750762
}
751763
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
764+
#ifdef MCUBOOT_UUID_VID
765+
case IMAGE_TLV_UUID_VID:
766+
{
767+
/*
768+
* Verify the image's vendor ID length.
769+
* This must always be present.
770+
*/
771+
if (len != sizeof(img_uuid_vid)) {
772+
/* Vendor UUID is not valid. */
773+
rc = -1;
774+
goto out;
775+
}
776+
777+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_vid.raw, len);
778+
if (rc) {
779+
goto out;
780+
}
781+
782+
FIH_CALL(boot_uuid_vid_match, fih_rc, image_index, &img_uuid_vid);
783+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
784+
FIH_SET(fih_rc, FIH_FAILURE);
785+
goto out;
786+
}
787+
788+
/* The image's vendor identifier has been successfully verified. */
789+
uuid_vid_valid = fih_rc;
790+
skip_vid_read:
791+
break;
792+
}
793+
#endif
794+
#ifdef MCUBOOT_UUID_CID
795+
case IMAGE_TLV_UUID_CID:
796+
{
797+
/*
798+
* Verify the image's class ID length.
799+
* This must always be present.
800+
*/
801+
if (len != sizeof(img_uuid_cid)) {
802+
/* Image class UUID is not valid. */
803+
rc = -1;
804+
goto out;
805+
}
806+
807+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_cid.raw, len);
808+
if (rc) {
809+
goto out;
810+
}
811+
812+
FIH_CALL(boot_uuid_cid_match, fih_rc, image_index, &img_uuid_cid);
813+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
814+
FIH_SET(fih_rc, FIH_FAILURE);
815+
goto out;
816+
}
817+
818+
/* The image's class identifier has been successfully verified. */
819+
uuid_cid_valid = fih_rc;
820+
skip_cid_read:
821+
break;
822+
}
823+
#endif
752824
}
753825
}
754826

@@ -771,6 +843,19 @@ bootutil_img_validate(struct boot_loader_state *state,
771843
}
772844
#endif
773845

846+
#ifdef MCUBOOT_UUID_VID
847+
if (FIH_NOT_EQ(uuid_vid_valid, FIH_SUCCESS)) {
848+
rc = -1;
849+
goto out;
850+
}
851+
#endif
852+
#ifdef MCUBOOT_UUID_CID
853+
if (FIH_NOT_EQ(uuid_cid_valid, FIH_SUCCESS)) {
854+
rc = -1;
855+
goto out;
856+
}
857+
#endif
858+
774859
out:
775860
if (rc) {
776861
FIH_SET(fih_rc, FIH_FAILURE);

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)