SPM: Add fault injection protection support in IPC model
Create a reference implementation of fault injection protection in IPC
model SPM initialization.
Change-Id: I789ef2f621f3187e6c99d683763f3d1b1aa3c465
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/secure_fw/spm/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
index fc661de..28b02ce 100755
--- a/secure_fw/spm/CMakeLists.txt
+++ b/secure_fw/spm/CMakeLists.txt
@@ -86,7 +86,7 @@
$<$<STREQUAL:${TEST_PSA_API},IPC>:tfm_psa_rot_partition_driver_partition>
$<$<STREQUAL:${TEST_PSA_API},IPC>:tfm_app_rot_partition_client_partition>
$<$<STREQUAL:${TEST_PSA_API},IPC>:tfm_app_rot_partition_server_partition>
- $<$<NOT:$<BOOL:${TFM_PSA_API}>>:tfm_fih>
+ tfm_fih
)
target_compile_definitions(tfm_spm
diff --git a/secure_fw/spm/cmsis_psa/main.c b/secure_fw/spm/cmsis_psa/main.c
index c820a46..41bd91a 100644
--- a/secure_fw/spm/cmsis_psa/main.c
+++ b/secure_fw/spm/cmsis_psa/main.c
@@ -5,6 +5,7 @@
*
*/
+#include "fih.h"
#include "ffm/tfm_boot_data.h"
#include "region.h"
#include "spm_ipc.h"
@@ -32,44 +33,68 @@
REGION_DECLARE(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Base);
-static int32_t tfm_core_init(void)
+static fih_int tfm_core_init(void)
{
size_t i;
enum tfm_hal_status_t hal_status = TFM_HAL_ERROR_GENERIC;
enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
enum irq_target_state_t irq_target_state = TFM_IRQ_TARGET_STATE_SECURE;
+#ifdef TFM_FIH_PROFILE_ON
+ fih_int fih_rc = FIH_FAILURE;
+#endif
/* Enables fault handlers */
plat_err = tfm_spm_hal_enable_fault_handlers();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
/* Configures the system reset request properties */
plat_err = tfm_spm_hal_system_reset_cfg();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
/* Configures debug authentication */
+#ifdef TFM_FIH_PROFILE_ON
+ FIH_CALL(tfm_spm_hal_init_debug, fih_rc);
+ if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
+ }
+#else /* TFM_FIH_PROFILE_ON */
plat_err = tfm_spm_hal_init_debug();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
return TFM_ERROR_GENERIC;
}
+#endif /* TFM_FIH_PROFILE_ON */
/*
* Access to any peripheral should be performed after programming
* the necessary security components such as PPC/SAU.
*/
+#ifdef TFM_FIH_PROFILE_ON
+ FIH_CALL(tfm_hal_set_up_static_boundaries, fih_rc);
+ if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
+ }
+#else /* TFM_FIH_PROFILE_ON */
hal_status = tfm_hal_set_up_static_boundaries();
if (hal_status != TFM_HAL_SUCCESS) {
return TFM_ERROR_GENERIC;
}
+#endif /* TFM_FIH_PROFILE_ON */
+
+#ifdef TFM_FIH_PROFILE_ON
+ FIH_CALL(tfm_spm_hal_verify_isolation_hw, fih_rc);
+ if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
+ tfm_core_panic();
+ }
+#endif
/* Performs platform specific initialization */
hal_status = tfm_hal_platform_init();
if (hal_status != TFM_HAL_SUCCESS) {
- return TFM_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
/* Configures architecture */
@@ -88,7 +113,7 @@
*/
plat_err = tfm_spm_hal_nvic_interrupt_target_state_cfg();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
for (i = 0; i < tfm_core_irq_signals_count; ++i) {
@@ -96,34 +121,40 @@
tfm_core_irq_signals[i].irq_line,
tfm_core_irq_signals[i].irq_priority);
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
irq_target_state = tfm_spm_hal_set_irq_target_state(
tfm_core_irq_signals[i].irq_line,
TFM_IRQ_TARGET_STATE_SECURE);
if (irq_target_state != TFM_IRQ_TARGET_STATE_SECURE) {
- return TFM_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
}
/* Enable secure peripherals interrupts */
plat_err = tfm_spm_hal_nvic_interrupt_enable();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_ERROR_GENERIC));
}
- return TFM_SUCCESS;
+ FIH_RET(fih_int_encode(TFM_SUCCESS));
}
int main(void)
{
+ fih_int fih_rc = FIH_FAILURE;
+
/* set Main Stack Pointer limit */
tfm_arch_init_secure_msp((uint32_t)®ION_NAME(Image$$, ARM_LIB_STACK_MSP,
$$ZI$$Base));
- if (tfm_core_init() != TFM_SUCCESS) {
+ fih_delay_init();
+
+ FIH_CALL(tfm_core_init, fih_rc);
+ if (fih_not_eq(fih_rc, fih_int_encode(TFM_SUCCESS))) {
tfm_core_panic();
}
+
/* Print the TF-M version */
SPMLOG_INFMSG("\033[1;34mBooting TFM v"VERSION_FULLSTR"\033[0m\r\n");
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index c30f6cd..fa828aa 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -8,6 +8,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include "bitops.h"
+#include "fih.h"
#include "psa/client.h"
#include "psa/service.h"
#include "tfm_thread.h"
@@ -642,6 +643,9 @@
struct partition_t *partition;
struct tfm_core_thread_t *pth, *p_ns_entry_thread = NULL;
const struct platform_data_t **platform_data_p;
+#ifdef TFM_FIH_PROFILE_ON
+ fih_int fih_rc = FIH_FAILURE;
+#endif
tfm_pool_init(conn_handle_pool,
POOL_BUFFER_SIZE(conn_handle_pool),
@@ -672,10 +676,18 @@
(const struct platform_data_t **)partition->p_static->platform_data;
if (platform_data_p != NULL) {
while ((*platform_data_p) != NULL) {
+#ifdef TFM_FIH_PROFILE_ON
+ FIH_CALL(tfm_spm_hal_configure_default_isolation, fih_rc, i,
+ *platform_data_p);
+ if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
+ tfm_core_panic();
+ }
+#else /* TFM_FIH_PROFILE_ON */
if (tfm_spm_hal_configure_default_isolation(i,
*platform_data_p) != TFM_PLAT_ERR_SUCCESS) {
tfm_core_panic();
}
+#endif /* TFM_FIH_PROFILE_ON */
++platform_data_p;
}
}
@@ -765,6 +777,9 @@
#endif
struct tfm_core_thread_t *pth_next = tfm_core_thrd_get_next();
struct tfm_core_thread_t *pth_curr = tfm_core_thrd_get_curr();
+#if defined(TFM_FIH_PROFILE_ON) && (TFM_LVL == 3)
+ fih_int fih_rc = FIH_FAILURE;
+#endif
if (pth_next != NULL && pth_curr != pth_next) {
#if TFM_LVL != 1
@@ -787,12 +802,21 @@
*/
if (is_privileged == TFM_PARTITION_UNPRIVILEGED_MODE) {
/* FIXME: only MPU-based implementations are supported currently */
+#ifdef TFM_FIH_PROFILE_ON
+ FIH_CALL(tfm_hal_mpu_update_partition_boundary, fih_rc,
+ p_next_partition->memory_data->data_start,
+ p_next_partition->memory_data->data_limit);
+ if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
+ tfm_core_panic();
+ }
+#else /* TFM_FIH_PROFILE_ON */
if (tfm_hal_mpu_update_partition_boundary(
p_next_partition->memory_data->data_start,
p_next_partition->memory_data->data_limit)
!= TFM_HAL_SUCCESS) {
tfm_core_panic();
}
+#endif /* TFM_FIH_PROFILE_ON */
}
#endif /* TFM_LVL == 3 */
#endif /* TFM_LVL != 1 */