From de93d60d89c4562926cba520b27621b23a2433d6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 16 Jul 2025 14:42:12 +0000 Subject: [PATCH 1/2] [nrf noup] bootutil: Separate KMU implementation from ED25519 Move KMU specific implementation to dedicated unit. Signed-off-by: Dominik Ermel --- boot/bootutil/pkg.yml | 1 + boot/bootutil/src/ed25519_psa.c | 142 ------------------------- boot/bootutil/src/ed25519_psa_kmu.c | 157 ++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 142 deletions(-) create mode 100644 boot/bootutil/src/ed25519_psa_kmu.c diff --git a/boot/bootutil/pkg.yml b/boot/bootutil/pkg.yml index c5d713b69..6a112b56f 100644 --- a/boot/bootutil/pkg.yml +++ b/boot/bootutil/pkg.yml @@ -45,6 +45,7 @@ pkg.ign_files.BOOTUTIL_SINGLE_APPLICATION_SLOT: pkg.ign_files: - "ram_load.c" - "ed25519_psa.c" # Currently no PSA for mynewet + - "ed25519_psa_kmu.c" - "encrypted_psa.c" pkg.deps.BOOTUTIL_USE_MBED_TLS: diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index c7e3910b1..563661b65 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -13,9 +13,6 @@ #include #include #include -#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) -#include -#endif BOOT_LOG_MODULE_REGISTER(ed25519_psa); @@ -23,47 +20,6 @@ BOOT_LOG_MODULE_REGISTER(ed25519_psa); #define EDDSA_KEY_LENGTH 32 #define EDDSA_SIGNAGURE_LENGTH 64 -#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) -/* List of KMU stored key ids available for MCUboot */ -#define PSA_KEY_INDEX_SIZE 2 - -#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || \ - defined(CONFIG_NCS_BOOT_SIGNATURE_KMU_UROT_MAPPING) -#define PSA_KEY_STARTING_ID 226 -#else -#define PSA_KEY_STARTING_ID 242 -#endif - -#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id) -static psa_key_id_t key_ids[] = { - MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID), - MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + PSA_KEY_INDEX_SIZE), - MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + (2 * PSA_KEY_INDEX_SIZE)) -}; - -#define KEY_SLOTS_COUNT CONFIG_BOOT_SIGNATURE_KMU_SLOTS - -#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) -#include -static psa_key_id_t *validated_with = NULL; -#endif - -BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(key_ids), - "Invalid number of KMU slots, up to 3 are supported on nRF54L15"); -#endif - -#if defined(CONFIG_NCS_BOOT_SIGNATURE_USING_ITS) -static const psa_key_id_t key_ids[] = { - 0x40022100, - 0x40022101, - 0x40022102, - 0x40022103 -}; - -#define KEY_SLOTS_COUNT ARRAY_SIZE(key_ids) -#endif - -#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) && !defined(CONFIG_NCS_BOOT_SIGNATURE_USING_ITS) int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], const uint8_t public_key[EDDSA_KEY_LENGTH]) @@ -116,101 +72,3 @@ int ED25519_verify(const uint8_t *message, size_t message_len, return ret; } -#else -int ED25519_verify(const uint8_t *message, size_t message_len, - const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], - const uint8_t public_key[EDDSA_KEY_LENGTH]) -{ - ARG_UNUSED(public_key); - /* Set to any error */ - psa_status_t status = PSA_ERROR_BAD_STATE; - - /* Initialize PSA Crypto */ - status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d", status); - return 0; - } - - status = PSA_ERROR_BAD_STATE; - - for (int i = 0; i < KEY_SLOTS_COUNT; ++i) { - psa_key_id_t kid = key_ids[i]; - - status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, - message_len, signature, - EDDSA_SIGNAGURE_LENGTH); - if (status == PSA_SUCCESS) { -#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) - validated_with = key_ids + i; -#endif - return 1; - } - - } - - BOOT_LOG_ERR("ED25519 signature verification failed %d", status); - - return 0; -} -#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) -int exec_revoke(void) -{ - int ret = BOOT_KEY_REVOKE_OK; - psa_status_t status = psa_crypto_init(); - - if (!validated_with) { - ret = BOOT_KEY_REVOKE_INVALID; - goto out; - } - - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed with error %d", status); - ret = BOOT_KEY_REVOKE_FAILED; - goto out; - } - for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; i++) { - if ((key_ids + i) == validated_with) { - break; - } - BOOT_LOG_DBG("Invalidating key ID %d", i); - - status = psa_destroy_key(key_ids[i]); - if (status == PSA_SUCCESS) { - BOOT_LOG_DBG("Success on key ID %d", i); - } else { - BOOT_LOG_ERR("Key invalidation failed with: %d", status); - } - } -out: - return ret; -} -#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */ - -void nrf_crypto_keys_housekeeping(void) -{ - psa_status_t status; - - /* We will continue through all keys, even if we have error while - * processing any of it. Only doing BOOT_LOG_DBG, as we do not - * really want to inform on failures to lock. - */ - for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; ++i) { - psa_key_attributes_t attr; - - status = psa_get_key_attributes(key_ids[i], &attr); - BOOT_LOG_DBG("KMU key 0x%x(%d) attr query status == %d", - key_ids[i], i, status); - - if (status == PSA_SUCCESS) { - status = cracen_kmu_block(&attr); - BOOT_LOG_DBG("KMU key lock status == %d", status); - } - - status = psa_purge_key(key_ids[i]); - BOOT_LOG_DBG("KMU key 0x%x(%d) purge status == %d", - key_ids[i], i, status); - } -} - -#endif diff --git a/boot/bootutil/src/ed25519_psa_kmu.c b/boot/bootutil/src/ed25519_psa_kmu.c new file mode 100644 index 000000000..bda4cc087 --- /dev/null +++ b/boot/bootutil/src/ed25519_psa_kmu.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include +#include "bootutil/bootutil_log.h" + +#include +#include +#include + +BOOT_LOG_MODULE_REGISTER(ed25519_psa); + +#define EDDSA_KEY_LENGTH 32 +#define EDDSA_SIGNAGURE_LENGTH 64 + +#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) +/* List of KMU stored key ids available for MCUboot */ +#define PSA_KEY_INDEX_SIZE 2 + +#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || \ + defined(CONFIG_NCS_BOOT_SIGNATURE_KMU_UROT_MAPPING) +#define PSA_KEY_STARTING_ID 226 +#else +#define PSA_KEY_STARTING_ID 242 +#endif + +#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id) +static psa_key_id_t key_ids[] = { + MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID), + MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + PSA_KEY_INDEX_SIZE), + MAKE_PSA_KMU_KEY_ID(PSA_KEY_STARTING_ID + (2 * PSA_KEY_INDEX_SIZE)) +}; + +#define KEY_SLOTS_COUNT CONFIG_BOOT_SIGNATURE_KMU_SLOTS + +#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) +#include +static psa_key_id_t *validated_with = NULL; +#endif + +BUILD_ASSERT(CONFIG_BOOT_SIGNATURE_KMU_SLOTS <= ARRAY_SIZE(key_ids), + "Invalid number of KMU slots, up to 3 are supported on nRF54L15"); +#endif + +#if defined(CONFIG_NCS_BOOT_SIGNATURE_USING_ITS) +static const psa_key_id_t key_ids[] = { + 0x40022100, + 0x40022101, + 0x40022102, + 0x40022103 +}; + +#define KEY_SLOTS_COUNT ARRAY_SIZE(key_ids) +#endif + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[EDDSA_SIGNAGURE_LENGTH], + const uint8_t public_key[EDDSA_KEY_LENGTH]) +{ + ARG_UNUSED(public_key); + /* Set to any error */ + psa_status_t status = PSA_ERROR_BAD_STATE; + + /* Initialize PSA Crypto */ + status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d", status); + return 0; + } + + status = PSA_ERROR_BAD_STATE; + + for (int i = 0; i < KEY_SLOTS_COUNT; ++i) { + psa_key_id_t kid = key_ids[i]; + + status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, + message_len, signature, + EDDSA_SIGNAGURE_LENGTH); + if (status == PSA_SUCCESS) { +#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) + validated_with = key_ids + i; +#endif + return 1; + } + + } + + BOOT_LOG_ERR("ED25519 signature verification failed %d", status); + + return 0; +} + +#if defined(CONFIG_BOOT_KMU_KEYS_REVOCATION) +int exec_revoke(void) +{ + int ret = BOOT_KEY_REVOKE_OK; + psa_status_t status = psa_crypto_init(); + + if (!validated_with) { + ret = BOOT_KEY_REVOKE_INVALID; + goto out; + } + + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed with error %d", status); + ret = BOOT_KEY_REVOKE_FAILED; + goto out; + } + for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; i++) { + if ((key_ids + i) == validated_with) { + break; + } + BOOT_LOG_DBG("Invalidating key ID %d", i); + + status = psa_destroy_key(key_ids[i]); + if (status == PSA_SUCCESS) { + BOOT_LOG_DBG("Success on key ID %d", i); + } else { + BOOT_LOG_ERR("Key invalidation failed with: %d", status); + } + } +out: + return ret; +} +#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */ + +void nrf_crypto_keys_housekeeping(void) +{ + psa_status_t status; + + /* We will continue through all keys, even if we have error while + * processing any of it. Only doing BOOT_LOG_DBG, as we do not + * really want to inform on failures to lock. + */ + for (int i = 0; i < CONFIG_BOOT_SIGNATURE_KMU_SLOTS; ++i) { + psa_key_attributes_t attr; + + status = psa_get_key_attributes(key_ids[i], &attr); + BOOT_LOG_DBG("KMU key 0x%x(%d) attr query status == %d", + key_ids[i], i, status); + + if (status == PSA_SUCCESS) { + status = cracen_kmu_block(&attr); + BOOT_LOG_DBG("KMU key lock status == %d", status); + } + + status = psa_purge_key(key_ids[i]); + BOOT_LOG_DBG("KMU key 0x%x(%d) purge status == %d", + key_ids[i], i, status); + } +} From e726c8b6e76fae031d7bc66f0a5ffad55210b4c2 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 16 Jul 2025 14:43:36 +0000 Subject: [PATCH 2/2] [nrf noup] zephyr: ED25519 KMU has now separate unit for compilation Modify CMake files to take the unit when KMU is desired. Signed-off-by: Dominik Ermel --- boot/zephyr/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index b34824def..ae8a563d3 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -316,9 +316,14 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519) ) endif() + elseif(NOT CONFIG_BOOT_SIGNATURE_USING_KMU) zephyr_library_sources( ${BOOT_DIR}/bootutil/src/ed25519_psa.c ) + else() + zephyr_library_sources( + ${BOOT_DIR}/bootutil/src/ed25519_psa_kmu.c + ) endif() endif()