Skip to content

Commit 03368b8

Browse files
davidvinczed3zd3z
authored andcommittedApr 7, 2020
boot: Add hardware key support
This change enables the public key (used for image authentication) to be removed from MCUboot and be appended to the image instead. In this case the key or its hash must be provisioned to the device and MCUboot must be able to retrieve the key-hash from the hardware to compare it with the calculated hash of the public key from the image manifest in order to verify its validity before image authentication. The source of this change: https://review.trustedfirmware.org/c/trusted-firmware-m/+/1581 Change-Id: I36fe699732e0e4c113eaed331c22e707c722ed6e Signed-off-by: David Vincze <[email protected]>
1 parent dde178d commit 03368b8

File tree

7 files changed

+116
-2
lines changed

7 files changed

+116
-2
lines changed
 

‎boot/bootutil/include/bootutil/image.h

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct flash_area;
7474
* 2nd one is the actual signature.
7575
*/
7676
#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
77+
#define IMAGE_TLV_PUBKEY 0x02 /* public key */
7778
#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
7879
#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
7980
#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output */

‎boot/bootutil/include/bootutil/sign_key.h

+25
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,43 @@
2020
#ifndef __BOOTUTIL_SIGN_KEY_H_
2121
#define __BOOTUTIL_SIGN_KEY_H_
2222

23+
#include <stddef.h>
2324
#include <stdint.h>
2425

2526
#ifdef __cplusplus
2627
extern "C" {
2728
#endif
2829

30+
#ifndef MCUBOOT_HW_KEY
2931
struct bootutil_key {
3032
const uint8_t *key;
3133
const unsigned int *len;
3234
};
3335

3436
extern const struct bootutil_key bootutil_keys[];
37+
#else
38+
struct bootutil_key {
39+
uint8_t *key;
40+
unsigned int *len;
41+
};
42+
43+
extern struct bootutil_key bootutil_keys[];
44+
45+
/**
46+
* Retrieve the hash of the corresponding public key for image authentication.
47+
*
48+
* @param[in] image_index Index of the image to be authenticated.
49+
* @param[out] public_key_hash Buffer to store the key-hash in.
50+
* @param[in,out] key_hash_size As input the size of the buffer. As output
51+
* the actual key-hash length.
52+
*
53+
* @return 0 on success; nonzero on failure.
54+
*/
55+
int boot_retrieve_public_key_hash(uint8_t image_index,
56+
uint8_t *public_key_hash,
57+
size_t *key_hash_size);
58+
#endif /* !MCUBOOT_HW_KEY */
59+
3560
extern const int bootutil_key_cnt;
3661

3762
#ifdef __cplusplus

‎boot/bootutil/src/image_validate.c

+52
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index,
177177
#endif
178178

179179
#ifdef EXPECTED_SIG_TLV
180+
#if !defined(MCUBOOT_HW_KEY)
180181
static int
181182
bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len)
182183
{
@@ -200,6 +201,34 @@ bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len)
200201
}
201202
return -1;
202203
}
204+
#else
205+
extern unsigned int pub_key_len;
206+
static int
207+
bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
208+
{
209+
bootutil_sha256_context sha256_ctx;
210+
uint8_t hash[32];
211+
uint8_t key_hash[32];
212+
size_t key_hash_size = sizeof(key_hash);
213+
int rc;
214+
215+
bootutil_sha256_init(&sha256_ctx);
216+
bootutil_sha256_update(&sha256_ctx, key, key_len);
217+
bootutil_sha256_finish(&sha256_ctx, hash);
218+
219+
rc = boot_retrieve_public_key_hash(image_index, key_hash, &key_hash_size);
220+
if (rc) {
221+
return rc;
222+
}
223+
224+
if (!memcmp(hash, key_hash, key_hash_size)) {
225+
bootutil_keys[0].key = key;
226+
pub_key_len = key_len;
227+
return 0;
228+
}
229+
return -1;
230+
}
231+
#endif /* !MCUBOOT_HW_KEY */
203232
#endif
204233

205234
#ifdef MCUBOOT_HW_ROLLBACK_PROT
@@ -281,7 +310,11 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
281310
#ifdef EXPECTED_SIG_TLV
282311
int valid_signature = 0;
283312
int key_id = -1;
313+
#ifdef MCUBOOT_HW_KEY
314+
/* Few extra bytes for encoding and for public exponent. */
315+
uint8_t key_buf[SIG_BUF_SIZE + 24];
284316
#endif
317+
#endif /* EXPECTED_SIG_TLV */
285318
struct image_tlv_iter it;
286319
uint8_t buf[SIG_BUF_SIZE];
287320
uint8_t hash[32];
@@ -337,6 +370,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
337370

