aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Liu <Ken.Liu@arm.com>2021-08-10 15:48:23 +0800
committerKen Liu <ken.liu@arm.com>2021-09-17 11:24:03 +0200
commit5885250399fdd643727e42c5495bcbc69556a4a0 (patch)
tree151ab4d5502caadb2afe050e1d018337d6804c33
parent1ba05f544bf071409f76d8f8f983b2bb089af5ba (diff)
downloadtrusted-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.h19
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.c68
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.h28
-rw-r--r--secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c2
-rw-r--r--secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c111
-rw-r--r--secure_fw/spm/include/tfm_core_trustzone.h6
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)&REGION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
- uint32_t veneer_limit =
- (uint32_t)&REGION_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: