Skip to content

Commit 9ecd61f

Browse files
de-nordicjukkar
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 e28f5e9) (cherry picked from commit 26192ca)
1 parent 7ed7306 commit 9ecd61f

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])
@@ -71,3 +86,39 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
7186

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

boot/bootutil/src/image_ed25519.c

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

37+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
3738
#if !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN)
3839
/*
3940
* Parse the public key used for signing.
@@ -76,6 +77,7 @@ bootutil_import_key(uint8_t **cp, uint8_t *end)
7677
return 0;
7778
}
7879
#endif /* !defined(MCUBOOT_KEY_IMPORT_BYPASS_ASN) */
80+
#endif
7981

8082
/* Signature verification base function.
8183
* The function takes buffer of specified length and tries to verify
@@ -90,8 +92,10 @@ bootutil_verify(uint8_t *buf, uint32_t blen,
9092
{
9193
int rc;
9294
FIH_DECLARE(fih_rc, FIH_FAILURE);
93-
uint8_t *pubkey;
95+
uint8_t *pubkey = NULL;
96+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
9497
uint8_t *end;
98+
#endif
9599

96100
BOOT_LOG_DBG("bootutil_verify: ED25519 key_id %d", (int)key_id);
97101

@@ -102,6 +106,7 @@ bootutil_verify(uint8_t *buf, uint32_t blen,
102106
goto out;
103107
}
104108

109+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
105110
pubkey = (uint8_t *)bootutil_keys[key_id].key;
106111
end = pubkey + *bootutil_keys[key_id].len;
107112

@@ -125,6 +130,8 @@ bootutil_verify(uint8_t *buf, uint32_t blen,
125130
}
126131

127132
pubkey = end - NUM_ED25519_BYTES;
133+
#endif
134+
128135
#endif
129136

130137
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
@@ -283,6 +283,7 @@ bootutil_img_hash(struct boot_loader_state *state,
283283

284284
#if !defined(MCUBOOT_BYPASS_KEY_MATCH)
285285
/* Find functions are only needed when key is checked first */
286+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
286287
#if !defined(MCUBOOT_HW_KEY)
287288
static int
288289
bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len)
@@ -351,6 +352,7 @@ bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
351352
}
352353
#endif /* !MCUBOOT_HW_KEY */
353354
#endif /* !MCUBOOT_BUILTIN_KEY */
355+
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
354356
#endif /* EXPECTED_SIG_TLV */
355357
#else /* !MCUBOOT_BYPASS_KEY_MATCH */
356358
static inline int
@@ -720,6 +722,7 @@ bootutil_img_validate(struct boot_loader_state *state,
720722
break;
721723
}
722724
#endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */
725+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
723726
#ifdef EXPECTED_KEY_TLV
724727
case EXPECTED_KEY_TLV:
725728
{
@@ -751,15 +754,18 @@ bootutil_img_validate(struct boot_loader_state *state,
751754
break;
752755
}
753756
#endif /* EXPECTED_KEY_TLV */
757+
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
754758
#ifdef EXPECTED_SIG_TLV
755759
case EXPECTED_SIG_TLV:
756760
{
757761
BOOT_LOG_DBG("bootutil_img_validate: EXPECTED_SIG_TLV == %d", EXPECTED_SIG_TLV);
762+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
758763
/* Ignore this signature if it is out of bounds. */
759764
if (key_id < 0 || key_id >= bootutil_key_cnt) {
760765
key_id = -1;
761766
continue;
762767
}
768+
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
763769
if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) {
764770
rc = -1;
765771
goto out;
@@ -918,7 +924,7 @@ bootutil_img_validate(struct boot_loader_state *state,
918924
}
919925

920926
#ifdef EXPECTED_SIG_TLV
921-
#ifdef EXPECTED_KEY_TLV
927+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) && defined(EXPECTED_KEY_TLV)
922928
rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_KEY_TLV, false);
923929
if (rc) {
924930
goto out;
@@ -964,7 +970,7 @@ bootutil_img_validate(struct boot_loader_state *state,
964970
*/
965971
}
966972
}
967-
#endif /* EXPECTED_KEY_TLV */
973+
#endif /* !CONFIG_BOOT_SIGNATURE_USING_KMU && EXPECTED_KEY_TLV */
968974

969975
rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_DECOMP_SIGNATURE, true);
970976
if (rc) {
@@ -987,10 +993,12 @@ bootutil_img_validate(struct boot_loader_state *state,
987993

988994
if (type == IMAGE_TLV_DECOMP_SIGNATURE) {
989995
/* Ignore this signature if it is out of bounds. */
996+
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
990997
if (key_id < 0 || key_id >= bootutil_key_cnt) {
991998
key_id = -1;
992999
continue;
9931000
}
1001+
#endif
9941002

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

boot/zephyr/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ if(CONFIG_MCUBOOT_SERIAL)
349349
endif()
350350
endif()
351351

352-
if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
352+
if(NOT CONFIG_BOOT_SIGNATURE_USING_KMU AND NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
353353
# CONF_FILE points to the KConfig configuration files of the bootloader.
354354
foreach (filepath ${CONF_FILE})
355355
file(READ ${filepath} temp_text)

boot/zephyr/Kconfig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,22 @@ config BOOT_BYPASS_KEY_MATCH
397397
Enabling this option turns off key matching, slightly reducing
398398
MCUboot code and boot time.
399399

400+
config BOOT_SIGNATURE_USING_KMU
401+
bool "Use KMU stored keys for signature verification"
402+
depends on NRF_SECURITY
403+
depends on CRACEN_LIB_KMU
404+
select PSA_WANT_ALG_GCM
405+
select PSA_WANT_KEY_TYPE_AES
406+
select PSA_WANT_AES_KEY_SIZE_256
407+
select PSA_WANT_ALG_SP800_108_COUNTER_CMAC
408+
select PSA_WANT_ALG_CMAC
409+
select PSA_WANT_ALG_ECB_NO_PADDING
410+
help
411+
MCUboot will use keys provisioned to the device key management unit for signature
412+
verification instead of compiling in key data from a file.
413+
414+
if !BOOT_SIGNATURE_USING_KMU
415+
400416
config BOOT_SIGNATURE_KEY_FILE
401417
string "PEM key file"
402418
default "root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256
@@ -414,6 +430,8 @@ config BOOT_SIGNATURE_KEY_FILE
414430
with the public key information will be written in a format expected by
415431
MCUboot.
416432

433+
endif
434+
417435
config MCUBOOT_CLEANUP_ARM_CORE
418436
bool "Perform core cleanup before chain-load the application"
419437
depends on CPU_CORTEX_M || ARMV7_R
@@ -443,6 +461,14 @@ config MCUBOOT_INFINITE_LOOP_AFTER_RAM_CLEANUP
443461
Verification option that keeps execution in infinite loop after
444462
RAM cleanup has been performed.
445463

464+
# Disable MBEDTLS from being selected if NRF_SECURITY is enabled, and use default NRF_SECURITY
465+
# configuration file for MBEDTLS
466+
config MBEDTLS
467+
depends on !NRF_SECURITY
468+
469+
config NRF_SECURITY
470+
select MBEDTLS_PROMPTLESS
471+
446472
config MBEDTLS_CFG_FILE
447473
# It might be awkward to define an Mbed TLS header file when TinyCrypt
448474
# is used, but the fact is that Mbed TLS' ASN1 parse module is used

0 commit comments

Comments
 (0)