diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index 72215bcf5..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,43 +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 - -#define PSA_KEY_STARTING_ID CONFIG_NCS_BOOT_SIGNATURE_KMU_BASE_SLOT - -#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 -#define VALIDATED_WITH_UNINITIALIZED INT32_MAX -static int32_t validated_with = VALIDATED_WITH_UNINITIALIZED; -#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]) @@ -112,105 +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) - if(i < validated_with) { - validated_with = 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 == VALIDATED_WITH_UNINITIALIZED) { - 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 ( 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_DBG("Key invalidation failed with: %d", status); - } - } -out: - return ret; -} -#endif /* CONFIG_BOOT_KMU_KEYS_REVOCATION */ - -#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) -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 - -#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..a5d58461e --- /dev/null +++ b/boot/bootutil/src/ed25519_psa_kmu.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include +#include "bootutil/bootutil_log.h" + +#include +#include +#include +#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU) +#include +#endif + +BOOT_LOG_MODULE_DECLARE(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 + +#define PSA_KEY_STARTING_ID CONFIG_NCS_BOOT_SIGNATURE_KMU_BASE_SLOT + +#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 +#define VALIDATED_WITH_UNINITIALIZED INT32_MAX +static int32_t validated_with = VALIDATED_WITH_UNINITIALIZED; +#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) + if(i < validated_with) { + validated_with = 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 == VALIDATED_WITH_UNINITIALIZED) { + 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 ( 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_DBG("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); + } +} diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 54e9e3e6b..f724da854 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -344,10 +344,15 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519) ${MBEDTLS_ASN1_DIR}/src/asn1parse.c ) endif() - - zephyr_library_sources( - ${BOOT_DIR}/bootutil/src/ed25519_psa.c - ) + if(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() endif()