Skip to content

Commit c7a67e7

Browse files
committed
bootutil: Parse key id for built in keys
When MCUBOOT_BUILTIN_KEY is enabled, the key id TLV entry is added to the image. Parse this entry while validating the image to identify the key used to sign the image. This enables future support for scenarios such as multiple built-in keys or multi-signature. Signed-off-by: Maulik Patel <maulik.patel@arm.com> Change-Id: Ibe26bc2b09e63350f4214719606a5aa4bc1be93c
1 parent c412cdf commit c7a67e7

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed

boot/bootutil/include/bootutil/crypto/ecdsa.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,6 @@ static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx)
392392
ctx->required_algorithm = 0;
393393

394394
#else /* !MCUBOOT_BUILTIN_KEY */
395-
/* The incoming key ID is equal to the image index. The key ID value must be
396-
* shifted (by one in this case) because zero is reserved (PSA_KEY_ID_NULL)
397-
* and considered invalid.
398-
*/
399-
ctx->key_id++; /* Make sure it is not equal to 0. */
400395
#if defined(MCUBOOT_SIGN_EC256)
401396
ctx->curve_byte_count = 32;
402397
ctx->required_algorithm = PSA_ALG_SHA_256;

boot/bootutil/include/bootutil/image.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct flash_area;
100100
*/
101101
#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
102102
#define IMAGE_TLV_PUBKEY 0x02 /* public key */
103+
#define IMAGE_TLV_KEYID 0x03 /* Key ID */
103104
#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
104105
#define IMAGE_TLV_SHA384 0x11 /* SHA384 of image hdr and body */
105106
#define IMAGE_TLV_SHA512 0x12 /* SHA512 of image hdr and body */

boot/bootutil/src/image_validate.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,21 @@ bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
335335
return -1;
336336
}
337337
#endif /* !MCUBOOT_HW_KEY */
338+
339+
#else
340+
/* For MCUBOOT_BUILTIN_KEY, key id is passed */
341+
#define EXPECTED_KEY_TLV IMAGE_TLV_KEYID
342+
#define KEY_BUF_SIZE sizeof(int)
343+
344+
static int bootutil_find_key(uint8_t *key_id_buf, uint8_t key_id_buf_len)
345+
{
346+
/* Key id is passed */
347+
assert(key_id_buf_len == sizeof(int32_t));
348+
return ((int32_t)key_id_buf[0] << 24) |
349+
((int32_t)key_id_buf[1] << 16) |
350+
((int32_t)key_id_buf[2] << 8) |
351+
((int32_t)key_id_buf[3]);
352+
}
338353
#endif /* !MCUBOOT_BUILTIN_KEY */
339354
#endif /* EXPECTED_SIG_TLV */
340355

@@ -450,6 +465,7 @@ static int bootutil_check_for_pure(const struct image_header *hdr,
450465
static const uint16_t allowed_unprot_tlvs[] = {
451466
IMAGE_TLV_KEYHASH,
452467
IMAGE_TLV_PUBKEY,
468+
IMAGE_TLV_KEYID,
453469
IMAGE_TLV_SHA256,
454470
IMAGE_TLV_SHA384,
455471
IMAGE_TLV_SHA512,
@@ -492,14 +508,7 @@ bootutil_img_validate(struct boot_loader_state *state,
492508
uint16_t type;
493509
#ifdef EXPECTED_SIG_TLV
494510
FIH_DECLARE(valid_signature, FIH_FAILURE);
495-
#ifndef MCUBOOT_BUILTIN_KEY
496511
int key_id = -1;
497-
#else
498-
/* Pass a key ID equal to the image index, the underlying crypto library
499-
* is responsible for mapping the image index to a builtin key ID.
500-
*/
501-
int key_id = image_index;
502-
#endif /* !MCUBOOT_BUILTIN_KEY */
503512
#ifdef MCUBOOT_HW_KEY
504513
uint8_t key_buf[KEY_BUF_SIZE];
505514
#endif

scripts/imgtool/image.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
TLV_VALUES = {
7777
'KEYHASH': 0x01,
7878
'PUBKEY': 0x02,
79+
'KEYID': 0x03,
7980
'SHA256': 0x10,
8081
'SHA384': 0x11,
8182
'SHA512': 0x12,
@@ -135,13 +136,19 @@ def add(self, kind, payload):
135136
"""
136137
e = STRUCT_ENDIAN_DICT[self.endian]
137138
if isinstance(kind, int):
138-
if not TLV_VENDOR_RES_MIN <= kind <= TLV_VENDOR_RES_MAX:
139+
if kind in TLV_VALUES.values():
140+
buf = struct.pack(e + 'I', kind)
141+
elif TLV_VENDOR_RES_MIN <= kind <= TLV_VENDOR_RES_MAX:
142+
# Custom vendor-reserved tag
143+
buf = struct.pack(e + 'HH', kind, len(payload))
144+
else:
139145
msg = "Invalid custom TLV type value '0x{:04x}', allowed " \
140146
"value should be between 0x{:04x} and 0x{:04x}".format(
141147
kind, TLV_VENDOR_RES_MIN, TLV_VENDOR_RES_MAX)
142148
raise click.UsageError(msg)
143-
buf = struct.pack(e + 'HH', kind, len(payload))
144149
else:
150+
if kind not in TLV_VALUES:
151+
raise click.UsageError(f"Unknown TLV type string: {kind}")
145152
buf = struct.pack(e + 'BBH', TLV_VALUES[kind], 0, len(payload))
146153
self.buf += buf
147154
self.buf += payload
@@ -632,6 +639,9 @@ def create(self, key, public_key_format, enckey, dependencies=None,
632639
print(os.path.basename(__file__) + ': export digest')
633640
return
634641

642+
if self.key_ids is not None:
643+
self._add_key_id_tlv_to_unprotected(tlv, self.key_ids[0])
644+
635645
if key is not None or fixed_sig is not None:
636646
if public_key_format == 'hash':
637647
tlv.add('KEYHASH', pubbytes)
@@ -883,3 +893,13 @@ def verify(imgfile, key):
883893
pass
884894
tlv_off += TLV_SIZE + tlv_len
885895
return VerifyResult.INVALID_SIGNATURE, None, None, None
896+
897+
def set_key_ids(self, key_ids):
898+
"""Set list of key IDs (integers) to be inserted before each signature."""
899+
self.key_ids = key_ids
900+
901+
def _add_key_id_tlv_to_unprotected(self, tlv, key_id: int):
902+
"""Add a key ID TLV into the *unprotected* TLV area."""
903+
tag = TLV_VALUES['KEYID']
904+
value = key_id.to_bytes(4, 'big')
905+
tlv.add(tag, value)

0 commit comments

Comments
 (0)