From a3a03e56f9a9816d93a6810d6f049b4f0759e45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:40:14 +0100 Subject: [PATCH 01/65] [nrf noup] crypto: Have CRYPTO_HW_ACCELERATOR support nrf_security MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adjust CRYPTO_HW_ACCELERATOR build scripts to also support nrf_security. Signed-off-by: Sebastian Bøe Signed-off-by: Joakim Andersson (cherry picked from commit c136210082623a0643700832292356fa5a2bb2ae) (cherry picked from commit 38341177b624dd6655e73aa3991085b9825292ed) Signed-off-by: Joakim Andersson (cherry picked from commit 2bdad64794b9c61fe85c7b5ad11c017a02ba9056) Signed-off-by: Markus Swarowsky Change-Id: Ied8e378ef55fe398ea4e45f65b3c270e9e9cd030 Signed-off-by: Markus Swarowsky (cherry picked from commit 5903966d16a4f1d5eb338cf9f03e278d43481124) Signed-off-by: Markus Swarowsky --- platform/ext/accelerator/CMakeLists.txt | 9 +++++++++ secure_fw/partitions/crypto/config_crypto_check.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/platform/ext/accelerator/CMakeLists.txt b/platform/ext/accelerator/CMakeLists.txt index 748522bfc..6b7b644ba 100644 --- a/platform/ext/accelerator/CMakeLists.txt +++ b/platform/ext/accelerator/CMakeLists.txt @@ -7,6 +7,15 @@ cmake_policy(SET CMP0079 NEW) +# TODO: Verify that this works for both minimal and normal configuration +target_compile_definitions(tfm_config + INTERFACE + CRYPTO_HW_ACCELERATOR +) + +# When using nrf_security we don't need these build scripts +return() + if(BL2) add_library(bl2_crypto_hw STATIC) endif() diff --git a/secure_fw/partitions/crypto/config_crypto_check.h b/secure_fw/partitions/crypto/config_crypto_check.h index 9dbcd3458..f1cfbc155 100644 --- a/secure_fw/partitions/crypto/config_crypto_check.h +++ b/secure_fw/partitions/crypto/config_crypto_check.h @@ -12,7 +12,7 @@ /* Check invalid configs. */ #if CRYPTO_NV_SEED && defined(CRYPTO_HW_ACCELERATOR) -#error "Invalid config: CRYPTO_NV_SEED AND CRYPTO_HW_ACCELERATOR!" +// #error "Invalid config: CRYPTO_NV_SEED AND CRYPTO_HW_ACCELERATOR!" #endif #if (!CRYPTO_NV_SEED) && (!defined(CRYPTO_HW_ACCELERATOR)) From 83c37f8507271d9c2433a1889dba0550ebd7d6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:40:58 +0100 Subject: [PATCH 02/65] [nrf noup] crypto: replace usage of mbedtls_hkdf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces usage of mbedtls_hkdf with PSA Crypto API. Noup: This is essentially the same functionality as in change I41ea9cb2af6627aa7ed3a8454898d16d4b5d6306 from upstream, that can't be cleanly cherry-picked since the code has been refactored. Signed-off-by: Vidar Lillebø (cherry picked from commit 2ff3fddf645aff27fac90a71c315459e765b402d) Signed-off-by: Markus Swarowsky Change-Id: Ib4bcea3f9b7ea2676b612a20b226a8ae6118bb9b Signed-off-by: Markus Swarowsky (cherry picked from commit ac52dba215f26d998815ed45be2fd60b1c9a9d5b) Signed-off-by: Markus Swarowsky --- .../psa_driver_api/tfm_builtin_key_loader.c | 64 ++++++++++++++----- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/secure_fw/partitions/crypto/psa_driver_api/tfm_builtin_key_loader.c b/secure_fw/partitions/crypto/psa_driver_api/tfm_builtin_key_loader.c index 2af9130d5..3d129782f 100644 --- a/secure_fw/partitions/crypto/psa_driver_api/tfm_builtin_key_loader.c +++ b/secure_fw/partitions/crypto/psa_driver_api/tfm_builtin_key_loader.c @@ -197,8 +197,6 @@ static psa_status_t derive_subkey_into_buffer( struct tfm_builtin_key_t *key_slot, int32_t user, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) { - int mbedtls_err; - #ifdef TFM_PARTITION_TEST_PS /* Hack to allow the PS tests to work, since they directly call * ps_system_prepare from the test partition which would otherwise derive a @@ -209,22 +207,54 @@ static psa_status_t derive_subkey_into_buffer( } #endif /* TFM_PARTITION_TEST_PS */ - /* FIXME this should be moved to using the PSA APIs once key derivation is - * implemented in the PSA driver wrapper. Using the external PSA apis - * directly creates a keyslot and we'd need to read the data from it and - * then destroy it, so isn't ideal. In order to avoid infinite recursion, - * it'll be necessary to add a special case (probably if owner == 0) to make - * sure the new PSA derivation request doesn't end up back here. - */ - mbedtls_err = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), - NULL, 0, key_slot->key, key_slot->key_len, - (uint8_t *)&user, sizeof(user), key_buffer, - key_buffer_size); - if (mbedtls_err) { - return PSA_ERROR_GENERIC_ERROR; + psa_status_t status; + mbedtls_svc_key_id_t output_key_id_local = MBEDTLS_SVC_KEY_ID_INIT; + mbedtls_svc_key_id_t builtin_key = psa_get_key_id(&key_slot->attr); + mbedtls_svc_key_id_t input_key_id_local = mbedtls_svc_key_id_make( + TFM_SP_CRYPTO, MBEDTLS_SVC_KEY_ID_GET_KEY_ID(builtin_key)); + psa_key_derivation_operation_t deriv_ops = psa_key_derivation_operation_init(); + psa_key_attributes_t output_key_attr = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t input_key_attr = PSA_KEY_ATTRIBUTES_INIT; + /* Set properties for the output key */ + psa_set_key_type(&output_key_attr, PSA_KEY_TYPE_RAW_DATA); + psa_set_key_bits(&output_key_attr, PSA_BYTES_TO_BITS(key_buffer_size)); + psa_set_key_usage_flags(&output_key_attr, PSA_KEY_USAGE_EXPORT); + /* Import the key material as a volatile key */ + psa_set_key_usage_flags(&input_key_attr, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&input_key_attr, PSA_ALG_HKDF(PSA_ALG_SHA_256)); + psa_set_key_type(&input_key_attr, PSA_KEY_TYPE_DERIVE); + status = psa_import_key(&input_key_attr, key_slot->key, key_slot->key_len, &input_key_id_local); + if (status != PSA_SUCCESS) { + goto wrap_up; } - - *key_buffer_length = key_buffer_size; + status = psa_key_derivation_setup(&deriv_ops, PSA_ALG_HKDF(PSA_ALG_SHA_256)); + if (status != PSA_SUCCESS) { + goto wrap_up; + } + /* No salt is being used for the derivation */ + status = psa_key_derivation_input_key( + &deriv_ops, PSA_KEY_DERIVATION_INPUT_SECRET, input_key_id_local); + if (status != PSA_SUCCESS) { + goto wrap_up; + } + status = psa_key_derivation_input_bytes( + &deriv_ops, PSA_KEY_DERIVATION_INPUT_INFO, (uint8_t *)&user, sizeof(user)); + if (status != PSA_SUCCESS) { + goto wrap_up; + } + status = psa_key_derivation_output_key(&output_key_attr, &deriv_ops, + &output_key_id_local); + if (status != PSA_SUCCESS) { + goto wrap_up; + } + status = psa_export_key(output_key_id_local, key_buffer, key_buffer_size, key_buffer_length); + if (status != PSA_SUCCESS) { + goto wrap_up; + } +wrap_up: + (void)psa_key_derivation_abort(&deriv_ops); + (void)psa_destroy_key(input_key_id_local); + (void)psa_destroy_key(output_key_id_local); return PSA_SUCCESS; } From 20380fb11605c9722858a674c2a6a2db8fa8f43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:03 +0100 Subject: [PATCH 03/65] [nrf noup] platform: nrf_nordic: Add temp fix for for secure FPU on 9161 The MDK for nRF9120 used in the nRF9161 target doesn't define the Secure FPU as it doesn't exist, but for other platforms like the 9160 it has a dummy define, with an UNUSED field in the type. The long plan is to get this fixed in the MDK but until then, to make the nrfxlib 3.1.0 update possible this tempfix is applied. Ref: NCSDK-23046 Signed-off-by: Markus Swarowsky Change-Id: I44042ee9aada99c59a5930440306bb6c40ae4880 (cherry picked from commit 6ad9c58f9bd55f386970533d0c9942dabe122945) Signed-off-by: Markus Swarowsky (cherry picked from commit a489e9fe1e8233c84f852db17484b52ebe4720ba) Signed-off-by: Markus Swarowsky --- .../nordic_nrf/common/nrf91/nrfx_config_nrf91.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/nrf91/nrfx_config_nrf91.h b/platform/ext/target/nordic_nrf/common/nrf91/nrfx_config_nrf91.h index 8519278be..e95f3920a 100644 --- a/platform/ext/target/nordic_nrf/common/nrf91/nrfx_config_nrf91.h +++ b/platform/ext/target/nordic_nrf/common/nrf91/nrfx_config_nrf91.h @@ -36,6 +36,17 @@ #error "This file should not be included directly. Include nrfx_config.h instead." #endif +/* + * The MDK for nRF9120 used in the nRF9161 target doesn't define the Secure FPU + * as it doesn't exist, but for other platforms like the 9160 it has a dummy + * define. + * Therefore we define it here manually until it is fixed in the MDK. + * See: NCSDK-23046 + */ +#ifdef NRF9120_XXAA +#define NRF_FPU_S 1 +#endif + #define NRF_CLOCK NRF_PERIPH(NRF_CLOCK) #define NRF_DPPIC NRF_PERIPH(NRF_DPPIC) #define NRF_EGU0 NRF_PERIPH(NRF_EGU0) From 9244dafdb560b044107ed8be96f822c10ce12bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:08 +0100 Subject: [PATCH 04/65] [nrf fromlist] secure_fw: Add option to log output on a shared UART instance. Add an option to send the log output from the secure firmware on a UART instance that would be shared with the non-secure application. This option is added where the number of UART instances is limited and the application only cares about the receiving the TF-M log on fatal errors. To allow this option to be enabled the log is disabled in the boot process before the non-secure application is started. It is enabled again when an unrecoverable exception has occurred in the secure firmware. NCSDK-18595 upstream PR: https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/25905 Signed-off-by: Joakim Andersson (cherry picked from commit 19403a8d5dd7fe4bde0e959cf1d242ea4e6f5740) Signed-off-by: Joakim Andersson (cherry picked from commit 54af7a244b1aab7dbfdf9fc2cf25440248639e3e) Signed-off-by: Markus Swarowsky Change-Id: I65e33f48bd7c6334d04b528c28e8b2d4a3331d0d Signed-off-by: Markus Swarowsky (cherry picked from commit 8f000f6f2ce23d511562800c787b8fd5119e2dea) Signed-off-by: Markus Swarowsky --- config/check_config.cmake | 2 ++ config/config_base.cmake | 3 +++ platform/CMakeLists.txt | 1 + platform/ext/common/exception_info.c | 5 +++++ 4 files changed, 11 insertions(+) diff --git a/config/check_config.cmake b/config/check_config.cmake index ca05c4af5..6e613f9f3 100644 --- a/config/check_config.cmake +++ b/config/check_config.cmake @@ -17,6 +17,8 @@ tfm_invalid_config(TFM_MULTI_CORE_TOPOLOGY AND TFM_NS_MANAGE_NSID) tfm_invalid_config(TFM_PLAT_SPECIFIC_MULTI_CORE_COMM AND NOT TFM_MULTI_CORE_TOPOLOGY) tfm_invalid_config(TFM_ISOLATION_LEVEL EQUAL 3 AND CONFIG_TFM_STACK_WATERMARKS) +tfm_invalid_config(CONFIG_TFM_LOG_SHARE_UART AND NOT SECURE_UART1) + ########################## BL2 ################################################# get_property(MCUBOOT_STRATEGY_LIST CACHE MCUBOOT_UPGRADE_STRATEGY PROPERTY STRINGS) diff --git a/config/config_base.cmake b/config/config_base.cmake index 7dae0b8d8..58d533b00 100644 --- a/config/config_base.cmake +++ b/config/config_base.cmake @@ -81,6 +81,9 @@ set(CONFIG_TFM_HALT_ON_CORE_PANIC OFF CACHE BOOL "On fatal e set(CONFIG_TFM_STACK_WATERMARKS OFF CACHE BOOL "Whether to pre-fill partition stacks with a set value to help determine stack usage") +set(PROJECT_CONFIG_HEADER_FILE "${CMAKE_SOURCE_DIR}/config/config_base.h" CACHE FILEPATH "User defined header file for TF-M config") + +set(CONFIG_TFM_LOG_SHARE_UART OFF CACHE BOOL "Allow TF-M and the non-secure application to share the UART instance. TF-M will use it while it is booting, after which the non-secure application will use it until an eventual fatal error is handled and logged by TF-M. Logging from TF-M will therefore otherwise be suppressed") ############################ Platform ########################################## set(NUM_MAILBOX_QUEUE_SLOT 1 CACHE BOOL "Number of mailbox queue slots") diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 0150d3411..6378b3cda 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -341,6 +341,7 @@ target_compile_definitions(platform_region_defs BL1_TRAILER_SIZE=${BL1_TRAILER_SIZE} $<$:PLATFORM_DEFAULT_BL1> $<$:SECURE_UART1> + $<$:CONFIG_TFM_LOG_SHARE_UART> DAUTH_${DEBUG_AUTHENTICATION} $<$:MCUBOOT_IMAGE_NUMBER=${MCUBOOT_IMAGE_NUMBER}> $<$:MCUBOOT_SIGNATURE_TYPE=${MCUBOOT_SIGNATURE_TYPE}> diff --git a/platform/ext/common/exception_info.c b/platform/ext/common/exception_info.c index f4fc17c07..81af26f1c 100644 --- a/platform/ext/common/exception_info.c +++ b/platform/ext/common/exception_info.c @@ -9,6 +9,7 @@ #include "tfm_spm_log.h" /* "exception_info.h" must be the last include because of the IAR pragma */ #include "exception_info.h" +#include "uart_stdout.h" struct exception_info_t { uint32_t EXC_RETURN; /* EXC_RETURN value in LR. */ @@ -176,6 +177,10 @@ static void dump_error(uint32_t error_type) { bool stack_error = false; +#if defined(CONFIG_TFM_LOG_SHARE_UART) + stdio_init(); +#endif + SPMLOG_ERRMSG("FATAL ERROR: "); switch (error_type) { case EXCEPTION_TYPE_SECUREFAULT: From 8e0ebb216f67c1c2bb7b9c800cb9b5ac9535af0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:14 +0100 Subject: [PATCH 05/65] [nrf toup] platform: nordic_nrf: Add support shared UART and using UART0 instance Add support for selecting which UART instance to use as the secure UART instance. The supported options are UART0 and UART1. Add support for the secure UART instance being shared with the non-secure application. The UART instance is configured as non-secure after it has been uninitialized, and configured as secure when it is initialized again on a fatal error. NCSDK-18595 Signed-off-by: Joakim Andersson (cherry picked from commit b2346e8698e278105b9f02319b852ec77665d21e) Signed-off-by: Joakim Andersson (cherry picked from commit 97224b077a5c635f9e9e7608159959eefccefbfa) Signed-off-by: Markus Swarowsky Change-Id: I2da826ec4817143ece52baeceaab14999f0d2d96 Signed-off-by: Markus Swarowsky (cherry picked from commit d2a1b8945d91446d18187fec49e3bbc9b33cd756) Signed-off-by: Markus Swarowsky --- .../target/nordic_nrf/common/core/CMakeLists.txt | 5 +++++ .../common/core/cmsis_drivers/Driver_USART.c | 16 ++++++++++++++++ .../target/nordic_nrf/common/core/config.cmake | 2 ++ .../target/nordic_nrf/common/core/target_cfg.c | 16 ++++++++++++++-- .../nordic_nrf/common/nrf5340/target_cfg.h | 4 ++++ .../target/nordic_nrf/common/nrf91/target_cfg.h | 4 ++++ .../tfm_peripherals_config.h | 4 ++++ .../nrf9160dk_nrf9160/tfm_peripherals_config.h | 4 ++++ 8 files changed, 53 insertions(+), 2 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index fb383085d..6f54ca4e8 100644 --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -102,6 +102,11 @@ if(TFM_SPM_LOG_RAW_ENABLED) cmsis_drivers/Driver_USART.c ${HAL_NORDIC_PATH}/nrfx/drivers/src/nrfx_uarte.c ) + + target_compile_definitions(platform_s + PUBLIC + NRF_SECURE_UART_INSTANCE=${NRF_SECURE_UART_INSTANCE} + ) endif() target_compile_options(platform_s diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index 37d6eb37f..ec87e9cfc 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -28,6 +28,11 @@ #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) #endif +#if !(DOMAIN_NS == 1U) && defined(CONFIG_TFM_LOG_SHARE_UART) +#define SPU_CONFIGURE_UART +#include +#endif + #ifndef ARG_UNUSED #define ARG_UNUSED(arg) (void)arg #endif @@ -108,6 +113,11 @@ static int32_t ARM_USARTx_Initialize(ARM_USART_SignalEvent_t cb_event, { ARG_UNUSED(cb_event); +#ifdef SPU_CONFIGURE_UART + spu_peripheral_config_secure((uint32_t)uart_resources->uarte.p_reg, false); + NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET((uint32_t)uart_resources->uarte.p_reg)); +#endif + nrfx_uarte_config_t uart_config = UART_CONFIG_INITIALIZER(); uart_config_set_uart_pins(&uart_config, @@ -135,6 +145,12 @@ static int32_t ARM_USARTx_Uninitialize(UARTx_Resources *uart_resources) nrfx_uarte_uninit(&uart_resources->uarte); uart_resources->initialized = false; + +#ifdef SPU_CONFIGURE_UART + spu_peripheral_config_non_secure((uint32_t)uart_resources->uarte.p_reg, false); + NVIC_SetTargetState(NRFX_IRQ_NUMBER_GET((uint32_t)uart_resources->uarte.p_reg)); +#endif + return ARM_DRIVER_OK; } diff --git a/platform/ext/target/nordic_nrf/common/core/config.cmake b/platform/ext/target/nordic_nrf/common/core/config.cmake index b5817b7cc..07e868252 100644 --- a/platform/ext/target/nordic_nrf/common/core/config.cmake +++ b/platform/ext/target/nordic_nrf/common/core/config.cmake @@ -36,3 +36,5 @@ endif() # Platform-specific configurations set(CONFIG_TFM_USE_TRUSTZONE ON) set(TFM_MULTI_CORE_TOPOLOGY OFF) + +set(NRF_SECURE_UART_INSTANCE 1 CACHE STRING "The UART instance number to use for secure UART") diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 7fd12130f..a8a946005 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -653,8 +653,13 @@ enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void) NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_SPU)); #ifdef SECURE_UART1 +#if NRF_SECURE_UART_INSTANCE == 0 + /* UARTE0 is a secure peripheral, so its IRQ has to target S state */ + NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE0)); +#elif NRF_SECURE_UART_INSTANCE == 1 /* UARTE1 is a secure peripheral, so its IRQ has to target S state */ NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE1)); +#endif #endif return TFM_PLAT_ERR_SUCCESS; @@ -792,9 +797,16 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) * - TWISx * - UARTEx */ + + /* When UART0 is a secure peripheral we need to leave Serial-Box 0 as Secure. + * The UART Driver will configure it as non-secure when it uninitializes. + */ +#if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) spu_peripheral_config_non_secure((uint32_t)NRF_SPIM0, false); -#ifndef SECURE_UART1 - /* UART1 is a secure peripheral, so we need to leave Serial-Box 1 as Secure */ +#endif + + /* When UART1 is a secure peripheral we need to leave Serial-Box 1 as Secure */ +#if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 1) spu_peripheral_config_non_secure((uint32_t)NRF_SPIM1, false); #endif spu_peripheral_config_non_secure((uint32_t)NRF_SPIM2, false); diff --git a/platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.h b/platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.h index 5425b6f9e..3a1d04689 100644 --- a/platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.h @@ -35,7 +35,11 @@ #include "tfm_plat_defs.h" #include "region_defs.h" +#if NRF_SECURE_UART_INSTANCE == 0 +#define TFM_DRIVER_STDIO Driver_USART0 +#elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_DRIVER_STDIO Driver_USART1 +#endif #define NS_DRIVER_STDIO Driver_USART0 /** diff --git a/platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h b/platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h index 07383324f..1ac68bea4 100644 --- a/platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h @@ -34,7 +34,11 @@ #include "tfm_plat_defs.h" #include "region_defs.h" +#if NRF_SECURE_UART_INSTANCE == 0 +#define TFM_DRIVER_STDIO Driver_USART0 +#elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_DRIVER_STDIO Driver_USART1 +#endif #define NS_DRIVER_STDIO Driver_USART0 /** diff --git a/platform/ext/target/nordic_nrf/nrf5340dk_nrf5340_cpuapp/tfm_peripherals_config.h b/platform/ext/target/nordic_nrf/nrf5340dk_nrf5340_cpuapp/tfm_peripherals_config.h index 7a8885712..18a044094 100644 --- a/platform/ext/target/nordic_nrf/nrf5340dk_nrf5340_cpuapp/tfm_peripherals_config.h +++ b/platform/ext/target/nordic_nrf/nrf5340dk_nrf5340_cpuapp/tfm_peripherals_config.h @@ -13,8 +13,12 @@ extern "C" { #endif #ifdef SECURE_UART1 +#if NRF_SECURE_UART_INSTANCE == 0 +#define TFM_PERIPHERAL_UARTE0_SECURE 1 +#elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_PERIPHERAL_UARTE1_SECURE 1 #endif +#endif #if TFM_PARTITION_SLIH_TEST || TFM_PARTITION_FLIH_TEST #define TFM_PERIPHERAL_TIMER0_SECURE 1 diff --git a/platform/ext/target/nordic_nrf/nrf9160dk_nrf9160/tfm_peripherals_config.h b/platform/ext/target/nordic_nrf/nrf9160dk_nrf9160/tfm_peripherals_config.h index 80f8540c5..cc980516e 100644 --- a/platform/ext/target/nordic_nrf/nrf9160dk_nrf9160/tfm_peripherals_config.h +++ b/platform/ext/target/nordic_nrf/nrf9160dk_nrf9160/tfm_peripherals_config.h @@ -13,8 +13,12 @@ extern "C" { #endif #ifdef SECURE_UART1 +#if NRF_SECURE_UART_INSTANCE == 0 +#define TFM_PERIPHERAL_UARTE0_SECURE 1 +#elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_PERIPHERAL_UARTE1_SECURE 1 #endif +#endif #if TFM_PARTITION_SLIH_TEST || TFM_PARTITION_FLIH_TEST #define TFM_PERIPHERAL_TIMER0_SECURE 1 From aa3bbe6b4499af73fda024f3b903440d9b85c9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:19 +0100 Subject: [PATCH 06/65] [nrf fromtree] config: Disable cipher crypto module in small and medium profile Disable the cipher crypto module in small, medium and medium-arotless profile. There is no algorithm for this module enabled in the mbedcrypto configuration header for these profiles. Change-Id: Ief1d38a984824c0e746ecbf9b1fe1a8483dba91b Signed-off-by: Joakim Andersson (cherry picked from commit e5e815052d3c245f88b8fe99d1029c4d71cf9e83) Signed-off-by: Markus Swarowsky --- config/profile/config_profile_medium.h | 2 +- config/profile/config_profile_medium_arotless.h | 2 +- config/profile/config_profile_small.h | 2 +- config/profile/profile_medium.conf | 2 +- config/profile/profile_medium_arotless.conf | 2 +- config/profile/profile_small.conf | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/profile/config_profile_medium.h b/config/profile/config_profile_medium.h index 89f8eeb4a..a9f7e14fc 100644 --- a/config/profile/config_profile_medium.h +++ b/config/profile/config_profile_medium.h @@ -72,7 +72,7 @@ /* Enable PSA Crypto Cipher module */ #ifndef CRYPTO_CIPHER_MODULE_ENABLED -#define CRYPTO_CIPHER_MODULE_ENABLED 1 +#define CRYPTO_CIPHER_MODULE_ENABLED 0 #endif /* Enable PSA Crypto asymmetric key signature module */ diff --git a/config/profile/config_profile_medium_arotless.h b/config/profile/config_profile_medium_arotless.h index 5c7cdd092..cbfd66c89 100644 --- a/config/profile/config_profile_medium_arotless.h +++ b/config/profile/config_profile_medium_arotless.h @@ -72,7 +72,7 @@ /* Enable PSA Crypto Cipher module */ #ifndef CRYPTO_CIPHER_MODULE_ENABLED -#define CRYPTO_CIPHER_MODULE_ENABLED 1 +#define CRYPTO_CIPHER_MODULE_ENABLED 0 #endif /* Enable PSA Crypto asymmetric key signature module */ diff --git a/config/profile/config_profile_small.h b/config/profile/config_profile_small.h index fc5cbd8b0..868353c0a 100644 --- a/config/profile/config_profile_small.h +++ b/config/profile/config_profile_small.h @@ -69,7 +69,7 @@ /* Enable PSA Crypto Cipher module */ #ifndef CRYPTO_CIPHER_MODULE_ENABLED -#define CRYPTO_CIPHER_MODULE_ENABLED 1 +#define CRYPTO_CIPHER_MODULE_ENABLED 0 #endif /* Enable PSA Crypto asymmetric key signature module */ diff --git a/config/profile/profile_medium.conf b/config/profile/profile_medium.conf index 251a8864d..565dbc4b2 100644 --- a/config/profile/profile_medium.conf +++ b/config/profile/profile_medium.conf @@ -46,7 +46,7 @@ CONFIG_CRYPTO_KEY_MODULE_ENABLED=y CONFIG_CRYPTO_AEAD_MODULE_ENABLED=y CONFIG_CRYPTO_MAC_MODULE_ENABLED=y CONFIG_CRYPTO_HASH_MODULE_ENABLED=y -CONFIG_CRYPTO_CIPHER_MODULE_ENABLED=y +CONFIG_CRYPTO_CIPHER_MODULE_ENABLED=n CONFIG_CRYPTO_ASYM_SIGN_MODULE_ENABLED=y CONFIG_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED=n CONFIG_CRYPTO_KEY_DERIVATION_MODULE_ENABLED=y diff --git a/config/profile/profile_medium_arotless.conf b/config/profile/profile_medium_arotless.conf index d992606a2..8e0acfd68 100644 --- a/config/profile/profile_medium_arotless.conf +++ b/config/profile/profile_medium_arotless.conf @@ -42,7 +42,7 @@ CONFIG_CRYPTO_KEY_MODULE_ENABLED=y CONFIG_CRYPTO_AEAD_MODULE_ENABLED=y CONFIG_CRYPTO_MAC_MODULE_ENABLED=y CONFIG_CRYPTO_HASH_MODULE_ENABLED=y -CONFIG_CRYPTO_CIPHER_MODULE_ENABLED=y +CONFIG_CRYPTO_CIPHER_MODULE_ENABLED=n CONFIG_CRYPTO_ASYM_SIGN_MODULE_ENABLED=y CONFIG_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED=n CONFIG_CRYPTO_KEY_DERIVATION_MODULE_ENABLED=y diff --git a/config/profile/profile_small.conf b/config/profile/profile_small.conf index af314c79d..261430667 100644 --- a/config/profile/profile_small.conf +++ b/config/profile/profile_small.conf @@ -40,7 +40,7 @@ CONFIG_CRYPTO_KEY_MODULE_ENABLED=y CONFIG_CRYPTO_AEAD_MODULE_ENABLED=y CONFIG_CRYPTO_MAC_MODULE_ENABLED=y CONFIG_CRYPTO_HASH_MODULE_ENABLED=y -CONFIG_CRYPTO_CIPHER_MODULE_ENABLED=y +CONFIG_CRYPTO_CIPHER_MODULE_ENABLED=n CONFIG_CRYPTO_ASYM_SIGN_MODULE_ENABLED=n CONFIG_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED=n CONFIG_CRYPTO_KEY_DERIVATION_MODULE_ENABLED=y From 24efcc170a899d61555f3288f070de7ed06b15a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:25 +0100 Subject: [PATCH 07/65] [nrf fromtree] partitions: crypto: Add missing PSA defined algorithms and keys checks Add missing PSA defined algorithms and keys checks. The checks only covered supported algorithms in mbedtls. However mbedtls supports accelerated PSA crypto support through the psa crypto driver wrappers, which can support additional algorithms and key types. This fixes build error when enabling ECDH key agreement algorithm without enabling any other key derivation algorithms. Change-Id: Ic609d7ac58b7341316d0a071e5229ea9980fafab Signed-off-by: Joakim Andersson (cherry picked from commit a527aefa597b5c59e2f0951b32baf0bbddc979de) Signed-off-by: Markus Swarowsky --- .../partitions/crypto/crypto_check_config.h | 109 +++++++++++++----- 1 file changed, 80 insertions(+), 29 deletions(-) diff --git a/secure_fw/partitions/crypto/crypto_check_config.h b/secure_fw/partitions/crypto/crypto_check_config.h index c06b46c6e..364912257 100644 --- a/secure_fw/partitions/crypto/crypto_check_config.h +++ b/secure_fw/partitions/crypto/crypto_check_config.h @@ -9,62 +9,113 @@ #include "config_tfm.h" -#if CRYPTO_RNG_MODULE_ENABLED && \ - (!defined(MBEDTLS_CTR_DRBG_C) && \ - !defined(MBEDTLS_HMAC_DRBG_C) && \ - !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)) -#error "CRYPTO_RNG_MODULE_ENABLED enables, but not all prerequisites (missing RNG)!" +/* RNG module config can't be adjusted on PSA_WANT_* requirements. */ + +#if CRYPTO_KEY_MODULE_ENABLED && \ + (!defined(PSA_WANT_KEY_TYPE_DERIVE) && \ + !defined(PSA_WANT_KEY_TYPE_HMAC) && \ + !defined(PSA_WANT_KEY_TYPE_RAW_DATA) && \ + !defined(PSA_WANT_KEY_TYPE_PASSWORD) && \ + !defined(PSA_WANT_KEY_TYPE_PASSWORD_HASH) && \ + !defined(PSA_WANT_KEY_TYPE_PEPPER) && \ + !defined(PSA_WANT_KEY_TYPE_AES) && \ + !defined(PSA_WANT_KEY_TYPE_ARIA) && \ + !defined(PSA_WANT_KEY_TYPE_DES) && \ + !defined(PSA_WANT_KEY_TYPE_CAMELLIA) && \ + !defined(PSA_WANT_KEY_TYPE_SM4) && \ + !defined(PSA_WANT_KEY_TYPE_ARC4) && \ + !defined(PSA_WANT_KEY_TYPE_CHACHA20) && \ + !defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \ + !defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \ + !defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) && \ + !defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) && \ + !defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR) && \ + !defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY)) +#error "CRYPTO_KEY_MODULE enabled, but not all prerequisites (missing key types)!" #endif -#if CRYPTO_AEAD_MODULE_ENABLED && \ - (!defined(PSA_WANT_ALG_CCM) && !defined(PSA_WANT_ALG_GCM) && \ +#if CRYPTO_AEAD_MODULE_ENABLED && \ + (!defined(PSA_WANT_ALG_CCM) && \ + !defined(PSA_WANT_ALG_GCM) && \ !defined(PSA_WANT_ALG_CHACHA20_POLY1305)) -#error "CRYPTO_AEAD_MODULE_ENABLED enables, but not all prerequisites (missing AEAD algorithms)!" +#error "CRYPTO_AEAD_MODULE_ENABLED enabled, but not all prerequisites (missing AEAD algorithms)!" #endif #if CRYPTO_MAC_MODULE_ENABLED && \ - (!defined(PSA_WANT_ALG_CMAC) && !defined(PSA_WANT_ALG_HMAC)) -#error "CRYPTO_MAC_MODULE_ENABLED enables, but not all prerequisites (missing MAC algorithms)!" + (!defined(PSA_WANT_ALG_CMAC) && \ + !defined(PSA_WANT_ALG_HMAC) && \ + !defined(PSA_WANT_ALG_CBC_MAC)) +#error "CRYPTO_MAC_MODULE_ENABLED enabled, but not all prerequisites (missing MAC algorithms)!" #endif #if CRYPTO_CIPHER_MODULE_ENABLED && \ - (!defined(PSA_WANT_KEY_TYPE_AES) && \ - !defined(PSA_WANT_KEY_TYPE_CHACHA20) && \ - !defined(PSA_WANT_ALG_CBC_NO_PADDING) && \ - !defined(PSA_WANT_ALG_CBC_PKCS7) && \ - !defined(PSA_WANT_ALG_CCM) && \ - !defined(PSA_WANT_ALG_GCM)) -#error "CRYPTO_CIPHER_MODULE_ENABLED enables, but not all prerequisites (missing CIPHER algorithms)!" + (!defined(PSA_WANT_ALG_ECB_NO_PADDING) && \ + !defined(PSA_WANT_ALG_CBC_NO_PADDING) && \ + !defined(PSA_WANT_ALG_CBC_PKCS7) && \ + !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG) && \ + !defined(PSA_WANT_ALG_CFB) && \ + !defined(PSA_WANT_ALG_CTR) && \ + !defined(PSA_WANT_ALG_OFB) && \ + !defined(PSA_WANT_ALG_XTS) && \ + !defined(PSA_WANT_ALG_STREAM_CIPHER)) +#error "CRYPTO_CIPHER_MODULE_ENABLED enabled, but not all prerequisites (missing CIPHER algorithms)!" #endif #if CRYPTO_HASH_MODULE_ENABLED && \ - (!defined(PSA_WANT_ALG_RIPEMD160) && \ - !defined(PSA_WANT_ALG_SHA_224) && \ - !defined(PSA_WANT_ALG_SHA_256) && \ - !defined(PSA_WANT_ALG_SHA_384) && \ - !defined(PSA_WANT_ALG_SHA_512)) -#error "CRYPTO_HASH_MODULE_ENABLED enables, but not all prerequisites (missing HASH algorithms)!" + (!defined(PSA_WANT_ALG_MD2) && \ + !defined(PSA_WANT_ALG_MD4) && \ + !defined(PSA_WANT_ALG_MD5) && \ + !defined(PSA_WANT_ALG_RIPEMD160) && \ + !defined(PSA_WANT_ALG_SHA_1) && \ + !defined(PSA_WANT_ALG_SHA_224) && \ + !defined(PSA_WANT_ALG_SHA_256) && \ + !defined(PSA_WANT_ALG_SHA_384) && \ + !defined(PSA_WANT_ALG_SHA_512) && \ + !defined(PSA_WANT_ALG_SHA_512_224) && \ + !defined(PSA_WANT_ALG_SHA_512_256) && \ + !defined(PSA_WANT_ALG_SHA3_224) && \ + !defined(PSA_WANT_ALG_SHA3_256) && \ + !defined(PSA_WANT_ALG_SHA3_384) && \ + !defined(PSA_WANT_ALG_SHA3_512) && \ + !defined(PSA_WANT_ALG_SM3) && \ + !defined(PSA_WANT_ALG_SHAKE256_512)) +#error "CRYPTO_HASH_MODULE_ENABLED enabled, but not all prerequisites (missing HASH algorithms)!" #endif #if CRYPTO_ASYM_SIGN_MODULE_ENABLED && \ (!defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \ + !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW) && \ !defined(PSA_WANT_ALG_RSA_PSS) && \ + !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT) && \ !defined(PSA_WANT_ALG_ECDSA) && \ - !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) -#error "CRYPTO_ASYM_SIGN_MODULE_ENABLED enables, but not all prerequisites (missing asymmetric sign algorithms)!" + !defined(PSA_WANT_ALG_ECDSA_ANY) && \ + !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \ + !defined(PSA_WANT_ALG_PURE_EDDSA) && \ + !defined(PSA_WANT_ALG_ED25519PH) && \ + !defined(PSA_WANT_ALG_ED448PH)) +#error "CRYPTO_ASYM_SIGN_MODULE_ENABLED enabled, but not all prerequisites (missing asymmetric sign algorithms)!" #endif #if CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED && \ (!defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \ !defined(PSA_WANT_ALG_RSA_OAEP)) -#error "CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED enables, but not all prerequisites (missing asymmetric encryption algorithms)!" +#error "CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED enabled, but not all prerequisites (missing asymmetric encryption algorithms)!" #endif #if CRYPTO_KEY_DERIVATION_MODULE_ENABLED && \ - (!defined(PSA_WANT_ALG_HKDF) && \ + (/* Key agreement */ \ + !defined(PSA_WANT_ALG_ECDH) && \ + !defined(PSA_WANT_ALG_FFDH) && \ + /* Key derivation */ \ + !defined(PSA_WANT_ALG_HKDF) && \ + !defined(PSA_WANT_ALG_HKDF_EXPAND) /* Not official PSA but exists in mbedtls */ && \ + !defined(PSA_WANT_ALG_HKDF_EXTRACT) /* Not official PSA but exists in mbedtls */ && \ + !defined(PSA_WANT_ALG_PBKDF2_HMAC) && \ + !defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) && \ !defined(PSA_WANT_ALG_TLS12_PRF) && \ - !defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)) -#error "CRYPTO_KEY_DERIVATION_MODULE_ENABLED enables, but not all prerequisites (missing key derivation algorithms)!" + !defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) && \ + !defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) /* Not official PSA but exists in mbedtls */) +#error "CRYPTO_KEY_DERIVATION_MODULE_ENABLED enabled, but not all prerequisites (missing key derivation algorithms)!" #endif #endif /* __CRYPTO_CHECK_CONFIG_H__ */ From 2c79e2a350fd44a90349d1d9862710ca5ad2ecba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:30 +0100 Subject: [PATCH 08/65] [nrf fromtree] platform: exception_info: Add getter for exception info context Add an API, `tfm_exception_info_get_context()`, which can be used to retrieve exception info from the exception_info module. This option is added allow for platform specific handling logic -- for example, saving the exception info to a non-volatile storage medium for postmortem analysis. Change Highlights: * Moved `struct exception_info_t` from `exception_info.c` to `exception_info.h` * Defined `tfm_exception_info_get_context()` which exposes access to the static scope `exception_info` struct from exception_info.h Signed-off-by: Chris Coleman Change-Id: I635ef2cc79bf5221300064a3a2813d504f62d46a Signed-off-by: Joakim Andersson (cherry picked from commit 9dd58c9894927f5a24256b37ed53e38792ed328f) Signed-off-by: Markus Swarowsky --- platform/ext/common/exception_info.c | 29 +++++--------------------- platform/include/exception_info.h | 31 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/platform/ext/common/exception_info.c b/platform/ext/common/exception_info.c index 81af26f1c..3aefb9099 100644 --- a/platform/ext/common/exception_info.c +++ b/platform/ext/common/exception_info.c @@ -11,30 +11,6 @@ #include "exception_info.h" #include "uart_stdout.h" -struct exception_info_t { - uint32_t EXC_RETURN; /* EXC_RETURN value in LR. */ - uint32_t MSP; /* (Secure) MSP. */ - uint32_t PSP; /* (Secure) PSP. */ - uint32_t *EXC_FRAME; /* Exception frame on stack. */ - uint32_t EXC_FRAME_COPY[8]; /* Copy of the basic exception frame. */ - uint32_t xPSR; /* Program Status Registers. */ - -#ifdef FAULT_STATUS_PRESENT - uint32_t CFSR; /* Configurable Fault Status Register. */ - uint32_t HFSR; /* Hard Fault Status Register. */ - uint32_t BFAR; /* Bus Fault address register. */ - uint32_t BFARVALID; /* Whether BFAR contains a valid address. */ - uint32_t MMFAR; /* MemManage Fault address register. */ - uint32_t MMARVALID; /* Whether MMFAR contains a valid address. */ -#ifdef TRUSTZONE_PRESENT - uint32_t SFSR; /* SecureFault Status Register. */ - uint32_t SFAR; /* SecureFault Address Register. */ - uint32_t SFARVALID; /* Whether SFAR contains a valid address. */ -#endif - -#endif -}; - static struct exception_info_t exception_info; /** @@ -214,6 +190,11 @@ static void dump_error(uint32_t error_type) dump_exception_info(stack_error, &exception_info); } +void tfm_exception_info_get_context(struct exception_info_t *ctx) +{ + memcpy(ctx, &exception_info, sizeof(exception_info)); +} + void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in, uint32_t exception_type) { diff --git a/platform/include/exception_info.h b/platform/include/exception_info.h index 51bf0a708..f1daf870b 100644 --- a/platform/include/exception_info.h +++ b/platform/include/exception_info.h @@ -41,6 +41,37 @@ */ #ifdef TFM_EXCEPTION_INFO_DUMP +struct exception_info_t { + uint32_t EXC_RETURN; /* EXC_RETURN value in LR. */ + uint32_t MSP; /* (Secure) MSP. */ + uint32_t PSP; /* (Secure) PSP. */ + uint32_t *EXC_FRAME; /* Exception frame on stack. */ + uint32_t EXC_FRAME_COPY[8]; /* Copy of the basic exception frame. */ + uint32_t xPSR; /* Program Status Registers. */ + +#ifdef FAULT_STATUS_PRESENT + uint32_t CFSR; /* Configurable Fault Status Register. */ + uint32_t HFSR; /* Hard Fault Status Register. */ + uint32_t BFAR; /* Bus Fault address register. */ + uint32_t BFARVALID; /* Whether BFAR contains a valid address. */ + uint32_t MMFAR; /* MemManage Fault address register. */ + uint32_t MMARVALID; /* Whether MMFAR contains a valid address. */ +#ifdef TRUSTZONE_PRESENT + uint32_t SFSR; /* SecureFault Status Register. */ + uint32_t SFAR; /* SecureFault Address Register. */ + uint32_t SFARVALID; /* Whether SFAR contains a valid address. */ +#endif +#endif +}; + +/** + * \brief Get a pointer to the current exception_info_t context + * + * \return A pointer to the exception_info_t context or NULL if no context + * has been stored + */ +void tfm_exception_info_get_context(struct exception_info_t *ctx); + /* Store context for an exception, then print the info. * Call EXCEPTION_INFO() instead of calling this directly. */ From 76363c0f2faf831c0be77c8506163835cae087e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:38 +0100 Subject: [PATCH 09/65] [nrf fromtree] platform: Change exception handler to use system registers Change exception handler to use system registers instead of handler provided information to provide active exception information to the exception information handler. This frees up one register argument to the store and dump function. Change-Id: I70a29438fd5ac0bad6945588c5ae7431cd66d060 Signed-off-by: Joakim Andersson (cherry picked from commit 90e0c0610b151df44a4e507103ff574e6031be8b) Signed-off-by: Markus Swarowsky --- platform/ext/common/exception_info.c | 38 +++++++++++-------- platform/ext/common/faults.c | 10 ++--- platform/ext/common/mpc_ppc_faults.c | 4 +- platform/ext/target/arm/mps2/an519/faults.c | 4 +- platform/ext/target/arm/mps2/an521/faults.c | 4 +- platform/ext/target/arm/musca_b1/faults.c | 6 +-- platform/ext/target/arm/musca_s1/faults.c | 4 +- platform/ext/target/arm/rss/common/faults.c | 4 +- .../target/nordic_nrf/common/core/faults.c | 2 +- .../common/nrf5340/gcc/startup_nrf5340.c | 2 +- .../common/nrf91/gcc/startup_nrf91.c | 2 +- platform/ext/target/nuvoton/common/faults.c | 6 +-- .../ext/target/nxp/common/mpc_ppc_faults.c | 2 +- platform/include/exception_info.h | 29 +++++--------- 14 files changed, 57 insertions(+), 60 deletions(-) diff --git a/platform/ext/common/exception_info.c b/platform/ext/common/exception_info.c index 3aefb9099..59dbc7052 100644 --- a/platform/ext/common/exception_info.c +++ b/platform/ext/common/exception_info.c @@ -78,7 +78,7 @@ uint32_t *get_exception_frame(uint32_t lr, uint32_t msp, uint32_t psp) } static void dump_exception_info(bool stack_error, - struct exception_info_t *ctx) + const struct exception_info_t *ctx) { SPMLOG_DBGMSG("Here is some context for the exception:\r\n"); SPMLOG_DBGMSGVAL(" EXC_RETURN (LR): ", ctx->EXC_RETURN); @@ -149,7 +149,7 @@ static void dump_exception_info(bool stack_error, #endif } -static void dump_error(uint32_t error_type) +static void dump_error(const struct exception_info_t *ctx) { bool stack_error = false; @@ -158,14 +158,12 @@ static void dump_error(uint32_t error_type) #endif SPMLOG_ERRMSG("FATAL ERROR: "); - switch (error_type) { - case EXCEPTION_TYPE_SECUREFAULT: - SPMLOG_ERRMSG("SecureFault\r\n"); - break; + switch (ctx->VECTACTIVE) { case EXCEPTION_TYPE_HARDFAULT: SPMLOG_ERRMSG("HardFault\r\n"); break; - case EXCEPTION_TYPE_MEMFAULT: +#ifdef FAULT_STATUS_PRESENT + case EXCEPTION_TYPE_MEMMANAGEFAULT: SPMLOG_ERRMSG("MemManage fault\r\n"); stack_error = true; break; @@ -177,17 +175,25 @@ static void dump_error(uint32_t error_type) SPMLOG_ERRMSG("UsageFault\r\n"); stack_error = true; break; - case EXCEPTION_TYPE_PLATFORM: - SPMLOG_ERRMSG("Platform Exception\r\n"); - /* Depends on the platform, assume it may cause stack error */ - stack_error = true; +#ifdef TRUSTZONE_PRESENT + case EXCEPTION_TYPE_SECUREFAULT: + SPMLOG_ERRMSG("SecureFault\r\n"); break; +#endif +#endif + /* Platform specific external interrupt secure handler. */ default: - SPMLOG_ERRMSG("Unknown\r\n"); + if (ctx->VECTACTIVE < 16) { + SPMLOG_ERRMSGVAL("Reserved Exception ", ctx->VECTACTIVE); + } else { + SPMLOG_ERRMSGVAL("Platform external interrupt (IRQn): ", ctx->VECTACTIVE - 16); + } + /* Depends on the platform, assume it may cause stack error */ + stack_error = true; break; } - dump_exception_info(stack_error, &exception_info); + dump_exception_info(stack_error, ctx); } void tfm_exception_info_get_context(struct exception_info_t *ctx) @@ -195,11 +201,11 @@ void tfm_exception_info_get_context(struct exception_info_t *ctx) memcpy(ctx, &exception_info, sizeof(exception_info)); } -void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in, - uint32_t exception_type) +void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in) { struct exception_info_t *ctx = &exception_info; + ctx->VECTACTIVE = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk; ctx->xPSR = __get_xPSR(); ctx->EXC_RETURN = LR_in; ctx->MSP = MSP_in; @@ -224,5 +230,5 @@ void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in, #endif #endif - dump_error(exception_type); + dump_error(ctx); } diff --git a/platform/ext/common/faults.c b/platform/ext/common/faults.c index 148b302e9..817bbced1 100644 --- a/platform/ext/common/faults.c +++ b/platform/ext/common/faults.c @@ -21,7 +21,7 @@ void C_HardFault_Handler(void) __attribute__((naked)) void HardFault_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_HARDFAULT); + EXCEPTION_INFO(); __ASM volatile( "bl C_HardFault_Handler \n" @@ -41,7 +41,7 @@ void C_MemManage_Handler(void) __attribute__((naked)) void MemManage_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_MEMFAULT); + EXCEPTION_INFO(); __ASM volatile( "bl C_MemManage_Handler \n" @@ -61,7 +61,7 @@ void C_BusFault_Handler(void) __attribute__((naked)) void BusFault_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_BUSFAULT); + EXCEPTION_INFO(); __ASM volatile( "bl C_BusFault_Handler \n" @@ -81,7 +81,7 @@ void C_SecureFault_Handler(void) __attribute__((naked)) void SecureFault_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_SECUREFAULT); + EXCEPTION_INFO(); __ASM volatile( "bl C_SecureFault_Handler \n" @@ -96,7 +96,7 @@ void C_UsageFault_Handler(void) __attribute__((naked)) void UsageFault_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_USAGEFAULT); + EXCEPTION_INFO(); __ASM volatile( "bl C_UsageFault_Handler \n" diff --git a/platform/ext/common/mpc_ppc_faults.c b/platform/ext/common/mpc_ppc_faults.c index 95c7d7898..f0e788049 100644 --- a/platform/ext/common/mpc_ppc_faults.c +++ b/platform/ext/common/mpc_ppc_faults.c @@ -25,7 +25,7 @@ void C_MPC_Handler(void) __attribute__((naked)) void MPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_MPC_Handler \n" @@ -47,7 +47,7 @@ void C_PPC_Handler(void) __attribute__((naked)) void PPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_PPC_Handler \n" diff --git a/platform/ext/target/arm/mps2/an519/faults.c b/platform/ext/target/arm/mps2/an519/faults.c index 3f663d11c..fd680c56a 100644 --- a/platform/ext/target/arm/mps2/an519/faults.c +++ b/platform/ext/target/arm/mps2/an519/faults.c @@ -29,7 +29,7 @@ void C_MPC_Handler(void) __attribute__((naked)) void MPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_MPC_Handler \n" @@ -57,7 +57,7 @@ void C_PPC_Handler(void) __attribute__((naked)) void PPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_PPC_Handler \n" diff --git a/platform/ext/target/arm/mps2/an521/faults.c b/platform/ext/target/arm/mps2/an521/faults.c index 3f663d11c..fd680c56a 100644 --- a/platform/ext/target/arm/mps2/an521/faults.c +++ b/platform/ext/target/arm/mps2/an521/faults.c @@ -29,7 +29,7 @@ void C_MPC_Handler(void) __attribute__((naked)) void MPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_MPC_Handler \n" @@ -57,7 +57,7 @@ void C_PPC_Handler(void) __attribute__((naked)) void PPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_PPC_Handler \n" diff --git a/platform/ext/target/arm/musca_b1/faults.c b/platform/ext/target/arm/musca_b1/faults.c index 8f5e5d1e8..5b658bf5c 100644 --- a/platform/ext/target/arm/musca_b1/faults.c +++ b/platform/ext/target/arm/musca_b1/faults.c @@ -32,7 +32,7 @@ void C_MPC_Handler(void) __attribute__((naked)) void MPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_MPC_Handler \n" @@ -60,7 +60,7 @@ void C_PPC_Handler(void) __attribute__((naked)) void PPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_PPC_Handler \n" @@ -84,7 +84,7 @@ void C_NMI_Handler(void) __attribute__((naked)) void NMI_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_NMI_Handler \n" diff --git a/platform/ext/target/arm/musca_s1/faults.c b/platform/ext/target/arm/musca_s1/faults.c index f2658e63c..a248c4052 100644 --- a/platform/ext/target/arm/musca_s1/faults.c +++ b/platform/ext/target/arm/musca_s1/faults.c @@ -29,7 +29,7 @@ void C_MPC_Handler(void) __attribute__((naked)) void MPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_MPC_Handler \n" @@ -57,7 +57,7 @@ void C_PPC_Handler(void) __attribute__((naked)) void PPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_PPC_Handler \n" diff --git a/platform/ext/target/arm/rss/common/faults.c b/platform/ext/target/arm/rss/common/faults.c index 95c7d7898..f0e788049 100644 --- a/platform/ext/target/arm/rss/common/faults.c +++ b/platform/ext/target/arm/rss/common/faults.c @@ -25,7 +25,7 @@ void C_MPC_Handler(void) __attribute__((naked)) void MPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_MPC_Handler \n" @@ -47,7 +47,7 @@ void C_PPC_Handler(void) __attribute__((naked)) void PPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_PPC_Handler \n" diff --git a/platform/ext/target/nordic_nrf/common/core/faults.c b/platform/ext/target/nordic_nrf/common/core/faults.c index 37ff846b6..5d3a554c3 100644 --- a/platform/ext/target/nordic_nrf/common/core/faults.c +++ b/platform/ext/target/nordic_nrf/common/core/faults.c @@ -47,7 +47,7 @@ void SPU_Handler(void) __attribute__((naked)) void SPU_IRQHandler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL SPU_Handler \n" diff --git a/platform/ext/target/nordic_nrf/common/nrf5340/gcc/startup_nrf5340.c b/platform/ext/target/nordic_nrf/common/nrf5340/gcc/startup_nrf5340.c index c164a5912..ed60466e2 100644 --- a/platform/ext/target/nordic_nrf/common/nrf5340/gcc/startup_nrf5340.c +++ b/platform/ext/target/nordic_nrf/common/nrf5340/gcc/startup_nrf5340.c @@ -26,7 +26,7 @@ #include "exception_info.h" __NO_RETURN __attribute__((naked)) void default_tfm_IRQHandler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL default_irq_handler \n" diff --git a/platform/ext/target/nordic_nrf/common/nrf91/gcc/startup_nrf91.c b/platform/ext/target/nordic_nrf/common/nrf91/gcc/startup_nrf91.c index a171249e5..d82f6a642 100644 --- a/platform/ext/target/nordic_nrf/common/nrf91/gcc/startup_nrf91.c +++ b/platform/ext/target/nordic_nrf/common/nrf91/gcc/startup_nrf91.c @@ -26,7 +26,7 @@ #include "exception_info.h" __NO_RETURN __attribute__((naked)) void default_tfm_IRQHandler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL default_irq_handler \n" diff --git a/platform/ext/target/nuvoton/common/faults.c b/platform/ext/target/nuvoton/common/faults.c index d243e555f..a05133406 100644 --- a/platform/ext/target/nuvoton/common/faults.c +++ b/platform/ext/target/nuvoton/common/faults.c @@ -21,7 +21,7 @@ void C_SCU_Handler(void) __attribute__((naked)) void SCU_IRQHandler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_SCU_Handler \n" @@ -39,7 +39,7 @@ void C_MPC_Handler(void) __attribute__((naked)) void MPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_MPC_Handler \n" @@ -57,7 +57,7 @@ void C_PPC_Handler(void) __attribute__((naked)) void PPC_Handler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_PPC_Handler \n" diff --git a/platform/ext/target/nxp/common/mpc_ppc_faults.c b/platform/ext/target/nxp/common/mpc_ppc_faults.c index e118f8f7b..a14ea86c7 100644 --- a/platform/ext/target/nxp/common/mpc_ppc_faults.c +++ b/platform/ext/target/nxp/common/mpc_ppc_faults.c @@ -25,7 +25,7 @@ void C_SEC_VIO_IRQHandler(void) __attribute__((naked)) void SEC_VIO_IRQHandler(void) { - EXCEPTION_INFO(EXCEPTION_TYPE_PLATFORM); + EXCEPTION_INFO(); __ASM volatile( "BL C_SEC_VIO_IRQHandler \n" diff --git a/platform/include/exception_info.h b/platform/include/exception_info.h index f1daf870b..e2d115fd6 100644 --- a/platform/include/exception_info.h +++ b/platform/include/exception_info.h @@ -19,20 +19,12 @@ #define FAULT_STATUS_PRESENT #endif -/* Arguments to EXCEPTION_INFO() */ -#define EXCEPTION_TYPE_SECUREFAULT 0 -#define EXCEPTION_TYPE_HARDFAULT 1 -#define EXCEPTION_TYPE_MEMFAULT 2 -#define EXCEPTION_TYPE_BUSFAULT 3 -#define EXCEPTION_TYPE_USAGEFAULT 4 -#define EXCEPTION_TYPE_PLATFORM 5 - -#ifndef __STRINGIFY -/* This level of indirection is needed to fully resolve exception info when it's - * a macro - */ -#define __STRINGIFY(exception_info) #exception_info -#endif +/* Exception type number (subtract 16 for IRQn) */ +#define EXCEPTION_TYPE_HARDFAULT 3 +#define EXCEPTION_TYPE_MEMMANAGEFAULT 4 +#define EXCEPTION_TYPE_BUSFAULT 5 +#define EXCEPTION_TYPE_USAGEFAULT 6 +#define EXCEPTION_TYPE_SECUREFAULT 7 /* Store context for an exception, and print an error message with the context. * @@ -42,6 +34,7 @@ #ifdef TFM_EXCEPTION_INFO_DUMP struct exception_info_t { + uint32_t VECTACTIVE; /* Active exception number. */ uint32_t EXC_RETURN; /* EXC_RETURN value in LR. */ uint32_t MSP; /* (Secure) MSP. */ uint32_t PSP; /* (Secure) PSP. */ @@ -75,25 +68,23 @@ void tfm_exception_info_get_context(struct exception_info_t *ctx); /* Store context for an exception, then print the info. * Call EXCEPTION_INFO() instead of calling this directly. */ -void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in, - uint32_t exception_type); +void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in); /* IAR Specific */ #if defined(__ICCARM__) #pragma required = store_and_dump_context #endif -#define EXCEPTION_INFO(exception_type) \ +#define EXCEPTION_INFO() \ __ASM volatile( \ "MOV r0, lr\n" \ "MRS r1, MSP\n" \ "MRS r2, PSP\n" \ - "MOVS r3, #" __STRINGIFY(exception_type) "\n"\ "BL store_and_dump_context\n" \ ) #else /* TFM_EXCEPTION_INFO_DUMP */ -#define EXCEPTION_INFO(exception_type) +#define EXCEPTION_INFO() #endif /* TFM_EXCEPTION_INFO_DUMP */ #endif /* __EXCEPTION_INFO_H__ */ From c18388762cc93e83244b945eb70b2c0bad04a893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:44 +0100 Subject: [PATCH 10/65] [nrf fromtree] platform: Store callee saved register in exception information Store the callee saved registers in the exception information logging. We store the current exception frame, which has the registers of the caller saved registers when the exception occurs, but the callee saved register information is lost during the exception handling. This provides us with an incomplete picture of the state at the time the exception occurred. Change-Id: I3d15f9eccf1aa8c2c1b99e75e38229ab82420f36 Signed-off-by: Joakim Andersson (cherry picked from commit dbdcfa06699e31ac29f0cc36b54c1f676e4a772e) Signed-off-by: Markus Swarowsky --- platform/ext/common/exception_info.c | 17 +++++++++- platform/include/exception_info.h | 49 ++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/platform/ext/common/exception_info.c b/platform/ext/common/exception_info.c index 59dbc7052..b13469008 100644 --- a/platform/ext/common/exception_info.c +++ b/platform/ext/common/exception_info.c @@ -118,6 +118,16 @@ static void dump_exception_info(bool stack_error, SPMLOG_DBGMSGVAL(" PC: ", ctx->EXC_FRAME_COPY[6]); SPMLOG_DBGMSGVAL(" xPSR: ", ctx->EXC_FRAME_COPY[7]); + SPMLOG_DBGMSG(" Callee saved register state:"); + SPMLOG_DBGMSGVAL(" R4: ", ctx->CALLEE_SAVED_COPY[0]); + SPMLOG_DBGMSGVAL(" R5: ", ctx->CALLEE_SAVED_COPY[1]); + SPMLOG_DBGMSGVAL(" R6: ", ctx->CALLEE_SAVED_COPY[2]); + SPMLOG_DBGMSGVAL(" R7: ", ctx->CALLEE_SAVED_COPY[3]); + SPMLOG_DBGMSGVAL(" R8: ", ctx->CALLEE_SAVED_COPY[4]); + SPMLOG_DBGMSGVAL(" R9: ", ctx->CALLEE_SAVED_COPY[5]); + SPMLOG_DBGMSGVAL(" R10: ", ctx->CALLEE_SAVED_COPY[6]); + SPMLOG_DBGMSGVAL(" R11: ", ctx->CALLEE_SAVED_COPY[7]); + #ifdef FAULT_STATUS_PRESENT SPMLOG_DBGMSGVAL(" CFSR: ", ctx->CFSR); SPMLOG_DBGMSGVAL(" BFSR: ", @@ -201,7 +211,8 @@ void tfm_exception_info_get_context(struct exception_info_t *ctx) memcpy(ctx, &exception_info, sizeof(exception_info)); } -void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in) +void store_and_dump_context(uint32_t MSP_in, uint32_t PSP_in, uint32_t LR_in, + uint32_t *callee_saved) { struct exception_info_t *ctx = &exception_info; @@ -213,6 +224,10 @@ void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in) ctx->EXC_FRAME = get_exception_frame(ctx->EXC_RETURN, ctx->MSP, ctx->PSP); memcpy(ctx->EXC_FRAME_COPY, ctx->EXC_FRAME, sizeof(ctx->EXC_FRAME_COPY)); + if (callee_saved) { + memcpy(ctx->CALLEE_SAVED_COPY, callee_saved, sizeof(ctx->CALLEE_SAVED_COPY)); + } + #ifdef FAULT_STATUS_PRESENT ctx->CFSR = SCB->CFSR; ctx->HFSR = SCB->HFSR; diff --git a/platform/include/exception_info.h b/platform/include/exception_info.h index e2d115fd6..9502008e0 100644 --- a/platform/include/exception_info.h +++ b/platform/include/exception_info.h @@ -40,6 +40,7 @@ struct exception_info_t { uint32_t PSP; /* (Secure) PSP. */ uint32_t *EXC_FRAME; /* Exception frame on stack. */ uint32_t EXC_FRAME_COPY[8]; /* Copy of the basic exception frame. */ + uint32_t CALLEE_SAVED_COPY[8]; /* Copy of the callee saved registers. */ uint32_t xPSR; /* Program Status Registers. */ #ifdef FAULT_STATUS_PRESENT @@ -68,20 +69,54 @@ void tfm_exception_info_get_context(struct exception_info_t *ctx); /* Store context for an exception, then print the info. * Call EXCEPTION_INFO() instead of calling this directly. */ -void store_and_dump_context(uint32_t LR_in, uint32_t MSP_in, uint32_t PSP_in); +void store_and_dump_context(uint32_t MSP_in, uint32_t PSP_in, uint32_t LR_in, + uint32_t *callee_saved); /* IAR Specific */ #if defined(__ICCARM__) #pragma required = store_and_dump_context #endif -#define EXCEPTION_INFO() \ - __ASM volatile( \ - "MOV r0, lr\n" \ - "MRS r1, MSP\n" \ - "MRS r2, PSP\n" \ - "BL store_and_dump_context\n" \ +#if defined(__ARM_ARCH_8M_BASE__) || defined(__ARCM_ARCH_V6_M__) +#define EXCEPTION_INFO() \ + __ASM volatile( \ + "MRS R0, MSP\n" \ + "MRS R1, PSP\n" \ + "MOV R2, R11\n" \ + "MOV R3, R10\n" \ + "PUSH {R2, R3}\n" \ + "MOV R2, R9\n" \ + "MOV R3, R8\n" \ + "PUSH {R2, R3}\n" \ + "PUSH {R4-R7}\n" \ + "MOV R3, SP\n" \ + "MOV R2, LR\n" \ + "BL store_and_dump_context\n" \ + "ADD SP, #32\n" \ ) +#elif defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ + defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) +#define EXCEPTION_INFO() \ + __ASM volatile( \ + "MRS R0, MSP\n" \ + "MRS R1, PSP\n" \ + "PUSH {R4-R11}\n" \ + "MOV R3, SP\n" \ + "MOV R2, LR\n" \ + "BL store_and_dump_context\n" \ + "ADD SP, #32\n" \ + ) +#else +/* Unhandled arch, call store_and_dump_context with callee_saved = NULL */ +#define EXCEPTION_INFO() \ + __ASM volatile( \ + "MRS R0, MSP\n" \ + "MRS R1, PSP\n" \ + "MOV R2, LR\n" \ + "MOV R3, #0\n" \ + "BL store_and_dump_context\n" \ + ) +#endif #else /* TFM_EXCEPTION_INFO_DUMP */ #define EXCEPTION_INFO() From 744ee55f42f12a2e02b3b2c05f41092b0d221294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:49 +0100 Subject: [PATCH 11/65] [nrf fromtree] platform: nordic_nrf: Store SPU fault information Move the SPU fault handling to only dump fault information on UART when TFM_EXCEPTION_INFO_DUMP is enabled. Store the exception info for later retrieval as the SPU handler clears the events. Change-Id: I3da12c30dc845e81e8725c687aefb498c82c90d7 Signed-off-by: Joakim Andersson (cherry picked from commit 7eace88ccd8bfa72b89ce968856407cc18ee1c07) Signed-off-by: Markus Swarowsky --- .../nordic_nrf/common/core/CMakeLists.txt | 1 + .../target/nordic_nrf/common/core/faults.c | 26 ++---------- .../common/core/native_drivers/spu.c | 17 ++++++++ .../common/core/native_drivers/spu.h | 11 +++++ .../common/core/nrf_exception_info.c | 42 +++++++++++++++++++ .../common/core/nrf_exception_info.h | 20 +++++++++ 6 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c create mode 100644 platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index 6f54ca4e8..cecb2ffe1 100644 --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -70,6 +70,7 @@ target_sources(platform_s nrfx_glue.c native_drivers/mpu_armv8m_drv.c native_drivers/spu.c + $<$:${CMAKE_CURRENT_SOURCE_DIR}/nrf_exception_info.c> $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c> $<$:${CMAKE_CURRENT_SOURCE_DIR}/pal_plat_test.c> $<$:${CMAKE_CURRENT_SOURCE_DIR}/tfm_hal_its_encryption.c> diff --git a/platform/ext/target/nordic_nrf/common/core/faults.c b/platform/ext/target/nordic_nrf/common/core/faults.c index 5d3a554c3..c4b9925ac 100644 --- a/platform/ext/target/nordic_nrf/common/core/faults.c +++ b/platform/ext/target/nordic_nrf/common/core/faults.c @@ -8,35 +8,17 @@ #include #include "cmsis.h" -#include "tfm_spm_log.h" #include "spu.h" #include "utilities.h" +#include "nrf_exception_info.h" /* "exception_info.h" must be the last include because of the IAR pragma */ #include "exception_info.h" -static void spu_dump_context(void) -{ - SPMLOG_ERRMSG("Platform Exception: SPU Fault\r\n"); - - /* Report which type of violation occured */ - if(NRF_SPU->EVENTS_RAMACCERR) - { - SPMLOG_DBGMSG(" RAMACCERR\r\n"); - } - if(NRF_SPU->EVENTS_PERIPHACCERR) - { - SPMLOG_DBGMSG(" PERIPHACCERR\r\n"); - } - if(NRF_SPU->EVENTS_FLASHACCERR) - { - SPMLOG_DBGMSG(" FLASHACCERR\r\n"); - } -} - void SPU_Handler(void) { - spu_dump_context(); - +#ifdef TFM_EXCEPTION_INFO_DUMP + nrf_exception_info_store_context(); +#endif /* Clear SPU interrupt flag and pending SPU IRQ */ spu_clear_events(); diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c index 8ba5b5776..1f23c3682 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c @@ -65,6 +65,23 @@ void spu_enable_interrupts(void) NRF_SPU_INT_PERIPHACCERR_MASK); } +uint32_t spu_events_get(void) +{ + uint32_t events = 0; + + if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_RAMACCERR)) { + events |= SPU_EVENT_RAMACCERR; + } + if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR)) { + events |= SPU_EVENT_FLASHACCERR; + } + if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR)) { + events |= SPU_EVENT_PERIPHACCERR; + } + + return events; +} + void spu_clear_events(void) { nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_RAMACCERR); diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h index 5e1bd4321..e10f42531 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h @@ -36,6 +36,17 @@ */ void spu_enable_interrupts(void); +enum spu_events { + SPU_EVENT_RAMACCERR = 1 << 0, + SPU_EVENT_FLASHACCERR = 1 << 1, + SPU_EVENT_PERIPHACCERR= 1 << 2, +}; + +/** + * \brief Retrieve bitmask of SPU events. + */ +uint32_t spu_events_get(void); + /** * \brief SPU event clearing * diff --git a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c new file mode 100644 index 000000000..16ac5a5d1 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, Nordic Semiconductor ASA. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "nrf_exception_info.h" +#include "tfm_spm_log.h" +#include "spu.h" + +static struct nrf_exception_info nrf_exc_info; + +static void spu_dump_context(struct nrf_exception_info *ctx) +{ + SPMLOG_ERRMSG("Platform Exception: SPU Fault\r\n"); + + /* Report which type of violation occured */ + if (ctx->events & SPU_EVENT_RAMACCERR) { + SPMLOG_DBGMSG(" RAMACCERR\r\n"); + } + + if (ctx->events & SPU_EVENT_PERIPHACCERR) { + SPMLOG_DBGMSG(" PERIPHACCERR\r\n"); + } + + if (ctx->events & SPU_EVENT_FLASHACCERR) { + SPMLOG_DBGMSG(" FLASHACCERR\r\n"); + } +} + +void nrf_exception_info_store_context(void) +{ + nrf_exc_info.events = spu_events_get(); + + spu_dump_context(&nrf_exc_info); +} + +void nrf_exception_info_get_context(struct nrf_exception_info *ctx) +{ + memcpy(ctx, &nrf_exc_info, sizeof(struct nrf_exception_info)); +} diff --git a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h new file mode 100644 index 000000000..7f297c800 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023, Nordic Semiconductor ASA. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __NRF_EXCEPTION_INFO_H__ +#define __NRF_EXCEPTION_INFO_H__ + +#include + +struct nrf_exception_info { + uint32_t events; +}; + +void nrf_exception_info_store_context(void); + +void nrf_exception_info_get_context(struct nrf_exception_info *ctx); + +#endif /* __NRF_EXCEPTION_INFO_H__ */ From 868fa2932afe69dc10f52a20569e70cb03e2e108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:41:56 +0100 Subject: [PATCH 12/65] [nrf fromtree] platform: nordic_nrf: unify target configuration header Unify the target configuration header, the target configuration source has already been unified. Change-Id: I23e3b47ac8e80fb5e54a24660fbb4e8313f54c78 Signed-off-by: Joakim Andersson (cherry picked from commit 7316fe17bf2383948c93e49040c4bf3bf493aff1) Signed-off-by: Markus Swarowsky --- .../common/bl5340/target_cfg.h | 141 ---------------- .../nordic_nrf/common/core/CMakeLists.txt | 1 + .../common/{nrf5340 => core}/target_cfg.h | 9 +- .../nordic_nrf/common/nrf5340/CMakeLists.txt | 1 - .../nordic_nrf/common/nrf91/CMakeLists.txt | 1 - .../nordic_nrf/common/nrf91/target_cfg.h | 150 ------------------ 6 files changed, 6 insertions(+), 297 deletions(-) delete mode 100644 platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h rename platform/ext/target/nordic_nrf/common/{nrf5340 => core}/target_cfg.h (95%) delete mode 100644 platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h b/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h deleted file mode 100644 index da87ff73e..000000000 --- a/platform/ext/target/lairdconnectivity/common/bl5340/target_cfg.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2017-2019 Arm Limited - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __TARGET_CFG_H__ -#define __TARGET_CFG_H__ - -/** - * \file target_cfg.h - * \brief nRF5340 target configuration header - * - * This file contains the platform specific functions to configure - * the Cortex-M33 core, memory permissions and security attribution - * on the nRF5340 platform. - * - * Memory permissions and security attribution are configured via - * the System Protection Unit (SPU) which is the nRF specific Implementation - * Defined Attribution Unit (IDAU). - */ - -#include "tfm_plat_defs.h" - -#define TFM_DRIVER_STDIO Driver_USART1 -#define NS_DRIVER_STDIO Driver_USART0 - -/** - * \brief Store the addresses of memory regions - */ -struct memory_region_limits { - uint32_t non_secure_code_start; - uint32_t non_secure_partition_base; - uint32_t non_secure_partition_limit; - uint32_t veneer_base; - uint32_t veneer_limit; -#ifdef NRF_NS_STORAGE_PARTITION_START - uint32_t non_secure_storage_partition_base; - uint32_t non_secure_storage_partition_limit; -#endif /* NRF_NS_STORAGE_PARTITION_START */ -}; - -/** - * \brief Holds the data necessary to do isolation for a specific peripheral. - */ -struct platform_data_t -{ - uint32_t periph_start; - uint32_t periph_limit; -}; - -/** - * \brief Configures memory permissions via the System Protection Unit. - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t spu_init_cfg(void); - -/** - * \brief Configures peripheral permissions via the System Protection Unit. - * - * The function does the following: - * - grants Non-Secure access to nRF peripherals that are not Secure-only - * - grants Non-Secure access to DDPI channels - * - grants Non-Secure access to GPIO pins - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t spu_periph_init_cfg(void); - -/** - * \brief Restrict access to peripheral to secure - */ -void spu_periph_configure_to_secure(uint32_t periph_num); - -/** - * \brief Allow non-secure access to peripheral - */ -void spu_periph_configure_to_non_secure(uint32_t periph_num); - -/** - * \brief Clears SPU interrupt. - */ -void spu_clear_irq(void); - -/** - * \brief Configures SAU and IDAU. - */ -void sau_and_idau_cfg(void); - -/** - * \brief Enables the fault handlers and sets priorities. - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t enable_fault_handlers(void); - -/** - * \brief Configures the system reset request properties - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t system_reset_cfg(void); - -/** - * \brief Configures the system debug properties. - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t init_debug(void); - -/** - * \brief Configures all external interrupts to target the - * NS state, apart for the ones associated to secure - * peripherals (plus SPU) - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void); - -/** - * \brief This function enable the interrupts associated - * to the secure peripherals (plus the isolation boundary violation - * interrupts) - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t nvic_interrupt_enable(void); - -#endif /* __TARGET_CFG_H__ */ diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index cecb2ffe1..1249d6604 100644 --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -192,6 +192,7 @@ install(FILES startup.c ) install(FILES startup.h + target_cfg.h nrfx_config.h ns/CMakeLists.txt config.cmake diff --git a/platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h similarity index 95% rename from platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.h rename to platform/ext/target/nordic_nrf/common/core/target_cfg.h index 3a1d04689..d75dbfbb9 100644 --- a/platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -20,11 +20,11 @@ /** * \file target_cfg.h - * \brief nRF5340 target configuration header + * \brief Target configuration header * * This file contains the platform specific functions to configure - * the Cortex-M33 core, memory permissions and security attribution - * on the nRF5340 platform. + * the Cortex-M33 core, memory permissions and security attribution. + * on the nordic_nrf platform. * * Memory permissions and security attribution are configured via * the System Protection Unit (SPU) which is the nRF specific Implementation @@ -84,7 +84,8 @@ enum tfm_plat_err_t spu_init_cfg(void); * - grants Non-Secure access to nRF peripherals that are not Secure-only * - grants Non-Secure access to DDPI channels * - grants Non-Secure access to GPIO pins - * - enforces that the external domain is still at the HW reset value of non-secure and locking it + * - On nrf5340 enforces that the external domain is still at the HW reset value + * of non-secure and locking it * * \return Returns values as specified by the \ref tfm_plat_err_t */ diff --git a/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt index 6cfcf87c6..773c5445e 100644 --- a/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt @@ -70,7 +70,6 @@ target_sources(tfm_spm #========================= Files for building NS side platform ================# install(FILES nrfx_config_nrf5340_application.h - target_cfg.h ns/CMakeLists.txt config.cmake cpuarch.cmake diff --git a/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt index 3fffd49f7..df86e1de5 100644 --- a/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt @@ -72,7 +72,6 @@ target_sources(tfm_spm #========================= Files for building NS side platform ================# install(FILES nrfx_config_nrf91.h - target_cfg.h ns/CMakeLists.txt config.cmake DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf91 diff --git a/platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h b/platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h deleted file mode 100644 index 1ac68bea4..000000000 --- a/platform/ext/target/nordic_nrf/common/nrf91/target_cfg.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2017-2019 Arm Limited - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __TARGET_CFG_H__ -#define __TARGET_CFG_H__ - -/** - * \file target_cfg.h - * \brief nRF9160 target configuration header - * - * This file contains the platform specific functions to configure - * the Cortex-M33 core, memory permissions and security attribution - * on the nRF9160 platform. - * - * Memory permissions and security attribution are configured via - * the System Protection Unit (SPU) which is the nRF specific Implementation - * Defined Attribution Unit (IDAU). - */ - -#include "tfm_plat_defs.h" -#include "region_defs.h" - -#if NRF_SECURE_UART_INSTANCE == 0 -#define TFM_DRIVER_STDIO Driver_USART0 -#elif NRF_SECURE_UART_INSTANCE == 1 -#define TFM_DRIVER_STDIO Driver_USART1 -#endif -#define NS_DRIVER_STDIO Driver_USART0 - -/** - * \brief Store the addresses of memory regions - */ -struct memory_region_limits { - uint32_t non_secure_code_start; - uint32_t non_secure_partition_base; - uint32_t non_secure_partition_limit; - uint32_t veneer_base; - uint32_t veneer_limit; -#ifdef NRF_NS_SECONDARY - uint32_t secondary_partition_base; - uint32_t secondary_partition_limit; -#endif /* NRF_NS_SECONDARY */ -#ifdef NRF_NS_STORAGE_PARTITION_START - uint32_t non_secure_storage_partition_base; - uint32_t non_secure_storage_partition_limit; -#endif /* NRF_NS_STORAGE_PARTITION_START */ -}; - -/** - * \brief Holds the data necessary to do isolation for a specific peripheral. - */ -struct platform_data_t -{ - uint32_t periph_start; - uint32_t periph_limit; -}; - -/** - * \brief Configures memory permissions via the System Protection Unit. - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t spu_init_cfg(void); - -/** - * \brief Configures peripheral permissions via the System Protection Unit. - * - * The function does the following: - * - grants Non-Secure access to nRF peripherals that are not Secure-only - * - grants Non-Secure access to DDPI channels - * - grants Non-Secure access to GPIO pins - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t spu_periph_init_cfg(void); - -/** - * \brief Restrict access to peripheral to secure - */ -void spu_periph_configure_to_secure(uint32_t periph_num); - -/** - * \brief Allow non-secure access to peripheral - */ -void spu_periph_configure_to_non_secure(uint32_t periph_num); - -/** - * \brief Clears SPU interrupt. - */ -void spu_clear_irq(void); - -/** - * \brief Configures SAU and IDAU. - */ -void sau_and_idau_cfg(void); - -/** - * \brief Enables the fault handlers and sets priorities. - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t enable_fault_handlers(void); - -/** - * \brief Configures the system reset request properties - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t system_reset_cfg(void); - -/** - * \brief Configures the system debug properties. - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t init_debug(void); - -/** - * \brief Configures all external interrupts to target the - * NS state, apart for the ones associated to secure - * peripherals (plus SPU) - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void); - -/** - * \brief This function enable the interrupts associated - * to the secure peripherals (plus the isolation boundary violation - * interrupts) - * - * \return Returns values as specified by the \ref tfm_plat_err_t - */ -enum tfm_plat_err_t nvic_interrupt_enable(void); - -#endif /* __TARGET_CFG_H__ */ From 9f6cd6e5bd54a3ec5c1d02e5451e7bde9c551e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:00 +0100 Subject: [PATCH 13/65] [nrf fromtree] platform: nordic_nrf: Refactor peripheral SPU configuration Refactor peripheral SPU configuration to use peripheral ID instead of address. Remove helper function that is only used once. Refactor peripheral SPU init configuration to be a loop over an array of peripheral IDs. This is done to save flash-usage of this function. Change-Id: If22956dcc791dcee4cddc3715edc65af8bafad58 Signed-off-by: Joakim Andersson (cherry picked from commit 8f8929b96e085701020e523720d1ca45c8418cf8) Signed-off-by: Markus Swarowsky --- .../common/core/native_drivers/spu.c | 10 +- .../common/core/native_drivers/spu.h | 10 +- .../nordic_nrf/common/core/target_cfg.c | 111 +++++++++--------- .../nordic_nrf/common/core/target_cfg.h | 10 -- .../common/core/tfm_hal_isolation.c | 3 +- 5 files changed, 61 insertions(+), 83 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c index 1f23c3682..63b89f6c5 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c @@ -283,11 +283,8 @@ uint32_t spu_regions_sram_get_region_size(void) { return SRAM_SECURE_ATTRIBUTION_REGION_SIZE; } -void spu_peripheral_config_secure(uint32_t periph_base_addr, bool periph_lock) +void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock) { - /* Determine peripheral ID */ - const uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_addr); - /* ASSERT checking that this is not an explicit Non-Secure peripheral */ NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM & SPU_PERIPHID_PERM_SECUREMAPPING_Msk) != @@ -300,11 +297,8 @@ void spu_peripheral_config_secure(uint32_t periph_base_addr, bool periph_lock) periph_lock); } -void spu_peripheral_config_non_secure(uint32_t periph_base_addr, bool periph_lock) +void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock) { - /* Determine peripheral ID */ - const uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_addr); - /* ASSERT checking that this is not an explicit Secure peripheral */ NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM & SPU_PERIPHID_PERM_SECUREMAPPING_Msk) != diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h index e10f42531..6561a894c 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h @@ -100,28 +100,26 @@ void spu_regions_flash_config_non_secure_callable(uint32_t start_addr, uint32_t * * Configure a device peripheral to be accessible from Secure domain only. * - * \param periph_base_addr peripheral base address - * (must correspond to a valid peripheral ID) + * \param periph_id ID number of a particular peripheral. * \param periph_lock Variable indicating whether to lock peripheral security * * \note * - peripheral shall not be a Non-Secure only peripheral * - DMA transactions are configured as Secure */ -void spu_peripheral_config_secure(uint32_t periph_base_addr, bool periph_lock); +void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock); /** * Configure a device peripheral to be accessible from Non-Secure domain. * - * \param periph_base_addr peripheral base address - * (must correspond to a valid peripheral ID) + * \param periph_id ID number of a particular peripheral. * \param periph_lock Variable indicating whether to lock peripheral security * * \note * - peripheral shall not be a Secure-only peripheral * - DMA transactions are configured as Non-Secure */ -void spu_peripheral_config_non_secure(uint32_t periph_base_addr, bool periph_lock); +void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock); /** * Configure DPPI channels to be accessible from Non-Secure domain. diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index a8a946005..79185120d 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -21,6 +21,7 @@ #include "tfm_plat_defs.h" #include "tfm_peripherals_config.h" #include "region.h" +#include "array.h" #include #include @@ -770,26 +771,25 @@ enum tfm_plat_err_t spu_init_cfg(void) enum tfm_plat_err_t spu_periph_init_cfg(void) { /* Peripheral configuration */ - +static const uint8_t target_peripherals[] = { /* The following peripherals share ID: * - FPU (FPU cannot be configured in NRF91 series, it's always NS) * - DCNF (On 53, but not 91) */ #ifndef NRF91_SERIES - spu_peripheral_config_non_secure((uint32_t)NRF_FPU, false); + NRFX_PERIPHERAL_ID_GET(NRF_FPU), #endif - /* The following peripherals share ID: * - REGULATORS * - OSCILLATORS */ - spu_peripheral_config_non_secure((uint32_t)NRF_REGULATORS, false); + NRFX_PERIPHERAL_ID_GET(NRF_REGULATORS), /* The following peripherals share ID: * - CLOCK * - POWER * - RESET (On 53, but not 91) */ - spu_peripheral_config_non_secure((uint32_t)NRF_CLOCK, false); + NRFX_PERIPHERAL_ID_GET(NRF_CLOCK), /* The following peripherals share ID: (referred to as Serial-Box) * - SPIMx * - SPISx @@ -802,99 +802,104 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) * The UART Driver will configure it as non-secure when it uninitializes. */ #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) - spu_peripheral_config_non_secure((uint32_t)NRF_SPIM0, false); + NRFX_PERIPHERAL_ID_GET(NRF_SPIM0), #endif /* When UART1 is a secure peripheral we need to leave Serial-Box 1 as Secure */ #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 1) - spu_peripheral_config_non_secure((uint32_t)NRF_SPIM1, false); + NRFX_PERIPHERAL_ID_GET(NRF_SPIM1), #endif - spu_peripheral_config_non_secure((uint32_t)NRF_SPIM2, false); - spu_peripheral_config_non_secure((uint32_t)NRF_SPIM3, false); + NRFX_PERIPHERAL_ID_GET(NRF_SPIM2), + NRFX_PERIPHERAL_ID_GET(NRF_SPIM3), #ifdef NRF_SPIM4 - spu_peripheral_config_non_secure((uint32_t)NRF_SPIM4, false); -#endif - spu_peripheral_config_non_secure((uint32_t)NRF_SAADC, false); - spu_peripheral_config_non_secure((uint32_t)NRF_TIMER0, false); - spu_peripheral_config_non_secure((uint32_t)NRF_TIMER1, false); - spu_peripheral_config_non_secure((uint32_t)NRF_TIMER2, false); - spu_peripheral_config_non_secure((uint32_t)NRF_RTC0, false); - spu_peripheral_config_non_secure((uint32_t)NRF_RTC1, false); - spu_peripheral_config_non_secure((uint32_t)NRF_DPPIC, false); + NRFX_PERIPHERAL_ID_GET(NRF_SPIM4), +#endif + NRFX_PERIPHERAL_ID_GET(NRF_SAADC), + NRFX_PERIPHERAL_ID_GET(NRF_TIMER0), + NRFX_PERIPHERAL_ID_GET(NRF_TIMER1), + NRFX_PERIPHERAL_ID_GET(NRF_TIMER2), + NRFX_PERIPHERAL_ID_GET(NRF_RTC0), + NRFX_PERIPHERAL_ID_GET(NRF_RTC1), + NRFX_PERIPHERAL_ID_GET(NRF_DPPIC), #ifndef PSA_API_TEST_IPC #ifdef NRF_WDT0 /* WDT0 is used as a secure peripheral in PSA FF tests */ - spu_peripheral_config_non_secure((uint32_t)NRF_WDT0, false); + NRFX_PERIPHERAL_ID_GET(NRF_WDT0), #endif #ifdef NRF_WDT - spu_peripheral_config_non_secure((uint32_t)NRF_WDT, false); + NRFX_PERIPHERAL_ID_GET(NRF_WDT), #endif #endif /* PSA_API_TEST_IPC */ #ifdef NRF_WDT1 - spu_peripheral_config_non_secure((uint32_t)NRF_WDT1, false); + NRFX_PERIPHERAL_ID_GET(NRF_WDT1), #endif /* The following peripherals share ID: * - COMP * - LPCOMP */ #ifdef NRF_COMP - spu_peripheral_config_non_secure((uint32_t)NRF_COMP, false); + NRFX_PERIPHERAL_ID_GET(NRF_COMP), #endif - spu_peripheral_config_non_secure((uint32_t)NRF_EGU0, false); - spu_peripheral_config_non_secure((uint32_t)NRF_EGU1, false); - spu_peripheral_config_non_secure((uint32_t)NRF_EGU2, false); - spu_peripheral_config_non_secure((uint32_t)NRF_EGU3, false); - spu_peripheral_config_non_secure((uint32_t)NRF_EGU4, false); + NRFX_PERIPHERAL_ID_GET(NRF_EGU0), + NRFX_PERIPHERAL_ID_GET(NRF_EGU1), + NRFX_PERIPHERAL_ID_GET(NRF_EGU2), + NRFX_PERIPHERAL_ID_GET(NRF_EGU3), + NRFX_PERIPHERAL_ID_GET(NRF_EGU4), #ifndef PSA_API_TEST_IPC /* EGU5 is used as a secure peripheral in PSA FF tests */ - spu_peripheral_config_non_secure((uint32_t)NRF_EGU5, false); + NRFX_PERIPHERAL_ID_GET(NRF_EGU5), #endif - spu_peripheral_config_non_secure((uint32_t)NRF_PWM0, false); - spu_peripheral_config_non_secure((uint32_t)NRF_PWM1, false); - spu_peripheral_config_non_secure((uint32_t)NRF_PWM2, false); - spu_peripheral_config_non_secure((uint32_t)NRF_PWM3, false); + NRFX_PERIPHERAL_ID_GET(NRF_PWM0), + NRFX_PERIPHERAL_ID_GET(NRF_PWM1), + NRFX_PERIPHERAL_ID_GET(NRF_PWM2), + NRFX_PERIPHERAL_ID_GET(NRF_PWM3), #ifdef NRF_PDM - spu_peripheral_config_non_secure((uint32_t)NRF_PDM, false); + NRFX_PERIPHERAL_ID_GET(NRF_PDM), #endif #ifdef NRF_PDM0 - spu_peripheral_config_non_secure((uint32_t)NRF_PDM0, false); + NRFX_PERIPHERAL_ID_GET(NRF_PDM0), #endif #ifdef NRF_I2S - spu_peripheral_config_non_secure((uint32_t)NRF_I2S, false); + NRFX_PERIPHERAL_ID_GET(NRF_I2S), #endif #ifdef NRF_I2S0 - spu_peripheral_config_non_secure((uint32_t)NRF_I2S0, false); + NRFX_PERIPHERAL_ID_GET(NRF_I2S0), #endif - spu_peripheral_config_non_secure((uint32_t)NRF_IPC, false); + NRFX_PERIPHERAL_ID_GET(NRF_IPC), #ifndef SECURE_QSPI #ifdef NRF_QSPI - spu_peripheral_config_non_secure((uint32_t)NRF_QSPI, false); + NRFX_PERIPHERAL_ID_GET(NRF_QSPI), #endif #endif #ifdef NRF_NFCT - spu_peripheral_config_non_secure((uint32_t)NRF_NFCT, false); + NRFX_PERIPHERAL_ID_GET(NRF_NFCT), #endif #ifdef NRF_MUTEX - spu_peripheral_config_non_secure((uint32_t)NRF_MUTEX, false); + NRFX_PERIPHERAL_ID_GET(NRF_MUTEX), #endif #ifdef NRF_QDEC0 - spu_peripheral_config_non_secure((uint32_t)NRF_QDEC0, false); + NRFX_PERIPHERAL_ID_GET(NRF_QDEC0), #endif #ifdef NRF_QDEC1 - spu_peripheral_config_non_secure((uint32_t)NRF_QDEC1, false); + NRFX_PERIPHERAL_ID_GET(NRF_QDEC1), #endif #ifdef NRF_USBD - spu_peripheral_config_non_secure((uint32_t)NRF_USBD, false); + NRFX_PERIPHERAL_ID_GET(NRF_USBD), #endif #ifdef NRF_USBREGULATOR - spu_peripheral_config_non_secure((uint32_t)NRF_USBREGULATOR, false); + NRFX_PERIPHERAL_ID_GET(NRF_USBREGULATOR), #endif - spu_peripheral_config_non_secure((uint32_t)NRF_NVMC, false); - spu_peripheral_config_non_secure((uint32_t)NRF_P0, false); + NRFX_PERIPHERAL_ID_GET(NRF_NVMC), + NRFX_PERIPHERAL_ID_GET(NRF_P0), #ifdef NRF_P1 - spu_peripheral_config_non_secure((uint32_t)NRF_P1, false); + NRFX_PERIPHERAL_ID_GET(NRF_P1), #endif - spu_peripheral_config_non_secure((uint32_t)NRF_VMC, false); + NRFX_PERIPHERAL_ID_GET(NRF_VMC), +}; + + for (int i = 0; i < ARRAY_SIZE(target_peripherals); i++) { + spu_peripheral_config_non_secure(target_peripherals[i], SPU_LOCK_CONF_UNLOCKED); + } /* DPPI channel configuration */ spu_dppi_config_non_secure(TFM_PERIPHERAL_DPPI_CHANNEL_MASK_SECURE, SPU_LOCK_CONF_LOCKED); @@ -942,13 +947,3 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) return TFM_PLAT_ERR_SUCCESS; } - -void spu_periph_configure_to_secure(uint32_t periph_num) -{ - spu_peripheral_config_secure(periph_num, true); -} - -void spu_periph_configure_to_non_secure(uint32_t periph_num) -{ - spu_peripheral_config_non_secure(periph_num, true); -} diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h index d75dbfbb9..356f1b794 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -91,16 +91,6 @@ enum tfm_plat_err_t spu_init_cfg(void); */ enum tfm_plat_err_t spu_periph_init_cfg(void); -/** - * \brief Restrict access to peripheral to secure - */ -void spu_periph_configure_to_secure(uint32_t periph_num); - -/** - * \brief Allow non-secure access to peripheral - */ -void spu_periph_configure_to_non_secure(uint32_t periph_num); - /** * \brief Clears SPU interrupt. */ diff --git a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c index 6c9633b3e..32a58458f 100644 --- a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c +++ b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c @@ -124,7 +124,8 @@ tfm_hal_bind_boundary(const struct partition_load_info_t *p_ldinf, continue; } - spu_periph_configure_to_secure(plat_data_ptr->periph_start); + spu_peripheral_config_secure(NRFX_PERIPHERAL_ID_GET(plat_data_ptr->periph_start), + SPU_LOCK_CONF_LOCKED); /* * Static boundaries are set. Set up MPU region for MMIO. From 7aed5d8010713eb6fabfc010a94e42bfb6cd7cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:04 +0100 Subject: [PATCH 14/65] [nrf fromlist] Build: crypto: Do not compile p256 if not enabled If MBEDTLS_P256M_ENABLED is not set then do not add the compile definitions and includes to the target upstream PR:https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/26339 Signed-off-by: Markus Swarowsky Change-Id: I1bd8fda71e6c3fa90acc79c31bf967e60ac42e3a Signed-off-by: Markus Swarowsky --- secure_fw/partitions/crypto/CMakeLists.txt | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/secure_fw/partitions/crypto/CMakeLists.txt b/secure_fw/partitions/crypto/CMakeLists.txt index 546930856..b922a0d6a 100644 --- a/secure_fw/partitions/crypto/CMakeLists.txt +++ b/secure_fw/partitions/crypto/CMakeLists.txt @@ -194,19 +194,21 @@ target_compile_definitions(${MBEDTLS_TARGET_PREFIX}mbedcrypto MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER ) -# FixMe: The p256m CmakeLists.txt in version 3.5.0 has an issue with target -# names and for this reason we need to force those defines at this stage -target_compile_definitions(${MBEDTLS_TARGET_PREFIX}p256m - PRIVATE - MBEDTLS_PSA_P256M_DRIVER_ENABLED - MBEDTLS_PSA_CRYPTO_SPM -) - -# The crypto_spe.h to be passed to p256m is here -target_include_directories(${MBEDTLS_TARGET_PREFIX}p256m - PRIVATE - . -) +if(MBEDTLS_P256M_ENABLED) + # FixMe: The p256m CmakeLists.txt in version 3.5.0 has an issue with target + # names and for this reason we need to force those defines at this stage + target_compile_definitions(${MBEDTLS_TARGET_PREFIX}p256m + PRIVATE + MBEDTLS_PSA_P256M_DRIVER_ENABLED + MBEDTLS_PSA_CRYPTO_SPM + ) + + # The crypto_spe.h to be passed to p256m is here + target_include_directories(${MBEDTLS_TARGET_PREFIX}p256m + PRIVATE + . + ) +endif() target_link_libraries(${MBEDTLS_TARGET_PREFIX}mbedcrypto PRIVATE From 9d185102fdd10ca110e06d6cba65feefa2a4771b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:09 +0100 Subject: [PATCH 15/65] [nrf fromlist] platform: nordic_nrf: Move startup CMake code into common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move CMake code for adding a startup file into common code. This improves portability. https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/25902 Signed-off-by: Sebastian Bøe Signed-off-by: Markus Swarowsky Change-Id: Ic59d3d01744eae3bb2ef2e0175a5294f7269c610 (cherry picked from commit 0f3bed474c9eabfe4423de27ee85ee26ca6a7d41) Signed-off-by: Markus Swarowsky --- .../common/bl5340/CMakeLists.txt | 6 +++--- .../nordic_nrf/common/core/CMakeLists.txt | 13 +++++++++++++ .../nordic_nrf/common/core/ns/CMakeLists.txt | 1 + .../{nrf5340/gcc => core}/startup_nrf5340.c | 0 .../common/{nrf91/gcc => core}/startup_nrf91.c | 0 .../nordic_nrf/common/nrf5340/CMakeLists.txt | 17 +---------------- .../nordic_nrf/common/nrf5340/ns/CMakeLists.txt | 6 +----- .../nordic_nrf/common/nrf91/CMakeLists.txt | 17 +---------------- .../nordic_nrf/common/nrf91/ns/CMakeLists.txt | 8 +------- 9 files changed, 21 insertions(+), 47 deletions(-) rename platform/ext/target/nordic_nrf/common/{nrf5340/gcc => core}/startup_nrf5340.c (100%) rename platform/ext/target/nordic_nrf/common/{nrf91/gcc => core}/startup_nrf91.c (100%) diff --git a/platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt b/platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt index 40d8380be..2bf62b926 100644 --- a/platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt +++ b/platform/ext/target/lairdconnectivity/common/bl5340/CMakeLists.txt @@ -19,20 +19,20 @@ set(NRF_FOLDER_PATH ${NRF_PLATFORM_PATH}/common/nrf5340) # Specify the location of platform specific build dependencies. target_sources(tfm_s PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/${NRF_FOLDER_PATH}/gcc/startup_nrf5340.c> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/${NRF_PLATFORM_PATH}/common/core/startup_nrf5340.c> ) if(NS) target_sources(tfm_ns PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/${NRF_FOLDER_PATH}/gcc/startup_nrf5340.c> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/${NRF_PLATFORM_PATH}/common/core/startup_nrf5340.c> ) endif() if(BL2) target_sources(bl2 PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/${NRF_FOLDER_PATH}/gcc/startup_nrf5340.c> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/${NRF_PLATFORM_PATH}/common/core/startup_nrf5340.c> ) endif() diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index 1249d6604..6e770049e 100644 --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -169,6 +169,18 @@ target_sources(tfm_spm target_cfg.c ) +target_sources(tfm_s + PRIVATE + $<$:${CMAKE_CURRENT_SOURCE_DIR}/startup_${target}.c> +) + +if(BL2) + target_sources(bl2 + PRIVATE + $<$:${CMAKE_CURRENT_SOURCE_DIR}/startup_${target}.c> + ) +endif() + #========================= Files for building NS side platform ================# configure_file(config_nordic_nrf_spe.cmake.in @@ -185,6 +197,7 @@ install(FILES ${PLATFORM_DIR}/ext/driver/Driver_Common.h install(FILES startup.c + startup_${target}.c nrfx_glue.c pal_plat_test.c pal_plat_test.h diff --git a/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt index 89c118e74..f73babec2 100644 --- a/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt @@ -19,6 +19,7 @@ target_compile_definitions(platform_region_defs target_sources(tfm_ns PRIVATE startup.c + $<$:${CMAKE_CURRENT_SOURCE_DIR}/startup_${target}.c> ) # Additional NS API sources diff --git a/platform/ext/target/nordic_nrf/common/nrf5340/gcc/startup_nrf5340.c b/platform/ext/target/nordic_nrf/common/core/startup_nrf5340.c similarity index 100% rename from platform/ext/target/nordic_nrf/common/nrf5340/gcc/startup_nrf5340.c rename to platform/ext/target/nordic_nrf/common/core/startup_nrf5340.c diff --git a/platform/ext/target/nordic_nrf/common/nrf91/gcc/startup_nrf91.c b/platform/ext/target/nordic_nrf/common/core/startup_nrf91.c similarity index 100% rename from platform/ext/target/nordic_nrf/common/nrf91/gcc/startup_nrf91.c rename to platform/ext/target/nordic_nrf/common/core/startup_nrf91.c diff --git a/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt index 773c5445e..b15178ec6 100644 --- a/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/nrf5340/CMakeLists.txt @@ -9,23 +9,9 @@ cmake_policy(SET CMP0076 NEW) set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(target nrf5340) add_subdirectory(../core nrf_common) -#========================= Platform common defs ===============================# - -# Specify the location of platform specific build dependencies. -target_sources(tfm_s - PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/gcc/startup_nrf5340.c> -) - -if(BL2) - target_sources(bl2 - PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/gcc/startup_nrf5340.c> - ) -endif() - #========================= Platform Secure ====================================# target_include_directories(platform_s @@ -77,7 +63,6 @@ install(FILES nrfx_config_nrf5340_application.h ) install(DIRECTORY partition - gcc tests DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf5340 ) diff --git a/platform/ext/target/nordic_nrf/common/nrf5340/ns/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf5340/ns/CMakeLists.txt index 8b8603d35..52593d125 100644 --- a/platform/ext/target/nordic_nrf/common/nrf5340/ns/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/nrf5340/ns/CMakeLists.txt @@ -8,13 +8,9 @@ cmake_policy(SET CMP0076 NEW) set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(target nrf5340) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../core nrf_common) -target_sources(tfm_ns - PRIVATE - $<$:${CMAKE_CURRENT_LIST_DIR}/gcc/startup_nrf5340.c> -) - target_include_directories(platform_ns PUBLIC ${CMAKE_CURRENT_LIST_DIR} diff --git a/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt index df86e1de5..31898e64c 100644 --- a/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/nrf91/CMakeLists.txt @@ -9,23 +9,9 @@ cmake_policy(SET CMP0076 NEW) set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(target nrf91) add_subdirectory(../core nrf_common) -#========================= Platform common defs ===============================# - -# Specify the location of platform specific build dependencies. -target_sources(tfm_s - PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/gcc/startup_nrf91.c> -) - -if(BL2) - target_sources(bl2 - PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/gcc/startup_nrf91.c> - ) -endif() - #========================= Platform Secure ====================================# target_include_directories(platform_s @@ -78,7 +64,6 @@ install(FILES nrfx_config_nrf91.h ) install(DIRECTORY partition - gcc tests DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf91 ) diff --git a/platform/ext/target/nordic_nrf/common/nrf91/ns/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf91/ns/CMakeLists.txt index 5a430489c..290d7f4c5 100644 --- a/platform/ext/target/nordic_nrf/common/nrf91/ns/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/nrf91/ns/CMakeLists.txt @@ -9,15 +9,9 @@ cmake_policy(SET CMP0076 NEW) set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(target nrf91) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../core nrf_common) -#========================= Platform common defs ===============================# - -target_sources(tfm_ns - PRIVATE - $<$:${CMAKE_CURRENT_SOURCE_DIR}/gcc/startup_nrf91.c> -) - #========================= Platform Non-Secure ================================# target_include_directories(platform_ns From 4e93810e40c08606b9ac9c99f90d714ed012e883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:14 +0100 Subject: [PATCH 16/65] [nrf noup] Do not pass PSA_CONFIG again to crypto library The MBEDTLS_PSA_CRYPTO_CONFIG_FILE gets already defined in the mbedtls_common target and is included in the nrf-config.h file. TF-M adds the compile definition again, causing a redefined warning when building Signed-off-by: Markus Swarowsky Change-Id: Idd813911f6886da279c16bcd8b81d07039a4db50 --- secure_fw/partitions/crypto/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/secure_fw/partitions/crypto/CMakeLists.txt b/secure_fw/partitions/crypto/CMakeLists.txt index b922a0d6a..436991848 100644 --- a/secure_fw/partitions/crypto/CMakeLists.txt +++ b/secure_fw/partitions/crypto/CMakeLists.txt @@ -91,10 +91,10 @@ target_link_libraries(tfm_config ############################### PSA CRYPTO CONFIG ############################## add_library(psa_crypto_config INTERFACE) -target_compile_definitions(psa_crypto_config - INTERFACE - MBEDTLS_PSA_CRYPTO_CONFIG_FILE="${TFM_MBEDCRYPTO_PSA_CRYPTO_CONFIG_PATH}" -) +# target_compile_definitions(psa_crypto_config +# INTERFACE +# MBEDTLS_PSA_CRYPTO_CONFIG_FILE="${TFM_MBEDCRYPTO_PSA_CRYPTO_CONFIG_PATH}" +# ) ############################### MBEDCRYPTO ##################################### From ed1bc894ffa758bbaea3161773d764dbf9592bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:18 +0100 Subject: [PATCH 17/65] [nrf fromlist] platform: nordic_nrf: Document FlashInfo fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [nrf fromlist] because this was cherry-picked from https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/25904/1 Document FlashInfo fields. NB: I found this commit was missing from the TF-M upmerge branch. I don't know how it went missing. Signed-off-by: Sebastian Bøe Change-Id: I9f92711edd754f7972a36baba2cd5c8e2675b03a Signed-off-by: Markus Swarowsky --- .../nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c index 833cf4f7c..15cdca4f0 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c @@ -63,8 +63,11 @@ static ARM_FLASH_INFO FlashInfo = { .sector_info = NULL, /* Uniform sector layout */ .sector_count = FLASH_TOTAL_SIZE / FLASH_AREA_IMAGE_SECTOR_SIZE, .sector_size = FLASH_AREA_IMAGE_SECTOR_SIZE, - .page_size = sizeof(uint32_t), /* 32-bit word = 4 bytes */ - .program_unit = sizeof(uint32_t), /* 32-bit word = 4 bytes */ + /* page_size denotes the optimal programming page size in bytes + * for fast programming, but is currently unused by TF-M. */ + .page_size = sizeof(uint32_t), + /* Note that program_unit must match TFM_HAL_ITS_PROGRAM_UNIT */ + .program_unit = sizeof(uint32_t), .erased_value = 0xFF }; From 660bd6d9475d658b9103eed3ca28f9af656e2d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:24 +0100 Subject: [PATCH 18/65] [nrf fromlist] platform: nordic_nrf: Remove unused driver functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [nrf fromlist] because this was cherry-picked from https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/25899/2 Remove unused driver functions. We are currently implementing several functions that TF-M is not using. This is bad practice as they are untested and may therefore be unreliable if TF-M were to start to use them. They also bloat the size of the binary and have a code maintenance cost. It would be better to implement the functions when they become used. NB: I found this commit was missing from the TF-M upmerge branch. I don't know how it went missing. Signed-off-by: Sebastian Bøe Change-Id: Icd7df7caa38ea890742b4b70118d642b196c4d71 Signed-off-by: Markus Swarowsky --- .../common/core/cmsis_drivers/Driver_Flash.c | 51 ++----------------- 1 file changed, 5 insertions(+), 46 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c index 15cdca4f0..0f960bc79 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c @@ -27,8 +27,6 @@ #define ARG_UNUSED(arg) (void)arg #endif -#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) - #if RTE_FLASH0 /** @@ -48,15 +46,10 @@ static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = { sizeof(uint32_t), }; -static const ARM_DRIVER_VERSION DriverVersion = { - ARM_FLASH_API_VERSION, - ARM_FLASH_DRV_VERSION -}; - static const ARM_FLASH_CAPABILITIES DriverCapabilities = { .event_ready = 0, .data_width = DATA_WIDTH_32BIT, - .erase_chip = 1 + .erase_chip = 0 }; static ARM_FLASH_INFO FlashInfo = { @@ -86,11 +79,6 @@ static bool is_range_valid(uint32_t addr, uint32_t cnt) return true; } -static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void) -{ - return DriverVersion; -} - static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void) { return DriverCapabilities; @@ -112,20 +100,6 @@ static int32_t ARM_Flash_Uninitialize(void) return ARM_DRIVER_OK; } -static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state) -{ - switch (state) { - case ARM_POWER_FULL: - /* Nothing to be done */ - return ARM_DRIVER_OK; - - case ARM_POWER_OFF: - case ARM_POWER_LOW: - default: - return ARM_DRIVER_ERROR_UNSUPPORTED; - } -} - static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) { /* Conversion between data items and bytes */ @@ -171,37 +145,22 @@ static int32_t ARM_Flash_EraseSector(uint32_t addr) return ARM_DRIVER_OK; } -static int32_t ARM_Flash_EraseChip(void) -{ - nrfx_nvmc_all_erase(); - return ARM_DRIVER_OK; -} - -static ARM_FLASH_STATUS ARM_Flash_GetStatus(void) -{ - ARM_FLASH_STATUS status = { - .busy = !nrfx_nvmc_write_done_check() - }; - - return status; -} - static ARM_FLASH_INFO * ARM_Flash_GetInfo(void) { return &FlashInfo; } ARM_DRIVER_FLASH Driver_FLASH0 = { - .GetVersion = ARM_Flash_GetVersion, + .GetVersion = NULL, .GetCapabilities = ARM_Flash_GetCapabilities, .Initialize = ARM_Flash_Initialize, .Uninitialize = ARM_Flash_Uninitialize, - .PowerControl = ARM_Flash_PowerControl, + .PowerControl = NULL, .ReadData = ARM_Flash_ReadData, .ProgramData = ARM_Flash_ProgramData, .EraseSector = ARM_Flash_EraseSector, - .EraseChip = ARM_Flash_EraseChip, - .GetStatus = ARM_Flash_GetStatus, + .EraseChip = NULL, + .GetStatus = NULL, .GetInfo = ARM_Flash_GetInfo }; From bfde4d7c86925249e8ca0b107196da37fc8ac8e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:29 +0100 Subject: [PATCH 19/65] [nrf fromlist] platform: nordic_nrf: Remove Flash_Uninitialize function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [nrf fromlist] because this was cherry-picked from https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/25903/1 Remove the function ARM_Flash_Uninitialize is it is only used in BL1 and BL2 integration and nordic is not compatible with BL1 or BL2. It is bad practice to have an unused function available as it is untested and may therefore be unreliable if TF-M were to start to using it. It also bloats the size of the binary and has a code maintenance cost. Signed-off-by: Sebastian Bøe Change-Id: I319b13b916e78f7692fab23a4f542877b8484bcb Signed-off-by: Markus Swarowsky --- .../nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c index 0f960bc79..987c5d5e5 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c @@ -95,11 +95,6 @@ static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event) return ARM_DRIVER_OK; } -static int32_t ARM_Flash_Uninitialize(void) -{ - return ARM_DRIVER_OK; -} - static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) { /* Conversion between data items and bytes */ @@ -154,7 +149,7 @@ ARM_DRIVER_FLASH Driver_FLASH0 = { .GetVersion = NULL, .GetCapabilities = ARM_Flash_GetCapabilities, .Initialize = ARM_Flash_Initialize, - .Uninitialize = ARM_Flash_Uninitialize, + .Uninitialize = NULL, .PowerControl = NULL, .ReadData = ARM_Flash_ReadData, .ProgramData = ARM_Flash_ProgramData, From f1aa7149ea5839dff76a83ce7272db7570e100f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:47 +0100 Subject: [PATCH 20/65] [nrf toup] secure_fw: spm: Add stdio_uinit We added the option for sharing a UART instance for the secure and non-secure application. To do that we have to call stdio_uninit from the secure side in order to configure the UART as non-secure. This was done before but got dropped with the latest update. Change-Id: Ic65ab61ba22b59b893f96e1c63f7e2f8da61c45b --- secure_fw/spm/core/tfm_svcalls.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/secure_fw/spm/core/tfm_svcalls.c b/secure_fw/spm/core/tfm_svcalls.c index ee0447def..16474180a 100644 --- a/secure_fw/spm/core/tfm_svcalls.c +++ b/secure_fw/spm/core/tfm_svcalls.c @@ -27,6 +27,7 @@ #include "load/spm_load_api.h" #include "load/partition_defs.h" #include "psa/client.h" +#include "uart_stdout.h" #ifdef PLATFORM_SVC_HANDLERS extern int32_t platform_svc_handlers(uint8_t svc_number, @@ -172,6 +173,10 @@ static uint32_t handle_spm_svc_requests(uint32_t svc_number, uint32_t exc_return case TFM_SVC_SPM_INIT: exc_return = tfm_spm_init(); tfm_arch_check_msp_sealing(); + +#if defined(CONFIG_TFM_LOG_SHARE_UART) + stdio_uninit(); +#endif /* The following call does not return */ tfm_arch_free_msp_and_exc_ret(SPM_BOOT_STACK_BOTTOM, exc_return); break; From db18f3f4d05d071d567b156e1e84ae50863fb219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:42:51 +0100 Subject: [PATCH 21/65] [nrf toup] platform: nordic_nrf: Fix USART driver The spu_peripheral_config_(non_)secure calls takes the ID of the peripheral as the argument and not the register address. Signed-off-by: Georgios Vasilakis Change-Id: I2546cd8e4ed4c09c742911bd0807f732de335f7c --- .../nordic_nrf/common/core/cmsis_drivers/Driver_USART.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index ec87e9cfc..b1ae79833 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -114,7 +114,7 @@ static int32_t ARM_USARTx_Initialize(ARM_USART_SignalEvent_t cb_event, ARG_UNUSED(cb_event); #ifdef SPU_CONFIGURE_UART - spu_peripheral_config_secure((uint32_t)uart_resources->uarte.p_reg, false); + spu_peripheral_config_secure(NRFX_PERIPHERAL_ID_GET((uint32_t)uart_resources->uarte.p_reg), false); NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET((uint32_t)uart_resources->uarte.p_reg)); #endif @@ -147,7 +147,7 @@ static int32_t ARM_USARTx_Uninitialize(UARTx_Resources *uart_resources) uart_resources->initialized = false; #ifdef SPU_CONFIGURE_UART - spu_peripheral_config_non_secure((uint32_t)uart_resources->uarte.p_reg, false); + spu_peripheral_config_non_secure(NRFX_PERIPHERAL_ID_GET((uint32_t)uart_resources->uarte.p_reg), false); NVIC_SetTargetState(NRFX_IRQ_NUMBER_GET((uint32_t)uart_resources->uarte.p_reg)); #endif From 293f6cf57a8dd2c172fa43576abc617da2705db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:43:35 +0100 Subject: [PATCH 22/65] [nrf noup] Remove check for P256M TF-M checks if P256M is available during build time using MBEDCRYPTO_PATH which is set to the TF-M repo to use custom mbed TLS cmake configurations, but this means the script can not be found. But as mbed TLS software crypto is not used anyway we can hardcode P256M to be disabled. Signed-off-by: Markus Swarowsky Change-Id: I94fde1f41e3493e840823cae284256176a364863 Signed-off-by: Markus Swarowsky --- secure_fw/partitions/crypto/CMakeLists.txt | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/secure_fw/partitions/crypto/CMakeLists.txt b/secure_fw/partitions/crypto/CMakeLists.txt index 436991848..7a463fed0 100644 --- a/secure_fw/partitions/crypto/CMakeLists.txt +++ b/secure_fw/partitions/crypto/CMakeLists.txt @@ -138,20 +138,8 @@ set(MBEDTLS_TARGET_PREFIX crypto_service_) #set(MBEDTLS_PSA_CRYPTO_CONFIG_FILE "${TFM_MBEDCRYPTO_PSA_CRYPTO_CONFIG_PATH}") #set(MBEDTLS_CONFIG_FILE "${TFM_MBEDCRYPTO_CONFIG_PATH}") -# Check if the p256m driver is enabled in the config file, as that will require a -# dedicated target to be linked in. Note that 0 means SUCCESS here, 1 means FAILURE -set(MBEDTLS_P256M_NOT_FOUND 1) -execute_process(COMMAND - ${Python3_EXECUTABLE} - ${MBEDCRYPTO_PATH}/scripts/config.py -f "${TFM_MBEDCRYPTO_CONFIG_PATH}" get MBEDTLS_PSA_P256M_DRIVER_ENABLED - RESULT_VARIABLE MBEDTLS_P256M_NOT_FOUND) - -if (${MBEDTLS_P256M_NOT_FOUND} EQUAL 0) - message(STATUS "[Crypto service] Using P256M software driver in PSA Crypto backend") - set(MBEDTLS_P256M_ENABLED true) -else() - set(MBEDTLS_P256M_ENABLED false) -endif() +# We use hardware acceleration or ocrypto so disable the P256M module by default +set(MBEDTLS_P256M_ENABLED false) # Mbedcrypto is quite a large lib, and it uses too much memory for it to be # reasonable to build it in debug info. As a compromise, if `debug` build type From 4eff83567b0ca90493a85b7c0a9124c3d3a255f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 1 Mar 2024 16:43:47 +0100 Subject: [PATCH 23/65] [nrf noup] platform: nordic_nrf: Add support for 54l MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for 54l Signed-off-by: Sebastian Bøe Change-Id: I3574d73222dd23d202e5259a863f2e1b4b001739 --- .../nordic_nrf/common/core/CMakeLists.txt | 33 +- .../common/core/cmsis_drivers/Driver_Flash.c | 46 ++ .../common/core/cmsis_drivers/Driver_USART.c | 9 +- .../common/nrfx_config_nrf54l15_application.h | 74 +++ .../target/nordic_nrf/common/core/faults.c | 4 + .../common/core/native_drivers/spu.c | 111 +++-- .../common/core/native_drivers/spu.h | 46 +- .../common/core/nrf_exception_info.c | 5 + .../nordic_nrf/common/core/nrfx_config.h | 19 +- .../target/nordic_nrf/common/core/plat_test.c | 22 +- .../services/src/tfm_platform_hal_ioctl.c | 7 + .../target/nordic_nrf/common/core/startup.h | 7 + .../nordic_nrf/common/core/startup_nrf54l15.c | 428 ++++++++++++++++++ .../nordic_nrf/common/core/target_cfg.c | 350 +++++++++++++- .../nordic_nrf/common/core/target_cfg.h | 16 + .../common/core/tfm_hal_isolation.c | 11 + 16 files changed, 1089 insertions(+), 99 deletions(-) create mode 100644 platform/ext/target/nordic_nrf/common/core/common/nrfx_config_nrf54l15_application.h create mode 100644 platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index 6e770049e..1ad66c344 100644 --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -19,6 +19,15 @@ if (NOT NRF_BOARD_SELECTED) "Instead of '${TFM_PLATFORM}', choose e.g. '${hint}'.") endif() +# At the time of writing there is no systematic way to identify which +# NVM technology is used by the SoC from the Kconfig, so we just +# hardcode this information here instead. +if(PSA_API_TEST_TARGET STREQUAL nrf54l15) + set(HAS_RRAMC 1) +else() + set(HAS_NVMC 1) +endif() + #========================= Platform dependencies ===============================# include(hal_nordic.cmake) @@ -63,10 +72,25 @@ target_include_directories(platform_s services/include ) +set(nvm_sources + $<$:${CMAKE_CURRENT_SOURCE_DIR}/cmsis_drivers/Driver_Flash.c> +) + +if(HAS_RRAMC) + list(APPEND nvm_sources + ${HAL_NORDIC_PATH}/nrfx/drivers/src/nrfx_rramc.c + ) +elseif(HAS_NVMC) + list(APPEND nvm_sources + ${HAL_NORDIC_PATH}/nrfx/drivers/src/nrfx_nvmc.c + ) +else() + message(FATAL_ERROR "Unexpected device") +endif() + target_sources(platform_s - PRIVATE - cmsis_drivers/Driver_Flash.c - ${HAL_NORDIC_PATH}/nrfx/drivers/src/nrfx_nvmc.c + PRIVATE + ${nvm_sources} nrfx_glue.c native_drivers/mpu_armv8m_drv.c native_drivers/spu.c @@ -127,10 +151,9 @@ target_compile_definitions(platform_s if(BL2) target_sources(platform_bl2 PRIVATE - cmsis_drivers/Driver_Flash.c + ${nvm_sources} cmsis_drivers/Driver_USART.c ${HAL_NORDIC_PATH}/nrfx/drivers/src/nrfx_uarte.c - ${HAL_NORDIC_PATH}/nrfx/drivers/src/nrfx_nvmc.c nrfx_glue.c ) target_sources(bl2 diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c index 987c5d5e5..c46462d63 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c @@ -21,7 +21,16 @@ #include #include #include + +#include + +#if defined(NRF_NVMC_S) #include +#elif defined(NRF_RRAMC_S) +#include +#else +#error "Unrecognized platform" +#endif #ifndef ARG_UNUSED #define ARG_UNUSED(arg) (void)arg @@ -92,7 +101,30 @@ static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event) return ARM_DRIVER_ERROR; } +#ifdef NRF_RRAMC_S + /* Disable buffering until it's security impact is understood */ + uint8_t write_buff_size = 0; + + /* Don't use an event handler until it's understood whether we + * want it or not */ + nrfx_rramc_evt_handler_t handler = NULL; + + nrfx_rramc_config_t p_config = NRFX_RRAMC_DEFAULT_CONFIG(write_buff_size); + + nrfx_err_t err_code = nrfx_rramc_init(&p_config, handler); + + switch(err_code){ + case NRFX_SUCCESS: + case NRFX_ERROR_ALREADY: + // TF-M appears to be invoking ARM_FLASH_Initialize multiple + // times, but this is of no concern to the driver. + return ARM_DRIVER_OK; + default: + return ARM_DRIVER_ERROR; + } +#else return ARM_DRIVER_OK; +#endif } static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) @@ -124,7 +156,11 @@ static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, return ARM_DRIVER_ERROR_PARAMETER; } +#ifdef NRF_NVMC_S nrfx_nvmc_words_write(addr, data, cnt); +#else + nrfx_rramc_words_write(addr, data, cnt); +#endif /* Conversion between bytes and data items */ return cnt; @@ -132,10 +168,20 @@ static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, static int32_t ARM_Flash_EraseSector(uint32_t addr) { +#ifdef NRF_NVMC_S nrfx_err_t err_code = nrfx_nvmc_page_erase(addr); + if (err_code != NRFX_SUCCESS) { return ARM_DRIVER_ERROR_PARAMETER; } +#else + for (uint32_t *erase_word_ptr = (uint32_t *)addr; + (uint32_t)erase_word_ptr < addr + FLASH_AREA_IMAGE_SECTOR_SIZE; erase_word_ptr++) { + if(*erase_word_ptr != 0xFFFFFFFFU) { + nrfx_rramc_word_write((uint32_t)erase_word_ptr, 0xFFFFFFFFU); + } + } +#endif return ARM_DRIVER_OK; } diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index b1ae79833..80f4f9201 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -39,7 +39,7 @@ #define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2) -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART22 #define PSEL_DISCONNECTED 0xFFFFFFFFUL @@ -438,4 +438,9 @@ DRIVER_USART(2); DRIVER_USART(3); #endif -#endif /* RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 */ +// TODO: NCSDK-25009: Support choosing an instance for TF-M +#if RTE_USART22 +DRIVER_USART(22); +#endif + +#endif /* RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART22 */ diff --git a/platform/ext/target/nordic_nrf/common/core/common/nrfx_config_nrf54l15_application.h b/platform/ext/target/nordic_nrf/common/core/common/nrfx_config_nrf54l15_application.h new file mode 100644 index 000000000..814f022b4 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/core/common/nrfx_config_nrf54l15_application.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef NRFX_CONFIG_NRF54L15_APPLICATION_H__ +#define NRFX_CONFIG_NRF54L15_APPLICATION_H__ + +#ifndef NRFX_CONFIG_H__ +#error "This file should not be included directly. Include nrfx_config.h instead." +#endif + +/** + * @brief NRFX_DEFAULT_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_DEFAULT_IRQ_PRIORITY +#define NRFX_DEFAULT_IRQ_PRIORITY 7 +#endif + +/** + * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_RRAMC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RRAMC_ENABLED +#define NRFX_RRAMC_ENABLED 0 +#endif + +/** + * @brief NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RRAMC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_RRAMC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RRAMC_CONFIG_LOG_ENABLED +#define NRFX_RRAMC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_RRAMC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_RRAMC_CONFIG_LOG_LEVEL +#define NRFX_RRAMC_CONFIG_LOG_LEVEL 3 +#endif + +#endif // NRFX_CONFIG_NRF54L15_APPLICATION_H__ diff --git a/platform/ext/target/nordic_nrf/common/core/faults.c b/platform/ext/target/nordic_nrf/common/core/faults.c index c4b9925ac..9306dc04b 100644 --- a/platform/ext/target/nordic_nrf/common/core/faults.c +++ b/platform/ext/target/nordic_nrf/common/core/faults.c @@ -22,7 +22,11 @@ void SPU_Handler(void) /* Clear SPU interrupt flag and pending SPU IRQ */ spu_clear_events(); +#ifdef SPU_IRQn NVIC_ClearPendingIRQ(SPU_IRQn); +#else + // TODO: NCSDK-25011: Support nrf54l +#endif tfm_core_panic(); } diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c index 63b89f6c5..d4a8cceec 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c @@ -16,8 +16,14 @@ #include "spu.h" #include "region_defs.h" +#include "array.h" /* Platform-specific configuration */ +#if NRF_SPU_HAS_MEMORY + +#define DEVICE_FLASH_BASE_ADDRESS FLASH_BASE_ADDRESS +#define DEVICE_SRAM_BASE_ADDRESS SRAM_BASE_ADDRESS + #define FLASH_SECURE_ATTRIBUTION_REGION_SIZE SPU_FLASH_REGION_SIZE #define SRAM_SECURE_ATTRIBUTION_REGION_SIZE SPU_SRAM_REGION_SIZE @@ -29,9 +35,6 @@ #define NUM_SRAM_SECURE_ATTRIBUTION_REGIONS \ (TOTAL_RAM_SIZE / SRAM_SECURE_ATTRIBUTION_REGION_SIZE) -#define DEVICE_FLASH_BASE_ADDRESS FLASH_BASE_ADDRESS -#define DEVICE_SRAM_BASE_ADDRESS SRAM_BASE_ADDRESS - /* Convenience macros for SPU Non-Secure Callable (NCS) attribution */ /* @@ -56,37 +59,24 @@ */ #define FLASH_NSC_SIZE_REG(size) ((31 - __builtin_clz(size)) - 4) - -void spu_enable_interrupts(void) +#if defined(REGION_PCD_SRAM_ADDRESS) +static bool spu_region_is_sram_region_in_address_range(uint8_t region_id, uint32_t start_address, uint32_t end_address) { - nrf_spu_int_enable(NRF_SPU, - NRF_SPU_INT_FLASHACCERR_MASK | - NRF_SPU_INT_RAMACCERR_MASK | - NRF_SPU_INT_PERIPHACCERR_MASK); + size_t start_id = (start_address - DEVICE_SRAM_BASE_ADDRESS) / SRAM_SECURE_ATTRIBUTION_REGION_SIZE; + size_t end_id = (end_address - DEVICE_SRAM_BASE_ADDRESS) / SRAM_SECURE_ATTRIBUTION_REGION_SIZE; + return region_id >= start_id && region_id <= end_id; } +#endif -uint32_t spu_events_get(void) +static bool spu_region_is_pcd_region(NRF_SPU_Type * p_reg, uint8_t region_id) { - uint32_t events = 0; - - if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_RAMACCERR)) { - events |= SPU_EVENT_RAMACCERR; - } - if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR)) { - events |= SPU_EVENT_FLASHACCERR; - } - if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR)) { - events |= SPU_EVENT_PERIPHACCERR; - } + bool is_pcd = false; - return events; -} +#ifdef PM_PCD_SRAM_ADDRESS + is_pcd = is_pcd || spu_region_is_sram_region_in_address_range(region_id, PM_PCD_SRAM_ADDRESS, PM_PCD_SRAM_END_ADDRESS); +#endif -void spu_clear_events(void) -{ - nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_RAMACCERR); - nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR); - nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR); + return is_pcd; } #if defined(REGION_MCUBOOT_ADDRESS) || defined(REGION_B0_ADDRESS) || defined(REGION_S0_ADDRESS) || defined(REGION_S1_ADDRESS) @@ -98,15 +88,6 @@ static bool spu_region_is_flash_region_in_address_range(uint8_t region_id, uint3 } #endif -#if defined(REGION_PCD_SRAM_ADDRESS) -static bool spu_region_is_sram_region_in_address_range(uint8_t region_id, uint32_t start_address, uint32_t end_address) -{ - size_t start_id = (start_address - DEVICE_SRAM_BASE_ADDRESS) / SRAM_SECURE_ATTRIBUTION_REGION_SIZE; - size_t end_id = (end_address - DEVICE_SRAM_BASE_ADDRESS) / SRAM_SECURE_ATTRIBUTION_REGION_SIZE; - return region_id >= start_id && region_id <= end_id; -} -#endif - static bool spu_region_is_bootloader_region(NRF_SPU_Type * p_reg, uint8_t region_id) { bool is_bootloader = false; @@ -127,17 +108,57 @@ static bool spu_region_is_bootloader_region(NRF_SPU_Type * p_reg, uint8_t region return is_bootloader; } -static bool spu_region_is_pcd_region(NRF_SPU_Type * p_reg, uint8_t region_id) +#endif /* NRF_SPU_HAS_MEMORY */ + +void spu_enable_interrupts(void) { - bool is_pcd = false; + uint32_t mask = 0; -#ifdef PM_PCD_SRAM_ADDRESS - is_pcd = is_pcd || spu_region_is_sram_region_in_address_range(region_id, PM_PCD_SRAM_ADDRESS, PM_PCD_SRAM_END_ADDRESS); +#if NRF_SPU_HAS_MEMORY + mask |= NRF_SPU_INT_RAMACCERR_MASK; + mask |= NRF_SPU_INT_FLASHACCERR_MASK; #endif - return is_pcd; + mask |= NRF_SPU_INT_PERIPHACCERR_MASK; + + for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { + nrf_spu_int_enable(spu_instances[i], mask); + } } +uint32_t spu_events_get(void) +{ + uint32_t events = 0; + +#if NRF_SPU_HAS_MEMORY + if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_RAMACCERR)) { + events |= SPU_EVENT_RAMACCERR; + } + if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR)) { + events |= SPU_EVENT_FLASHACCERR; + } + if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR)) { + events |= SPU_EVENT_PERIPHACCERR; + } +#else + // TODO: NCSDK-25011: Support fault handling on 54L +#endif + + return events; +} + +void spu_clear_events(void) +{ + for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { +#if NRF_SPU_HAS_MEMORY + nrf_spu_event_clear(spu_instances[i], NRF_SPU_EVENT_RAMACCERR); + nrf_spu_event_clear(spu_instances[i], NRF_SPU_EVENT_FLASHACCERR); +#endif + nrf_spu_event_clear(spu_instances[i], NRF_SPU_EVENT_PERIPHACCERR); + } +} + +#if NRF_SPU_HAS_MEMORY void spu_regions_reset_unlocked_secure(void) { for (size_t i = 0; i < NUM_FLASH_SECURE_ATTRIBUTION_REGIONS ; i++) { @@ -283,6 +304,9 @@ uint32_t spu_regions_sram_get_region_size(void) { return SRAM_SECURE_ATTRIBUTION_REGION_SIZE; } +#endif /* NRF_SPU_HAS_MEMORY */ + +#ifdef NRF_SPU void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock) { /* ASSERT checking that this is not an explicit Non-Secure peripheral */ @@ -310,3 +334,6 @@ void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock) 0 /* Non-Secure DMA */, periph_lock); } +#else +// TODO: NCSDK-22597: Support configuring peripherals as secure +#endif diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h index 6561a894c..60731de47 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h @@ -28,6 +28,24 @@ #define SPU_SECURE_ATTR_SECURE true #define SPU_SECURE_ATTR_NONSECURE false +__attribute__((unused)) static NRF_SPU_Type * spu_instances[] = { +#ifdef NRF_SPU + NRF_SPU, +#endif +#ifdef NRF_SPU00 + NRF_SPU00, +#endif +#ifdef NRF_SPU10 + NRF_SPU10, +#endif +#ifdef NRF_SPU20 + NRF_SPU20, +#endif +#ifdef NRF_SPU30 + NRF_SPU30, +#endif +}; + /** * \brief SPU interrupt enabling * @@ -121,34 +139,6 @@ void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock); */ void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock); -/** - * Configure DPPI channels to be accessible from Non-Secure domain. - * - * \param channels_mask Bitmask with channels configuration. - * \param lock_conf Variable indicating whether to lock DPPI channel security - * - * \note all channels are configured as Non-Secure - */ -static inline void spu_dppi_config_non_secure(uint32_t channels_mask, bool lock_conf) -{ - nrf_spu_dppi_config_set(NRF_SPU, 0, channels_mask, lock_conf); -} - -/** - * Configure GPIO pins to be accessible from Non-Secure domain. - * - * \param port_number GPIO Port number - * \param gpio_mask Bitmask with gpio configuration. - * \param lock_conf Variable indicating whether to lock GPIO port security - * - * \note all pins are configured as Non-Secure - */ -static inline void spu_gpio_config_non_secure(uint8_t port_number, uint32_t gpio_mask, - bool lock_conf) -{ - nrf_spu_gpio_config_set(NRF_SPU, port_number, gpio_mask, lock_conf); -} - /** * \brief Return base address of a Flash SPU regions * diff --git a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c index 16ac5a5d1..e2aceb1f0 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c +++ b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c @@ -15,6 +15,7 @@ static void spu_dump_context(struct nrf_exception_info *ctx) { SPMLOG_ERRMSG("Platform Exception: SPU Fault\r\n"); +#ifdef NRF_SPU /* Report which type of violation occured */ if (ctx->events & SPU_EVENT_RAMACCERR) { SPMLOG_DBGMSG(" RAMACCERR\r\n"); @@ -27,6 +28,10 @@ static void spu_dump_context(struct nrf_exception_info *ctx) if (ctx->events & SPU_EVENT_FLASHACCERR) { SPMLOG_DBGMSG(" FLASHACCERR\r\n"); } +#else + // TODO: NCSDK-25011: Support error handling on nrf54l +#endif + } void nrf_exception_info_store_context(void) diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h index e30baef60..d25689ffe 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h +++ b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h @@ -35,10 +35,20 @@ #include #if RTE_FLASH0 + +#include + +#if defined(NRF_NVMC_S) #define NRFX_NVMC_ENABLED 1 +#elif defined(NRF_RRAMC_S) +#define NRFX_RRAMC_ENABLED 1 +#else +#error "Unrecognized platform" #endif -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 +#endif /* RTE_FLASH0 */ + +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART22 #define NRFX_UARTE_ENABLED 1 #endif #if RTE_USART0 @@ -54,6 +64,11 @@ #define NRFX_UARTE3_ENABLED 1 #endif +// TODO: NCSDK-25009: Moonlight: Make it possible to use different UARTS with TF-M +#if RTE_USART22 +#define NRFX_UARTE22_ENABLED 1 +#endif + /* * For chips with TrustZone support, MDK provides CMSIS-Core peripheral * accessing symbols in two flavors, with secure and non-secure base address @@ -72,6 +87,8 @@ #include #elif defined(NRF91_SERIES) #include +#elif defined(NRF54L15_ENGA_XXAA) + #include #else #error "Unknown device." #endif diff --git a/platform/ext/target/nordic_nrf/common/core/plat_test.c b/platform/ext/target/nordic_nrf/common/core/plat_test.c index e9ea327e5..b653f3d03 100644 --- a/platform/ext/target/nordic_nrf/common/core/plat_test.c +++ b/platform/ext/target/nordic_nrf/common/core/plat_test.c @@ -30,6 +30,14 @@ #include "tfm_spm_log.h" #endif +#ifdef NRF_TIMER10 +#define SECURE_TIMER NRF_TIMER10 +#define NON_SECURE_TIMER NRF_TIMER20 +#else +#define SECURE_TIMER NRF_TIMER0 +#define NON_SECURE_TIMER NRF_TIMER1 +#endif + #define TIMER_RELOAD_VALUE (1*1000*1000) #define TIMER_FREQ_HZ (1000000) @@ -70,27 +78,27 @@ static void timer_event_clear(NRF_TIMER_Type *TIMER) void tfm_plat_test_secure_timer_start(void) { - timer_init(NRF_TIMER0, TIMER_RELOAD_VALUE); - timer_start(NRF_TIMER0); + timer_init(SECURE_TIMER, TIMER_RELOAD_VALUE); + timer_start(SECURE_TIMER); } void tfm_plat_test_secure_timer_clear_intr(void) { - timer_event_clear(NRF_TIMER0); + timer_event_clear(SECURE_TIMER); } void tfm_plat_test_secure_timer_stop(void) { - timer_stop(NRF_TIMER0); + timer_stop(SECURE_TIMER); } void tfm_plat_test_non_secure_timer_start(void) { - timer_init(NRF_TIMER1, TIMER_RELOAD_VALUE); - timer_start(NRF_TIMER1); + timer_init(NON_SECURE_TIMER, TIMER_RELOAD_VALUE); + timer_start(NON_SECURE_TIMER); } void tfm_plat_test_non_secure_timer_stop(void) { - timer_stop(NRF_TIMER1); + timer_stop(NON_SECURE_TIMER); } diff --git a/platform/ext/target/nordic_nrf/common/core/services/src/tfm_platform_hal_ioctl.c b/platform/ext/target/nordic_nrf/common/core/services/src/tfm_platform_hal_ioctl.c index c7a1bcc46..c916f4e2b 100644 --- a/platform/ext/target/nordic_nrf/common/core/services/src/tfm_platform_hal_ioctl.c +++ b/platform/ext/target/nordic_nrf/common/core/services/src/tfm_platform_hal_ioctl.c @@ -76,10 +76,17 @@ tfm_platform_hal_read_service(const psa_invec *in_vec, static bool valid_mcu_select(uint32_t mcu) { switch (mcu) { +#if defined(NRF54L15_ENGA_XXAA) + case NRF_GPIO_PIN_SEL_GPIO: + case NRF_GPIO_PIN_SEL_VPR: + case NRF_GPIO_PIN_SEL_GRTC: + case NRF_GPIO_PIN_SEL_TND: +#else case NRF_GPIO_PIN_SEL_APP: case NRF_GPIO_PIN_SEL_NETWORK: case NRF_GPIO_PIN_SEL_PERIPHERAL: case NRF_GPIO_PIN_SEL_TND: +#endif return true; default: return false; diff --git a/platform/ext/target/nordic_nrf/common/core/startup.h b/platform/ext/target/nordic_nrf/common/core/startup.h index be6a6cb70..8e77c38c2 100644 --- a/platform/ext/target/nordic_nrf/common/core/startup.h +++ b/platform/ext/target/nordic_nrf/common/core/startup.h @@ -35,6 +35,13 @@ __NO_RETURN void SecureFault_Handler(void); void SPU_IRQHandler(void); +void SPU00_IRQHandler(void); +void SPU10_IRQHandler(void); +void SPU20_IRQHandler(void); +void SPU30_IRQHandler(void); + +void CRACEN_IRQHandler(void); + /* * The default irq handler is used as a backup in case of * misconfiguration. diff --git a/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c new file mode 100644 index 000000000..1cbe196ba --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.9.0 startup_ARMCM33.c + * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c + */ + +// TODO: NCSDK-25033: Support interrupt handling in TF-M. The IRQs +// below correspond to nrf53, not nrf54L. + +/* + * Define __VECTOR_TABLE_ATTRIBUTE (which can be provided by cmsis.h) + * before including cmsis.h because TF-M's linker script + * tfm_common_s.ld assumes the vector table section is called .vectors + * while cmsis.h will sometimes (e.g. when cmsis is provided by nrfx) + * default to using the name .isr_vector. + */ +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) + +#include "cmsis.h" +#include "hw_init.h" +#include "startup.h" +#include "exception_info.h" + +__NO_RETURN __attribute__((naked)) void default_tfm_IRQHandler(void) { + EXCEPTION_INFO(); + + __ASM volatile( + "BL default_irq_handler \n" + "B . \n" + ); +} + +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(SWI00_Handler) +DEFAULT_IRQ_HANDLER(SWI01_Handler) +DEFAULT_IRQ_HANDLER(SWI02_Handler) +DEFAULT_IRQ_HANDLER(SWI03_Handler) +DEFAULT_IRQ_HANDLER(MPC00_Handler) +DEFAULT_IRQ_HANDLER(AAR00_CCM00_Handler) +DEFAULT_IRQ_HANDLER(ECB00_Handler) +DEFAULT_IRQ_HANDLER(SERIAL00_Handler) +DEFAULT_IRQ_HANDLER(RRAMC_Handler) +DEFAULT_IRQ_HANDLER(VPR00_Handler) +DEFAULT_IRQ_HANDLER(CTRLAP_Handler) +DEFAULT_IRQ_HANDLER(CM33SS_Handler) +DEFAULT_IRQ_HANDLER(TIMER00_Handler) +DEFAULT_IRQ_HANDLER(TIMER10_Handler) +DEFAULT_IRQ_HANDLER(RTC10_Handler) +DEFAULT_IRQ_HANDLER(EGU10_Handler) +DEFAULT_IRQ_HANDLER(AAR10_CCM10_Handler) +DEFAULT_IRQ_HANDLER(ECB10_Handler) +DEFAULT_IRQ_HANDLER(RADIO_0_Handler) +DEFAULT_IRQ_HANDLER(RADIO_1_Handler) +DEFAULT_IRQ_HANDLER(SERIAL20_Handler) +DEFAULT_IRQ_HANDLER(SERIAL21_Handler) +DEFAULT_IRQ_HANDLER(SERIAL22_Handler) +DEFAULT_IRQ_HANDLER(EGU20_Handler) +DEFAULT_IRQ_HANDLER(TIMER20_Handler) +DEFAULT_IRQ_HANDLER(TIMER21_Handler) +DEFAULT_IRQ_HANDLER(TIMER22_Handler) +DEFAULT_IRQ_HANDLER(TIMER23_Handler) +DEFAULT_IRQ_HANDLER(TIMER24_Handler) +DEFAULT_IRQ_HANDLER(PWM20_Handler) +DEFAULT_IRQ_HANDLER(PWM21_Handler) +DEFAULT_IRQ_HANDLER(PWM22_Handler) +DEFAULT_IRQ_HANDLER(SAADC_Handler) +DEFAULT_IRQ_HANDLER(NFCT_Handler) +DEFAULT_IRQ_HANDLER(TEMP_Handler) +DEFAULT_IRQ_HANDLER(GPIOTE20_0_Handler) +DEFAULT_IRQ_HANDLER(GPIOTE20_1_Handler) +DEFAULT_IRQ_HANDLER(TAMPC_Handler) +DEFAULT_IRQ_HANDLER(I2S20_Handler) +DEFAULT_IRQ_HANDLER(QDEC20_Handler) +DEFAULT_IRQ_HANDLER(QDEC21_Handler) +DEFAULT_IRQ_HANDLER(GRTC_0_Handler) +DEFAULT_IRQ_HANDLER(GRTC_1_Handler) +DEFAULT_IRQ_HANDLER(GRTC_2_Handler) +DEFAULT_IRQ_HANDLER(GRTC_3_Handler) +DEFAULT_IRQ_HANDLER(SERIAL30_Handler) +DEFAULT_IRQ_HANDLER(RTC30_Handler) +DEFAULT_IRQ_HANDLER(COMP_LPCOMP_Handler) +DEFAULT_IRQ_HANDLER(WDT30_Handler) +DEFAULT_IRQ_HANDLER(WDT31_Handler) +DEFAULT_IRQ_HANDLER(GPIOTE30_0_Handler) +DEFAULT_IRQ_HANDLER(GPIOTE30_1_Handler) +DEFAULT_IRQ_HANDLER(CLOCK_POWER_Handler) + +#if defined(DOMAIN_NS) || defined(BL2) +DEFAULT_IRQ_HANDLER(SPU00_Handler) +DEFAULT_IRQ_HANDLER(SPU10_Handler) +DEFAULT_IRQ_HANDLER(SPU20_Handler) +DEFAULT_IRQ_HANDLER(SPU30_Handler) +DEFAULT_IRQ_HANDLER(CRACEN_IRQHandler) +#else +// TODO: Move into the SPU error handling code +DEFAULT_IRQ_HANDLER(SPU00_Handler) +DEFAULT_IRQ_HANDLER(SPU10_Handler) +DEFAULT_IRQ_HANDLER(SPU20_Handler) +DEFAULT_IRQ_HANDLER(SPU30_Handler) +#endif + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { + (VECTOR_TABLE_Type)(&__INITIAL_SP), /* Initial Stack Pointer */ +/* Exceptions */ + Reset_Handler, + NMI_Handler, + HardFault_Handler, + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, + UsageFault_Handler, + SecureFault_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SVC_Handler, + DebugMon_Handler, + default_tfm_IRQHandler, + PendSV_Handler, + SysTick_Handler, +/* Device specific interrupt handlers */ + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SWI00_Handler, + SWI01_Handler, + SWI02_Handler, + SWI03_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SPU00_Handler, + MPC00_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + AAR00_CCM00_Handler, + ECB00_Handler, + CRACEN_IRQHandler, + default_tfm_IRQHandler, + SERIAL00_Handler, + RRAMC_Handler, + VPR00_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + CTRLAP_Handler, + CM33SS_Handler, + default_tfm_IRQHandler, + TIMER00_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SPU10_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + TIMER10_Handler, + RTC10_Handler, + EGU10_Handler, + AAR10_CCM10_Handler, + ECB10_Handler, + RADIO_0_Handler, + RADIO_1_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SPU20_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SERIAL20_Handler, + SERIAL21_Handler, + SERIAL22_Handler, + EGU20_Handler, + TIMER20_Handler, + TIMER21_Handler, + TIMER22_Handler, + TIMER23_Handler, + TIMER24_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + PWM20_Handler, + PWM21_Handler, + PWM22_Handler, + SAADC_Handler, + NFCT_Handler, + TEMP_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + GPIOTE20_0_Handler, + GPIOTE20_1_Handler, + TAMPC_Handler, + I2S20_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + QDEC20_Handler, + QDEC21_Handler, + GRTC_0_Handler, + GRTC_1_Handler, + GRTC_2_Handler, + GRTC_3_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SPU30_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + SERIAL30_Handler, + RTC30_Handler, + COMP_LPCOMP_Handler, + default_tfm_IRQHandler, + WDT30_Handler, + WDT31_Handler, + default_tfm_IRQHandler, + default_tfm_IRQHandler, + GPIOTE30_0_Handler, + GPIOTE30_1_Handler, + CLOCK_POWER_Handler, +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 79185120d..77cb39949 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -20,23 +20,31 @@ #include "region_defs.h" #include "tfm_plat_defs.h" #include "tfm_peripherals_config.h" +#include "utilities.h" #include "region.h" #include "array.h" #include #include -#include -#include + #include #include -#define PIN_XL1 0 -#define PIN_XL2 1 +#ifdef CACHE_PRESENT +#include +#endif -#if !(defined(NRF91_SERIES) || defined(NRF53_SERIES)) -#error "Invalid configuration" +#ifdef NVMC_PRESENT +#include +#include +#endif + +#ifdef MPC_PRESENT +#include #endif +#define PIN_XL1 0 +#define PIN_XL2 1 #if TFM_PERIPHERAL_DCNF_SECURE struct platform_data_t tfm_peripheral_dcnf = { @@ -234,6 +242,13 @@ struct platform_data_t tfm_peripheral_uarte3 = { }; #endif +#if TFM_PERIPHERAL_UARTE22_SECURE +struct platform_data_t tfm_peripheral_uarte22 = { + NRF_UARTE22_S_BASE, + NRF_UARTE22_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_SAADC_SECURE struct platform_data_t tfm_peripheral_saadc = { NRF_SAADC_S_BASE, @@ -637,6 +652,12 @@ enum tfm_plat_err_t init_debug(void) NRF_CTRLAP->SECUREAPPROTECT.LOCK = CTRLAPPERI_SECUREAPPROTECT_LOCK_LOCK_Locked << CTRLAPPERI_SECUREAPPROTECT_LOCK_LOCK_Msk; +#elif defined(NRF54L15_ENGA_XXAA) + // TODO: NCSDK-25047: Support nRF54L +#else + +#error "Unrecognized platform" + #endif return TFM_PLAT_ERR_SUCCESS; @@ -650,8 +671,14 @@ enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void) NVIC->ITNS[i] = 0xFFFFFFFF; } - /* Make sure that the SPU is targeted to S state */ - NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_SPU)); + /* Make sure that the SPU instance(s) are targeted to S state */ + for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { + NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(spu_instances[i])); + } + +#ifdef NRF_CRACEN + NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_CRACEN)); +#endif #ifdef SECURE_UART1 #if NRF_SECURE_UART_INSTANCE == 0 @@ -660,6 +687,9 @@ enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void) #elif NRF_SECURE_UART_INSTANCE == 1 /* UARTE1 is a secure peripheral, so its IRQ has to target S state */ NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE1)); +#elif NRF_SECURE_UART_INSTANCE == 22 + /* UARTE22 is a secure peripheral, so its IRQ has to target S state */ + NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE22)); #endif #endif @@ -672,8 +702,14 @@ enum tfm_plat_err_t nvic_interrupt_enable(void) /* SPU interrupt enabling */ spu_enable_interrupts(); - NVIC_ClearPendingIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPU)); - NVIC_EnableIRQ(NRFX_IRQ_NUMBER_GET(NRF_SPU)); + for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { + NVIC_ClearPendingIRQ(NRFX_IRQ_NUMBER_GET(spu_instances[i])); + NVIC_EnableIRQ(NRFX_IRQ_NUMBER_GET(spu_instances[i])); + } + + /* The CRACEN driver configures the NVIC for CRACEN and is + * therefore omitted here. + */ return TFM_PLAT_ERR_SUCCESS; } @@ -682,13 +718,61 @@ enum tfm_plat_err_t nvic_interrupt_enable(void) void sau_and_idau_cfg(void) { + /* + * SAU and IDAU configuration is very different between old + * (53/91) and new (54++) platforms. New platforms have a proper SAU + * and IDAU, whereas old platforms do not. + */ +#ifdef NRF54L15_ENGA_XXAA + /* + * This SAU configuration aligns with ARM's RSS implementation of + * sau_and_idau_cfg when possible. + */ + + /* Enables SAU */ + TZ_SAU_Enable(); + + /* Configures SAU regions to be non-secure */ + + /* Note that this SAU configuration assumes that there is only one + * secure NVM partition and one non-secure NVM partition. Meaning, + * memory_regions.non_secure_partition_limit is at the end of + * NVM. + */ + + /* Configure the end of NVM, and the FICR, to be non-secure using + a single region. Note that the FICR is placed after the + non-secure NVM and before the UICR.*/ + SAU->RNR = 0; + SAU->RBAR = (memory_regions.non_secure_partition_base + & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (NRF_UICR_S_BASE & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + + /* Leave SAU region 1 disabled until we find a use for it */ + + /* Configures veneers region to be non-secure callable */ + SAU->RNR = 2; + SAU->RBAR = (memory_regions.veneer_base & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk) + | SAU_RLAR_ENABLE_Msk | SAU_RLAR_NSC_Msk; + + /* Configures SAU region 3 to cover both the end of SRAM and + * regions above it as shown in the "Example memory map" in the + * "Product Specification" */ + SAU->RNR = 3; + SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk); + SAU->RLAR = (0xFFFFFFFFul & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk; + +#else /* IDAU (SPU) is always enabled. SAU is non-existent. * Allow SPU to have precedence over (non-existing) ARMv8-M SAU. */ TZ_SAU_Disable(); SAU->CTRL |= SAU_CTRL_ALLNS_Msk; +#endif } +#if NRF_SPU_HAS_MEMORY enum tfm_plat_err_t spu_init_cfg(void) { /* @@ -767,10 +851,221 @@ enum tfm_plat_err_t spu_init_cfg(void) return TFM_PLAT_ERR_SUCCESS; } +#endif /* NRF_SPU_HAS_MEMORY */ + + +#ifdef MPC_PRESENT +struct mpc_region_override { + nrf_mpc_override_config_t config; + nrf_owner_t owner_id; + uintptr_t start_address; + size_t endaddr; + uint32_t perm; + uint32_t permmask; + size_t index; +}; + +static void mpc_configure_override(NRF_MPC_Type *mpc, struct mpc_region_override *override) +{ + nrf_mpc_override_startaddr_set(mpc, override->index, override->start_address); + nrf_mpc_override_endaddr_set(mpc, override->index, override->endaddr); + nrf_mpc_override_perm_set(mpc, override->index, override->perm); + nrf_mpc_override_permmask_set(mpc, override->index, override->permmask); + nrf_mpc_override_ownerid_set(mpc, override->index, override->owner_id); + nrf_mpc_override_config_set(mpc, override->index, &override->config); +} + +/* + * Configure the override struct with reasonable defaults. This includes: + * + * Use a slave number of 0 to avoid redirecting bus transactions from + * one slave to another. + * + * Lock the override to prevent the code that follows from tampering + * with the configuration. + * + * Enable the override so it takes effect. + * + * Indicate that secdom is not enabled as this driver is not used on + * platforms with secdom. + */ +static void init_mpc_region_override(struct mpc_region_override * override) +{ + *override = (struct mpc_region_override){ + .config = + (nrf_mpc_override_config_t){ + .slave_number = 0, + .lock = true, + .enable = true, + .secdom_enable = false, + .secure_mask = true, + }, + .perm = 0, /* 0 for non-secure */ + .owner_id = 1, // TODO: NCSDK-25169: Investigate if 1 is correct + }; + + override->permmask = MPC_OVERRIDE_PERM_SECATTR_Msk; +} + +enum tfm_plat_err_t nrf_mpc_init_cfg(void) +{ + /* On 54l the NRF_MPC00->REGION[]'s are fixed in HW and the + * OVERRIDE indexes (that are useful to us) start at 0 and end + * (inclusive) at 4. + */ + uint32_t index = 0; + + /* Configure the non-secure partition of the non-volatile + * memory. This MPC region is intended to cover both the + * non-secure partition in the NVM and also the FICR. The FICR + * starts after the NVM and ends just before the UICR. + */ + { + struct mpc_region_override override; + + init_mpc_region_override(&override); + + override.start_address = memory_regions.non_secure_partition_base; + override.endaddr = NRF_UICR_S_BASE; + override.index = index++; + + mpc_configure_override(NRF_MPC00, &override); + } + + /* Configure the non-secure partition of the volatile memory */ + { + struct mpc_region_override override; + + init_mpc_region_override(&override); + + override.start_address = NS_DATA_START; + override.endaddr = 1 + NS_DATA_LIMIT; + override.index = index++; + + mpc_configure_override(NRF_MPC00, &override); + } + + if(index > 4) { + /* Used more overrides than are available */ + tfm_core_panic(); + } + + /* TODO: NCSDK-25050: Review configuration. Any other addresses we need to override? */ + + /* Note that we don't configure the NSC region to be NS because it is secure */ + + /* Note that OVERRIDE[n].MASTERPORT has a reasonable reset value + * so it is left unconfigured. + */ + + return TFM_PLAT_ERR_SUCCESS; +} + +#endif /* MPC_PRESENT */ + +static void dppi_channel_configuration(void) +{ + /* The SPU HW and corresponding NRFX HAL API have two different + * API's for DPPI security configuration. The defines + * NRF_SPU_HAS_OWNERSHIP and NRF_SPU_HAS_MEMORY identify which of the two API's + * are present. + * + * TFM_PERIPHERAL_DPPI_CHANNEL_MASK_SECURE is configurable, but + * usually defaults to 0, which results in all DPPI channels being + * non-secure. + */ +#if NRF_SPU_HAS_MEMORY + /* There is only one dppi_id */ + uint8_t dppi_id = 0; + nrf_spu_dppi_config_set(NRF_SPU, dppi_id, TFM_PERIPHERAL_DPPI_CHANNEL_MASK_SECURE, + SPU_LOCK_CONF_LOCKED); +#else + /* TODO_NRF54L15: Use the nrf_spu_feature API to configure DPPI + channels according to a user-controllable config similar to + TFM_PERIPHERAL_DPPI_CHANNEL_MASK_SECURE. */ +#endif +} enum tfm_plat_err_t spu_periph_init_cfg(void) { /* Peripheral configuration */ +#ifdef NRF54L15_ENGA_XXAA + /* Configure features to be non-secure */ + + /* + * Due to MLT-7600, many SPU HW reset values are wrong. The docs + * generally features being non-secure when coming out of HW + * reset, but the HW has a good mix of both. + * + * When configuring NRF_SPU 0 will indicate non-secure and 1 will + * indicate secure. + * + * Most of the chip should be non-secure so to simplify and be + * consistent, we memset the entire memory map of each SPU + * peripheral to 0. + * + * Just after memsetting to 0 we explicitly configure the + * peripherals that should be secure back to secure again. + * + * At the moment we also have some redundant code that is + * configuring things to 0/NonSecure because it is not clear if + * this strategy is safe and we want to keep this code in case we + * need it later. + */ + // TODO: NCSDK-22597: Evaluate if it is safe to memset everything + // in NRF_SPU to 0. + memset(NRF_SPU00, 0, sizeof(NRF_SPU_Type)); + memset(NRF_SPU10, 0, sizeof(NRF_SPU_Type)); + memset(NRF_SPU20, 0, sizeof(NRF_SPU_Type)); + memset(NRF_SPU30, 0, sizeof(NRF_SPU_Type)); + + /* Configure peripherals to be non-secure */ + for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { + NRF_SPU_Type * spu_instance = spu_instances[i]; + + /* Configure all pins as non-secure */ + bool spu_has_GPIO = i != 1; + if(spu_has_GPIO) { + for(int j = 0; j < ARRAY_SIZE(spu_instance->FEATURE.GPIO); j++) { + for(int pin = 0; pin < 32; pin++) { + spu_instance->FEATURE.GPIO[j].PIN[pin] = 0; + } + } + } + + /* TODO: NCSDK-22597: Configure UART22 pins as secure */ + + for(uint8_t index = 0; index < ARRAY_SIZE(spu_instance->PERIPH); index++) { + if(!nrf_spu_periph_perm_present_get(spu_instance, index)) { + /* Peripheral is not present, nothing to configure */ + continue; + } + + nrf_spu_securemapping_t securemapping = nrf_spu_periph_perm_securemapping_get(spu_instance, index); + + bool secattr_has_effect = + securemapping == NRF_SPU_SECUREMAPPING_USERSELECTABLE || + securemapping == NRF_SPU_SECUREMAPPING_SPLIT; + + if(secattr_has_effect) { + bool enable = false; /* false means non-secure */ + + nrf_spu_periph_perm_secattr_set(spu_instance, index, enable); + } + + /* Note that we don't configure dmasec because it has no effect when secattr is non-secure */ + + /* nrf_spu_periph_perm_lock_enable TODO: NCSDK-25009: Lock it down without breaking TF-M UART */ + } + } + + /* Configure TF-M's UART22 peripheral to be secure with secure DMA */ + bool enable = true; /* true means secure */ + uint32_t UART22_SLAVE_INDEX = (NRF_UARTE22_S_BASE & 0x0003F000) >> 12; + nrf_spu_periph_perm_secattr_set(NRF_SPU20, UART22_SLAVE_INDEX, enable); + nrf_spu_periph_perm_dmasec_set(NRF_SPU20, UART22_SLAVE_INDEX, enable); + +#else static const uint8_t target_peripherals[] = { /* The following peripherals share ID: * - FPU (FPU cannot be configured in NRF91 series, it's always NS) @@ -811,6 +1106,11 @@ static const uint8_t target_peripherals[] = { #endif NRFX_PERIPHERAL_ID_GET(NRF_SPIM2), NRFX_PERIPHERAL_ID_GET(NRF_SPIM3), + /* When UART22 is a secure peripheral we need to leave Serial-Box 22 as Secure */ +#if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 22) + // TODO: NCSDK-25009: spu_peripheral_config_non_secure((uint32_t)NRF_SPIM22, false); +#endif + #ifdef NRF_SPIM4 NRFX_PERIPHERAL_ID_GET(NRF_SPIM4), #endif @@ -901,13 +1201,21 @@ static const uint8_t target_peripherals[] = { spu_peripheral_config_non_secure(target_peripherals[i], SPU_LOCK_CONF_UNLOCKED); } +#endif /* Moonlight */ + /* DPPI channel configuration */ - spu_dppi_config_non_secure(TFM_PERIPHERAL_DPPI_CHANNEL_MASK_SECURE, SPU_LOCK_CONF_LOCKED); + dppi_channel_configuration(); /* GPIO pin configuration */ - spu_gpio_config_non_secure(0, TFM_PERIPHERAL_GPIO0_PIN_MASK_SECURE, SPU_LOCK_CONF_LOCKED); +#ifdef NRF_SPU + + nrf_spu_gpio_config_set(NRF_SPU, 0, TFM_PERIPHERAL_GPIO0_PIN_MASK_SECURE, SPU_LOCK_CONF_LOCKED); #ifdef TFM_PERIPHERAL_GPIO1_PIN_MASK_SECURE - spu_gpio_config_non_secure(1, TFM_PERIPHERAL_GPIO1_PIN_MASK_SECURE, SPU_LOCK_CONF_LOCKED); + nrf_spu_gpio_config_set(NRF_SPU, 1, TFM_PERIPHERAL_GPIO1_PIN_MASK_SECURE, SPU_LOCK_CONF_LOCKED); +#endif + +#else + /* TODO: NCSDK-22597: Support configuring pins as secure or non-secure on nrf54L */ #endif #ifdef NRF53_SERIES @@ -933,9 +1241,20 @@ static const uint8_t target_peripherals[] = { #if defined(NVMC_FEATURE_CACHE_PRESENT) // From MDK nrfx_nvmc_icache_enable(); #elif defined(CACHE_PRESENT) // From MDK - NRF_CACHE->ENABLE = CACHE_ENABLE_ENABLE_Enabled; + +#ifdef NRF_CACHE + nrf_cache_enable(NRF_CACHE); +#endif +#ifdef NRF_ICACHE + nrf_cache_enable(NRF_ICACHE); +#endif +#ifdef NRF_DCACHE + nrf_cache_enable(NRF_DCACHE); +#endif + #endif +#if NRF_SPU_HAS_MEMORY /* Enforce that the nRF5340 Network MCU is in the Non-Secure * domain. Non-secure is the HW reset value for the network core * so configuring this should not be necessary, but we want to @@ -944,6 +1263,9 @@ static const uint8_t target_peripherals[] = { * it doesn't get changed by accident. */ nrf_spu_extdomain_set(NRF_SPU, 0, false, true); +#else + /* TODO: NCSDK-22597: Configure VPR to be non-secure on nrf54L */ +#endif return TFM_PLAT_ERR_SUCCESS; } diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h index 356f1b794..1680abb0b 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -35,12 +35,21 @@ #include "tfm_plat_defs.h" #include "region_defs.h" +// TODO: NCSDK-25009: Support configuring which UART is used by TF-M on nrf54L + #if NRF_SECURE_UART_INSTANCE == 0 #define TFM_DRIVER_STDIO Driver_USART0 #elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_DRIVER_STDIO Driver_USART1 +#elif NRF_SECURE_UART_INSTANCE == 22 +#define TFM_DRIVER_STDIO Driver_USART22 #endif + +#ifdef NRF54L15_ENGA_XXAA +#define NS_DRIVER_STDIO Driver_USART22 +#else #define NS_DRIVER_STDIO Driver_USART0 +#endif /** * \brief Store the addresses of memory regions @@ -96,6 +105,13 @@ enum tfm_plat_err_t spu_periph_init_cfg(void); */ void spu_clear_irq(void); +/** + * \brief Configures memory permissions via the MPC. + * + * \return Returns values as specified by the \ref tfm_plat_err_t + */ +enum tfm_plat_err_t nrf_mpc_init_cfg(void); + /** * \brief Configures SAU and IDAU. */ diff --git a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c index 32a58458f..a2bc0b4d3 100644 --- a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c +++ b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c @@ -50,9 +50,16 @@ enum tfm_hal_status_t tfm_hal_set_up_static_boundaries( /* Set up isolation boundaries between SPE and NSPE */ sau_and_idau_cfg(); +#if NRF_SPU_HAS_MEMORY if (spu_init_cfg() != TFM_PLAT_ERR_SUCCESS) { return TFM_HAL_ERROR_GENERIC; } +#else + /* If the SPU doesn't configure MEMORY on this platform then the NRF_MPC does */ + if (nrf_mpc_init_cfg() != TFM_PLAT_ERR_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } +#endif if (spu_periph_init_cfg() != TFM_PLAT_ERR_SUCCESS) { return TFM_HAL_ERROR_GENERIC; @@ -124,8 +131,12 @@ tfm_hal_bind_boundary(const struct partition_load_info_t *p_ldinf, continue; } +#ifdef NRF_SPU spu_peripheral_config_secure(NRFX_PERIPHERAL_ID_GET(plat_data_ptr->periph_start), SPU_LOCK_CONF_LOCKED); +#else + // TODO: NCSDK-22597: Support configuring peripherals as secure +#endif /* * Static boundaries are set. Set up MPU region for MMIO. From 2a2e1ce5e80fa3893a7747728003552bf6cfef55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 7 Mar 2024 11:53:05 +0100 Subject: [PATCH 24/65] [nrf noup] cmake: tools: Dont add a custom command for running the manifest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit is [nrf noup] because I would like to user-test this for a few months in case of unintended side-effects before upstreaming. In the TF-M build scripts we run the manifest tool twice, first from CMake and then from ninja. It is bad practice to configure CMake projects like this. Instead, if configuration from CMake is necessary, one should configure from CMake only, and then re-run CMake when necessary, not just the command. This organization has been causing problems for our users as they have been required to rebuild TF-M twice. This is due to this scenario playing out: CMake generates config_impl.cmake by invoking the manifest tool at Configure time. CMake generates build.ninja. Ninja generates config_impl.cmake by invoking the manifest tool at build time. When the user then invokes ninja a second time config_impl.cmake will be newer than build.ninja. But CMake is supposed to be includ'ing config_impl.cmake, so build.ninja is now considered out-of-date wrt. config_impl.cmake. ninja therefore invokes CMake again, and then ninja afterwards. Signed-off-by: Sebastian Bøe Change-Id: Icef588479d27fa3a172b40b09eacad417922fba5 --- tools/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8389b85f5..e34469fe7 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -159,12 +159,17 @@ set(MANIFEST_COMMAND -o ${CMAKE_BINARY_DIR}/generated ${PARSE_MANIFEST_QUIET_FLAG}) +set(NO_BUILD_CMD_FOR_MANIFEST 1) + +if(NO_BUILD_CMD_FOR_MANIFEST) +else() add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/generated COMMAND ${MANIFEST_COMMAND} DEPENDS ${MANIFEST_LISTS} ${GENERATED_FILE_LISTS} ${MANIFEST_FILES} ${TEMPLATE_FILES} ) +endif() add_custom_target( manifest_tool From d824e9483ba22a628e7c0a715fa6115103de9bc7 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Thu, 29 Feb 2024 13:31:10 +0100 Subject: [PATCH 25/65] [nrf noup] crypto: Add PAKE support This is noup commit as upstream TF-M relies on the mbed TLS PSA Core hat does not support the PAKE API's according to 1.2 at the moment. Once this exists then this can be up streamed, or removed if TF-M adds it themself. Added PAKE API support accoding the PSA crypto spec 1.2 Ref: NCSDK-22416 Change-Id: Ie3254db411e21b0d9408ca1c81f74917be2e632f Signed-off-by: Markus Swarowsky --- interface/include/psa/crypto_extra.h | 1359 +++++++++++++++++ interface/include/psa/crypto_sizes.h | 62 + interface/include/psa/crypto_struct.h | 24 + interface/include/psa/crypto_types.h | 47 + interface/include/psa/crypto_values.h | 37 + interface/include/tfm_crypto_defs.h | 21 + interface/src/tfm_crypto_api.c | 156 ++ secure_fw/partitions/crypto/CMakeLists.txt | 1 + secure_fw/partitions/crypto/Kconfig.comp | 4 + .../partitions/crypto/crypto_check_config.h | 10 + secure_fw/partitions/crypto/crypto_init.c | 2 + secure_fw/partitions/crypto/crypto_pake.c | 171 +++ secure_fw/partitions/crypto/crypto_spe.h | 18 + secure_fw/partitions/crypto/tfm_crypto_api.h | 14 + 14 files changed, 1926 insertions(+) create mode 100644 secure_fw/partitions/crypto/crypto_pake.c diff --git a/interface/include/psa/crypto_extra.h b/interface/include/psa/crypto_extra.h index 2dd559019..6709b7b10 100644 --- a/interface/include/psa/crypto_extra.h +++ b/interface/include/psa/crypto_extra.h @@ -127,6 +127,1365 @@ void psa_set_key_enrollment_algorithm( psa_algorithm_t psa_get_key_enrollment_algorithm( const psa_key_attributes_t *attributes); + +#define PSA_KEY_TYPE_SPAKE2P_KEY_PAIR_BASE ((psa_key_type_t) 0x7400) +#define PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4400) +#define PSA_KEY_TYPE_SPAKE2P_CURVE_MASK ((psa_key_type_t) 0x00ff) + + /** SPAKE2+ key pair. Both the prover and verifier key. + * + * The size of a SPAKE2+ key is the size associated with the elliptic curve + * group. See the documentation of each elliptic curve family for details. + * To construct a SPAKE2+ key pair, it must be output from a key derivation + * operation. + * The corresponding public key can be exported using psa_export_public_key(). + * See also #PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(). + * + * \param curve A value of type psa_ecc_family_t that identifies the elliptic + * curve family to be used. + */ +#define PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(curve) \ + ((psa_key_type_t) (PSA_KEY_TYPE_SPAKE2P_KEY_PAIR_BASE | (curve))) + + /** SPAKE2+ public key. The verifier key. + * + * The size of an SPAKE2+ public key is the same as the corresponding private + * key. See #PSA_KEY_TYPE_SPAKE2P_KEY_PAIR() and the documentation of each + * elliptic curve family for details. + * To construct a SPAKE2+ public key, it must be imported. + * + * \param curve A value of type psa_ecc_family_t that identifies the elliptic + * curve family to be used. + */ +#define PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(curve) \ + ((psa_key_type_t) (PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE | (curve))) + + /** Whether a key type is a SPAKE2+ key (pair or public-only). */ +#define PSA_KEY_TYPE_IS_SPAKE2P(type) \ + ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \ + ~PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) == \ + PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE) + /** Whether a key type is a SPAKE2+ key pair. */ +#define PSA_KEY_TYPE_IS_SPAKE2P_KEY_PAIR(type) \ + (((type) & ~PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) == \ + PSA_KEY_TYPE_SPAKE2P_KEY_PAIR_BASE) + /** Whether a key type is a SPAKE2+ public key. */ +#define PSA_KEY_TYPE_IS_SPAKE2P_PUBLIC_KEY(type) \ + (((type) & ~PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) == \ + PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE) + /** Extract the curve from a SPAKE2+ key type. */ +#define PSA_KEY_TYPE_SPAKE2P_GET_FAMILY(type) \ + ((psa_ecc_family_t) (PSA_KEY_TYPE_IS_SPAKE2P(type) ? \ + ((type) & PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) : \ + 0)) + +#define PSA_KEY_TYPE_SRP_KEY_PAIR_BASE ((psa_key_type_t) 0x7700) +#define PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4700) +#define PSA_KEY_TYPE_SRP_GROUP_MASK ((psa_key_type_t) 0x00ff) + + /** SRP key pair. Both the client and server key. + * + * The size of a SRP key is the size associated with the Diffie-Hellman + * group. See the documentation of each Diffie-Hellman group for details. + * To construct a SRP key pair, the password hash must be imported. + * The corresponding public key (password verifier) can be exported using + * psa_export_public_key(). See also #PSA_KEY_TYPE_SRP_PUBLIC_KEY(). + * + * \param group A value of type ::psa_dh_family_t that identifies the + * Diffie-Hellman group to be used. + */ +#define PSA_KEY_TYPE_SRP_KEY_PAIR(group) \ + ((psa_key_type_t) (PSA_KEY_TYPE_SRP_KEY_PAIR_BASE | (group))) + + /** SRP public key. The server key (password verifier). + * + * The size of an SRP public key is the same as the corresponding private + * key. See #PSA_KEY_TYPE_SRP_KEY_PAIR() and the documentation of each + * Diffie-Hellman group for details. + * To construct a SRP public key, it must be imported. The key size + * in attributes must not be zero. + * + * \param group A value of type ::psa_dh_family_t that identifies the + * Diffie-Hellman group to be used. + */ +#define PSA_KEY_TYPE_SRP_PUBLIC_KEY(group) \ + ((psa_key_type_t) (PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE | (group))) + + /** Whether a key type is a SRP key (pair or public-only). */ +#define PSA_KEY_TYPE_IS_SRP(type) \ + ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \ + ~PSA_KEY_TYPE_SRP_GROUP_MASK) == \ + PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE) + /** Whether a key type is a SRP key pair. */ +#define PSA_KEY_TYPE_IS_SRP_KEY_PAIR(type) \ + (((type) & ~PSA_KEY_TYPE_SRP_GROUP_MASK) == \ + PSA_KEY_TYPE_SRP_KEY_PAIR_BASE) + /** Whether a key type is a SRP public key. */ +#define PSA_KEY_TYPE_IS_SRP_PUBLIC_KEY(type) \ + (((type) & ~PSA_KEY_TYPE_SRP_GROUP_MASK) == \ + PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE) + /** Extract the curve from a SRP key type. */ +#define PSA_KEY_TYPE_SRP_GET_FAMILY(type) \ + ((psa_ecc_family_t) (PSA_KEY_TYPE_IS_SRP(type) ? \ + ((type) & PSA_KEY_TYPE_SRP_GROUP_MASK) : \ + 0)) + +#define PSA_ALG_CATEGORY_PAKE ((psa_algorithm_t) 0x0a000000) + +/** Whether the specified algorithm is a password-authenticated key exchange. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a password-authenticated key exchange (PAKE) + * algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_PAKE(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_PAKE) + +/** The Password-authenticated key exchange by juggling (J-PAKE) algorithm. + * + * This is J-PAKE as defined by RFC 8236, instantiated with the following + * parameters: + * + * - The group can be either an elliptic curve or defined over a finite field. + * - Schnorr NIZK proof as defined by RFC 8235 and using the same group as the + * J-PAKE algorithm. + * - A cryptographic hash function. + * + * To select these parameters and set up the cipher suite, call these functions + * in any order: + * + * \code + * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_JPAKE(hash)); + * psa_pake_cs_set_primitive(cipher_suite, + * PSA_PAKE_PRIMITIVE(type, family, bits)); + * \endcode + * + * For more information on how to set a specific curve or field, refer to the + * documentation of the individual \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants. + * + * After initializing a J-PAKE operation, call + * + * \code + * psa_pake_setup(operation, key, cipher_suite); + * psa_pake_set_user(operation, ...); + * psa_pake_set_peer(operation, ...); + * \endcode + * + * The password is provided as a key. This can be the password text itself, + * in an agreed character encoding, or some value derived from the password + * as required by a higher level protocol. + * + * (The implementation converts the key material to a number as described in + * Section 2.3.8 of _SEC 1: Elliptic Curve Cryptography_ + * (https://www.secg.org/sec1-v2.pdf), before reducing it modulo \c q. Here + * \c q is order of the group defined by the primitive set in the cipher suite. + * The \c psa_pake_setup() function returns an error if the result of the + * reduction is 0.) + * + * The key exchange flow for J-PAKE is as follows: + * -# To get the first round data that needs to be sent to the peer, call + * \code + * // Get g1 + * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // Get the ZKP public key for x1 + * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); + * // Get the ZKP proof for x1 + * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); + * // Get g2 + * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // Get the ZKP public key for x2 + * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); + * // Get the ZKP proof for x2 + * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); + * \endcode + * -# To provide the first round data received from the peer to the operation, + * call + * \code + * // Set g3 + * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // Set the ZKP public key for x3 + * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); + * // Set the ZKP proof for x3 + * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); + * // Set g4 + * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // Set the ZKP public key for x4 + * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); + * // Set the ZKP proof for x4 + * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); + * \endcode + * -# To get the second round data that needs to be sent to the peer, call + * \code + * // Get A + * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // Get ZKP public key for x2*s + * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); + * // Get ZKP proof for x2*s + * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); + * \endcode + * -# To provide the second round data received from the peer to the operation, + * call + * \code + * // Set B + * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // Set ZKP public key for x4*s + * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...); + * // Set ZKP proof for x4*s + * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...); + * \endcode + * -# To access the shared secret call + * \code + * // Get Ka=Kb=K + * psa_pake_get_shared_key() + * \endcode + * + * For more information consult the documentation of the individual + * \c PSA_PAKE_STEP_XXX constants. + * + * At this point there is a cryptographic guarantee that only the authenticated + * party who used the same password is able to compute the key. But there is no + * guarantee that the peer is the party it claims to be and was able to do so. + * + * That is, the authentication is only implicit (the peer is not authenticated + * at this point, and no action should be taken that assume that they are - like + * for example accessing restricted files). + * + * To make the authentication explicit there are various methods, see Section 5 + * of RFC 8236 for two examples. + * + */ +#define PSA_ALG_JPAKE_BASE ((psa_algorithm_t) 0x0a000100) +#define PSA_ALG_JPAKE(hash_alg) (PSA_ALG_JPAKE_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_IS_JPAKE(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_JPAKE_BASE) + + /** The SPAKE2+ algorithm. + * + * SPAKE2+ is the augmented password-authenticated key exchange protocol, + * defined by RFC9383. SPAKE2+ includes confirmation of the shared secret + * key that results from the key exchange. + * SPAKE2+ is required by Matter Specification, Version 1.2, as MATTER_PAKE. + * Matter uses an earlier draft of the SPAKE2+ protocol: "SPAKE2+, an + * Augmented PAKE (Draft 02)". + * Although the operation of the PAKE is similar for both of these variants, + * they have different key schedules for the derivation of the shared secret. + * + * When setting up a PAKE cipher suite to use the SPAKE2+ protocol defined + * in RFC9383: + * - For cipher-suites that use HMAC for key confirmation, use the + * PSA_ALG_SPAKE2P_HMAC() algorithm, parameterized by the required hash + * algorithm. + * - For cipher-suites that use CMAC-AES-128 for key confirmation, use the + * PSA_ALG_SPAKE2P_CMAC() algorithm, parameterized by the required hash + * algorithm. + * - Use a PAKE primitive for the required elliptic curve. + * + * For example, the following code creates a cipher suite to select SPAKE2+ + * using edwards25519 with the SHA-256 hash function: + * + * \code + * psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; + * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_SPAKE2P_HMAC(PSA_ALG_SHA_256)); + * psa_pake_cs_set_primitive(&cipher_suite, + * PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, + * PSA_ECC_FAMILY_TWISTED_EDWARDS, 255)); + * \endcode + * + * When setting up a PAKE cipher suite to use the SPAKE2+ protocol used by + * Matter: + * - Use the PSA_ALG_SPAKE2P_MATTER algorithm. + * - Use the PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, + * PSA_ECC_FAMILY_SECP_R1, 256) + * PAKE primitive. + * + * The following code creates a cipher suite to select the Matter variant of + * SPAKE2+: + * + * \code + * psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; + * psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_SPAKE2P_MATTER); + * psa_pake_cs_set_primitive(&cipher_suite, + * PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, + * PSA_ECC_FAMILY_SECP_R1, 256)); + * \endcode + * + * After initializing a SPAKE2+ operation, call + * + * \code + * psa_pake_setup(operation, password, cipher_suite); + * psa_pake_set_role(operation, ...); + * \endcode + * + * The password provided to the client side must be of type + * #PSA_KEY_TYPE_SPAKE2P_KEY_PAIR. + * The password provided to the server side must be of type + * #PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY. + * + * The role set by \c psa_pake_set_role() must be either + * \c PSA_PAKE_ROLE_CLIENT or \c PSA_PAKE_ROLE_SERVER. + * + * Then provide any additional, optional parameters: + * + * \code + * psa_pake_set_user(operation, ...); + * psa_pake_set_peer(operation, ...); + * psa_pake_set_context(operation, ...); + * \endcode + * + * + * The key exchange flow for a SPAKE2+ client is as follows: + * \code + * // send shareP + * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // receive shareV + * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // receive confirmV + * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // send confirmP + * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // get K_shared + * psa_pake_get_shared_key(operation, ...); + * \endcode + * + * The key exchange flow for a SPAKE2+ server is as follows: + * \code + * // receive shareP + * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // send shareV + * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // send confirmV + * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // receive confirmP + * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // get K_shared + * psa_pake_get_shared_key(operation, ...); + * \endcode + * + * The shared secret that is produced by SPAKE2+ is pseudorandom. Although + * it can be used directly as an encryption key, it is recommended to use + * the shared secret as an input to a key derivation operation to produce + * additional cryptographic keys. + */ +#define PSA_ALG_IS_SPAKE2P_HMAC_BASE ((psa_algorithm_t) 0x0a000400) +#define PSA_ALG_SPAKE2P_HMAC(hash_alg) (PSA_ALG_IS_SPAKE2P_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_IS_SPAKE2P_CMAC_BASE ((psa_algorithm_t) 0x0a000500) +#define PSA_ALG_SPAKE2P_CMAC(hash_alg) (PSA_ALG_IS_SPAKE2P_CMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_SPAKE2P_MATTER ((psa_algorithm_t) 0x0A000609) +#define PSA_ALG_IS_SPAKE2P(alg) (((alg) & ~0x000003ff) == PSA_ALG_IS_SPAKE2P_HMAC_BASE) +#define PSA_ALG_IS_SPAKE2P_HMAC(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_IS_SPAKE2P_HMAC_BASE) +#define PSA_ALG_IS_SPAKE2P_CMAC(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_IS_SPAKE2P_CMAC_BASE) + + /** The Secure Remote Passwort key exchange (SRP) algorithm. + * + * This is SRP-6 as defined by RFC 2945 and RFC 5054, instantiated with the + * following parameters: + * + * - The group is defined over a finite field using a secure prime. + * - A cryptographic hash function. + * + * To select these parameters and set up the cipher suite, call these functions: + * + * \code + * psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; + * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_SRP_6(hash)); + * psa_pake_cs_set_primitive(&cipher_suite, + * PSA_PAKE_PRIMITIVE(type, family, bits)); + * \endcode + * + * After initializing a SRP operation, call: + * + * \code + * psa_pake_setup(operation, password, cipher_suite); + * psa_pake_set_role(operation, ...); + * psa_pake_set_user(operation, ...); + * \endcode + * + * The password provided to the client side must be of type + * #PSA_KEY_TYPE_SRP_KEY_PAIR. + * The password provided to the server side must be of type + * #PSA_KEY_TYPE_SRP_PUBLIC_KEY. + * + * The role set by \c psa_pake_set_role() must be either + * \c PSA_PAKE_ROLE_CLIENT or \c PSA_PAKE_ROLE_SERVER. + * + * For the SRP client key exchange call the following functions in any order: + * \code + * // get salt + * psa_pake_input(operation, #PSA_PAKE_STEP_SALT, ...); + * // get server key + * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // write client key + * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * \endcode + * + * For the SRP server key exchange call the following functions in any order: + * \code + * // get salt + * psa_pake_input(operation, #PSA_PAKE_STEP_SALT, ...); + * // get client key + * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * // write server key + * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...); + * \endcode + * + * For the client proof phase call the following functions in this order: + * \code + * // send M1 + * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // receive M2 + * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // Get secret + * psa_pake_get_shared_key() + * \endcode + * + * For the server proof phase call the following functions in this order: + * \code + * // receive M1 + * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // send M2 + * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...); + * // Get secret + * psa_pake_get_shared_key() + * \endcode + * + * The shared secret that is produced by SRP is pseudorandom. Although + * it can be used directly as an encryption key, it is recommended to use + * the shared secret as an input to a key derivation operation to produce + * additional cryptographic keys. + */ +#define PSA_ALG_SRP_6_BASE ((psa_algorithm_t) 0x0a000300) +#define PSA_ALG_SRP_6(hash_alg) (PSA_ALG_SRP_6_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_IS_SRP_6(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_SRP_6_BASE) + +/** @} */ + +/** \defgroup pake Password-authenticated key exchange (PAKE) + * + * This is a proposed PAKE interface for the PSA Crypto API. It is not part of + * the official PSA Crypto API yet. + * + * \note The content of this section is not part of the stable API and ABI + * of Mbed TLS and may change arbitrarily from version to version. + * Same holds for the corresponding macros #PSA_ALG_CATEGORY_PAKE and + * #PSA_ALG_JPAKE. + * @{ + */ + +/** A value to indicate no role in a PAKE algorithm. + * This value can be used in a call to psa_pake_set_role() for symmetric PAKE + * algorithms which do not assign roles. + */ +#define PSA_PAKE_ROLE_NONE ((psa_pake_role_t) 0x00) + +/** The first peer in a balanced PAKE. + * + * Although balanced PAKE algorithms are symmetric, some of them need an + * ordering of peers for the transcript calculations. If the algorithm does not + * need this, both #PSA_PAKE_ROLE_FIRST and #PSA_PAKE_ROLE_SECOND are + * accepted. + */ +#define PSA_PAKE_ROLE_FIRST ((psa_pake_role_t) 0x01) + +/** The second peer in a balanced PAKE. + * + * Although balanced PAKE algorithms are symmetric, some of them need an + * ordering of peers for the transcript calculations. If the algorithm does not + * need this, either #PSA_PAKE_ROLE_FIRST or #PSA_PAKE_ROLE_SECOND are + * accepted. + */ +#define PSA_PAKE_ROLE_SECOND ((psa_pake_role_t) 0x02) + +/** The client in an augmented PAKE. + * + * Augmented PAKE algorithms need to differentiate between client and server. + */ +#define PSA_PAKE_ROLE_CLIENT ((psa_pake_role_t) 0x11) + +/** The server in an augmented PAKE. + * + * Augmented PAKE algorithms need to differentiate between client and server. + */ +#define PSA_PAKE_ROLE_SERVER ((psa_pake_role_t) 0x12) + +/** The PAKE primitive type indicating the use of elliptic curves. + * + * The values of the \c family and \c bits fields of the cipher suite identify a + * specific elliptic curve, using the same mapping that is used for ECC + * (::psa_ecc_family_t) keys. + * + * (Here \c family means the value returned by PSA_PAKE_PRIMITIVE_GET_FAMILY() and + * \c bits means the value returned by PSA_PAKE_PRIMITIVE_GET_BITS().) + * + * Input and output during the operation can involve group elements and scalar + * values: + * -# The format for group elements is the same as for public keys on the + * specific curve would be. For more information, consult the documentation of + * psa_export_public_key(). + * -# The format for scalars is the same as for private keys on the specific + * curve would be. For more information, consult the documentation of + * psa_export_key(). + */ +#define PSA_PAKE_PRIMITIVE_TYPE_ECC ((psa_pake_primitive_type_t) 0x01) + +/** The PAKE primitive type indicating the use of Diffie-Hellman groups. + * + * The values of the \c family and \c bits fields of the cipher suite identify + * a specific Diffie-Hellman group, using the same mapping that is used for + * Diffie-Hellman (::psa_dh_family_t) keys. + * + * (Here \c family means the value returned by PSA_PAKE_PRIMITIVE_GET_FAMILY() and + * \c bits means the value returned by PSA_PAKE_PRIMITIVE_GET_BITS().) + * + * Input and output during the operation can involve group elements and scalar + * values: + * -# The format for group elements is the same as for public keys on the + * specific group would be. For more information, consult the documentation of + * psa_export_public_key(). + * -# The format for scalars is the same as for private keys on the specific + * group would be. For more information, consult the documentation of + * psa_export_key(). + */ +#define PSA_PAKE_PRIMITIVE_TYPE_DH ((psa_pake_primitive_type_t) 0x02) + +/** Construct a PAKE primitive from type, family and bit-size. + * + * \param pake_type The type of the primitive + * (value of type ::psa_pake_primitive_type_t). + * \param pake_family The family of the primitive + * (the type and interpretation of this parameter depends + * on \p pake_type, for more information consult the + * documentation of individual ::psa_pake_primitive_type_t + * constants). + * \param pake_bits The bit-size of the primitive + * (Value of type \c size_t. The interpretation + * of this parameter depends on \p pake_family, for more + * information consult the documentation of individual + * ::psa_pake_primitive_type_t constants). + * + * \return The constructed primitive value of type ::psa_pake_primitive_t. + * Return 0 if the requested primitive can't be encoded as + * ::psa_pake_primitive_t. + */ +#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \ + (((pake_bits & 0xFFFF) != pake_bits) ? 0 : \ + ((psa_pake_primitive_t) (((pake_type) << 24 | \ + (pake_family) << 16) | (pake_bits)))) + +#define PSA_PAKE_PRIMITIVE_GET_BITS(pake_primitive) \ + ((size_t)(pake_primitive & 0xFFFF)) + +#define PSA_PAKE_PRIMITIVE_GET_FAMILY(pake_primitive) \ + ((psa_pake_family_t)((pake_primitive >> 16) & 0xFF)) + +#define PSA_PAKE_PRIMITIVE_GET_TYPE(pake_primitive) \ + ((psa_pake_primitive_type_t)((pake_primitive >> 24) & 0xFF)) + +/** A key confirmation value that indicates a confirmed key in a PAKE cipher + * suite. + * + * This key confirmation value will result in the PAKE algorithm exchanging + * data to verify that the shared key is identical for both parties. This is + * the default key confirmation value in an initialized PAKE cipher suite + * object. + * Some algorithms do not include confirmation of the shared key. + */ +#define PSA_PAKE_CONFIRMED_KEY 0 + +/** A key confirmation value that indicates an unconfirmed key in a PAKE cipher + * suite. + * + * This key confirmation value will result in the PAKE algorithm terminating + * prior to confirming that the resulting shared key is identical for both + * parties. + * Some algorithms do not support returning an unconfirmed shared key. + */ +#define PSA_PAKE_UNCONFIRMED_KEY 1 + + /** The key share being sent to or received from the peer. + * + * The format for both input and output at this step is the same as for public + * keys on the group determined by the primitive (::psa_pake_primitive_t) would + * be. + * + * For more information on the format, consult the documentation of + * psa_export_public_key(). + * + * For information regarding how the group is determined, consult the + * documentation #PSA_PAKE_PRIMITIVE. + */ +#define PSA_PAKE_STEP_KEY_SHARE ((psa_pake_step_t) 0x01) + +/** A Schnorr NIZKP public key. + * + * This is the ephemeral public key in the Schnorr Non-Interactive + * Zero-Knowledge Proof (the value denoted by the letter 'V' in RFC 8235). + * + * The format for both input and output at this step is the same as for public + * keys on the group determined by the primitive (::psa_pake_primitive_t) would + * be. + * + * For more information on the format, consult the documentation of + * psa_export_public_key(). + * + * For information regarding how the group is determined, consult the + * documentation #PSA_PAKE_PRIMITIVE. + */ +#define PSA_PAKE_STEP_ZK_PUBLIC ((psa_pake_step_t) 0x02) + +/** A Schnorr NIZKP proof. + * + * This is the proof in the Schnorr Non-Interactive Zero-Knowledge Proof (the + * value denoted by the letter 'r' in RFC 8235). + * + * Both for input and output, the value at this step is an integer less than + * the order of the group selected in the cipher suite. The format depends on + * the group as well: + * + * - For Montgomery curves, the encoding is little endian. + * - For everything else the encoding is big endian (see Section 2.3.8 of + * _SEC 1: Elliptic Curve Cryptography_ at https://www.secg.org/sec1-v2.pdf). + * + * In both cases leading zeroes are allowed as long as the length in bytes does + * not exceed the byte length of the group order. + * + * For information regarding how the group is determined, consult the + * documentation #PSA_PAKE_PRIMITIVE. + */ +#define PSA_PAKE_STEP_ZK_PROOF ((psa_pake_step_t) 0x03) + +/** The key confirmation value. + * + * This value is used during the key confirmation phase of a PAKE protocol. + * The format of the value depends on the algorithm and cipher suite: + * + * For SPAKE2+ algorithms, the format for both input and output at this step is + * the same as the output of the MAC algorithm specified in the cipher suite. + * + * For PSA_ALG_SRP_6, the format for both input and output at this step is + * the same as the output of the Hash algorithm specified. + */ +#define PSA_PAKE_STEP_CONFIRM ((psa_pake_step_t)0x04) + +/** The salt. + * + * The format for both input and output at this step is plain binary data. + */ +#define PSA_PAKE_STEP_SALT ((psa_pake_step_t)0x05) + +/** Retrieve the PAKE algorithm from a PAKE cipher suite. + * + * \param[in] cipher_suite The cipher suite structure to query. + * + * \return The PAKE algorithm stored in the cipher suite structure. + */ +static psa_algorithm_t psa_pake_cs_get_algorithm( + const psa_pake_cipher_suite_t *cipher_suite); + +/** Declare the PAKE algorithm for the cipher suite. + * + * This function overwrites any PAKE algorithm + * previously set in \p cipher_suite. + * + * \param[out] cipher_suite The cipher suite structure to write to. + * \param algorithm The PAKE algorithm to write. + * (`PSA_ALG_XXX` values of type ::psa_algorithm_t + * such that #PSA_ALG_IS_PAKE(\c alg) is true.) + * If this is 0, the PAKE algorithm in + * \p cipher_suite becomes unspecified. + */ +static void psa_pake_cs_set_algorithm(psa_pake_cipher_suite_t *cipher_suite, + psa_algorithm_t algorithm); + +/** Retrieve the primitive from a PAKE cipher suite. + * + * \param[in] cipher_suite The cipher suite structure to query. + * + * \return The primitive stored in the cipher suite structure. + */ +static psa_pake_primitive_t psa_pake_cs_get_primitive( + const psa_pake_cipher_suite_t *cipher_suite); + +/** Declare the primitive for a PAKE cipher suite. + * + * This function overwrites any primitive previously set in \p cipher_suite. + * + * \param[out] cipher_suite The cipher suite structure to write to. + * \param primitive The primitive to write. If this is 0, the + * primitive type in \p cipher_suite becomes + * unspecified. + */ +static void psa_pake_cs_set_primitive(psa_pake_cipher_suite_t *cipher_suite, + psa_pake_primitive_t primitive); + +/** The type of the state data structure for PAKE operations. + * + * Before calling any function on a PAKE operation object, the application + * must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_pake_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_pake_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_PAKE_OPERATION_INIT, + * for example: + * \code + * psa_pake_operation_t operation = PSA_PAKE_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_pake_operation_init() + * to the structure, for example: + * \code + * psa_pake_operation_t operation; + * operation = psa_pake_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ +typedef struct psa_pake_operation_s psa_pake_operation_t; + +/** Return an initial value for a PAKE operation object. + */ +static psa_pake_operation_t psa_pake_operation_init(void); + +/** Set the session information for a password-authenticated key exchange. + * + * The sequence of operations to set up a password-authenticated key exchange + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_pake_operation_t, e.g. + * #PSA_PAKE_OPERATION_INIT. + * -# Call psa_pake_setup() to specify the password key and the cipher suite. + * -# Call \c psa_pake_set_xxx() functions on the operation to complete the + * setup. The exact sequence of \c psa_pake_set_xxx() functions that needs + * to be called depends on the algorithm in use. + * + * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` + * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) + * for more information. + * + * A typical sequence of calls to perform a password-authenticated key + * exchange: + * -# Call psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to get the + * key share that needs to be sent to the peer. + * -# Call psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to provide + * the key share that was received from the peer. + * -# Depending on the algorithm additional calls to psa_pake_output() and + * psa_pake_input() might be necessary. + * -# Call psa_pake_get_shared_key() for accessing the shared secret. + * + * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` + * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) + * for more information. + * + * If an error occurs at any step after a call to psa_pake_setup(), + * the operation will need to be reset by a call to psa_pake_abort(). The + * application may call psa_pake_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_pake_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A call to psa_pake_abort(). + * - A successful call to psa_pake_get_shared_key(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized but not set up yet. + * \param[in] password_key Identifier of the key holding the password or + * a value derived from the password. It must + * remain valid until the operation terminates. + * The valid key types depend on the PAKE algorithm, + * and participant role. + * \param[in] cipher_suite The cipher suite to use. (A cipher suite fully + * characterizes a PAKE algorithm and determines + * the algorithm as well.) + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p password_key is not a valid key identifier. + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_DERIVE flag, or it does not + * permit the \p operation's algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The algorithm in \p cipher_suite is not a PAKE algorithm or encodes + * an invalid hash algorithm, or the PAKE primitive in \p cipher_suite + * is not compatible with the PAKE algorithm, or the key confirmation + * value in \p cipher_suite is not compatible with the PAKE algorithm + * and primitive, or the \p password_key is not compatible with + * \p cipher_suite. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The algorithm in \p cipher_suite is not a supported PAKE algorithm, + * or the PAKE primitive in \p cipher_suite is not supported or not + * compatible with the PAKE algorithm, or the key confirmation value + * in \p cipher_suite is not supported or not compatible with the PAKE + * algorithm and primitive, or the key type or key size of + * \p password_key is not supported with \p cipher_suite. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid, or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_setup(psa_pake_operation_t *operation, + mbedtls_svc_key_id_t password_key, + const psa_pake_cipher_suite_t *cipher_suite); + +/** Set the application role for a password-authenticated key exchange. +* +* Not all PAKE algorithms need to differentiate the communicating entities. +* It is optional to call this function for PAKEs that don't require a role +* to be specified. For such PAKEs the application role parameter is ignored, +* or #PSA_PAKE_ROLE_NONE can be passed as \c role. +* +* Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` +* values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) +* for more information. +* +* \param[in,out] operation The operation object to specify the +* application's role for. It must have been set up +* by psa_pake_setup() and not yet in use (neither +* psa_pake_output() nor psa_pake_input() has been +* called yet). It must be an operation for which +* the application's role hasn't been specified +* (psa_pake_set_role() hasn't been called yet). +* \param role A value of type ::psa_pake_role_t indicating the +* application's role in the PAKE algorithm +* that is being set up. For more information see +* the documentation of \c PSA_PAKE_ROLE_XXX +* constants. +* +* \retval #PSA_SUCCESS +* Success. +* \retval #PSA_ERROR_INVALID_ARGUMENT +* The \p role is not a valid PAKE role in the \p operation’s algorithm. +* \retval #PSA_ERROR_NOT_SUPPORTED +* The \p role for this algorithm is not supported or is not valid. +* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription +* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription +* \retval #PSA_ERROR_BAD_STATE +* The operation state is not valid, or +* the library has not been previously initialized by psa_crypto_init(). +* It is implementation-dependent whether a failure to initialize +* results in this error code. +*/ +psa_status_t psa_pake_set_role(psa_pake_operation_t *operation, + psa_pake_role_t role); + +/** Set the user ID for a password-authenticated key exchange. + * + * Call this function to set the user ID. For PAKE algorithms that associate a + * user identifier with each side of the session you need to call + * psa_pake_set_peer() as well. For PAKE algorithms that associate a single + * user identifier with the session, call psa_pake_set_user() only. + * + * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` + * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) + * for more information. + * + * \param[in,out] operation The operation object to set the user ID for. It + * must have been set up by psa_pake_setup() and + * not yet in use (neither psa_pake_output() nor + * psa_pake_input() has been called yet). It must + * be on operation for which the user ID hasn't + * been set (psa_pake_set_user() hasn't been + * called yet). + * \param[in] user_id The user ID to authenticate with. + * \param user_id_len Size of the \p user_id buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p user_id is not valid for the \p operation's algorithm and cipher + * suite. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The value of \p user_id is not supported by the implementation. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid, or + * the library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_set_user(psa_pake_operation_t *operation, + const uint8_t *user_id, + size_t user_id_len); + +/** Set the peer ID for a password-authenticated key exchange. + * + * Call this function in addition to psa_pake_set_user() for PAKE algorithms + * that associate a user identifier with each side of the session. For PAKE + * algorithms that associate a single user identifier with the session, call + * psa_pake_set_user() only. + * + * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` + * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) + * for more information. + * + * \param[in,out] operation The operation object to set the peer ID for. It + * must have been set up by psa_pake_setup() and + * not yet in use (neither psa_pake_output() nor + * psa_pake_input() has been called yet). It must + * be on operation for which the peer ID hasn't + * been set (psa_pake_set_peer() hasn't been + * called yet). + * \param[in] peer_id The peer's ID to authenticate. + * \param peer_id_len Size of the \p peer_id buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p peer_id is not valid for the \p operation's algorithm and cipher + * suite. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The algorithm doesn't associate a second identity with the session. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * Calling psa_pake_set_peer() is invalid with the \p operation's + * algorithm, the operation state is not valid, or the library has not + * been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation, + const uint8_t *peer_id, + size_t peer_id_len); + +/** Set the context data for a password-authenticated key exchange. + * + * Call this function for PAKE algorithms that accept additional context data + * as part of the protocol setup. + * + * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX` + * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) + * for more information. + * + * \param[in,out] operation The operation object to set the context for. It + * must have been set up by psa_pake_setup() and + * not yet in use (neither psa_pake_output() nor + * psa_pake_input() has been called yet). It must + * be on operation for which the context hasn't + * been set (psa_pake_set_context() hasn't been + * called yet). + * \param[in] context The context. + * \param context_len Size of the \p context buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The \p context is not valid for the operation’s algorithm and cipher suite. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The \p context is not supported by the implementation. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * Calling psa_pake_set_context() is invalid with the \p operation's + * algorithm, the operation state is not valid, or the library has not + * been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_set_context(psa_pake_operation_t *operation, + const uint8_t *context, + size_t context_len); + +/** Get output for a step of a password-authenticated key exchange. + * + * Depending on the algorithm being executed, you might need to call this + * function several times or you might not need to call this at all. + * + * The exact sequence of calls to perform a password-authenticated key + * exchange depends on the algorithm in use. Refer to the documentation of + * individual PAKE algorithm types (`PSA_ALG_XXX` values of type + * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more + * information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_pake_abort(). + * + * \param[in,out] operation Active PAKE operation. + * \param step The step of the algorithm for which the output + * is requested. + * \param[out] output Buffer where the output is to be written in the + * format appropriate for this \p step. Refer to + * the documentation of the individual + * \c PSA_PAKE_STEP_XXX constants for more + * information. + * \param output_size Size of the \p output buffer in bytes. This must + * be at least #PSA_PAKE_OUTPUT_SIZE(\c alg, \c + * primitive, \p output_step) where \c alg and + * \p primitive are the PAKE algorithm and primitive + * in the operation's cipher suite, and \p step is + * the output step. + * + * \param[out] output_length On success, the number of bytes of the returned + * output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p step is not compatible with the operation's algorithm. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p step is not supported with the operation's algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, and fully set + * up, and this call must conform to the algorithm's requirements + * for ordering of input and output steps), or the library has not + * been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_output(psa_pake_operation_t *operation, + psa_pake_step_t step, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Provide input for a step of a password-authenticated key exchange. + * + * Depending on the algorithm being executed, you might need to call this + * function several times or you might not need to call this at all. + * + * The exact sequence of calls to perform a password-authenticated key + * exchange depends on the algorithm in use. Refer to the documentation of + * individual PAKE algorithm types (`PSA_ALG_XXX` values of type + * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more + * information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_pake_abort(). + * + * \param[in,out] operation Active PAKE operation. + * \param step The step for which the input is provided. + * \param[in] input Buffer containing the input in the format + * appropriate for this \p step. Refer to the + * documentation of the individual + * \c PSA_PAKE_STEP_XXX constants for more + * information. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The verification fails for a #PSA_PAKE_STEP_ZK_PROOF input step. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p step is not compatible with the operation's algorithm, or + * \p input_length is not compatible with the \p operation’s algorithm, + * or the \p input is not valid for the \p operation's algorithm, + * cipher suite or \p step. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p step is not supported with the operation's algorithm, or + * \p step p is not supported with the \p operation's algorithm, or the + * \p input is not supported for the \p operation's algorithm, cipher + * suite or \p step. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, and fully set + * up, and this call must conform to the algorithm's requirements + * for ordering of input and output steps), or the library has not + * been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_input(psa_pake_operation_t *operation, + psa_pake_step_t step, + const uint8_t *input, + size_t input_length); + +/** Get shared secret from a PAKE. + * + * This is the final call in a PAKE operation, which retrieves the shared + * secret as a key. It is recommended that this key is used as an input to a + * key derivation operation to produce additional cryptographic keys. For + * some PAKE algorithms, the shared secret is also suitable for use as a key + * in cryptographic operations such as encryption. Refer to the documentation + * of individual PAKE algorithm types (`PSA_ALG_XXX` values of type + * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more + * information. + * + * Depending on the key confirmation requested in the cipher suite, + * psa_pake_get_shared_key() must be called either before or after the + * key-confirmation output and input steps for the PAKE algorithm. The key + * confirmation affects the guarantees that can be made about the shared key: + * + * Unconfirmed key + * If the cipher suite used to set up the operation requested an unconfirmed + * key, the application must call psa_pake_get_shared_key() after the + * key-exchange output and input steps are completed. The PAKE algorithm + * provides a cryptographic guarantee that only a peer who used the same + * password, and identity inputs, is able to compute the same key. However, + * there is no guarantee that the peer is the participant it claims to be, + * and was able to compute the same key. + * Since the peer is not authenticated, no action should be taken that assumes + * that the peer is who it claims to be. For example, do not access restricted + * files on the peer’s behalf until an explicit authentication has succeeded. + * Note: + * Some PAKE algorithms do not enable the output of the shared secret until it + * has been confirmed. + * + * Confirmed key + * If the cipher suite used to set up the operation requested a confirmed key, + * the application must call psa_pake_get_shared_key() after the key-exchange + * and key-confirmation output and input steps are completed. + * Following key confirmation, the PAKE algorithm provides a cryptographic + * guarantee that the peer used the same password and identity inputs, and has + * computed the identical shared secret key. + * Since the peer is not authenticated, no action should be taken that assumes + * that the peer is who it claims to be. For example, do not access restricted + * files on the peer’s behalf until an explicit authentication has succeeded. + * Note: + * Some PAKE algorithms do not include any key-confirmation steps. + * + * The exact sequence of calls to perform a password-authenticated key + * exchange depends on the algorithm in use. + * + * When this function returns successfully, \p operation becomes inactive. + * If this function returns an error status, both \p operation + * and \c key_derivation operations enter an error state and must be aborted + * by calling psa_pake_abort(). + * + * \param[in,out] operation Active PAKE operation. + * \param[in] attributes The attributes for the new key. + * \param[out] key On success, an identifier for the newly created + * key. #PSA_KEY_ID_NULL on failure. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_NOT_PERMITTED + * The implementation does not permit creating a key with the + * specified attributes due to some implementation-specific policy. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key type is not valid for output from this operation’s + * algorithm, or the key size is nonzero, or the key lifetime is + * invalid, the key identifier is not valid for the key lifetime, + * or the key usage flags include invalid values, or the key’s + * permitted-usage algorithm is invalid, or the key attributes, + * as a whole, are invalid. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key attributes, as a whole, are not supported for creation + * from a PAKE secret, either by the implementation in general or + * in the specified storage location. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The PAKE operation state is not valid (it must be ready to return + * the shared secret), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_get_shared_key(psa_pake_operation_t *operation, + const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key); + +/** Abort a PAKE operation. + * + * Aborting an operation frees all associated resources except for the \c + * operation structure itself. Once aborted, the operation object can be reused + * for another operation by calling psa_pake_setup() again. + * + * This function may be called at any time after the operation + * object has been initialized as described in #psa_pake_operation_t. + * + * In particular, calling psa_pake_abort() after the operation has been + * terminated by a call to psa_pake_abort() or psa_pake_get_shared_key() + * is safe and has no effect. + * + * \param[in,out] operation The operation to abort. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_pake_abort(psa_pake_operation_t *operation); + +/**@}*/ + +/** A sufficient output buffer size for psa_pake_output(). + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_pake_output() will not fail due to an insufficient output buffer + * size. The actual size of the output might be smaller in any given call. + * + * See also #PSA_PAKE_OUTPUT_MAX_SIZE + * + * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_PAKE(\p alg) is true). + * \param primitive A primitive of type ::psa_pake_primitive_t that is + * compatible with algorithm \p alg. + * \param output_step A value of type ::psa_pake_step_t that is valid for the + * algorithm \p alg. + * \return A sufficient output buffer size for the specified + * PAKE algorithm, primitive, and output step. If the + * PAKE algorithm, primitive, or output step is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \ + (output_step == PSA_PAKE_STEP_KEY_SHARE ? \ + PSA_PAKE_PRIMITIVE_GET_TYPE(primitive) == PSA_PAKE_PRIMITIVE_TYPE_DH ? \ + PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + output_step == PSA_PAKE_STEP_ZK_PUBLIC ? \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + output_step == PSA_PAKE_STEP_ZK_PROOF ? \ + PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + output_step == PSA_PAKE_STEP_CONFIRM ? \ + PSA_ALG_IS_SPAKE2P_CMAC(alg) ? \ + PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC) : \ + PSA_HASH_LENGTH(alg) : \ + 0u) + +/** A sufficient input buffer size for psa_pake_input(). + * + * The value returned by this macro is guaranteed to be large enough for any + * valid input to psa_pake_input() in an operation with the specified + * parameters. + * + * See also #PSA_PAKE_INPUT_MAX_SIZE + * + * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_PAKE(\p alg) is true). + * \param primitive A primitive of type ::psa_pake_primitive_t that is + * compatible with algorithm \p alg. + * \param input_step A value of type ::psa_pake_step_t that is valid for the + * algorithm \p alg. + * \return A sufficient input buffer size for the specified + * input, cipher suite and algorithm. If the cipher suite, + * the input type or PAKE algorithm is not recognized, or + * the parameters are incompatible, return 0. + */ +#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \ + (input_step == PSA_PAKE_STEP_KEY_SHARE ? \ + PSA_PAKE_PRIMITIVE_GET_TYPE(primitive) == PSA_PAKE_PRIMITIVE_TYPE_DH ? \ + PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + input_step == PSA_PAKE_STEP_ZK_PUBLIC ? \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + input_step == PSA_PAKE_STEP_ZK_PROOF ? \ + PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \ + input_step == PSA_PAKE_STEP_CONFIRM ? \ + PSA_ALG_IS_SPAKE2P_CMAC(alg) ? \ + PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC) : \ + PSA_HASH_LENGTH(alg) : \ + input_step == PSA_PAKE_STEP_SALT ? \ + 64u : \ + 0u) + +/** Output buffer size for psa_pake_output() for any of the supported PAKE + * algorithm and primitive suites and output step. + * + * This macro must expand to a compile-time constant integer. + * + * The value of this macro must be at least as large as the largest value + * returned by PSA_PAKE_OUTPUT_SIZE() + * + * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step). + */ +#ifdef PSA_WANT_ALG_SRP_6 +#define PSA_PAKE_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) +#else +#define PSA_PAKE_OUTPUT_MAX_SIZE PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) +#endif + +/** Input buffer size for psa_pake_input() for any of the supported PAKE + * algorithm and primitive suites and input step. + * + * This macro must expand to a compile-time constant integer. + * + * The value of this macro must be at least as large as the largest value + * returned by PSA_PAKE_INPUT_SIZE() + * + * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step). + */ +#ifdef PSA_WANT_ALG_SRP_6 +#define PSA_PAKE_INPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) +#else +#define PSA_PAKE_INPUT_MAX_SIZE PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) +#endif + +static inline psa_algorithm_t psa_pake_cs_get_algorithm( + const psa_pake_cipher_suite_t *cipher_suite) +{ + return cipher_suite->algorithm; +} + +static inline void psa_pake_cs_set_algorithm( + psa_pake_cipher_suite_t *cipher_suite, + psa_algorithm_t algorithm) +{ + if (!PSA_ALG_IS_PAKE(algorithm)) { + cipher_suite->algorithm = 0; + } else { + cipher_suite->algorithm = algorithm; + } +} + +static inline psa_pake_primitive_t psa_pake_cs_get_primitive( + const psa_pake_cipher_suite_t *cipher_suite) +{ + return cipher_suite->primitive; +} + +static inline void psa_pake_cs_set_primitive( + psa_pake_cipher_suite_t *cipher_suite, + psa_pake_primitive_t primitive) +{ + cipher_suite->primitive = primitive; +} + +static inline uint32_t psa_pake_cs_get_key_confirmation( + const psa_pake_cipher_suite_t* cipher_suite) +{ + return cipher_suite->key_confirmation; +} + +static inline void psa_pake_cs_set_key_confirmation( + psa_pake_cipher_suite_t* cipher_suite, + uint32_t key_confirmation) +{ + cipher_suite->key_confirmation = key_confirmation; +} + /**@}*/ #ifdef __cplusplus diff --git a/interface/include/psa/crypto_sizes.h b/interface/include/psa/crypto_sizes.h index 8906ebf5e..94da58339 100644 --- a/interface/include/psa/crypto_sizes.h +++ b/interface/include/psa/crypto_sizes.h @@ -869,6 +869,34 @@ #define PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(key_bits) \ (PSA_BITS_TO_BYTES(key_bits)) +/* Maximum size of the export encoding of an SPAKE2+ public key. + * + * An SPAKE2+ public key is represented by the secret values w0 and L. + */ +#define PSA_KEY_EXPORT_SPAKE2P_PUBLIC_KEY_MAX_SIZE(key_bits) \ + (3u * PSA_BITS_TO_BYTES(key_bits) + 1u) + +/* Maximum size of the export encoding of an SPAKE2+ key pair. + * + * An SPAKE2+ key pair is represented by the secret values w0 and w1. + */ +#define PSA_KEY_EXPORT_SPAKE2P_KEY_PAIR_MAX_SIZE(key_bits) \ + (2u * PSA_BITS_TO_BYTES(key_bits)) + +/* Maximum size of the export encoding of an SRP public key. + * + * An SRP public key is represented by the password verifier. + */ +#define PSA_KEY_EXPORT_SRP_PUBLIC_KEY_MAX_SIZE(key_bits) \ + (PSA_BITS_TO_BYTES(key_bits)) + +/* Maximum size of the export encoding of an SRP key pair. + * + * An SRP key pair is represented by the password hash. + */ +#define PSA_KEY_EXPORT_SRP_KEY_PAIR_MAX_SIZE(key_bits) \ + (PSA_HASH_MAX_SIZE) + /** Sufficient output buffer size for psa_export_key() or * psa_export_public_key(). * @@ -915,6 +943,10 @@ (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \ (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_SPAKE2P_KEY_PAIR(key_type) ? 2u * PSA_BITS_TO_BYTES(key_bits) : \ + PSA_KEY_TYPE_IS_SPAKE2P_PUBLIC_KEY(key_type) ? 3u * PSA_BITS_TO_BYTES(key_bits) + 1u : \ + PSA_KEY_TYPE_IS_SRP_KEY_PAIR(key_type) ? PSA_HASH_MAX_SIZE : \ + PSA_KEY_TYPE_IS_SRP_PUBLIC_KEY(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ 0u) @@ -968,6 +1000,8 @@ (PSA_KEY_TYPE_IS_RSA(key_type) ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ PSA_KEY_TYPE_IS_DH(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ + PSA_KEY_TYPE_IS_SPAKE2P(key_type) ? 3u * PSA_BITS_TO_BYTES(key_bits) + 1u : \ + PSA_KEY_TYPE_IS_SRP(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ 0u) /** Sufficient buffer size for exporting any asymmetric key pair. @@ -1001,6 +1035,20 @@ #define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) #endif +#if defined(PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_BASIC) && \ + (PSA_KEY_EXPORT_SPAKE2P_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \ + PSA_EXPORT_KEY_PAIR_MAX_SIZE) +#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ + PSA_KEY_EXPORT_SPAKE2P_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) +#endif +#if defined(PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_BASIC) && \ + (PSA_KEY_EXPORT_SRP_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \ + PSA_EXPORT_KEY_PAIR_MAX_SIZE) +#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ + PSA_KEY_EXPORT_SRP_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) +#endif /** Sufficient buffer size for exporting any asymmetric public key. * @@ -1034,6 +1082,20 @@ #define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) #endif +#if defined(PSA_WANT_KEY_TYPE_SPAKE2P_PUBLIC_KEY) && \ + (PSA_KEY_EXPORT_SPAKE2P_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \ + PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) +#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + PSA_KEY_EXPORT_SPAKE2P_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) +#endif +#if defined(PSA_WANT_KEY_TYPE_SRP_PUBLIC_KEY) && \ + (PSA_KEY_EXPORT_SRP_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \ + PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) +#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + PSA_KEY_EXPORT_SRP_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) +#endif /** Sufficient output buffer size for psa_raw_key_agreement(). * diff --git a/interface/include/psa/crypto_struct.h b/interface/include/psa/crypto_struct.h index 88b6b5367..1cbbe4081 100644 --- a/interface/include/psa/crypto_struct.h +++ b/interface/include/psa/crypto_struct.h @@ -236,6 +236,30 @@ static inline size_t psa_get_key_bits( return attributes->client.bits; } +struct psa_pake_cipher_suite_s { + psa_algorithm_t algorithm; + psa_pake_primitive_t primitive; + uint32_t key_confirmation; +}; + +#define PSA_PAKE_CIPHER_SUITE_INIT {PSA_ALG_NONE, 0, 0} +static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void) +{ + const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT; + return v; +} + +struct psa_pake_operation_s { + uint32_t handle; +}; + +#define PSA_PAKE_OPERATION_INIT {0} +static inline struct psa_pake_operation_s psa_pake_operation_init(void) +{ + const struct psa_pake_operation_s v = PSA_PAKE_OPERATION_INIT; + return v; +} + #ifdef __cplusplus } #endif diff --git a/interface/include/psa/crypto_types.h b/interface/include/psa/crypto_types.h index c41053d15..01feaebf9 100644 --- a/interface/include/psa/crypto_types.h +++ b/interface/include/psa/crypto_types.h @@ -450,4 +450,51 @@ typedef uint16_t psa_key_derivation_step_t; /**@}*/ +/** The type of the data structure for PAKE cipher suites. + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. + */ +typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t; + +/** Encoding of the type of the PAKE's primitive. +* +* Values defined by this standard will never be in the range 0x80-0xff. +* Vendors who define additional types must use an encoding in this range. +* +* For more information see the documentation of individual +* \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants. +*/ +typedef uint8_t psa_pake_primitive_type_t; + +/** \brief Encoding of the family of the primitive associated with the PAKE. +* +* For more information see the documentation of individual +* \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants. +*/ +typedef uint8_t psa_pake_family_t; + +/** \brief Encoding of the primitive associated with the PAKE. +* +* For more information see the documentation of the #PSA_PAKE_PRIMITIVE macro. +*/ +typedef uint32_t psa_pake_primitive_t; + +/** \brief Encoding of the application role of PAKE + * + * Encodes the application's role in the algorithm being executed. For more + * information see the documentation of individual \c PSA_PAKE_ROLE_XXX + * constants. + */ +typedef uint8_t psa_pake_role_t; + +/** Encoding of input and output indicators for PAKE. + * + * Some PAKE algorithms need to exchange more data than just a single key share. + * This type is for encoding additional input and output data for such + * algorithms. + */ +typedef uint8_t psa_pake_step_t; + #endif /* PSA_CRYPTO_TYPES_H */ diff --git a/interface/include/psa/crypto_values.h b/interface/include/psa/crypto_values.h index 8eba1d4d0..e4a8c45f6 100644 --- a/interface/include/psa/crypto_values.h +++ b/interface/include/psa/crypto_values.h @@ -724,6 +724,14 @@ */ #define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03) +/** Diffie-Hellman groups defined in RFC 3526. + * + * This family includes groups with the following key sizes (in bits): + * 1536, 2048, 3072, 4096, 6144, 8192. A given implementation may support + * all of these sizes or only a subset. + */ +#define PSA_DH_FAMILY_RFC3526 ((psa_dh_family_t) 0x05) /*!!OM*/ + #define PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) \ (((type) >> 8) & 7) /** The block size of a block cipher. @@ -2105,6 +2113,35 @@ */ #define PSA_ALG_PBKDF2_AES_CMAC_PRF_128 ((psa_algorithm_t) 0x08800200) +#define PSA_ALG_SRP_PASSWORD_HASH_BASE ((psa_algorithm_t) 0x08800300) + /** The SRP password to password-hash KDF. + * It takes the password p, the salt s, and the user id u. + * It calculates the password hash h as + * h = H(salt || H(u || ":" || p)) + * where H is the given hash algorithm. + * + * This key derivation algorithm uses the following inputs, which must be + * provided in the following order: + * - #PSA_KEY_DERIVATION_INPUT_INFO is the user id. + * - #PSA_KEY_DERIVATION_INPUT_PASSWORD is the password. + * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt. + * The output has to be read as a key of type PSA_KEY_TYPE_SRP_KEY_PAIR. + */ +#define PSA_ALG_SRP_PASSWORD_HASH(hash_alg) \ + (PSA_ALG_SRP_PASSWORD_HASH_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) + + /** Whether the specified algorithm is a key derivation algorithm constructed + * using #PSA_ALG_SRP_PASSWORD_HASH(\p hash_alg). + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a key derivation algorithm constructed using #PSA_ALG_SRP_PASSWORD_HASH(), + * 0 otherwise. This macro may return either 0 or 1 if \c alg is not a supported + * key derivation algorithm identifier. + */ +#define PSA_ALG_IS_SRP_PASSWORD_HASH(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_SRP_PASSWORD_HASH_BASE) + #define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t) 0xfe00ffff) #define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t) 0xffff0000) diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h index d32073035..fcfc218ba 100644 --- a/interface/include/tfm_crypto_defs.h +++ b/interface/include/tfm_crypto_defs.h @@ -58,6 +58,7 @@ struct tfm_crypto_pack_iovec { * See tfm_crypto_func_sid for detail */ uint16_t step; /*!< Key derivation step */ + psa_pake_role_t role; /*!< PAKE role */ }; /** @@ -75,6 +76,7 @@ enum tfm_crypto_group_id { TFM_CRYPTO_GROUP_ID_ASYM_SIGN, TFM_CRYPTO_GROUP_ID_ASYM_ENCRYPT, TFM_CRYPTO_GROUP_ID_KEY_DERIVATION, + TFM_CRYPTO_GROUP_ID_PAKE, }; /* Set of X macros describing each of the available PSA Crypto APIs */ @@ -161,6 +163,17 @@ enum tfm_crypto_group_id { #define RANDOM_FUNCS \ X(TFM_CRYPTO_GENERATE_RANDOM) +#define PAKE_FUNCS \ + X(TFM_CRYPTO_PAKE_SETUP) \ + X(TFM_CRYPTO_PAKE_SET_ROLE) \ + X(TFM_CRYPTO_PAKE_SET_USER) \ + X(TFM_CRYPTO_PAKE_SET_PEER) \ + X(TFM_CRYPTO_PAKE_SET_CONTEXT) \ + X(TFM_CRYPTO_PAKE_OUTPUT) \ + X(TFM_CRYPTO_PAKE_INPUT) \ + X(TFM_CRYPTO_PAKE_GET_SHARED_KEY) \ + X(TFM_CRYPTO_PAKE_ABORT) + /** * \brief Define function IDs in each group. The function ID will be encoded into * tfm_crypto_func_sid below. Each group is defined as a dedicated enum @@ -193,6 +206,9 @@ enum tfm_crypto_key_derivation_func_id { enum tfm_crypto_random_func_id { RANDOM_FUNCS }; +enum tfm_crypto_pake_func_id { + PAKE_FUNCS +}; #undef X /** @@ -268,6 +284,11 @@ enum tfm_crypto_func_sid { (TFM_CRYPTO_GROUP_ID_RANDOM & 0xFF)), RANDOM_FUNCS +#undef X +#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \ + (TFM_CRYPTO_GROUP_ID_PAKE & 0xFF)), + PAKE_FUNCS + }; #undef X diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c index 8c857324b..0164ae8ac 100644 --- a/interface/src/tfm_crypto_api.c +++ b/interface/src/tfm_crypto_api.c @@ -1656,3 +1656,159 @@ TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_key)( return API_DISPATCH(in_vec, out_vec); } + + +TFM_CRYPTO_API(psa_status_t, psa_pake_setup) +(psa_pake_operation_t *operation, psa_key_id_t password_key, + const psa_pake_cipher_suite_t *cipher_suite) { + struct tfm_crypto_pack_iovec iov = {.function_id = TFM_CRYPTO_PAKE_SETUP_SID, + .op_handle = operation->handle, + .key_id = password_key}; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = cipher_suite, .len = sizeof(psa_pake_cipher_suite_t)}, + }; + + psa_outvec out_vec[] = { + {.base = &(operation->handle), .len = sizeof(uint32_t)}, + }; + + return API_DISPATCH(in_vec, out_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_set_role) +(psa_pake_operation_t *operation, psa_pake_role_t role) { + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_SET_ROLE_SID, + .op_handle = operation->handle, + .role = role, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + }; + + return API_DISPATCH_NO_OUTVEC(in_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_set_user) +(psa_pake_operation_t *operation, const uint8_t *user_id, size_t user_id_len) { + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_SET_USER_SID, + .op_handle = operation->handle, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = user_id, .len = user_id_len}, + }; + + return API_DISPATCH_NO_OUTVEC(in_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_set_peer) +(psa_pake_operation_t *operation, const uint8_t *peer_id, size_t peer_id_len) { + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_SET_PEER_SID, + .op_handle = operation->handle, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = peer_id, .len = peer_id_len}, + }; + + return API_DISPATCH_NO_OUTVEC(in_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_set_context) +(psa_pake_operation_t *operation, const uint8_t *context, size_t context_len) { + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_SET_CONTEXT_SID, + .op_handle = operation->handle, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = context, .len = context_len}, + }; + + return API_DISPATCH_NO_OUTVEC(in_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_output) +(psa_pake_operation_t *operation, psa_pake_step_t step, uint8_t *output, + size_t output_size, size_t *output_length) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_OUTPUT_SID, + .op_handle = operation->handle, + .step = step, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + }; + + psa_outvec out_vec[] = {{.base = output, .len = output_size}}; + + status = API_DISPATCH(in_vec, out_vec); + + *output_length = out_vec[0].len; + + return status; +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_input) +(psa_pake_operation_t *operation, psa_pake_step_t step, const uint8_t *input, + size_t input_length) { + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_INPUT_SID, + .op_handle = operation->handle, + .step = step, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = input, .len = input_length}, + }; + + return API_DISPATCH_NO_OUTVEC(in_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_get_shared_key) +(psa_pake_operation_t *operation, const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key) { + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_GET_SHARED_KEY_SID, + .op_handle = operation->handle, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + {.base = attributes, .len = sizeof(psa_key_attributes_t)}, + }; + + psa_outvec out_vec[] = { + {.base = &(operation->handle), .len = sizeof(uint32_t)}, + {.base = key, .len = sizeof(mbedtls_svc_key_id_t)}}; + + return API_DISPATCH(in_vec, out_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_pake_abort)(psa_pake_operation_t *operation) { + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_PAKE_ABORT_SID, + .op_handle = operation->handle, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + }; + psa_outvec out_vec[] = { + {.base = &(operation->handle), .len = sizeof(uint32_t)}, + }; + + return API_DISPATCH(in_vec, out_vec); +} \ No newline at end of file diff --git a/secure_fw/partitions/crypto/CMakeLists.txt b/secure_fw/partitions/crypto/CMakeLists.txt index 7a463fed0..db92779f6 100644 --- a/secure_fw/partitions/crypto/CMakeLists.txt +++ b/secure_fw/partitions/crypto/CMakeLists.txt @@ -31,6 +31,7 @@ target_sources(tfm_psa_rot_partition_crypto crypto_key_management.c crypto_rng.c crypto_library.c + crypto_pake.c $<$:psa_driver_api/tfm_builtin_key_loader.c> ) diff --git a/secure_fw/partitions/crypto/Kconfig.comp b/secure_fw/partitions/crypto/Kconfig.comp index e5bf08780..f8ef7658c 100644 --- a/secure_fw/partitions/crypto/Kconfig.comp +++ b/secure_fw/partitions/crypto/Kconfig.comp @@ -71,6 +71,10 @@ config CRYPTO_KEY_DERIVATION_MODULE_ENABLED bool "PSA Crypto key derivation module" default y +config CRYPTO_PAKE_MODULE_ENABLED + bool "PSA Crypto PAKE module" + default y + config CRYPTO_NV_SEED bool default n if CRYPTO_HW_ACCELERATOR diff --git a/secure_fw/partitions/crypto/crypto_check_config.h b/secure_fw/partitions/crypto/crypto_check_config.h index 364912257..19d04b77b 100644 --- a/secure_fw/partitions/crypto/crypto_check_config.h +++ b/secure_fw/partitions/crypto/crypto_check_config.h @@ -118,4 +118,14 @@ #error "CRYPTO_KEY_DERIVATION_MODULE_ENABLED enabled, but not all prerequisites (missing key derivation algorithms)!" #endif +#if CRYPTO_PAKE_MODULE_ENABLED && \ + (!defined(PSA_WANT_ALG_JPAKE) && \ + !defined(PSA_WANT_ALG_SPAKE2P_HMAC) && \ + !defined(PSA_WANT_ALG_SPAKE2P_CMAC) && \ + !defined(PSA_WANT_ALG_SPAKE2P_MATTER) && \ + !defined(PSA_WANT_ALG_SRP_6) && \ + !defined(PSA_WANT_ALG_SRP_PASSWORD_HASH)) +#error "CRYPTO_PAKE_MODULE_ENABLED enabled, but not all prerequisites (missing PAKE algorithms)!" +#endif + #endif /* __CRYPTO_CHECK_CONFIG_H__ */ diff --git a/secure_fw/partitions/crypto/crypto_init.c b/secure_fw/partitions/crypto/crypto_init.c index da20896d4..6067ea07d 100644 --- a/secure_fw/partitions/crypto/crypto_init.c +++ b/secure_fw/partitions/crypto/crypto_init.c @@ -388,6 +388,8 @@ psa_status_t tfm_crypto_api_dispatcher(psa_invec in_vec[], &encoded_key); case TFM_CRYPTO_GROUP_ID_RANDOM: return tfm_crypto_random_interface(in_vec, out_vec); + case TFM_CRYPTO_GROUP_ID_PAKE: + return tfm_crypto_pake_interface(in_vec, out_vec, &encoded_key); default: LOG_ERRFMT("[ERR][Crypto] Unsupported request!\r\n"); return PSA_ERROR_NOT_SUPPORTED; diff --git a/secure_fw/partitions/crypto/crypto_pake.c b/secure_fw/partitions/crypto/crypto_pake.c new file mode 100644 index 000000000..c19791fe8 --- /dev/null +++ b/secure_fw/partitions/crypto/crypto_pake.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_tfm.h" +#include "tfm_mbedcrypto_include.h" + +#include "tfm_crypto_api.h" +#include "tfm_crypto_key.h" +#include "tfm_crypto_defs.h" + +#include "crypto_library.h" + +/*! + * \addtogroup tfm_crypto_api_shim_layer + * + */ + +/*!@{*/ +#if CRYPTO_PAKE_MODULE_ENABLED +psa_status_t tfm_crypto_pake_interface(psa_invec in_vec[], + psa_outvec out_vec[], + struct tfm_crypto_key_id_s *encoded_key) +{ + const struct tfm_crypto_pack_iovec *iov = in_vec[0].base; + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + psa_pake_operation_t *operation = NULL; + uint32_t *p_handle = NULL; + uint16_t sid = iov->function_id; + + tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init( + encoded_key->owner, encoded_key->key_id); + if(sid == TFM_CRYPTO_PAKE_SETUP_SID) { + p_handle = out_vec[0].base; + *p_handle = iov->op_handle; + status = tfm_crypto_operation_alloc(TFM_CRYPTO_PAKE_OPERATION, + out_vec[0].base, + (void **)&operation); + } else { + status = tfm_crypto_operation_lookup(TFM_CRYPTO_PAKE_OPERATION, + iov->op_handle, + (void **)&operation); + if ((sid == TFM_CRYPTO_PAKE_ABORT_SID) || sid == TFM_CRYPTO_PAKE_GET_SHARED_KEY_SID){ + /* + * finish()/abort() interface put handle in out_vec[0]. + * Therefore, out_vec[0] shall be specially set to original handle + * value. Otherwise, the garbage data in message out_vec[0] may + * override the original handle value in client, after lookup fails. + */ + p_handle = out_vec[0].base; + *p_handle = iov->op_handle; + } + } + if (status != PSA_SUCCESS) { + if (sid == TFM_CRYPTO_PAKE_ABORT_SID) { + /* + * Mbed TLS psa_pake_abort() will return a misleading error code + * if it is called with invalid operation content, since it + * doesn't validate the operation handle. + * It is neither necessary to call tfm_crypto_operation_release() + * with an invalid handle. + * Therefore return PSA_SUCCESS directly as psa_cipher_abort() can + * be called multiple times. + */ + return PSA_SUCCESS; + } + return status; + } + + switch (sid) + { + case TFM_CRYPTO_PAKE_SETUP_SID: + { + status = psa_pake_setup(operation, library_key, in_vec[1].base); + if (status != PSA_SUCCESS) { + goto release_operation_and_return; + } + } + break; + case TFM_CRYPTO_PAKE_SET_ROLE_SID: + { + status = psa_pake_set_role(operation, iov->role); + } + break; + case TFM_CRYPTO_PAKE_SET_USER_SID: + { + status = psa_pake_set_user(operation, in_vec[1].base, in_vec[1].len); + } + break; + case TFM_CRYPTO_PAKE_SET_PEER_SID: + { + status = psa_pake_set_peer(operation, in_vec[1].base, in_vec[1].len); + } + break; + case TFM_CRYPTO_PAKE_SET_CONTEXT_SID: + { + status = psa_pake_set_context(operation, in_vec[1].base, in_vec[1].len); + } + break; + case TFM_CRYPTO_PAKE_OUTPUT_SID: + { + psa_pake_step_t step = (psa_pake_step_t)iov->step; + uint8_t *output = (uint8_t *)out_vec[0].base; + size_t output_size = out_vec[0].len; + size_t *output_length = &out_vec[0].len; + status = psa_pake_output(operation, step, output, output_size, output_length); + if (status != PSA_SUCCESS) { + out_vec[0].len = 0; + } + } + break; + case TFM_CRYPTO_PAKE_INPUT_SID: + { + status = psa_pake_input(operation, (psa_pake_step_t)iov->step, in_vec[1].base, in_vec[1].len); + } + break; + case TFM_CRYPTO_PAKE_GET_SHARED_KEY_SID: + { + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + const struct psa_client_key_attributes_s *client_key_attr = + in_vec[1].base; + psa_key_id_t *key_handle = out_vec[1].base; + + status = tfm_crypto_core_library_key_attributes_from_client( + client_key_attr, + encoded_key->owner, + &key_attributes); + + if (status != PSA_SUCCESS) { + break; + } + + status = psa_pake_get_shared_key(operation, &key_attributes, &library_key); + if (status == PSA_SUCCESS) { + *key_handle = CRYPTO_LIBRARY_GET_KEY_ID(library_key); + /* In case of success automatically release the operation */ + goto release_operation_and_return; + } + } + break; + case TFM_CRYPTO_PAKE_ABORT_SID: + { + status = psa_pake_abort(operation); + goto release_operation_and_return; + } + default: + return PSA_ERROR_NOT_SUPPORTED; + } + + return status; + +release_operation_and_return: + /* Release the operation context, ignore if the operation fails. */ + (void)tfm_crypto_operation_release(p_handle); + return status; +} +#else /* CRYPTO_PAKE_MODULE_ENABLED */ +psa_status_t tfm_crypto_pake_interface(psa_invec in_vec[], + psa_outvec out_vec[], + struct tfm_crypto_key_id_s *encoded_key) +{ + (void)in_vec; + (void)out_vec; + (void)encoded_key; + + return PSA_ERROR_NOT_SUPPORTED; +} +#endif /* CRYPTO_PAKE_MODULE_ENABLED */ +/*!@}*/ diff --git a/secure_fw/partitions/crypto/crypto_spe.h b/secure_fw/partitions/crypto/crypto_spe.h index b4d21fa0c..ba017898b 100644 --- a/secure_fw/partitions/crypto/crypto_spe.h +++ b/secure_fw/partitions/crypto/crypto_spe.h @@ -160,5 +160,23 @@ PSA_FUNCTION_NAME(psa_asymmetric_decrypt) #define psa_generate_key \ PSA_FUNCTION_NAME(psa_generate_key) +#define psa_pake_setup \ + PSA_FUNCTION_NAME(psa_pake_setup) +#define psa_pake_set_role \ + PSA_FUNCTION_NAME(psa_pake_set_role) +#define psa_pake_set_user \ + PSA_FUNCTION_NAME(psa_pake_set_user) +#define psa_pake_set_peer \ + PSA_FUNCTION_NAME(psa_pake_set_peer) +#define psa_pake_set_context \ + PSA_FUNCTION_NAME(psa_pake_set_context) +#define psa_pake_output \ + PSA_FUNCTION_NAME(psa_pake_output) +#define psa_pake_input \ + PSA_FUNCTION_NAME(psa_pake_input) +#define psa_pake_get_shared_key \ + PSA_FUNCTION_NAME(psa_pake_get_shared_key) +#define psa_pake_abort \ + PSA_FUNCTION_NAME(psa_pake_abort) #endif /* CRYPTO_SPE_H */ diff --git a/secure_fw/partitions/crypto/tfm_crypto_api.h b/secure_fw/partitions/crypto/tfm_crypto_api.h index 8fff29dce..2dc8473fd 100644 --- a/secure_fw/partitions/crypto/tfm_crypto_api.h +++ b/secure_fw/partitions/crypto/tfm_crypto_api.h @@ -31,6 +31,7 @@ enum tfm_crypto_operation_type { TFM_CRYPTO_HASH_OPERATION = 3, TFM_CRYPTO_KEY_DERIVATION_OPERATION = 4, TFM_CRYPTO_AEAD_OPERATION = 5, + TFM_CRYPTO_PAKE_OPERATION = 6, /* Used to force the enum size */ TFM_CRYPTO_OPERATION_TYPE_MAX = INT_MAX @@ -217,6 +218,19 @@ psa_status_t tfm_crypto_random_interface(psa_invec in_vec[], psa_status_t tfm_crypto_hash_interface(psa_invec in_vec[], psa_outvec out_vec[]); +/** + * \brief This function acts as interface for the PAKE module + * + * \param[in] in_vec Array of invec parameters + * \param[out] out_vec Array of outvec parameters + * \param[in] encoded_key Key encoded with partition_id and key_id + * + * \return Return values as described in \ref psa_status_t + */ +psa_status_t tfm_crypto_pake_interface(psa_invec in_vec[], + psa_outvec out_vec[], + struct tfm_crypto_key_id_s *encoded_key); + #ifdef __cplusplus } #endif From a22fef345c7d2287636dab3b750348cc88e8e79f Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Fri, 8 Mar 2024 14:24:50 +0100 Subject: [PATCH 26/65] [nrf noup] Add missing SPU funcs in target_cfg.c Add missing SPU functions for nRF54L15. SPU support in nrfx seems limited at the moment for nRF54L15 and this is a workaround. That's a noup because we expect to revert it when support is more mature. Ref: NCSDK-26277 Signed-off-by: Georgios Vasilakis --- .../nordic_nrf/common/core/target_cfg.c | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 77cb39949..894cb8bc6 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -46,6 +46,59 @@ #define PIN_XL1 0 #define PIN_XL2 1 +/* Use the SPU_PERIPH_PERM_SECUREMAPPING_NonSecure symbol to determine + * if we have and old or new SPU. + */ +#ifdef SPU_PERIPH_PERM_SECUREMAPPING_NonSecure +/* TODO: Remove this temporary fix when the patch from NRFX-3570 is available. + * These symbols named nrf_spu_* were copied from nrf_spu.h. + */ +/** @brief SPU read capabilities for TrustZone Cortex-M secure attribute. */ +typedef enum +{ + NRF_SPU_SECUREMAPPING_NONSECURE = SPU_PERIPH_PERM_SECUREMAPPING_NonSecure, /**< Peripheral is always accessible as non-secure. */ + NRF_SPU_SECUREMAPPING_SECURE = SPU_PERIPH_PERM_SECUREMAPPING_Secure, /**< Peripheral is always accessible as secure. */ + NRF_SPU_SECUREMAPPING_USERSELECTABLE = SPU_PERIPH_PERM_SECUREMAPPING_UserSelectable, /**< Non-secure or secure attribute for this peripheral is defined by the PERIPH[n].PERM register. */ + NRF_SPU_SECUREMAPPING_SPLIT = SPU_PERIPH_PERM_SECUREMAPPING_Split, /**< Peripheral implements the split security mechanism. */ +} nrf_spu_securemapping_t; + +void nrf_spu_periph_perm_secattr_set(NRF_SPU_Type * p_reg, + uint8_t index, + bool enable) +{ + p_reg->PERIPH[index].PERM = ((p_reg->PERIPH[index].PERM & ~SPU_PERIPH_PERM_SECATTR_Msk) + | ((enable ? SPU_PERIPH_PERM_SECATTR_Secure : + SPU_PERIPH_PERM_SECATTR_NonSecure) << + SPU_PERIPH_PERM_SECATTR_Pos)); +} + +void nrf_spu_periph_perm_dmasec_set(NRF_SPU_Type * p_reg, + uint8_t index, + bool enable) +{ + p_reg->PERIPH[index].PERM = ((p_reg->PERIPH[index].PERM & ~SPU_PERIPH_PERM_DMASEC_Msk) + | ((enable ? SPU_PERIPH_PERM_DMASEC_Secure : + SPU_PERIPH_PERM_DMASEC_NonSecure) << + SPU_PERIPH_PERM_DMASEC_Pos)); +} + +bool nrf_spu_periph_perm_present_get(NRF_SPU_Type const * p_reg, + uint8_t index) +{ + return (p_reg->PERIPH[index].PERM & SPU_PERIPH_PERM_PRESENT_Msk) >> + SPU_PERIPH_PERM_PRESENT_Pos; +} + +nrf_spu_securemapping_t nrf_spu_periph_perm_securemapping_get(NRF_SPU_Type const * p_reg, + uint8_t index) +{ + return (nrf_spu_securemapping_t)((p_reg->PERIPH[index].PERM + & SPU_PERIPH_PERM_SECUREMAPPING_Msk) >> + SPU_PERIPH_PERM_SECUREMAPPING_Pos); +} + +#endif /* SPU_PERIPH_PERM_SECUREMAPPING_NonSecure */ + #if TFM_PERIPHERAL_DCNF_SECURE struct platform_data_t tfm_peripheral_dcnf = { NRF_DCNF_S_BASE, From 5454e8edfcb240e564405cc92708716e5846770c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Mon, 25 Mar 2024 15:02:39 +0100 Subject: [PATCH 27/65] Revert "[nrf noup] Add missing SPU funcs in target_cfg.c" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a22fef345c7d2287636dab3b750348cc88e8e79f. Signed-off-by: Andrzej Głąbek --- .../nordic_nrf/common/core/target_cfg.c | 53 ------------------- 1 file changed, 53 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 894cb8bc6..77cb39949 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -46,59 +46,6 @@ #define PIN_XL1 0 #define PIN_XL2 1 -/* Use the SPU_PERIPH_PERM_SECUREMAPPING_NonSecure symbol to determine - * if we have and old or new SPU. - */ -#ifdef SPU_PERIPH_PERM_SECUREMAPPING_NonSecure -/* TODO: Remove this temporary fix when the patch from NRFX-3570 is available. - * These symbols named nrf_spu_* were copied from nrf_spu.h. - */ -/** @brief SPU read capabilities for TrustZone Cortex-M secure attribute. */ -typedef enum -{ - NRF_SPU_SECUREMAPPING_NONSECURE = SPU_PERIPH_PERM_SECUREMAPPING_NonSecure, /**< Peripheral is always accessible as non-secure. */ - NRF_SPU_SECUREMAPPING_SECURE = SPU_PERIPH_PERM_SECUREMAPPING_Secure, /**< Peripheral is always accessible as secure. */ - NRF_SPU_SECUREMAPPING_USERSELECTABLE = SPU_PERIPH_PERM_SECUREMAPPING_UserSelectable, /**< Non-secure or secure attribute for this peripheral is defined by the PERIPH[n].PERM register. */ - NRF_SPU_SECUREMAPPING_SPLIT = SPU_PERIPH_PERM_SECUREMAPPING_Split, /**< Peripheral implements the split security mechanism. */ -} nrf_spu_securemapping_t; - -void nrf_spu_periph_perm_secattr_set(NRF_SPU_Type * p_reg, - uint8_t index, - bool enable) -{ - p_reg->PERIPH[index].PERM = ((p_reg->PERIPH[index].PERM & ~SPU_PERIPH_PERM_SECATTR_Msk) - | ((enable ? SPU_PERIPH_PERM_SECATTR_Secure : - SPU_PERIPH_PERM_SECATTR_NonSecure) << - SPU_PERIPH_PERM_SECATTR_Pos)); -} - -void nrf_spu_periph_perm_dmasec_set(NRF_SPU_Type * p_reg, - uint8_t index, - bool enable) -{ - p_reg->PERIPH[index].PERM = ((p_reg->PERIPH[index].PERM & ~SPU_PERIPH_PERM_DMASEC_Msk) - | ((enable ? SPU_PERIPH_PERM_DMASEC_Secure : - SPU_PERIPH_PERM_DMASEC_NonSecure) << - SPU_PERIPH_PERM_DMASEC_Pos)); -} - -bool nrf_spu_periph_perm_present_get(NRF_SPU_Type const * p_reg, - uint8_t index) -{ - return (p_reg->PERIPH[index].PERM & SPU_PERIPH_PERM_PRESENT_Msk) >> - SPU_PERIPH_PERM_PRESENT_Pos; -} - -nrf_spu_securemapping_t nrf_spu_periph_perm_securemapping_get(NRF_SPU_Type const * p_reg, - uint8_t index) -{ - return (nrf_spu_securemapping_t)((p_reg->PERIPH[index].PERM - & SPU_PERIPH_PERM_SECUREMAPPING_Msk) >> - SPU_PERIPH_PERM_SECUREMAPPING_Pos); -} - -#endif /* SPU_PERIPH_PERM_SECUREMAPPING_NonSecure */ - #if TFM_PERIPHERAL_DCNF_SECURE struct platform_data_t tfm_peripheral_dcnf = { NRF_DCNF_S_BASE, From 0cf4946d14e4b67eec9b5cc139a70469892ec068 Mon Sep 17 00:00:00 2001 From: Summer Qin Date: Wed, 29 Nov 2023 11:01:55 +0800 Subject: [PATCH 28/65] [nrf fromtree] Crypto: Add missing key derivation APIs in the interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following APIs are in psa/crypto.h hence they need to be linkable by partitions/applications: * psa_key_derivation_input_integer * psa_key_derivation_verify_bytes * psa_key_derivation_verify_key Only psa_key_derivation_input_integer is currently implemented by Mbed TLS 3.5.0 as the PSA Crypto backend hence it's the only one requiring full plumbing from interface through service up to the Crypto backend library call. Signed-off-by: Summer Qin Change-Id: I69f262e5a95e04935c8bec05b0b6b509f4b65ad4 (cherry picked from commit cec79b0328125b6730879966261ddf1a869440c4) Signed-off-by: Vidar Lillebø --- interface/include/tfm_crypto_defs.h | 6 ++- interface/src/tfm_crypto_api.c | 39 ++++++++++++++++++- .../partitions/crypto/crypto_key_derivation.c | 4 ++ secure_fw/partitions/crypto/crypto_spe.h | 6 +++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h index fcfc218ba..4b3cfca75 100644 --- a/interface/include/tfm_crypto_defs.h +++ b/interface/include/tfm_crypto_defs.h @@ -47,7 +47,6 @@ struct tfm_crypto_pack_iovec { uint32_t op_handle; /*!< Frontend context handle associated to a * multipart operation */ - size_t capacity; /*!< Key derivation capacity */ size_t ad_length; /*!< Additional Data length for multipart AEAD */ size_t plaintext_length; /*!< Plaintext length for multipart AEAD */ @@ -59,6 +58,10 @@ struct tfm_crypto_pack_iovec { */ uint16_t step; /*!< Key derivation step */ psa_pake_role_t role; /*!< PAKE role */ + union { + size_t capacity; /*!< Key derivation capacity */ + uint64_t value; /*!< Key derivation integer for update*/ + }; }; /** @@ -155,6 +158,7 @@ enum tfm_crypto_group_id { X(TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY) \ X(TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES) \ X(TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY) \ + X(TFM_CRYPTO_KEY_DERIVATION_INPUT_INTEGER) \ X(TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT) \ X(TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES) \ X(TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY) \ diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c index 0164ae8ac..4dc7ea81d 100644 --- a/interface/src/tfm_crypto_api.c +++ b/interface/src/tfm_crypto_api.c @@ -1657,7 +1657,6 @@ TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_key)( return API_DISPATCH(in_vec, out_vec); } - TFM_CRYPTO_API(psa_status_t, psa_pake_setup) (psa_pake_operation_t *operation, psa_key_id_t password_key, const psa_pake_cipher_suite_t *cipher_suite) { @@ -1811,4 +1810,40 @@ TFM_CRYPTO_API(psa_status_t, psa_pake_abort)(psa_pake_operation_t *operation) { }; return API_DISPATCH(in_vec, out_vec); -} \ No newline at end of file +} + +TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_integer)( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + uint64_t value) +{ + struct tfm_crypto_pack_iovec iov = { + .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_INTEGER_SID, + .step = step, + .value = value, + .op_handle = operation->handle, + }; + + psa_invec in_vec[] = { + {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}, + }; + + return API_DISPATCH_NO_OUTVEC(in_vec); +} + +TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_bytes)( + psa_key_derivation_operation_t *operation, + const uint8_t *expected_output, + size_t output_length) +{ + /* To be implemented when the PSA backend supports it */ + return PSA_ERROR_NOT_SUPPORTED; +} + +TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_key)( + psa_key_derivation_operation_t *operation, + psa_key_id_t expected) +{ + /* To be implemented when the PSA backend supports it */ + return PSA_ERROR_NOT_SUPPORTED; +} diff --git a/secure_fw/partitions/crypto/crypto_key_derivation.c b/secure_fw/partitions/crypto/crypto_key_derivation.c index f9fb1dafb..d642bdf10 100644 --- a/secure_fw/partitions/crypto/crypto_key_derivation.c +++ b/secure_fw/partitions/crypto/crypto_key_derivation.c @@ -94,6 +94,10 @@ psa_status_t tfm_crypto_key_derivation_interface(psa_invec in_vec[], return psa_key_derivation_input_bytes(operation, iov->step, data, data_length); } + case TFM_CRYPTO_KEY_DERIVATION_INPUT_INTEGER_SID: + { + return psa_key_derivation_input_integer(operation, iov->step, iov->value); + } case TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID: { uint8_t *output = out_vec[0].base; diff --git a/secure_fw/partitions/crypto/crypto_spe.h b/secure_fw/partitions/crypto/crypto_spe.h index ba017898b..091b894a5 100644 --- a/secure_fw/partitions/crypto/crypto_spe.h +++ b/secure_fw/partitions/crypto/crypto_spe.h @@ -30,8 +30,14 @@ PSA_FUNCTION_NAME(psa_key_derivation_set_capacity) #define psa_key_derivation_input_bytes \ PSA_FUNCTION_NAME(psa_key_derivation_input_bytes) +#define psa_key_derivation_input_integer \ + PSA_FUNCTION_NAME(psa_key_derivation_input_integer) +#define psa_key_derivation_verify_key \ + PSA_FUNCTION_NAME(psa_key_derivation_verify_key) #define psa_key_derivation_output_bytes \ PSA_FUNCTION_NAME(psa_key_derivation_output_bytes) +#define psa_key_derivation_verify_bytes \ + PSA_FUNCTION_NAME(psa_key_derivation_verify_bytes) #define psa_key_derivation_input_key \ PSA_FUNCTION_NAME(psa_key_derivation_input_key) #define psa_key_derivation_output_key \ From 42494c104f56e247443d89c316911b0ffc11f6bd Mon Sep 17 00:00:00 2001 From: Anton Komlev Date: Wed, 3 Apr 2024 12:36:25 +0100 Subject: [PATCH 29/65] [nrf fromtree] TFMV-7: SPM: Fix ARoT to PRot data access vulnerability. Please check the advisory document for details. Signed-off-by: Anton Komlev Change-Id: I3fc948c948379e5a36cc577bdbac7c5f7a2c3d1e Ref: NCSDK-26942 (cherry picked from commit e6f5d8c065115a2531128066a735cce1345f6197) Signed-off-by: Markus Swarowsky --- .../debug_log_vulnerability.rst | 69 +++++++++++++++++++ docs/security/security_advisories/index.rst | 4 ++ secure_fw/spm/core/tfm_svcalls.c | 17 ++++- 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 docs/security/security_advisories/debug_log_vulnerability.rst diff --git a/docs/security/security_advisories/debug_log_vulnerability.rst b/docs/security/security_advisories/debug_log_vulnerability.rst new file mode 100644 index 000000000..279dca0be --- /dev/null +++ b/docs/security/security_advisories/debug_log_vulnerability.rst @@ -0,0 +1,69 @@ +Advisory TFMV-7 +=============== + ++------------------+-----------------------------------------------------------+ +| Title | ARoT can access PRoT data via debug logging functionality | ++==================+===========================================================+ +| CVE ID | `CVE-2023-51712`_ | ++------------------+-----------------------------------------------------------+ +| Public | The issue was publicly reported on 2023.12.04 | +| Disclosure Date | | ++------------------+-----------------------------------------------------------+ +| Versions | All version up to TF-M v2.0.0 inclusive | +| Affected | | ++------------------+-----------------------------------------------------------+ +| Configurations | IPC mode with TFM_SP_LOG_RAW_ENABLED=1 | ++------------------+-----------------------------------------------------------+ +| Impact | A malicious ARoT partition can expose any part of memory | +| | via stdio interface if TFM_SP_LOG_RAW_ENABLED is set | ++------------------+-----------------------------------------------------------+ +| Fix Version | TBD | ++------------------+-----------------------------------------------------------+ +| Credit | Roman Mazurak, Infineon | ++------------------+-----------------------------------------------------------+ + +Background +---------- + +TF-M log subsystem if enabled by ``TFM_SP_LOG_RAW_ENABLED`` config option, +uses a SVC call to print logging messages on the stdio output interface. +Since the SVC handler has the highest privilege level and full memory +access, this communication channel can be exploited to expose any memory content +to stdout device, usually UART. +The logging subsystem is available to the secure side only but in isolation +level 2 and higher PSA Root of Trust partitions (PRoT) shall be protected +from an access from Application Root of Trust (ARoT) partitions. Although +a direct call of ``tfm_hal_output_sp_log()`` from ARoT partition will be +blocked by MPU raising the ``MemoryManagement()`` exception, a malicious +ARoT partition can create an alternative SVC call to output any memory +data like this: + +.. code-block:: c + + static int tfm_output_unpriv_string(const unsigned char *str, size_t len) + { + __ASM volatile("SVC %0 \n" + "BX LR \n" + : : "I" (2)); + } + +Impact +------ + +In IPC mode with PSA isolation level 2 and higher and ``TFM_SP_LOG_RAW_ENABLED`` +option enabled an ARoT partition can expose to the stdout device any memory +data using TF-M logging subsystem via SVC call. + +Mitigation +---------- + +Ensure that data sent for logging belongs to the current partition. For that purpose +``tfm_hal_memory_check(curr_partition->boundary, data, size, TFM_HAL_ACCESS_READABLE)`` +is added to the logging function of the SVC handler. If the check fails +then ``tfm_core_panic()`` is invoked and system halts. + +.. _CVE-2023-51712: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-51712 + +--------------------- + +*Copyright (c) 2024, Arm Limited. All rights reserved.* diff --git a/docs/security/security_advisories/index.rst b/docs/security/security_advisories/index.rst index 249f38255..c7829cedf 100644 --- a/docs/security/security_advisories/index.rst +++ b/docs/security/security_advisories/index.rst @@ -12,6 +12,7 @@ Security Advisories profile_small_key_id_encoding_vulnerability fwu_write_vulnerability cc3xx_partial_tag_compare_on_chacha20_poly1305 + debug_log_vulnerability +------------+-----------------------------------------------------------------+ | ID | Title | @@ -33,6 +34,8 @@ Security Advisories | |TFMV-6| | Partial tag comparison when using Chacha20-Poly1305 on the PSA | | | driver API interface in CryptoCell enabled platforms | +------------+-----------------------------------------------------------------+ +| |TFMV-7| | ARoT can access PRoT data via debug logging functionality | ++------------+-----------------------------------------------------------------+ .. |TFMV-1| replace:: :doc:`TFMV-1 ` .. |TFMV-2| replace:: :doc:`TFMV-2 ` @@ -40,6 +43,7 @@ Security Advisories .. |TFMV-4| replace:: :doc:`TFMV-4 ` .. |TFMV-5| replace:: :doc:`TFMV-5 ` .. |TFMV-6| replace:: :doc:`TFMV-6 ` +.. |TFMV-7| replace:: :doc:`TFMV-7 ` -------------- diff --git a/secure_fw/spm/core/tfm_svcalls.c b/secure_fw/spm/core/tfm_svcalls.c index 16474180a..3ab48c7ba 100644 --- a/secure_fw/spm/core/tfm_svcalls.c +++ b/secure_fw/spm/core/tfm_svcalls.c @@ -169,6 +169,11 @@ static int32_t prepare_to_thread_mode_spm(uint8_t svc_number, uint32_t *ctx, uin static uint32_t handle_spm_svc_requests(uint32_t svc_number, uint32_t exc_return, uint32_t *svc_args, uint32_t *msp) { +#if TFM_SP_LOG_RAW_ENABLED + struct partition_t *curr_partition; + fih_int fih_rc = FIH_FAILURE; +#endif + switch (svc_number) { case TFM_SVC_SPM_INIT: exc_return = tfm_spm_init(); @@ -194,7 +199,17 @@ static uint32_t handle_spm_svc_requests(uint32_t svc_number, uint32_t exc_return #endif #if TFM_SP_LOG_RAW_ENABLED case TFM_SVC_OUTPUT_UNPRIV_STRING: - svc_args[0] = tfm_hal_output_spm_log((const char *)svc_args[0], svc_args[1]); + /* Protect PRoT data from unauthorised access from ARoT partition. + * This fixes the TFMV-7 vulnerability + */ + curr_partition = GET_CURRENT_COMPONENT(); + FIH_CALL(tfm_hal_memory_check, fih_rc, curr_partition->boundary, (uintptr_t)svc_args[0], + svc_args[1], TFM_HAL_ACCESS_READABLE); + if (fih_eq(fih_rc, fih_int_encode(PSA_SUCCESS))) { + svc_args[0] = tfm_hal_output_spm_log((const char *)svc_args[0], svc_args[1]); + } else { + tfm_core_panic(); + } break; #endif #if TFM_ISOLATION_LEVEL > 1 From 8959d4cc5fa4bc00c1f51d680586f601453db860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Mon, 18 Mar 2024 15:31:30 +0100 Subject: [PATCH 30/65] [nrf fromlist] ps: Fix the support for disabling PS_ENCRYPTION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromlist: https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/27311 It is supported to disable PS_ENCRYPTION, but when one tries to do so you get a compilation error because ps_object_defs.h is using encryption symbols unconditionally. Signed-off-by: Sebastian Bøe Change-Id: Iebfc88ada9ccc45152224108cd8530de331ef1c5 --- secure_fw/partitions/protected_storage/ps_object_defs.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/secure_fw/partitions/protected_storage/ps_object_defs.h b/secure_fw/partitions/protected_storage/ps_object_defs.h index 7b0265443..ca66d0c77 100644 --- a/secure_fw/partitions/protected_storage/ps_object_defs.h +++ b/secure_fw/partitions/protected_storage/ps_object_defs.h @@ -45,8 +45,11 @@ struct ps_obj_header_t { #define PS_MAX_OBJECT_DATA_SIZE PS_MAX_ASSET_SIZE + +#ifdef PS_ENCRYPTION #define PS_TAG_IV_LEN_MAX ((PS_TAG_LEN_BYTES > PS_IV_LEN_BYTES) ? \ PS_TAG_LEN_BYTES : PS_IV_LEN_BYTES) +#endif /*! * \struct ps_object_t @@ -57,7 +60,9 @@ struct ps_obj_header_t { struct ps_object_t { struct ps_obj_header_t header; /*!< Object header */ uint8_t data[PS_MAX_OBJECT_DATA_SIZE]; /*!< Object data */ +#ifdef PS_ENCRYPTION uint8_t tag_iv[PS_TAG_IV_LEN_MAX]; +#endif }; From 68e552fb5aae3c42087fa4ffbd3e8426f311b370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Mon, 18 Mar 2024 15:44:32 +0100 Subject: [PATCH 31/65] [nrf fromlist] platform: nordic_nrf: Add MDK defines required by tfm_ns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromlist: https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/27313 Add MDK defines required by tfm_ns. Not all platforms need these defines. But to ease porting we unconditionally add them to all platforms. Signed-off-by: Sebastian Bøe Change-Id: I434a817f13a198e6368710e1d6fffd96c1bea64f --- .../target/nordic_nrf/common/core/ns/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt index f73babec2..f2909dafe 100644 --- a/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/ns/CMakeLists.txt @@ -56,3 +56,14 @@ target_compile_definitions(platform_ns NRF_TRUSTZONE_NONSECURE DOMAIN_NS=1 ) + +target_compile_definitions(platform_ns + PUBLIC + # We don't need to trim the device in the non-secure image because it + # is the secure image's responsiblity to do this. + NRF_DISABLE_FICR_TRIMCNF + # The glitch detector can only be configured from a secure image so + # we need to skip this configuration. + NRF_SKIP_GLITCHDETECTOR_DISABLE +) + From 308344ff590e33811b835261248a7cba64d2dfa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 15 Mar 2024 15:09:45 +0100 Subject: [PATCH 32/65] [nrf fromlist] platform: nordic_nrf: add support for more UARTs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromlist: https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/27314 Add support for more UARTs. Signed-off-by: Sebastian Bøe Change-Id: Iffdce1df87fd603cf76f435028896c12f1d2c276 --- .../nordic_nrf/common/core/cmsis_drivers/Driver_USART.c | 8 ++++++-- platform/ext/target/nordic_nrf/common/core/nrfx_config.h | 5 ++++- platform/ext/target/nordic_nrf/common/core/target_cfg.h | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index 80f4f9201..c44ab8041 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -39,7 +39,7 @@ #define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2) -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART22 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART22 #define PSEL_DISCONNECTED 0xFFFFFFFFUL @@ -439,8 +439,12 @@ DRIVER_USART(3); #endif // TODO: NCSDK-25009: Support choosing an instance for TF-M +#if RTE_USART20 +DRIVER_USART(20); +#endif + #if RTE_USART22 DRIVER_USART(22); #endif -#endif /* RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART22 */ +#endif /* RTE_USART0 || RTE_USART1 || etc. */ diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h index d25689ffe..dadddeb97 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h +++ b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h @@ -48,7 +48,7 @@ #endif /* RTE_FLASH0 */ -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART22 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART22 #define NRFX_UARTE_ENABLED 1 #endif #if RTE_USART0 @@ -65,6 +65,9 @@ #endif // TODO: NCSDK-25009: Moonlight: Make it possible to use different UARTS with TF-M +#if RTE_USART20 +#define NRFX_UARTE20_ENABLED 1 +#endif #if RTE_USART22 #define NRFX_UARTE22_ENABLED 1 #endif diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h index 1680abb0b..df3dc4fd3 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -46,7 +46,7 @@ #endif #ifdef NRF54L15_ENGA_XXAA -#define NS_DRIVER_STDIO Driver_USART22 +#define NS_DRIVER_STDIO Driver_USART20 #else #define NS_DRIVER_STDIO Driver_USART0 #endif From 17c198f991ce2ed9e63d4b54c7bea0562d86e697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Mon, 18 Mar 2024 16:03:20 +0100 Subject: [PATCH 33/65] [nrf fromlist] platform: nordic_nrf: Support RRAMC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromlist: https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/27315 Support the RRAMC driver from nrfx. Signed-off-by: Sebastian Bøe Change-Id: I5c797d15f4acb4f59aeb9f737b41294ff624dfb1 --- platform/ext/target/nordic_nrf/common/core/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index 1ad66c344..43c7b7662 100644 --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -22,7 +22,9 @@ endif() # At the time of writing there is no systematic way to identify which # NVM technology is used by the SoC from the Kconfig, so we just # hardcode this information here instead. -if(PSA_API_TEST_TARGET STREQUAL nrf54l15) +if((NRF_SOC_VARIANT STREQUAL nrf54l15) OR (target STREQUAL nrf54l15)) + # Maybe we only need to check one of these options but these + # variables keep changing so we check both to be future proof set(HAS_RRAMC 1) else() set(HAS_NVMC 1) From 813aa165d8a924c3377508ad46f5c13373f6ed53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 14 Mar 2024 13:56:25 +0100 Subject: [PATCH 34/65] [nrf noup] platform: nordic_nrf: Add support for 54l MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Move files from nrf to TF-M to make the platform support more aligned and therefore easier to understand. Also, add misc. files required to get psa-arch-tests to work. Signed-off-by: Sebastian Bøe Change-Id: I2e20b71414b4e28a6243e35e940d9217aa51405d --- .../nordic_nrf/common/core/startup_nrf54l15.c | 1 - .../nordic_nrf/common/nrf54l15/CMakeLists.txt | 51 +++++++++++++++++++ .../nordic_nrf/common/nrf54l15/config.cmake | 17 +++++++ .../nordic_nrf/common/nrf54l15/cpuarch.cmake | 23 +++++++++ .../nordic_nrf/common/nrf54l15/mmio_defs.h | 32 ++++++++++++ .../nrfx_config_nrf54l15_application.h | 0 .../common/nrf54l15/ns/CMakeLists.txt | 28 ++++++++++ .../common/nrf54l15/partition/flash_layout.h | 23 +++++++++ .../common/nrf54l15/partition/region_defs.h | 23 +++++++++ .../tests/psa_arch_tests_config.cmake | 9 ++++ .../common/nrf54l15/tfm_peripherals_def.h | 42 +++++++++++++++ .../ns/CMakeLists.txt | 31 +++++++++++ .../ns/cpuarch_ns.cmake | 10 ++++ .../tests/psa_arch_tests_config.cmake | 8 +++ .../tests/tfm_tests_config.cmake | 8 +++ 15 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/CMakeLists.txt create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/cpuarch.cmake create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h rename platform/ext/target/nordic_nrf/common/{core/common => nrf54l15}/nrfx_config_nrf54l15_application.h (100%) create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/ns/CMakeLists.txt create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/partition/flash_layout.h create mode 100755 platform/ext/target/nordic_nrf/common/nrf54l15/partition/region_defs.h create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/tests/psa_arch_tests_config.cmake create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h create mode 100644 platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/CMakeLists.txt create mode 100644 platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/cpuarch_ns.cmake create mode 100644 platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/psa_arch_tests_config.cmake create mode 100644 platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/tfm_tests_config.cmake diff --git a/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c index 1cbe196ba..a08a12611 100644 --- a/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c +++ b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c @@ -34,7 +34,6 @@ #define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) #include "cmsis.h" -#include "hw_init.h" #include "startup.h" #include "exception_info.h" diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf54l15/CMakeLists.txt new file mode 100644 index 000000000..e093190b3 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/CMakeLists.txt @@ -0,0 +1,51 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020-2022, Arm Limited. All rights reserved. +# Copyright (c) 2020, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +cmake_policy(SET CMP0076 NEW) +set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) + +set(target nrf54l15) +add_subdirectory(../core nrf_common) + +#========================= Platform Secure ====================================# + +target_include_directories(platform_s + PUBLIC + . +) + +target_sources(platform_s + PRIVATE + ${HAL_NORDIC_PATH}/nrfx/mdk/system_nrf54l.c +) + +target_compile_definitions(platform_s + PUBLIC + NRF_SKIP_FICR_NS_COPY_TO_RAM +) + +#========================= tfm_spm ============================================# + +target_sources(tfm_spm + PRIVATE + $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c> +) + +#========================= Files for building NS side platform ================# + +install(FILES nrfx_config_nrf54l15_application.h + ns/CMakeLists.txt + config.cmake + cpuarch.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf54l15 +) + +install(DIRECTORY partition + tests + DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf54l15 +) diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake b/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake new file mode 100644 index 000000000..baa1e4d1f --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Nordic Semiconductor ASA. +# Copyright (c) 2020-2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +include(${PLATFORM_PATH}/common/core/config.cmake) + +set(SECURE_UART1 ON CACHE BOOL "Enable secure UART1") +set(NRF_NS_STORAGE OFF CACHE BOOL "Enable non-secure storage partition") +set(BL2 OFF CACHE BOOL "Whether to build BL2") +set(NRF_NS_SECONDARY OFF CACHE BOOL "Enable non-secure secondary partition") + +# NCSDK-26630: Not supported yet +set(PS_ENCRYPTION OFF CACHE BOOL "") diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/cpuarch.cmake b/platform/ext/target/nordic_nrf/common/nrf54l15/cpuarch.cmake new file mode 100644 index 000000000..18c7fa920 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/cpuarch.cmake @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# cpuarch.cmake is used to set things that related to the platform that are both +# immutable and global, which is to say they should apply to any kind of project +# that uses this platform. In practice this is normally compiler definitions and +# variables related to hardware. + +# Set architecture and CPU +set(TFM_SYSTEM_PROCESSOR cortex-m33) +set(TFM_SYSTEM_ARCHITECTURE armv8-m.main) +set(CONFIG_TFM_FP_ARCH "fpv5-sp-d16") + +add_compile_definitions( + NRF54L15_ENGA_XXAA # Required by nrf.h + NRF_APPLICATION + # SKIP configuring the SAU from the MDK as it does not fit TF-M's needs + NRF_SKIP_SAU_CONFIGURATION + NRF_SKIP_FICR_NS_COPY_TO_RAM +) diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h b/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h new file mode 100644 index 000000000..f45682cc2 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + * + */ + +#ifndef __MMIO_DEFS_H__ +#define __MMIO_DEFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "tfm_peripherals_def.h" +#include "tfm_peripherals_config.h" +#include "handle_attr.h" + +/* Allowed named MMIO of this platform */ +const uintptr_t partition_named_mmio_list[] = { + /* TODO: NCSDK-22597: Populate this list */ +#if TFM_PERIPHERAL_TIMER00_SECURE + (uintptr_t)TFM_PERIPHERAL_TIMER00, +#endif +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __MMIO_DEFS_H__ */ diff --git a/platform/ext/target/nordic_nrf/common/core/common/nrfx_config_nrf54l15_application.h b/platform/ext/target/nordic_nrf/common/nrf54l15/nrfx_config_nrf54l15_application.h similarity index 100% rename from platform/ext/target/nordic_nrf/common/core/common/nrfx_config_nrf54l15_application.h rename to platform/ext/target/nordic_nrf/common/nrf54l15/nrfx_config_nrf54l15_application.h diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/ns/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/nrf54l15/ns/CMakeLists.txt new file mode 100644 index 000000000..541b039f7 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/ns/CMakeLists.txt @@ -0,0 +1,28 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +cmake_policy(SET CMP0076 NEW) +set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) + +set(target nrf54l15) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../core nrf_common) + +target_include_directories(platform_ns + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) + +target_sources(platform_ns + PRIVATE + ${HAL_NORDIC_PATH}/nrfx/mdk/system_nrf54l.c +) + +target_compile_definitions(platform_ns + PUBLIC + NRF_TRUSTZONE_NONSECURE + DOMAIN_NS=1 +) diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/partition/flash_layout.h b/platform/ext/target/nordic_nrf/common/nrf54l15/partition/flash_layout.h new file mode 100644 index 000000000..08b90647e --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/partition/flash_layout.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2022 Arm Limited. All rights reserved. + * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FLASH_LAYOUT_H__ +#define __FLASH_LAYOUT_H__ + +#error "not supported yet" + +#endif /* __FLASH_LAYOUT_H__ */ diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/partition/region_defs.h b/platform/ext/target/nordic_nrf/common/nrf54l15/partition/region_defs.h new file mode 100755 index 000000000..212106c96 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/partition/region_defs.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017-2022 Arm Limited. All rights reserved. + * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "flash_layout.h" + +#endif /* __REGION_DEFS_H__ */ diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/tests/psa_arch_tests_config.cmake b/platform/ext/target/nordic_nrf/common/nrf54l15/tests/psa_arch_tests_config.cmake new file mode 100644 index 000000000..88586c115 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/tests/psa_arch_tests_config.cmake @@ -0,0 +1,9 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +# Platform-specific configurations +set(PSA_API_TEST_TARGET "nrf54l15") diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h new file mode 100644 index 000000000..42bdb35bd --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + * + */ + +#ifndef __TFM_PERIPHERALS_DEF_H__ +#define __TFM_PERIPHERALS_DEF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + /* TODO: NCSDK-22597: Define peripherals */ + +#include + +#define TFM_TIMER0_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER0)) + +extern struct platform_data_t tfm_peripheral_timer0; + +#define TFM_PERIPHERAL_TIMER0 (&tfm_peripheral_timer0) + +/* + * Quantized default IRQ priority, the value is: + * (Number of configurable priority) / 4: (1UL << __NVIC_PRIO_BITS) / 4 + */ +#define DEFAULT_IRQ_PRIORITY (1UL << (__NVIC_PRIO_BITS - 2)) + +#define TFM_PERIPHERAL_STD_UART TFM_PERIPHERAL_UARTE1 + +#ifdef PSA_API_TEST_IPC +/* see other platforms when supporting this */ +#error "Not supported yet" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_PERIPHERALS_DEF_H__ */ diff --git a/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/CMakeLists.txt b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/CMakeLists.txt new file mode 100644 index 000000000..5cd4273e4 --- /dev/null +++ b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/CMakeLists.txt @@ -0,0 +1,31 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +cmake_policy(SET CMP0076 NEW) +set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(NRF_BOARD_SELECTED True) + +add_library(platform_ns STATIC) + +# Get the value of HAL_NORDIC_PATH +include(${CMAKE_CURRENT_LIST_DIR}/common/core/config_nordic_nrf_spe.cmake) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common/nrf54l15 nrf54l15) + +target_include_directories(platform_ns + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) + +target_link_libraries(platform_ns + PUBLIC + platform_region_defs +) + +target_include_directories(platform_region_defs + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/common/nrf54l15/partition +) diff --git a/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/cpuarch_ns.cmake b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/cpuarch_ns.cmake new file mode 100644 index 000000000..25f91fb54 --- /dev/null +++ b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: BSD-3-Clause +#------------------------------------------------------------------------------- + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf54l15/cpuarch.cmake) diff --git a/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/psa_arch_tests_config.cmake b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/psa_arch_tests_config.cmake new file mode 100644 index 000000000..327e36c66 --- /dev/null +++ b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/psa_arch_tests_config.cmake @@ -0,0 +1,8 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +include(${PLATFORM_PATH}/common/nrf54l15/tests/psa_arch_tests_config.cmake) diff --git a/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/tfm_tests_config.cmake b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/tfm_tests_config.cmake new file mode 100644 index 000000000..619f1f92c --- /dev/null +++ b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tests/tfm_tests_config.cmake @@ -0,0 +1,8 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2023, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +include(${PLATFORM_PATH}/common/core/tests/tfm_tests_config.cmake) From 21287579d4d76f0c4634a9634289f17534d5ed3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Wed, 20 Mar 2024 16:29:34 +0100 Subject: [PATCH 35/65] [nrf noup] platform: nordic_nrf: Add support for 54l MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l The HW guys said it should be set to 0. Signed-off-by: Sebastian Bøe Change-Id: I335401d70b8aa8088c6af2c9c824e3d0af087698 --- platform/ext/target/nordic_nrf/common/core/target_cfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 77cb39949..b49a812c1 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -901,7 +901,7 @@ static void init_mpc_region_override(struct mpc_region_override * override) .secure_mask = true, }, .perm = 0, /* 0 for non-secure */ - .owner_id = 1, // TODO: NCSDK-25169: Investigate if 1 is correct + .owner_id = 0, }; override->permmask = MPC_OVERRIDE_PERM_SECATTR_Msk; From 1a178885e758b2a40a60a0dd419a29ed94236965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 19 Mar 2024 14:27:01 +0100 Subject: [PATCH 36/65] [nrf noup] platform: nordic_nrf: include autoconf.h from target_cfg.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include autoconf.h from target_cfg.c so we can configure the TF-M image based on the non-secure image's Kconfig. Signed-off-by: Sebastian Bøe Change-Id: I2212f2ec3428f16618334c5583b0e641aa30ea08 --- platform/ext/target/nordic_nrf/common/core/target_cfg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index b49a812c1..b624428a3 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -24,6 +24,8 @@ #include "region.h" #include "array.h" +#include + #include #include From f3cc572a052e7d3fd8d8a0ed292c4cf996efb392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 21 Mar 2024 17:05:34 +0100 Subject: [PATCH 37/65] [nrf noup] platform: nordic_nrf: Add support for 54l MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l use uart30 instead of uart22 as the secure UART Signed-off-by: Sebastian Bøe Change-Id: I3d54602043a9d984908bfa4d9732bc2158fdca2b --- .../common/core/cmsis_drivers/Driver_USART.c | 6 ++-- .../nordic_nrf/common/core/nrfx_config.h | 6 ++-- .../nordic_nrf/common/core/target_cfg.c | 30 +++++++++---------- .../nordic_nrf/common/core/target_cfg.h | 4 +-- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index c44ab8041..803ab82e5 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -39,7 +39,7 @@ #define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2) -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART22 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART30 #define PSEL_DISCONNECTED 0xFFFFFFFFUL @@ -443,8 +443,8 @@ DRIVER_USART(3); DRIVER_USART(20); #endif -#if RTE_USART22 -DRIVER_USART(22); +#if RTE_USART30 +DRIVER_USART(30); #endif #endif /* RTE_USART0 || RTE_USART1 || etc. */ diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h index dadddeb97..1bbe75f6e 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h +++ b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h @@ -48,7 +48,7 @@ #endif /* RTE_FLASH0 */ -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART22 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART30 #define NRFX_UARTE_ENABLED 1 #endif #if RTE_USART0 @@ -68,8 +68,8 @@ #if RTE_USART20 #define NRFX_UARTE20_ENABLED 1 #endif -#if RTE_USART22 -#define NRFX_UARTE22_ENABLED 1 +#if RTE_USART30 +#define NRFX_UARTE30_ENABLED 1 #endif /* diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index b624428a3..dae0086b6 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -244,10 +244,10 @@ struct platform_data_t tfm_peripheral_uarte3 = { }; #endif -#if TFM_PERIPHERAL_UARTE22_SECURE -struct platform_data_t tfm_peripheral_uarte22 = { - NRF_UARTE22_S_BASE, - NRF_UARTE22_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +#if TFM_PERIPHERAL_UARTE30_SECURE +struct platform_data_t tfm_peripheral_uarte30 = { + NRF_UARTE30_S_BASE, + NRF_UARTE30_S_BASE + (sizeof(NRF_UARTE_Type) - 1), }; #endif @@ -689,9 +689,9 @@ enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void) #elif NRF_SECURE_UART_INSTANCE == 1 /* UARTE1 is a secure peripheral, so its IRQ has to target S state */ NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE1)); -#elif NRF_SECURE_UART_INSTANCE == 22 - /* UARTE22 is a secure peripheral, so its IRQ has to target S state */ - NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE22)); +#elif NRF_SECURE_UART_INSTANCE == 30 + /* UARTE30 is a secure peripheral, so its IRQ has to target S state */ + NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_UARTE30)); #endif #endif @@ -1035,7 +1035,7 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) } } - /* TODO: NCSDK-22597: Configure UART22 pins as secure */ + /* TODO: NCSDK-22597: Configure UART30 pins as secure */ for(uint8_t index = 0; index < ARRAY_SIZE(spu_instance->PERIPH); index++) { if(!nrf_spu_periph_perm_present_get(spu_instance, index)) { @@ -1061,11 +1061,11 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) } } - /* Configure TF-M's UART22 peripheral to be secure with secure DMA */ + /* Configure TF-M's UART30 peripheral to be secure with secure DMA */ bool enable = true; /* true means secure */ - uint32_t UART22_SLAVE_INDEX = (NRF_UARTE22_S_BASE & 0x0003F000) >> 12; - nrf_spu_periph_perm_secattr_set(NRF_SPU20, UART22_SLAVE_INDEX, enable); - nrf_spu_periph_perm_dmasec_set(NRF_SPU20, UART22_SLAVE_INDEX, enable); + uint32_t UART30_SLAVE_INDEX = (NRF_UARTE30_S_BASE & 0x0003F000) >> 12; + nrf_spu_periph_perm_secattr_set(NRF_SPU30, UART30_SLAVE_INDEX, enable); + nrf_spu_periph_perm_dmasec_set(NRF_SPU30, UART30_SLAVE_INDEX, enable); #else static const uint8_t target_peripherals[] = { @@ -1108,9 +1108,9 @@ static const uint8_t target_peripherals[] = { #endif NRFX_PERIPHERAL_ID_GET(NRF_SPIM2), NRFX_PERIPHERAL_ID_GET(NRF_SPIM3), - /* When UART22 is a secure peripheral we need to leave Serial-Box 22 as Secure */ -#if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 22) - // TODO: NCSDK-25009: spu_peripheral_config_non_secure((uint32_t)NRF_SPIM22, false); + /* When UART30 is a secure peripheral we need to leave Serial-Box 30 as Secure */ +#if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 30) + // TODO: NCSDK-25009: spu_peripheral_config_non_secure((uint32_t)NRF_SPIM30, false); #endif #ifdef NRF_SPIM4 diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h index df3dc4fd3..e430737c4 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -41,8 +41,8 @@ #define TFM_DRIVER_STDIO Driver_USART0 #elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_DRIVER_STDIO Driver_USART1 -#elif NRF_SECURE_UART_INSTANCE == 22 -#define TFM_DRIVER_STDIO Driver_USART22 +#elif NRF_SECURE_UART_INSTANCE == 30 +#define TFM_DRIVER_STDIO Driver_USART30 #endif #ifdef NRF54L15_ENGA_XXAA From 9c8fa413ec47f59b35500b73210b6e8de4293fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Wed, 10 Apr 2024 10:27:58 +0200 Subject: [PATCH 38/65] [nrf toup] platform: nordic_nrf: Add support shared UART and using UART0 instance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] area: previous short log goes here support 54L as well. Signed-off-by: Sebastian Bøe Change-Id: I06171d72b7d55d45f9719c531fc551fa4be47641 --- .../target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index 803ab82e5..d69a84fa6 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -28,7 +28,8 @@ #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) #endif -#if !(DOMAIN_NS == 1U) && defined(CONFIG_TFM_LOG_SHARE_UART) +// TODO: NCSDK-22597: Support configuring peripherals as secure +#if !(DOMAIN_NS == 1U) && defined(CONFIG_TFM_LOG_SHARE_UART) && defined(NRF_SPU) #define SPU_CONFIGURE_UART #include #endif From 914545280fd8d8f65141398734685b924de10ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vidar=20Lilleb=C3=B8?= Date: Mon, 15 Apr 2024 14:45:38 +0200 Subject: [PATCH 39/65] [nrf noup] Support CMAC KDF and custom builtin solution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows custom key-loader to be used for the PSA core and allows configuring CMAC KDF usage for PS. noup-reason: PSA_ALG_SP800_108_COUNTER_CMAC is not available in upstream. After testing and verifying the solution (determining if we need further changes) we should try to upstream this. Signed-off-by: Vidar Lillebø --- config/config_base.cmake | 1 + interface/include/psa/crypto_values.h | 2 ++ secure_fw/partitions/crypto/crypto_library.c | 2 ++ .../protected_storage/crypto/ps_crypto_interface.c | 9 +++++++-- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/config/config_base.cmake b/config/config_base.cmake index 58d533b00..30fad5d84 100644 --- a/config/config_base.cmake +++ b/config/config_base.cmake @@ -124,6 +124,7 @@ set(BL2_TRAILER_SIZE 0x000 CACHE STRING "BL2 Trailer set(TFM_PARTITION_PROTECTED_STORAGE OFF CACHE BOOL "Enable Protected Storage partition") set(PS_ENCRYPTION ON CACHE BOOL "Enable encryption for Protected Storage partition") set(PS_CRYPTO_AEAD_ALG PSA_ALG_GCM CACHE STRING "The AEAD algorithm to use for authenticated encryption in Protected Storage") +set(PS_CRYPTO_KDF_ALG PSA_ALG_HKDF(PSA_ALG_SHA_256) CACHE STRING "KDF Algorithm to use for Protect Storage") set(TFM_PARTITION_INTERNAL_TRUSTED_STORAGE OFF CACHE BOOL "Enable Internal Trusted Storage partition") set(ITS_ENCRYPTION OFF CACHE BOOL "Enable authenticated encryption of ITS files using platform specific APIs") diff --git a/interface/include/psa/crypto_values.h b/interface/include/psa/crypto_values.h index e4a8c45f6..a2b21ae3f 100644 --- a/interface/include/psa/crypto_values.h +++ b/interface/include/psa/crypto_values.h @@ -2102,6 +2102,8 @@ #define PSA_ALG_IS_PBKDF2_HMAC(alg) \ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_PBKDF2_HMAC_BASE) +#define PSA_ALG_SP800_108_COUNTER_CMAC ((psa_algorithm_t) 0x08000800) + /** The PBKDF2-AES-CMAC-PRF-128 password hashing / key stretching algorithm. * * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2). diff --git a/secure_fw/partitions/crypto/crypto_library.c b/secure_fw/partitions/crypto/crypto_library.c index f65e366be..1f1688123 100644 --- a/secure_fw/partitions/crypto/crypto_library.c +++ b/secure_fw/partitions/crypto/crypto_library.c @@ -153,6 +153,7 @@ psa_status_t tfm_crypto_core_library_key_attributes_to_client( return PSA_SUCCESS; } +#ifdef PSA_CRYPTO_DRIVER_TFM_BUILTIN_KEY_LOADER /** * \brief This function is required by mbed TLS to enable support for * platform builtin keys in the PSA Crypto core layer implemented @@ -181,4 +182,5 @@ psa_status_t mbedtls_psa_platform_get_builtin_key( return PSA_ERROR_DOES_NOT_EXIST; } +#endif /*!@}*/ diff --git a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c index 20e9adfed..d5d6bc603 100644 --- a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c +++ b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c @@ -18,6 +18,10 @@ #define PS_CRYPTO_AEAD_ALG PSA_ALG_GCM #endif +#ifndef PS_CRYPTO_KDF_ALG +#define PS_CRYPTO_KDF_ALG PSA_ALG_HKDF(PSA_ALG_SHA_256) +#endif + /* The PSA key type used by this implementation */ #define PS_KEY_TYPE PSA_KEY_TYPE_AES /* The PSA key usage required by this implementation */ @@ -73,7 +77,7 @@ psa_status_t ps_crypto_setkey(const uint8_t *key_label, size_t key_label_len) psa_set_key_type(&attributes, PS_KEY_TYPE); psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(PS_KEY_LEN_BYTES)); - status = psa_key_derivation_setup(&op, PSA_ALG_HKDF(PSA_ALG_SHA_256)); + status = psa_key_derivation_setup(&op, PS_CRYPTO_KDF_ALG); if (status != PSA_SUCCESS) { return status; } @@ -86,7 +90,8 @@ psa_status_t ps_crypto_setkey(const uint8_t *key_label, size_t key_label_len) } /* Supply the PS key label as an input to the key derivation */ - status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_INFO, + status = psa_key_derivation_input_bytes(&op, PS_CRYPTO_KDF_ALG == PSA_ALG_SP800_108_COUNTER_CMAC ? + PSA_KEY_DERIVATION_INPUT_LABEL : PSA_KEY_DERIVATION_INPUT_INFO, key_label, key_label_len); if (status != PSA_SUCCESS) { From f62fbdda9d6edf67e5564edbc6c4e1ec15f6e7e3 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Tue, 23 Apr 2024 13:44:11 +0200 Subject: [PATCH 40/65] [noup] platform: nordic_nrf: Add LFXO support for 54L fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Configure the XL1 and XL2 to be controlled by GPIO or peripheral. This is need to ust the ow-frequency crystal oscillator (LFXO). This can only been done from secure therefore do it in TF-M Ref: NCSDK-26595 Signed-off-by: Markus Swarowsky --- .../ext/target/nordic_nrf/common/core/target_cfg.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index dae0086b6..e32fba07c 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -45,8 +45,15 @@ #include #endif +#ifdef NRF53_SERIES #define PIN_XL1 0 #define PIN_XL2 1 +#endif +#ifdef NRF54L15_ENGA_XXAA +/* On nRF54L15 XL1 and XL2 are(P1.00) and XL2(P1.01) */ +#define PIN_XL1 32 +#define PIN_XL2 33 +#endif #if TFM_PERIPHERAL_DCNF_SECURE struct platform_data_t tfm_peripheral_dcnf = { @@ -1220,15 +1227,20 @@ static const uint8_t target_peripherals[] = { /* TODO: NCSDK-22597: Support configuring pins as secure or non-secure on nrf54L */ #endif -#ifdef NRF53_SERIES /* Configure properly the XL1 and XL2 pins so that the low-frequency crystal * oscillator (LFXO) can be used. * This configuration can be done only from secure code, as otherwise those * register fields are not accessible. That's why it is placed here. */ +#ifdef NRF53_SERIES nrf_gpio_pin_control_select(PIN_XL1, NRF_GPIO_PIN_SEL_PERIPHERAL); nrf_gpio_pin_control_select(PIN_XL2, NRF_GPIO_PIN_SEL_PERIPHERAL); #endif +#ifdef NRF54L15_ENGA_XXAA + /* NRF54L has a different define */ + nrf_gpio_pin_control_select(PIN_XL1, NRF_GPIO_PIN_SEL_GPIO); + nrf_gpio_pin_control_select(PIN_XL2, NRF_GPIO_PIN_SEL_GPIO); +#endif /* * 91 has an instruction cache. From be6042780b8f8e86ed9333e07d38b3c7f0160802 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Tue, 23 Apr 2024 15:58:33 +0200 Subject: [PATCH 41/65] [nrf noup] platform: nordic_nrf: Add debug port support fixup! [nrf noup] platform: nordic_nrf: Add support for 54l The Product spec says: To enable port protection access for both secure and non-secure modes, use the registers UICR.SECUREAPPROTECT and UICR.APPROTECT. Which is the same behavior than on the 91 platforms so TF-M doesn't need to do anything. Ref: NCSDK-25047 Signed-off-by: Markus Swarowsky --- platform/ext/target/nordic_nrf/common/core/target_cfg.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index e32fba07c..81150740e 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -630,7 +630,7 @@ enum tfm_plat_err_t system_reset_cfg(void) enum tfm_plat_err_t init_debug(void) { -#if defined(NRF91_SERIES) +#if defined(NRF91_SERIES) || defined(NRF54L15_ENGA_XXAA) #if !defined(DAUTH_CHIP_DEFAULT) #error "Debug access on this platform can only be configured by programming the corresponding registers in UICR." @@ -661,10 +661,7 @@ enum tfm_plat_err_t init_debug(void) NRF_CTRLAP->SECUREAPPROTECT.LOCK = CTRLAPPERI_SECUREAPPROTECT_LOCK_LOCK_Locked << CTRLAPPERI_SECUREAPPROTECT_LOCK_LOCK_Msk; -#elif defined(NRF54L15_ENGA_XXAA) - // TODO: NCSDK-25047: Support nRF54L #else - #error "Unrecognized platform" #endif From 017ecdf449cffc4b27c4e9b86e4ef771b452d021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 11 Apr 2024 15:09:55 +0200 Subject: [PATCH 42/65] [nrf noup] platform: nordic_nrf: configure the NRF_RRAMC_S peripheral MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NRF_RRAMC peripheral is hardware-fixed to S so the non-secure image cannot configure the peripheral without costly TF-M system calls. To fix this we do static configuration of the NRF_RRAMC_S peripheral for the NRF_RRAMC_S->CONFIG value during TF-M boot. Signed-off-by: Sebastian Bøe Change-Id: I3a3224e01b6fed022c79489ddaa8a50acf0dc6a6 --- .../common/core/cmsis_drivers/Driver_Flash.c | 55 +++++++++++++------ .../nordic_nrf/common/core/target_cfg.c | 36 ++++++++++++ 2 files changed, 74 insertions(+), 17 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c index c46462d63..e143634c4 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_Flash.c @@ -24,10 +24,19 @@ #include +#include + #if defined(NRF_NVMC_S) #include #elif defined(NRF_RRAMC_S) #include + +#if CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE > 0 +#define WRITE_BUFFER_SIZE CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE +#else +#define WRITE_BUFFER_SIZE 0 +#endif + #else #error "Unrecognized platform" #endif @@ -101,30 +110,31 @@ static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event) return ARM_DRIVER_ERROR; } -#ifdef NRF_RRAMC_S - /* Disable buffering until it's security impact is understood */ - uint8_t write_buff_size = 0; +#ifdef RRAMC_PRESENT + nrfx_rramc_config_t config = NRFX_RRAMC_DEFAULT_CONFIG(WRITE_BUFFER_SIZE); + + config.mode_write = true; + +#if CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE > 0 + config.preload_timeout_enable = true; + config.preload_timeout = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE; +#else + config.preload_timeout_enable = false; + config.preload_timeout = 0; +#endif /* Don't use an event handler until it's understood whether we - * want it or not */ + * want it or not + */ nrfx_rramc_evt_handler_t handler = NULL; - nrfx_rramc_config_t p_config = NRFX_RRAMC_DEFAULT_CONFIG(write_buff_size); + nrfx_err_t err = nrfx_rramc_init(&config, handler); - nrfx_err_t err_code = nrfx_rramc_init(&p_config, handler); - - switch(err_code){ - case NRFX_SUCCESS: - case NRFX_ERROR_ALREADY: - // TF-M appears to be invoking ARM_FLASH_Initialize multiple - // times, but this is of no concern to the driver. - return ARM_DRIVER_OK; - default: - return ARM_DRIVER_ERROR; + if(err != NRFX_SUCCESS && err != NRFX_ERROR_ALREADY) { + return err; } -#else +#endif /* RRAMC_PRESENT */ return ARM_DRIVER_OK; -#endif } static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt) @@ -160,6 +170,15 @@ static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, nrfx_nvmc_words_write(addr, data, cnt); #else nrfx_rramc_words_write(addr, data, cnt); + + /* At time of writing, the Zephyr driver commits writes, but the + * nrfx driver does not, so we commit here using the HAL to align + * Zephyr and TF-M behaviour. + * + * Not committing may cause data loss and/or high power + * consumption. + */ + nrf_rramc_task_trigger(NRF_RRAMC, NRF_RRAMC_TASK_COMMIT_WRITEBUF); #endif /* Conversion between bytes and data items */ @@ -181,6 +200,8 @@ static int32_t ARM_Flash_EraseSector(uint32_t addr) nrfx_rramc_word_write((uint32_t)erase_word_ptr, 0xFFFFFFFFU); } } + + nrf_rramc_task_trigger(NRF_RRAMC, NRF_RRAMC_TASK_COMMIT_WRITEBUF); #endif return ARM_DRIVER_OK; diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 81150740e..d49812f95 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -32,6 +32,18 @@ #include #include +#ifdef RRAMC_PRESENT +#include +#include + +#if CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE > 0 +#define WRITE_BUFFER_SIZE CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE +#else +#define WRITE_BUFFER_SIZE 0 +#endif + +#endif + #ifdef CACHE_PRESENT #include #endif @@ -1265,6 +1277,30 @@ static const uint8_t target_peripherals[] = { #endif +#ifdef RRAMC_PRESENT + nrfx_rramc_config_t config = NRFX_RRAMC_DEFAULT_CONFIG(WRITE_BUFFER_SIZE); + + config.mode_write = true; + +#if CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE > 0 + config.preload_timeout_enable = true; + config.preload_timeout = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE; +#else + config.preload_timeout_enable = false; + config.preload_timeout = 0; +#endif + + /* Don't use an event handler until it's understood whether we + * want it or not + */ + nrfx_rramc_evt_handler_t handler = NULL; + + nrfx_err_t err = nrfx_rramc_init(&config, handler); + if(err != NRFX_SUCCESS && err != NRFX_ERROR_ALREADY) { + return err; + } +#endif /* RRAMC_PRESENT */ + #if NRF_SPU_HAS_MEMORY /* Enforce that the nRF5340 Network MCU is in the Non-Secure * domain. Non-secure is the HW reset value for the network core From a829788f4645d709001926857aeb810f615cb4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Wed, 10 Apr 2024 16:00:24 +0200 Subject: [PATCH 43/65] [nrf noup] tfm: Detect wrong headers being included MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit is a noup because we want an NCS specific error message. Detect wrong headers being included. See comment for details. Signed-off-by: Sebastian Bøe Change-Id: I23089b08cee5961a5800707ffb222e306004cfee --- interface/include/psa/crypto_platform.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/interface/include/psa/crypto_platform.h b/interface/include/psa/crypto_platform.h index e49438aa8..c46289887 100644 --- a/interface/include/psa/crypto_platform.h +++ b/interface/include/psa/crypto_platform.h @@ -32,4 +32,25 @@ * available for reference and future compatibility */ +#if defined(__NRF_TFM__) && defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) +/* + * This header file is provided by TF-M and is only intended to be + * used by clients of PSA, not implementations of PSA. So secure + * partitions in the TF-M image (other than the crypto partition + * itself), and non-secure images. + * + * In NCS, the TF-M crypto partition should be using PSA header files + * from Oberon as it is Oberon that implements PSA. + * + * We want to detect that a source file is in the crypto partition, + * but has accidentally used this TF-M header instead of headers + * provided by Oberon. To do this we would ideally have a + * IS_IN_CRYPTO_PARTION define, but since there is no such define at + * time of writing we check MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + * instead, which should only be defined by the PSA implementation, + * not by PSA clients. + */ +#error "The TF-M image included the TF-M PSA headers but should have included Oberon PSA headers" +#endif + #endif /* PSA_CRYPTO_PLATFORM_H */ From 7b734feaad68ae53d98dbdd916d80d45ffda9a9f Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Wed, 24 Apr 2024 12:51:34 +0200 Subject: [PATCH 44/65] [noup] platform: nordic_nrf: Configure XL1/2 pin based on Kconfig For Secure only builds on 53 there exists the Kconfig CONFIG_SOC_ENABLE_LFXO to define if the XL1 and XL2 pin should be configured to used for the LFXO oscillator. TF-M should have the same behavior, to enable the possibility to use these pins for something else noup as we don't have the NCS Kconfigs available in upstream TF-M, the change to pull them in was done in the noup commit: 1a178885e758b2a40a60a0dd419a29ed94236965 Ref: NCSDK-20678 Signed-off-by: Markus Swarowsky diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 81150740e..f1f0f1e4c 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1230,8 +1230,11 @@ static const uint8_t target_peripherals[] = { * register fields are not accessible. That's why it is placed here. */ #ifdef NRF53_SERIES +#if defined(CONFIG_SOC_ENABLE_LFXO) && CONFIG_SOC_ENABLE_LFXO == 1 +/* CONFIG_SOC_ENABLE_LFXO doesn't exist for 54L15 target, might be changed in future */ nrf_gpio_pin_control_select(PIN_XL1, NRF_GPIO_PIN_SEL_PERIPHERAL); nrf_gpio_pin_control_select(PIN_XL2, NRF_GPIO_PIN_SEL_PERIPHERAL); +#endif /* CONFIG_SOC_ENABLE_LFXO */ #endif #ifdef NRF54L15_ENGA_XXAA /* NRF54L has a different define */ --- platform/ext/target/nordic_nrf/common/core/target_cfg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index d49812f95..f4b8c534e 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1242,8 +1242,11 @@ static const uint8_t target_peripherals[] = { * register fields are not accessible. That's why it is placed here. */ #ifdef NRF53_SERIES +#if defined(CONFIG_SOC_ENABLE_LFXO) && CONFIG_SOC_ENABLE_LFXO == 1 +/* CONFIG_SOC_ENABLE_LFXO doesn't exist for 54L15 target, might be changed in future */ nrf_gpio_pin_control_select(PIN_XL1, NRF_GPIO_PIN_SEL_PERIPHERAL); nrf_gpio_pin_control_select(PIN_XL2, NRF_GPIO_PIN_SEL_PERIPHERAL); +#endif /* CONFIG_SOC_ENABLE_LFXO */ #endif #ifdef NRF54L15_ENGA_XXAA /* NRF54L has a different define */ From ddd5acf077809d1f08e2fb3277ff9eed97fe4a20 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Tue, 30 Apr 2024 16:10:30 +0200 Subject: [PATCH 45/65] [nrf noup] Fix support CMAC KDF and custom builtin solution !fixup [nrf noup] Support CMAC KDF and custom builtin solution Pass the PS_CRYPTO_KDF_ALG to the its partition where it will be used Signed-off-by: Markus Swarowsky --- config/config_base.cmake | 2 +- .../partitions/internal_trusted_storage/CMakeLists.txt | 1 + .../protected_storage/crypto/ps_crypto_interface.c | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/config/config_base.cmake b/config/config_base.cmake index 30fad5d84..af4256d12 100644 --- a/config/config_base.cmake +++ b/config/config_base.cmake @@ -124,7 +124,7 @@ set(BL2_TRAILER_SIZE 0x000 CACHE STRING "BL2 Trailer set(TFM_PARTITION_PROTECTED_STORAGE OFF CACHE BOOL "Enable Protected Storage partition") set(PS_ENCRYPTION ON CACHE BOOL "Enable encryption for Protected Storage partition") set(PS_CRYPTO_AEAD_ALG PSA_ALG_GCM CACHE STRING "The AEAD algorithm to use for authenticated encryption in Protected Storage") -set(PS_CRYPTO_KDF_ALG PSA_ALG_HKDF(PSA_ALG_SHA_256) CACHE STRING "KDF Algorithm to use for Protect Storage") +set(PS_CRYPTO_KDF_ALG PSA_ALG_HKDF\(PSA_ALG_SHA_256\) CACHE STRING "KDF Algorithm to use for Protect Storage") set(TFM_PARTITION_INTERNAL_TRUSTED_STORAGE OFF CACHE BOOL "Enable Internal Trusted Storage partition") set(ITS_ENCRYPTION OFF CACHE BOOL "Enable authenticated encryption of ITS files using platform specific APIs") diff --git a/secure_fw/partitions/internal_trusted_storage/CMakeLists.txt b/secure_fw/partitions/internal_trusted_storage/CMakeLists.txt index 94aa82236..f4c960c2e 100644 --- a/secure_fw/partitions/internal_trusted_storage/CMakeLists.txt +++ b/secure_fw/partitions/internal_trusted_storage/CMakeLists.txt @@ -64,6 +64,7 @@ target_link_libraries(tfm_psa_rot_partition_its target_compile_definitions(tfm_psa_rot_partition_its PUBLIC PS_CRYPTO_AEAD_ALG=${PS_CRYPTO_AEAD_ALG} + PS_CRYPTO_KDF_ALG=${PS_CRYPTO_KDF_ALG} ) ################ Display the configuration being applied ####################### diff --git a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c index d5d6bc603..f508ff455 100644 --- a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c +++ b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c @@ -18,7 +18,11 @@ #define PS_CRYPTO_AEAD_ALG PSA_ALG_GCM #endif -#ifndef PS_CRYPTO_KDF_ALG +/* CMake can't handle round brackets for compile defines so PSA_ALG_HKDF(PSA_ALG_SHA_256) doesn't + * work, therefore we have to use a own defined for the C code where + * PSA_ALG_HKDF_PSA_ALG_SHA_256 gets translated to PSA_ALG_HKDF_PSA_ALG_SHA_256 + */ +#if !defined(PS_CRYPTO_KDF_ALG) #define PS_CRYPTO_KDF_ALG PSA_ALG_HKDF(PSA_ALG_SHA_256) #endif From 79ad65ec875127c707b2b0c06929b2e99cdd8166 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Tue, 30 Apr 2024 16:11:39 +0200 Subject: [PATCH 46/65] [nrf noup] platform: nordic_nrf: Enable PS encryption again !fixup [nrf noup] platform: nordic_nrf: Add support for 54l Ref: NCSDK-26630 Signed-off-by: Markus Swarowsky --- platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake | 3 --- 1 file changed, 3 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake b/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake index baa1e4d1f..01426be79 100644 --- a/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake @@ -12,6 +12,3 @@ set(SECURE_UART1 ON CACHE BOOL "Enable secur set(NRF_NS_STORAGE OFF CACHE BOOL "Enable non-secure storage partition") set(BL2 OFF CACHE BOOL "Whether to build BL2") set(NRF_NS_SECONDARY OFF CACHE BOOL "Enable non-secure secondary partition") - -# NCSDK-26630: Not supported yet -set(PS_ENCRYPTION OFF CACHE BOOL "") From 87059ebbb9b729930b1c644410f341f78a60ef1e Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Thu, 2 May 2024 15:55:58 +0200 Subject: [PATCH 47/65] [nrf noup] platform: nordic_nrf: 54L Add ITS encryption support !fixup [nrf noup] platform: nordic_nrf: Add support for 54l Add an PSA/Cracen implementation for ITS encryption. Ref: NCSDK-26678 Signed-off-by: Markus Swarowsky diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index 43c7b7662..19e2aee64 100644 Signed-off-by: Markus Swarowsky --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -26,8 +26,10 @@ if((NRF_SOC_VARIANT STREQUAL nrf54l15) OR (target STREQUAL nrf54l15)) # Maybe we only need to check one of these options but these # variables keep changing so we check both to be future proof set(HAS_RRAMC 1) + set(HAS_CRACEN 1) else() set(HAS_NVMC 1) + set(HAS_CRACEN 0) endif() #========================= Platform dependencies ===============================# @@ -99,7 +101,8 @@ target_sources(platform_s $<$:${CMAKE_CURRENT_SOURCE_DIR}/nrf_exception_info.c> $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c> $<$:${CMAKE_CURRENT_SOURCE_DIR}/pal_plat_test.c> - $<$:${CMAKE_CURRENT_SOURCE_DIR}/tfm_hal_its_encryption.c> + $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_hal_its_encryption.c> + $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_hal_its_encryption_cracen.c> ) if (NRF_HW_INIT_RESET_ON_BOOT) diff --git a/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c b/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c new file mode 100644 index 000000000..bbcbb97a0 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "config_tfm.h" +#include "platform/include/tfm_hal_its_encryption.h" +#include "platform/include/tfm_hal_its.h" +#include "psa/crypto.h" +#include "tfm_crypto_defs.h" + +#define CHACHA20_KEY_SIZE 32 +#define TFM_ITS_AEAD_ALG PSA_ALG_CHACHA20_POLY1305 + +#define ITS_ENCRYPTION_SUCCESS 0 + +#define HUK_KMU_SLOT 2 +#define HUK_KMU_SIZE_BITS 128 + +/* Global encryption counter which resets per boot. The counter ensures that + * the nonce will not be identical for consecutive file writes during the same + * boot. + */ +static uint32_t g_enc_counter; + +/* The global nonce seed which is fetched once in every boot. The seed is used + * as part of the nonce and allows the platforms to diversify their nonces + * across resets. Note that the way that this seed is generated is platform + * specific, so the diversification is optional. + */ +static uint8_t g_enc_nonce_seed[TFM_ITS_ENC_NONCE_LENGTH - + sizeof(g_enc_counter)]; + +/* TFM_ITS_ENC_NONCE_LENGTH is configurable but this implementation expects + * the seed to be 8 bytes and the nonce length to be 12. + */ +#if TFM_ITS_ENC_NONCE_LENGTH != 12 +#error "This implementation only supports a ITS nonce of size 12" +#endif + +/* + * This implementation doesn't use monotonic counters, but therfore a 64 bit + * seed combined with a counter, that gets reset on each reboot. + * This still has the risk of getting a collision on the seed resulting in + * nonce's beeing the same after a reboot. + * It would still need 3.3x10^9 resets to get a collision with a probability of + * 0.25. + */ +enum tfm_hal_status_t tfm_hal_its_aead_generate_nonce(uint8_t *nonce, + const size_t nonce_size) +{ + if(nonce == NULL){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if(nonce_size < sizeof(g_enc_nonce_seed) + sizeof(g_enc_counter)){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + /* To avoid wrap-around of the g_enc_counter and subsequent re-use of the + * nonce we check the counter value for its max value + */ + if(g_enc_counter == UINT32_MAX) { + return TFM_HAL_ERROR_GENERIC; + } + + /* psa_generate_random is not using any key/its functions wo we can use it here*/ + if (g_enc_counter == 0) { + psa_status_t status = psa_generate_random(g_enc_nonce_seed, sizeof(g_enc_nonce_seed)); + if (status != PSA_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + } + + memcpy(nonce, g_enc_nonce_seed, sizeof(g_enc_nonce_seed)); + memcpy(nonce + sizeof(g_enc_nonce_seed), + &g_enc_counter, + sizeof(g_enc_counter)); + + g_enc_counter++; + + return TFM_HAL_SUCCESS; +} + +static bool ctx_is_valid(struct tfm_hal_its_auth_crypt_ctx *ctx) +{ + bool ret; + + if (ctx == NULL) { + return false; + } + + ret = (ctx->deriv_label == NULL && ctx->deriv_label_size != 0) || + (ctx->aad == NULL && ctx->add_size != 0) || + (ctx->nonce == NULL && ctx->nonce_size != 0); + + return !ret; +} + +/* + * The cracen driver code doesn't use any persistent keys so no calls to its + * therefore the PSA API's can be used directly. + */ +psa_status_t tfm_hal_its_get_aead(struct tfm_hal_its_auth_crypt_ctx *ctx, + uint8_t *plaintext, + const size_t plaintext_size, + uint8_t *ciphertext, + const size_t ciphertext_size, + uint8_t *tag, + const size_t tag_size, + bool encrypt) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_derivation_operation_t op = PSA_KEY_DERIVATION_OPERATION_INIT; + psa_key_id_t key; + size_t ciphertext_length; + size_t tag_length = PSA_AEAD_TAG_LENGTH(PSA_KEY_TYPE_CHACHA20, + PSA_BYTES_TO_BITS(CHACHA20_KEY_SIZE), + TFM_ITS_AEAD_ALG); + + if (!ctx_is_valid(ctx) || tag == NULL) { + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if(tag_size < tag_length){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if (ciphertext_size < PSA_AEAD_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_CHACHA20, + TFM_ITS_AEAD_ALG, + plaintext_size)){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + /* Set the key attributes for the key */ + psa_set_key_usage_flags(&attributes, (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT)); + psa_set_key_algorithm(&attributes, TFM_ITS_AEAD_ALG); + psa_set_key_type(&attributes, PSA_KEY_TYPE_CHACHA20); + psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(CHACHA20_KEY_SIZE)); + + status = psa_key_derivation_setup(&op, PSA_ALG_SP800_108_COUNTER_CMAC); + if (status != PSA_SUCCESS) { + return status; + } + + /* Set up a key derivation operation with HUK */ + status = psa_key_derivation_input_key(&op, PSA_KEY_DERIVATION_INPUT_SECRET, + TFM_BUILTIN_KEY_ID_HUK); + if (status != PSA_SUCCESS) { + goto err_release_op; + } + + /* Supply the PS key label as an input to the key derivation */ + status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_LABEL, + ctx->deriv_label, + ctx->deriv_label_size); + if (status != PSA_SUCCESS) { + goto err_release_op; + } + + /* Create the storage key from the key derivation operation */ + status = psa_key_derivation_output_key(&attributes, &op, &key); + if (status != PSA_SUCCESS) { + goto err_release_op; + } + + /* Free resources associated with the key derivation operation */ + status = psa_key_derivation_abort(&op); + if (status != PSA_SUCCESS) { + goto err_release_key; + } + + if (encrypt) { + status = psa_aead_encrypt(key, + TFM_ITS_AEAD_ALG, + ctx->nonce, + ctx->nonce_size, + ctx->aad, + ctx->add_size, + plaintext, + plaintext_size, + ciphertext, + ciphertext_size, + &ciphertext_length); + } else { + status = psa_aead_decrypt(key, + TFM_ITS_AEAD_ALG, + ctx->nonce, + ctx->nonce_size, + ctx->aad, + ctx->add_size, + ciphertext, + ciphertext_size, + plaintext, + plaintext_size, + &ciphertext_length); + } + if(status != PSA_SUCCESS){ + goto err_release_key; + } + + /* copy tag from ciphertext buffer to tag buffer */ + memcpy(tag, ciphertext + ciphertext_length - tag_length, tag_length); + +err_release_key: + (void)psa_destroy_key(key); + + return status; + +err_release_op: + (void)psa_key_derivation_abort(&op); + + return PSA_ERROR_GENERIC_ERROR; +} + +enum tfm_hal_status_t tfm_hal_its_aead_encrypt(struct tfm_hal_its_auth_crypt_ctx *ctx, + const uint8_t *plaintext, + const size_t plaintext_size, + uint8_t *ciphertext, + const size_t ciphertext_size, + uint8_t *tag, + const size_t tag_size) +{ + psa_status_t status = tfm_hal_its_get_aead(ctx, + plaintext, + plaintext_size, + ciphertext, + ciphertext_size, + tag, + tag_size, + true); + if (status != PSA_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + + return TFM_HAL_SUCCESS; +} + +enum tfm_hal_status_t tfm_hal_its_aead_decrypt(struct tfm_hal_its_auth_crypt_ctx *ctx, + const uint8_t *ciphertext, + const size_t ciphertext_size, + uint8_t *tag, + const size_t tag_size, + uint8_t *plaintext, + const size_t plaintext_size) +{ + psa_status_t status = tfm_hal_its_get_aead(ctx, + ciphertext, + ciphertext_size, + plaintext, + plaintext_size, + tag, + tag_size, + false); + + return TFM_HAL_SUCCESS; +} + --- .../nordic_nrf/common/core/CMakeLists.txt | 5 +- .../core/tfm_hal_its_encryption_cracen.c | 273 ++++++++++++++++++ 2 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c diff --git a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt index 43c7b7662..19e2aee64 100644 --- a/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt +++ b/platform/ext/target/nordic_nrf/common/core/CMakeLists.txt @@ -26,8 +26,10 @@ if((NRF_SOC_VARIANT STREQUAL nrf54l15) OR (target STREQUAL nrf54l15)) # Maybe we only need to check one of these options but these # variables keep changing so we check both to be future proof set(HAS_RRAMC 1) + set(HAS_CRACEN 1) else() set(HAS_NVMC 1) + set(HAS_CRACEN 0) endif() #========================= Platform dependencies ===============================# @@ -99,7 +101,8 @@ target_sources(platform_s $<$:${CMAKE_CURRENT_SOURCE_DIR}/nrf_exception_info.c> $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c> $<$:${CMAKE_CURRENT_SOURCE_DIR}/pal_plat_test.c> - $<$:${CMAKE_CURRENT_SOURCE_DIR}/tfm_hal_its_encryption.c> + $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_hal_its_encryption.c> + $<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_hal_its_encryption_cracen.c> ) if (NRF_HW_INIT_RESET_ON_BOOT) diff --git a/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c b/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c new file mode 100644 index 000000000..bbcbb97a0 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "config_tfm.h" +#include "platform/include/tfm_hal_its_encryption.h" +#include "platform/include/tfm_hal_its.h" +#include "psa/crypto.h" +#include "tfm_crypto_defs.h" + +#define CHACHA20_KEY_SIZE 32 +#define TFM_ITS_AEAD_ALG PSA_ALG_CHACHA20_POLY1305 + +#define ITS_ENCRYPTION_SUCCESS 0 + +#define HUK_KMU_SLOT 2 +#define HUK_KMU_SIZE_BITS 128 + +/* Global encryption counter which resets per boot. The counter ensures that + * the nonce will not be identical for consecutive file writes during the same + * boot. + */ +static uint32_t g_enc_counter; + +/* The global nonce seed which is fetched once in every boot. The seed is used + * as part of the nonce and allows the platforms to diversify their nonces + * across resets. Note that the way that this seed is generated is platform + * specific, so the diversification is optional. + */ +static uint8_t g_enc_nonce_seed[TFM_ITS_ENC_NONCE_LENGTH - + sizeof(g_enc_counter)]; + +/* TFM_ITS_ENC_NONCE_LENGTH is configurable but this implementation expects + * the seed to be 8 bytes and the nonce length to be 12. + */ +#if TFM_ITS_ENC_NONCE_LENGTH != 12 +#error "This implementation only supports a ITS nonce of size 12" +#endif + +/* + * This implementation doesn't use monotonic counters, but therfore a 64 bit + * seed combined with a counter, that gets reset on each reboot. + * This still has the risk of getting a collision on the seed resulting in + * nonce's beeing the same after a reboot. + * It would still need 3.3x10^9 resets to get a collision with a probability of + * 0.25. + */ +enum tfm_hal_status_t tfm_hal_its_aead_generate_nonce(uint8_t *nonce, + const size_t nonce_size) +{ + if(nonce == NULL){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if(nonce_size < sizeof(g_enc_nonce_seed) + sizeof(g_enc_counter)){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + /* To avoid wrap-around of the g_enc_counter and subsequent re-use of the + * nonce we check the counter value for its max value + */ + if(g_enc_counter == UINT32_MAX) { + return TFM_HAL_ERROR_GENERIC; + } + + /* psa_generate_random is not using any key/its functions wo we can use it here*/ + if (g_enc_counter == 0) { + psa_status_t status = psa_generate_random(g_enc_nonce_seed, sizeof(g_enc_nonce_seed)); + if (status != PSA_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + } + + memcpy(nonce, g_enc_nonce_seed, sizeof(g_enc_nonce_seed)); + memcpy(nonce + sizeof(g_enc_nonce_seed), + &g_enc_counter, + sizeof(g_enc_counter)); + + g_enc_counter++; + + return TFM_HAL_SUCCESS; +} + +static bool ctx_is_valid(struct tfm_hal_its_auth_crypt_ctx *ctx) +{ + bool ret; + + if (ctx == NULL) { + return false; + } + + ret = (ctx->deriv_label == NULL && ctx->deriv_label_size != 0) || + (ctx->aad == NULL && ctx->add_size != 0) || + (ctx->nonce == NULL && ctx->nonce_size != 0); + + return !ret; +} + +/* + * The cracen driver code doesn't use any persistent keys so no calls to its + * therefore the PSA API's can be used directly. + */ +psa_status_t tfm_hal_its_get_aead(struct tfm_hal_its_auth_crypt_ctx *ctx, + uint8_t *plaintext, + const size_t plaintext_size, + uint8_t *ciphertext, + const size_t ciphertext_size, + uint8_t *tag, + const size_t tag_size, + bool encrypt) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_derivation_operation_t op = PSA_KEY_DERIVATION_OPERATION_INIT; + psa_key_id_t key; + size_t ciphertext_length; + size_t tag_length = PSA_AEAD_TAG_LENGTH(PSA_KEY_TYPE_CHACHA20, + PSA_BYTES_TO_BITS(CHACHA20_KEY_SIZE), + TFM_ITS_AEAD_ALG); + + if (!ctx_is_valid(ctx) || tag == NULL) { + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if(tag_size < tag_length){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + if (ciphertext_size < PSA_AEAD_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_CHACHA20, + TFM_ITS_AEAD_ALG, + plaintext_size)){ + return TFM_HAL_ERROR_INVALID_INPUT; + } + + /* Set the key attributes for the key */ + psa_set_key_usage_flags(&attributes, (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT)); + psa_set_key_algorithm(&attributes, TFM_ITS_AEAD_ALG); + psa_set_key_type(&attributes, PSA_KEY_TYPE_CHACHA20); + psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(CHACHA20_KEY_SIZE)); + + status = psa_key_derivation_setup(&op, PSA_ALG_SP800_108_COUNTER_CMAC); + if (status != PSA_SUCCESS) { + return status; + } + + /* Set up a key derivation operation with HUK */ + status = psa_key_derivation_input_key(&op, PSA_KEY_DERIVATION_INPUT_SECRET, + TFM_BUILTIN_KEY_ID_HUK); + if (status != PSA_SUCCESS) { + goto err_release_op; + } + + /* Supply the PS key label as an input to the key derivation */ + status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_LABEL, + ctx->deriv_label, + ctx->deriv_label_size); + if (status != PSA_SUCCESS) { + goto err_release_op; + } + + /* Create the storage key from the key derivation operation */ + status = psa_key_derivation_output_key(&attributes, &op, &key); + if (status != PSA_SUCCESS) { + goto err_release_op; + } + + /* Free resources associated with the key derivation operation */ + status = psa_key_derivation_abort(&op); + if (status != PSA_SUCCESS) { + goto err_release_key; + } + + if (encrypt) { + status = psa_aead_encrypt(key, + TFM_ITS_AEAD_ALG, + ctx->nonce, + ctx->nonce_size, + ctx->aad, + ctx->add_size, + plaintext, + plaintext_size, + ciphertext, + ciphertext_size, + &ciphertext_length); + } else { + status = psa_aead_decrypt(key, + TFM_ITS_AEAD_ALG, + ctx->nonce, + ctx->nonce_size, + ctx->aad, + ctx->add_size, + ciphertext, + ciphertext_size, + plaintext, + plaintext_size, + &ciphertext_length); + } + if(status != PSA_SUCCESS){ + goto err_release_key; + } + + /* copy tag from ciphertext buffer to tag buffer */ + memcpy(tag, ciphertext + ciphertext_length - tag_length, tag_length); + +err_release_key: + (void)psa_destroy_key(key); + + return status; + +err_release_op: + (void)psa_key_derivation_abort(&op); + + return PSA_ERROR_GENERIC_ERROR; +} + +enum tfm_hal_status_t tfm_hal_its_aead_encrypt(struct tfm_hal_its_auth_crypt_ctx *ctx, + const uint8_t *plaintext, + const size_t plaintext_size, + uint8_t *ciphertext, + const size_t ciphertext_size, + uint8_t *tag, + const size_t tag_size) +{ + psa_status_t status = tfm_hal_its_get_aead(ctx, + plaintext, + plaintext_size, + ciphertext, + ciphertext_size, + tag, + tag_size, + true); + if (status != PSA_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + + return TFM_HAL_SUCCESS; +} + +enum tfm_hal_status_t tfm_hal_its_aead_decrypt(struct tfm_hal_its_auth_crypt_ctx *ctx, + const uint8_t *ciphertext, + const size_t ciphertext_size, + uint8_t *tag, + const size_t tag_size, + uint8_t *plaintext, + const size_t plaintext_size) +{ + psa_status_t status = tfm_hal_its_get_aead(ctx, + ciphertext, + ciphertext_size, + plaintext, + plaintext_size, + tag, + tag_size, + false); + + return TFM_HAL_SUCCESS; +} + From fb1c0db8d32a7a100210e31871461e0bb33ac3af Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Wed, 8 May 2024 17:15:20 +0200 Subject: [PATCH 48/65] [nrf noup] platform: nordic_nrf: config of UART instances fixup! [nrf noup] platform: nordic_nrf: Add support for 54l This allows select which UART instance is used for TF-M Ref: NCSDK-25009 Signed-off-by: Markus Swarowsky diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index d69a84fa6..f2ffaf1a6 100644 Signed-off-by: Markus Swarowsky --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -40,7 +40,8 @@ #define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2) -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART30 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || \ + RTE_UART00 || RTE_USART20 || RTE_UART21 || RTE_UART22 || RTE_USART30 #define PSEL_DISCONNECTED 0xFFFFFFFFUL @@ -439,11 +440,22 @@ DRIVER_USART(2); DRIVER_USART(3); #endif -// TODO: NCSDK-25009: Support choosing an instance for TF-M +#if RTE_USART00 +DRIVER_USART(00); +#endif + #if RTE_USART20 DRIVER_USART(20); #endif +#if RTE_USART21 +DRIVER_USART(21); +#endif + +#if RTE_USART22 +DRIVER_USART(22); +#endif + #if RTE_USART30 DRIVER_USART(30); #endif diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h index 1bbe75f6e..f76e49cdd 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h +++ b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h @@ -48,7 +48,8 @@ #endif /* RTE_FLASH0 */ -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART30 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || \ + RTE_USART00 || RTE_USART20 || RTE_USART21 || RTE_USART22 || RTE_USART30 #define NRFX_UARTE_ENABLED 1 #endif #if RTE_USART0 @@ -64,10 +65,19 @@ #define NRFX_UARTE3_ENABLED 1 #endif -// TODO: NCSDK-25009: Moonlight: Make it possible to use different UARTS with TF-M +/* 54L15 has different UART instances */ +#if RTE_USART00 +#define NRFX_UARTE00_ENABLED 1 +#endif #if RTE_USART20 #define NRFX_UARTE20_ENABLED 1 #endif +#if RTE_USART21 +#define NRFX_UARTE21_ENABLED 1 +#endif +#if RTE_USART22 +#define NRFX_UARTE22_ENABLED 1 +#endif #if RTE_USART30 #define NRFX_UARTE30_ENABLED 1 #endif diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index f4b8c534e..fa1a8eda6 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -44,6 +44,11 @@ #endif +#define SPU_ADDRESS_REGION (0x50000000) +#define GET_SPU_SLAVE_INDEX(periph) ((periph.periph_start & 0x0003F000) >> 12) +#define GET_SPU_INSTANCE(periph) ((NRF_SPU_Type*)(SPU_ADDRESS_REGION | (periph.periph_start & 0x00FC0000))) + + #ifdef CACHE_PRESENT #include #endif @@ -263,6 +268,34 @@ struct platform_data_t tfm_peripheral_uarte3 = { }; #endif +#if TFM_PERIPHERAL_UARTE00_SECURE +struct platform_data_t tfm_peripheral_uarte00 = { + NRF_UARTE00_S_BASE, + NRF_UARTE00_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_UARTE20_SECURE +struct platform_data_t tfm_peripheral_uarte20 = { + NRF_UARTE20_S_BASE, + NRF_UARTE20_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_UARTE21_SECURE +struct platform_data_t tfm_peripheral_uarte21 = { + NRF_UARTE21_S_BASE, + NRF_UARTE21_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_UARTE22_SECURE +struct platform_data_t tfm_peripheral_uarte22 = { + NRF_UARTE22_S_BASE, + NRF_UARTE22_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_UARTE30_SECURE struct platform_data_t tfm_peripheral_uarte30 = { NRF_UARTE30_S_BASE, @@ -1051,8 +1084,7 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) } } - /* TODO: NCSDK-22597: Configure UART30 pins as secure */ - + /* TODO: NCSDK-22597: Make peripherals configurable */ for(uint8_t index = 0; index < ARRAY_SIZE(spu_instance->PERIPH); index++) { if(!nrf_spu_periph_perm_present_get(spu_instance, index)) { /* Peripheral is not present, nothing to configure */ @@ -1072,16 +1104,34 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) } /* Note that we don't configure dmasec because it has no effect when secattr is non-secure */ - - /* nrf_spu_periph_perm_lock_enable TODO: NCSDK-25009: Lock it down without breaking TF-M UART */ } } - /* Configure TF-M's UART30 peripheral to be secure with secure DMA */ + /* Configure TF-M's UART peripheral to be secure with secure DMA */ +#if NRF_SECURE_UART_INSTANCE == 00 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte00); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte00); +#endif +#if NRF_SECURE_UART_INSTANCE == 20 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte20); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte20); +#endif +#if NRF_SECURE_UART_INSTANCE == 21 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte21); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte21); +#endif +#if NRF_SECURE_UART_INSTANCE == 22 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte22); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte22); +#endif +#if NRF_SECURE_UART_INSTANCE == 30 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte30); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte30); +#endif bool enable = true; /* true means secure */ - uint32_t UART30_SLAVE_INDEX = (NRF_UARTE30_S_BASE & 0x0003F000) >> 12; - nrf_spu_periph_perm_secattr_set(NRF_SPU30, UART30_SLAVE_INDEX, enable); - nrf_spu_periph_perm_dmasec_set(NRF_SPU30, UART30_SLAVE_INDEX, enable); + nrf_spu_periph_perm_secattr_set(p_spu_instance, UART_SPU_SLAVE_INDEX, enable); + nrf_spu_periph_perm_dmasec_set(p_spu_instance, UART_SPU_SLAVE_INDEX, enable); + nrf_spu_periph_perm_lock_enable(p_spu_instance,UART_SPU_SLAVE_INDEX); #else static const uint8_t target_peripherals[] = { @@ -1114,9 +1164,13 @@ static const uint8_t target_peripherals[] = { /* When UART0 is a secure peripheral we need to leave Serial-Box 0 as Secure. * The UART Driver will configure it as non-secure when it uninitializes. */ +#if defined(NRF54L15_ENGA_XXAA) + NRFX_PERIPHERAL_ID_GET(NRF_SPIM00), +#else #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) NRFX_PERIPHERAL_ID_GET(NRF_SPIM0), -#endif +#endif /* !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) */ +#endif /* NRF54L15_ENGA_XXAA */ /* When UART1 is a secure peripheral we need to leave Serial-Box 1 as Secure */ #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 1) @@ -1124,9 +1178,19 @@ static const uint8_t target_peripherals[] = { #endif NRFX_PERIPHERAL_ID_GET(NRF_SPIM2), NRFX_PERIPHERAL_ID_GET(NRF_SPIM3), - /* When UART30 is a secure peripheral we need to leave Serial-Box 30 as Secure */ -#if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 30) - // TODO: NCSDK-25009: spu_peripheral_config_non_secure((uint32_t)NRF_SPIM30, false); + +/* For Moonlight if a UART instance is selected to be the secure instance leave it as secure */ +#if NRF_SECURE_UART_INSTANCE == 20 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM20), +#endif +#if NRF_SECURE_UART_INSTANCE == 21 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM21), +#endif +#if NRF_SECURE_UART_INSTANCE == 22 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM22), +#endif +#if NRF_SECURE_UART_INSTANCE == 30 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM30), #endif #ifdef NRF_SPIM4 diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h index e430737c4..afa0f672a 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -35,22 +35,22 @@ #include "tfm_plat_defs.h" #include "region_defs.h" -// TODO: NCSDK-25009: Support configuring which UART is used by TF-M on nrf54L - #if NRF_SECURE_UART_INSTANCE == 0 #define TFM_DRIVER_STDIO Driver_USART0 #elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_DRIVER_STDIO Driver_USART1 +#elif NRF_SECURE_UART_INSTANCE == 00 +#define TFM_DRIVER_STDIO Driver_USART00 +#elif NRF_SECURE_UART_INSTANCE == 20 +#define TFM_DRIVER_STDIO Driver_USART20 +#elif NRF_SECURE_UART_INSTANCE == 21 +#define TFM_DRIVER_STDIO Driver_USART21 +#elif NRF_SECURE_UART_INSTANCE == 22 +#define TFM_DRIVER_STDIO Driver_USART22 #elif NRF_SECURE_UART_INSTANCE == 30 #define TFM_DRIVER_STDIO Driver_USART30 #endif -#ifdef NRF54L15_ENGA_XXAA -#define NS_DRIVER_STDIO Driver_USART20 -#else -#define NS_DRIVER_STDIO Driver_USART0 -#endif - /** * \brief Store the addresses of memory regions */ --- .../common/core/cmsis_drivers/Driver_USART.c | 16 +++- .../nordic_nrf/common/core/nrfx_config.h | 14 ++- .../nordic_nrf/common/core/target_cfg.c | 88 ++++++++++++++++--- .../nordic_nrf/common/core/target_cfg.h | 17 +++- .../crypto/ps_crypto_interface.c | 4 - 5 files changed, 117 insertions(+), 22 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index d69a84fa6..f2ffaf1a6 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -40,7 +40,8 @@ #define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2) -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART30 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || \ + RTE_UART00 || RTE_USART20 || RTE_UART21 || RTE_UART22 || RTE_USART30 #define PSEL_DISCONNECTED 0xFFFFFFFFUL @@ -439,11 +440,22 @@ DRIVER_USART(2); DRIVER_USART(3); #endif -// TODO: NCSDK-25009: Support choosing an instance for TF-M +#if RTE_USART00 +DRIVER_USART(00); +#endif + #if RTE_USART20 DRIVER_USART(20); #endif +#if RTE_USART21 +DRIVER_USART(21); +#endif + +#if RTE_USART22 +DRIVER_USART(22); +#endif + #if RTE_USART30 DRIVER_USART(30); #endif diff --git a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h index 1bbe75f6e..f76e49cdd 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrfx_config.h +++ b/platform/ext/target/nordic_nrf/common/core/nrfx_config.h @@ -48,7 +48,8 @@ #endif /* RTE_FLASH0 */ -#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || RTE_USART20 || RTE_USART30 +#if RTE_USART0 || RTE_USART1 || RTE_USART2 || RTE_USART3 || \ + RTE_USART00 || RTE_USART20 || RTE_USART21 || RTE_USART22 || RTE_USART30 #define NRFX_UARTE_ENABLED 1 #endif #if RTE_USART0 @@ -64,10 +65,19 @@ #define NRFX_UARTE3_ENABLED 1 #endif -// TODO: NCSDK-25009: Moonlight: Make it possible to use different UARTS with TF-M +/* 54L15 has different UART instances */ +#if RTE_USART00 +#define NRFX_UARTE00_ENABLED 1 +#endif #if RTE_USART20 #define NRFX_UARTE20_ENABLED 1 #endif +#if RTE_USART21 +#define NRFX_UARTE21_ENABLED 1 +#endif +#if RTE_USART22 +#define NRFX_UARTE22_ENABLED 1 +#endif #if RTE_USART30 #define NRFX_UARTE30_ENABLED 1 #endif diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index f4b8c534e..fa1a8eda6 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -44,6 +44,11 @@ #endif +#define SPU_ADDRESS_REGION (0x50000000) +#define GET_SPU_SLAVE_INDEX(periph) ((periph.periph_start & 0x0003F000) >> 12) +#define GET_SPU_INSTANCE(periph) ((NRF_SPU_Type*)(SPU_ADDRESS_REGION | (periph.periph_start & 0x00FC0000))) + + #ifdef CACHE_PRESENT #include #endif @@ -263,6 +268,34 @@ struct platform_data_t tfm_peripheral_uarte3 = { }; #endif +#if TFM_PERIPHERAL_UARTE00_SECURE +struct platform_data_t tfm_peripheral_uarte00 = { + NRF_UARTE00_S_BASE, + NRF_UARTE00_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_UARTE20_SECURE +struct platform_data_t tfm_peripheral_uarte20 = { + NRF_UARTE20_S_BASE, + NRF_UARTE20_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_UARTE21_SECURE +struct platform_data_t tfm_peripheral_uarte21 = { + NRF_UARTE21_S_BASE, + NRF_UARTE21_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_UARTE22_SECURE +struct platform_data_t tfm_peripheral_uarte22 = { + NRF_UARTE22_S_BASE, + NRF_UARTE22_S_BASE + (sizeof(NRF_UARTE_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_UARTE30_SECURE struct platform_data_t tfm_peripheral_uarte30 = { NRF_UARTE30_S_BASE, @@ -1051,8 +1084,7 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) } } - /* TODO: NCSDK-22597: Configure UART30 pins as secure */ - + /* TODO: NCSDK-22597: Make peripherals configurable */ for(uint8_t index = 0; index < ARRAY_SIZE(spu_instance->PERIPH); index++) { if(!nrf_spu_periph_perm_present_get(spu_instance, index)) { /* Peripheral is not present, nothing to configure */ @@ -1072,16 +1104,34 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) } /* Note that we don't configure dmasec because it has no effect when secattr is non-secure */ - - /* nrf_spu_periph_perm_lock_enable TODO: NCSDK-25009: Lock it down without breaking TF-M UART */ } } - /* Configure TF-M's UART30 peripheral to be secure with secure DMA */ + /* Configure TF-M's UART peripheral to be secure with secure DMA */ +#if NRF_SECURE_UART_INSTANCE == 00 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte00); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte00); +#endif +#if NRF_SECURE_UART_INSTANCE == 20 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte20); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte20); +#endif +#if NRF_SECURE_UART_INSTANCE == 21 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte21); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte21); +#endif +#if NRF_SECURE_UART_INSTANCE == 22 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte22); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte22); +#endif +#if NRF_SECURE_UART_INSTANCE == 30 + uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte30); + NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte30); +#endif bool enable = true; /* true means secure */ - uint32_t UART30_SLAVE_INDEX = (NRF_UARTE30_S_BASE & 0x0003F000) >> 12; - nrf_spu_periph_perm_secattr_set(NRF_SPU30, UART30_SLAVE_INDEX, enable); - nrf_spu_periph_perm_dmasec_set(NRF_SPU30, UART30_SLAVE_INDEX, enable); + nrf_spu_periph_perm_secattr_set(p_spu_instance, UART_SPU_SLAVE_INDEX, enable); + nrf_spu_periph_perm_dmasec_set(p_spu_instance, UART_SPU_SLAVE_INDEX, enable); + nrf_spu_periph_perm_lock_enable(p_spu_instance,UART_SPU_SLAVE_INDEX); #else static const uint8_t target_peripherals[] = { @@ -1114,9 +1164,13 @@ static const uint8_t target_peripherals[] = { /* When UART0 is a secure peripheral we need to leave Serial-Box 0 as Secure. * The UART Driver will configure it as non-secure when it uninitializes. */ +#if defined(NRF54L15_ENGA_XXAA) + NRFX_PERIPHERAL_ID_GET(NRF_SPIM00), +#else #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) NRFX_PERIPHERAL_ID_GET(NRF_SPIM0), -#endif +#endif /* !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) */ +#endif /* NRF54L15_ENGA_XXAA */ /* When UART1 is a secure peripheral we need to leave Serial-Box 1 as Secure */ #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 1) @@ -1124,9 +1178,19 @@ static const uint8_t target_peripherals[] = { #endif NRFX_PERIPHERAL_ID_GET(NRF_SPIM2), NRFX_PERIPHERAL_ID_GET(NRF_SPIM3), - /* When UART30 is a secure peripheral we need to leave Serial-Box 30 as Secure */ -#if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 30) - // TODO: NCSDK-25009: spu_peripheral_config_non_secure((uint32_t)NRF_SPIM30, false); + +/* For Moonlight if a UART instance is selected to be the secure instance leave it as secure */ +#if NRF_SECURE_UART_INSTANCE == 20 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM20), +#endif +#if NRF_SECURE_UART_INSTANCE == 21 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM21), +#endif +#if NRF_SECURE_UART_INSTANCE == 22 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM22), +#endif +#if NRF_SECURE_UART_INSTANCE == 30 + NRFX_PERIPHERAL_ID_GET(NRF_SPIM30), #endif #ifdef NRF_SPIM4 diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h index e430737c4..a2b6355ca 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -35,18 +35,31 @@ #include "tfm_plat_defs.h" #include "region_defs.h" -// TODO: NCSDK-25009: Support configuring which UART is used by TF-M on nrf54L - #if NRF_SECURE_UART_INSTANCE == 0 #define TFM_DRIVER_STDIO Driver_USART0 #elif NRF_SECURE_UART_INSTANCE == 1 #define TFM_DRIVER_STDIO Driver_USART1 +#elif NRF_SECURE_UART_INSTANCE == 00 +#define TFM_DRIVER_STDIO Driver_USART00 +#elif NRF_SECURE_UART_INSTANCE == 20 +#define TFM_DRIVER_STDIO Driver_USART20 +#elif NRF_SECURE_UART_INSTANCE == 21 +#define TFM_DRIVER_STDIO Driver_USART21 +#elif NRF_SECURE_UART_INSTANCE == 22 +#define TFM_DRIVER_STDIO Driver_USART22 #elif NRF_SECURE_UART_INSTANCE == 30 #define TFM_DRIVER_STDIO Driver_USART30 #endif +/* Only UART20 and UART30 are supported for TF-M tests, which are the + * Non-secure applications build via the TF-M build system + */ #ifdef NRF54L15_ENGA_XXAA +#if NRF_SECURE_UART_INSTANCE == 20 +#define NS_DRIVER_STDIO Driver_USART30 +#else #define NS_DRIVER_STDIO Driver_USART20 +#endif #else #define NS_DRIVER_STDIO Driver_USART0 #endif diff --git a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c index f508ff455..5b12275d0 100644 --- a/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c +++ b/secure_fw/partitions/protected_storage/crypto/ps_crypto_interface.c @@ -18,10 +18,6 @@ #define PS_CRYPTO_AEAD_ALG PSA_ALG_GCM #endif -/* CMake can't handle round brackets for compile defines so PSA_ALG_HKDF(PSA_ALG_SHA_256) doesn't - * work, therefore we have to use a own defined for the C code where - * PSA_ALG_HKDF_PSA_ALG_SHA_256 gets translated to PSA_ALG_HKDF_PSA_ALG_SHA_256 - */ #if !defined(PS_CRYPTO_KDF_ALG) #define PS_CRYPTO_KDF_ALG PSA_ALG_HKDF(PSA_ALG_SHA_256) #endif From 6e6d572c87480ccf816a8a08ff6f2bcb2ae557d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Fri, 3 May 2024 11:44:52 +0200 Subject: [PATCH 49/65] [nrf noup] tfm: 54l: Improve MPC configuration documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Improve MPC configuration documentation. Signed-off-by: Sebastian Bøe Change-Id: I191ca14ba8a6880217cc740a77ea2806af1e0d61 Signed-off-by: Markus Swarowsky diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index fa1a8eda6..66929256a 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -963,10 +963,30 @@ enum tfm_plat_err_t nrf_mpc_init_cfg(void) /* On 54l the NRF_MPC00->REGION[]'s are fixed in HW and the * OVERRIDE indexes (that are useful to us) start at 0 and end * (inclusive) at 4. + * + * Note that the MPC regions configure all volatile and non-volatile memory as secure, so we only + * need to explicitly OVERRIDE the non-secure addresses to permit non-secure access. + * + * Explicitly configuring memory as secure is not necessary. + * + * The last OVERRIDE in 54L is fixed in HW and exists to prevent + * other bus masters than the KMU from accessing CRACEN protected RAM. + * + * Note that we must take care not to configure an OVERRIDE that + * affects an active bus transaction. + * + * Note that we don't configure the NSC region to be NS because + * from the MPC's perspective it is secure. NSC is only configurable from the SAU. + * + * Note that OVERRIDE[n].MASTERPORT has a reasonable reset value + * so it is left unconfigured. + * + * Note that there are two owners in 54L. KMU with owner ID 1, and everything else with owner ID 0. */ - uint32_t index = 0; - /* Configure the non-secure partition of the non-volatile + uint32_t index = 0; + /* + * Configure the non-secure partition of the non-volatile * memory. This MPC region is intended to cover both the * non-secure partition in the NVM and also the FICR. The FICR * starts after the NVM and ends just before the UICR. @@ -1001,13 +1021,8 @@ enum tfm_plat_err_t nrf_mpc_init_cfg(void) tfm_core_panic(); } - /* TODO: NCSDK-25050: Review configuration. Any other addresses we need to override? */ - /* Note that we don't configure the NSC region to be NS because it is secure */ - /* Note that OVERRIDE[n].MASTERPORT has a reasonable reset value - * so it is left unconfigured. - */ return TFM_PLAT_ERR_SUCCESS; } --- .../nordic_nrf/common/core/target_cfg.c | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index fa1a8eda6..66929256a 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -963,10 +963,30 @@ enum tfm_plat_err_t nrf_mpc_init_cfg(void) /* On 54l the NRF_MPC00->REGION[]'s are fixed in HW and the * OVERRIDE indexes (that are useful to us) start at 0 and end * (inclusive) at 4. + * + * Note that the MPC regions configure all volatile and non-volatile memory as secure, so we only + * need to explicitly OVERRIDE the non-secure addresses to permit non-secure access. + * + * Explicitly configuring memory as secure is not necessary. + * + * The last OVERRIDE in 54L is fixed in HW and exists to prevent + * other bus masters than the KMU from accessing CRACEN protected RAM. + * + * Note that we must take care not to configure an OVERRIDE that + * affects an active bus transaction. + * + * Note that we don't configure the NSC region to be NS because + * from the MPC's perspective it is secure. NSC is only configurable from the SAU. + * + * Note that OVERRIDE[n].MASTERPORT has a reasonable reset value + * so it is left unconfigured. + * + * Note that there are two owners in 54L. KMU with owner ID 1, and everything else with owner ID 0. */ - uint32_t index = 0; - /* Configure the non-secure partition of the non-volatile + uint32_t index = 0; + /* + * Configure the non-secure partition of the non-volatile * memory. This MPC region is intended to cover both the * non-secure partition in the NVM and also the FICR. The FICR * starts after the NVM and ends just before the UICR. @@ -1001,13 +1021,8 @@ enum tfm_plat_err_t nrf_mpc_init_cfg(void) tfm_core_panic(); } - /* TODO: NCSDK-25050: Review configuration. Any other addresses we need to override? */ - /* Note that we don't configure the NSC region to be NS because it is secure */ - /* Note that OVERRIDE[n].MASTERPORT has a reasonable reset value - * so it is left unconfigured. - */ return TFM_PLAT_ERR_SUCCESS; } From 016b1ddaa29a848e3a4b361c316441e482f078cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 14 May 2024 14:29:12 +0200 Subject: [PATCH 50/65] [nrf noup] tfm: 54l: Lock unused MPC OVERRIDES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Lock and disable any unused MPC overrides to prevent malicious configuration. Signed-off-by: Sebastian Bøe Change-Id: I1956f113012d6b67100d814a52d7ce1490663953 --- .../ext/target/nordic_nrf/common/core/target_cfg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 66929256a..d9a15de4e 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1021,8 +1021,18 @@ enum tfm_plat_err_t nrf_mpc_init_cfg(void) tfm_core_panic(); } + /* Lock and disable any unused MPC overrides to prevent malicious configuration */ + while(index <= 4) { + struct mpc_region_override override; + + init_mpc_region_override(&override); + override.config.enable = false; + override.index = index++; + + mpc_configure_override(NRF_MPC00, &override); + } return TFM_PLAT_ERR_SUCCESS; } From dd0114796baf44d249764b2f3b9bc3be9c1d01d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vidar=20Lilleb=C3=B8?= Date: Fri, 19 Apr 2024 15:49:47 +0200 Subject: [PATCH 51/65] [nrf noup] Add MPC and SPC error reporting for nrf54l MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Adds handling of MPC and SPC errors. Signed-off-by: Vidar Lillebø --- .../target/nordic_nrf/common/core/faults.c | 80 +++++++++++++++++-- .../common/core/native_drivers/spu.c | 61 +++++++++++--- .../common/core/native_drivers/spu.h | 31 +++++++ .../common/core/nrf_exception_info.c | 46 ++++++++--- .../common/core/nrf_exception_info.h | 10 +++ .../target/nordic_nrf/common/core/startup.h | 2 + .../nordic_nrf/common/core/startup_nrf54l15.c | 27 ++++--- .../nordic_nrf/common/core/target_cfg.c | 11 +++ .../nordic_nrf/common/core/target_cfg.h | 5 -- 9 files changed, 230 insertions(+), 43 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/faults.c b/platform/ext/target/nordic_nrf/common/core/faults.c index 9306dc04b..912c5106a 100644 --- a/platform/ext/target/nordic_nrf/common/core/faults.c +++ b/platform/ext/target/nordic_nrf/common/core/faults.c @@ -22,11 +22,7 @@ void SPU_Handler(void) /* Clear SPU interrupt flag and pending SPU IRQ */ spu_clear_events(); -#ifdef SPU_IRQn - NVIC_ClearPendingIRQ(SPU_IRQn); -#else - // TODO: NCSDK-25011: Support nrf54l -#endif + NVIC_ClearPendingIRQ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) - NVIC_USER_IRQ_OFFSET); tfm_core_panic(); } @@ -40,3 +36,77 @@ __attribute__((naked)) void SPU_IRQHandler(void) "B . \n" ); } + +#ifdef NRF_SPU00 +__attribute__((naked)) void SPU00_IRQHandler(void) +{ + EXCEPTION_INFO(); + + __ASM volatile( + "BL SPU_Handler \n" + "B . \n" + ); +} +#endif + +#ifdef NRF_SPU10 +__attribute__((naked)) void SPU10_IRQHandler(void) +{ + EXCEPTION_INFO(); + + __ASM volatile( + "BL SPU_Handler \n" + "B . \n" + ); +} +#endif + +#ifdef NRF_SPU20 +__attribute__((naked)) void SPU20_IRQHandler(void) +{ + EXCEPTION_INFO(); + + __ASM volatile( + "BL SPU_Handler \n" + "B . \n" + ); +} +#endif + +#ifdef NRF_SPU30 +__attribute__((naked)) void SPU30_IRQHandler(void) +{ + EXCEPTION_INFO(); + + __ASM volatile( + "BL SPU_Handler \n" + "B . \n" + ); +} +#endif + +#ifdef NRF_MPC00 +void MPC_Handler(void) +{ +#ifdef TFM_EXCEPTION_INFO_DUMP + nrf_exception_info_store_context(); +#endif + + /* Clear MPC interrupt flag and pending MPC IRQ */ + mpc_clear_events(); + + NVIC_ClearPendingIRQ(MPC00_IRQn); + + tfm_core_panic(); +} + +__attribute__((naked)) void MPC00_IRQHandler(void) +{ + EXCEPTION_INFO(); + + __ASM volatile( + "BL MPC_Handler \n" + "B . \n" + ); +} +#endif diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c index d4a8cceec..c28802b3c 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c @@ -130,23 +130,47 @@ uint32_t spu_events_get(void) { uint32_t events = 0; + for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { + if(nrf_spu_event_check(spu_instances[i], NRF_SPU_EVENT_PERIPHACCERR)){ + events |= SPU_EVENT_PERIPHACCERR; + } #if NRF_SPU_HAS_MEMORY - if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_RAMACCERR)) { - events |= SPU_EVENT_RAMACCERR; - } - if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR)) { - events |= SPU_EVENT_FLASHACCERR; + if (nrf_spu_event_check(spu_instances[i], NRF_SPU_EVENT_RAMACCERR)) { + events |= SPU_EVENT_RAMACCERR; + } + if (nrf_spu_event_check(spu_instances[i], NRF_SPU_EVENT_FLASHACCERR)) { + events |= SPU_EVENT_FLASHACCERR; + } +#endif /* NRF_SPU_HAS_MEMORY */ } - if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR)) { - events |= SPU_EVENT_PERIPHACCERR; + + return events; +} + +#ifdef MPC_PRESENT +void mpc_enable_interrupts(void) +{ + uint32_t mask = NRF_MPC_INT_MEMACCERR_MASK; + nrf_mpc_int_enable(NRF_MPC00, mask); +} + +uint32_t mpc_events_get(void) +{ + uint32_t events = 0; + + if (nrf_mpc_event_check(NRF_MPC00, NRF_MPC_EVENT_MEMACCERR)){ + events |= MPC_EVENT_MEMACCERR; } -#else - // TODO: NCSDK-25011: Support fault handling on 54L -#endif return events; } +void mpc_clear_events() +{ + nrf_mpc_event_clear(NRF_MPC00, NRF_MPC_EVENT_MEMACCERR); +} +#endif /* MPC_PRESENT */ + void spu_clear_events(void) { for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { @@ -158,6 +182,23 @@ void spu_clear_events(void) } } +#ifdef SPU_PERIPHACCERR_ADDRESS_ADDRESS_Msk +uint32_t spu_get_peri_addr(void) { + uint32_t addr = 0; + + for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { + if(spu_instances[i]->EVENTS_PERIPHACCERR){ + /* Only the lower 16 bits of the address are captured into the register. The upper + * 16 bits correspond to the upper 16 bits of the SPU's base address. + */ + addr = spu_instances[i]->PERIPHACCERR.ADDRESS | ((uint32_t)spu_instances[i] & 0xFFFF0000); + } + } + + return addr; +} +#endif + #if NRF_SPU_HAS_MEMORY void spu_regions_reset_unlocked_secure(void) { diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h index 60731de47..670c5f511 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h @@ -20,8 +20,12 @@ #include #include #include +#include #include +#ifdef MPC_PRESENT +#include +#endif #define SPU_LOCK_CONF_LOCKED true #define SPU_LOCK_CONF_UNLOCKED false @@ -58,6 +62,7 @@ enum spu_events { SPU_EVENT_RAMACCERR = 1 << 0, SPU_EVENT_FLASHACCERR = 1 << 1, SPU_EVENT_PERIPHACCERR= 1 << 2, + MPC_EVENT_MEMACCERR = 1 << 3 }; /** @@ -139,6 +144,12 @@ void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock); */ void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock); +/** + * /brief Retrieve the address of the transaction that triggered PERIPHACCERR. + * + */ +uint32_t spu_get_peri_addr(void); + /** * \brief Return base address of a Flash SPU regions * @@ -225,4 +236,24 @@ uint32_t spu_regions_sram_get_last_id(void); */ uint32_t spu_regions_sram_get_region_size(void); +/** + * \brief MPC interrupt enabling + * + * Enable security violations outside the Cortex-M33 + * to trigger SPU interrupts. + */ +void mpc_enable_interrupts(void); + +/** + * \brief Retrieve bitmask of MPC events. + */ +uint32_t mpc_events_get(void); + +/** + * \brief MPC event clearing + * + * Clear MPC event registers + */ +void mpc_clear_events(void); + #endif diff --git a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c index e2aceb1f0..a5df17e8e 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c +++ b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c @@ -11,34 +11,60 @@ static struct nrf_exception_info nrf_exc_info; -static void spu_dump_context(struct nrf_exception_info *ctx) +static void dump_exception_info(struct nrf_exception_info *ctx) { - SPMLOG_ERRMSG("Platform Exception: SPU Fault\r\n"); + SPMLOG_ERRMSG("Platform Exception:\r\n"); -#ifdef NRF_SPU /* Report which type of violation occured */ if (ctx->events & SPU_EVENT_RAMACCERR) { - SPMLOG_DBGMSG(" RAMACCERR\r\n"); + SPMLOG_DBGMSG(" SPU.RAMACCERR\r\n"); } if (ctx->events & SPU_EVENT_PERIPHACCERR) { - SPMLOG_DBGMSG(" PERIPHACCERR\r\n"); + SPMLOG_DBGMSG(" SPU.PERIPHACCERR\r\n"); + SPMLOG_DBGMSGVAL(" Target addr: ", ctx->periphaccerr.address); } if (ctx->events & SPU_EVENT_FLASHACCERR) { - SPMLOG_DBGMSG(" FLASHACCERR\r\n"); + SPMLOG_DBGMSG(" SPU.FLASHACCERR\r\n"); } -#else - // TODO: NCSDK-25011: Support error handling on nrf54l -#endif +#if MPC_PRESENT + if (ctx->events & MPC_EVENT_MEMACCERR) { + SPMLOG_DBGMSG(" MPC.MEMACCERR\r\n"); + SPMLOG_DBGMSGVAL(" Target addr: ", ctx->memaccerr.address); + SPMLOG_DBGMSGVAL(" Access information: ", ctx->memaccerr.info); + SPMLOG_DBGMSGVAL(" Owner id: ", ctx->memaccerr.info & 0xf); + SPMLOG_DBGMSGVAL(" Masterport: ", (ctx->memaccerr.info & 0x1f0) >> 4); + SPMLOG_DBGMSGVAL(" Read: ", (ctx->memaccerr.info >> 12) & 1); + SPMLOG_DBGMSGVAL(" Write: ", (ctx->memaccerr.info >> 13) & 1); + SPMLOG_DBGMSGVAL(" Execute: ", (ctx->memaccerr.info >> 14) & 1); + SPMLOG_DBGMSGVAL(" Secure: ", (ctx->memaccerr.info >> 15) & 1); + SPMLOG_DBGMSGVAL(" Error source: ", (ctx->memaccerr.info >> 16) & 1); + } +#endif } void nrf_exception_info_store_context(void) { nrf_exc_info.events = spu_events_get(); - spu_dump_context(&nrf_exc_info); +#ifdef SPU_PERIPHACCERR_ADDRESS_ADDRESS_Msk + if (nrf_exc_info.events & SPU_EVENT_PERIPHACCERR){ + nrf_exc_info.periphaccerr.address = spu_get_peri_addr(); + } +#endif + +#ifdef MPC_PRESENT + nrf_exc_info.events |= mpc_events_get(); + if (nrf_exc_info.events & MPC_EVENT_MEMACCERR) + { + nrf_exc_info.memaccerr.address = NRF_MPC00->MEMACCERR.ADDRESS; + nrf_exc_info.memaccerr.info = NRF_MPC00->MEMACCERR.INFO; + } +#endif + + dump_exception_info(&nrf_exc_info); } void nrf_exception_info_get_context(struct nrf_exception_info *ctx) diff --git a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h index 7f297c800..04b2eb8ba 100644 --- a/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h +++ b/platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h @@ -11,6 +11,16 @@ struct nrf_exception_info { uint32_t events; + union{ + struct { + uint32_t address; + } periphaccerr; + + struct { + uint32_t address; + uint32_t info; + } memaccerr; + }; }; void nrf_exception_info_store_context(void); diff --git a/platform/ext/target/nordic_nrf/common/core/startup.h b/platform/ext/target/nordic_nrf/common/core/startup.h index 8e77c38c2..3906f138d 100644 --- a/platform/ext/target/nordic_nrf/common/core/startup.h +++ b/platform/ext/target/nordic_nrf/common/core/startup.h @@ -40,6 +40,8 @@ void SPU10_IRQHandler(void); void SPU20_IRQHandler(void); void SPU30_IRQHandler(void); +void MPC00_IRQHandler(void); + void CRACEN_IRQHandler(void); /* diff --git a/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c index a08a12611..59d3802b0 100644 --- a/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c +++ b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c @@ -112,17 +112,18 @@ DEFAULT_IRQ_HANDLER(GPIOTE30_1_Handler) DEFAULT_IRQ_HANDLER(CLOCK_POWER_Handler) #if defined(DOMAIN_NS) || defined(BL2) -DEFAULT_IRQ_HANDLER(SPU00_Handler) -DEFAULT_IRQ_HANDLER(SPU10_Handler) -DEFAULT_IRQ_HANDLER(SPU20_Handler) -DEFAULT_IRQ_HANDLER(SPU30_Handler) +DEFAULT_IRQ_HANDLER(MPC00_IRQHandler) +DEFAULT_IRQ_HANDLER(SPU00_IRQHandler) +DEFAULT_IRQ_HANDLER(SPU10_IRQHandler) +DEFAULT_IRQ_HANDLER(SPU20_IRQHandler) +DEFAULT_IRQ_HANDLER(SPU30_IRQHandler) DEFAULT_IRQ_HANDLER(CRACEN_IRQHandler) #else // TODO: Move into the SPU error handling code -DEFAULT_IRQ_HANDLER(SPU00_Handler) -DEFAULT_IRQ_HANDLER(SPU10_Handler) -DEFAULT_IRQ_HANDLER(SPU20_Handler) -DEFAULT_IRQ_HANDLER(SPU30_Handler) +DEFAULT_IRQ_HANDLER(SPU00_IRQHandler) +DEFAULT_IRQ_HANDLER(SPU10_IRQHandler) +DEFAULT_IRQ_HANDLER(SPU20_IRQHandler) +DEFAULT_IRQ_HANDLER(SPU30_IRQHandler) #endif #if defined ( __GNUC__ ) @@ -213,8 +214,8 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - SPU00_Handler, - MPC00_Handler, + SPU00_IRQHandler, + MPC00_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, @@ -277,7 +278,7 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - SPU10_Handler, + SPU10_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, @@ -341,7 +342,7 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - SPU20_Handler, + SPU20_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, @@ -405,7 +406,7 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - SPU30_Handler, + SPU30_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index d9a15de4e..c75a69920 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -730,6 +730,9 @@ enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void) #ifdef NRF_CRACEN NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET(NRF_CRACEN)); #endif +#ifdef NRF_MPC00 + NVIC_ClearTargetState(MPC00_IRQn); +#endif #ifdef SECURE_UART1 #if NRF_SECURE_UART_INSTANCE == 0 @@ -758,6 +761,14 @@ enum tfm_plat_err_t nvic_interrupt_enable(void) NVIC_EnableIRQ(NRFX_IRQ_NUMBER_GET(spu_instances[i])); } +#ifdef MPC_PRESENT + /* MPC interrupt enabling */ + mpc_enable_interrupts(); + + NVIC_ClearPendingIRQ(NRFX_IRQ_NUMBER_GET(NRF_MPC00)); + NVIC_EnableIRQ(NRFX_IRQ_NUMBER_GET(NRF_MPC00)); +#endif + /* The CRACEN driver configures the NVIC for CRACEN and is * therefore omitted here. */ diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.h b/platform/ext/target/nordic_nrf/common/core/target_cfg.h index a2b6355ca..aea09bece 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.h +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.h @@ -113,11 +113,6 @@ enum tfm_plat_err_t spu_init_cfg(void); */ enum tfm_plat_err_t spu_periph_init_cfg(void); -/** - * \brief Clears SPU interrupt. - */ -void spu_clear_irq(void); - /** * \brief Configures memory permissions via the MPC. * From 2ade42fc3d12f1c64aefec62c22fa6dabd2a80ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 14 May 2024 17:09:49 +0200 Subject: [PATCH 52/65] [nrf fromtree] Platform: Nordic: refactor spu_peripheral_config to use base addr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor spu_peripheral_config to use base addresses instead of IDs as future platforms will need the base address to identify which spu instance to use. Signed-off-by: Sebastian Bøe Change-Id: Ife60d1e76adffeb62f5ad32e0a85da8cfa467203 --- .../common/core/native_drivers/spu.c | 8 +- .../common/core/native_drivers/spu.h | 8 +- .../nordic_nrf/common/core/target_cfg.c | 90 +++++++++---------- .../common/core/tfm_hal_isolation.c | 2 +- 4 files changed, 56 insertions(+), 52 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c index c28802b3c..2c6885512 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c @@ -348,8 +348,10 @@ uint32_t spu_regions_sram_get_region_size(void) { #endif /* NRF_SPU_HAS_MEMORY */ #ifdef NRF_SPU -void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock) +void spu_peripheral_config_secure(const uint32_t periph_base_address, bool periph_lock) { + uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_address); + /* ASSERT checking that this is not an explicit Non-Secure peripheral */ NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM & SPU_PERIPHID_PERM_SECUREMAPPING_Msk) != @@ -362,8 +364,10 @@ void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock) periph_lock); } -void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock) +void spu_peripheral_config_non_secure(const uint32_t periph_base_address, bool periph_lock) { + uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_address); + /* ASSERT checking that this is not an explicit Secure peripheral */ NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM & SPU_PERIPHID_PERM_SECUREMAPPING_Msk) != diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h index 670c5f511..da7f9fc1f 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h @@ -123,26 +123,26 @@ void spu_regions_flash_config_non_secure_callable(uint32_t start_addr, uint32_t * * Configure a device peripheral to be accessible from Secure domain only. * - * \param periph_id ID number of a particular peripheral. + * \param periph_base_address Base address of a particular peripheral. * \param periph_lock Variable indicating whether to lock peripheral security * * \note * - peripheral shall not be a Non-Secure only peripheral * - DMA transactions are configured as Secure */ -void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock); +void spu_peripheral_config_secure(const uint32_t periph_base_address, bool periph_lock); /** * Configure a device peripheral to be accessible from Non-Secure domain. * - * \param periph_id ID number of a particular peripheral. + * \param periph_base_address Base address of a particular peripheral. * \param periph_lock Variable indicating whether to lock peripheral security * * \note * - peripheral shall not be a Secure-only peripheral * - DMA transactions are configured as Non-Secure */ -void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock); +void spu_peripheral_config_non_secure(const uint32_t periph_base_address, bool periph_lock); /** * /brief Retrieve the address of the transaction that triggered PERIPHACCERR. diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index c75a69920..6517b84e0 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1170,25 +1170,25 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) nrf_spu_periph_perm_lock_enable(p_spu_instance,UART_SPU_SLAVE_INDEX); #else -static const uint8_t target_peripherals[] = { +static const uint32_t target_peripherals[] = { /* The following peripherals share ID: * - FPU (FPU cannot be configured in NRF91 series, it's always NS) * - DCNF (On 53, but not 91) */ #ifndef NRF91_SERIES - NRFX_PERIPHERAL_ID_GET(NRF_FPU), + NRF_FPU_S_BASE, #endif /* The following peripherals share ID: * - REGULATORS * - OSCILLATORS */ - NRFX_PERIPHERAL_ID_GET(NRF_REGULATORS), + NRF_REGULATORS_S_BASE, /* The following peripherals share ID: * - CLOCK * - POWER * - RESET (On 53, but not 91) */ - NRFX_PERIPHERAL_ID_GET(NRF_CLOCK), + NRF_CLOCK_S_BASE, /* The following peripherals share ID: (referred to as Serial-Box) * - SPIMx * - SPISx @@ -1212,8 +1212,8 @@ static const uint8_t target_peripherals[] = { #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 1) NRFX_PERIPHERAL_ID_GET(NRF_SPIM1), #endif - NRFX_PERIPHERAL_ID_GET(NRF_SPIM2), - NRFX_PERIPHERAL_ID_GET(NRF_SPIM3), + NRF_SPIM2_S_BASE, + NRF_SPIM3_S_BASE, /* For Moonlight if a UART instance is selected to be the secure instance leave it as secure */ #if NRF_SECURE_UART_INSTANCE == 20 @@ -1230,89 +1230,89 @@ static const uint8_t target_peripherals[] = { #endif #ifdef NRF_SPIM4 - NRFX_PERIPHERAL_ID_GET(NRF_SPIM4), -#endif - NRFX_PERIPHERAL_ID_GET(NRF_SAADC), - NRFX_PERIPHERAL_ID_GET(NRF_TIMER0), - NRFX_PERIPHERAL_ID_GET(NRF_TIMER1), - NRFX_PERIPHERAL_ID_GET(NRF_TIMER2), - NRFX_PERIPHERAL_ID_GET(NRF_RTC0), - NRFX_PERIPHERAL_ID_GET(NRF_RTC1), - NRFX_PERIPHERAL_ID_GET(NRF_DPPIC), + NRF_SPIM4_S_BASE, +#endif + NRF_SAADC_S_BASE, + NRF_TIMER0_S_BASE, + NRF_TIMER1_S_BASE, + NRF_TIMER2_S_BASE, + NRF_RTC0_S_BASE, + NRF_RTC1_S_BASE, + NRF_DPPIC_S_BASE, #ifndef PSA_API_TEST_IPC #ifdef NRF_WDT0 /* WDT0 is used as a secure peripheral in PSA FF tests */ - NRFX_PERIPHERAL_ID_GET(NRF_WDT0), + NRF_WDT0_S_BASE, #endif #ifdef NRF_WDT - NRFX_PERIPHERAL_ID_GET(NRF_WDT), + NRF_WDT_S_BASE, #endif #endif /* PSA_API_TEST_IPC */ #ifdef NRF_WDT1 - NRFX_PERIPHERAL_ID_GET(NRF_WDT1), + NRF_WDT1_S_BASE, #endif /* The following peripherals share ID: * - COMP * - LPCOMP */ #ifdef NRF_COMP - NRFX_PERIPHERAL_ID_GET(NRF_COMP), + NRF_COMP_S_BASE, #endif - NRFX_PERIPHERAL_ID_GET(NRF_EGU0), - NRFX_PERIPHERAL_ID_GET(NRF_EGU1), - NRFX_PERIPHERAL_ID_GET(NRF_EGU2), - NRFX_PERIPHERAL_ID_GET(NRF_EGU3), - NRFX_PERIPHERAL_ID_GET(NRF_EGU4), + NRF_EGU0_S_BASE, + NRF_EGU1_S_BASE, + NRF_EGU2_S_BASE, + NRF_EGU3_S_BASE, + NRF_EGU4_S_BASE, #ifndef PSA_API_TEST_IPC /* EGU5 is used as a secure peripheral in PSA FF tests */ - NRFX_PERIPHERAL_ID_GET(NRF_EGU5), + NRF_EGU5_S_BASE, #endif - NRFX_PERIPHERAL_ID_GET(NRF_PWM0), - NRFX_PERIPHERAL_ID_GET(NRF_PWM1), - NRFX_PERIPHERAL_ID_GET(NRF_PWM2), - NRFX_PERIPHERAL_ID_GET(NRF_PWM3), + NRF_PWM0_S_BASE, + NRF_PWM1_S_BASE, + NRF_PWM2_S_BASE, + NRF_PWM3_S_BASE, #ifdef NRF_PDM - NRFX_PERIPHERAL_ID_GET(NRF_PDM), + NRF_PDM_S_BASE, #endif #ifdef NRF_PDM0 - NRFX_PERIPHERAL_ID_GET(NRF_PDM0), + NRF_PDM0_S_BASE, #endif #ifdef NRF_I2S - NRFX_PERIPHERAL_ID_GET(NRF_I2S), + NRF_I2S_S_BASE, #endif #ifdef NRF_I2S0 - NRFX_PERIPHERAL_ID_GET(NRF_I2S0), + NRF_I2S0_S_BASE, #endif - NRFX_PERIPHERAL_ID_GET(NRF_IPC), + NRF_IPC_S_BASE, #ifndef SECURE_QSPI #ifdef NRF_QSPI - NRFX_PERIPHERAL_ID_GET(NRF_QSPI), + NRF_QSPI_S_BASE, #endif #endif #ifdef NRF_NFCT - NRFX_PERIPHERAL_ID_GET(NRF_NFCT), + NRF_NFCT_S_BASE, #endif #ifdef NRF_MUTEX - NRFX_PERIPHERAL_ID_GET(NRF_MUTEX), + NRF_MUTEX_S_BASE, #endif #ifdef NRF_QDEC0 - NRFX_PERIPHERAL_ID_GET(NRF_QDEC0), + NRF_QDEC0_S_BASE, #endif #ifdef NRF_QDEC1 - NRFX_PERIPHERAL_ID_GET(NRF_QDEC1), + NRF_QDEC1_S_BASE, #endif #ifdef NRF_USBD - NRFX_PERIPHERAL_ID_GET(NRF_USBD), + NRF_USBD_S_BASE, #endif #ifdef NRF_USBREGULATOR - NRFX_PERIPHERAL_ID_GET(NRF_USBREGULATOR), + NRF_USBREGULATOR_S_BASE, #endif - NRFX_PERIPHERAL_ID_GET(NRF_NVMC), - NRFX_PERIPHERAL_ID_GET(NRF_P0), + NRF_NVMC_S_BASE, + NRF_P0_S_BASE, #ifdef NRF_P1 - NRFX_PERIPHERAL_ID_GET(NRF_P1), + NRF_P1_S_BASE, #endif - NRFX_PERIPHERAL_ID_GET(NRF_VMC), + NRF_VMC_S_BASE, }; for (int i = 0; i < ARRAY_SIZE(target_peripherals); i++) { diff --git a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c index a2bc0b4d3..f35ef8825 100644 --- a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c +++ b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c @@ -132,7 +132,7 @@ tfm_hal_bind_boundary(const struct partition_load_info_t *p_ldinf, } #ifdef NRF_SPU - spu_peripheral_config_secure(NRFX_PERIPHERAL_ID_GET(plat_data_ptr->periph_start), + spu_peripheral_config_secure(plat_data_ptr->periph_start, SPU_LOCK_CONF_LOCKED); #else // TODO: NCSDK-22597: Support configuring peripherals as secure From a1bbc60218dcd872652e6df40297ef78e6db1a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 14 May 2024 17:11:26 +0200 Subject: [PATCH 53/65] [nrf noup] nordic_nrf: refactor spu_peripheral_config to use base addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Refactor spu_peripheral_config to use base addresses instead of IDs as future platforms will need the base address to identify which spu instance to use. Signed-off-by: Sebastian Bøe Change-Id: Ife60d1e76adffeb62f5ad32e0a85da8cfa467203 --- .../common/core/cmsis_drivers/Driver_USART.c | 4 ++-- .../ext/target/nordic_nrf/common/core/target_cfg.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index f2ffaf1a6..42053ebd8 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -116,7 +116,7 @@ static int32_t ARM_USARTx_Initialize(ARM_USART_SignalEvent_t cb_event, ARG_UNUSED(cb_event); #ifdef SPU_CONFIGURE_UART - spu_peripheral_config_secure(NRFX_PERIPHERAL_ID_GET((uint32_t)uart_resources->uarte.p_reg), false); + spu_peripheral_config_secure((uint32_t)uart_resources->uarte.p_reg, false); NVIC_ClearTargetState(NRFX_IRQ_NUMBER_GET((uint32_t)uart_resources->uarte.p_reg)); #endif @@ -149,7 +149,7 @@ static int32_t ARM_USARTx_Uninitialize(UARTx_Resources *uart_resources) uart_resources->initialized = false; #ifdef SPU_CONFIGURE_UART - spu_peripheral_config_non_secure(NRFX_PERIPHERAL_ID_GET((uint32_t)uart_resources->uarte.p_reg), false); + spu_peripheral_config_non_secure((uint32_t)uart_resources->uarte.p_reg, false); NVIC_SetTargetState(NRFX_IRQ_NUMBER_GET((uint32_t)uart_resources->uarte.p_reg)); #endif diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 6517b84e0..5f981a3c3 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1201,32 +1201,32 @@ static const uint32_t target_peripherals[] = { * The UART Driver will configure it as non-secure when it uninitializes. */ #if defined(NRF54L15_ENGA_XXAA) - NRFX_PERIPHERAL_ID_GET(NRF_SPIM00), + NRF_SPIM00_S_BASE, #else #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) - NRFX_PERIPHERAL_ID_GET(NRF_SPIM0), + NRF_SPIM0_S_BASE, #endif /* !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 0) */ #endif /* NRF54L15_ENGA_XXAA */ /* When UART1 is a secure peripheral we need to leave Serial-Box 1 as Secure */ #if !(defined(SECURE_UART1) && NRF_SECURE_UART_INSTANCE == 1) - NRFX_PERIPHERAL_ID_GET(NRF_SPIM1), + NRF_SPIM1_S_BASE, #endif NRF_SPIM2_S_BASE, NRF_SPIM3_S_BASE, /* For Moonlight if a UART instance is selected to be the secure instance leave it as secure */ #if NRF_SECURE_UART_INSTANCE == 20 - NRFX_PERIPHERAL_ID_GET(NRF_SPIM20), + NRF_SPIM20_S_BASE, #endif #if NRF_SECURE_UART_INSTANCE == 21 - NRFX_PERIPHERAL_ID_GET(NRF_SPIM21), + NRF_SPIM21_S_BASE, #endif #if NRF_SECURE_UART_INSTANCE == 22 - NRFX_PERIPHERAL_ID_GET(NRF_SPIM22), + NRF_SPIM22_S_BASE, #endif #if NRF_SECURE_UART_INSTANCE == 30 - NRFX_PERIPHERAL_ID_GET(NRF_SPIM30), + NRF_SPIM30_S_BASE, #endif #ifdef NRF_SPIM4 From 232f8b5cfd7753fbdae454660b58b8eb589b742a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 14 May 2024 15:09:28 +0200 Subject: [PATCH 54/65] [nrf fromlist] Platform: Nordic: Add function for calculating spu instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add driver function. Signed-off-by: Sebastian Bøe Change-Id: Ib1e442a54d599c4e42e74903d49920f24e9d8ec9 --- .../nordic_nrf/common/core/native_drivers/spu.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h index da7f9fc1f..8c8856af2 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h @@ -150,6 +150,19 @@ void spu_peripheral_config_non_secure(const uint32_t periph_base_address, bool p */ uint32_t spu_get_peri_addr(void); +/** + * Return the SPU instance that can be used to configure the + * peripheral at the given base address. + */ +static inline NRF_SPU_Type * spu_instance_from_peripheral_addr(uint32_t peripheral_addr) +{ + /* See the SPU chapter in the IPS for how this is calculated */ + + uint32_t apb_bus_number = peripheral_addr & 0x00FC0000; + + return (NRF_SPU_Type *)(0x50000000 | apb_bus_number); +} + /** * \brief Return base address of a Flash SPU regions * From a35b6a419d6e78451931d00437b5f9778f26acb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 16 May 2024 14:31:49 +0200 Subject: [PATCH 55/65] [nrf fromlist] Platform: Nordic: Port spu_peripheral_config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port spu_peripheral_config to also support the new API. Signed-off-by: Sebastian Bøe Change-Id: I1763874ce74ad39cbf0ef256ef8edc669038d226 --- .../common/core/native_drivers/spu.c | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c index 2c6885512..3d93de8b6 100644 --- a/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c +++ b/platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c @@ -347,11 +347,11 @@ uint32_t spu_regions_sram_get_region_size(void) { #endif /* NRF_SPU_HAS_MEMORY */ -#ifdef NRF_SPU void spu_peripheral_config_secure(const uint32_t periph_base_address, bool periph_lock) { uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_address); +#if NRF_SPU_HAS_MEMORY /* ASSERT checking that this is not an explicit Non-Secure peripheral */ NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM & SPU_PERIPHID_PERM_SECUREMAPPING_Msk) != @@ -362,12 +362,26 @@ void spu_peripheral_config_secure(const uint32_t periph_base_address, bool perip 1 /* Secure */, 1 /* Secure DMA */, periph_lock); + +#else + + NRF_SPU_Type * nrf_spu = spu_instance_from_peripheral_addr(periph_base_address); + + uint8_t spu_id = NRFX_PERIPHERAL_ID_GET(nrf_spu); + + uint8_t index = periph_id - spu_id; + + nrf_spu_periph_perm_secattr_set(nrf_spu, index, true /* Secure */); + nrf_spu_periph_perm_dmasec_set(nrf_spu, index, true /* Secure */); + nrf_spu_periph_perm_lock_enable(nrf_spu, index); +#endif } void spu_peripheral_config_non_secure(const uint32_t periph_base_address, bool periph_lock) { uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_address); +#if NRF_SPU_HAS_MEMORY /* ASSERT checking that this is not an explicit Secure peripheral */ NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM & SPU_PERIPHID_PERM_SECUREMAPPING_Msk) != @@ -378,7 +392,15 @@ void spu_peripheral_config_non_secure(const uint32_t periph_base_address, bool p 0 /* Non-Secure */, 0 /* Non-Secure DMA */, periph_lock); -} #else -// TODO: NCSDK-22597: Support configuring peripherals as secure + NRF_SPU_Type * nrf_spu = spu_instance_from_peripheral_addr(periph_base_address); + + uint8_t spu_id = NRFX_PERIPHERAL_ID_GET(nrf_spu); + + uint8_t index = periph_id - spu_id; + + nrf_spu_periph_perm_secattr_set(nrf_spu, index, false /* Non-Secure */); + nrf_spu_periph_perm_dmasec_set(nrf_spu, index, false /* Non-Secure */); + nrf_spu_periph_perm_lock_enable(nrf_spu, index); #endif +} From 4e3cdd2bcf03cccc20137a421a21a6700130eb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 14 May 2024 15:00:35 +0200 Subject: [PATCH 56/65] [nrf noup] nrf54l: configure pins as secure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Configure pins as secure on 54L. Signed-off-by: Sebastian Bøe Change-Id: Id50ef81807c5109c01ed6405376f3cfa882c66e0 --- .../nordic_nrf/common/core/target_cfg.c | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 5f981a3c3..72b6fe392 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1325,15 +1325,48 @@ static const uint32_t target_peripherals[] = { dppi_channel_configuration(); /* GPIO pin configuration */ -#ifdef NRF_SPU - - nrf_spu_gpio_config_set(NRF_SPU, 0, TFM_PERIPHERAL_GPIO0_PIN_MASK_SECURE, SPU_LOCK_CONF_LOCKED); + uint32_t secure_pins[] = { + TFM_PERIPHERAL_GPIO0_PIN_MASK_SECURE, #ifdef TFM_PERIPHERAL_GPIO1_PIN_MASK_SECURE - nrf_spu_gpio_config_set(NRF_SPU, 1, TFM_PERIPHERAL_GPIO1_PIN_MASK_SECURE, SPU_LOCK_CONF_LOCKED); + TFM_PERIPHERAL_GPIO1_PIN_MASK_SECURE, +#endif +#ifdef TFM_PERIPHERAL_GPIO2_PIN_MASK_SECURE + TFM_PERIPHERAL_GPIO2_PIN_MASK_SECURE, #endif + }; + + /* Note that there are two different API's for SPU configuration */ +#if NRF_SPU_HAS_MEMORY + + for(int port = 0; port < ARRAY_SIZE(secure_pins); port++){ + nrf_spu_gpio_config_set(NRF_SPU, port, secure_pins[port], SPU_LOCK_CONF_LOCKED); + } +#elif NRF_SPU_HAS_PERIPHERAL_ACCESS + + for(int port = 0; port < ARRAY_SIZE(secure_pins); port++) { + for (int pin = 0; pin < 32; pin++) { + if (secure_pins[port] & (1 << pin)) { + bool enable = true; // secure + + /* + * Unfortunately, NRF_P0 is not configured by NRF_SPU00, etc. + * so it is a bit convoluted to find the SPU instance for port x. + */ + uint32_t gpio_port_addr[2] = { + NRF_P0_S_BASE, + NRF_P1_S_BASE, + }; + + NRF_SPU_Type * spu_instance = spu_instance_from_peripheral_addr(gpio_port_addr[port]); + + nrf_spu_feature_secattr_set(spu_instance, NRF_SPU_FEATURE_GPIO_PIN, port, pin, enable); + nrf_spu_feature_lock_enable(spu_instance, NRF_SPU_FEATURE_GPIO_PIN, port, pin); + } + } + } #else - /* TODO: NCSDK-22597: Support configuring pins as secure or non-secure on nrf54L */ +#error "Expected either NRF_SPU_HAS_MEMORY or NRF_SPU_HAS_PERIPHERAL_ACCESS to be true" #endif /* Configure properly the XL1 and XL2 pins so that the low-frequency crystal From 57aa07dff478ce7ff79ed233fa25ed02738879a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 16 May 2024 14:33:12 +0200 Subject: [PATCH 57/65] [nrf noup] Platform: 54l: Delete dead code in target_cfg.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Delete dead code in target_cfg.c. It is redundant with the memset. Signed-off-by: Sebastian Bøe Change-Id: I96ffb4002d70a08c827d47fe87ae938b57731f0c --- .../nordic_nrf/common/core/target_cfg.c | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 72b6fe392..0f8c15bce 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1093,11 +1093,6 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) * * Just after memsetting to 0 we explicitly configure the * peripherals that should be secure back to secure again. - * - * At the moment we also have some redundant code that is - * configuring things to 0/NonSecure because it is not clear if - * this strategy is safe and we want to keep this code in case we - * need it later. */ // TODO: NCSDK-22597: Evaluate if it is safe to memset everything // in NRF_SPU to 0. @@ -1106,42 +1101,6 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) memset(NRF_SPU20, 0, sizeof(NRF_SPU_Type)); memset(NRF_SPU30, 0, sizeof(NRF_SPU_Type)); - /* Configure peripherals to be non-secure */ - for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) { - NRF_SPU_Type * spu_instance = spu_instances[i]; - - /* Configure all pins as non-secure */ - bool spu_has_GPIO = i != 1; - if(spu_has_GPIO) { - for(int j = 0; j < ARRAY_SIZE(spu_instance->FEATURE.GPIO); j++) { - for(int pin = 0; pin < 32; pin++) { - spu_instance->FEATURE.GPIO[j].PIN[pin] = 0; - } - } - } - - /* TODO: NCSDK-22597: Make peripherals configurable */ - for(uint8_t index = 0; index < ARRAY_SIZE(spu_instance->PERIPH); index++) { - if(!nrf_spu_periph_perm_present_get(spu_instance, index)) { - /* Peripheral is not present, nothing to configure */ - continue; - } - - nrf_spu_securemapping_t securemapping = nrf_spu_periph_perm_securemapping_get(spu_instance, index); - - bool secattr_has_effect = - securemapping == NRF_SPU_SECUREMAPPING_USERSELECTABLE || - securemapping == NRF_SPU_SECUREMAPPING_SPLIT; - - if(secattr_has_effect) { - bool enable = false; /* false means non-secure */ - - nrf_spu_periph_perm_secattr_set(spu_instance, index, enable); - } - - /* Note that we don't configure dmasec because it has no effect when secattr is non-secure */ - } - } /* Configure TF-M's UART peripheral to be secure with secure DMA */ #if NRF_SECURE_UART_INSTANCE == 00 From 406ebd506ae8e40402aebc168c1458a52ef4793f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 16 May 2024 14:34:36 +0200 Subject: [PATCH 58/65] [nrf noup] Platform: 54L: Refactor UART security configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Refactor UART security configuration to use spu_peripheral_config_secure. Signed-off-by: Sebastian Bøe Change-Id: I00d21c4401fa7c67d51eaf14804c992262c73710 --- .../nordic_nrf/common/core/target_cfg.c | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index 0f8c15bce..eba9e5b52 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1101,32 +1101,23 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) memset(NRF_SPU20, 0, sizeof(NRF_SPU_Type)); memset(NRF_SPU30, 0, sizeof(NRF_SPU_Type)); - - /* Configure TF-M's UART peripheral to be secure with secure DMA */ + /* Configure TF-M's UART peripheral to be secure */ #if NRF_SECURE_UART_INSTANCE == 00 - uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte00); - NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte00); + uint32_t uart_periph_start = tfm_peripheral_uarte00.periph_start; #endif #if NRF_SECURE_UART_INSTANCE == 20 - uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte20); - NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte20); + uint32_t uart_periph_start = tfm_peripheral_uarte20.periph_start; #endif #if NRF_SECURE_UART_INSTANCE == 21 - uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte21); - NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte21); + uint32_t uart_periph_start = tfm_peripheral_uarte21.periph_start; #endif #if NRF_SECURE_UART_INSTANCE == 22 - uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte22); - NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte22); + uint32_t uart_periph_start = tfm_peripheral_uarte22.periph_start; #endif #if NRF_SECURE_UART_INSTANCE == 30 - uint32_t UART_SPU_SLAVE_INDEX = GET_SPU_SLAVE_INDEX(tfm_peripheral_uarte30); - NRF_SPU_Type * p_spu_instance = GET_SPU_INSTANCE(tfm_peripheral_uarte30); + uint32_t uart_periph_start = tfm_peripheral_uarte30.periph_start; #endif - bool enable = true; /* true means secure */ - nrf_spu_periph_perm_secattr_set(p_spu_instance, UART_SPU_SLAVE_INDEX, enable); - nrf_spu_periph_perm_dmasec_set(p_spu_instance, UART_SPU_SLAVE_INDEX, enable); - nrf_spu_periph_perm_lock_enable(p_spu_instance,UART_SPU_SLAVE_INDEX); + spu_peripheral_config_secure(uart_periph_start, SPU_LOCK_CONF_LOCKED); #else static const uint32_t target_peripherals[] = { From 67783a647d6b7976bd7b6b3a9acbda19565e7f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Thu, 16 May 2024 14:35:22 +0200 Subject: [PATCH 59/65] [nrf noup] Platform: Nordic: Configure misc. peripherals as Secure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Configure misc. peripherals as Secure. See the code for which peripherals and why. Signed-off-by: Sebastian Bøe Change-Id: I3cf4f42d5d3bc0aa4dc266e0c1d8035ad69372a1 --- .../nordic_nrf/common/core/target_cfg.c | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index eba9e5b52..adb2bf53e 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1119,6 +1119,29 @@ enum tfm_plat_err_t spu_periph_init_cfg(void) #endif spu_peripheral_config_secure(uart_periph_start, SPU_LOCK_CONF_LOCKED); + /* Configure the CTRL-AP mailbox interface to be secure as it is used by the secure ADAC service */ + spu_peripheral_config_secure(NRF_CTRLAP_S_BASE, SPU_LOCK_CONF_LOCKED); + + /* Configure NRF_MEMCONF to be secure as it could otherwise be used to corrupt secure RAM. */ + spu_peripheral_config_secure(NRF_MEMCONF_S_BASE, SPU_LOCK_CONF_LOCKED); + + /* Configure trace to be secure, as the security implications of non-secure trace are not understood */ + spu_peripheral_config_secure(NRF_TAD_S_BASE, SPU_LOCK_CONF_LOCKED); + + /* Configure these HW features, which are not in the MDK, to be + * secure, as the security implications of them being non-secure + * are not understood + */ + uint32_t base_addresses[4] = { + 0x50056000, + 0x5008C000, + 0x500E6000, + 0x5010F000 + }; + for(int i = 0; i < 4; i++) { + spu_peripheral_config_secure(base_addresses[i], SPU_LOCK_CONF_LOCKED); + } + #else static const uint32_t target_peripherals[] = { /* The following peripherals share ID: From 3ebf3d3bd0fe906873eaaa3e13bba319b5705131 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Tue, 21 May 2024 15:43:08 +0200 Subject: [PATCH 60/65] [nrf noup] platform: nordic_nrf: 54L Use HUK library for EITS fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Due to dependencies problems between the ITS and crypto partitions refactoring the ITS encryption interface to use the HUK library and the cracen driver directly. Signed-off-by: Markus Swarowsky --- .../core/tfm_hal_its_encryption_cracen.c | 95 ++++++------------- 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c b/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c index bbcbb97a0..f75901622 100644 --- a/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c +++ b/platform/ext/target/nordic_nrf/common/core/tfm_hal_its_encryption_cracen.c @@ -20,16 +20,15 @@ #include "config_tfm.h" #include "platform/include/tfm_hal_its_encryption.h" #include "platform/include/tfm_hal_its.h" -#include "psa/crypto.h" -#include "tfm_crypto_defs.h" + +typedef uint64_t psa_drv_slot_number_t; +#include +#include + #define CHACHA20_KEY_SIZE 32 #define TFM_ITS_AEAD_ALG PSA_ALG_CHACHA20_POLY1305 -#define ITS_ENCRYPTION_SUCCESS 0 - -#define HUK_KMU_SLOT 2 -#define HUK_KMU_SIZE_BITS 128 /* Global encryption counter which resets per boot. The counter ensures that * the nonce will not be identical for consecutive file writes during the same @@ -78,9 +77,8 @@ enum tfm_hal_status_t tfm_hal_its_aead_generate_nonce(uint8_t *nonce, return TFM_HAL_ERROR_GENERIC; } - /* psa_generate_random is not using any key/its functions wo we can use it here*/ if (g_enc_counter == 0) { - psa_status_t status = psa_generate_random(g_enc_nonce_seed, sizeof(g_enc_nonce_seed)); + psa_status_t status = cracen_get_random(NULL, g_enc_nonce_seed, sizeof(g_enc_nonce_seed)); if (status != PSA_SUCCESS) { return TFM_HAL_ERROR_GENERIC; } @@ -111,12 +109,8 @@ static bool ctx_is_valid(struct tfm_hal_its_auth_crypt_ctx *ctx) return !ret; } -/* - * The cracen driver code doesn't use any persistent keys so no calls to its - * therefore the PSA API's can be used directly. - */ psa_status_t tfm_hal_its_get_aead(struct tfm_hal_its_auth_crypt_ctx *ctx, - uint8_t *plaintext, + const uint8_t *plaintext, const size_t plaintext_size, uint8_t *ciphertext, const size_t ciphertext_size, @@ -125,9 +119,8 @@ psa_status_t tfm_hal_its_get_aead(struct tfm_hal_its_auth_crypt_ctx *ctx, bool encrypt) { psa_status_t status; + uint8_t key_out[CHACHA20_KEY_SIZE]; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_derivation_operation_t op = PSA_KEY_DERIVATION_OPERATION_INIT; - psa_key_id_t key; size_t ciphertext_length; size_t tag_length = PSA_AEAD_TAG_LENGTH(PSA_KEY_TYPE_CHACHA20, PSA_BYTES_TO_BITS(CHACHA20_KEY_SIZE), @@ -141,52 +134,27 @@ psa_status_t tfm_hal_its_get_aead(struct tfm_hal_its_auth_crypt_ctx *ctx, return TFM_HAL_ERROR_INVALID_INPUT; } - if (ciphertext_size < PSA_AEAD_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_CHACHA20, - TFM_ITS_AEAD_ALG, - plaintext_size)){ + if (encrypt && (ciphertext_size < PSA_AEAD_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_CHACHA20, + TFM_ITS_AEAD_ALG, + plaintext_size))){ return TFM_HAL_ERROR_INVALID_INPUT; } - /* Set the key attributes for the key */ + + status = hw_unique_key_derive_key(HUK_KEYSLOT_MKEK, NULL, 0, ctx->deriv_label, ctx->deriv_label_size, key_out, sizeof(key_out)); + if (status != HW_UNIQUE_KEY_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + psa_set_key_usage_flags(&attributes, (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT)); psa_set_key_algorithm(&attributes, TFM_ITS_AEAD_ALG); psa_set_key_type(&attributes, PSA_KEY_TYPE_CHACHA20); psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(CHACHA20_KEY_SIZE)); - status = psa_key_derivation_setup(&op, PSA_ALG_SP800_108_COUNTER_CMAC); - if (status != PSA_SUCCESS) { - return status; - } - - /* Set up a key derivation operation with HUK */ - status = psa_key_derivation_input_key(&op, PSA_KEY_DERIVATION_INPUT_SECRET, - TFM_BUILTIN_KEY_ID_HUK); - if (status != PSA_SUCCESS) { - goto err_release_op; - } - - /* Supply the PS key label as an input to the key derivation */ - status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_LABEL, - ctx->deriv_label, - ctx->deriv_label_size); - if (status != PSA_SUCCESS) { - goto err_release_op; - } - - /* Create the storage key from the key derivation operation */ - status = psa_key_derivation_output_key(&attributes, &op, &key); - if (status != PSA_SUCCESS) { - goto err_release_op; - } - - /* Free resources associated with the key derivation operation */ - status = psa_key_derivation_abort(&op); - if (status != PSA_SUCCESS) { - goto err_release_key; - } - if (encrypt) { - status = psa_aead_encrypt(key, + status = cracen_aead_encrypt(&attributes, + key_out, + sizeof(key_out), TFM_ITS_AEAD_ALG, ctx->nonce, ctx->nonce_size, @@ -198,34 +166,28 @@ psa_status_t tfm_hal_its_get_aead(struct tfm_hal_its_auth_crypt_ctx *ctx, ciphertext_size, &ciphertext_length); } else { - status = psa_aead_decrypt(key, + status = cracen_aead_decrypt(&attributes, + key_out, + sizeof(key_out), TFM_ITS_AEAD_ALG, ctx->nonce, ctx->nonce_size, ctx->aad, ctx->add_size, - ciphertext, - ciphertext_size, plaintext, plaintext_size, + ciphertext, + ciphertext_size, &ciphertext_length); } if(status != PSA_SUCCESS){ - goto err_release_key; + return status; } /* copy tag from ciphertext buffer to tag buffer */ memcpy(tag, ciphertext + ciphertext_length - tag_length, tag_length); -err_release_key: - (void)psa_destroy_key(key); - return status; - -err_release_op: - (void)psa_key_derivation_abort(&op); - - return PSA_ERROR_GENERIC_ERROR; } enum tfm_hal_status_t tfm_hal_its_aead_encrypt(struct tfm_hal_its_auth_crypt_ctx *ctx, @@ -268,6 +230,9 @@ enum tfm_hal_status_t tfm_hal_its_aead_decrypt(struct tfm_hal_its_auth_crypt_ctx tag_size, false); + if (status != PSA_SUCCESS) { + return TFM_HAL_ERROR_GENERIC; + } + return TFM_HAL_SUCCESS; } - From 39a386c797428a82d77c2b173a6b028af565f03c Mon Sep 17 00:00:00 2001 From: Markus Rekdal Date: Thu, 23 May 2024 09:16:56 +0200 Subject: [PATCH 61/65] [nrf fromtree] Platform: nordic_nrf: Don't configure NRF_VMC as non-secure Dont configure the volatile memory controller as a non-secure peripheral (cherry picked from commit c670a6af1f0a3d7d6389e8879e8de17c1bd442fe) Change-Id: I2489defaf6deb89beba7447ba079ea3e5afebca5 Signed-off-by: Markus Rekdal --- platform/ext/target/nordic_nrf/common/core/target_cfg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index adb2bf53e..cf0dd2b28 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -1285,7 +1285,6 @@ static const uint32_t target_peripherals[] = { #ifdef NRF_P1 NRF_P1_S_BASE, #endif - NRF_VMC_S_BASE, }; for (int i = 0; i < ARRAY_SIZE(target_peripherals); i++) { From 92a5b4ffa527a1d9fb00924c227536e46169bd6e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 21 May 2024 15:11:33 +0200 Subject: [PATCH 62/65] [nrf noup] cmake: Fix TFM psa_crypto_config linking error Fix linking errors with psa_crypto_config observed in TFM test applications. To be reverted during the next TFM upmerge, as this isolated change is already part of a larger commit upstream. Signed-off-by: Robert Lubos --- cmake/spe-CMakeLists.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/spe-CMakeLists.cmake b/cmake/spe-CMakeLists.cmake index 1915a9c4d..b92e97b62 100644 --- a/cmake/spe-CMakeLists.cmake +++ b/cmake/spe-CMakeLists.cmake @@ -13,7 +13,7 @@ cmake_minimum_required(VERSION 3.15) include(spe_config) include(spe_export) -set_target_properties(tfm_config psa_interface PROPERTIES IMPORTED_GLOBAL True) +set_target_properties(tfm_config psa_interface psa_crypto_config PROPERTIES IMPORTED_GLOBAL True) target_link_libraries(tfm_config INTERFACE psa_interface) # In actual NS integration, NS side build should include the source files From e6e34d625a81e2380650417690db4661fa4d42a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vidar=20Lilleb=C3=B8?= Date: Thu, 23 May 2024 12:31:50 +0200 Subject: [PATCH 63/65] [nrf noup] nRF54L support for secure interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for handling secure interrupts and secure peripherals for nRF54L. Signed-off-by: Vidar Lillebø --- .../common/core/cmsis_drivers/Driver_USART.c | 1 - .../nordic_nrf/common/core/startup_nrf54l15.c | 210 +++++------ .../nordic_nrf/common/core/target_cfg.c | 147 +++++++- .../common/core/tfm_hal_isolation.c | 4 - .../nordic_nrf/common/nrf54l15/mmio_defs.h | 67 +++- .../common/nrf54l15/tfm_interrupts.c | 348 ++++++++++++++++++ .../common/nrf54l15/tfm_peripherals_def.h | 72 +++- 7 files changed, 714 insertions(+), 135 deletions(-) create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/tfm_interrupts.c diff --git a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c index 42053ebd8..bf2ca6852 100644 --- a/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c +++ b/platform/ext/target/nordic_nrf/common/core/cmsis_drivers/Driver_USART.c @@ -28,7 +28,6 @@ #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) #endif -// TODO: NCSDK-22597: Support configuring peripherals as secure #if !(DOMAIN_NS == 1U) && defined(CONFIG_TFM_LOG_SHARE_UART) && defined(NRF_SPU) #define SPU_CONFIGURE_UART #include diff --git a/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c index 59d3802b0..1f0eab8f5 100644 --- a/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c +++ b/platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c @@ -57,59 +57,59 @@ DEFAULT_IRQ_HANDLER(DebugMon_Handler) DEFAULT_IRQ_HANDLER(PendSV_Handler) DEFAULT_IRQ_HANDLER(SysTick_Handler) -DEFAULT_IRQ_HANDLER(SWI00_Handler) -DEFAULT_IRQ_HANDLER(SWI01_Handler) -DEFAULT_IRQ_HANDLER(SWI02_Handler) -DEFAULT_IRQ_HANDLER(SWI03_Handler) -DEFAULT_IRQ_HANDLER(MPC00_Handler) -DEFAULT_IRQ_HANDLER(AAR00_CCM00_Handler) -DEFAULT_IRQ_HANDLER(ECB00_Handler) -DEFAULT_IRQ_HANDLER(SERIAL00_Handler) -DEFAULT_IRQ_HANDLER(RRAMC_Handler) -DEFAULT_IRQ_HANDLER(VPR00_Handler) -DEFAULT_IRQ_HANDLER(CTRLAP_Handler) -DEFAULT_IRQ_HANDLER(CM33SS_Handler) -DEFAULT_IRQ_HANDLER(TIMER00_Handler) -DEFAULT_IRQ_HANDLER(TIMER10_Handler) -DEFAULT_IRQ_HANDLER(RTC10_Handler) -DEFAULT_IRQ_HANDLER(EGU10_Handler) -DEFAULT_IRQ_HANDLER(AAR10_CCM10_Handler) -DEFAULT_IRQ_HANDLER(ECB10_Handler) -DEFAULT_IRQ_HANDLER(RADIO_0_Handler) -DEFAULT_IRQ_HANDLER(RADIO_1_Handler) -DEFAULT_IRQ_HANDLER(SERIAL20_Handler) -DEFAULT_IRQ_HANDLER(SERIAL21_Handler) -DEFAULT_IRQ_HANDLER(SERIAL22_Handler) -DEFAULT_IRQ_HANDLER(EGU20_Handler) -DEFAULT_IRQ_HANDLER(TIMER20_Handler) -DEFAULT_IRQ_HANDLER(TIMER21_Handler) -DEFAULT_IRQ_HANDLER(TIMER22_Handler) -DEFAULT_IRQ_HANDLER(TIMER23_Handler) -DEFAULT_IRQ_HANDLER(TIMER24_Handler) -DEFAULT_IRQ_HANDLER(PWM20_Handler) -DEFAULT_IRQ_HANDLER(PWM21_Handler) -DEFAULT_IRQ_HANDLER(PWM22_Handler) -DEFAULT_IRQ_HANDLER(SAADC_Handler) -DEFAULT_IRQ_HANDLER(NFCT_Handler) -DEFAULT_IRQ_HANDLER(TEMP_Handler) -DEFAULT_IRQ_HANDLER(GPIOTE20_0_Handler) -DEFAULT_IRQ_HANDLER(GPIOTE20_1_Handler) -DEFAULT_IRQ_HANDLER(TAMPC_Handler) -DEFAULT_IRQ_HANDLER(I2S20_Handler) -DEFAULT_IRQ_HANDLER(QDEC20_Handler) -DEFAULT_IRQ_HANDLER(QDEC21_Handler) -DEFAULT_IRQ_HANDLER(GRTC_0_Handler) -DEFAULT_IRQ_HANDLER(GRTC_1_Handler) -DEFAULT_IRQ_HANDLER(GRTC_2_Handler) -DEFAULT_IRQ_HANDLER(GRTC_3_Handler) -DEFAULT_IRQ_HANDLER(SERIAL30_Handler) -DEFAULT_IRQ_HANDLER(RTC30_Handler) -DEFAULT_IRQ_HANDLER(COMP_LPCOMP_Handler) -DEFAULT_IRQ_HANDLER(WDT30_Handler) -DEFAULT_IRQ_HANDLER(WDT31_Handler) -DEFAULT_IRQ_HANDLER(GPIOTE30_0_Handler) -DEFAULT_IRQ_HANDLER(GPIOTE30_1_Handler) -DEFAULT_IRQ_HANDLER(CLOCK_POWER_Handler) +DEFAULT_IRQ_HANDLER(SWI00_IRQHandler) +DEFAULT_IRQ_HANDLER(SWI01_IRQHandler) +DEFAULT_IRQ_HANDLER(SWI02_IRQHandler) +DEFAULT_IRQ_HANDLER(SWI03_IRQHandler) +DEFAULT_IRQ_HANDLER(MPC00_IRQHandler) +DEFAULT_IRQ_HANDLER(AAR00_CCM00_IRQHandler) +DEFAULT_IRQ_HANDLER(ECB00_IRQHandler) +DEFAULT_IRQ_HANDLER(SERIAL00_IRQHandler) +DEFAULT_IRQ_HANDLER(RRAMC_IRQHandler) +DEFAULT_IRQ_HANDLER(VPR00_IRQHandler) +DEFAULT_IRQ_HANDLER(CTRLAP_IRQHandler) +DEFAULT_IRQ_HANDLER(CM33SS_IRQHandler) +DEFAULT_IRQ_HANDLER(TIMER00_IRQHandler) +DEFAULT_IRQ_HANDLER(TIMER10_IRQHandler) +DEFAULT_IRQ_HANDLER(RTC10_IRQHandler) +DEFAULT_IRQ_HANDLER(EGU10_IRQHandler) +DEFAULT_IRQ_HANDLER(AAR10_CCM10_IRQHandler) +DEFAULT_IRQ_HANDLER(ECB10_IRQHandler) +DEFAULT_IRQ_HANDLER(RADIO_0_IRQHandler) +DEFAULT_IRQ_HANDLER(RADIO_1_IRQHandler) +DEFAULT_IRQ_HANDLER(SERIAL20_IRQHandler) +DEFAULT_IRQ_HANDLER(SERIAL21_IRQHandler) +DEFAULT_IRQ_HANDLER(SERIAL22_IRQHandler) +DEFAULT_IRQ_HANDLER(EGU20_IRQHandler) +DEFAULT_IRQ_HANDLER(TIMER20_IRQHandler) +DEFAULT_IRQ_HANDLER(TIMER21_IRQHandler) +DEFAULT_IRQ_HANDLER(TIMER22_IRQHandler) +DEFAULT_IRQ_HANDLER(TIMER23_IRQHandler) +DEFAULT_IRQ_HANDLER(TIMER24_IRQHandler) +DEFAULT_IRQ_HANDLER(PWM20_IRQHandler) +DEFAULT_IRQ_HANDLER(PWM21_IRQHandler) +DEFAULT_IRQ_HANDLER(PWM22_IRQHandler) +DEFAULT_IRQ_HANDLER(SAADC_IRQHandler) +DEFAULT_IRQ_HANDLER(NFCT_IRQHandler) +DEFAULT_IRQ_HANDLER(TEMP_IRQHandler) +DEFAULT_IRQ_HANDLER(GPIOTE20_0_IRQHandler) +DEFAULT_IRQ_HANDLER(GPIOTE20_1_IRQHandler) +DEFAULT_IRQ_HANDLER(TAMPC_IRQHandler) +DEFAULT_IRQ_HANDLER(I2S20_IRQHandler) +DEFAULT_IRQ_HANDLER(QDEC20_IRQHandler) +DEFAULT_IRQ_HANDLER(QDEC21_IRQHandler) +DEFAULT_IRQ_HANDLER(GRTC_0_IRQHandler) +DEFAULT_IRQ_HANDLER(GRTC_1_IRQHandler) +DEFAULT_IRQ_HANDLER(GRTC_2_IRQHandler) +DEFAULT_IRQ_HANDLER(GRTC_3_IRQHandler) +DEFAULT_IRQ_HANDLER(SERIAL30_IRQHandler) +DEFAULT_IRQ_HANDLER(RTC30_IRQHandler) +DEFAULT_IRQ_HANDLER(COMP_LPCOMP_IRQHandler) +DEFAULT_IRQ_HANDLER(WDT30_IRQHandler) +DEFAULT_IRQ_HANDLER(WDT31_IRQHandler) +DEFAULT_IRQ_HANDLER(GPIOTE30_0_IRQHandler) +DEFAULT_IRQ_HANDLER(GPIOTE30_1_IRQHandler) +DEFAULT_IRQ_HANDLER(CLOCK_POWER_IRQHandler) #if defined(DOMAIN_NS) || defined(BL2) DEFAULT_IRQ_HANDLER(MPC00_IRQHandler) @@ -178,10 +178,10 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - SWI00_Handler, - SWI01_Handler, - SWI02_Handler, - SWI03_Handler, + SWI00_IRQHandler, + SWI01_IRQHandler, + SWI02_IRQHandler, + SWI03_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, @@ -220,22 +220,22 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - AAR00_CCM00_Handler, - ECB00_Handler, + AAR00_CCM00_IRQHandler, + ECB00_IRQHandler, CRACEN_IRQHandler, default_tfm_IRQHandler, - SERIAL00_Handler, - RRAMC_Handler, - VPR00_Handler, + SERIAL00_IRQHandler, + RRAMC_IRQHandler, + VPR00_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - CTRLAP_Handler, - CM33SS_Handler, + CTRLAP_IRQHandler, + CM33SS_IRQHandler, default_tfm_IRQHandler, - TIMER00_Handler, + TIMER00_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, @@ -283,13 +283,13 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - TIMER10_Handler, - RTC10_Handler, - EGU10_Handler, - AAR10_CCM10_Handler, - ECB10_Handler, - RADIO_0_Handler, - RADIO_1_Handler, + TIMER10_IRQHandler, + RTC10_IRQHandler, + EGU10_IRQHandler, + AAR10_CCM10_IRQHandler, + ECB10_IRQHandler, + RADIO_0_IRQHandler, + RADIO_1_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, @@ -348,38 +348,38 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - SERIAL20_Handler, - SERIAL21_Handler, - SERIAL22_Handler, - EGU20_Handler, - TIMER20_Handler, - TIMER21_Handler, - TIMER22_Handler, - TIMER23_Handler, - TIMER24_Handler, + SERIAL20_IRQHandler, + SERIAL21_IRQHandler, + SERIAL22_IRQHandler, // todo + EGU20_IRQHandler, + TIMER20_IRQHandler, + TIMER21_IRQHandler, + TIMER22_IRQHandler, + TIMER23_IRQHandler, + TIMER24_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - PWM20_Handler, - PWM21_Handler, - PWM22_Handler, - SAADC_Handler, - NFCT_Handler, - TEMP_Handler, + PWM20_IRQHandler, + PWM21_IRQHandler, + PWM22_IRQHandler, + SAADC_IRQHandler, + NFCT_IRQHandler, + TEMP_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - GPIOTE20_0_Handler, - GPIOTE20_1_Handler, - TAMPC_Handler, - I2S20_Handler, + GPIOTE20_0_IRQHandler, + GPIOTE20_1_IRQHandler, + TAMPC_IRQHandler, + I2S20_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - QDEC20_Handler, - QDEC21_Handler, - GRTC_0_Handler, - GRTC_1_Handler, - GRTC_2_Handler, - GRTC_3_Handler, + QDEC20_IRQHandler, + QDEC21_IRQHandler, + GRTC_0_IRQHandler, + GRTC_1_IRQHandler, + GRTC_2_IRQHandler, + GRTC_3_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, @@ -410,17 +410,17 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = { default_tfm_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - SERIAL30_Handler, - RTC30_Handler, - COMP_LPCOMP_Handler, + SERIAL30_IRQHandler, + RTC30_IRQHandler, + COMP_LPCOMP_IRQHandler, default_tfm_IRQHandler, - WDT30_Handler, - WDT31_Handler, + WDT30_IRQHandler, + WDT31_IRQHandler, default_tfm_IRQHandler, default_tfm_IRQHandler, - GPIOTE30_0_Handler, - GPIOTE30_1_Handler, - CLOCK_POWER_Handler, + GPIOTE30_0_IRQHandler, + GPIOTE30_1_IRQHandler, + CLOCK_POWER_IRQHandler, }; #if defined ( __GNUC__ ) diff --git a/platform/ext/target/nordic_nrf/common/core/target_cfg.c b/platform/ext/target/nordic_nrf/common/core/target_cfg.c index cf0dd2b28..5763daeb5 100644 --- a/platform/ext/target/nordic_nrf/common/core/target_cfg.c +++ b/platform/ext/target/nordic_nrf/common/core/target_cfg.c @@ -128,6 +128,48 @@ struct platform_data_t tfm_peripheral_spim0 = { }; #endif +#if TFM_PERIPHERAL_SPIM00_SECURE +struct platform_data_t tfm_peripheral_spim00 = { + NRF_SPIM00_S_BASE, + NRF_SPIM00_S_BASE + (sizeof(NRF_SPIM_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_SPIM20_SECURE +struct platform_data_t tfm_peripheral_spim20 = { + NRF_SPIM20_S_BASE, + NRF_SPIM20_S_BASE + (sizeof(NRF_SPIM_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_SPIM22_SECURE +struct platform_data_t tfm_peripheral_spim21 = { + NRF_SPIM21_S_BASE, + NRF_SPIM21_S_BASE + (sizeof(NRF_SPIM_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_SPIM22_SECURE +struct platform_data_t tfm_peripheral_spim22 = { + NRF_SPIM22_S_BASE, + NRF_SPIM22_S_BASE + (sizeof(NRF_SPIM_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_SPIM23_SECURE +struct platform_data_t tfm_peripheral_spim23 = { + NRF_SPIM23_S_BASE, + NRF_SPIM23_S_BASE + (sizeof(NRF_SPIM_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_SPIM30_SECURE +struct platform_data_t tfm_peripheral_spim30 = { + NRF_SPIM30_S_BASE, + NRF_SPIM30_S_BASE + (sizeof(NRF_SPIM_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_SPIS0_SECURE struct platform_data_t tfm_peripheral_spis0 = { NRF_SPIS0_S_BASE, @@ -317,6 +359,55 @@ struct platform_data_t tfm_peripheral_timer0 = { }; #endif +#if TFM_PERIPHERAL_TIMER00_SECURE +struct platform_data_t tfm_peripheral_timer00 = { + NRF_TIMER00_S_BASE, + NRF_TIMER00_S_BASE + (sizeof(NRF_TIMER_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_TIMER10_SECURE +struct platform_data_t tfm_peripheral_timer10 = { + NRF_TIMER10_S_BASE, + NRF_TIMER10_S_BASE + (sizeof(NRF_TIMER_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_TIMER20_SECURE +struct platform_data_t tfm_peripheral_timer20 = { + NRF_TIMER20_S_BASE, + NRF_TIMER20_S_BASE + (sizeof(NRF_TIMER_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_TIMER21_SECURE +struct platform_data_t tfm_peripheral_timer21 = { + NRF_TIMER21_S_BASE, + NRF_TIMER21_S_BASE + (sizeof(NRF_TIMER_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_TIMER22_SECURE +struct platform_data_t tfm_peripheral_timer22 = { + NRF_TIMER22_S_BASE, + NRF_TIMER22_S_BASE + (sizeof(NRF_TIMER_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_TIMER23_SECURE +struct platform_data_t tfm_peripheral_timer23 = { + NRF_TIMER23_S_BASE, + NRF_TIMER23_S_BASE + (sizeof(NRF_TIMER_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_TIMER24_SECURE +struct platform_data_t tfm_peripheral_timer24 = { + NRF_TIMER24_S_BASE, + NRF_TIMER24_S_BASE + (sizeof(NRF_TIMER_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_TIMER1_SECURE struct platform_data_t tfm_peripheral_timer1 = { NRF_TIMER1_S_BASE, @@ -429,6 +520,20 @@ struct platform_data_t tfm_peripheral_egu5 = { }; #endif +#if TFM_PERIPHERAL_EGU10_SECURE +struct platform_data_t tfm_peripheral_egu10 = { + NRF_EGU10_S_BASE, + NRF_EGU10_S_BASE + (sizeof(NRF_EGU_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_EGU20_SECURE +struct platform_data_t tfm_peripheral_egu20 = { + NRF_EGU20_S_BASE, + NRF_EGU20_S_BASE + (sizeof(NRF_EGU_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_PWM0_SECURE struct platform_data_t tfm_peripheral_pwm0 = { NRF_PWM0_S_BASE, @@ -457,6 +562,27 @@ struct platform_data_t tfm_peripheral_pwm3 = { }; #endif +#if TFM_PERIPHERAL_PWM20_SECURE +struct platform_data_t tfm_peripheral_pwm20 = { + NRF_PWM20_S_BASE, + NRF_PWM20_S_BASE + (sizeof(NRF_PWM_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_PWM21_SECURE +struct platform_data_t tfm_peripheral_pwm21 = { + NRF_PWM21_S_BASE, + NRF_PWM21_S_BASE + (sizeof(NRF_PWM_Type) - 1), +}; +#endif + +#if TFM_PERIPHERAL_PWM22_SECURE +struct platform_data_t tfm_peripheral_pwm22 = { + NRF_PWM22_S_BASE, + NRF_PWM22_S_BASE + (sizeof(NRF_PWM_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_PDM0_SECURE struct platform_data_t tfm_peripheral_pdm0 = { NRF_PDM0_S_BASE, @@ -569,6 +695,13 @@ struct platform_data_t tfm_peripheral_gpio1 = { }; #endif +#if TFM_PERIPHERAL_GPIOTE20_SECURE +struct platform_data_t tfm_peripheral_gpiote20 = { + NRF_GPIOTE20_S_BASE, + NRF_GPIOTE20_S_BASE + (sizeof(NRF_GPIOTE_Type) - 1), +}; +#endif + #if TFM_PERIPHERAL_VMC_SECURE struct platform_data_t tfm_peripheral_vmc = { NRF_VMC_S_BASE, @@ -1188,20 +1321,6 @@ static const uint32_t target_peripherals[] = { NRF_SPIM2_S_BASE, NRF_SPIM3_S_BASE, -/* For Moonlight if a UART instance is selected to be the secure instance leave it as secure */ -#if NRF_SECURE_UART_INSTANCE == 20 - NRF_SPIM20_S_BASE, -#endif -#if NRF_SECURE_UART_INSTANCE == 21 - NRF_SPIM21_S_BASE, -#endif -#if NRF_SECURE_UART_INSTANCE == 22 - NRF_SPIM22_S_BASE, -#endif -#if NRF_SECURE_UART_INSTANCE == 30 - NRF_SPIM30_S_BASE, -#endif - #ifdef NRF_SPIM4 NRF_SPIM4_S_BASE, #endif diff --git a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c index f35ef8825..5b2e2ebbe 100644 --- a/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c +++ b/platform/ext/target/nordic_nrf/common/core/tfm_hal_isolation.c @@ -131,12 +131,8 @@ tfm_hal_bind_boundary(const struct partition_load_info_t *p_ldinf, continue; } -#ifdef NRF_SPU spu_peripheral_config_secure(plat_data_ptr->periph_start, SPU_LOCK_CONF_LOCKED); -#else - // TODO: NCSDK-22597: Support configuring peripherals as secure -#endif /* * Static boundaries are set. Set up MPU region for MMIO. diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h b/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h index f45682cc2..cce3ff57a 100644 --- a/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h @@ -12,17 +12,76 @@ extern "C" { #endif -#include -#include "tfm_peripherals_def.h" -#include "tfm_peripherals_config.h" #include "handle_attr.h" +#include "tfm_peripherals_config.h" +#include "tfm_peripherals_def.h" +#include /* Allowed named MMIO of this platform */ const uintptr_t partition_named_mmio_list[] = { - /* TODO: NCSDK-22597: Populate this list */ #if TFM_PERIPHERAL_TIMER00_SECURE (uintptr_t)TFM_PERIPHERAL_TIMER00, #endif +#if TFM_PERIPHERAL_TIMER10_SECURE + (uintptr_t)TFM_PERIPHERAL_TIMER10, +#endif +#if TFM_PERIPHERAL_TIMER20_SECURE + (uintptr_t)TFM_PERIPHERAL_TIMER20, +#endif +#if TFM_PERIPHERAL_TIMER21_SECURE + (uintptr_t)TFM_PERIPHERAL_TIMER21, +#endif +#if TFM_PERIPHERAL_TIMER22_SECURE + (uintptr_t)TFM_PERIPHERAL_TIMER22, +#endif +#if TFM_PERIPHERAL_TIMER23_SECURE + (uintptr_t)TFM_PERIPHERAL_TIMER23, +#endif +#if TFM_PERIPHERAL_TIMER24_SECURE + (uintptr_t)TFM_PERIPHERAL_TIMER24, +#endif +#if TFM_PERIPHERAL_SPIM00_SECURE + (uintptr_t)TFM_PERIPHERAL_SPIM00, +#endif +#if TFM_PERIPHERAL_SPIM20_SECURE + (uintptr_t)TFM_PERIPHERAL_SPIM20, +#endif +#if TFM_PERIPHERAL_SPIM21_SECURE + (uintptr_t)TFM_PERIPHERAL_SPIM21, +#endif +#if TFM_PERIPHERAL_SPIM22_SECURE + (uintptr_t)TFM_PERIPHERAL_SPIM22, +#endif +#if TFM_PERIPHERAL_SPIM23_SECURE + (uintptr_t)TFM_PERIPHERAL_SPIM23, +#endif +#if TFM_PERIPHERAL_SPIM30_SECURE + (uintptr_t)TFM_PERIPHERAL_SPIM30, +#endif +#if TFM_PERIPHERAL_EGU10_SECURE + (uintptr_t)TFM_PERIPHERAL_EGU10, +#endif +#if TFM_PERIPHERAL_EGU20_SECURE + (uintptr_t)TFM_PERIPHERAL_EGU20, +#endif +#if TFM_PERIPHERAL_GPIOTE20_SECURE + (uintptr_t)TFM_PERIPHERAL_GPIOTE20, +#endif +#if TFM_PERIPHERAL_GPIOTE30_SECURE + (uintptr_t)TFM_PERIPHERAL_GPIOTE30, +#endif +#if TFM_PERIPHERAL_PWM20_SECURE + (uintptr_t)TFM_PERIPHERAL_PWM20, +#endif +#if TFM_PERIPHERAL_PWM21_SECURE + (uintptr_t)TFM_PERIPHERAL_PWM21, +#endif +#if TFM_PERIPHERAL_PWM22_SECURE + (uintptr_t)TFM_PERIPHERAL_PWM22, +#endif +#if TFM_PERIPHERAL_PWM20_SECURE + (uintptr_t)TFM_PERIPHERAL_PWM20, +#endif }; #ifdef __cplusplus diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_interrupts.c b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_interrupts.c new file mode 100644 index 000000000..8b2da48c4 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_interrupts.c @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include + +#include "cmsis.h" +#include "spm.h" +#include "tfm_hal_interrupt.h" +#include "tfm_peripherals_def.h" +#include "tfm_peripherals_config.h" +#include "load/interrupt_defs.h" +#include "interrupt.h" + +static enum tfm_hal_status_t irq_init(struct irq_t *irq, IRQn_Type irqn, + void * p_pt, + const struct irq_load_info_t *p_ildi) +{ + irq->p_ildi = p_ildi; + irq->p_pt = p_pt; + + NVIC_SetPriority(irqn, DEFAULT_IRQ_PRIORITY); + NVIC_ClearTargetState(irqn); + NVIC_DisableIRQ(irqn); + + return TFM_HAL_SUCCESS; +} + +#if TFM_PERIPHERAL_FPU_SECURE +static struct irq_t fpu_irq = {0}; + +void FPU_IRQHandler(void) +{ + spm_handle_interrupt(fpu_irq.p_pt, fpu_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_fpu_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&fpu_irq, TFM_FPU_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_TIMER00_SECURE +static struct irq_t timer00_irq = {0}; + +void TIMER00_IRQHandler(void) +{ + spm_handle_interrupt(timer00_irq.p_pt, timer00_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer00_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&timer00_irq, TFM_TIMER00_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_TIMER10_SECURE +static struct irq_t timer10_irq = {0}; + +void TIMER10_IRQHandler(void) +{ + spm_handle_interrupt(timer10_irq.p_pt, timer10_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer10_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&timer10_irq, TFM_TIMER10_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_TIMER20_SECURE +static struct irq_t timer20_irq = {0}; + +void TIMER20_IRQHandler(void) +{ + spm_handle_interrupt(timer20_irq.p_pt, timer20_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer20_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&timer20_irq, TFM_TIMER20_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_TIMER21_SECURE +static struct irq_t timer21_irq = {0}; + +void TIMER21_IRQHandler(void) +{ + spm_handle_interrupt(timer21_irq.p_pt, timer21_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer21_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&timer21_irq, TFM_TIMER21_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_TIMER22_SECURE +static struct irq_t timer22_irq = {0}; + +void TIMER22_IRQHandler(void) +{ + spm_handle_interrupt(timer22_irq.p_pt, timer22_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer22_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&timer22_irq, TFM_TIMER22_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_TIMER23_SECURE +static struct irq_t timer23_irq = {0}; + +void TIMER23_IRQHandler(void) +{ + spm_handle_interrupt(timer23_irq.p_pt, timer23_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer23_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&timer23_irq, TFM_TIMER23_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_TIMER24_SECURE +static struct irq_t timer24_irq = {0}; + +void TIMER24_IRQHandler(void) +{ + spm_handle_interrupt(timer24_irq.p_pt, timer24_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_timer24_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&timer24_irq, TFM_TIMER24_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_GPIOTE20_SECURE +static struct irq_t gpiote20_0_irq = {0}; + +void GPIOTE20_0_IRQHandler(void) +{ + spm_handle_interrupt(gpiote20_0_irq.p_pt, gpiote20_0_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_gpiote20_0_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&gpiote20_0_irq, TFM_GPIOTE20_0_IRQ, p_pt, p_ildi); +} + +static struct irq_t gpiote20_1_irq = {0}; + +void GPIOTE20_1_IRQHandler(void) +{ + spm_handle_interrupt(gpiote20_1_irq.p_pt, gpiote20_1_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_gpiote20_1_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&gpiote20_1_irq, TFM_GPIOTE20_1_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_GPIOTE30_SECURE +static struct irq_t gpiote30_0_irq = {0}; + +void GPIOTE30_0_IRQHandler(void) +{ + spm_handle_interrupt(gpiote30_0_irq.p_pt, gpiote30_0_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_gpiote30_0_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&gpiote30_0_irq, TFM_GPIOTE30_0_IRQ, p_pt, p_ildi); +} + +static struct irq_t gpiote30_1_irq = {0}; + +void GPIOTE30_1_IRQHandler(void) +{ + spm_handle_interrupt(gpiote30_1_irq.p_pt, gpiote30_1_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_gpiote30_1_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&gpiote30_1_irq, TFM_GPIOTE30_1_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_SPIM00_SECURE +static struct irq_t spim00_irq = {0}; + +void SPIM00_IRQHandler(void) +{ + spm_handle_interrupt(spim00_irq.p_pt, spim00_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_spim00_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&spim00_irq, TFM_SPIM00_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_SPIM22_SECURE +static struct irq_t spim22_irq = {0}; + +void SPIM22_IRQHandler(void) +{ + spm_handle_interrupt(spim22_irq.p_pt, spim22_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_spim22_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&spim22_irq, TFM_SPIM22_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_SPIM23_SECURE +static struct irq_t spim23_irq = {0}; + +void SPIM23_IRQHandler(void) +{ + spm_handle_interrupt(spim23_irq.p_pt, spim23_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_spim23_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&spim23_irq, TFM_SPIM23_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_SPIM30_SECURE +static struct irq_t spim30_irq = {0}; + +void SPIM30_IRQHandler(void) +{ + spm_handle_interrupt(spim30_irq.p_pt, spim30_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_spim30_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&spim30_irq, TFM_SPIM30_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_EGU10_SECURE +static struct irq_t egu10_irq = {0}; + +void EGU10_IRQHandler(void) +{ + spm_handle_interrupt(egu10_irq.p_pt, egu10_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_egu10_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&egu10_irq, TFM_EGU10_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_EGU20_SECURE +static struct irq_t egu20_irq = {0}; + +void EGU20_IRQHandler(void) +{ + spm_handle_interrupt(egu20_irq.p_pt, egu20_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_egu20_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&egu20_irq, TFM_EGU20_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_PWM20_SECURE +static struct irq_t pwm20_irq = {0}; + +void PWM20_IRQHandler(void) +{ + spm_handle_interrupt(pwm20_irq.p_pt, pwm20_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_pwm20_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&pwm20_irq, TFM_PWM20_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_PWM21_SECURE +static struct irq_t pwm21_irq = {0}; + +void PWM21_IRQHandler(void) +{ + spm_handle_interrupt(pwm21_irq.p_pt, pwm21_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_pwm21_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&pwm21_irq, TFM_PWM21_IRQ, p_pt, p_ildi); +} +#endif + +#if TFM_PERIPHERAL_PWM22_SECURE +static struct irq_t pwm22_irq = {0}; + +void PWM22_IRQHandler(void) +{ + spm_handle_interrupt(pwm22_irq.p_pt, pwm22_irq.p_ildi); +} + +enum tfm_hal_status_t tfm_pwm22_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +{ + return irq_init(&pwm22_irq, TFM_PWM22_IRQ, p_pt, p_ildi); +} +#endif + +#ifdef PSA_API_TEST_IPC +enum tfm_hal_status_t ff_test_uart_irq_init(void *p_pt, + const struct irq_load_info_t *p_ildi) +__attribute__((alias("tfm_egu10_irq_init"))); + +#endif diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h index 42bdb35bd..7fe1dbba4 100644 --- a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h @@ -12,23 +12,81 @@ extern "C" { #endif - /* TODO: NCSDK-22597: Define peripherals */ - #include -#define TFM_TIMER0_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER0)) +#define TFM_FPU_IRQ (NRFX_IRQ_NUMBER_GET(NRF_FPU)) +#define TFM_TIMER00_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER00)) +#define TFM_TIMER10_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER10)) +#define TFM_TIMER20_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER20)) +#define TFM_TIMER21_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER21)) +#define TFM_TIMER22_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER22)) +#define TFM_TIMER23_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER23)) +#define TFM_TIMER24_IRQ (NRFX_IRQ_NUMBER_GET(NRF_TIMER24)) +#define TFM_SPIM00_IRQ (NRFX_IRQ_NUMBER_GET(NRF_SPIM00)) +#define TFM_SPIM20_IRQ (NRFX_IRQ_NUMBER_GET(NRF_SPIM20)) +#define TFM_SPIM21_IRQ (NRFX_IRQ_NUMBER_GET(NRF_SPIM21)) +#define TFM_SPIM22_IRQ (NRFX_IRQ_NUMBER_GET(NRF_SPIM22)) +#define TFM_SPIM23_IRQ (NRFX_IRQ_NUMBER_GET(NRF_SPIM23)) +#define TFM_SPIM30_IRQ (NRFX_IRQ_NUMBER_GET(NRF_SPIM30)) +#define TFM_EGU10_IRQ (NRFX_IRQ_NUMBER_GET(NRF_EGU10)) +#define TFM_EGU20_IRQ (NRFX_IRQ_NUMBER_GET(NRF_EGU20)) +#define TFM_GPIOTE20_0_IRQ GPIOTE20_0_IRQn +#define TFM_GPIOTE20_1_IRQ GPIOTE20_1_IRQn +#define TFM_GPIOTE30_0_IRQ GPIOTE30_0_IRQn +#define TFM_GPIOTE30_1_IRQ GPIOTE30_1_IRQn +#define TFM_PWM20_IRQ (NRFX_IRQ_NUMBER_GET(NRF_PWM20)) +#define TFM_PWM21_IRQ (NRFX_IRQ_NUMBER_GET(NRF_PWM21)) +#define TFM_PWM22_IRQ (NRFX_IRQ_NUMBER_GET(NRF_PWM22)) -extern struct platform_data_t tfm_peripheral_timer0; +extern struct platform_data_t tfm_peripheral_timer00; +extern struct platform_data_t tfm_peripheral_timer10; +extern struct platform_data_t tfm_peripheral_timer20; +extern struct platform_data_t tfm_peripheral_timer21; +extern struct platform_data_t tfm_peripheral_timer22; +extern struct platform_data_t tfm_peripheral_timer23; +extern struct platform_data_t tfm_peripheral_timer24; +extern struct platform_data_t tfm_peripheral_spim00; +extern struct platform_data_t tfm_peripheral_spim20; +extern struct platform_data_t tfm_peripheral_spim21; +extern struct platform_data_t tfm_peripheral_spim22; +extern struct platform_data_t tfm_peripheral_spim23; +extern struct platform_data_t tfm_peripheral_spim30; +extern struct platform_data_t tfm_peripheral_egu10; +extern struct platform_data_t tfm_peripheral_egu20; +extern struct platform_data_t tfm_peripheral_gpiote20; +extern struct platform_data_t tfm_peripheral_gpiote30; +extern struct platform_data_t tfm_peripheral_pwm20; +extern struct platform_data_t tfm_peripheral_pwm21; +extern struct platform_data_t tfm_peripheral_pwm22; -#define TFM_PERIPHERAL_TIMER0 (&tfm_peripheral_timer0) +#define TFM_PERIPHERAL_TIMER00 (&tfm_peripheral_timer00) +#define TFM_PERIPHERAL_TIMER10 (&tfm_peripheral_timer10) +#define TFM_PERIPHERAL_TIMER20 (&tfm_peripheral_timer20) +#define TFM_PERIPHERAL_TIMER21 (&tfm_peripheral_timer21) +#define TFM_PERIPHERAL_TIMER22 (&tfm_peripheral_timer22) +#define TFM_PERIPHERAL_TIMER23 (&tfm_peripheral_timer23) +#define TFM_PERIPHERAL_TIMER24 (&tfm_peripheral_timer24) +#define TFM_PERIPHERAL_SPIM00 (&tfm_peripheral_spim00) +#define TFM_PERIPHERAL_SPIM20 (&tfm_peripheral_spim20) +#define TFM_PERIPHERAL_SPIM21 (&tfm_peripheral_spim21) +#define TFM_PERIPHERAL_SPIM22 (&tfm_peripheral_spim22) +#define TFM_PERIPHERAL_SPIM23 (&tfm_peripheral_spim23) +#define TFM_PERIPHERAL_SPIM30 (&tfm_peripheral_spim30) +#define TFM_PERIPHERAL_EGU10 (&tfm_peripheral_egu10) +#define TFM_PERIPHERAL_EGU20 (&tfm_peripheral_egu20) +#define TFM_PERIPHERAL_GPIOTE20 (&tfm_peripheral_gpiote20) +#define TFM_PERIPHERAL_GPIOTE30 (&tfm_peripheral_gpiote30) +#define TFM_PERIPHERAL_PWM20 (&tfm_peripheral_pwm20) +#define TFM_PERIPHERAL_PWM21 (&tfm_peripheral_pwm21) +#define TFM_PERIPHERAL_PWM22 (&tfm_peripheral_pwm22) /* * Quantized default IRQ priority, the value is: * (Number of configurable priority) / 4: (1UL << __NVIC_PRIO_BITS) / 4 */ -#define DEFAULT_IRQ_PRIORITY (1UL << (__NVIC_PRIO_BITS - 2)) +#define DEFAULT_IRQ_PRIORITY (1UL << (__NVIC_PRIO_BITS - 2)) -#define TFM_PERIPHERAL_STD_UART TFM_PERIPHERAL_UARTE1 +#define TFM_PERIPHERAL_STD_UART TFM_PERIPHERAL_UARTE1 #ifdef PSA_API_TEST_IPC /* see other platforms when supporting this */ From c2db73d2afcd3724264a14a34f9c51ee7ec3ceda Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Mon, 27 May 2024 10:37:46 +0200 Subject: [PATCH 64/65] [noup] nordic_nrf: 54l Add UARTE defines to peripherals config fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Adding missing definitions for UART ports to build the regression tests Ref: NCSDK-27431 Signed-off-by: Markus Swarowsky --- .../nordic_nrf/common/nrf54l15/config.cmake | 2 +- .../nordic_nrf/common/nrf54l15/mmio_defs.h | 15 ++++++++++ .../tfm_peripherals_config_nrf54l15.h | 20 +++++++++++++ .../common/nrf54l15/tfm_peripherals_def.h | 14 +++++++++ .../tfm_peripherals_config.h | 30 +++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h create mode 100644 platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake b/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake index 01426be79..f81eafb02 100644 --- a/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/config.cmake @@ -8,7 +8,7 @@ include(${PLATFORM_PATH}/common/core/config.cmake) -set(SECURE_UART1 ON CACHE BOOL "Enable secure UART1") +set(SECURE_UART30 ON CACHE BOOL "Enable secure UART") set(NRF_NS_STORAGE OFF CACHE BOOL "Enable non-secure storage partition") set(BL2 OFF CACHE BOOL "Whether to build BL2") set(NRF_NS_SECONDARY OFF CACHE BOOL "Enable non-secure secondary partition") diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h b/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h index cce3ff57a..09d9ce345 100644 --- a/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/mmio_defs.h @@ -82,6 +82,21 @@ const uintptr_t partition_named_mmio_list[] = { #if TFM_PERIPHERAL_PWM20_SECURE (uintptr_t)TFM_PERIPHERAL_PWM20, #endif +#if TFM_PERIPHERAL_UARTE00_SECURE + (uintptr_t)TFM_PERIPHERAL_UARTE00, +#endif +#if TFM_PERIPHERAL_UARTE20_SECURE + (uintptr_t)TFM_PERIPHERAL_UARTE20, +#endif +#if TFM_PERIPHERAL_UARTE21_SECURE + (uintptr_t)TFM_PERIPHERAL_UARTE21, +#endif +#if TFM_PERIPHERAL_UARTE22_SECURE + (uintptr_t)TFM_PERIPHERAL_UARTE22, +#endif +#if TFM_PERIPHERAL_UARTE30_SECURE + (uintptr_t)TFM_PERIPHERAL_UARTE30, +#endif }; #ifdef __cplusplus diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h new file mode 100644 index 000000000..c6dec9b93 --- /dev/null +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h @@ -0,0 +1,20 @@ + +#ifndef TFM_PERIPHERAL_UARTE00_SECURE +#define TFM_PERIPHERAL_UARTE00_SECURE 0 +#endif + +#ifndef TFM_PERIPHERAL_UARTE20_SECURE +#define TFM_PERIPHERAL_UARTE20_SECURE 0 +#endif + +#ifndef TFM_PERIPHERAL_UARTE21_SECURE +#define TFM_PERIPHERAL_UARTE21_SECURE 0 +#endif + +#ifndef TFM_PERIPHERAL_UARTE22_SECURE +#define TFM_PERIPHERAL_UARTE22_SECURE 0 +#endif + +#ifndef TFM_PERIPHERAL_UARTE30_SECURE +#define TFM_PERIPHERAL_UARTE30_SECURE 0 +#endif diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h index 7fe1dbba4..376599f1e 100644 --- a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_def.h @@ -88,6 +88,20 @@ extern struct platform_data_t tfm_peripheral_pwm22; #define TFM_PERIPHERAL_STD_UART TFM_PERIPHERAL_UARTE1 +extern struct platform_data_t tfm_peripheral_uarte00; +extern struct platform_data_t tfm_peripheral_uarte20; +extern struct platform_data_t tfm_peripheral_uarte21; +extern struct platform_data_t tfm_peripheral_uarte22; +extern struct platform_data_t tfm_peripheral_uarte30; + +#define TFM_PERIPHERAL_UARTE00 (&tfm_peripheral_uarte00) +#define TFM_PERIPHERAL_UARTE20 (&tfm_peripheral_uarte20) +#define TFM_PERIPHERAL_UARTE21 (&tfm_peripheral_uarte21) +#define TFM_PERIPHERAL_UARTE22 (&tfm_peripheral_uarte22) +#define TFM_PERIPHERAL_UARTE30 (&tfm_peripheral_uarte30) + +#define TFM_PERIPHERAL_STD_UART TFM_PERIPHERAL_UARTE30 + #ifdef PSA_API_TEST_IPC /* see other platforms when supporting this */ #error "Not supported yet" diff --git a/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h new file mode 100644 index 000000000..1ed07d120 --- /dev/null +++ b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef TFM_PERIPHERALS_CONFIG_H__ +#define TFM_PERIPHERALS_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SECURE_UART30 +#define TFM_PERIPHERAL_UARTE30_SECURE 1 +#endiff + + +#if defined(NRF54L15_ENGA_XXAA) + #include +#else + #error "Unknown device." +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* TFM_PERIPHERAL_CONFIG_H__ */ From bb857da1223b70f4a7bbb4cc9f258f1c76785a56 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Mon, 27 May 2024 14:48:12 +0200 Subject: [PATCH 65/65] [noup] nordic_nrf: 54l: Add TIMER00 config for regression tests fixup! [nrf noup] platform: nordic_nrf: Add support for 54l Adding missing definitions for UART ports to build the regression tests Ref: NCSDK-27431 Signed-off-by: Markus Swarowsky --- .../common/nrf54l15/tfm_peripherals_config_nrf54l15.h | 4 ++++ .../nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h index c6dec9b93..12f3a003c 100644 --- a/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h +++ b/platform/ext/target/nordic_nrf/common/nrf54l15/tfm_peripherals_config_nrf54l15.h @@ -1,4 +1,8 @@ +#ifndef TFM_PERIPHERAL_TIMER00_SECURE +#define TFM_PERIPHERAL_TIMER00_SECURE 0 +#endif + #ifndef TFM_PERIPHERAL_UARTE00_SECURE #define TFM_PERIPHERAL_UARTE00_SECURE 0 #endif diff --git a/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h index 1ed07d120..bc3301087 100644 --- a/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h +++ b/platform/ext/target/nordic_nrf/nrf54l15dk_nrf54l15_cpuapp/tfm_peripherals_config.h @@ -16,6 +16,10 @@ extern "C" { #define TFM_PERIPHERAL_UARTE30_SECURE 1 #endiff +#if TFM_PARTITION_SLIH_TEST || TFM_PARTITION_FLIH_TEST +#define TFM_PERIPHERAL_TIMER00_SECURE 1 +#endif + #if defined(NRF54L15_ENGA_XXAA) #include