Merge pull request #10502 from kfnta/feature_trusted-firmware-m_f2dea5b

PSA: TFM import
pull/10512/head
Martin Kojtal 2019-04-30 09:12:37 +01:00 committed by GitHub
commit 47205bfd02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 443 additions and 374 deletions

View File

@ -54,11 +54,15 @@ uint32_t tfm_ns_lock_dispatch(veneer_fn fn,
}
/* TFM request protected by NS lock */
osMutexAcquire(ns_lock.id,osWaitForever);
if (osMutexAcquire(ns_lock.id,osWaitForever) != osOK) {
return TFM_ERROR_GENERIC;
}
result = fn(arg0, arg1, arg2, arg3);
osMutexRelease(ns_lock.id);
if (osMutexRelease(ns_lock.id) != osOK) {
return TFM_ERROR_GENERIC;
}
return result;
}
@ -66,7 +70,7 @@ uint32_t tfm_ns_lock_dispatch(veneer_fn fn,
/**
* \brief NS world, Init NS lock
*/
uint32_t tfm_ns_lock_init()
enum tfm_status_e tfm_ns_lock_init()
{
if (ns_lock.init == false) {
ns_lock.id = osMutexNew(&ns_lock_attrib);

View File

@ -197,6 +197,16 @@ struct shared_data_tlv_entry {
uint16_t tlv_len; /* size of single TLV entry (including this header). */
};
/**
* \struct tfm_boot_data
*
* \brief Store the data for the runtime SW
*/
struct tfm_boot_data {
struct shared_data_tlv_header header;
uint8_t data[];
};
#define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry)
#define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE)

View File

@ -9,6 +9,7 @@
#include <stdbool.h>
#include "tfm_list.h"
#include "tfm_secure_api.h"
#ifndef TFM_SPM_MAX_ROT_SERV_NUM
#define TFM_SPM_MAX_ROT_SERV_NUM 28
@ -283,12 +284,15 @@ int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
* \param[in] buffer Pointer of memory reference
* \param[in] len Length of memory reference in bytes
* \param[in] ns_caller From non-secure caller
* \param[in] access Type of access specified by the
* \ref tfm_memory_access_e
*
* \retval IPC_SUCCESS Success
* \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
* \retval IPC_ERROR_MEMORY_CHECK Check failed
*/
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller);
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
enum tfm_memory_access_e access);
/* This function should be called before schedule function */
void tfm_spm_init(void);

View File

@ -13,25 +13,25 @@
__attribute__((naked))
uint32_t psa_framework_version(void)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
}
__attribute__((naked))
uint32_t psa_version(uint32_t sid)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_VERSION));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_VERSION));
}
__attribute__((naked))
psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CONNECT));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CONNECT));
}
__attribute__((naked))
@ -41,15 +41,15 @@ psa_status_t psa_call(psa_handle_t handle,
psa_outvec *out_vec,
size_t out_len)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CALL));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CALL));
}
__attribute__((naked))
void psa_close(psa_handle_t handle)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CLOSE));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CLOSE));
}

View File

@ -15,25 +15,25 @@ __attribute__((naked))
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_WAIT));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_WAIT));
}
__attribute__((naked))
psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_GET));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_GET));
}
__attribute__((naked))
void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_SET_RHANDLE));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_SET_RHANDLE));
}
__attribute__((naked))
@ -41,56 +41,56 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
void *buffer, size_t num_bytes)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_READ));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_READ));
}
__attribute__((naked))
size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_SKIP));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_SKIP));
}
__attribute__((naked))
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
const void *buffer, size_t num_bytes)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_WRITE));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_WRITE));
}
__attribute__((naked))
void psa_reply(psa_handle_t msg_handle, psa_status_t retval)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_REPLY));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_REPLY));
}
__attribute__((naked))
void psa_notify(int32_t partition_id)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_NOTIFY));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_NOTIFY));
}
__attribute__((naked))
void psa_clear(void)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CLEAR));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_CLEAR));
}
__attribute__((naked))
void psa_eoi(psa_signal_t irq_signal)
{
__ASM("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_EOI));
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_PSA_EOI));
}

View File

@ -94,7 +94,7 @@ void tfm_initialize_context(struct tfm_state_context *ctx,
#if defined(__ARM_ARCH_8M_MAIN__)
__attribute__((naked)) void PendSV_Handler(void)
{
__ASM(
__ASM volatile(
"mrs r0, psp \n"
"mrs r1, psplim \n"
"push {r0, r1, r2, lr} \n"
@ -111,7 +111,7 @@ __attribute__((naked)) void PendSV_Handler(void)
#elif defined(__ARM_ARCH_8M_BASE__)
__attribute__((naked)) void PendSV_Handler(void)
{
__ASM(
__ASM volatile(
"mrs r0, psp \n"
"mrs r1, psplim \n"
"push {r0, r1, r2, lr} \n"
@ -143,14 +143,14 @@ __attribute__((naked)) void PendSV_Handler(void)
/* Reserved for future usage */
__attribute__((naked)) void MemManage_Handler(void)
{
__ASM("b .");
__ASM volatile("b .");
}
__attribute__((naked)) void BusFault_Handler(void)
{
__ASM("b .");
__ASM volatile("b .");
}
__attribute__((naked)) void UsageFault_Handler(void)
{
__ASM("b .");
__ASM volatile("b .");
}

View File

@ -12,6 +12,7 @@
#include "psa_client.h"
#include "psa_service.h"
#include "tfm_utils.h"
#include "platform/include/tfm_spm_hal.h"
#include "spm_api.h"
#include "spm_db.h"
#include "spm_db_setup.h"
@ -460,46 +461,11 @@ static uint32_t tfm_spm_partition_get_priority_ext(uint32_t partition_idx)
partition_priority;
}
/* Macros to pick linker symbols and allow references to sections in all level*/
#define REGION_DECLARE_EXT(a, b, c) extern uint32_t REGION_NAME(a, b, c)
REGION_DECLARE_EXT(Image$$, ARM_LIB_HEAP, $$ZI$$Base);
REGION_DECLARE_EXT(Image$$, ARM_LIB_HEAP, $$ZI$$Limit);
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$ZI$$Base);
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$ZI$$Limit);
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$RW$$Base);
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$RW$$Limit);
REGION_DECLARE_EXT(Image$$, TFM_SECURE_STACK, $$ZI$$Base);
REGION_DECLARE_EXT(Image$$, TFM_SECURE_STACK, $$ZI$$Limit);
REGION_DECLARE_EXT(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
REGION_DECLARE_EXT(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);
/*
* \brief Check the memory whether in the given range.
*
* \param[in] buffer Pointer of memory reference
* \param[in] len Length of memory reference in bytes
* \param[in] base The base address
* \param[in] limit The limit address, the first byte of next
* area memory
*
* \retval IPC_SUCCESS Success
* \retval IPC_ERROR_MEMORY_CHECK Check failed
*/
static int32_t memory_check_range(const void *buffer, size_t len,
uintptr_t base, uintptr_t limit)
{
if (((uintptr_t)buffer >= base) &&
((uintptr_t)((uint8_t *)buffer + len - 1) < limit)) {
return IPC_SUCCESS;
}
return IPC_ERROR_MEMORY_CHECK;
}
/* FixMe: This is only valid for TFM LVL 1 now */
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller)
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
enum tfm_memory_access_e access)
{
uintptr_t base, limit;
int32_t err;
/* If len is zero, this indicates an empty buffer and base is ignored */
if (len == 0) {
@ -514,55 +480,13 @@ int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller)
return IPC_ERROR_MEMORY_CHECK;
}
if (ns_caller) {
base = (uintptr_t)NS_DATA_START;
limit = (uintptr_t)(NS_DATA_START + NS_DATA_SIZE);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
base = (uintptr_t)NS_CODE_START;
limit = (uintptr_t)(NS_CODE_START + NS_CODE_SIZE);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
if (access == TFM_MEMORY_ACCESS_RW) {
err = tfm_core_has_write_access_to_region(buffer, len, ns_caller);
} else {
base = (uintptr_t)&REGION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Base);
limit = (uintptr_t)&REGION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Limit);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
base = (uintptr_t)&REGION_NAME(Image$$, ER_TFM_DATA, $$RW$$Base);
limit = (uintptr_t)&REGION_NAME(Image$$, ER_TFM_DATA, $$RW$$Limit);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
base = (uintptr_t)&REGION_NAME(Image$$, ER_TFM_DATA, $$ZI$$Base);
limit = (uintptr_t)&REGION_NAME(Image$$, ER_TFM_DATA, $$ZI$$Limit);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
base = (uintptr_t)&REGION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Base);
limit = (uintptr_t)&REGION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
base = (uintptr_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
limit = (uintptr_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH,
$$ZI$$Limit);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
base = (uintptr_t)S_CODE_START;
limit = (uintptr_t)(S_CODE_START + S_CODE_SIZE);
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
return IPC_SUCCESS;
}
err = tfm_core_has_read_access_to_region(buffer, len, ns_caller);
}
if (err == 1) {
return IPC_SUCCESS;
}
return IPC_ERROR_MEMORY_CHECK;

