Skip to content

Commit f7209d5

Browse files
committed
[nrf noup] bootutil: Separate KMU implementation from ED25519
Move KMU specific implementation to dedicated unit. Signed-off-by: Dominik Ermel <[email protected]>
1 parent 459288d commit f7209d5

File tree

3 files changed

+163
-144
lines changed

3 files changed

+163
-144
lines changed

boot/bootutil/pkg.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pkg.ign_files.BOOTUTIL_SINGLE_APPLICATION_SLOT:
4545
pkg.ign_files:
4646
- "ram_load.c"
4747
- "ed25519_psa.c" # Currently no PSA for mynewet
48+
- "ed25519_psa_kmu.c"
4849
- "encrypted_psa.c"
4950

5051
pkg.deps.BOOTUTIL_USE_MBED_TLS:

boot/bootutil/src/ed25519_psa.c

Lines changed: 0 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -13,57 +13,13 @@
1313
#include <psa/crypto.h>
1414
#include <psa/crypto_types.h>
1515
#include <zephyr/sys/util.h>
16-
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
17-
#include <cracen_psa_kmu.h>
18-
#endif
1916

2017
BOOT_LOG_MODULE_REGISTER(ed25519_psa);
2118

2219
#define SHA512_DIGEST_LENGTH 64
2320
#define EDDSA_KEY_LENGTH 32
2421
#define EDDSA_SIGNAGURE_LENGTH 64
2522

26-
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
27-
/* List of KMU stored key ids available for MCUboot */
28-
#define PSA_KEY_INDEX_SIZE 2
29-
30-
#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || \
31-
defined(CONFIG_NCS_BOOT_SIGNATURE_KMU_UROT_MAPPING)
32-
#define PSA_KEY_STARTING_ID 226
33-
#else
34-
#define PSA_KEY_STARTING_ID 242
35-
#endif
36-
37-
#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id)
38-
static psa_key_id_t key_ids[] = {
39-
MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID),
40-
MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + PSA_KEY_INDEX_SIZE),
41-
MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + (2 * PSA_KEY_INDEX_SIZE))
42-
};
43-
44-
#define KEY_SLOTS_COUNT CONFIG_BOOT_SIGNATURE_KMU_SLOTS
45-
46-
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
47-
#include <bootutil/key_revocation.h>
48-
static psa_key_id_t *validated_with = NULL;
49-
#endif
50-
51-
BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(key_ids),
52-
"Invalid number of KMU slots, up to 3 are supported on nRF54L15");
53-
#endif
54-
55-
#if defined(CONFIG_NCS_BOOT_SIGNATURE_USING_ITS)
56-
static const psa_key_id_t key_ids[] = {
57-
0x40022100,
58-
0x40022101,
59-
0x40022102,
60-
0x40022103
61-
};
62-
63-
#define KEY_SLOTS_COUNT ARRAY_SIZE(key_ids)
64-
#endif
65-
66-
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) && !defined(CONFIG_NCS_BOOT_SIGNATURE_USING_ITS)
6723
int ED25519_verify(const uint8_t *message, size_t message_len,
6824
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
6925
const uint8_t public_key[EDDSA_KEY_LENGTH])
@@ -116,103 +72,3 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
11672

