Skip to content

Commit 73a93f7

Browse files
committed
bootutil: Add support for multi-sign of same type
This commit adds functionality to the bootutil library to support multiple sign verfication of same type when 'MCUBOOT_BUILTIN_KEY' or 'MCUBOOT_HW_KEY' is enabled. The image_validate.c file is refactored such that: * bootutil_find_key() find the key is moved to a new file bootutil_find_key.c. * bootutil_image_hash() is moved to a new file bootutil_image_hash.c. * bootutil_img_security_cnt() is moved to a new file bootutil_img_security_cnt.c. This allows common validation code to be reused for multiple signatures. All code specific to multi sign is under the option 'MCUBOOT_IMAGE_MULTI_SIG_SUPPORT'. Furthermore, key id type is updated to uint32_t as per PSA crypto spec. Signed-off-by: Maulik Patel <maulik.patel@arm.com> Change-Id: I05c97ac385c5816c812c51feb010028df8412fe5
1 parent 491eb47 commit 73a93f7

File tree

11 files changed

+508
-324
lines changed

11 files changed

+508
-324
lines changed

boot/bootutil/CMakeLists.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#------------------------------------------------------------------------------
2-
# Copyright (c) 2020-2023, Arm Limited. All rights reserved.
2+
# Copyright (c) 2020-2025, Arm Limited. All rights reserved.
33
#
44
# SPDX-License-Identifier: Apache-2.0
55
#
@@ -17,6 +17,8 @@ target_include_directories(bootutil
1717
target_sources(bootutil
1818
PRIVATE
1919
src/boot_record.c
20+
src/bootutil_find_key.c
21+
src/bootutil_image_hash.c
2022
src/bootutil_misc.c
2123
src/bootutil_public.c
2224
src/caps.c
@@ -33,9 +35,24 @@ target_sources(bootutil
3335
src/swap_scratch.c
3436
src/tlv.c
3537
)
38+
39+
if(MCUBOOT_HW_ROLLBACK_PROT)
40+
target_sources(bootutil
41+
PRIVATE
42+
src/bootutil_img_security_cnt.c
43+
)
44+
endif()
45+
3646
if(CONFIG_BOOT_RAM_LOAD)
3747
target_sources(bootutil
3848
PRIVATE
3949
src/ram_load.c
4050
)
4151
endif()
52+
53+
target_compile_definitions(bootutil
54+
PRIVATE
55+
$<$<BOOL:${MCUBOOT_IMAGE_MULTI_SIG_SUPPORT}>:MCUBOOT_IMAGE_MULTI_SIG_SUPPORT>
56+
$<$<BOOL:${MCUBOOT_IMAGE_MULTI_SIG_SUPPORT}>:MCUBOOT_ROTPK_MAX_KEYS_PER_IMAGE=${MCUBOOT_ROTPK_MAX_KEYS_PER_IMAGE}>
57+
)
58+

boot/bootutil/include/bootutil/image.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,23 @@ int32_t bootutil_get_img_security_cnt(struct boot_loader_state *state, int slot,
237237
const struct flash_area *fap,
238238
uint32_t *img_security_cnt);
239239

240+
#if defined(MCUBOOT_BUILTIN_KEY)
241+
int bootutil_find_key(uint8_t image_index, uint8_t *key_id_buf, uint8_t key_id_buf_len);
242+
#elif defined(MCUBOOT_HW_KEY)
243+
int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len);
244+
#else
245+
int bootutil_find_key(uint8_t image_index, uint8_t *keyhash, uint8_t keyhash_len);
246+
#endif
247+
248+
int bootutil_img_hash(struct boot_loader_state *state,
249+
struct image_header *hdr, const struct flash_area *fap,
250+
uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result,
251+
uint8_t *seed, int seed_len
252+
#if defined(MCUBOOT_SWAP_USING_OFFSET) && defined(MCUBOOT_SERIAL_RECOVERY)
253+
, uint32_t start_offset
254+
#endif
255+
);
256+
240257
#ifdef __cplusplus
241258
}
242259
#endif

boot/bootutil/include/bootutil/sign_key.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,18 @@ extern struct bootutil_key bootutil_keys[];
6262
* Retrieve the hash of the corresponding public key for image authentication.
6363
*
6464
* @param[in] image_index Index of the image to be authenticated.
65+
* @param[in] key_index Index of the key to be used.
6566
* @param[out] public_key_hash Buffer to store the key-hash in.
6667
* @param[in,out] key_hash_size As input the size of the buffer. As output
6768
* the actual key-hash length.
6869
*
6970
* @return 0 on success; nonzero on failure.
7071
*/
7172
int boot_retrieve_public_key_hash(uint8_t image_index,
73+
uint8_t key_index,
7274
uint8_t *public_key_hash,
7375
size_t *key_hash_size);
76+
7477
#endif /* !MCUBOOT_HW_KEY */
7578

7679
extern const int bootutil_key_cnt;

