mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/tfm_handler.c@1:9db0e321a9f4, 2019-12-31 (annotated)
- Committer:
- kenjiArai
- Date:
- Tue Dec 31 06:02:27 2019 +0000
- Revision:
- 1:9db0e321a9f4
- Parent:
- 0:5b88d5760320
updated based on mbed-os5.15.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 0:5b88d5760320 | 1 | /* |
kenjiArai | 0:5b88d5760320 | 2 | * Copyright (c) 2017-2019, Arm Limited. All rights reserved. |
kenjiArai | 0:5b88d5760320 | 3 | * |
kenjiArai | 0:5b88d5760320 | 4 | * SPDX-License-Identifier: BSD-3-Clause |
kenjiArai | 0:5b88d5760320 | 5 | * |
kenjiArai | 0:5b88d5760320 | 6 | */ |
kenjiArai | 0:5b88d5760320 | 7 | |
kenjiArai | 0:5b88d5760320 | 8 | #include <stdio.h> |
kenjiArai | 0:5b88d5760320 | 9 | #include <string.h> |
kenjiArai | 0:5b88d5760320 | 10 | |
kenjiArai | 0:5b88d5760320 | 11 | #include "secure_utilities.h" |
kenjiArai | 0:5b88d5760320 | 12 | #include "tfm_svc.h" |
kenjiArai | 0:5b88d5760320 | 13 | #include "tfm_secure_api.h" |
kenjiArai | 0:5b88d5760320 | 14 | #include "region_defs.h" |
kenjiArai | 0:5b88d5760320 | 15 | #include "tfm_api.h" |
kenjiArai | 0:5b88d5760320 | 16 | #include "tfm_internal.h" |
kenjiArai | 0:5b88d5760320 | 17 | #include "tfm_memory_utils.h" |
kenjiArai | 0:5b88d5760320 | 18 | #ifdef TFM_PSA_API |
kenjiArai | 0:5b88d5760320 | 19 | #include <stdbool.h> |
kenjiArai | 0:5b88d5760320 | 20 | #include "tfm_svcalls.h" |
kenjiArai | 0:5b88d5760320 | 21 | #endif |
kenjiArai | 0:5b88d5760320 | 22 | |
kenjiArai | 0:5b88d5760320 | 23 | /* This SVC handler is called when a secure partition requests access to a |
kenjiArai | 0:5b88d5760320 | 24 | * buffer area |
kenjiArai | 0:5b88d5760320 | 25 | */ |
kenjiArai | 0:5b88d5760320 | 26 | extern int32_t tfm_core_set_buffer_area_handler(const uint32_t args[]); |
kenjiArai | 0:5b88d5760320 | 27 | #ifdef TFM_PSA_API |
kenjiArai | 0:5b88d5760320 | 28 | extern void tfm_psa_ipc_request_handler(const uint32_t svc_args[]); |
kenjiArai | 0:5b88d5760320 | 29 | #endif |
kenjiArai | 0:5b88d5760320 | 30 | |
kenjiArai | 0:5b88d5760320 | 31 | struct tfm_fault_context_s { |
kenjiArai | 0:5b88d5760320 | 32 | uint32_t R0; |
kenjiArai | 0:5b88d5760320 | 33 | uint32_t R1; |
kenjiArai | 0:5b88d5760320 | 34 | uint32_t R2; |
kenjiArai | 0:5b88d5760320 | 35 | uint32_t R3; |
kenjiArai | 0:5b88d5760320 | 36 | uint32_t R12; |
kenjiArai | 0:5b88d5760320 | 37 | uint32_t LR; |
kenjiArai | 0:5b88d5760320 | 38 | uint32_t ReturnAddress; |
kenjiArai | 0:5b88d5760320 | 39 | uint32_t RETPSR; |
kenjiArai | 0:5b88d5760320 | 40 | } tfm_fault_context; |
kenjiArai | 0:5b88d5760320 | 41 | |
kenjiArai | 0:5b88d5760320 | 42 | #if defined(__ARM_ARCH_8M_MAIN__) |
kenjiArai | 0:5b88d5760320 | 43 | /** |
kenjiArai | 0:5b88d5760320 | 44 | * \brief Overwrites default Secure fault handler. |
kenjiArai | 0:5b88d5760320 | 45 | */ |
kenjiArai | 0:5b88d5760320 | 46 | void SecureFault_Handler(void) |
kenjiArai | 0:5b88d5760320 | 47 | { |
kenjiArai | 0:5b88d5760320 | 48 | /* figure out context from which we landed in fault handler */ |
kenjiArai | 0:5b88d5760320 | 49 | uint32_t lr = __get_LR(); |
kenjiArai | 0:5b88d5760320 | 50 | uint32_t sp; |
kenjiArai | 0:5b88d5760320 | 51 | |
kenjiArai | 0:5b88d5760320 | 52 | if (lr & EXC_RETURN_SECURE_STACK) { |
kenjiArai | 0:5b88d5760320 | 53 | if (lr & EXC_RETURN_STACK_PROCESS) { |
kenjiArai | 0:5b88d5760320 | 54 | sp = __get_PSP(); |
kenjiArai | 0:5b88d5760320 | 55 | } else { |
kenjiArai | 0:5b88d5760320 | 56 | sp = __get_MSP(); |
kenjiArai | 0:5b88d5760320 | 57 | } |
kenjiArai | 0:5b88d5760320 | 58 | } else { |
kenjiArai | 0:5b88d5760320 | 59 | if (lr & EXC_RETURN_STACK_PROCESS) { |
kenjiArai | 0:5b88d5760320 | 60 | sp = __TZ_get_PSP_NS(); |
kenjiArai | 0:5b88d5760320 | 61 | } else { |
kenjiArai | 0:5b88d5760320 | 62 | sp = __TZ_get_MSP_NS(); |
kenjiArai | 0:5b88d5760320 | 63 | } |
kenjiArai | 0:5b88d5760320 | 64 | } |
kenjiArai | 0:5b88d5760320 | 65 | |
kenjiArai | 0:5b88d5760320 | 66 | /* Only save the context if sp is valid */ |
kenjiArai | 0:5b88d5760320 | 67 | if ((sp >= S_DATA_START && |
kenjiArai | 0:5b88d5760320 | 68 | sp <= (S_DATA_LIMIT - sizeof(tfm_fault_context)) + 1) || |
kenjiArai | 0:5b88d5760320 | 69 | (sp >= NS_DATA_START && |
kenjiArai | 0:5b88d5760320 | 70 | sp <= (NS_DATA_LIMIT - sizeof(tfm_fault_context)) + 1)) { |
kenjiArai | 0:5b88d5760320 | 71 | tfm_memcpy(&tfm_fault_context, |
kenjiArai | 0:5b88d5760320 | 72 | (const void *)sp, |
kenjiArai | 0:5b88d5760320 | 73 | sizeof(tfm_fault_context)); |
kenjiArai | 0:5b88d5760320 | 74 | } |
kenjiArai | 0:5b88d5760320 | 75 | |
kenjiArai | 0:5b88d5760320 | 76 | LOG_MSG("Oops... Secure fault!!! You're not going anywhere!"); |
kenjiArai | 0:5b88d5760320 | 77 | while (1) { |
kenjiArai | 0:5b88d5760320 | 78 | ; |
kenjiArai | 0:5b88d5760320 | 79 | } |
kenjiArai | 0:5b88d5760320 | 80 | } |
kenjiArai | 0:5b88d5760320 | 81 | #elif defined(__ARM_ARCH_8M_BASE__) |
kenjiArai | 0:5b88d5760320 | 82 | /** |
kenjiArai | 0:5b88d5760320 | 83 | * \brief Overwrites default Hard fault handler. |
kenjiArai | 0:5b88d5760320 | 84 | * |
kenjiArai | 0:5b88d5760320 | 85 | * In case of a baseline implementation fault conditions that would generate a |
kenjiArai | 0:5b88d5760320 | 86 | * SecureFault in a mainline implementation instead generate a Secure HardFault. |
kenjiArai | 0:5b88d5760320 | 87 | */ |
kenjiArai | 0:5b88d5760320 | 88 | void HardFault_Handler(void) |
kenjiArai | 0:5b88d5760320 | 89 | { |
kenjiArai | 0:5b88d5760320 | 90 | /* In a baseline implementation there is no way, to find out whether this is |
kenjiArai | 0:5b88d5760320 | 91 | * a hard fault triggered directly, or another fault that has been |
kenjiArai | 0:5b88d5760320 | 92 | * escalated. |
kenjiArai | 0:5b88d5760320 | 93 | */ |
kenjiArai | 0:5b88d5760320 | 94 | while (1) { |
kenjiArai | 0:5b88d5760320 | 95 | ; |
kenjiArai | 0:5b88d5760320 | 96 | } |
kenjiArai | 0:5b88d5760320 | 97 | } |
kenjiArai | 0:5b88d5760320 | 98 | #else |
kenjiArai | 0:5b88d5760320 | 99 | #error "Unsupported ARM Architecture." |
kenjiArai | 0:5b88d5760320 | 100 | #endif |
kenjiArai | 0:5b88d5760320 | 101 | |
kenjiArai | 0:5b88d5760320 | 102 | #if defined(__ARM_ARCH_8M_MAIN__) |
kenjiArai | 0:5b88d5760320 | 103 | __attribute__((naked)) void SVC_Handler(void) |
kenjiArai | 0:5b88d5760320 | 104 | { |
kenjiArai | 0:5b88d5760320 | 105 | __ASM volatile( |
kenjiArai | 0:5b88d5760320 | 106 | "TST lr, #4\n" /* Check store SP in thread mode to r0 */ |
kenjiArai | 0:5b88d5760320 | 107 | "IT EQ\n" |
kenjiArai | 0:5b88d5760320 | 108 | "BXEQ lr\n" |
kenjiArai | 0:5b88d5760320 | 109 | "MRS r0, PSP\n" |
kenjiArai | 0:5b88d5760320 | 110 | "MOV r1, lr\n" |
kenjiArai | 0:5b88d5760320 | 111 | "BL SVCHandler_main\n" |
kenjiArai | 0:5b88d5760320 | 112 | "BX r0\n" |
kenjiArai | 0:5b88d5760320 | 113 | ); |
kenjiArai | 0:5b88d5760320 | 114 | } |
kenjiArai | 0:5b88d5760320 | 115 | #elif defined(__ARM_ARCH_8M_BASE__) |
kenjiArai | 0:5b88d5760320 | 116 | __attribute__((naked)) void SVC_Handler(void) |
kenjiArai | 0:5b88d5760320 | 117 | { |
kenjiArai | 0:5b88d5760320 | 118 | __ASM volatile( |
kenjiArai | 0:5b88d5760320 | 119 | ".syntax unified\n" |
kenjiArai | 0:5b88d5760320 | 120 | "MOVS r0, #4\n" /* Check store SP in thread mode to r0 */ |
kenjiArai | 0:5b88d5760320 | 121 | "MOV r1, lr\n" |
kenjiArai | 0:5b88d5760320 | 122 | "TST r0, r1\n" |
kenjiArai | 0:5b88d5760320 | 123 | "BEQ handler\n" |
kenjiArai | 0:5b88d5760320 | 124 | "MRS r0, PSP\n" /* Coming from thread mode */ |
kenjiArai | 0:5b88d5760320 | 125 | "B sp_stored\n" |
kenjiArai | 0:5b88d5760320 | 126 | "handler:\n" |
kenjiArai | 0:5b88d5760320 | 127 | "BX lr\n" /* Coming from handler mode */ |
kenjiArai | 0:5b88d5760320 | 128 | "sp_stored:\n" |
kenjiArai | 0:5b88d5760320 | 129 | "MOV r1, lr\n" |
kenjiArai | 0:5b88d5760320 | 130 | "BL SVCHandler_main\n" |
kenjiArai | 0:5b88d5760320 | 131 | "BX r0\n" |
kenjiArai | 0:5b88d5760320 | 132 | ); |
kenjiArai | 0:5b88d5760320 | 133 | } |
kenjiArai | 0:5b88d5760320 | 134 | #else |
kenjiArai | 0:5b88d5760320 | 135 | #error "Unsupported ARM Architecture." |
kenjiArai | 0:5b88d5760320 | 136 | #endif |
kenjiArai | 0:5b88d5760320 | 137 | |
kenjiArai | 0:5b88d5760320 | 138 | uint32_t SVCHandler_main(uint32_t *svc_args, uint32_t lr) |
kenjiArai | 0:5b88d5760320 | 139 | { |
kenjiArai | 0:5b88d5760320 | 140 | uint8_t svc_number; |
kenjiArai | 0:5b88d5760320 | 141 | /* |
kenjiArai | 0:5b88d5760320 | 142 | * Stack contains: |
kenjiArai | 0:5b88d5760320 | 143 | * r0, r1, r2, r3, r12, r14 (lr), the return address and xPSR |
kenjiArai | 0:5b88d5760320 | 144 | * First argument (r0) is svc_args[0] |
kenjiArai | 0:5b88d5760320 | 145 | */ |
kenjiArai | 0:5b88d5760320 | 146 | if (lr & EXC_RETURN_SECURE_STACK) { |
kenjiArai | 0:5b88d5760320 | 147 | /* SV called directly from secure context. Check instruction for |
kenjiArai | 0:5b88d5760320 | 148 | * svc_number |
kenjiArai | 0:5b88d5760320 | 149 | */ |
kenjiArai | 0:5b88d5760320 | 150 | svc_number = ((uint8_t *)svc_args[6])[-2]; |
kenjiArai | 0:5b88d5760320 | 151 | } else { |
kenjiArai | 0:5b88d5760320 | 152 | /* Secure SV executing with NS return. |
kenjiArai | 0:5b88d5760320 | 153 | * NS cannot directly trigger S SVC so this should not happen |
kenjiArai | 0:5b88d5760320 | 154 | * FixMe: check for security implications |
kenjiArai | 0:5b88d5760320 | 155 | */ |
kenjiArai | 0:5b88d5760320 | 156 | return lr; |
kenjiArai | 0:5b88d5760320 | 157 | } |
kenjiArai | 0:5b88d5760320 | 158 | switch (svc_number) { |
kenjiArai | 0:5b88d5760320 | 159 | #ifdef TFM_PSA_API |
kenjiArai | 0:5b88d5760320 | 160 | case TFM_SVC_IPC_REQUEST: |
kenjiArai | 0:5b88d5760320 | 161 | tfm_psa_ipc_request_handler(svc_args); |
kenjiArai | 0:5b88d5760320 | 162 | break; |
kenjiArai | 0:5b88d5760320 | 163 | case TFM_SVC_SCHEDULE: |
kenjiArai | 0:5b88d5760320 | 164 | case TFM_SVC_EXIT_THRD: |
kenjiArai | 0:5b88d5760320 | 165 | case TFM_SVC_PSA_FRAMEWORK_VERSION: |
kenjiArai | 0:5b88d5760320 | 166 | case TFM_SVC_PSA_VERSION: |
kenjiArai | 0:5b88d5760320 | 167 | case TFM_SVC_PSA_CONNECT: |
kenjiArai | 0:5b88d5760320 | 168 | case TFM_SVC_PSA_CALL: |
kenjiArai | 0:5b88d5760320 | 169 | case TFM_SVC_PSA_CLOSE: |
kenjiArai | 0:5b88d5760320 | 170 | case TFM_SVC_PSA_WAIT: |
kenjiArai | 0:5b88d5760320 | 171 | case TFM_SVC_PSA_GET: |
kenjiArai | 0:5b88d5760320 | 172 | case TFM_SVC_PSA_SET_RHANDLE: |
kenjiArai | 0:5b88d5760320 | 173 | case TFM_SVC_PSA_READ: |
kenjiArai | 0:5b88d5760320 | 174 | case TFM_SVC_PSA_SKIP: |
kenjiArai | 0:5b88d5760320 | 175 | case TFM_SVC_PSA_WRITE: |
kenjiArai | 0:5b88d5760320 | 176 | case TFM_SVC_PSA_REPLY: |
kenjiArai | 0:5b88d5760320 | 177 | case TFM_SVC_PSA_NOTIFY: |
kenjiArai | 0:5b88d5760320 | 178 | case TFM_SVC_PSA_CLEAR: |
kenjiArai | 0:5b88d5760320 | 179 | case TFM_SVC_PSA_EOI: |
kenjiArai | 0:5b88d5760320 | 180 | svc_args[0] = SVC_Handler_IPC(svc_number, svc_args, lr); |
kenjiArai | 0:5b88d5760320 | 181 | break; |
kenjiArai | 0:5b88d5760320 | 182 | #else |
kenjiArai | 0:5b88d5760320 | 183 | case TFM_SVC_SFN_REQUEST: |
kenjiArai | 0:5b88d5760320 | 184 | lr = tfm_core_partition_request_svc_handler(svc_args, lr); |
kenjiArai | 0:5b88d5760320 | 185 | break; |
kenjiArai | 0:5b88d5760320 | 186 | case TFM_SVC_SFN_RETURN: |
kenjiArai | 0:5b88d5760320 | 187 | lr = tfm_core_partition_return_handler(lr); |
kenjiArai | 0:5b88d5760320 | 188 | break; |
kenjiArai | 0:5b88d5760320 | 189 | case TFM_SVC_VALIDATE_SECURE_CALLER: |
kenjiArai | 0:5b88d5760320 | 190 | tfm_core_validate_secure_caller_handler(svc_args); |
kenjiArai | 0:5b88d5760320 | 191 | break; |
kenjiArai | 0:5b88d5760320 | 192 | case TFM_SVC_GET_CALLER_CLIENT_ID: |
kenjiArai | 0:5b88d5760320 | 193 | tfm_core_get_caller_client_id_handler(svc_args); |
kenjiArai | 0:5b88d5760320 | 194 | break; |
kenjiArai | 0:5b88d5760320 | 195 | case TFM_SVC_SPM_REQUEST: |
kenjiArai | 0:5b88d5760320 | 196 | tfm_core_spm_request_handler((struct tfm_exc_stack_t *)svc_args); |
kenjiArai | 0:5b88d5760320 | 197 | break; |
kenjiArai | 0:5b88d5760320 | 198 | case TFM_SVC_MEMORY_CHECK: |
kenjiArai | 0:5b88d5760320 | 199 | tfm_core_memory_permission_check_handler(svc_args); |
kenjiArai | 0:5b88d5760320 | 200 | break; |
kenjiArai | 0:5b88d5760320 | 201 | case TFM_SVC_SET_SHARE_AREA: |
kenjiArai | 0:5b88d5760320 | 202 | tfm_core_set_buffer_area_handler(svc_args); |
kenjiArai | 0:5b88d5760320 | 203 | break; |
kenjiArai | 0:5b88d5760320 | 204 | #endif |
kenjiArai | 0:5b88d5760320 | 205 | case TFM_SVC_PRINT: |
kenjiArai | 0:5b88d5760320 | 206 | printf("\e[1;34m[Sec Thread] %s\e[0m\r\n", (char *)svc_args[0]); |
kenjiArai | 0:5b88d5760320 | 207 | break; |
kenjiArai | 0:5b88d5760320 | 208 | case TFM_SVC_GET_BOOT_DATA: |
kenjiArai | 0:5b88d5760320 | 209 | tfm_core_get_boot_data_handler(svc_args); |
kenjiArai | 0:5b88d5760320 | 210 | break; |
kenjiArai | 0:5b88d5760320 | 211 | default: |
kenjiArai | 0:5b88d5760320 | 212 | LOG_MSG("Unknown SVC number requested!"); |
kenjiArai | 0:5b88d5760320 | 213 | break; |
kenjiArai | 0:5b88d5760320 | 214 | } |
kenjiArai | 0:5b88d5760320 | 215 | |
kenjiArai | 0:5b88d5760320 | 216 | return lr; |
kenjiArai | 0:5b88d5760320 | 217 | } |
kenjiArai | 0:5b88d5760320 | 218 | |
kenjiArai | 0:5b88d5760320 | 219 | void tfm_access_violation_handler(void) |
kenjiArai | 0:5b88d5760320 | 220 | { |
kenjiArai | 0:5b88d5760320 | 221 | while (1) { |
kenjiArai | 0:5b88d5760320 | 222 | ; |
kenjiArai | 0:5b88d5760320 | 223 | } |
kenjiArai | 0:5b88d5760320 | 224 | } |