diff --git a/boot/bootutil/include/bootutil/crypto/backend.h b/boot/bootutil/include/bootutil/crypto/backend.h new file mode 100644 index 000000000..118e75f4e --- /dev/null +++ b/boot/bootutil/include/bootutil/crypto/backend.h @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Nordic Semiconductor ASA + */ + +#ifndef __BOOTUTIL_CRYPTO_BACKEND_H__ +#define __BOOTUTIL_CRYPTO_BACKEND_H__ + +#if defined(MCUBOOT_CRYPTO_BACKEND_HAS_INIT) +/* Backend specific implementation for crypto subsystem + * initialization. + * MCUboot is supposed to call this function before + * any crypto operation, including sha functions, + * is executed. + * Returns true on success. The function can also just fault + * and topple entire boot process. + */ +bool bootutil_crypto_backend_init(void); + +/* Backend specific implementation for crypto subsystem + * deinitialization. + * No more cryptographic operations are expected to be + * invoked by MCUboot after this founction is called. + * Returns true on success. + */ +bool bootutil_crypto_backend_deinit(void); +#else +#define bootutil_crypto_backend_init() (true) +#define bootutil_crypto_backend_deinit() (true) +#endif + +#endif /* __BOOTUTIL_CRYPTO_BACKEND_H__ */ diff --git a/boot/bootutil/src/ed25519_psa.c b/boot/bootutil/src/ed25519_psa.c index 5b8a4ed7c..ae9c20b20 100644 --- a/boot/bootutil/src/ed25519_psa.c +++ b/boot/bootutil/src/ed25519_psa.c @@ -19,6 +19,16 @@ BOOT_LOG_MODULE_REGISTER(ed25519_psa); #define EDDSA_KEY_LENGTH 32 #define EDDSA_SIGNAGURE_LENGTH 64 +int bootutil_crypto_backend_init(void) +{ + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + BOOT_LOG_ERR("PSA crypto init failed %d\n", status); + return false; + } + return true; +} + 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]) @@ -31,13 +41,6 @@ int ED25519_verify(const uint8_t *message, size_t message_len, BOOT_LOG_DBG("ED25519_verify: PSA implementation"); - /* Initialize PSA Crypto */ - status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d\n", status); - return 0; - } - status = PSA_ERROR_BAD_STATE; psa_set_key_type(&key_attr, diff --git a/boot/bootutil/src/encrypted_psa.c b/boot/bootutil/src/encrypted_psa.c index d6b470b94..5e732e0f1 100644 --- a/boot/bootutil/src/encrypted_psa.c +++ b/boot/bootutil/src/encrypted_psa.c @@ -188,13 +188,6 @@ parse_priv_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key) void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) { - psa_status_t psa_ret = psa_crypto_init(); - - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("AES init PSA crypto init failed %d", psa_ret); - assert(0); - } - ctx->key = PSA_KEY_ID_NULL; } @@ -266,12 +259,6 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey) BOOT_LOG_DBG("boot_decrypt_key: PSA ED25519"); - psa_ret = psa_crypto_init(); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); - return -1; - } - /* * * Load the stored decryption private key */ @@ -431,16 +418,6 @@ int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, psa_cipher_operation_t psa_op; size_t elen = 0; /* Decrypted length */ - /* Fixme: calling psa_crypto_init multiple times is not a problem, - * yet the code here is only present because there is not general - * crypto init. */ - psa_ret = psa_crypto_init(); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); - ret = -1; - goto gone; - } - psa_op = psa_cipher_operation_init(); /* This could be done with psa_cipher_decrypt one-shot operation, but @@ -488,16 +465,6 @@ int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, psa_cipher_operation_t psa_op; size_t dlen = 0; /* Decrypted length */ - /* Fixme: the init should already happen before calling the function, but - * somehow it does not, for example when recovering in swap. - */ - psa_ret = psa_crypto_init(); - if (psa_ret != PSA_SUCCESS) { - BOOT_LOG_ERR("PSA crypto init failed %d", psa_ret); - ret = -1; - goto gone; - } - psa_op = psa_cipher_operation_init(); /* This could be done with psa_cipher_decrypt one-shot operation, but diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 5dec8a257..79c553045 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -51,6 +51,10 @@ #define MCUBOOT_USE_PSA_CRYPTO #endif +#if defined(MCUBOOT_SIGN_ED25519) && defined(MCUBOOT_USE_PSA_CRYPTO) +#define MCUBOOT_CRYPTO_BACKEND_HAS_INIT +#endif + #ifdef CONFIG_BOOT_IMG_HASH_ALG_SHA512 #define MCUBOOT_SHA512 #endif diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 1494002e7..ae83c527f 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -46,6 +46,7 @@ #include "bootutil/boot_hooks.h" #include "bootutil/fault_injection_hardening.h" #include "bootutil/mcuboot_status.h" +#include "bootutil/crypto/backend.h" #include "flash_map_backend/flash_map_backend.h" #if defined(CONFIG_MCUBOOT_UUID_VID) || defined(CONFIG_MCUBOOT_UUID_CID) @@ -496,6 +497,7 @@ static void boot_serial_enter() int main(void) { + bool crypto_ok; struct boot_rsp rsp; int rc; #if defined(CONFIG_BOOT_USB_DFU_GPIO) || defined(CONFIG_BOOT_USB_DFU_WAIT) @@ -512,6 +514,12 @@ int main(void) BOOT_LOG_INF("Starting Direct-XIP bootloader"); #endif + crypto_ok = bootutil_crypto_backend_init(); + if (!crypto_ok) { + BOOT_LOG_ERR("Failed to initialize crypto backend"); + FIH_PANIC; + } + #ifdef CONFIG_MCUBOOT_INDICATION_LED /* LED init */ io_led_init();