Skip to content

Commit 9dacf6d

Browse files
michalek-norlubos
authored andcommitted
[nrf noup] bootutil: key revocation
Disable previous generation key when update comes with new valid key and application is confirmed. Signed-off-by: Mateusz Michalek <[email protected]> Signed-off-by: Dominik Ermel <[email protected]> (cherry picked from commit a378749)
1 parent 373038b commit 9dacf6d

File tree

6 files changed

+129
-0
lines changed

6 files changed

+129
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#ifndef H_KEY_REVOCATION_
8+
#define H_KEY_REVOCATION_
9+
10+
#include <inttypes.h>
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
#define BOOT_KEY_REVOKE_OK 0
17+
#define BOOT_KEY_REVOKE_NOT_READY 1
18+
#define BOOT_KEY_REVOKE_INVALID 2
19+
#define BOOT_KEY_REVOKE_FAILED 2
20+
21+
22+
void allow_revoke(void);
23+
24+
int revoke(void);
25+
26+
#ifdef __cplusplus
27+
}
28+
#endif
29+
30+
#endif

boot/bootutil/src/ed25519_psa.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ static psa_key_id_t kmu_key_ids[3] = {
3232
MAKE_PSA_KMU_KEY_ID(230)
3333
};
3434

35+
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
36+
#include <bootutil/key_revocation.h>
37+
static psa_key_id_t *validated_with = NULL;
38+
#endif
39+
3540
BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(kmu_key_ids),
3641
"Invalid number of KMU slots, up to 3 are supported on nRF54L15");
3742
#endif
@@ -116,6 +121,9 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
116121
EDDSA_SIGNAGURE_LENGTH);
117122
if (status == PSA_SUCCESS) {
118123
ret = 1;
124+
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
125+
validated_with = kmu_key_ids + i;
126+
#endif
119127
break;
120128
}
121129

@@ -124,4 +132,37 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
124132

125133
return ret;
126134
}
135+
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
136+
int exec_revoke(void)
137+
{
138+
int ret = BOOT_KEY_REVOKE_OK;
139+
psa_status_t status = psa_crypto_init();
140+
141+
if (!validated_with) {
142+
ret = BOOT_KEY_REVOKE_INVALID;
143+
goto out;
144+
}
145+
146+
if (status != PSA_SUCCESS) {
147+
BOOT_LOG_ERR("PSA crypto init failed with error %d", status);
148+
ret = BOOT_KEY_REVOKE_FAILED;
149+
goto out;
150+
}
151+
for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; i++) {
152+
if ((kmu_key_ids + i) == validated_with) {
153+
break;
154+
}
155+
BOOT_LOG_DBG("Invalidating key ID %d", i);
156+
157+
status = psa_destroy_key(kmu_key_ids[i]);
158+
if (status == PSA_SUCCESS) {
159+
BOOT_LOG_DBG("Success on key ID %d", i);
160+
} else {
161+
BOOT_LOG_ERR("Key invalidation failed with: %d", status);
162+
}
163+
}
164+
out:
165+
return ret;
166+
}
167+
#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */
127168
#endif

boot/bootutil/src/key_revocation.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <bootutil/key_revocation.h>
8+
9+
extern int exec_revoke(void);
10+
11+
static uint8_t ready_to_revoke;
12+
13+
void allow_revoke(void)
14+
{
15+
ready_to_revoke = 1;
16+
}
17+
18+
int revoke(void)
19+
{
20+
if (ready_to_revoke) {
21+
return exec_revoke();
22+
}
23+
return BOOT_KEY_REVOKE_NOT_READY;
24+
}

boot/bootutil/src/loader.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr);
8080

8181
#include "mcuboot_config/mcuboot_config.h"
8282

83+
#if defined(CONFIG_BOOT_KEYS_REVOCATION)
84+
#include "bootutil/key_revocation.h"
85+
#endif
86+
8387
BOOT_LOG_MODULE_DECLARE(mcuboot);
8488

8589
static struct boot_loader_state boot_data;
@@ -3110,6 +3114,11 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
31103114
}
31113115
}
31123116

3117+
#if defined(CONFIG_BOOT_KEYS_REVOCATION)
3118+
if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) {
3119+
allow_revoke();
3120+
}
3121+
#endif
31133122
/* Iterate over all the images. At this point all required update operations
31143123
* have finished. By the end of the loop each image in the primary slot will
31153124
* have been re-validated.
@@ -3218,6 +3227,13 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
32183227
fill_rsp(state, rsp);
32193228

32203229
fih_rc = FIH_SUCCESS;
3230+
#if defined(CONFIG_BOOT_KEYS_REVOCATION)
3231+
rc = revoke();
3232+
if (rc != BOOT_KEY_REVOKE_OK &&
3233+
rc != BOOT_KEY_REVOKE_NOT_READY) {
3234+
FIH_SET(fih_rc, FIH_FAILURE);
3235+
}
3236+
#endif /* CONFIG_BOOT_KEYS_REVOCATION */
32213237
out:
32223238
/*
32233239
* Since the boot_status struct stores plaintext encryption keys, reset

boot/zephyr/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ if(DEFINED CONFIG_BOOT_SHARE_BACKEND_RETENTION)
104104
)
105105
endif()
106106

107+
if(DEFINED CONFIG_BOOT_KEYS_REVOCATION)
108+
zephyr_library_sources(
109+
${BOOT_DIR}/bootutil/src/key_revocation.c
110+
)
111+
endif()
112+
107113
# Generic bootutil sources and includes.
108114
zephyr_library_include_directories(${BOOT_DIR}/bootutil/include)
109115
zephyr_library_sources(

boot/zephyr/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,18 @@ config BOOT_SIGNATURE_KMU_SLOTS
410410

411411
endif
412412

413+
config BOOT_KEYS_REVOCATION
414+
bool "Auto revoke previous gen key"
415+
help
416+
Automatically revoke previous generation key upon new valid key usage.
417+
418+
config BOOT_KMU_KEYS_REVOCATION
419+
bool
420+
depends on BOOT_KEYS_REVOCATION
421+
default y if BOOT_SIGNATURE_USING_KMU
422+
help
423+
Enabling KMU key revocation backend.
424+
413425
if !BOOT_SIGNATURE_USING_KMU
414426

415427
config BOOT_SIGNATURE_KEY_FILE

0 commit comments

Comments
 (0)