View File

@ -148,12 +148,16 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
* FixMe: From non-secure caller, vec and len are composed into a new
* struct parameter. Need to extract them.
*/
/*
* Read parameters from the arguments. It is a fatal error if the
* memory reference for buffer is invalid or not readable.
*/
if (tfm_memory_check((void *)args[1], sizeof(uint32_t),
ns_caller) != IPC_SUCCESS) {
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
tfm_panic();
}
if (tfm_memory_check((void *)args[2], sizeof(uint32_t),
ns_caller) != IPC_SUCCESS) {
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
tfm_panic();
}
@ -175,13 +179,22 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
tfm_panic();
}
/* It is a fatal error if an invalid memory reference was provide. */
/*
* Read client invecs from the wrap input vector. It is a fatal error
* if the memory reference for the wrap input vector is invalid or not
* readable.
*/
if (tfm_memory_check((void *)inptr, in_num * sizeof(psa_invec),
ns_caller) != IPC_SUCCESS) {
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
tfm_panic();
}
/*
* Read client outvecs from the wrap output vector and will update the
* actual length later. It is a fatal error if the memory reference for
* the wrap output vector is invalid or not read-write.
*/
if (tfm_memory_check((void *)outptr, out_num * sizeof(psa_outvec),
ns_caller) != IPC_SUCCESS) {
ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
tfm_panic();
}
@ -193,18 +206,22 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
tfm_memcpy(outvecs, outptr, out_num * sizeof(psa_outvec));
/*
* It is a fatal error if an invalid payload memory reference
* was provided.
* For client input vector, it is a fatal error if the provided payload
* memory reference was invalid or not readable.
*/
for (i = 0; i < in_num; i++) {
if (tfm_memory_check((void *)invecs[i].base, invecs[i].len,
ns_caller) != IPC_SUCCESS) {
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
tfm_panic();
}
}
/*
* For client output vector, it is a fatal error if the provided payload
* memory reference was invalid or not read-write.
*/
for (i = 0; i < out_num; i++) {
if (tfm_memory_check(outvecs[i].base, outvecs[i].len,
ns_caller) != IPC_SUCCESS) {
ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
tfm_panic();
}
}
@ -360,11 +377,11 @@ static psa_status_t tfm_svcall_psa_get(uint32_t *args)
}
/*
* It is a fatal error if the input msg pointer is not a valid memory
* reference.
* Write the message to the service buffer. It is a fatal error if the
* input msg pointer is not a valid memory reference or not read-write.
*/
if (tfm_memory_check((void *)msg, sizeof(psa_msg_t),
false) != IPC_SUCCESS) {
false, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
tfm_panic();
}
@ -517,11 +534,11 @@ static size_t tfm_svcall_psa_read(uint32_t *args)
}
/*
* It is a fatal error if the memory reference for buffer is invalid or
* not writable
* Copy the client data to the service buffer. It is a fatal error
* if the memory reference for buffer is invalid or not read-write.
*/
/* FixMe: write permission check to be added */
if (tfm_memory_check(buffer, num_bytes, false) != IPC_SUCCESS) {
if (tfm_memory_check(buffer, num_bytes, false,
TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
tfm_panic();
}
@ -671,8 +688,12 @@ static void tfm_svcall_psa_write(uint32_t *args)
tfm_panic();
}
/* It is a fatal error if the memory reference for buffer is valid */
if (tfm_memory_check(buffer, num_bytes, false) != IPC_SUCCESS) {
/*
* Copy the service buffer to client outvecs. It is a fatal error
* if the memory reference for buffer is invalid or not readable.
*/
if (tfm_memory_check(buffer, num_bytes, false,
TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
tfm_panic();
}

View File

@ -51,9 +51,9 @@ struct tfm_exc_stack_t {
#endif
#define LOG_MSG_THR(MSG) \
__ASM("MOV r0, %0\n" \
"SVC %1\n" \
: : "r" (MSG), "I" (TFM_SVC_PRINT))
__ASM volatile("MOV r0, %0\n" \
"SVC %1\n" \
: : "r" (MSG), "I" (TFM_SVC_PRINT))
#define LOG_MSG(MSG) \
do { \
@ -96,14 +96,14 @@ __STATIC_INLINE uint32_t __get_active_exc_num(void)
}
__attribute__ ((always_inline))
__STATIC_INLINE void __set_CONTROL_SPSEL(int32_t SPSEL)
__STATIC_INLINE void __set_CONTROL_SPSEL(uint32_t SPSEL)
{
CONTROL_Type ctrl;
ctrl.w = __get_CONTROL();
ctrl.b.SPSEL = SPSEL;
__set_CONTROL(ctrl.w);
__asm("ISB");
__ISB();
}
#endif /* __SECURE_UTILITIES_H__ */

View File

@ -39,9 +39,9 @@ static uint32_t is_boot_data_valid = BOOT_DATA_INVALID;
void tfm_core_validate_boot_data(void)
{
struct shared_data_tlv_header *tlv_header;
struct tfm_boot_data *boot_data;
tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
/* FixMe: Enhance sanity check of shared memory area, it might be invalid:
* - temporal exposure of RAM to non-secure actors
@ -49,7 +49,7 @@ void tfm_core_validate_boot_data(void)
* - version mismatch between bootloader and runtime binary
* - etc.
*/
if (tlv_header->tlv_magic == SHARED_DATA_TLV_INFO_MAGIC) {
if (boot_data->header.tlv_magic == SHARED_DATA_TLV_INFO_MAGIC) {
is_boot_data_valid = BOOT_DATA_VALID;
}
}
@ -62,7 +62,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
uint8_t *ptr;
uint32_t running_partition_idx =
tfm_spm_partition_get_running_partition_idx();
struct shared_data_tlv_header *tlv_header;
struct tfm_boot_data *boot_data;
struct shared_data_tlv_entry tlv_entry;
uintptr_t tlv_end, offset;
uint32_t res;
@ -88,8 +88,8 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
}
/* Get the boundaries of TLV section */
tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
tlv_end = BOOT_TFM_SHARED_DATA_BASE + tlv_header->tlv_tot_len;
boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
tlv_end = BOOT_TFM_SHARED_DATA_BASE + boot_data->header.tlv_tot_len;
offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
/* Add header to output buffer as well */
@ -97,10 +97,10 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
args[0] = TFM_ERROR_INVALID_PARAMETER;
return;
} else {
tlv_header = (struct shared_data_tlv_header *)buf_start;
tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
ptr = (uint8_t *)tlv_header + SHARED_DATA_HEADER_SIZE;
boot_data = (struct tfm_boot_data *)buf_start;
boot_data->header.tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
ptr = boot_data->data;
}
/* Iterates over the TLV section and copy TLVs with requested major
@ -113,7 +113,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
SHARED_DATA_ENTRY_HEADER_SIZE);
if (GET_MAJOR(tlv_entry.tlv_type) == tlv_major) {
/* Check buffer overflow */
if ((ptr - buf_start + tlv_entry.tlv_len) > buf_size) {
if (((ptr - buf_start) + tlv_entry.tlv_len) > buf_size) {
args[0] = TFM_ERROR_INVALID_PARAMETER;
return;
}
@ -121,7 +121,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
tfm_memcpy(ptr, (const void *)offset, tlv_entry.tlv_len);
ptr += tlv_entry.tlv_len;
tlv_header->tlv_tot_len += tlv_entry.tlv_len;
boot_data->header.tlv_tot_len += tlv_entry.tlv_len;
}
}
args[0] = TFM_SUCCESS;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -43,8 +43,8 @@ __asm(" .global __ARM_use_no_argv\n");
#ifndef TFM_LVL
#error TFM_LVL is not defined!
#endif
#if (TFM_LVL != 1) && (TFM_LVL != 3)
#error Only TFM_LVL 1 and 3 are supported!
#if (TFM_LVL != 1) && (TFM_LVL != 2) && (TFM_LVL != 3)
#error Only TFM_LVL 1, 2 and 3 are supported!
#endif
/* Macros to pick linker symbols and allow to form the partition data base */
@ -129,6 +129,23 @@ static int32_t tfm_core_set_secure_exception_priorities(void)
/* FixMe: Explicitly set secure fault and Secure SVC priority to highest */
/*
* Set secure PendSV priority to the lowest in SECURE state.
*
* IMPORTANT NOTE:
*
* Although the priority of the secure PendSV must be the lowest possible
* among other interrupts in the Secure state, it must be ensured that
* PendSV is not preempted nor masked by Non-Secure interrupts to ensure
* the integrity of the Secure operation.
* When AIRCR.PRIS is set, the Non-Secure execution can act on
* FAULTMASK_NS, PRIMASK_NS or BASEPRI_NS register to boost its priority
* number up to the value 0x80.
* For this reason, set the priority of the PendSV interrupt to the next
* priority level configurable on the platform, just below 0x80.
*/
NVIC_SetPriority(PendSV_IRQn, (1 << (__NVIC_PRIO_BITS - 1)) - 1);
return TFM_SUCCESS;
}
@ -152,9 +169,13 @@ void tfm_core_spm_request_handler(const struct tfm_exc_stack_t *svc_ctx)
int main(void)
{
tfm_core_init();
if (tfm_core_init() != 0) {
/* Placeholder for error handling, currently ignored. */
}
tfm_spm_db_init();
if (tfm_spm_db_init() != SPM_ERR_OK) {
/* Placeholder for error handling, currently ignored. */
}
tfm_spm_hal_setup_isolation_hw();
@ -171,6 +192,12 @@ int main(void)
*/
}
/*
* Prioritise secure exceptions to avoid NS being able to pre-empt
* secure SVC or SecureFault. Do it before PSA API initialization.
*/
tfm_core_set_secure_exception_priorities();
#ifdef TFM_PSA_API
tfm_spm_init();
#endif
@ -187,10 +214,5 @@ int main(void)
tfm_spm_partition_set_state(TFM_SP_NON_SECURE_ID,
SPM_PARTITION_STATE_RUNNING);
/* Prioritise secure exceptions to avoid NS being able to pre-empt secure
* SVC or SecureFault
*/
tfm_core_set_secure_exception_priorities();
jump_to_ns_code();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Arm Limited. All rights reserved.
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -8,11 +8,11 @@
#ifndef __TFM_CORE_H__
#define __TFM_CORE_H__
#include "arm_cmse.h"
#include <arm_cmse.h>
#include "tfm_svc.h"
#include "secure_utilities.h"
extern int32_t tfm_scratch_area_size;
extern uint32_t tfm_scratch_area_size;
extern uint8_t *tfm_scratch_area;
#endif /* __TFM_CORE_H__ */

View File

@ -9,7 +9,6 @@
#include <string.h>
#include "secure_utilities.h"
#include "arm_acle.h"
#include "tfm_svc.h"
#include "tfm_secure_api.h"
#include "region_defs.h"
@ -66,9 +65,9 @@ void SecureFault_Handler(void)
/* Only save the context if sp is valid */
if ((sp >= S_DATA_START &&
sp <= S_DATA_LIMIT - sizeof(tfm_fault_context) + 1) ||
sp <= (S_DATA_LIMIT - sizeof(tfm_fault_context)) + 1) ||
(sp >= NS_DATA_START &&
sp <= NS_DATA_LIMIT - sizeof(tfm_fault_context) + 1)) {
sp <= (NS_DATA_LIMIT - sizeof(tfm_fault_context)) + 1)) {
tfm_memcpy(&tfm_fault_context,
(const void *)sp,
sizeof(tfm_fault_context));
@ -103,7 +102,7 @@ void HardFault_Handler(void)
#if defined(__ARM_ARCH_8M_MAIN__)
__attribute__((naked)) void SVC_Handler(void)
{
__ASM(
__ASM volatile(
"TST lr, #4\n" /* Check store SP in thread mode to r0 */
"IT EQ\n"
"BXEQ lr\n"
@ -116,7 +115,7 @@ __attribute__((naked)) void SVC_Handler(void)
#elif defined(__ARM_ARCH_8M_BASE__)
__attribute__((naked)) void SVC_Handler(void)
{
__ASM(
__ASM volatile(
".syntax unified\n"
"MOVS r0, #4\n" /* Check store SP in thread mode to r0 */
"MOV r1, lr\n"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -35,7 +35,7 @@ void jump_to_ns_code(void);
* \brief Called if veneer is running in thread mode
*/
uint32_t tfm_core_partition_request_svc_handler(
uint32_t *svc_args, uint32_t lr);
const uint32_t *svc_args, uint32_t lr);
/**
* \brief Called when secure service returns

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -121,7 +121,7 @@ TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module)
}
/* TZ_MemoryId_t must be a positive integer */
tz_id = free_index + 1;
tz_id = (TZ_MemoryId_t)free_index + 1;
NsClientIdList[free_index].ns_client_id = get_next_ns_client_id();
#ifdef PRINT_NSPM_DEBUG
printf("TZ_AllocModuleContext_S called, returning id %d\r\n",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Arm Limited. All rights reserved.
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -43,14 +43,20 @@ int32_t tfm_psa_veneer_sanity_check(struct tfm_sfn_req_s *desc_ptr)
return tfm_core_ns_ipc_request(fn, (int32_t)a, (int32_t)b, \
(int32_t)c, (int32_t)d)
__attribute__ ((naked))
static int32_t tfm_core_ipc_request(const struct tfm_sfn_req_s *desc_ptr)
{
__ASM volatile("SVC %0 \n"
"BX LR \n"
: : "I" (TFM_SVC_IPC_REQUEST));
}
__attribute__ ((always_inline)) __STATIC_INLINE
int32_t tfm_core_ns_ipc_request(void *fn, int32_t arg1, int32_t arg2,
int32_t arg3, int32_t arg4)
{
int32_t args[4] = {arg1, arg2, arg3, arg4};
volatile struct tfm_sfn_req_s desc;
struct tfm_sfn_req_s *desc_ptr = &desc;
int32_t res;
struct tfm_sfn_req_s desc = {0};
desc.sfn = fn;
desc.args = args;
@ -61,13 +67,7 @@ int32_t tfm_core_ns_ipc_request(void *fn, int32_t arg1, int32_t arg2,
/* FIXME: Proper error handling to be implemented */
return TFM_ERROR_INVALID_EXC_MODE;
} else {
__ASM("MOV r0, %1\n"
"SVC %2\n"
"MOV %0, r0\n"
: "=r" (res)
: "r" (desc_ptr), "I" (TFM_SVC_IPC_REQUEST)
: "r0");
return res;
return tfm_core_ipc_request(&desc);
}
}

View File

@ -50,17 +50,17 @@ static int32_t is_iovec_api_call(void)
return curr_part_data->iovec_api;
}
static int32_t *prepare_partition_ctx(
struct tfm_exc_stack_t *svc_ctx,
struct tfm_sfn_req_s *desc_ptr,
int32_t *dst)
static uint32_t *prepare_partition_ctx(
const struct tfm_exc_stack_t *svc_ctx,
const struct tfm_sfn_req_s *desc_ptr,
uint32_t *dst)
{
/* XPSR = as was when called, but make sure it's thread mode */
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00;
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00U;
/* ReturnAddress = resume veneer in new context */
*(--dst) = svc_ctx->RetAddr;
/* LR = sfn address */
*(--dst) = (int32_t)desc_ptr->sfn;
*(--dst) = (uint32_t)desc_ptr->sfn;
/* R12 = don't care */
*(--dst) = 0;
@ -74,20 +74,20 @@ static int32_t *prepare_partition_ctx(
return dst;
}
static int32_t *prepare_partition_iovec_ctx(
struct tfm_exc_stack_t *svc_ctx,
struct tfm_sfn_req_s *desc_ptr,
struct iovec_args_t *iovec_args,
int32_t *dst)
static uint32_t *prepare_partition_iovec_ctx(
const struct tfm_exc_stack_t *svc_ctx,
const struct tfm_sfn_req_s *desc_ptr,
const struct iovec_args_t *iovec_args,
uint32_t *dst)
{
/* XPSR = as was when called, but make sure it's thread mode */
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00;
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00U;
/* ReturnAddress = resume veneer in new context */
*(--dst) = svc_ctx->RetAddr;
/* LR = sfn address */
*(--dst) = (int32_t)desc_ptr->sfn;
*(--dst) = (uint32_t)desc_ptr->sfn;
/* R12 = don't care */
*(--dst) = 0;
*(--dst) = 0U;
/* R0-R3 = sfn arguments */
*(--dst) = iovec_args->out_len;
@ -99,7 +99,7 @@ static int32_t *prepare_partition_iovec_ctx(
}
static void restore_caller_ctx(
struct tfm_exc_stack_t *svc_ctx,
const struct tfm_exc_stack_t *svc_ctx,
struct tfm_exc_stack_t *target_ctx)
{
/* ReturnAddress = resume veneer after second SVC */
@ -157,7 +157,7 @@ static int32_t check_address_range(const void *p, size_t s,
*
* \return 1 if the partition has access to the memory range, 0 otherwise.
*/
static int32_t has_access_to_region(const void *p, size_t s, uint32_t flags)
static int32_t has_access_to_region(const void *p, size_t s, int flags)
{
int32_t range_access_allowed_by_mpu;
@ -192,22 +192,10 @@ static int32_t has_access_to_region(const void *p, size_t s, uint32_t flags)
check_address_range(p, s, NS_DATA_START, NS_DATA_LIMIT+1-NS_DATA_START);
}
/**
* \brief Check whether the current partition has read access to a memory range
*
* This function assumes, that the current MPU configuration is set for the
* partition to be checked.
*
* \param[in] p The start address of the range to check
* \param[in] s The size of the range to check
* \param[in] ns_caller Whether the current partition is a non-secure one
*
* \return 1 if the partition has access to the memory range, 0 otherwise.
*/
static int32_t has_read_access_to_region(const void *p, size_t s,
int32_t ns_caller)
int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
uint32_t ns_caller)
{
uint32_t flags = CMSE_MPU_UNPRIV|CMSE_MPU_READ;
int flags = CMSE_MPU_UNPRIV|CMSE_MPU_READ;
if (ns_caller) {
flags |= CMSE_NONSECURE;
@ -216,21 +204,10 @@ static int32_t has_read_access_to_region(const void *p, size_t s,
return has_access_to_region(p, s, flags);
}
/**
* \brief Check whether the current partition has write access to a memory range
*
* This function assumes, that the current MPU configuration is set for the
* partition to be checked.
*
* \param[in] p The start address of the range to check
* \param[in] s The size of the range to check
* \param[in] ns_caller Whether the current partition is a non-secure one
*
* \return 1 if the partition has access to the memory range, 0 otherwise.
*/
static int32_t has_write_access_to_region(void *p, size_t s, int32_t ns_caller)
int32_t tfm_core_has_write_access_to_region(void *p, size_t s,
uint32_t ns_caller)
{
uint32_t flags = CMSE_MPU_UNPRIV|CMSE_MPU_READWRITE;
int flags = CMSE_MPU_UNPRIV|CMSE_MPU_READWRITE;
if (ns_caller) {
flags |= CMSE_NONSECURE;
@ -247,15 +224,23 @@ static int32_t has_write_access_to_region(void *p, size_t s, int32_t ns_caller)
* \return Return /ref TFM_SUCCESS if the iovec parameters are valid, error code
* otherwise as in /ref tfm_status_e
*/
static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
static int32_t tfm_core_check_sfn_parameters(
const struct tfm_sfn_req_s *desc_ptr)
{
struct psa_invec *in_vec = (psa_invec *)desc_ptr->args[0];
size_t in_len = desc_ptr->args[1];
size_t in_len;
struct psa_outvec *out_vec = (psa_outvec *)desc_ptr->args[2];
size_t out_len = desc_ptr->args[3];
size_t out_len;
uint32_t i;
if ((desc_ptr->args[1] < 0) || (desc_ptr->args[3] < 0)) {
return TFM_ERROR_INVALID_PARAMETER;
}
in_len = (size_t)(desc_ptr->args[1]);
out_len = (size_t)(desc_ptr->args[3]);
/* The number of vectors are within range. Extra checks to avoid overflow */
if ((in_len > PSA_MAX_IOVEC) || (out_len > PSA_MAX_IOVEC) ||
(in_len + out_len > PSA_MAX_IOVEC)) {
@ -267,8 +252,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
*/
if (in_len > 0) {
if ((in_vec == NULL) ||
(has_write_access_to_region(in_vec, sizeof(psa_invec)*in_len,
desc_ptr->ns_caller) != 1)) {
(tfm_core_has_write_access_to_region(in_vec,
sizeof(psa_invec)*in_len,
desc_ptr->ns_caller) != 1)) {
return TFM_ERROR_INVALID_PARAMETER;
}
} else {
@ -278,8 +264,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
}
if (out_len > 0) {
if ((out_vec == NULL) ||
(has_write_access_to_region(out_vec, sizeof(psa_outvec)*out_len,
desc_ptr->ns_caller) != 1)) {
(tfm_core_has_write_access_to_region(out_vec,
sizeof(psa_outvec)*out_len,
desc_ptr->ns_caller) != 1)) {
return TFM_ERROR_INVALID_PARAMETER;
}
} else {
@ -294,8 +281,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
for (i = 0; i < in_len; ++i) {
if (in_vec[i].len > 0) {
if ((in_vec[i].base == NULL) ||
(has_read_access_to_region(in_vec[i].base, in_vec[i].len,
desc_ptr->ns_caller) != 1)) {
(tfm_core_has_read_access_to_region(in_vec[i].base,
in_vec[i].len,
desc_ptr->ns_caller) != 1)) {
return TFM_ERROR_INVALID_PARAMETER;
}
}
@ -303,8 +291,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
for (i = 0; i < out_len; ++i) {
if (out_vec[i].len > 0) {
if ((out_vec[i].base == NULL) ||
(has_write_access_to_region(out_vec[i].base, out_vec[i].len,
desc_ptr->ns_caller) != 1)) {
(tfm_core_has_write_access_to_region(out_vec[i].base,
out_vec[i].len,
desc_ptr->ns_caller) != 1)) {
return TFM_ERROR_INVALID_PARAMETER;
}
}
@ -316,7 +305,7 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
static void tfm_copy_iovec_parameters(struct iovec_args_t *target,
const struct iovec_args_t *source)
{
int i;
size_t i;
target->in_len = source->in_len;
for (i = 0; i < source->in_len; ++i) {
@ -346,7 +335,7 @@ static void tfm_clear_iovec_parameters(struct iovec_args_t *args)
}
}
static int32_t tfm_start_partition(struct tfm_sfn_req_s *desc_ptr,
static int32_t tfm_start_partition(const struct tfm_sfn_req_s *desc_ptr,
uint32_t excReturn)
{
uint32_t caller_partition_idx = desc_ptr->caller_part_idx;
@ -479,18 +468,21 @@ static int32_t tfm_start_partition(struct tfm_sfn_req_s *desc_ptr,
iovec_args = (struct iovec_args_t *)
((uint32_t)&REGION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)-
sizeof(struct iovec_args_t));
tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args);
if (tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args) !=
SPM_ERR_OK) {
return TFM_ERROR_GENERIC;
}
tfm_copy_iovec_parameters(iovec_args,
&(curr_part_data->iovec_args));
/* Prepare the partition context, update stack ptr */
psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
iovec_args,
(int32_t *)partition_psp);
(uint32_t *)partition_psp);
} else {
/* Prepare the partition context, update stack ptr */
psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
(int32_t *)partition_psp);
(uint32_t *)partition_psp);
}
__set_PSP(psp);
__set_PSPLIM(partition_psplim);
@ -505,17 +497,20 @@ static int32_t tfm_start_partition(struct tfm_sfn_req_s *desc_ptr,
iovec_args =
(struct iovec_args_t *)(tfm_spm_partition_get_stack_top(partition_idx) -
sizeof(struct iovec_args_t));
tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args);
if (tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args) !=
SPM_ERR_OK) {
return TFM_ERROR_GENERIC;
}
tfm_copy_iovec_parameters(iovec_args, &(curr_part_data->iovec_args));
/* Prepare the partition context, update stack ptr */
psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
iovec_args,
(int32_t *)partition_psp);
(uint32_t *)partition_psp);
} else {
/* Prepare the partition context, update stack ptr */
psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
(int32_t *)partition_psp);
(uint32_t *)partition_psp);
}
__set_PSP(psp);
__set_PSPLIM(partition_psplim);
@ -538,7 +533,7 @@ static int32_t tfm_return_from_partition(uint32_t *excReturn)
uint32_t return_partition_idx;
uint32_t return_partition_flags;
uint32_t psp = __get_PSP();
int i;
size_t i;
struct tfm_exc_stack_t *svc_ctx = (struct tfm_exc_stack_t *)psp;
struct iovec_args_t *iovec_args;
@ -676,7 +671,7 @@ void tfm_secure_api_error_handler(void)
}
}
static int32_t tfm_check_sfn_req_integrity(struct tfm_sfn_req_s *desc_ptr)
static int32_t tfm_check_sfn_req_integrity(const struct tfm_sfn_req_s *desc_ptr)
{
if ((desc_ptr == NULL) ||
(desc_ptr->sp_id == 0) ||
@ -688,7 +683,7 @@ static int32_t tfm_check_sfn_req_integrity(struct tfm_sfn_req_s *desc_ptr)
}
static int32_t tfm_core_check_sfn_req_rules(
struct tfm_sfn_req_s *desc_ptr)
const struct tfm_sfn_req_s *desc_ptr)
{
/* Check partition idx validity */
if (desc_ptr->caller_part_idx == SPM_INVALID_PARTITION_IDX) {
@ -1046,7 +1041,7 @@ void tfm_core_memory_permission_check_handler(uint32_t *svc_args)
/* This SVC handler is called if veneer is running in thread mode */
uint32_t tfm_core_partition_request_svc_handler(
struct tfm_exc_stack_t *svc_ctx, uint32_t excReturn)
const struct tfm_exc_stack_t *svc_ctx, uint32_t excReturn)
{
struct tfm_sfn_req_s *desc_ptr;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -8,11 +8,12 @@
#ifndef __TFM_SECURE_API_H__
#define __TFM_SECURE_API_H__
#include "arm_cmse.h"
#include <arm_cmse.h>
#include "tfm_svc.h"
#include "secure_utilities.h"
#include "tfm_core.h"
#include "tfm_api.h"
#include "bl2/include/tfm_boot_status.h"
/*!
* \def __tfm_secure_gateway_attributes__
@ -46,7 +47,7 @@ struct tfm_sfn_req_s {
int32_t *args;
uint32_t caller_part_idx;
int32_t iovec_api;
int32_t ns_caller : 1;
uint32_t ns_caller;
};
enum tfm_buffer_share_region_e {
@ -81,13 +82,44 @@ extern int32_t tfm_core_memory_permission_check(const void *ptr,
uint32_t size,
int32_t access);
extern int32_t tfm_core_get_boot_data(uint8_t major_type, void *ptr,
extern int32_t tfm_core_get_boot_data(uint8_t major_type,
struct tfm_boot_data *boot_data,
uint32_t len);
int32_t tfm_core_sfn_request(struct tfm_sfn_req_s *desc_ptr);
int32_t tfm_core_sfn_request(const struct tfm_sfn_req_s *desc_ptr);
int32_t tfm_core_sfn_request_thread_mode(struct tfm_sfn_req_s *desc_ptr);
/**
* \brief Check whether the current partition has read access to a memory range
*
* This function assumes, that the current MPU configuration is set for the
* partition to be checked.
*
* \param[in] p The start address of the range to check
* \param[in] s The size of the range to check
* \param[in] ns_caller Whether the current partition is a non-secure one
*
* \return 1 if the partition has access to the memory range, 0 otherwise.
*/
int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
uint32_t ns_caller);
/**
* \brief Check whether the current partition has write access to a memory range
*
* This function assumes, that the current MPU configuration is set for the
* partition to be checked.
*
* \param[in] p The start address of the range to check
* \param[in] s The size of the range to check
* \param[in] ns_caller Whether the current partition is a non-secure one
*
* \return 1 if the partition has access to the memory range, 0 otherwise.
*/
int32_t tfm_core_has_write_access_to_region(void *p, size_t s,
uint32_t ns_caller);
#define TFM_CORE_IOVEC_SFN_REQUEST(id, fn, a, b, c, d) \
return tfm_core_partition_request(id, fn, TFM_SFN_API_IOVEC, \
(int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d)
@ -106,7 +138,31 @@ int32_t tfm_core_partition_request(uint32_t id, void *fn, int32_t iovec_api,
desc.sp_id = id;
desc.sfn = fn;
desc.args = args;
desc.ns_caller = cmse_nonsecure_caller();
/*
* This preprocessor condition checks if a version of GCC smaller than
* 7.3.1 is being used to compile the code.
* These versions are affected by a bug on the cmse_nonsecure_caller
* intrinsic which returns incorrect results.
* Please check Bug 85203 on GCC Bugzilla for more information.
*/
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && \
(__GNUC__ < 7 || \
(__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || \
(__GNUC_MINOR__ == 3 && __GNUC_PATCHLEVEL__ < 1))))
/*
* Use the fact that, if called from Non-Secure, the LSB of the return
* address is set to 0.
*/
desc.ns_caller = (uint32_t)!(
(intptr_t)__builtin_extract_return_addr(__builtin_return_address(0U))
& 1);
#else
/*
* Convert the result of cmse_nonsecure_caller from an int to a uint32_t
* to prevent using an int in the tfm_sfn_req_s structure.
*/
desc.ns_caller = (cmse_nonsecure_caller() != 0) ? 1U : 0U;
#endif /* Check for GCC compiler version smaller than 7.3.1 */
desc.iovec_api = iovec_api;
if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
/* FixMe: Error severity TBD */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -13,7 +13,7 @@
#include "secure_fw/include/tfm_spm_services_api.h"
uint8_t *tfm_scratch_area;
int32_t tfm_scratch_area_size;
uint32_t tfm_scratch_area_size;
nsfptr_t ns_entry;
void jump_to_ns_code(void)
@ -36,9 +36,9 @@ void jump_to_ns_code(void)
#if defined(__ARM_ARCH_8M_MAIN__)
__attribute__((naked)) int32_t tfm_core_sfn_request(
struct tfm_sfn_req_s *desc_ptr)
const struct tfm_sfn_req_s *desc_ptr)
{
__ASM(
__ASM volatile(
"PUSH {r4-r12, lr}\n"
"SVC %[SVC_REQ]\n"
"MOV r4, #0\n"
@ -58,9 +58,9 @@ __attribute__((naked)) int32_t tfm_core_sfn_request(
}
#elif defined(__ARM_ARCH_8M_BASE__)
__attribute__((naked)) int32_t tfm_core_sfn_request(
struct tfm_sfn_req_s *desc_ptr)
const struct tfm_sfn_req_s *desc_ptr)
{
__ASM(
__ASM volatile(
".syntax unified\n"
"PUSH {lr}\n"
"PUSH {r4-r7}\n"
@ -104,7 +104,7 @@ int32_t tfm_core_memory_permission_check(const void *ptr,
uint32_t len,
int32_t access)
{
__ASM(
__ASM volatile(
"SVC %0\n"
"BX lr\n"
: : "I" (TFM_SVC_MEMORY_CHECK));
@ -113,7 +113,7 @@ int32_t tfm_core_memory_permission_check(const void *ptr,
__attribute__((naked))
int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
{
__ASM(
__ASM volatile(
"SVC %0\n"
"BX LR\n"
: : "I" (TFM_SVC_GET_CALLER_CLIENT_ID));
@ -122,7 +122,7 @@ int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
__attribute__((naked))
int32_t tfm_spm_request_reset_vote(void)
{
__ASM(
__ASM volatile(
"MOVS R0, %0\n"
"B tfm_spm_request\n"
: : "I" (TFM_SPM_REQUEST_RESET_VOTE));
@ -131,7 +131,7 @@ int32_t tfm_spm_request_reset_vote(void)
__attribute__((naked))
int32_t tfm_spm_request(void)
{
__ASM(
__ASM volatile(
"SVC %0\n"
"BX lr\n"
: : "I" (TFM_SVC_SPM_REQUEST));
@ -140,7 +140,7 @@ int32_t tfm_spm_request(void)
__attribute__((naked))
int32_t tfm_core_validate_secure_caller(void)
{
__ASM(
__ASM volatile(
"SVC %0\n"
"BX lr\n"
: : "I" (TFM_SVC_VALIDATE_SECURE_CALLER));
@ -149,16 +149,18 @@ int32_t tfm_core_validate_secure_caller(void)
__attribute__((naked))
int32_t tfm_core_set_buffer_area(enum tfm_buffer_share_region_e share)
{
__ASM(
__ASM volatile(
"SVC %0\n"
"BX lr\n"
: : "I" (TFM_SVC_SET_SHARE_AREA));
}
__attribute__((naked))
int32_t tfm_core_get_boot_data(uint8_t major_type, void *ptr, uint32_t len)
int32_t tfm_core_get_boot_data(uint8_t major_type,
struct tfm_boot_data *boot_status,
uint32_t len)
{
__ASM(
__ASM volatile(
"SVC %0\n"
"BX lr\n"
: : "I" (TFM_SVC_GET_BOOT_DATA));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -43,6 +43,6 @@ typedef enum {
#endif
} tfm_svc_number_t;
#define SVC(code) __ASM("svc %0" : : "I" (code))
#define SVC(code) __ASM volatile("svc %0" : : "I" (code))
#endif /* __TFM_SVC_H__ */

View File

@ -33,7 +33,7 @@ typedef enum {
* returned.
*/
static void tfm_spm_partition_err_handler(
struct spm_partition_desc_t *partition,
const struct spm_partition_desc_t *partition,
sp_error_type_t err_type,
int32_t err_code)
{
@ -42,17 +42,32 @@ static void tfm_spm_partition_err_handler(
printf("Partition init failed for partition id 0x%08X\r\n",
partition->static_data.partition_id);
} else {
printf("Unknown partition error %d for partition id 0x%08X\r\n",
err_type, partition->static_data.partition_id);
printf(
"Unknown partition error %d (code: %d) for partition id 0x%08X\r\n",
err_type, err_code, partition->static_data.partition_id);
}
#else
(void)err_type;
(void)err_code;
#endif
tfm_spm_partition_set_state(partition->static_data.partition_id,
SPM_PARTITION_STATE_CLOSED);
}
/*
* This function prevents name clashes between the variable names accessibles in
* the scope of where tfm_partition_list.inc is included and the varaible names
* defined inside tfm_partition_list.inc file.
*/
static inline enum spm_err_t add_user_defined_partitions(void) {
#include "tfm_partition_list.inc"
return SPM_ERR_OK;
}
uint32_t get_partition_idx(uint32_t partition_id)
{
int i;
uint32_t i;
if (partition_id == INVALID_PARTITION_ID) {
return SPM_INVALID_PARTITION_IDX;
@ -70,8 +85,9 @@ uint32_t get_partition_idx(uint32_t partition_id)
enum spm_err_t tfm_spm_db_init(void)
{
struct spm_partition_desc_t *part_ptr;
enum spm_err_t err;
tfm_memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
(void)tfm_memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
/* This function initialises partition db */
g_spm_partition_db.running_partition_idx = SPM_INVALID_PARTITION_IDX;
@ -82,12 +98,11 @@ enum spm_err_t tfm_spm_db_init(void)
*/
/* For the non secure Execution environment */
#if TFM_LVL != 1
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[];
uint32_t psp_stack_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base;
uint32_t psp_stack_top = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit;
#endif
if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
return SPM_ERR_INVALID_CONFIG;
}
@ -103,6 +118,9 @@ enum spm_err_t tfm_spm_db_init(void)
* RW start address to psp_stack_bottom to get RW access to stack
*/
part_ptr->memory_data.rw_start = psp_stack_bottom;
#else
part_ptr->stack_limit = psp_stack_bottom;
part_ptr->stack_size = psp_stack_top - psp_stack_bottom;
#endif
part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
@ -121,8 +139,10 @@ enum spm_err_t tfm_spm_db_init(void)
part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
++g_spm_partition_db.partition_count;
/* Add user-defined secure partitions */
#include "tfm_partition_list.inc"
err = add_user_defined_partitions();
if (err != SPM_ERR_OK) {
return err;
}
g_spm_partition_db.is_init = 1;
@ -154,7 +174,7 @@ enum spm_err_t tfm_spm_partition_init(void)
int32_t res;
desc.args = args;
desc.ns_caller = 0;
desc.ns_caller = 0U;
desc.iovec_api = TFM_SFN_API_IOVEC;
desc.sfn = (sfn_t)part->static_data.partition_init;
desc.sp_id = part->static_data.partition_id;
@ -314,20 +334,25 @@ enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
return ret;
}
void tfm_spm_partition_set_iovec(uint32_t partition_idx, int32_t *args)
enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
const int32_t *args)
{
struct spm_partition_runtime_data_t *runtime_data =
&g_spm_partition_db.partitions[partition_idx].runtime_data;
int32_t i;
size_t i;
runtime_data->iovec_args.in_len = args[1];
for (i = 0; i < runtime_data->iovec_args.in_len; ++i) {
if ((args[1] < 0) || (args[3] < 0)) {
return SPM_ERR_INVALID_PARAMETER;
}
runtime_data->iovec_args.in_len = (size_t)args[1];
for (i = 0U; i < runtime_data->iovec_args.in_len; ++i) {
runtime_data->iovec_args.in_vec[i].base =
((psa_invec *)args[0])[i].base;
runtime_data->iovec_args.in_vec[i].len = ((psa_invec *)args[0])[i].len;
}
runtime_data->iovec_args.out_len = args[3];
for (i = 0; i < runtime_data->iovec_args.out_len; ++i) {
runtime_data->iovec_args.out_len = (size_t)args[3];
for (i = 0U; i < runtime_data->iovec_args.out_len; ++i) {
runtime_data->iovec_args.out_vec[i].base =
((psa_outvec *)args[2])[i].base;
runtime_data->iovec_args.out_vec[i].len =
@ -335,6 +360,8 @@ void tfm_spm_partition_set_iovec(uint32_t partition_idx, int32_t *args)
}
runtime_data->orig_outvec = (psa_outvec *)args[2];
runtime_data->iovec_api = 1;
return SPM_ERR_OK;
}
uint32_t tfm_spm_partition_get_running_partition_idx(void)

View File

@ -20,6 +20,7 @@ enum spm_err_t {
SPM_ERR_PARTITION_DB_NOT_INIT,
SPM_ERR_PARTITION_ALREADY_ACTIVE,
SPM_ERR_PARTITION_NOT_AVAILABLE,
SPM_ERR_INVALID_PARAMETER,
SPM_ERR_INVALID_CONFIG,
};
@ -297,11 +298,14 @@ enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
* args[2] is out_vec
* args[3] is out_len
*
* \return Error code \ref spm_err_t
*
* \note This function doesn't check if partition_idx is valid.
* \note This function assumes that the iovecs that are passed in args are
* valid, and does no sanity check on them at all.
*/
void tfm_spm_partition_set_iovec(uint32_t partition_idx, int32_t *args);
enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
const int32_t *args);
/**
* \brief Initialize partition database

View File

@ -21,7 +21,7 @@ typedef psa_status_t(*sp_init_function)(void);
#define TFM_PARTITION_TYPE_APP "APPLICATION-ROT"
#define TFM_PARTITION_TYPE_PSA "PSA-ROT"
#define TFM_STACK_SIZE 1024
#define TFM_STACK_SIZE (1024 * 5)
#ifdef TFM_PSA_API
enum tfm_partition_priority {

View File

@ -115,21 +115,21 @@ struct spm_partition_db_t {
++g_spm_partition_db.partition_count; \
} while (0)
#define PARTITION_ADD_INIT_FUNC(partition, init_func) \
do { \
extern int32_t init_func(void); \
uint32_t partition_idx = get_partition_idx(partition##_ID); \
struct spm_partition_desc_t *part_ptr = \
&(g_spm_partition_db.partitions[partition_idx]); \
part_ptr->static_data.partition_init = init_func; \
#define PARTITION_ADD_INIT_FUNC(partition, init_func) \
do { \
extern int32_t init_func(void); \
uint32_t partition_idx = get_partition_idx(partition##_ID); \
struct spm_partition_desc_t *part_ptr = \
&(g_spm_partition_db.partitions[partition_idx]); \
part_ptr->static_data.partition_init = init_func; \
} while (0)
#define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
do { \
uint32_t partition_idx = get_partition_idx(partition##_ID); \
struct spm_partition_desc_t *part_ptr = \
&(g_spm_partition_db.partitions[partition_idx]); \
part_ptr->platform_data = peripheral; \
#define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
do { \
uint32_t partition_idx = get_partition_idx(partition##_ID); \
struct spm_partition_desc_t *part_ptr = \
&(g_spm_partition_db.partitions[partition_idx]); \
part_ptr->platform_data = peripheral; \
} while (0)
#endif /* __SPM_DB_SETUP_H__ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -12,6 +12,7 @@ extern "C" {
#endif
#include <stdint.h>
#include "tfm_api.h"
typedef int32_t (*veneer_fn) (uint32_t arg0, uint32_t arg1,
uint32_t arg2, uint32_t arg3);
@ -32,7 +33,7 @@ uint32_t tfm_ns_lock_dispatch(veneer_fn fn,
* \details Needs to be called during non-secure app init
* to initialize the TFM NS lock object
*/
uint32_t tfm_ns_lock_init();
enum tfm_status_e tfm_ns_lock_init();
#ifdef __cplusplus
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -24,7 +24,7 @@ extern "C" {
* \brief Macro to encode an svc instruction
*
*/
#define SVC(code) __ASM("svc %0" : : "I" (code))
#define SVC(code) __ASM volatile("svc %0" : : "I" (code))
/**
* \def LIST_SVC_NSPM
@ -59,7 +59,7 @@ enum tfm_svc_num {
};
/* number of user SVC functions */
#define USER_SVC_COUNT (SVC_TFM_MAX - 1)
#define USER_SVC_COUNT ((uint32_t)SVC_TFM_MAX - 1)
#ifdef __cplusplus
}

View File

@ -1,75 +1,75 @@
{
"files" : [
"files": [
{
"src_file" : "interface/src/tfm_ns_lock_rtx.c",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_ns_lock_rtx.c"
"src_file": "interface/src/tfm_ns_lock_rtx.c",
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_ns_lock_rtx.c"
},
{
"src_file" : "interface/src/tfm_psa_ns_api.c",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_psa_ns_api.c"
"src_file": "interface/src/tfm_psa_ns_api.c",
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_psa_ns_api.c"
},
{
"src_file" : "interface/include/psa_client.h",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/psa_client.h"
"src_file": "interface/include/psa_client.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/psa_client.h"
},
{
"src_file" : "interface/include/psa_service.h",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/psa_service.h"
"src_file": "interface/include/psa_service.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/psa_service.h"
},
{
"src_file" : "interface/include/tfm_api.h",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_api.h"
"src_file": "interface/include/tfm_api.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_api.h"
},
{
"src_file" : "interface/include/tfm_ns_lock.h",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_lock.h"
"src_file": "interface/include/tfm_ns_lock.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_lock.h"
},
{
"src_file" : "interface/include/tfm_ns_svc.h",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_svc.h"
"src_file": "interface/include/tfm_ns_svc.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_svc.h"
},
{
"src_file" : "interface/include/tfm_nspm_svc_handler.h",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_nspm_svc_handler.h"
"src_file": "interface/include/tfm_nspm_svc_handler.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_nspm_svc_handler.h"
},
{
"src_file" : "platform/include/tfm_spm_hal.h",
"dest_file" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/platform/include/tfm_spm_hal.h"
"src_file": "platform/include/tfm_spm_hal.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/platform/include/tfm_spm_hal.h"
}
],
"folders" : [
"folders": [
{
"src_folder" : "secure_fw/core",
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core"
"src_folder": "secure_fw/core",
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core"
},
{
"src_folder" : "secure_fw/core/ipc",
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc"
"src_folder": "secure_fw/core/ipc",
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc"
},
{
"src_folder" : "secure_fw/core/ipc/include",
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc/include"
"src_folder": "secure_fw/core/ipc/include",
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc/include"
},
{
"src_folder" : "secure_fw/include",
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/include"
"src_folder": "secure_fw/include",
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/include"
},
{
"src_folder" : "secure_fw/spm",
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/spm"
"src_folder": "secure_fw/spm",
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/spm"
},
{
"src_folder" : "bl2/include",
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/bl2/include"
"src_folder": "bl2/include",
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/bl2/include"
}
],
"commit_sha" : [
"185d2865da45cc2c6ac3acb755b90c196934d7d5",
"e89c1a68ce8f690ce0d6029cd9196b03906060de",
"3fbc73e046e59e45b58ea2935c5d2fe5e89e67d8",
"f0e4583b72c887c87bd06797d1dc815f4f9e3300",
"ad8ddd8e6e4f8cb378e16617931cfd80515fb51f",
"3badc126cf4c3b6ff224d57cb469f9be546b30e2",
"5a9dff2e04c3471caafb94962fe6fc1357305c1a"
"commit_sha": [
"fb068d2cb4e89cacf0e9f413075bb4b211f1484f",
"5d41a2aeae71b13f2763bea4e55899646291e0eb",
"9c1e080e39adc7211c8c2c12cd652da3dc124299",
"78ed87028718b1b926d847ff6fc2f91d44e53d6d",
"280715f9b74ab29459d81edaf02b39e7a6acb13c",
"ea81bf91c90ae23dd9de012bfd7498613be00601",
"5342015bb12a486a1c563175a8a7129f0737c925"
]
}