Skip to content

Commit a2b1cf2

Browse files
michalek-node-nordic
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 <mateusz.michalek@nordicsemi.no> Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no> (cherry picked from commit 4546dc5a150d1cc62a5ef51c99ab3ce87df652e1) (cherry picked from commit 22c2cac)
1 parent 8a2c213 commit a2b1cf2

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
@@ -77,6 +77,10 @@ int pcd_version_cmp_net(const struct flash_area *fap, struct image_header *hdr);
7777

7878
#include "mcuboot_config/mcuboot_config.h"
7979

80+
#if defined(CONFIG_BOOT_KEYS_REVOCATION)
81+
#include "bootutil/key_revocation.h"
82+
#endif
83+
8084
BOOT_LOG_MODULE_DECLARE(mcuboot);
8185

8286
static struct boot_loader_state boot_data;
@@ -3019,6 +3023,11 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
30193023
}
30203024
}
30213025

3026+
#if defined(CONFIG_BOOT_KEYS_REVOCATION)
3027+
if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) {
3028+
allow_revoke();
3029+
}
3030+
#endif
30223031
/* Iterate over all the images. At this point all required update operations
30233032
* have finished. By the end of the loop each image in the primary slot will
30243033
* have been re-validated.
@@ -3124,6 +3133,13 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
31243133
fill_rsp(state, rsp);
31253134

31263135
fih_rc = FIH_SUCCESS;
3136+
#if defined(CONFIG_BOOT_KEYS_REVOCATION)
3137+
rc = revoke();
3138+
if (rc != BOOT_KEY_REVOKE_OK &&
3139+
rc != BOOT_KEY_REVOKE_NOT_READY) {
3140+
FIH_SET(fih_rc, FIH_FAILURE);
3141+
}
3142+
#endif /* CONFIG_BOOT_KEYS_REVOCATION */
31273143
out:
31283144
/*
31293145
* 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
@@ -99,6 +99,12 @@ if(DEFINED CONFIG_BOOT_SHARE_BACKEND_RETENTION)
9999
)
100100
endif()
101101

102+
if(DEFINED CONFIG_BOOT_KEYS_REVOCATION)
103+
zephyr_library_sources(
104+
${BOOT_DIR}/bootutil/src/key_revocation.c
105+
)
106+
endif()
107+
102108
# Generic bootutil sources and includes.
103109
zephyr_library_include_directories(${BOOT_DIR}/bootutil/include)
104110
zephyr_library_sources(

boot/zephyr/Kconfig

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

358358
endif
359359

360+
config BOOT_KEYS_REVOCATION
361+
bool "Auto revoke previous gen key"
362+
help
363+
Automatically revoke previous generation key upon new valid key usage.
364+
365+
config BOOT_KMU_KEYS_REVOCATION
366+
bool
367+
depends on BOOT_KEYS_REVOCATION
368+
default y if BOOT_SIGNATURE_USING_KMU
369+
help
370+
Enabling KMU key revocation backend.
371+
360372
if !BOOT_SIGNATURE_USING_KMU
361373

362374
config BOOT_SIGNATURE_KEY_FILE

0 commit comments

Comments
 (0)