diff options
author | Ken Liu <Ken.Liu@arm.com> | 2021-08-10 15:48:23 +0800 |
---|---|---|
committer | Ken Liu <ken.liu@arm.com> | 2021-09-17 11:24:03 +0200 |
commit | 5885250399fdd643727e42c5495bcbc69556a4a0 (patch) | |
tree | 151ab4d5502caadb2afe050e1d018337d6804c33 | |
parent | 1ba05f544bf071409f76d8f8f983b2bb089af5ba (diff) | |
download | trusted-firmware-m-5885250399fdd643727e42c5495bcbc69556a4a0.tar.gz |
SPM: Re-entrant detection in NS Agent
The existing re-entrant detecting mechanism for Armv8.0-M is
placed inside SPM, which needs extra SVC and complex frame size
computing.
Apply the re-entrant detecting mechanism to NS Agent partition.
By checking if the stack top is the SEAL can detect re-entrant
easily.
Change-Id: I5ea86bd43d4e1ab1b8a3cadc87fe7a9a78e93c90
Signed-off-by: Ken Liu <Ken.Liu@arm.com>
-rw-r--r-- | secure_fw/include/security_defs.h | 19 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/spm_ipc.c | 68 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/spm_ipc.h | 28 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c | 2 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c | 111 | ||||
-rw-r--r-- | secure_fw/spm/include/tfm_core_trustzone.h | 6 |
6 files changed, 110 insertions, 124 deletions
diff --git a/secure_fw/include/security_defs.h b/secure_fw/include/security_defs.h new file mode 100644 index 0000000000..5d752d4cdc --- /dev/null +++ b/secure_fw/include/security_defs.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __SECURITY_DEFS_H__ +#define __SECURITY_DEFS_H__ + +/* Generic security-related definitions */ + +/* + * Stack SEAL is involved since Security Extension exists, it becomes + * a generic security defs used by both SPM and Partitions. + */ +#define STACK_SEAL_PATTERN 0xFEF5EDA5 + +#endif /* __SECURITY_DEFS_H__ */ diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c index a578a18ca5..fc3dd739db 100644 --- a/secure_fw/spm/cmsis_psa/spm_ipc.c +++ b/secure_fw/spm/cmsis_psa/spm_ipc.c @@ -45,10 +45,6 @@ struct service_t *stateless_services_ref_tbl[STATIC_HANDLE_NUM_LIMIT]; TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t), TFM_CONN_HANDLE_MAX_NUM); -/* The veneer section names come from the scatter file */ -REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base); -REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit); - void spm_interrupt_handler(struct partition_load_info_t *p_ldinf, psa_signal_t signal, uint32_t irq_line, @@ -888,67 +884,3 @@ struct irq_load_info_t *get_irq_info_for_signal( return NULL; } - -#if !defined(__ARM_ARCH_8_1M_MAIN__) -void tfm_spm_validate_caller(uint32_t *p_ctx, uint32_t exc_return) -{ - /* - * TODO: the reentrant detection mechanism needs to be changed when there - * is no boundaries. - */ - uintptr_t stacked_ctx_pos; - bool ns_caller = false; - struct partition_t *p_cur_sp = tfm_spm_get_running_partition(); - uint32_t veneer_base = - (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base); - uint32_t veneer_limit = - (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit); - - if (!p_cur_sp) { - tfm_core_panic(); - } - - /* - * The caller security attribute detection bases on LR of state context. - * However, if SP calls PSA APIs based on its customized SVC, the LR may be - * occupied by general purpose value while calling SVC. - * Check if caller comes from non-secure: return address (p_ctx[6]) belongs - * to veneer section, and the bit0 of LR (p_ctx[5]) is zero. - */ - if (p_ctx[6] >= veneer_base && p_ctx[6] < veneer_limit && - !(p_ctx[5] & TFM_VENEER_LR_BIT0_MASK)) { - ns_caller = true; - } - - /* If called from ns, partition ID should be TFM_SP_NON_SECURE_ID. */ - if ((ns_caller == true) != - (p_cur_sp->p_ldinf->pid == TFM_SP_NON_SECURE_ID)) { - tfm_core_panic(); - } - - if (ns_caller) { - /* - * The background IRQ can't be supported, since if SP is executing, - * the preempted context of SP can be different with the one who - * preempts veneer. Check if veneer stack contains multiple contexts. - */ - stacked_ctx_pos = (uintptr_t)p_ctx + - sizeof(struct tfm_state_context_t) + - TFM_STACK_SEALED_SIZE; - - if (is_stack_alloc_fp_space(exc_return)) { -#if defined(__FPU_USED) && (__FPU_USED == 1U) - if (FPU->FPCCR & FPU_FPCCR_TS_Msk) { - stacked_ctx_pos += TFM_ADDTIONAL_FP_CONTEXT_WORDS * - sizeof(uint32_t); - } -#endif - stacked_ctx_pos += TFM_BASIC_FP_CONTEXT_WORDS * sizeof(uint32_t); - } - - if (stacked_ctx_pos != p_cur_sp->sp_thread.stk_top) { - tfm_core_panic(); - } - } -} -#endif diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h index 64d8cac80e..78334c4e9f 100644 --- a/secure_fw/spm/cmsis_psa/spm_ipc.h +++ b/secure_fw/spm/cmsis_psa/spm_ipc.h @@ -398,34 +398,6 @@ void tfm_pendsv_do_schedule(struct tfm_arch_ctx_t *p_actx); */ uint32_t tfm_spm_init(void); -#if !defined(__ARM_ARCH_8_1M_MAIN__) -/** - * \brief Validate the whether NS caller re-enter. - * - * \param[in] p_ctx Pointer to current stack context. - * \param[in] exc_return EXC_RETURN value. - * - * \retval void Success. - * - * Notes: - * For architecture v8.1m and later, will use hardware re-entrant detection. - * Otherwise will use the software solution to validate the caller. - */ -void tfm_spm_validate_caller(uint32_t *p_ctx, uint32_t exc_return); -#else -/** - * In v8.1 mainline, will use hardware re-entrant detection instead. - */ -__STATIC_INLINE -void tfm_spm_validate_caller(uint32_t *p_ctx, uint32_t exc_return) -{ - (void)p_ctx; - (void)exc_return; - return; -} -#endif - - /** * \brief Converts a handle instance into a corresponded user handle. */ diff --git a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c index 60a0124eea..ea94fdf86d 100644 --- a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c +++ b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c @@ -41,8 +41,6 @@ struct tfm_svc_flih_ctx_t { static int32_t SVC_Handler_IPC(uint8_t svc_num, uint32_t *ctx, uint32_t lr) { - tfm_spm_validate_caller(ctx, lr); - switch (svc_num) { case TFM_SVC_PSA_FRAMEWORK_VERSION: return tfm_spm_client_psa_framework_version(); diff --git a/secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c b/secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c index a3328cde0e..12b11f82b5 100644 --- a/secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c +++ b/secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c @@ -7,45 +7,80 @@ #include <stdbool.h> #include <stdio.h> -#include "psa/client.h" -#include "psa/service.h" +#include "security_defs.h" #include "tfm_arch.h" #include "tfm_secure_api.h" #include "tfm_api.h" #include "tfm_svcalls.h" - -/* Veneer implementation */ +#include "utilities.h" /* - * SVC to core directly before touch stack due to: - * - Re-entrant detection bases on stack information. - * - SVC here stores the current xPSR into stack and recover it back while - * exception returns, no leakage of secure state information and no - * interference between two sides. + * Use assembly to: + * - Explicit stack usage to perform re-entrant detection. + * - SVC here to take hardware context management advantages. */ __tfm_psa_secure_gateway_attributes__ uint32_t tfm_psa_framework_version_veneer(void) { - __ASM volatile("SVC %0 \n" - "BXNS LR \n" - : : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION)); + __ASM volatile( +#if !defined(__ARM_ARCH_8_1M_MAIN__) + " ldr r2, [sp] \n" + " ldr r3, ="M2S(STACK_SEAL_PATTERN)" \n" + " cmp r2, r3 \n" + " bne reent_panic1 \n" +#endif + " svc %0 \n" + " bxns lr \n" +#if !defined(__ARM_ARCH_8_1M_MAIN__) + "reent_panic1: \n" + " svc %1 \n" + " b . \n" +#endif + : : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION), + "I" (TFM_SVC_PSA_PANIC)); } __tfm_psa_secure_gateway_attributes__ uint32_t tfm_psa_version_veneer(uint32_t sid) { - __ASM volatile("SVC %0 \n" - "BXNS LR \n" - : : "I" (TFM_SVC_PSA_VERSION)); + __ASM volatile( +#if !defined(__ARM_ARCH_8_1M_MAIN__) + " ldr r2, [sp] \n" + " ldr r3, ="M2S(STACK_SEAL_PATTERN)" \n" + " cmp r2, r3 \n" + " bne reent_panic2 \n" +#endif + " svc %0 \n" + " bxns lr \n" +#if !defined(__ARM_ARCH_8_1M_MAIN__) + "reent_panic2: \n" + " svc %1 \n" + " b . \n" +#endif + : : "I" (TFM_SVC_PSA_VERSION), + "I" (TFM_SVC_PSA_PANIC)); } __tfm_psa_secure_gateway_attributes__ psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t version) { - __ASM volatile("SVC %0 \n" - "BXNS LR \n" - : : "I" (TFM_SVC_PSA_CONNECT)); + __ASM volatile( +#if !defined(__ARM_ARCH_8_1M_MAIN__) + " ldr r2, [sp] \n" + " ldr r3, ="M2S(STACK_SEAL_PATTERN)" \n" + " cmp r2, r3 \n" + " bne reent_panic3 \n" +#endif + " svc %0 \n" + " bxns lr \n" +#if !defined(__ARM_ARCH_8_1M_MAIN__) + "reent_panic3: \n" + " svc %1 \n" + " b . \n" +#endif + : : "I" (TFM_SVC_PSA_CONNECT), + "I" (TFM_SVC_PSA_PANIC)); } __tfm_psa_secure_gateway_attributes__ @@ -54,15 +89,43 @@ psa_status_t tfm_psa_call_veneer(psa_handle_t handle, const psa_invec *in_vec, psa_outvec *out_vec) { - __ASM volatile("SVC %0 \n" - "BXNS LR \n" - : : "I" (TFM_SVC_PSA_CALL)); + __ASM volatile( +#if !defined(__ARM_ARCH_8_1M_MAIN__) + " push {r2, r3} \n" + " ldr r2, [sp, #8] \n" + " ldr r3, ="M2S(STACK_SEAL_PATTERN)" \n" + " cmp r2, r3 \n" + " bne reent_panic4 \n" + " pop {r2, r3} \n" +#endif + " svc %0 \n" + " bxns lr \n" +#if !defined(__ARM_ARCH_8_1M_MAIN__) + "reent_panic4: \n" + " svc %1 \n" + " b . \n" +#endif + : : "I" (TFM_SVC_PSA_CALL), + "I" (TFM_SVC_PSA_PANIC)); } __tfm_psa_secure_gateway_attributes__ void tfm_psa_close_veneer(psa_handle_t handle) { - __ASM volatile("SVC %0 \n" - "BXNS LR \n" - : : "I" (TFM_SVC_PSA_CLOSE)); + __ASM volatile( +#if !defined(__ARM_ARCH_8_1M_MAIN__) + " ldr r2, [sp] \n" + " ldr r3, ="M2S(STACK_SEAL_PATTERN)" \n" + " cmp r2, r3 \n" + " bne reent_panic5 \n" +#endif + " svc %0 \n" + " bxns lr \n" +#if !defined(__ARM_ARCH_8_1M_MAIN__) + "reent_panic5: \n" + " svc %1 \n" + " b . \n" +#endif + : : "I" (TFM_SVC_PSA_CLOSE), + "I" (TFM_SVC_PSA_PANIC)); } diff --git a/secure_fw/spm/include/tfm_core_trustzone.h b/secure_fw/spm/include/tfm_core_trustzone.h index c53e034fea..c0a6f59702 100644 --- a/secure_fw/spm/include/tfm_core_trustzone.h +++ b/secure_fw/spm/include/tfm_core_trustzone.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * Copyright (c) 2019-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -8,6 +8,8 @@ #ifndef __TFM_CORE_TRUSTZONE_H__ #define __TFM_CORE_TRUSTZONE_H__ +#include "security_defs.h" + /* This file holds specification or design defined TrustZone settings. */ /* @@ -17,7 +19,7 @@ * 0xFEF5EDA5. */ #define TFM_STACK_SEALED_SIZE 8 -#define TFM_STACK_SEAL_VALUE 0xFEF5EDA5 +#define TFM_STACK_SEAL_VALUE STACK_SEAL_PATTERN /* * The numbers in 32bit words while basic FP involved in preempted context: |