Skip to content

Commit 6b70855

Browse files
maulik-armdavidvincze
authored andcommitted
bootutil: (refactor) split image_validate.c into separate files
Move bootutil_find_key(), bootutil_img_hash(), and bootutil_img_security_cnt() into their own source files for cleaner No functional changes have been made. Signed-off-by: Maulik Patel <[email protected]> Change-Id: I5d3f4a1327356238e5865dba91b4ec251ffcf1aa
1 parent 16cfdaf commit 6b70855

File tree

9 files changed

+460
-309
lines changed

9 files changed

+460
-309
lines changed

boot/bootutil/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ target_include_directories(bootutil
1717
target_sources(bootutil
1818
PRIVATE
1919
src/boot_record.c
20+
src/bootutil_find_key.c
21+
src/bootutil_img_hash.c
22+
src/bootutil_img_security_cnt.c
2023
src/bootutil_misc.c
2124
src/bootutil_public.c
2225
src/caps.c

boot/bootutil/include/bootutil/image.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,19 @@ int32_t bootutil_get_img_security_cnt(struct boot_loader_state *state, int slot,
243243
const struct flash_area *fap,
244244
uint32_t *img_security_cnt);
245245

246+
#if !defined(MCUBOOT_HW_KEY)
247+
int bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len);
248+
#else
249+
int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len);
250+
#endif
251+
252+
int
253+
bootutil_img_hash(struct boot_loader_state *state,
254+
struct image_header *hdr, const struct flash_area *fap,
255+
uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result,
256+
uint8_t *seed, int seed_len
257+
);
258+
246259
#ifdef __cplusplus
247260
}
248261
#endif

boot/bootutil/src/bootutil_find_key.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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+
31+
#include "bootutil/crypto/sha.h"
32+
#include "bootutil/fault_injection_hardening.h"
33+
#include "bootutil/image.h"
34+
#include "bootutil/sign_key.h"
35+
#include "bootutil_priv.h"
36+
#include "mcuboot_config/mcuboot_config.h"
37+
#include "bootutil/bootutil_log.h"
38+
39+
BOOT_LOG_MODULE_DECLARE(mcuboot);
40+
41+
#if defined(MCUBOOT_SIGN_RSA) || \
42+
defined(MCUBOOT_SIGN_EC256) || \
43+
defined(MCUBOOT_SIGN_EC384) || \
44+
defined(MCUBOOT_SIGN_EC) || \
45+
defined(MCUBOOT_SIGN_ED25519)
46+
#define EXPECTED_SIG_TLV
47+
#else
48+
/* no signing, sha256 digest only */
49+
#endif
50+
51+
#ifdef EXPECTED_SIG_TLV
52+
#if !defined(MCUBOOT_BYPASS_KEY_MATCH)
53+
/* Find functions are only needed when key is checked first */
54+
#if !defined(MCUBOOT_BUILTIN_KEY)
55+
#if !defined(MCUBOOT_HW_KEY)
56+
int bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len)
57+
{
58+
bootutil_sha_context sha_ctx;
59+
int i;
60+
const struct bootutil_key *key;
61+
uint8_t hash[IMAGE_HASH_SIZE];
62+
63+
BOOT_LOG_DBG("bootutil_find_key");
64+
65+
if (keyhash_len > IMAGE_HASH_SIZE) {
66+
return -1;
67+
}
68+
69+
for (i = 0; i < bootutil_key_cnt; i++) {
70+
key = &bootutil_keys[i];
71+
bootutil_sha_init(&sha_ctx);
72+
bootutil_sha_update(&sha_ctx, key->key, *key->len);
73+
bootutil_sha_finish(&sha_ctx, hash);
74+
bootutil_sha_drop(&sha_ctx);
75+
if (!memcmp(hash, keyhash, keyhash_len)) {
76+
return i;
77+
}
78+
}
79+
return -1;
80+
}
81+
#else /* !MCUBOOT_HW_KEY */
82+
extern unsigned int pub_key_len;
83+
int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
84+
{
85+
bootutil_sha_context sha_ctx;
86+
uint8_t hash[IMAGE_HASH_SIZE];
87+
uint8_t key_hash[IMAGE_HASH_SIZE];
88+
size_t key_hash_size = sizeof(key_hash);
89+
int rc;
90+
FIH_DECLARE(fih_rc, FIH_FAILURE);
91+
92+
BOOT_LOG_DBG("bootutil_find_key: image_index %d", image_index);
93+
94+
bootutil_sha_init(&sha_ctx);
95+
bootutil_sha_update(&sha_ctx, key, key_len);
96+
bootutil_sha_finish(&sha_ctx, hash);
97+
bootutil_sha_drop(&sha_ctx);
98+
99+
rc = boot_retrieve_public_key_hash(image_index, key_hash, &key_hash_size);
100+
if (rc) {
101+
return -1;
102+
}
103+
104+
/* Adding hardening to avoid this potential attack:
105+
* - Image is signed with an arbitrary key and the corresponding public
106+
* key is added as a TLV field.
107+
* - During public key validation (comparing against key-hash read from
108+
* HW) a fault is injected to accept the public key as valid one.
109+
*/
110+
FIH_CALL(boot_fih_memequal, fih_rc, hash, key_hash, key_hash_size);
111+
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
112+
bootutil_keys[0].key = key;
113+
pub_key_len = key_len;
114+
return 0;
115+
}
116+
117+
return -1;
118+
}
119+
#endif /* !MCUBOOT_HW_KEY */
120+
#endif /* !MCUBOOT_BUILTIN_KEY */
121+
122+
#else /* !MCUBOOT_BYPASS_KEY_MATCH */
123+
static inline int
124+
bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
125+
{
126+
(void)image_index;
127+
(void)key;
128+
(void)key_len;
129+
130+
/* There is only one key, so it always matches */
131+
return 0;
132+
}
133+
#endif /* !MCUBOOT_BYPASS_KEY_MATCH */
134+
#endif /* EXPECTED_SIG_TLV */

