Skip to content

Commit 90ad95e

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 21e614f commit 90ad95e

File tree

4 files changed

+197
-17
lines changed

4 files changed

+197
-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: 84 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
#endif
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;
@@ -553,6 +557,14 @@ bootutil_img_validate(struct boot_loader_state *state,
553557
goto out;
554558
}
555559
#endif
560+
#ifdef MCUBOOT_UUID_VID
561+
struct image_uuid img_uuid_vid = {0x00};
562+
FIH_DECLARE(uuid_vid_valid, FIH_FAILURE);
563+
#endif
564+
#ifdef MCUBOOT_UUID_CID
565+
struct image_uuid img_uuid_cid = {0x00};
566+
FIH_DECLARE(uuid_cid_valid, FIH_FAILURE);
567+
#endif
556568

557569
BOOT_LOG_DBG("bootutil_img_validate: flash area %p", fap);
558570

@@ -793,6 +805,64 @@ bootutil_img_validate(struct boot_loader_state *state,
793805
break;
794806
}
795807
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
808+
#ifdef MCUBOOT_UUID_VID
809+
case IMAGE_TLV_UUID_VID:
810+
{
811+
/*
812+
* Verify the image's vendor ID length.
813+
* This must always be present.
814+
*/
815+
if (len != sizeof(img_uuid_vid)) {
816+
/* Vendor UUID is not valid. */
817+
rc = -1;
818+
goto out;
819+
}
820+
821+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_vid.raw, len);
822+
if (rc) {
823+
goto out;
824+
}
825+
826+
FIH_CALL(boot_uuid_vid_match, fih_rc, image_index, &img_uuid_vid);
827+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
828+
FIH_SET(uuid_vid_valid, FIH_FAILURE);
829+
goto out;
830+
}
831+
832+
/* The image's vendor identifier has been successfully verified. */
833+
uuid_vid_valid = fih_rc;
834+
break;
835+
}
836+
#endif
837+
#ifdef MCUBOOT_UUID_CID
838+
case IMAGE_TLV_UUID_CID:
839+
{
840+
/*
841+
* Verify the image's class ID length.
842+
* This must always be present.
843+
*/
844+
if (len != sizeof(img_uuid_cid)) {
845+
/* Image class UUID is not valid. */
846+
rc = -1;
847+
goto out;
848+
}
849+
850+
rc = LOAD_IMAGE_DATA(hdr, fap, off, img_uuid_cid.raw, len);
851+
if (rc) {
852+
goto out;
853+
}
854+
855+
FIH_CALL(boot_uuid_cid_match, fih_rc, image_index, &img_uuid_cid);
856+
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
857+
FIH_SET(uuid_cid_valid, FIH_FAILURE);
858+
goto out;
859+
}
860+
861+
/* The image's class identifier has been successfully verified. */
862+
uuid_cid_valid = fih_rc;
863+
break;
864+
}
865+
#endif
796866
}
797867
}
798868

@@ -821,6 +891,19 @@ bootutil_img_validate(struct boot_loader_state *state,
821891
skip_security_counter_check:
822892
#endif
823893

894+
#ifdef MCUBOOT_UUID_VID
895+
if (FIH_NOT_EQ(uuid_vid_valid, FIH_SUCCESS)) {
896+
rc = -1;
897+
goto out;
898+
}
899+
#endif
900+
#ifdef MCUBOOT_UUID_CID
901+
if (FIH_NOT_EQ(uuid_cid_valid, FIH_SUCCESS)) {
902+
rc = -1;
903+
goto out;
904+
}
905+
#endif
906+
824907
out:
825908
if (rc) {
826909
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)