Skip to content

Commit 6c9711b

Browse files
committed
[nrf fromlist] boot: Add VID and CID checks
Add a possibility to express vendor ID and image class ID inside image's TLVs. Upstream PR #: 2409 Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent d69621e commit 6c9711b

File tree

4 files changed

+196
-17
lines changed

4 files changed

+196
-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: 83 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
#if defined(MCUBOOT_DECOMPRESS_IMAGES)
4952
#include <nrf_compress/implementation.h>
@@ -515,7 +518,7 @@ bootutil_img_validate(struct boot_loader_state *state,
515518
)
516519
{
517520
#if (defined(EXPECTED_KEY_TLV) && defined(MCUBOOT_HW_KEY)) || defined(MCUBOOT_HW_ROLLBACK_PROT) || defined(MCUBOOT_DECOMPRESS_IMAGES) \
518-
|| defined(MCUBOOT_BUILTIN_KEY)
521+
|| defined(MCUBOOT_BUILTIN_KEY) || defined(MCUBOOT_UUID_VID) || defined(MCUBOOT_UUID_CID)
519522
int image_index = (state == NULL ? 0 : BOOT_CURR_IMG(state));
520523
#endif
521524
uint32_t off;
@@ -558,6 +561,14 @@ bootutil_img_validate(struct boot_loader_state *state,
558561
goto out;
559562
}
560563
#endif
564+
#ifdef MCUBOOT_UUID_VID
565+
struct image_uuid img_uuid_vid = {0x00};
566+
FIH_DECLARE(uuid_vid_valid, FIH_FAILURE);
567+
#endif
568+
#ifdef MCUBOOT_UUID_CID
569+
struct image_uuid img_uuid_cid = {0x00};
570+
FIH_DECLARE(uuid_cid_valid, FIH_FAILURE);
571+
#endif
561572

562573
BOOT_LOG_DBG("bootutil_img_validate: flash area %p", fap);
563574
#ifdef MCUBOOT_DECOMPRESS_IMAGES
@@ -845,6 +856,64 @@ bootutil_img_validate(struct boot_loader_state *state,
845856
break;
846857
}
847858
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
859+
#ifdef MCUBOOT_UUID_VID
860+
case IMAGE_TLV_UUID_VID:
861+
{
862+
/*
863+
* Verify the image's vendor ID length.
864+
* This must always be present.
865+
*/
866+
if (len != sizeof(img_uuid_vid)) {
867+
/* Vendor UUID is not valid. */
868+
rc = -1;
869+
goto out;
870+
}
871+
872+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_vid.raw, len);
873+
if (rc) {
874+
goto out;
875+
}
876+
877+
FIH_CALL(boot_uuid_vid_match, fih_rc, image_index, &img_uuid_vid);
878+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
879+
FIH_SET(fih_rc, FIH_FAILURE);
880+
goto out;
881+
}
882+
883+
/* The image's vendor identifier has been successfully verified. */
884+
uuid_vid_valid = fih_rc;
885+
break;
886+
}
887+
#endif
888+
#ifdef MCUBOOT_UUID_CID
889+
case IMAGE_TLV_UUID_CID:
890+
{
891+
/*
892+
* Verify the image's class ID length.
893+
* This must always be present.
894+
*/
895+
if (len != sizeof(img_uuid_cid)) {
896+
/* Image class UUID is not valid. */
897+
rc = -1;
898+
goto out;
899+
}
900+
901+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_cid.raw, len);
902+
if (rc) {
903+
goto out;
904+
}
905+
906+
FIH_CALL(boot_uuid_cid_match, fih_rc, image_index, &img_uuid_cid);
907+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
908+
FIH_SET(fih_rc, FIH_FAILURE);
909+
goto out;
910+
}
911+
912+
/* The image's class identifier has been successfully verified. */
913+
uuid_cid_valid = fih_rc;
914+
break;
915+
}
916+
#endif
848917
}
849918
}
850919

@@ -1030,6 +1099,19 @@ bootutil_img_validate(struct boot_loader_state *state,
10301099
FIH_SET(fih_rc, valid_signature);
10311100
#endif
10321101

1102+
#ifdef MCUBOOT_UUID_VID
1103+
if (FIH_NOT_EQ(uuid_vid_valid, FIH_SUCCESS)) {
1104+
rc = -1;
1105+
goto out;
1106+
}
1107+
#endif
1108+
#ifdef MCUBOOT_UUID_CID
1109+
if (FIH_NOT_EQ(uuid_cid_valid, FIH_SUCCESS)) {
1110+
rc = -1;
1111+
goto out;
1112+
}
1113+
#endif
1114+
10331115
out:
10341116
if (rc) {
10351117
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)