diff options
Diffstat (limited to 'secure_fw/core/tfm_secure_api.c')
-rw-r--r-- | secure_fw/core/tfm_secure_api.c | 144 |
1 files changed, 6 insertions, 138 deletions
diff --git a/secure_fw/core/tfm_secure_api.c b/secure_fw/core/tfm_secure_api.c index 6555fcb86b..f713b0345c 100644 --- a/secure_fw/core/tfm_secure_api.c +++ b/secure_fw/core/tfm_secure_api.c @@ -5,32 +5,9 @@ * */ -#include <stdio.h> -#include <string.h> #include <stdbool.h> -#include <arm_cmse.h> +#include "secure_utilities.h" #include "tfm_secure_api.h" -#include "tfm_nspm.h" -#include "uart_stdout.h" -#include "secure_fw/spm/spm_api.h" -#include "region_defs.h" -#include "tfm_api.h" - -#define EXC_RETURN_SECURE_FUNCTION 0xFFFFFFFD - -#ifndef TFM_LVL -#error TFM_LVL is not defined! -#endif - -/* Macros to pick linker symbols and allow references to sections */ -#define REGION(a, b, c) a##b##c -#define REGION_NAME(a, b, c) REGION(a, b, c) -#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c) - -#ifndef TFM_PSA_API /* Only use scratch if using veneer functions, not IPC */ -REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base); -REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit); -#endif /* !defined(TFM_PSA_API) */ /* This is the "Big Lock" on the secure side, to guarantee single entry * to SPE @@ -52,27 +29,14 @@ bool tfm_is_one_bit_set(uint32_t n) return ((n && !(n & (n-1))) ? true : false); } -/** - * \brief Check whether a memory range is inside a memory region. - * - * \param[in] p The start address of the range to check - * \param[in] s The size of the range to check - * \param[in] region_start The start address of the region, which should - * contain the range - * \param[in] region_len The size of the region, which should contain the - * range - * - * \return TFM_SUCCESS if the region contains the range, - * TFM_ERROR_GENERIC otherwise. - */ -static enum tfm_status_e check_address_range(const void *p, size_t s, - uintptr_t region_start, - uint32_t region_len) +enum tfm_status_e check_address_range(const void *p, size_t s, + uintptr_t region_start, + uintptr_t region_limit) { int32_t range_in_region; /* Check for overflow in the range parameters */ - if ((uintptr_t)p > UINTPTR_MAX-s) { + if ((uintptr_t)p > UINTPTR_MAX - s) { return TFM_ERROR_GENERIC; } @@ -80,7 +44,7 @@ static enum tfm_status_e check_address_range(const void *p, size_t s, /* Calculate the result */ range_in_region = ((uintptr_t)p >= region_start) && - ((uintptr_t)p+s <= region_start+region_len); + ((uintptr_t)(p + s - 1) <= region_limit); if (range_in_region) { return TFM_SUCCESS; } else { @@ -88,101 +52,6 @@ static enum tfm_status_e check_address_range(const void *p, size_t s, } } -/** - * \brief Check whether the current partition has access to a memory range - * - * This function assumes, that the current MPU configuration is set for the - * partition to be checked. The flags should contain information of the - * execution mode of the partition code (priv/unpriv), and access type - * (read/write) as specified in "ARMv8-M Security Extensions: Requirements on - * Development Tools" chapter "Address range check intrinsic" - * - * \param[in] p The start address of the range to check - * \param[in] s The size of the range to check - * \param[in] flags The flags to pass to the cmse_check_address_range func - * - * \return TFM_SUCCESS if the partition has access to the memory range, - * TFM_ERROR_GENERIC otherwise. - */ -static enum tfm_status_e has_access_to_region(const void *p, size_t s, - int flags) -{ - int32_t range_access_allowed_by_mpu; - -#ifndef TFM_PSA_API /* Only use scratch if using veneer functions, not IPC */ - uint32_t scratch_base = - (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base); - uint32_t scratch_limit = - (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit); -#endif /* !defined(TFM_PSA_API) */ - - /* Use the TT instruction to check access to the partition's regions*/ - range_access_allowed_by_mpu = - cmse_check_address_range((void *)p, s, flags) != NULL; - - if (range_access_allowed_by_mpu) { - return TFM_SUCCESS; - } - -#ifndef TFM_PSA_API /* Only use scratch if using veneer functions, not IPC */ - /* If the check for the current MPU settings fails, check for the share - * region, only if the partition is secure - */ - if ((flags & CMSE_NONSECURE) == 0) { - if (check_address_range(p, s, scratch_base, - scratch_limit+1-scratch_base) == TFM_SUCCESS) { - return TFM_SUCCESS; - } - } -#endif /* !defined(TFM_PSA_API) */ - - /* If all else fails, check whether the region is in the non-secure - * memory - */ - if (check_address_range(p, s, NS_CODE_START, - NS_CODE_LIMIT+1-NS_CODE_START) == TFM_SUCCESS || - check_address_range(p, s, NS_DATA_START, - NS_DATA_LIMIT+1-NS_DATA_START) == TFM_SUCCESS) { - return TFM_SUCCESS; - } else { - return TFM_ERROR_GENERIC; - } -} - -enum tfm_status_e tfm_core_has_read_access_to_region(const void *p, size_t s, - uint32_t ns_caller, - uint32_t privileged) -{ - int flags = CMSE_MPU_READ; - - if (privileged == TFM_PARTITION_UNPRIVILEGED_MODE) { - flags |= CMSE_MPU_UNPRIV; - } - - if (ns_caller) { - flags |= CMSE_NONSECURE; - } - - return has_access_to_region(p, s, flags); -} - -enum tfm_status_e tfm_core_has_write_access_to_region(const void *p, size_t s, - uint32_t ns_caller, - uint32_t privileged) -{ - int flags = CMSE_MPU_READWRITE; - - if (privileged == TFM_PARTITION_UNPRIVILEGED_MODE) { - flags |= CMSE_MPU_UNPRIV; - } - - if (ns_caller) { - flags |= CMSE_NONSECURE; - } - - return has_access_to_region(p, s, flags); -} - void tfm_secure_api_error_handler(void) { ERROR_MSG("Security violation when calling secure API"); @@ -190,4 +59,3 @@ void tfm_secure_api_error_handler(void) ; } } - |