338371
sha256_valid = 1;
339372
#ifdef EXPECTED_SIG_TLV
373+
#ifndef MCUBOOT_HW_KEY
340374
} else if (type == IMAGE_TLV_KEYHASH) {
341375
/*
342376
* Determine which key we should be checking.
@@ -353,6 +387,24 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
353387
* The key may not be found, which is acceptable. There
354388
* can be multiple signatures, each preceded by a key.
355389
*/
390+
#else
391+
} else if (type == IMAGE_TLV_PUBKEY) {
392+
/*
393+
* Determine which key we should be checking.
394+
*/
395+
if (len > sizeof(key_buf)) {
396+
return -1;
397+
}
398+
rc = flash_area_read(fap, off, key_buf, len);
399+
if (rc) {
400+
return rc;
401+
}
402+
key_id = bootutil_find_key(image_index, key_buf, len);
403+
/*
404+
* The key may not be found, which is acceptable. There
405+
* can be multiple signatures, each preceded by a key.
406+
*/
407+
#endif /* !MCUBOOT_HW_KEY */
356408
} else if (type == EXPECTED_SIG_TLV) {
357409
/* Ignore this signature if it is out of bounds. */
358410
if (key_id < 0 || key_id >= bootutil_key_cnt) {

‎boot/cypress/MCUBootApp/keys.c

+11
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include <bootutil/sign_key.h>
5858
#include <mcuboot_config/mcuboot_config.h>
5959

60+
#if !defined(MCUBOOT_HW_KEY)
6061
#if defined(MCUBOOT_SIGN_RSA)
6162
const unsigned char rsa_pub_key[] = {
6263
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd1, 0x06, 0x08,
@@ -163,3 +164,13 @@ const struct bootutil_key bootutil_keys[] = {
163164
};
164165
const int bootutil_key_cnt = 1;
165166
#endif
167+
#else
168+
unsigned int pub_key_len;
169+
struct bootutil_key bootutil_keys[1] = {
170+
{
171+
.key = 0,
172+
.len = &pub_key_len,
173+
}
174+
};
175+
const int bootutil_key_cnt = 1;
176+
#endif /* !MCUBOOT_HW_KEY */

‎boot/zephyr/Kconfig

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2017 Linaro Limited
1+
# Copyright (c) 2017-2020 Linaro Limited
22
# Copyright (c) 2020 Arm Limited
33
#
44
# SPDX-License-Identifier: Apache-2.0
@@ -128,6 +128,15 @@ config MCUBOOT_CLEANUP_ARM_CORE
128128
config MBEDTLS_CFG_FILE
129129
default "mcuboot-mbedtls-cfg.h"
130130

131+
config BOOT_HW_KEY
132+
bool "Use HW key for image verification"
133+
default n
134+
help
135+
Use HW key for image verification, otherwise the public key is embedded
136+
in MCUBoot. If enabled the public key is appended to the signed image
137+
and requires the hash of the public key to be provisioned to the device
138+
beforehand.
139+
131140
config BOOT_VALIDATE_SLOT0
132141
bool "Validate image in the primary slot on every boot"
133142
default y

‎boot/zephyr/include/mcuboot_config/mcuboot_config.h

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright (c) 2018 Open Source Foundries Limited
33
* Copyright (c) 2019-2020 Arm Limited
4+
* Copyright (c) 2019-2020 Linaro Limited
45
*
56
* SPDX-License-Identifier: Apache-2.0
67
*/
@@ -44,6 +45,10 @@
4445
#endif
4546
#endif
4647

48+
#ifdef CONFIG_BOOT_HW_KEY
49+
#define MCUBOOT_HW_KEY
50+
#endif
51+
4752
#ifdef CONFIG_BOOT_VALIDATE_SLOT0
4853
#define MCUBOOT_VALIDATE_PRIMARY_SLOT
4954
#endif

‎boot/zephyr/keys.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
*/
2929
#include <mcuboot_config/mcuboot_config.h>
3030

31+
#if !defined(MCUBOOT_HW_KEY)
3132
#if defined(MCUBOOT_SIGN_RSA)
3233
#define HAVE_KEYS
3334
extern const unsigned char rsa_pub_key[];
@@ -65,7 +66,17 @@ const struct bootutil_key bootutil_keys[] = {
6566
},
6667
};
6768
const int bootutil_key_cnt = 1;
68-
#endif
69+
#endif /* HAVE_KEYS */
70+
#else
71+
unsigned int pub_key_len;
72+
struct bootutil_key bootutil_keys[1] = {
73+
{
74+
.key = 0,
75+
.len = &pub_key_len,
76+
}
77+
};
78+
const int bootutil_key_cnt = 1;
79+
#endif /* !MCUBOOT_HW_KEY */
6980

7081
#if defined(MCUBOOT_ENCRYPT_RSA)
7182
unsigned char enc_priv_key[] = {

0 commit comments

Comments
 (0)
Please sign in to comment.