boot/bootutil/src/bootutil_find_key.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright (c) 2017-2019 Linaro LTD
5+
* Copyright (c) 2016-2019 JUUL Labs
6+
* Copyright (c) 2019-2025 Arm Limited
7+
* Copyright (c) 2025 Nordic Semiconductor ASA
8+
*
9+
* Original license:
10+
*
11+
* Licensed to the Apache Software Foundation (ASF) under one
12+
* or more contributor license agreements. See the NOTICE file
13+
* distributed with this work for additional information
14+
* regarding copyright ownership. The ASF licenses this file
15+
* to you under the Apache License, Version 2.0 (the
16+
* "License"); you may not use this file except in compliance
17+
* with the License. You may obtain a copy of the License at
18+
*
19+
* http://www.apache.org/licenses/LICENSE-2.0
20+
*
21+
* Unless required by applicable law or agreed to in writing,
22+
* software distributed under the License is distributed on an
23+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
24+
* KIND, either express or implied. See the License for the
25+
* specific language governing permissions and limitations
26+
* under the License.
27+
*/
28+
29+
#include <stdint.h>
30+
#include <flash_map_backend/flash_map_backend.h>
31+
32+
#include "bootutil/bootutil_log.h"
33+
#include "bootutil/crypto/sha.h"
34+
#include "bootutil/fault_injection_hardening.h"
35+
#include "bootutil/image.h"
36+
#include "bootutil/sign_key.h"
37+
#include "bootutil_priv.h"
38+
#include "mcuboot_config/mcuboot_config.h"
39+
40+
#ifdef MCUBOOT_IMAGE_MULTI_SIG_SUPPORT
41+
#define NUM_OF_KEYS MCUBOOT_ROTPK_MAX_KEYS_PER_IMAGE
42+
#else
43+
#define NUM_OF_KEYS 1
44+
#endif /* MCUBOOT_IMAGE_MULTI_SIG_SUPPORT */
45+
46+
#if defined(MCUBOOT_BUILTIN_KEY)
47+
int bootutil_find_key(uint8_t image_index, uint8_t *key_id_buf, uint8_t key_id_buf_len)
48+
{
49+
int rc;
50+
uint32_t key_id;
51+
FIH_DECLARE(fih_rc, FIH_FAILURE);
52+
53+
/* Key id is passed */
54+
assert(key_id_buf_len == sizeof(uint32_t));
55+
key_id = (((uint32_t)key_id_buf[0] << 24) |
56+
((uint32_t)key_id_buf[1] << 16) |
57+
((uint32_t)key_id_buf[2] << 8) |
58+
((uint32_t)key_id_buf[3]));
59+
60+
/* Check if key id is associated with the image */
61+
FIH_CALL(boot_verify_key_id_for_image, fih_rc, image_index, key_id);
62+
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
63+
return (int32_t)key_id;
64+
}
65+
66+
return -1;
67+
}
68+
69+
#elif defined(MCUBOOT_HW_KEY)
70+
extern unsigned int pub_key_len;
71+
int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
72+
{
73+
bootutil_sha_context sha_ctx;
74+
uint8_t hash[IMAGE_HASH_SIZE];
75+
uint8_t key_hash[IMAGE_HASH_SIZE];
76+
size_t key_hash_size = sizeof(key_hash);
77+
int rc;
78+
uint8_t key_index;
79+
FIH_DECLARE(fih_rc, FIH_FAILURE);
80+
81+
bootutil_sha_init(&sha_ctx);
82+
bootutil_sha_update(&sha_ctx, key, key_len);
83+
bootutil_sha_finish(&sha_ctx, hash);
84+
bootutil_sha_drop(&sha_ctx);
85+
86+
for(key_index = 0; key_index < NUM_OF_KEYS; key_index++) {
87+
rc = boot_retrieve_public_key_hash(image_index, key_index, key_hash, &key_hash_size);
88+
if (rc) {
89+
return -1;
90+
}
91+
92+
/* Adding hardening to avoid this potential attack:
93+
* - Image is signed with an arbitrary key and the corresponding public
94+
* key is added as a TLV field.
95+
* - During public key validation (comparing against key-hash read from
96+
* HW) a fault is injected to accept the public key as valid one.
97+
*/
98+
FIH_CALL(boot_fih_memequal, fih_rc, hash, key_hash, key_hash_size);
99+
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
100+
BOOT_LOG_INF("Key %d hash found for image %d", key_index, image_index);
101+
bootutil_keys[0].key = key;
102+
pub_key_len = key_len;
103+
return 0;
104+
}
105+
}
106+
BOOT_LOG_ERR("Key hash NOT found for image %d!", image_index);
107+
108+
return -1;
109+
}
110+
111+
#else /* !defined MCUBOOT_BUILTIN_KEY && !defined MCUBOOT_HW_KEY */
112+
int bootutil_find_key(uint8_t image_index, uint8_t *keyhash, uint8_t keyhash_len)
113+
{
114+
bootutil_sha_context sha_ctx;
115+
int i;
116+
uint8_t hash[IMAGE_HASH_SIZE];
117+
const struct bootutil_key *key;
118+
(void)image_index;
119+
120+
if (keyhash_len > IMAGE_HASH_SIZE) {
121+
return -1;
122+
}
123+
124+
for (i = 0; i < bootutil_key_cnt; i++) {
125+
key = &bootutil_keys[i];
126+
bootutil_sha_init(&sha_ctx);
127+
bootutil_sha_update(&sha_ctx, key->key, *key->len);
128+
bootutil_sha_finish(&sha_ctx, hash);
129+
bootutil_sha_drop(&sha_ctx);
130+
if (!memcmp(hash, keyhash, keyhash_len)) {
131+
return i;
132+
}
133+
}
134+
return -1;
135+
}
136+
#endif
137+

0 commit comments

Comments
 (0)