Skip to content

Commit 7d649aa

Browse files
de-nordicnordicjm
authored andcommitted
[nrf noup] bootutil: Add support for KMU stored ED25519 signature key
The commit adds verification of image using keys stored in KMU. Signed-off-by: Dominik Ermel <[email protected]> (cherry picked from commit 2ae98d5)
1 parent eb5056a commit 7d649aa

File tree

5 files changed

+96
-4
lines changed

5 files changed

+96
-4
lines changed

boot/bootutil/src/ed25519_psa.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,28 @@
1212

1313
#include <psa/crypto.h>
1414
#include <psa/crypto_types.h>
15+
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
16+
#include <cracen_psa_kmu.h>
17+
#endif
1518

1619
BOOT_LOG_MODULE_REGISTER(ed25519_psa);
1720

1821
#define SHA512_DIGEST_LENGTH 64
1922
#define EDDSA_KEY_LENGTH 32
2023
#define EDDSA_SIGNAGURE_LENGTH 64
2124

25+
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
26+
/* List of KMU stored key ids available for MCUboot */
27+
#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id)
28+
static psa_key_id_t kmu_key_ids[3] = {
29+
MAKE_PSA_KMU_KEY_ID(226),
30+
MAKE_PSA_KMU_KEY_ID(228),
31+
MAKE_PSA_KMU_KEY_ID(230)
32+
};
33+
#define KMU_KEY_COUNT (sizeof(kmu_key_ids)/sizeof(kmu_key_ids[0]))
34+
#endif
35+
36+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
2237
int ED25519_verify(const uint8_t *message, size_t message_len,
2338
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
2439
const uint8_t public_key[EDDSA_KEY_LENGTH])
@@ -69,3 +84,39 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
6984

7085
return ret;
7186
}
87+
#else
88+
int ED25519_verify(const uint8_t *message, size_t message_len,
89+
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
90+
const uint8_t public_key[EDDSA_KEY_LENGTH])
91+
{
92+
ARG_UNUSED(public_key);
93+
/* Set to any error */
94+
psa_status_t status = PSA_ERROR_BAD_STATE;
95+
int ret = 0; /* Fail by default */
96+
97+
/* Initialize PSA Crypto */
98+
status = psa_crypto_init();
99+
if (status != PSA_SUCCESS) {
100+
BOOT_LOG_ERR("PSA crypto init failed %d", status);
101+
return 0;
102+
}
103+
104+
status = PSA_ERROR_BAD_STATE;
105+
106+
for (int i = 0; i < KMU_KEY_COUNT; ++i) {
107+
psa_key_id_t kid = kmu_key_ids[i];
108+
109+
status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message,
110+
message_len, signature,
111+
EDDSA_SIGNAGURE_LENGTH);
112+
if (status == PSA_SUCCESS) {
113+
ret = 1;
114+
break;
115+
}
116+
117+
BOOT_LOG_ERR("ED25519 signature verification failed %d", status);
118+
}
119+
120+
return ret;
121+
}
122+
#endif

boot/bootutil/src/image_ed25519.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern int ED25519_verify(const uint8_t *message, size_t message_len,
3131
const uint8_t signature[EDDSA_SIGNATURE_LENGTH],
3232
const uint8_t public_key[NUM_ED25519_BYTES]);
3333

34+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
3435
#if !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN)
3536
/*
3637
* Parse the public key used for signing.
@@ -73,6 +74,7 @@ bootutil_import_key(uint8_t **cp, uint8_t *end)
7374
return 0;
7475
}
7576
#endif /* !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) */
77+
#endif
7678

7779
/* Signature verification base function.
7880
* The function takes buffer of specified length and tries to verify
@@ -87,14 +89,17 @@ bootutil_verify(uint8_t *buf, uint32_t blen,
8789
{
8890
int rc;
8991
FIH_DECLARE(fih_rc, FIH_FAILURE);
90-
uint8_t *pubkey;
92+
uint8_t *pubkey = NULL;
93+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
9194
uint8_t *end;
95+
#endif
9296

9397
if (slen != EDDSA_SIGNATURE_LENGTH) {
9498
FIH_SET(fih_rc, FIH_FAILURE);
9599
goto out;
96100
}
97101

102+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
98103
pubkey = (uint8_t *)bootutil_keys[key_id].key;
99104
end = pubkey + *bootutil_keys[key_id].len;
100105

@@ -116,6 +121,8 @@ bootutil_verify(uint8_t *buf, uint32_t blen,
116121
}
117122

118123
pubkey = end - NUM_ED25519_BYTES;
124+
#endif
125+
119126
#endif
120127

121128
rc = ED25519_verify(buf, blen, sig, pubkey);

boot/bootutil/src/image_validate.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ bootutil_img_hash(struct boot_loader_state *state,
280280
# define KEY_BUF_SIZE (SIG_BUF_SIZE + 24)
281281
#endif /* !MCUBOOT_HW_KEY */
282282