boot/bootutil/src/bootutil_img_hash.c

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
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/crypto/sha.h"
33+
#include "bootutil/image.h"
34+
#include "bootutil_priv.h"
35+
#include "mcuboot_config/mcuboot_config.h"
36+
#include "bootutil/bootutil_log.h"
37+
38+
BOOT_LOG_MODULE_DECLARE(mcuboot);
39+
40+
#ifndef MCUBOOT_SIGN_PURE
41+
/*
42+
* Compute SHA hash over the image.
43+
* (SHA384 if ECDSA-P384 is being used,
44+
* SHA256 otherwise).
45+
*/
46+
int
47+
bootutil_img_hash(struct boot_loader_state *state,
48+
struct image_header *hdr, const struct flash_area *fap,
49+
uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result,
50+
uint8_t *seed, int seed_len
51+
)
52+
{
53+
bootutil_sha_context sha_ctx;
54+
uint32_t size;
55+
uint16_t hdr_size;
56+
uint32_t blk_off;
57+
uint32_t tlv_off;
58+
#if !defined(MCUBOOT_HASH_STORAGE_DIRECTLY)
59+
int rc;
60+
uint32_t off;
61+
uint32_t blk_sz;
62+
#endif
63+
#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY
64+
uintptr_t base = 0;
65+
int fa_ret;
66+
#endif
67+
#if defined(MCUBOOT_ENC_IMAGES)
68+
struct enc_key_data *enc_state;
69+
int image_index;
70+
#endif
71+
#if defined(MCUBOOT_SWAP_USING_OFFSET)
72+
uint32_t sector_off = 0;
73+
#endif
74+
75+
#if (BOOT_IMAGE_NUMBER == 1) || !defined(MCUBOOT_ENC_IMAGES) || \
76+
defined(MCUBOOT_RAM_LOAD)
77+
(void)state;
78+
(void)hdr_size;
79+
(void)blk_off;
80+
(void)tlv_off;
81+
#ifdef MCUBOOT_RAM_LOAD
82+
(void)blk_sz;
83+
(void)off;
84+
(void)rc;
85+
(void)fap;
86+
(void)tmp_buf;
87+
(void)tmp_buf_sz;
88+
#endif
89+
#endif
90+
BOOT_LOG_DBG("bootutil_img_hash");
91+
92+
#ifdef MCUBOOT_ENC_IMAGES
93+
if (state == NULL) {
94+
enc_state = NULL;
95+
image_index = 0;
96+
} else {
97+
enc_state = BOOT_CURR_ENC(state);
98+
image_index = BOOT_CURR_IMG(state);
99+
}
100+
101+
/* Encrypted images only exist in the secondary slot */
102+
if (MUST_DECRYPT(fap, image_index, hdr) &&
103+
!boot_enc_valid(enc_state, 1)) {
104+
BOOT_LOG_DBG("bootutil_img_hash: error encrypted image found in primary slot");
105+
return -1;
106+
}
107+
#endif
108+
109+
#if defined(MCUBOOT_SWAP_USING_OFFSET)
110+
/* For swap using offset mode, the image starts in the second sector of the upgrade slot, so
111+
* apply the offset when this is needed
112+
*/
113+
sector_off = boot_get_state_secondary_offset(state, fap);
114+
#endif
115+
116+
bootutil_sha_init(&sha_ctx);
117+
118+
/* in some cases (split image) the hash is seeded with data from
119+
* the loader image */
120+
if (seed && (seed_len > 0)) {
121+
bootutil_sha_update(&sha_ctx, seed, seed_len);
122+
}
123+
124+
/* Hash is computed over image header and image itself. */
125+
size = hdr_size = hdr->ih_hdr_size;
126+
size += hdr->ih_img_size;
127+
tlv_off = size;
128+
129+
/* If protected TLVs are present they are also hashed. */
130+
size += hdr->ih_protect_tlv_size;
131+
132+
#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY
133+
/* No chunk loading, storage is mapped to address space and can
134+
* be directly given to hashing function.
135+
*/
136+
fa_ret = flash_device_base(flash_area_get_device_id(fap), &base);
137+
if (fa_ret != 0) {
138+
base = 0;
139+
}
140+
141+
bootutil_sha_update(&sha_ctx, (void *)(base + flash_area_get_off(fap)), size);
142+
#else /* MCUBOOT_HASH_STORAGE_DIRECTLY */
143+
#ifdef MCUBOOT_RAM_LOAD
144+
bootutil_sha_update(&sha_ctx,
145+
(void*)(IMAGE_RAM_BASE + hdr->ih_load_addr),
146+
size);
147+
#else
148+
for (off = 0; off < size; off += blk_sz) {
149+
blk_sz = size - off;
150+
if (blk_sz > tmp_buf_sz) {
151+
blk_sz = tmp_buf_sz;
152+
}
153+
#ifdef MCUBOOT_ENC_IMAGES
154+
/* The only data that is encrypted in an image is the payload;
155+
* both header and TLVs (when protected) are not.
156+
*/
157+
if ((off < hdr_size) && ((off + blk_sz) > hdr_size)) {
158+
/* read only the header */
159+
blk_sz = hdr_size - off;
160+
}
161+
if ((off < tlv_off) && ((off + blk_sz) > tlv_off)) {
162+
/* read only up to the end of the image payload */
163+
blk_sz = tlv_off - off;
164+
}
165+
#endif
166+
#if defined(MCUBOOT_SWAP_USING_OFFSET)
167+
rc = flash_area_read(fap, off + sector_off, tmp_buf, blk_sz);
168+
#else
169+
rc = flash_area_read(fap, off, tmp_buf, blk_sz);
170+
#endif
171+
if (rc) {
172+
bootutil_sha_drop(&sha_ctx);
173+
BOOT_LOG_DBG("bootutil_img_validate Error %d reading data chunk %p %u %u",
174+
rc, fap, off, blk_sz);
175+
return rc;
176+
}
177+
#ifdef MCUBOOT_ENC_IMAGES
178+
if (MUST_DECRYPT(fap, image_index, hdr)) {
179+
/* Only payload is encrypted (area between header and TLVs) */
180+
int slot = flash_area_id_to_multi_image_slot(image_index,
181+
flash_area_get_id(fap));
182+
183+
if (off >= hdr_size && off < tlv_off) {
184+
blk_off = (off - hdr_size) & 0xf;
185+
boot_enc_decrypt(enc_state, slot, off - hdr_size,
186+
blk_sz, blk_off, tmp_buf);
187+
}
188+
}
189+
#endif
190+
bootutil_sha_update(&sha_ctx, tmp_buf, blk_sz);
191+
}
192+
#endif /* MCUBOOT_RAM_LOAD */
193+
#endif /* MCUBOOT_HASH_STORAGE_DIRECTLY */
194+
bootutil_sha_finish(&sha_ctx, hash_result);
195+
bootutil_sha_drop(&sha_ctx);
196+
197+
return 0;
198+
}
199+
#endif /* !MCUBOOT_SIGN_PURE */

0 commit comments

Comments
 (0)