From 355a50065ef0f3e7909afa1de31e1589e5741c42 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Nov 2024 11:10:10 +0000 Subject: [PATCH 01/10] bootloader: bl_crypto: Add PSA SHA512 support Adds support for using SHA512 signatures using PSA crypto Signed-off-by: Jamie McCrae --- include/bl_crypto.h | 89 ++++++++++--- subsys/bootloader/bl_crypto/CMakeLists.txt | 18 +-- subsys/bootloader/bl_crypto/Kconfig | 121 +++++++++++------- subsys/bootloader/bl_crypto/bl_crypto.c | 2 +- .../bootloader/bl_crypto/bl_crypto_sha512.c | 50 ++++++++ 5 files changed, 209 insertions(+), 71 deletions(-) create mode 100644 subsys/bootloader/bl_crypto/bl_crypto_sha512.c diff --git a/include/bl_crypto.h b/include/bl_crypto.h index 2a353e7147a1..f78351701440 100644 --- a/include/bl_crypto.h +++ b/include/bl_crypto.h @@ -13,7 +13,10 @@ extern "C" { #include #include - +#if defined(CONFIG_NRF_SECURITY) +#include +#include +#endif /** @defgroup bl_crypto Bootloader crypto functions * @{ @@ -24,21 +27,23 @@ extern "C" { #define EHASHINV 101 #define ESIGINV 102 - -#if CONFIG_SB_CRYPTO_OBERON_SHA256 - #include - #define SHA256_CTX_SIZE sizeof(ocrypto_sha256_ctx) - typedef ocrypto_sha256_ctx bl_sha256_ctx_t; -#elif CONFIG_SB_CRYPTO_CC310_SHA256 - #include - #define SHA256_CTX_SIZE sizeof(nrf_cc310_bl_hash_context_sha256_t) - typedef nrf_cc310_bl_hash_context_sha256_t bl_sha256_ctx_t; +#if defined(CONFIG_SB_CRYPTO_PSA_SHA512) +typedef psa_hash_operation_t bl_sha512_ctx_t; +#elif defined(CONFIG_SB_CRYPTO_OBERON_SHA256) +#include +#define SHA256_CTX_SIZE sizeof(ocrypto_sha256_ctx) +typedef ocrypto_sha256_ctx bl_sha256_ctx_t; +#elif defined(CONFIG_SB_CRYPTO_CC310_SHA256) +#include +#define SHA256_CTX_SIZE sizeof(nrf_cc310_bl_hash_context_sha256_t) +typedef nrf_cc310_bl_hash_context_sha256_t bl_sha256_ctx_t; #else - #define SHA256_CTX_SIZE 256 - // uint32_t to make sure it is aligned equally as the other contexts. - typedef uint32_t bl_sha256_ctx_t[SHA256_CTX_SIZE/4]; +#define SHA256_CTX_SIZE 256 +/* uint32_t to make sure it is aligned equally as the other contexts. */ +typedef uint32_t bl_sha256_ctx_t[SHA256_CTX_SIZE/4]; #endif + /** * @brief Initialize bootloader crypto module. * @@ -96,7 +101,6 @@ int bl_root_of_trust_verify_external(const uint8_t *public_key, const uint8_t *firmware, const uint32_t firmware_len); - /** * @brief Initialize a sha256 operation context variable. * @@ -169,6 +173,62 @@ int bl_sha256_verify(const uint8_t *data, uint32_t data_len, const uint8_t *expe typedef int (*bl_sha256_verify_t)(const uint8_t *data, uint32_t data_len, const uint8_t *expected); +#if defined(CONFIG_SB_CRYPTO_PSA_SHA512) +/** + * @brief Initialize a sha512 operation context variable. + * + * @param[out] ctx Context to be initialized. + * + * @retval 0 On success. + * @retval -EINVAL If @p ctx was NULL. + */ +int bl_sha512_init(bl_sha512_ctx_t *ctx); + +/** + * @brief Hash a portion of data. + * + * @note @p ctx must be initialized before being used in this function. + * An uninitialized @p ctx might not be reported as an error. Also, + * @p ctx must not be used if it has been finalized, though this might + * also not be reported as an error. + * + * @param[in] ctx Context variable. Must have been initialized. + * @param[in] data Data to hash. + * @param[in] data_len Length of @p data. + * + * @retval 0 On success. + * @retval -EINVAL If @p ctx was NULL, uninitialized, or corrupted. + * @retval -ENOSYS If the context has already been finalized. + */ +int bl_sha512_update(bl_sha512_ctx_t *ctx, const uint8_t *data, uint32_t data_len); + +/** + * @brief Finalize a hash result. + * + * @param[in] ctx Context variable. + * @param[out] output Where to put the resulting digest. Must be at least + * 32 bytes long. + * + * @retval 0 On success. + * @retval -EINVAL If @p ctx was NULL or corrupted, or @p output was NULL. + */ +int bl_sha512_finalize(bl_sha512_ctx_t *ctx, uint8_t *output); + +/** + * @brief Calculate a digest and verify it directly. + * + * @param[in] data The data to hash. + * @param[in] data_len The length of @p data. + * @param[in] expected The expected digest over @p data. + * + * @retval 0 If the procedure succeeded and the resulting digest is + * identical to @p expected. + * @retval -EHASHINV If the procedure succeeded, but the digests don't match. + * @return Any error code from @ref bl_512_init, @ref bl_sha512_update, or + * @ref bl_sha512_finalize if something else went wrong. + */ +int bl_sha512_verify(const uint8_t *data, uint32_t data_len, const uint8_t *expected); +#endif /** * @brief Validate a secp256r1 signature. @@ -195,7 +255,6 @@ typedef int (*bl_secp256r1_validate_t)( const uint8_t *signature, const uint8_t *public_key); - /** * @brief Structure describing the BL_ROT_VERIFY EXT_API. */ diff --git a/subsys/bootloader/bl_crypto/CMakeLists.txt b/subsys/bootloader/bl_crypto/CMakeLists.txt index 641f09cbad24..21b8972d1c16 100644 --- a/subsys/bootloader/bl_crypto/CMakeLists.txt +++ b/subsys/bootloader/bl_crypto/CMakeLists.txt @@ -9,32 +9,34 @@ zephyr_library_sources(bl_crypto.c) zephyr_library_link_libraries(nrfxlib_crypto) zephyr_link_libraries(nrfxlib_crypto) -if (CONFIG_SB_CRYPTO_OBERON_ECDSA_SECP256R1) +if(CONFIG_SB_CRYPTO_OBERON_ECDSA_SECP256R1) zephyr_library_sources(bl_crypto_oberon_ecdsa.c) -elseif (CONFIG_SB_CRYPTO_CC310_ECDSA_SECP256R1) +elseif(CONFIG_SB_CRYPTO_CC310_ECDSA_SECP256R1) zephyr_library_sources( bl_crypto_cc310_ecdsa.c bl_crypto_cc310_common.c ) -elseif (CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1) +elseif(CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1) zephyr_library_sources(../bl_crypto_client/bl_crypto_client.c) -elseif (CONFIG_SB_CRYPTO_NO_ECDSA_SECP256R1) +elseif(CONFIG_SB_CRYPTO_NO_ECDSA_SECP256R1) # Do nothing else() message(FATAL_ERROR "No signature implementation chosen for bootloader.") endif() -if (CONFIG_SB_CRYPTO_OBERON_SHA256) +if(CONFIG_SB_CRYPTO_OBERON_SHA256) zephyr_library_sources(bl_crypto_oberon_hash.c) -elseif (CONFIG_SB_CRYPTO_CC310_SHA256) +elseif(CONFIG_SB_CRYPTO_CC310_SHA256) zephyr_library_sources( bl_crypto_cc310_hash.c bl_crypto_cc310_common.c ) -elseif (CONFIG_SB_CRYPTO_CLIENT_SHA256) +elseif(CONFIG_SB_CRYPTO_CLIENT_SHA256) zephyr_library_sources(../bl_crypto_client/bl_crypto_client.c) -elseif (CONFIG_SB_CRYPTO_NO_SHA256) +elseif(CONFIG_SB_CRYPTO_NO_SHA256 OR CONFIG_SB_CRYPTO_NONE) # Do nothing +elseif(CONFIG_SB_CRYPTO_PSA_SHA512) + zephyr_library_sources(bl_crypto_sha512.c) else() message(FATAL_ERROR "No hash implementation chosen for bootloader.") endif() diff --git a/subsys/bootloader/bl_crypto/Kconfig b/subsys/bootloader/bl_crypto/Kconfig index 9bd327e7d1c6..86f49cf259d9 100644 --- a/subsys/bootloader/bl_crypto/Kconfig +++ b/subsys/bootloader/bl_crypto/Kconfig @@ -12,13 +12,19 @@ menuconfig SECURE_BOOT_CRYPTO select NRF_OBERON if (SECURE_BOOT_CRYPTO) + config SB_ECDSA_SECP256R1 bool + config SB_RSA_PSS2048 bool + config SB_SHA256 bool +config SB_SHA512 + bool + config SB_SIGNATURE_LEN int default 64 if SB_ECDSA_SECP256R1 @@ -30,7 +36,8 @@ config SB_PUBLIC_KEY_LEN default 256 if SB_RSA_PSS2048 config SB_HASH_LEN - def_int 32 + def_int 64 if SB_SHA512 + def_int 32 if !SB_CRYPTO_NONE choice SB_CRYPTO_SIG prompt "Firmware verification Algorithm" @@ -40,29 +47,29 @@ choice SB_CRYPTO_SIG help Crypto implementation to use for signature verification of firmware in Bootloader. - config SB_CRYPTO_OBERON_ECDSA_SECP256R1 - bool "Software ECDSA secp256r1" - select SB_ECDSA_SECP256R1 - help - Software implementation of ECDSA with NIST curve secp256r1. - - config SB_CRYPTO_CC310_ECDSA_SECP256R1 - bool "Hardware ECDSA secp256r1" if HAS_HW_NRF_CC310 - select NRF_CC310_BL - select SB_ECDSA_SECP256R1 - help - Hardware implementation of ECDSA with NIST curve secp256r1. - - config SB_CRYPTO_CLIENT_ECDSA_SECP256R1 - bool "Use another image's ECDSA secp256r1 implementation" - select BL_SECP256R1_EXT_API_ATLEAST_REQUIRED - select SB_ECDSA_SECP256R1 - help - Using EXT_APIs from fw_info. - - config SB_CRYPTO_NO_ECDSA_SECP256R1 - bool "Disable secp256r1 support" - select SB_ECDSA_SECP256R1 +config SB_CRYPTO_OBERON_ECDSA_SECP256R1 + bool "Software ECDSA secp256r1" + select SB_ECDSA_SECP256R1 + help + Software implementation of ECDSA with NIST curve secp256r1. + +config SB_CRYPTO_CC310_ECDSA_SECP256R1 + bool "Hardware ECDSA secp256r1" if HAS_HW_NRF_CC310 + select NRF_CC310_BL + select SB_ECDSA_SECP256R1 + help + Hardware implementation of ECDSA with NIST curve secp256r1. + +config SB_CRYPTO_CLIENT_ECDSA_SECP256R1 + bool "Use another image's ECDSA secp256r1 implementation" + select BL_SECP256R1_EXT_API_ATLEAST_REQUIRED + select SB_ECDSA_SECP256R1 + help + Using EXT_APIs from fw_info. + +config SB_CRYPTO_NO_ECDSA_SECP256R1 + bool "Disable secp256r1 support" + select SB_ECDSA_SECP256R1 #config SB_CRYPTO_OBERON_RSA_2048 # bool #"Software RSA-PSS 2048-bits" @@ -84,35 +91,51 @@ endchoice choice SB_CRYPTO_HASH prompt "Hashing Implementation" + default SB_CRYPTO_NONE if SB_CRYPTO_PSA_ED25519 default SB_CRYPTO_NO_SHA256 if !IS_SECURE_BOOTLOADER default SB_CRYPTO_CC310_SHA256 if HAS_HW_NRF_CC310 default SB_CRYPTO_OBERON_SHA256 help Crypto implementation to use for hash generation in Bootloader. - config SB_CRYPTO_OBERON_SHA256 - bool "Software SHA256" - select SB_SHA256 - help - Software implementation of SHA256. - - config SB_CRYPTO_CC310_SHA256 - bool "Hardware SHA256" if HAS_HW_NRF_CC310 - select NRF_CC310_BL - select SB_SHA256 - help - Hardware implementation of SHA256. - - config SB_CRYPTO_CLIENT_SHA256 - bool "Use another image's SHA256 implementation" - select BL_SHA256_EXT_API_ATLEAST_REQUIRED - select SB_SHA256 - help - Using EXT_APIs from fw_info. - - config SB_CRYPTO_NO_SHA256 - bool "Disable SHA256 support" - select SB_SHA256 +config SB_CRYPTO_OBERON_SHA256 + bool "Software SHA256" + select SB_SHA256 + help + Software implementation of SHA256. + +config SB_CRYPTO_CC310_SHA256 + bool "Hardware SHA256" if HAS_HW_NRF_CC310 + select NRF_CC310_BL + select SB_SHA256 + help + Hardware implementation of SHA256. + +config SB_CRYPTO_CLIENT_SHA256 + bool "Use another image's SHA256 implementation" + select BL_SHA256_EXT_API_ATLEAST_REQUIRED + select SB_SHA256 + help + Using EXT_APIs from fw_info. + +config SB_CRYPTO_NO_SHA256 + bool "Disable SHA256 support" + +config SB_CRYPTO_NONE + bool "None" + help + No hash will be present in the image. + +config SB_CRYPTO_PSA_SHA512 + bool "PSA SHA512 support" + depends on NRF_SECURITY + select SB_SHA512 + select PSA_WANT_ALG_SHA_512 + select PSA_WANT_ALG_PURE_EDDSA + select PSA_WANT_ECC_TWISTED_EDWARDS_255 + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + help + Use PSA crypto for SHA512 support. endchoice @@ -122,16 +145,20 @@ flags = 2 ver = 1 source "${ZEPHYR_BASE}/../nrf/subsys/fw_info/Kconfig.template.fw_info_ext_api" +if SB_SHA256 EXT_API = BL_SHA256 id = 0x1002 flags = 0 ver = 1 source "${ZEPHYR_BASE}/../nrf/subsys/fw_info/Kconfig.template.fw_info_ext_api" +endif +if SB_ECDSA_SECP256R1 EXT_API = BL_SECP256R1 id = 0x1003 flags = 1 ver = 1 source "${ZEPHYR_BASE}/../nrf/subsys/fw_info/Kconfig.template.fw_info_ext_api" +endif endif # SECURE_BOOT_CRYPTO diff --git a/subsys/bootloader/bl_crypto/bl_crypto.c b/subsys/bootloader/bl_crypto/bl_crypto.c index d9796a7fb6ef..40163ded3808 100644 --- a/subsys/bootloader/bl_crypto/bl_crypto.c +++ b/subsys/bootloader/bl_crypto/bl_crypto.c @@ -115,7 +115,7 @@ int bl_root_of_trust_verify_external( firmware, firmware_len, true); } -#ifndef CONFIG_BL_SHA256_EXT_API_REQUIRED +#if !defined(CONFIG_BL_SHA256_EXT_API_REQUIRED) && !defined(CONFIG_SB_CRYPTO_NONE) int bl_sha256_verify(const uint8_t *data, uint32_t data_len, const uint8_t *expected) { return verify_truncated_hash(data, data_len, expected, CONFIG_SB_HASH_LEN, true); diff --git a/subsys/bootloader/bl_crypto/bl_crypto_sha512.c b/subsys/bootloader/bl_crypto/bl_crypto_sha512.c new file mode 100644 index 000000000000..32810ba3c46d --- /dev/null +++ b/subsys/bootloader/bl_crypto/bl_crypto_sha512.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include + +int bl_sha512_init(bl_sha512_ctx_t * const ctx) +{ + *ctx = psa_hash_operation_init(); + return (int)psa_hash_setup(ctx, PSA_ALG_SHA_512); +} + +int bl_sha512_update(bl_sha512_ctx_t *ctx, const uint8_t *data, uint32_t data_len) +{ + return (int)psa_hash_update(ctx, data, data_len); +} + +int bl_sha512_finalize(bl_sha512_ctx_t *ctx, uint8_t *output) +{ + size_t hash_length = 0; + /* Assumes the output buffer is at least the expected size of the hash */ + return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_512), &hash_length); +} + +int get_hash(uint8_t *hash, const uint8_t *data, uint32_t data_len, bool external) +{ + bl_sha512_ctx_t ctx; + int rc; + + rc = bl_sha512_init(&ctx); + + if (rc != 0) { + return rc; + } + + rc = bl_sha512_update(&ctx, data, data_len); + + if (rc != 0) { + return rc; + } + + rc = bl_sha512_finalize(&ctx, hash); + return rc; +} From 9ebb9ca4da430f4e2ffcbbbfe23632a14cb66b68 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Nov 2024 11:12:11 +0000 Subject: [PATCH 02/10] bootloader: bl_crypto: Add support for PSA ED25519 signatures Adds support for ED25519 signatures using PSA crypto Signed-off-by: Jamie McCrae --- include/bl_crypto.h | 16 +++++ subsys/bootloader/bl_crypto/CMakeLists.txt | 2 + subsys/bootloader/bl_crypto/Kconfig | 22 +++++++ subsys/bootloader/bl_crypto/bl_crypto.c | 16 ++++- .../bootloader/bl_crypto/bl_crypto_ed25519.c | 64 +++++++++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 subsys/bootloader/bl_crypto/bl_crypto_ed25519.c diff --git a/include/bl_crypto.h b/include/bl_crypto.h index f78351701440..cdb4574abc00 100644 --- a/include/bl_crypto.h +++ b/include/bl_crypto.h @@ -255,6 +255,22 @@ typedef int (*bl_secp256r1_validate_t)( const uint8_t *signature, const uint8_t *public_key); +/** + * @brief Validate an ed25519 signature. + * + * @param[in] hash The hash to validate against. + * @param[in] hash_len The length of the hash. + * @param[in] signature The signature to validate. + * + * @retval 0 The operation succeeded and the signature is valid for the + * hash. + * @retval -EINVAL A parameter was NULL, or the @p hash_len was not 64 bytes. + * @retval -ESIGINV The signature validation failed. + */ +int bl_ed25519_validate(const uint8_t *hash, + uint32_t hash_len, + const uint8_t *signature); + /** * @brief Structure describing the BL_ROT_VERIFY EXT_API. */ diff --git a/subsys/bootloader/bl_crypto/CMakeLists.txt b/subsys/bootloader/bl_crypto/CMakeLists.txt index 21b8972d1c16..667ce89a16f4 100644 --- a/subsys/bootloader/bl_crypto/CMakeLists.txt +++ b/subsys/bootloader/bl_crypto/CMakeLists.txt @@ -20,6 +20,8 @@ elseif(CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1) zephyr_library_sources(../bl_crypto_client/bl_crypto_client.c) elseif(CONFIG_SB_CRYPTO_NO_ECDSA_SECP256R1) # Do nothing +elseif(CONFIG_SB_CRYPTO_PSA_ED25519) + zephyr_library_sources(bl_crypto_ed25519.c) else() message(FATAL_ERROR "No signature implementation chosen for bootloader.") endif() diff --git a/subsys/bootloader/bl_crypto/Kconfig b/subsys/bootloader/bl_crypto/Kconfig index 86f49cf259d9..f7e3e370b862 100644 --- a/subsys/bootloader/bl_crypto/Kconfig +++ b/subsys/bootloader/bl_crypto/Kconfig @@ -16,6 +16,9 @@ if (SECURE_BOOT_CRYPTO) config SB_ECDSA_SECP256R1 bool +config SB_ED25519 + bool + config SB_RSA_PSS2048 bool @@ -28,11 +31,13 @@ config SB_SHA512 config SB_SIGNATURE_LEN int default 64 if SB_ECDSA_SECP256R1 + default 64 if SB_ED25519 default 256 if SB_RSA_PSS2048 config SB_PUBLIC_KEY_LEN int default 64 if SB_ECDSA_SECP256R1 + default 32 if SB_ED25519 default 256 if SB_RSA_PSS2048 config SB_HASH_LEN @@ -71,6 +76,19 @@ config SB_CRYPTO_NO_ECDSA_SECP256R1 bool "Disable secp256r1 support" select SB_ECDSA_SECP256R1 +config SB_CRYPTO_PSA_ED25519 + bool "PSA ed25519 support" + depends on NRF_SECURITY + depends on CRACEN_LIB_KMU + select SB_ED25519 + select PSA_WANT_ALG_SHA_512 + select PSA_WANT_ALG_PURE_EDDSA + select PSA_WANT_ECC_TWISTED_EDWARDS_255 + select PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + select MBEDTLS_ENABLE_HEAP + help + Use PSA crypto for ed25519 support. + #config SB_CRYPTO_OBERON_RSA_2048 # bool #"Software RSA-PSS 2048-bits" # select NRF_OBERON @@ -161,4 +179,8 @@ ver = 1 source "${ZEPHYR_BASE}/../nrf/subsys/fw_info/Kconfig.template.fw_info_ext_api" endif +module = SB_CRYPTO +module-str = secure boot crypto +source "subsys/logging/Kconfig.template.log_config" + endif # SECURE_BOOT_CRYPTO diff --git a/subsys/bootloader/bl_crypto/bl_crypto.c b/subsys/bootloader/bl_crypto/bl_crypto.c index 40163ded3808..190d386fa6e7 100644 --- a/subsys/bootloader/bl_crypto/bl_crypto.c +++ b/subsys/bootloader/bl_crypto/bl_crypto.c @@ -34,6 +34,7 @@ int bl_crypto_init(void) #include #include "bl_crypto_internal.h" +#if !defined(CONFIG_SB_ED25519) static int verify_truncated_hash(const uint8_t *data, uint32_t data_len, const uint8_t *expected, uint32_t hash_len, bool external) { @@ -43,15 +44,18 @@ static int verify_truncated_hash(const uint8_t *data, uint32_t data_len, if (retval != 0) { return retval; } + if (!ocrypto_constant_time_equal(expected, hash, hash_len)) { return -EHASHINV; } return 0; } +#endif static int verify_signature(const uint8_t *data, uint32_t data_len, const uint8_t *signature, const uint8_t *public_key, bool external) { +#if defined(CONFIG_SB_ECDSA_SECP256R1) uint8_t hash1[CONFIG_SB_HASH_LEN]; uint8_t hash2[CONFIG_SB_HASH_LEN]; @@ -66,6 +70,11 @@ static int verify_signature(const uint8_t *data, uint32_t data_len, } return bl_secp256r1_validate(hash2, CONFIG_SB_HASH_LEN, public_key, signature); +#elif defined(CONFIG_SB_ED25519) + return bl_ed25519_validate(data, data_len, signature); +#else +#error "Unsupported signature type selected" +#endif } /* Base implementation, with 'external' parameter. */ @@ -74,14 +83,19 @@ static int root_of_trust_verify( const uint8_t *signature, const uint8_t *firmware, const uint32_t firmware_len, bool external) { +#if !defined(CONFIG_SB_ED25519) __ASSERT(public_key && public_key_hash && signature && firmware, - "A parameter was NULL."); + "A parameter was NULL."); + int retval = verify_truncated_hash(public_key, CONFIG_SB_PUBLIC_KEY_LEN, public_key_hash, SB_PUBLIC_KEY_HASH_LEN, external); if (retval != 0) { return retval; } +#else + __ASSERT((signature && firmware), "A parameter was NULL."); +#endif return verify_signature(firmware, firmware_len, signature, public_key, external); diff --git a/subsys/bootloader/bl_crypto/bl_crypto_ed25519.c b/subsys/bootloader/bl_crypto/bl_crypto_ed25519.c new file mode 100644 index 000000000000..a51a952e1fc6 --- /dev/null +++ b/subsys/bootloader/bl_crypto/bl_crypto_ed25519.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include "bl_crypto_internal.h" +#include +#include +#include +#include + +LOG_MODULE_REGISTER(sb_crypto, CONFIG_SB_CRYPTO_LOG_LEVEL); + +/* List of KMU stored key ids available for NSIB */ +#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 kmu_key_ids[] = { + MAKE_PSA_KMU_KEY_ID(242), + MAKE_PSA_KMU_KEY_ID(244), + MAKE_PSA_KMU_KEY_ID(246) +}; + +int bl_ed25519_validate(const uint8_t *data, uint32_t data_len, const uint8_t *signature) +{ + psa_status_t status = PSA_ERROR_BAD_STATE; + + if (!data || (data_len == 0) || !signature) { + return -EINVAL; + } + + /* Initialize PSA Crypto */ + status = psa_crypto_init(); + + if (status != PSA_SUCCESS) { + LOG_ERR("PSA crypto init failed %d", status); + return -EIO; + } + + status = PSA_ERROR_BAD_STATE; + + for (int i = 0; i < ARRAY_SIZE(kmu_key_ids); ++i) { + psa_key_id_t kid = kmu_key_ids[i]; + + LOG_DBG("Checking against KMU key: %d", i); + + status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, data, data_len, signature, + CONFIG_SB_SIGNATURE_LEN); + + LOG_DBG("PSA verify message result: %d", status); + + if (status == PSA_SUCCESS) { + return 0; + } + } + + LOG_ERR("ED25519 signature verification failed: %d", status); + + return -ESIGINV; +} From f92e41205cf0547d21314f9c4424f100851958a7 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Nov 2024 11:13:09 +0000 Subject: [PATCH 03/10] bootloader: bl_validation: Make public key and hash optional Makes these fields optional for configurations where they are not needed Signed-off-by: Jamie McCrae --- subsys/bootloader/bl_validation/Kconfig | 12 +++++++ .../bootloader/bl_validation/bl_validation.c | 32 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/subsys/bootloader/bl_validation/Kconfig b/subsys/bootloader/bl_validation/Kconfig index 917d58101427..011845f91c2f 100644 --- a/subsys/bootloader/bl_validation/Kconfig +++ b/subsys/bootloader/bl_validation/Kconfig @@ -51,6 +51,18 @@ config SB_VALIDATION_METADATA_OFFSET the metadata is appended directly after the application image, aligned to the closest word. +config SB_VALIDATION_STRUCT_HAS_HASH + bool + default y if !SB_CRYPTO_PSA_ED25519 + help + Set if the struct should contain the hash field. + +config SB_VALIDATION_STRUCT_HAS_PUBLIC_KEY + bool + default y if !SB_CRYPTO_PSA_ED25519 + help + Set if the struct should contain the public key field. + if SECURE_BOOT_VALIDATION EXT_API = BL_VALIDATE_FW diff --git a/subsys/bootloader/bl_validation/bl_validation.c b/subsys/bootloader/bl_validation/bl_validation.c index c75a0b9909ba..90d665152ef0 100644 --- a/subsys/bootloader/bl_validation/bl_validation.c +++ b/subsys/bootloader/bl_validation/bl_validation.c @@ -131,13 +131,17 @@ struct __packed fw_validation_info { /* The address of the start (vector table) of the firmware. */ uint32_t address; +#if defined(CONFIG_SB_VALIDATION_STRUCT_HAS_HASH) /* The hash of the firmware.*/ uint8_t hash[CONFIG_SB_HASH_LEN]; +#endif +#if defined(CONFIG_SB_VALIDATION_STRUCT_HAS_PUBLIC_KEY) /* Public key to be used for signature verification. This must be * checked against a trusted hash. */ uint8_t public_key[CONFIG_SB_PUBLIC_KEY_LEN]; +#endif /* Signature over the firmware as represented by the address and size in * the firmware_info. @@ -149,10 +153,24 @@ struct __packed fw_validation_info { /* Static asserts to ensure compatibility */ OFFSET_CHECK(struct fw_validation_info, magic, 0); OFFSET_CHECK(struct fw_validation_info, address, 12); + +#if defined(CONFIG_SB_VALIDATION_STRUCT_HAS_HASH) OFFSET_CHECK(struct fw_validation_info, hash, 16); +#if defined(CONFIG_SB_VALIDATION_STRUCT_HAS_PUBLIC_KEY) OFFSET_CHECK(struct fw_validation_info, public_key, (16 + CONFIG_SB_HASH_LEN)); OFFSET_CHECK(struct fw_validation_info, signature, (16 + CONFIG_SB_HASH_LEN + CONFIG_SB_PUBLIC_KEY_LEN)); +#else +OFFSET_CHECK(struct fw_validation_info, signature, (16 + CONFIG_SB_HASH_LEN)); +#endif +#else +#if defined(CONFIG_SB_VALIDATION_STRUCT_HAS_PUBLIC_KEY) +OFFSET_CHECK(struct fw_validation_info, public_key, 16); +OFFSET_CHECK(struct fw_validation_info, signature, (16 + CONFIG_SB_PUBLIC_KEY_LEN)); +#else +OFFSET_CHECK(struct fw_validation_info, signature, 16); +#endif +#endif /* Can be used to make the firmware discoverable in other locations, e.g. when * searching backwards. This struct would typically be constructed locally, so @@ -219,6 +237,8 @@ static bool validate_signature(const uint32_t fw_src_address, const uint32_t fw_ bl_root_of_trust_verify_t rot_verify = external ? bl_root_of_trust_verify_external : bl_root_of_trust_verify; + +#if defined(CONFIG_SB_VALIDATION_STRUCT_HAS_PUBLIC_KEY) /* Some key data storage backends require word sized reads, hence * we need to ensure word alignment for 'key_data' */ @@ -265,6 +285,18 @@ static bool validate_signature(const uint32_t fw_src_address, const uint32_t fw_ return false; } } +#else + int retval = rot_verify(NULL, NULL, fw_val_info->signature, + (const uint8_t *)fw_src_address, + fw_size); + + if (retval == 0) { + LOG_INF("Firmware signature verified."); + return true; + } + + LOG_ERR("Firmware validation failed with error %d.", retval); +#endif LOG_ERR("Failed to validate signature."); return false; From fb2a97c67d982b4a4583a0408563afdd9d4c9aa0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Nov 2024 11:14:19 +0000 Subject: [PATCH 04/10] sysbuild: Add support for selecting b0 hash/signature types Adds support for allowing the hash and signature type to be selected, and adds support for ED25519 on nrf54l15 Signed-off-by: Jamie McCrae --- cmake/sysbuild/debug_keys.cmake | 10 +- cmake/sysbuild/provision_hex.cmake | 6 +- cmake/sysbuild/sign.cmake | 141 ++++++++++++----- sysbuild/CMakeLists.txt | 47 ++++++ sysbuild/Kconfig.secureboot | 236 ++++++++++++++++++++++++++++- 5 files changed, 396 insertions(+), 44 deletions(-) diff --git a/cmake/sysbuild/debug_keys.cmake b/cmake/sysbuild/debug_keys.cmake index bcf9def42dde..bf23da7c7756 100644 --- a/cmake/sysbuild/debug_keys.cmake +++ b/cmake/sysbuild/debug_keys.cmake @@ -6,14 +6,20 @@ string(REPLACE "," ";" PUBLIC_KEY_FILES_LIST "${SB_CONFIG_SECURE_BOOT_PUBLIC_KEY_FILES}") +if(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519) + set(keygen_algorithm --algorithm ed25519) +else() + set(keygen_algorithm) +endif() + set(PRIV_CMD ${PYTHON_EXECUTABLE} - ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/keygen.py --private + ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/keygen.py --private ${keygen_algorithm} ) set(PUB_CMD ${PYTHON_EXECUTABLE} - ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/keygen.py --public + ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/keygen.py --public ${keygen_algorithm} ) # Check if PEM file is specified by user, if not, create one a debug key diff --git a/cmake/sysbuild/provision_hex.cmake b/cmake/sysbuild/provision_hex.cmake index 81d727afc74d..a65e3b8d17ef 100644 --- a/cmake/sysbuild/provision_hex.cmake +++ b/cmake/sysbuild/provision_hex.cmake @@ -67,19 +67,21 @@ function(provision application prefix_name) set(partition_manager_target partition_manager_CPUNET) set(s0_arg --s0-addr $) set(s1_arg) + set(cpunet_target y) else() set(partition_manager_target partition_manager) set(s0_arg --s0-addr $) set(s1_arg --s1-addr $) + set(cpunet_target n) endif() if(SB_CONFIG_SECURE_BOOT_DEBUG_NO_VERIFY_HASHES) set(no_verify_hashes_arg --no-verify-hashes) endif() - b0_sign_image(${application}) + b0_sign_image(${application} ${cpunet_target}) if(NOT (CONFIG_SOC_NRF5340_CPUNET OR "${domain}" STREQUAL "CPUNET") AND SB_CONFIG_SECURE_BOOT_BUILD_S1_VARIANT_IMAGE) - b0_sign_image("s1_image") + b0_sign_image("s1_image" n) endif() endif() diff --git a/cmake/sysbuild/sign.cmake b/cmake/sysbuild/sign.cmake index bc504b1bcb33..ceae91bc6a5e 100644 --- a/cmake/sysbuild/sign.cmake +++ b/cmake/sysbuild/sign.cmake @@ -14,11 +14,17 @@ function(b0_gen_keys) set(SIGNATURE_PUBLIC_KEY_FILE ${GENERATED_PATH}/public.pem) set(SIGNATURE_PUBLIC_KEY_FILE ${GENERATED_PATH}/public.pem PARENT_SCOPE) + if(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519) + set(keygen_algorithm --algorithm ed25519) + else() + set(keygen_algorithm) + endif() + if(SB_CONFIG_SECURE_BOOT_SIGNING_PYTHON) set(PUB_GEN_CMD ${PYTHON_EXECUTABLE} ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/keygen.py - --public + --public ${keygen_algorithm} --in ${SIGNATURE_PRIVATE_KEY_FILE} --out ${SIGNATURE_PUBLIC_KEY_FILE} ) @@ -66,7 +72,7 @@ function(b0_gen_keys) ) endfunction() -function(b0_sign_image slot) +function(b0_sign_image slot cpunet_target) set(GENERATED_PATH ${CMAKE_BINARY_DIR}/nrf/subsys/bootloader/generated) # Get variables for secure boot usage @@ -104,6 +110,7 @@ function(b0_sign_image slot) sysbuild_get(${slot}_crypto_id IMAGE ${slot} VAR CONFIG_SB_VALIDATION_INFO_CRYPTO_ID KCONFIG) sysbuild_get(${slot}_validation_offset IMAGE ${slot} VAR CONFIG_SB_VALIDATION_METADATA_OFFSET KCONFIG) + set(slot_bin ${${slot}_image_dir}/zephyr/${${slot}_kernel_name}.bin) set(slot_hex ${${slot}_image_dir}/zephyr/${${slot}_kernel_name}.hex) set(sign_depends ${${slot}_image_dir}/zephyr/${${slot}_kernel_name}.elf) set(target_name ${slot}) @@ -119,6 +126,7 @@ function(b0_sign_image slot) sysbuild_get(${slot}_crypto_id IMAGE ${target_name} VAR CONFIG_SB_VALIDATION_INFO_CRYPTO_ID KCONFIG) sysbuild_get(${slot}_validation_offset IMAGE ${target_name} VAR CONFIG_SB_VALIDATION_METADATA_OFFSET KCONFIG) + set(slot_bin ${${target_name}_image_dir}/zephyr/${${target_name}_kernel_name}.bin) set(slot_hex ${${target_name}_image_dir}/zephyr/${${target_name}_kernel_name}.hex) set(sign_depends ${target_name} ${${target_name}_image_dir}/zephyr/${${target_name}_kernel_name}.elf) else() @@ -133,36 +141,70 @@ function(b0_sign_image slot) "This value of SB_VALIDATION_INFO_CRYPTO_ID is not supported") endif() - set(to_sign ${slot_hex}) - set(hash_file ${GENERATED_PATH}/${slot}_firmware.sha256) set(signature_file ${GENERATED_PATH}/${slot}_firmware.signature) - set(hash_cmd - ${PYTHON_EXECUTABLE} - ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/hash.py - --in ${to_sign} - > ${hash_file} - ) + if(cpunet_target) + set(config_addition NETCORE) + else() + set(config_addition APPCORE) + endif() + + if(SB_CONFIG_SECURE_BOOT_${config_addition}_HASH_TYPE_NONE) + set(hash_file ${slot_bin}) + set(to_sign ${slot_hex}) + elseif(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519) + set(hash_file ${GENERATED_PATH}/${slot}_firmware.sha512) + set(hash_cmd_type --type sha512) + set(sign_cmd_hash_type sha512) + elseif(SB_CONFIG_SECURE_BOOT_HASH_TYPE_SHA256) + set(hash_file ${GENERATED_PATH}/${slot}_firmware.sha256) + set(hash_cmd_type) + set(sign_cmd_hash_type sha256) + endif() + + if(sign_cmd_hash_type) + set(to_sign ${slot_hex}) + set(hash_cmd + ${PYTHON_EXECUTABLE} + ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/hash.py + --in ${to_sign} ${hash_cmd_type} + > ${hash_file} + ) + endif() if(SB_CONFIG_SECURE_BOOT_SIGNING_PYTHON) + if(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519) + set(sign_cmd_signature_type --algorithm ed25519) + else() + set(sign_cmd_signature_type) + endif() + set(sign_cmd ${PYTHON_EXECUTABLE} ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/do_sign.py --private-key ${SIGNATURE_PRIVATE_KEY_FILE} - --in ${hash_file} + --in ${hash_file} ${sign_cmd_signature_type} > ${signature_file} ) elseif(SB_CONFIG_SECURE_BOOT_SIGNING_OPENSSL) - set(sign_cmd - openssl dgst - -sha256 - -sign ${SIGNATURE_PRIVATE_KEY_FILE} ${hash_file} | - ${PYTHON_EXECUTABLE} - ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/asn1parse.py - --alg ecdsa - --contents signature - > ${signature_file} - ) + if(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519) + set(sign_cmd + openssl pkeyutl -sign -inkey ${SIGNATURE_PRIVATE_KEY_FILE} -rawin -in ${hash_file} > ${signature_file} && + openssl pkeyutl -verify -pubin -inkey ${SIGNATURE_PRIVATE_KEY_FILE} -rawin -in ${hash_file} -sigfile ${signature_file} + ) + else() + set(sign_cmd + openssl dgst + -${sign_cmd_hash_type} + -sign ${SIGNATURE_PRIVATE_KEY_FILE} ${hash_file} | + ${PYTHON_EXECUTABLE} + ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/asn1parse.py + --alg ecdsa + --contents signature + > ${signature_file} + ) + endif() + elseif(SB_CONFIG_SECURE_BOOT_SIGNING_CUSTOM) set(custom_sign_cmd "${SB_CONFIG_SECURE_BOOT_SIGNING_COMMAND}") string(CONFIGURE "${custom_sign_cmd}" custom_sign_cmd) @@ -177,22 +219,39 @@ function(b0_sign_image slot) message(WARNING "Unable to parse signing config.") endif() - add_custom_command( - OUTPUT - ${signature_file} - COMMAND - ${hash_cmd} - COMMAND - ${sign_cmd} - DEPENDS - ${sign_depends} - WORKING_DIRECTORY - ${PROJECT_BINARY_DIR} - COMMENT - "Creating signature of application" - USES_TERMINAL - COMMAND_EXPAND_LISTS - ) + if(sign_cmd_hash_type) + add_custom_command( + OUTPUT + ${signature_file} + COMMAND + ${hash_cmd} + COMMAND + ${sign_cmd} + DEPENDS + ${sign_depends} + WORKING_DIRECTORY + ${PROJECT_BINARY_DIR} + COMMENT + "Creating signature of application" + USES_TERMINAL + COMMAND_EXPAND_LISTS + ) + else() + add_custom_command( + OUTPUT + ${signature_file} + COMMAND + ${sign_cmd} + DEPENDS + ${sign_depends} + WORKING_DIRECTORY + ${PROJECT_BINARY_DIR} + COMMENT + "Creating signature of application" + USES_TERMINAL + COMMAND_EXPAND_LISTS + ) + endif() add_custom_target( ${slot}_signature_file_target @@ -204,6 +263,12 @@ function(b0_sign_image slot) cmake_path(GET to_sign FILENAME to_sign_filename) set(validation_comment "Creating validation for ${to_sign_filename}, storing to ${signed_hex_filename}") + if(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519) + set(validation_signature_cmd --algorithm ed25519) + else() + set(validation_signature_cmd) + endif() + add_custom_command( OUTPUT ${signed_hex} @@ -211,7 +276,7 @@ function(b0_sign_image slot) COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_NRF_MODULE_DIR}/scripts/bootloader/validation_data.py - --input ${to_sign} + --input ${to_sign} ${validation_signature_cmd} --output-hex ${signed_hex} --output-bin ${signed_bin} --offset ${${slot}_validation_offset} diff --git a/sysbuild/CMakeLists.txt b/sysbuild/CMakeLists.txt index 15b0bb044b49..7955c4d9d08f 100644 --- a/sysbuild/CMakeLists.txt +++ b/sysbuild/CMakeLists.txt @@ -475,6 +475,34 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) set_config_bool(${DEFAULT_IMAGE} CONFIG_SECURE_BOOT y) set_config_bool(${DEFAULT_IMAGE} CONFIG_FW_INFO y) endif() + + # Apply configuration for hashing + if(SB_CONFIG_SECURE_BOOT_HASH_TYPE_SHA256 AND NOT SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_NONE) + if(SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_HARDWARE) + set_config_bool(b0 CONFIG_SB_CRYPTO_CC310_SHA256 y) + elseif(SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_SOFTWARE) + set_config_bool(b0 CONFIG_SB_CRYPTO_OBERON_SHA256 y) + elseif(SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_UNUSED) + set_config_bool(b0 CONFIG_SB_CRYPTO_NO_SHA256 y) + endif() + elseif(SB_CONFIG_SECURE_BOOT_HASH_TYPE_NONE OR SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_NONE) + set_config_bool(b0 CONFIG_SB_CRYPTO_NONE y) + endif() + + if(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ED25519) + if(SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_HARDWARE) + set_config_bool(b0 CONFIG_NRF_SECURITY y) + set_config_bool(b0 CONFIG_SB_CRYPTO_PSA_ED25519 y) + endif() + elseif(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ECDSA) + if(SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_HARDWARE) + set_config_bool(b0 CONFIG_SB_CRYPTO_CC310_ECDSA_SECP256R1 y) + elseif(SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_SOFTWARE) + set_config_bool(b0 CONFIG_SB_CRYPTO_OBERON_ECDSA_SECP256R1 y) + elseif(SB_CONFIG_SECURE_BOOT_APPCORE_HASH_TYPE_UNUSED) + set_config_bool(b0 CONFIG_SB_CRYPTO_NO_ECDSA_SECP256R1 y) + endif() + endif() endif() if(SB_CONFIG_SECURE_BOOT_NETCORE) @@ -482,6 +510,25 @@ function(${SYSBUILD_CURRENT_MODULE_NAME}_pre_cmake) set_config_bool(${SB_CONFIG_NETCORE_IMAGE_NAME} CONFIG_SECURE_BOOT y) endif() + # Apply configuration for hashing + if(SB_CONFIG_SECURE_BOOT_HASH_TYPE_SHA256 AND NOT SB_CONFIG_SECURE_BOOT_NETCORE_HASH_TYPE_NONE) + if(SB_CONFIG_SECURE_BOOT_NETCORE_HASH_TYPE_SOFTWARE) + set_config_bool(b0n CONFIG_SB_CRYPTO_OBERON_SHA256 y) + elseif(SB_CONFIG_SECURE_BOOT_NETCORE_HASH_TYPE_UNUSED) + set_config_bool(b0n CONFIG_SB_CRYPTO_NO_SHA256 y) + endif() + elseif(SB_CONFIG_SECURE_BOOT_HASH_TYPE_NONE OR SB_CONFIG_SECURE_BOOT_NETCORE_HASH_TYPE_NONE) + set_config_bool(b0n CONFIG_SB_CRYPTO_NONE y) + endif() + + if(SB_CONFIG_SECURE_BOOT_SIGNATURE_TYPE_ECDSA) + if(SB_CONFIG_SECURE_BOOT_NETCORE_SIGNATURE_TYPE_SOFTWARE) + set_config_bool(b0n CONFIG_SB_CRYPTO_OBERON_ECDSA_SECP256R1 y) + elseif(SB_CONFIG_SECURE_BOOT_NETCORE_SIGNATURE_TYPE_UNUSED) + set_config_bool(b0n CONFIG_SB_CRYPTO_NO_ECDSA_SECP256R1 y) + endif() + endif() + if(SB_CONFIG_BOOTLOADER_MCUBOOT) if(SB_CONFIG_NETCORE_APP_UPDATE) set_config_bool(mcuboot CONFIG_PCD_APP y) diff --git a/sysbuild/Kconfig.secureboot b/sysbuild/Kconfig.secureboot index b1476209836e..8a1ef0b76e98 100644 --- a/sysbuild/Kconfig.secureboot +++ b/sysbuild/Kconfig.secureboot @@ -10,21 +10,253 @@ config SECURE_BOOT This option will be set if the first stage bootloader which verifies the signature of the application is enabled for one or multiple cores. -config SECURE_BOOT_APPCORE +menuconfig SECURE_BOOT_APPCORE bool "Appcore" select SECURE_BOOT help Enable first stage bootloader for application core. -config SECURE_BOOT_NETCORE +if SECURE_BOOT_APPCORE + +config SECURE_BOOT_APPCORE_SUPPORTED_HASH_HARDWARE + bool + default y if SECURE_BOOT_HASH_TYPE_SHA256 && (SOC_SERIES_NRF91X || SOC_NRF52840) + +config SECURE_BOOT_APPCORE_SUPPORTED_HASH_SOFTWARE + bool + default y if !SECURE_BOOT_HASH_TYPE_NONE + +config SECURE_BOOT_APPCORE_SUPPORTED_HASH_UNUSED + bool + default y if !SECURE_BOOT_HASH_TYPE_NONE + +config SECURE_BOOT_APPCORE_SUPPORTED_HASH_NONE + bool + default y if SECURE_BOOT_HASH_TYPE_NONE + +config SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_HARDWARE + bool + default y if SECURE_BOOT_SIGNATURE_TYPE_ECDSA && (SOC_SERIES_NRF91X || SOC_NRF52840) + default y if SECURE_BOOT_SIGNATURE_TYPE_ED25519 && SOC_NRF54L15_CPUAPP + +config SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_SOFTWARE + bool + default y if !SECURE_BOOT_SIGNATURE_TYPE_NONE && !SECURE_BOOT_SIGNATURE_TYPE_ED25519 + +config SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_UNUSED + bool + default y + +choice SECURE_BOOT_APPCORE_HASH_TYPE + prompt "Hash mode" + default SECURE_BOOT_APPCORE_HASH_TYPE_HARDWARE if SECURE_BOOT_APPCORE_SUPPORTED_HASH_HARDWARE + default SECURE_BOOT_APPCORE_HASH_TYPE_SOFTWARE if SECURE_BOOT_APPCORE_SUPPORTED_HASH_SOFTWARE + default SECURE_BOOT_APPCORE_HASH_TYPE_UNUSED if SECURE_BOOT_APPCORE_SUPPORTED_HASH_UNUSED + default SECURE_BOOT_APPCORE_HASH_TYPE_NONE if SECURE_BOOT_APPCORE_SUPPORTED_HASH_NONE + +config SECURE_BOOT_APPCORE_HASH_TYPE_HARDWARE + bool "Hardware" + depends on SECURE_BOOT_APPCORE_SUPPORTED_HASH_HARDWARE + help + Hashing using hardware acceleration. + +config SECURE_BOOT_APPCORE_HASH_TYPE_SOFTWARE + bool "Software" + depends on SECURE_BOOT_APPCORE_SUPPORTED_HASH_SOFTWARE + help + Hashing using software implementation. + +config SECURE_BOOT_APPCORE_HASH_TYPE_UNUSED + bool "Unused" + depends on SECURE_BOOT_APPCORE_SUPPORTED_HASH_UNUSED + help + Hash present but not used/verified. + +config SECURE_BOOT_APPCORE_HASH_TYPE_NONE + bool "None" + depends on SECURE_BOOT_APPCORE_SUPPORTED_HASH_NONE + help + Disables hashing and excludes hash. + +endchoice + +choice SECURE_BOOT_APPCORE_SIGNATURE_TYPE + prompt "Signature mode" + default SECURE_BOOT_APPCORE_SIGNATURE_TYPE_HARDWARE if SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_HARDWARE + default SECURE_BOOT_APPCORE_SIGNATURE_TYPE_SOFTWARE if SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_SOFTWARE + default SECURE_BOOT_APPCORE_SIGNATURE_TYPE_UNUSED if SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_UNUSED + +config SECURE_BOOT_APPCORE_SIGNATURE_TYPE_HARDWARE + bool "Hardware" + depends on SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_HARDWARE + help + Signature verification using hardware acceleration. + +config SECURE_BOOT_APPCORE_SIGNATURE_TYPE_SOFTWARE + bool "Software" + depends on SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_SOFTWARE + help + Signatures verification using software implementation. + +config SECURE_BOOT_APPCORE_SIGNATURE_TYPE_UNUSED + bool "Unused" + depends on SECURE_BOOT_APPCORE_SUPPORTED_SIGNATURE_UNUSED + help + Signature present but not used/verified. + +endchoice + +endif # SECURE_BOOT_APPCORE + +menuconfig SECURE_BOOT_NETCORE bool "Netcore" depends on SUPPORT_NETCORE select SECURE_BOOT help Enable first stage bootloader for network core. +if SECURE_BOOT_NETCORE + +config SECURE_BOOT_NETCORE_SUPPORTED_HASH_SOFTWARE + bool + default y if !SECURE_BOOT_HASH_TYPE_NONE + +config SECURE_BOOT_NETCORE_SUPPORTED_HASH_UNUSED + bool + default y if !SECURE_BOOT_HASH_TYPE_NONE + +config SECURE_BOOT_NETCORE_SUPPORTED_HASH_NONE + bool + default y if SECURE_BOOT_HASH_TYPE_NONE + +config SECURE_BOOT_NETCORE_SUPPORTED_SIGNATURE_SOFTWARE + bool + default y + +config SECURE_BOOT_NETCORE_SUPPORTED_SIGNATURE_UNUSED + bool + default y + +choice SECURE_BOOT_NETCORE_HASH_TYPE + prompt "Hash mode" + default SECURE_BOOT_NETCORE_HASH_TYPE_SOFTWARE if SECURE_BOOT_NETCORE_SUPPORTED_HASH_SOFTWARE + default SECURE_BOOT_NETCORE_HASH_TYPE_UNUSED if SECURE_BOOT_NETCORE_SUPPORTED_HASH_UNUSED + default SECURE_BOOT_NETCORE_HASH_TYPE_NONE if SECURE_BOOT_NETCORE_SUPPORTED_HASH_NONE + +config SECURE_BOOT_NETCORE_HASH_TYPE_SOFTWARE + bool "Software" + depends on SECURE_BOOT_NETCORE_SUPPORTED_HASH_SOFTWARE + help + Hashing using software implementation. + +config SECURE_BOOT_NETCORE_HASH_TYPE_UNUSED + bool "Unused" + depends on SECURE_BOOT_NETCORE_SUPPORTED_HASH_UNUSED + help + Hash present but not used/verified. + +config SECURE_BOOT_NETCORE_HASH_TYPE_NONE + bool "None" + depends on SECURE_BOOT_NETCORE_SUPPORTED_HASH_NONE + help + Disables hashing and excludes hash. + +endchoice + +choice SECURE_BOOT_NETCORE_SIGNATURE_TYPE + # Application core verifies image, network core signature checking support is disabled by + # default selection to reduce flash usage + prompt "Signature mode" + default SECURE_BOOT_NETCORE_SIGNATURE_TYPE_UNUSED if SECURE_BOOT_NETCORE_SUPPORTED_SIGNATURE_UNUSED + +config SECURE_BOOT_NETCORE_SIGNATURE_TYPE_SOFTWARE + bool "Software" + depends on SECURE_BOOT_NETCORE_SUPPORTED_SIGNATURE_SOFTWARE + help + Signatures verification using software implementation. + +config SECURE_BOOT_NETCORE_SIGNATURE_TYPE_UNUSED + bool "Unused" + depends on SECURE_BOOT_NETCORE_SUPPORTED_SIGNATURE_UNUSED + help + Signature present but not used/verified. + +endchoice + +endif # SECURE_BOOT_NETCORE + if SECURE_BOOT +config SECURE_BOOT_SUPPORTED_HASH_SHA512 + bool + +config SECURE_BOOT_SUPPORTED_HASH_SHA256 + bool + default y if !SECURE_BOOT_SIGNATURE_TYPE_ED25519 + +config SECURE_BOOT_SUPPORTED_HASH_NONE + bool + default y if SECURE_BOOT_SIGNATURE_TYPE_ED25519 + +config SECURE_BOOT_SUPPORTED_SIGNATURE_ECDSA + bool + default y + +config SECURE_BOOT_SUPPORTED_SIGNATURE_ED25519 + bool + default y if SOC_NRF54L15_CPUAPP + +choice SECURE_BOOT_HASH_TYPE + prompt "Hash type" + default SECURE_BOOT_HASH_TYPE_SHA512 if SECURE_BOOT_SUPPORTED_HASH_SHA512 + default SECURE_BOOT_HASH_TYPE_SHA256 if SECURE_BOOT_SUPPORTED_HASH_SHA256 + default SECURE_BOOT_HASH_TYPE_NONE if SECURE_BOOT_SUPPORTED_HASH_NONE + +config SECURE_BOOT_HASH_TYPE_SHA512 + bool "SHA512" + depends on SECURE_BOOT_SUPPORTED_HASH_SHA512 + help + SHA512 hash. + +config SECURE_BOOT_HASH_TYPE_SHA256 + bool "SHA256" + depends on SECURE_BOOT_SUPPORTED_HASH_SHA256 + help + SHA256 hash. + +config SECURE_BOOT_HASH_TYPE_NONE + bool "None" + depends on SECURE_BOOT_SUPPORTED_HASH_NONE + help + Disables hashing and excludes hash. + +endchoice + +choice SECURE_BOOT_SIGNATURE_TYPE + prompt "Signature type" + default SECURE_BOOT_SIGNATURE_TYPE_ED25519 if SECURE_BOOT_SUPPORTED_SIGNATURE_ED25519 + default SECURE_BOOT_SIGNATURE_TYPE_ECDSA if SECURE_BOOT_SUPPORTED_SIGNATURE_ECDSA + default SECURE_BOOT_SIGNATURE_TYPE_NONE + +config SECURE_BOOT_SIGNATURE_TYPE_ED25519 + bool "ED25519" + depends on SECURE_BOOT_SUPPORTED_SIGNATURE_ED25519 + help + ED25519 signatures using hardware acceleration. + +config SECURE_BOOT_SIGNATURE_TYPE_ECDSA + bool "ECDSA" + depends on SECURE_BOOT_SUPPORTED_SIGNATURE_ECDSA + help + ECDSA signatures using hardware acceleration. + +config SECURE_BOOT_SIGNATURE_TYPE_NONE + bool "None" + help + Disables signatures and excludes public key. + +endchoice + config SECURE_BOOT_NETWORK_BOARD_TARGET_CPUCLUSTER string default "cpunet" if SOC_NRF5340_CPUAPP From d497e07b1d85db236f7b1ef1a3306887f9deb76e Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Nov 2024 11:15:08 +0000 Subject: [PATCH 05/10] samples: bootloader: Add nrf54l15dk configuration Adds a default configuration file which uses ED25519 with KMU support Signed-off-by: Jamie McCrae --- .../boards/nrf54l15dk_nrf54l15_cpuapp.conf | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 samples/bootloader/boards/nrf54l15dk_nrf54l15_cpuapp.conf diff --git a/samples/bootloader/boards/nrf54l15dk_nrf54l15_cpuapp.conf b/samples/bootloader/boards/nrf54l15dk_nrf54l15_cpuapp.conf new file mode 100644 index 000000000000..487a815ce95c --- /dev/null +++ b/samples/bootloader/boards/nrf54l15dk_nrf54l15_cpuapp.conf @@ -0,0 +1,14 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_BL_ROT_VERIFY_EXT_API_ENABLED=n +CONFIG_BL_SHA256_EXT_API_ENABLED=n +CONFIG_BL_SECP256R1_EXT_API_ENABLED=n +CONFIG_BL_VALIDATE_FW_EXT_API_ENABLED=n +CONFIG_EXT_API_PROVIDE_EXT_API_ENABLED=n +CONFIG_NRF_SECURITY=y +CONFIG_SB_CRYPTO_PSA_ED25519=y +CONFIG_SB_CRYPTO_NONE=y From 137d4417247774aea21141cc9ab8c67d94669525 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Nov 2024 11:59:56 +0000 Subject: [PATCH 06/10] include: bl_crypto: Fix wrong order of parameters The parameters listed are wrong Signed-off-by: Jamie McCrae --- include/bl_crypto.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/bl_crypto.h b/include/bl_crypto.h index cdb4574abc00..accea912ff64 100644 --- a/include/bl_crypto.h +++ b/include/bl_crypto.h @@ -235,8 +235,8 @@ int bl_sha512_verify(const uint8_t *data, uint32_t data_len, const uint8_t *expe * * @param[in] hash The hash to validate against. * @param[in] hash_len The length of the hash. - * @param[in] signature The signature to validate. * @param[in] public_key The public key to validate with. + * @param[in] signature The signature to validate. * * @retval 0 The operation succeeded and the signature is valid for the * hash. @@ -245,15 +245,15 @@ int bl_sha512_verify(const uint8_t *data, uint32_t data_len, const uint8_t *expe */ int bl_secp256r1_validate(const uint8_t *hash, uint32_t hash_len, - const uint8_t *signature, - const uint8_t *public_key); + const uint8_t *public_key, + const uint8_t *signature); /* Typedef for use in EXT_API declaration */ typedef int (*bl_secp256r1_validate_t)( const uint8_t *hash, uint32_t hash_len, - const uint8_t *signature, - const uint8_t *public_key); + const uint8_t *public_key, + const uint8_t *signature); /** * @brief Validate an ed25519 signature. From 17255a6ec894e24997417dd39d225297ff263995 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 29 Nov 2024 12:06:58 +0000 Subject: [PATCH 07/10] fw_info: Fix AT LEAST with underscore Prevents compliance from complaining Signed-off-by: Jamie McCrae --- subsys/bootloader/bl_crypto/Kconfig | 4 ++-- subsys/fw_info/Kconfig.template.fw_info_ext_api | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/bootloader/bl_crypto/Kconfig b/subsys/bootloader/bl_crypto/Kconfig index f7e3e370b862..670279c7293c 100644 --- a/subsys/bootloader/bl_crypto/Kconfig +++ b/subsys/bootloader/bl_crypto/Kconfig @@ -67,7 +67,7 @@ config SB_CRYPTO_CC310_ECDSA_SECP256R1 config SB_CRYPTO_CLIENT_ECDSA_SECP256R1 bool "Use another image's ECDSA secp256r1 implementation" - select BL_SECP256R1_EXT_API_ATLEAST_REQUIRED + select BL_SECP256R1_EXT_API_AT_LEAST_REQUIRED select SB_ECDSA_SECP256R1 help Using EXT_APIs from fw_info. @@ -131,7 +131,7 @@ config SB_CRYPTO_CC310_SHA256 config SB_CRYPTO_CLIENT_SHA256 bool "Use another image's SHA256 implementation" - select BL_SHA256_EXT_API_ATLEAST_REQUIRED + select BL_SHA256_EXT_API_AT_LEAST_REQUIRED select SB_SHA256 help Using EXT_APIs from fw_info. diff --git a/subsys/fw_info/Kconfig.template.fw_info_ext_api b/subsys/fw_info/Kconfig.template.fw_info_ext_api index 1957f511e5ce..e1e6c267343a 100644 --- a/subsys/fw_info/Kconfig.template.fw_info_ext_api +++ b/subsys/fw_info/Kconfig.template.fw_info_ext_api @@ -10,13 +10,13 @@ choice config $(EXT_API)_EXT_API_UNUSED bool "Don't request the $(EXT_API) EXT_API" - depends on !$(EXT_API)_EXT_API_ATLEAST_OPTIONAL && !$(EXT_API)_EXT_API_ATLEAST_REQUIRED + depends on !$(EXT_API)_EXT_API_AT_LEAST_OPTIONAL && !$(EXT_API)_EXT_API_AT_LEAST_REQUIRED help Do not include the client code for this external API (EXT_API). config $(EXT_API)_EXT_API_OPTIONAL bool "Request to use the $(EXT_API) EXT_API (optional)" - depends on !$(EXT_API)_EXT_API_ATLEAST_REQUIRED + depends on !$(EXT_API)_EXT_API_AT_LEAST_REQUIRED help Include client code for this EXT_API. This also puts a request for this EXT_API into the firmware info, marked as optional. The user must @@ -29,12 +29,12 @@ config $(EXT_API)_EXT_API_REQUIRED this EXT_API into the firmware info, marked as required. endchoice -config $(EXT_API)_EXT_API_ATLEAST_OPTIONAL +config $(EXT_API)_EXT_API_AT_LEAST_OPTIONAL bool help Can be selected to force at least OPTIONAL -config $(EXT_API)_EXT_API_ATLEAST_REQUIRED +config $(EXT_API)_EXT_API_AT_LEAST_REQUIRED bool help Can be selected to force REQUIRED From 8bdf8af018eb2249e9aee4db29c3ac9de0455990 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 3 Dec 2024 09:45:51 +0000 Subject: [PATCH 08/10] tests: bootloader: bl_validation: Select Kconfig for sha256 Selects the Kconfig to enable the hash field be present in the output Signed-off-by: Jamie McCrae --- tests/subsys/bootloader/bl_validation/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/subsys/bootloader/bl_validation/prj.conf b/tests/subsys/bootloader/bl_validation/prj.conf index 52471f8dd8a5..9b2a90db16ca 100644 --- a/tests/subsys/bootloader/bl_validation/prj.conf +++ b/tests/subsys/bootloader/bl_validation/prj.conf @@ -11,6 +11,7 @@ CONFIG_FW_INFO=y CONFIG_SECURE_BOOT_CRYPTO=y CONFIG_SECURE_BOOT_VALIDATION=y CONFIG_SECURE_BOOT_STORAGE=y +CONFIG_SB_CRYPTO_OBERON_SHA256=y CONFIG_BL_VALIDATE_FW_EXT_API_REQUIRED=y CONFIG_NRFX_NVMC=y CONFIG_MPU_ALLOW_FLASH_WRITE=y From 6eb637fab5fb0fe5b6b41d30c6bb9622a26710af Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 3 Dec 2024 09:53:41 +0000 Subject: [PATCH 09/10] bootloader: bl_crypto: Change wrong comments The comments for no SHA256 and no secp256r1 wrongly stated that these are disabled, this however is not true, the fields are accessed and must still be present, therefore explain that whilst they might not be checked, they are still required to be present Signed-off-by: Jamie McCrae --- subsys/bootloader/bl_crypto/Kconfig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/subsys/bootloader/bl_crypto/Kconfig b/subsys/bootloader/bl_crypto/Kconfig index 670279c7293c..a99f9a594b77 100644 --- a/subsys/bootloader/bl_crypto/Kconfig +++ b/subsys/bootloader/bl_crypto/Kconfig @@ -73,8 +73,10 @@ config SB_CRYPTO_CLIENT_ECDSA_SECP256R1 Using EXT_APIs from fw_info. config SB_CRYPTO_NO_ECDSA_SECP256R1 - bool "Disable secp256r1 support" + bool "secp256r1 without validation" select SB_ECDSA_SECP256R1 + help + Requires that a secp256r1 signature be present in the image but does no validation. config SB_CRYPTO_PSA_ED25519 bool "PSA ed25519 support" @@ -137,7 +139,9 @@ config SB_CRYPTO_CLIENT_SHA256 Using EXT_APIs from fw_info. config SB_CRYPTO_NO_SHA256 - bool "Disable SHA256 support" + bool "SHA256 without validation" + help + Requires that a SHA256 hash be present in the image but does no validation. config SB_CRYPTO_NONE bool "None" From 6b35112223d072363f5529237cead54a0f087744 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 3 Dec 2024 15:09:10 +0000 Subject: [PATCH 10/10] bootloader: Increase default nRF54L15 partition size Increases the size to account for the larger image which has CRACEN support Signed-off-by: Jamie McCrae --- subsys/bootloader/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bootloader/Kconfig b/subsys/bootloader/Kconfig index 09255c4eee31..6abd42a41faa 100644 --- a/subsys/bootloader/Kconfig +++ b/subsys/bootloader/Kconfig @@ -73,7 +73,7 @@ config PM_PARTITION_SIZE_B0_IMAGE default 0x7800 if !B0_MIN_PARTITION_SIZE && (SOC_NRF5340_CPUNET) default FPROTECT_BLOCK_SIZE if SOC_SERIES_NRF91X || SOC_NRF5340_CPUAPP default 0x3800 if SOC_NRF5340_CPUNET - default 0x7800 if SOC_NRF54L15_CPUAPP + default 0x9800 if SOC_NRF54L15_CPUAPP default 0x7000 if !B0_MIN_PARTITION_SIZE default 0x4000 help