283+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
283284
#if !defined(MCUBOOT_HW_KEY)
284285
static int
285286
bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len)
@@ -345,6 +346,7 @@ bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
345346
}
346347
#endif /* !MCUBOOT_HW_KEY */
347348
#endif /* !MCUBOOT_BUILTIN_KEY */
349+
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
348350
#endif /* EXPECTED_SIG_TLV */
349351

350352
/**
@@ -696,6 +698,7 @@ bootutil_img_validate(struct boot_loader_state *state,
696698
break;
697699
}
698700
#endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */
701+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
699702
#ifdef EXPECTED_KEY_TLV
700703
case EXPECTED_KEY_TLV:
701704
{
@@ -726,14 +729,17 @@ bootutil_img_validate(struct boot_loader_state *state,
726729
break;
727730
}
728731
#endif /* EXPECTED_KEY_TLV */
732+
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
729733
#ifdef EXPECTED_SIG_TLV
730734
case EXPECTED_SIG_TLV:
731735
{
736+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
732737
/* Ignore this signature if it is out of bounds. */
733738
if (key_id < 0 || key_id >= bootutil_key_cnt) {
734739
key_id = -1;
735740
continue;
736741
}
742+
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
737743
if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) {
738744
rc = -1;
739745
goto out;
@@ -890,7 +896,7 @@ bootutil_img_validate(struct boot_loader_state *state,
890896
}
891897

892898
#ifdef EXPECTED_SIG_TLV
893-
#ifdef EXPECTED_KEY_TLV
899+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) && defined(EXPECTED_KEY_TLV)
894900
rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false);
895901
if (rc) {
896902
goto out;
@@ -936,7 +942,7 @@ bootutil_img_validate(struct boot_loader_state *state,
936942
*/
937943
}
938944
}
939-
#endif /* EXPECTED_KEY_TLV */
945+
#endif /* !CONFIG_BOOT_SIGNATURE_USING_KMU && EXPECTED_KEY_TLV */
940946

941947
rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true);
942948
if (rc) {
@@ -959,10 +965,12 @@ bootutil_img_validate(struct boot_loader_state *state,
959965

960966
if (type == IMAGE_TLV_DECOMP_SIGNATURE) {
961967
/* Ignore this signature if it is out of bounds. */
968+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
962969
if (key_id < 0 || key_id >= bootutil_key_cnt) {
963970
key_id = -1;
964971
continue;
965972
}
973+
#endif
966974

967975
if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) {
968976
rc = -1;

boot/zephyr/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ if(CONFIG_MCUBOOT_SERIAL)
341341
endif()
342342
endif()
343343

344-
if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
344+
if(NOT CONFIG_BOOT_SIGNATURE_USING_KMU AND NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
345345
# CONF_FILE points to the KConfig configuration files of the bootloader.
346346
foreach (filepath ${CONF_FILE})
347347
file(READ ${filepath} temp_text)

boot/zephyr/Kconfig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,22 @@ endif
329329

330330
endchoice
331331

332+
config BOOT_SIGNATURE_USING_KMU
333+
bool "Use KMU stored keys for signature verification"
334+
depends on NRF_SECURITY
335+
depends on CRACEN_LIB_KMU
336+
select PSA_WANT_ALG_GCM
337+
select PSA_WANT_KEY_TYPE_AES
338+
select PSA_WANT_AES_KEY_SIZE_256
339+
select PSA_WANT_ALG_SP800_108_COUNTER_CMAC
340+
select PSA_WANT_ALG_CMAC
341+
select PSA_WANT_ALG_ECB_NO_PADDING
342+
help
343+
MCUboot will use keys provisioned to the device key management unit for signature
344+
verification instead of compiling in key data from a file.
345+
346+
if !BOOT_SIGNATURE_USING_KMU
347+
332348
config BOOT_SIGNATURE_KEY_FILE
333349
string "PEM key file"
334350
default "root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256
@@ -346,6 +362,8 @@ config BOOT_SIGNATURE_KEY_FILE
346362
with the public key information will be written in a format expected by
347363
MCUboot.
348364

365+
endif
366+
349367
config MCUBOOT_CLEANUP_ARM_CORE
350368
bool "Perform core cleanup before chain-load the application"
351369
depends on CPU_CORTEX_M
@@ -368,6 +386,14 @@ config MCUBOOT_CLEANUP_RAM
368386
help
369387
Sets contents of memory to 0 before jumping to application.
370388

389+
# Disable MBEDTLS from being selected if NRF_SECURITY is enabled, and use default NRF_SECURITY
390+
# configuration file for MBEDTLS
391+
config MBEDTLS
392+
depends on !NRF_SECURITY
393+
394+
config NRF_SECURITY
395+
select MBEDTLS_PROMPTLESS
396+
371397
config MBEDTLS_CFG_FILE
372398
# It might be awkward to define an Mbed TLS header file when TinyCrypt
373399
# is used, but the fact is that Mbed TLS' ASN1 parse module is used

0 commit comments

Comments
 (0)