11773
return ret;
11874
}
119-
#else
120-
int ED25519_verify(const uint8_t *message, size_t message_len,
121-
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
122-
const uint8_t public_key[EDDSA_KEY_LENGTH])
123-
{
124-
ARG_UNUSED(public_key);
125-
/* Set to any error */
126-
psa_status_t status = PSA_ERROR_BAD_STATE;
127-
128-
/* Initialize PSA Crypto */
129-
status = psa_crypto_init();
130-
if (status != PSA_SUCCESS) {
131-
BOOT_LOG_ERR("PSA crypto init failed %d", status);
132-
return 0;
133-
}
134-
135-
status = PSA_ERROR_BAD_STATE;
136-
137-
for (int i = 0; i < KEY_SLOTS_COUNT; ++i) {
138-
psa_key_id_t kid = key_ids[i];
139-
140-
status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message,
141-
message_len, signature,
142-
EDDSA_SIGNAGURE_LENGTH);
143-
if (status == PSA_SUCCESS) {
144-
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
145-
validated_with = key_ids + i;
146-
#endif
147-
return 1;
148-
}
149-
150-
}
151-
152-
BOOT_LOG_ERR("ED25519 signature verification failed %d", status);
153-
154-
return 0;
155-
}
156-
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
157-
int exec_revoke(void)
158-
{
159-
int ret = BOOT_KEY_REVOKE_OK;
160-
psa_status_t status = psa_crypto_init();
161-
162-
if (!validated_with) {
163-
ret = BOOT_KEY_REVOKE_INVALID;
164-
goto out;
165-
}
166-
167-
if (status != PSA_SUCCESS) {
168-
BOOT_LOG_ERR("PSA crypto init failed with error %d", status);
169-
ret = BOOT_KEY_REVOKE_FAILED;
170-
goto out;
171-
}
172-
for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; i++) {
173-
if ((key_ids + i) == validated_with) {
174-
break;
175-
}
176-
BOOT_LOG_DBG("Invalidating key ID %d", i);
177-
178-
status = psa_destroy_key(key_ids[i]);
179-
if (status == PSA_SUCCESS) {
180-
BOOT_LOG_DBG("Success on key ID %d", i);
181-
} else {
182-
BOOT_LOG_ERR("Key invalidation failed with: %d", status);
183-
}
184-
}
185-
out:
186-
return ret;
187-
}
188-
#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */
189-
190-
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
191-
void nrf_crypto_keys_housekeeping(void)
192-
{
193-
psa_status_t status;
194-
195-
/* We will continue through all keys, even if we have error while
196-
* processing any of it. Only doing BOOT_LOG_DBG, as we do not
197-
* really want to inform on failures to lock.
198-
*/
199-
for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; ++i) {
200-
psa_key_attributes_t attr;
201-
202-
status = psa_get_key_attributes(key_ids[i], &attr);
203-
BOOT_LOG_DBG("KMU key 0x%x(%d) attr query status == %d",
204-
key_ids[i], i, status);
205-
206-
if (status == PSA_SUCCESS) {
207-
status = cracen_kmu_block(&attr);
208-
BOOT_LOG_DBG("KMU key lock status == %d", status);
209-
}
210-
211-
status = psa_purge_key(key_ids[i]);
212-
BOOT_LOG_DBG("KMU key 0x%x(%d) purge status == %d",
213-
key_ids[i], i, status);
214-
}
215-
}
216-
#endif
217-
218-
#endif
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <assert.h>
7+
#include <string.h>
8+
#include <stdint.h>
9+
10+
#include <mcuboot_config/mcuboot_config.h>
11+
#include "bootutil/bootutil_log.h"
12+
13+
#include <psa/crypto.h>
14+
#include <psa/crypto_types.h>
15+
#include <zephyr/sys/util.h>
16+
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
17+
#include <cracen_psa_kmu.h>
18+
#endif
19+
20+
BOOT_LOG_MODULE_DECLARE(ed25519_psa);
21+
22+
#define EDDSA_KEY_LENGTH 32
23+
#define EDDSA_SIGNAGURE_LENGTH 64
24+
25+
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
26+
/* List of KMU stored key ids available for MCUboot */
27+
#define PSA_KEY_INDEX_SIZE 2
28+
29+
#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || \
30+
defined(CONFIG_NCS_BOOT_SIGNATURE_KMU_UROT_MAPPING)
31+
#define PSA_KEY_STARTING_ID 226
32+
#else
33+
#define PSA_KEY_STARTING_ID 242
34+
#endif
35+
36+
#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id)
37+
static psa_key_id_t key_ids[] = {
38+
MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID),
39+
MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + PSA_KEY_INDEX_SIZE),
40+
MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + (2 * PSA_KEY_INDEX_SIZE))
41+
};
42+
43+
#define KEY_SLOTS_COUNT CONFIG_BOOT_SIGNATURE_KMU_SLOTS
44+
45+
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
46+
#include <bootutil/key_revocation.h>
47+
static psa_key_id_t *validated_with = NULL;
48+
#endif
49+
50+
BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(key_ids),
51+
"Invalid number of KMU slots, up to 3 are supported on nRF54L15");
52+
#endif
53+
54+
#if defined(CONFIG_NCS_BOOT_SIGNATURE_USING_ITS)
55+
static const psa_key_id_t key_ids[] = {
56+
0x40022100,
57+
0x40022101,
58+
0x40022102,
59+
0x40022103
60+
};
61+
62+
#define KEY_SLOTS_COUNT ARRAY_SIZE(key_ids)
63+
#endif
64+
65+
int ED25519_verify(const uint8_t *message, size_t message_len,
66+
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
67+
const uint8_t public_key[EDDSA_KEY_LENGTH])
68+
{
69+
ARG_UNUSED(public_key);
70+
/* Set to any error */
71+
psa_status_t status = PSA_ERROR_BAD_STATE;
72+
73+
/* Initialize PSA Crypto */
74+
status = psa_crypto_init();
75+
if (status != PSA_SUCCESS) {
76+
BOOT_LOG_ERR("PSA crypto init failed %d", status);
77+
return 0;
78+
}
79+
80+
status = PSA_ERROR_BAD_STATE;
81+
82+
for (int i = 0; i < KEY_SLOTS_COUNT; ++i) {
83+
psa_key_id_t kid = key_ids[i];
84+
85+
status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message,
86+
message_len, signature,
87+
EDDSA_SIGNAGURE_LENGTH);
88+
if (status == PSA_SUCCESS) {
89+
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
90+
validated_with = key_ids + i;
91+
#endif
92+
return 1;
93+
}
94+
95+
}
96+
97+
BOOT_LOG_ERR("ED25519 signature verification failed %d", status);
98+
99+
return 0;
100+
}
101+
102+
#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION)
103+
int exec_revoke(void)
104+
{
105+
int ret = BOOT_KEY_REVOKE_OK;
106+
psa_status_t status = psa_crypto_init();
107+
108+
if (!validated_with) {
109+
ret = BOOT_KEY_REVOKE_INVALID;
110+
goto out;
111+
}
112+
113+
if (status != PSA_SUCCESS) {
114+
BOOT_LOG_ERR("PSA crypto init failed with error %d", status);
115+
ret = BOOT_KEY_REVOKE_FAILED;
116+
goto out;
117+
}
118+
for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; i++) {
119+
if ((key_ids + i) == validated_with) {
120+
break;
121+
}
122+
BOOT_LOG_DBG("Invalidating key ID %d", i);
123+
124+
status = psa_destroy_key(key_ids[i]);
125+
if (status == PSA_SUCCESS) {
126+
BOOT_LOG_DBG("Success on key ID %d", i);
127+
} else {
128+
BOOT_LOG_ERR("Key invalidation failed with: %d", status);
129+
}
130+
}
131+
out:
132+
return ret;
133+
}
134+
#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */
135+
136+
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
137+
void nrf_crypto_keys_housekeeping(void)
138+
{
139+
psa_status_t status;
140+
141+
/* We will continue through all keys, even if we have error while
142+
* processing any of it. Only doing BOOT_LOG_DBG, as we do not
143+
* really want to inform on failures to lock.
144+
*/
145+
for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; ++i) {
146+
psa_key_attributes_t attr;
147+
148+
status = psa_get_key_attributes(key_ids[i], &attr);
149+
BOOT_LOG_DBG("KMU key 0x%x(%d) attr query status == %d",
150+
key_ids[i], i, status);
151+
152+
if (status == PSA_SUCCESS) {
153+
status = cracen_kmu_block(&attr);
154+
BOOT_LOG_DBG("KMU key lock status == %d", status);
155+
}
156+
157+
status = psa_purge_key(key_ids[i]);
158+
BOOT_LOG_DBG("KMU key 0x%x(%d) purge status == %d",
159+
key_ids[i], i, status);
160+
}
161+
}
162+
#endif

0 commit comments

Comments
 (0)