1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 */ 5 #include <compiler.h> 6 #include <config.h> 7 #include <malloc.h> 8 #include <tee_ta_api.h> 9 #include <tee_internal_api_extensions.h> 10 #include <trace.h> 11 #include <user_ta_header.h> 12 #include <user_ta_header_defines.h> 13 #include <utee_syscalls.h> 14 15 extern void *__stack_chk_guard; 16 17 int trace_level = TRACE_LEVEL; 18 19 const char trace_ext_prefix[] = "TA"; 20 21 #ifndef TA_VERSION 22 #define TA_VERSION "Undefined version" 23 #endif 24 25 #ifndef TA_DESCRIPTION 26 #define TA_DESCRIPTION "Undefined description" 27 #endif 28 29 /* exprted to user_ta_header.c, built within TA */ 30 struct utee_params; 31 32 #ifdef ARM32 33 #define _C_FUNCTION(name) name##_c 34 #else 35 #define _C_FUNCTION(name) name 36 #endif /* ARM32 */ 37 38 /* From libutee */ 39 TEE_Result __utee_entry(unsigned long func, unsigned long session_id, 40 struct utee_params *up, unsigned long cmd_id); 41 42 void __noreturn _C_FUNCTION(__ta_entry)(unsigned long func, 43 unsigned long session_id, 44 struct utee_params *up, 45 unsigned long cmd_id); 46 47 void __noreturn _C_FUNCTION(__ta_entry)(unsigned long func, 48 unsigned long session_id, 49 struct utee_params *up, 50 unsigned long cmd_id) 51 { 52 static bool stack_canary_inited; 53 TEE_Result res = TEE_ERROR_GENERIC; 54 55 if (IS_ENABLED(_CFG_TA_STACK_PROTECTOR) && !stack_canary_inited) { 56 uintptr_t canary = 0; 57 58 res = _utee_cryp_random_number_generate(&canary, 59 sizeof(canary)); 60 if (res != TEE_SUCCESS) 61 _utee_return(res); 62 63 /* Leave null byte in canary to prevent string base exploit */ 64 canary &= ~0xffUL; 65 66 __stack_chk_guard = (void *)canary; 67 stack_canary_inited = true; 68 } 69 70 res = __utee_entry(func, session_id, up, cmd_id); 71 72 #if defined(CFG_FTRACE_SUPPORT) 73 /* 74 * __ta_entry is the first TA API called from TEE core. As it being 75 * __noreturn API, we need to call ftrace_return in this API just 76 * before _utee_return syscall to get proper ftrace call graph. 77 */ 78 ftrace_return(); 79 #endif 80 81 _utee_return(res); 82 } 83 84 /* 85 * According to GP Internal API, TA_STACK_SIZE corresponds to the stack 86 * size used by the TA code itself and does not include stack space 87 * possibly used by the Trusted Core Framework. 88 * Hence, stack_size which is the size of the stack to use, 89 * must be enlarged 90 * It has been set to 2048 to include trace framework and invoke commands 91 */ 92 #define TA_FRAMEWORK_STACK_SIZE 2048 93 94 const struct ta_head ta_head __section(".ta_head") = { 95 /* UUID, unique to each TA */ 96 .uuid = TA_UUID, 97 /* 98 * According to GP Internal API, TA_FRAMEWORK_STACK_SIZE corresponds to 99 * the stack size used by the TA code itself and does not include stack 100 * space possibly used by the Trusted Core Framework. 101 * Hence, stack_size which is the size of the stack to use, 102 * must be enlarged 103 */ 104 .stack_size = TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE, 105 .flags = TA_FLAGS, 106 /* 107 * The TA entry doesn't go via this field any longer, to be able to 108 * reliably check that an old TA isn't loaded set this field to a 109 * fixed value. 110 */ 111 .depr_entry = UINT64_MAX, 112 }; 113 114 /* Keeping the heap in bss */ 115 #if TA_DATA_SIZE < MALLOC_INITIAL_POOL_MIN_SIZE 116 #error TA_DATA_SIZE too small 117 #endif 118 119 uint8_t ta_heap[TA_DATA_SIZE]; 120 const size_t ta_heap_size = sizeof(ta_heap); 121 122 #ifndef TA_NO_SHARE_DATA_SIZE 123 #define TA_NO_SHARE_DATA_SIZE 0 124 #endif 125 #if TA_NO_SHARE_DATA_SIZE && \ 126 TA_NO_SHARE_DATA_SIZE < MALLOC_INITIAL_POOL_MIN_SIZE 127 #error TA_NO_SHARE_DATA_SIZE too small 128 #endif 129 130 uint8_t __ta_no_share_heap[TA_NO_SHARE_DATA_SIZE]; 131 const size_t __ta_no_share_heap_size = sizeof(__ta_no_share_heap); 132 133 const struct user_ta_property ta_props[] = { 134 {TA_PROP_STR_SINGLE_INSTANCE, USER_TA_PROP_TYPE_BOOL, 135 &(const bool){(TA_FLAGS & TA_FLAG_SINGLE_INSTANCE) != 0}}, 136 137 {TA_PROP_STR_MULTI_SESSION, USER_TA_PROP_TYPE_BOOL, 138 &(const bool){(TA_FLAGS & TA_FLAG_MULTI_SESSION) != 0}}, 139 140 {TA_PROP_STR_KEEP_ALIVE, USER_TA_PROP_TYPE_BOOL, 141 &(const bool){(TA_FLAGS & TA_FLAG_INSTANCE_KEEP_ALIVE) != 0}}, 142 143 {TA_PROP_STR_DATA_SIZE, USER_TA_PROP_TYPE_U32, 144 &(const uint32_t){TA_DATA_SIZE}}, 145 146 {TA_PROP_STR_STACK_SIZE, USER_TA_PROP_TYPE_U32, 147 &(const uint32_t){TA_STACK_SIZE}}, 148 149 {TA_PROP_STR_VERSION, USER_TA_PROP_TYPE_STRING, 150 TA_VERSION}, 151 152 {TA_PROP_STR_DESCRIPTION, USER_TA_PROP_TYPE_STRING, 153 TA_DESCRIPTION}, 154 155 /* Only little-endian supported */ 156 {TA_PROP_STR_ENDIAN, USER_TA_PROP_TYPE_U32, &(const uint32_t){0}}, 157 158 {TA_PROP_STR_DOES_NOT_CLOSE_HANDLE_ON_CORRUPT_OBJECT, 159 USER_TA_PROP_TYPE_BOOL, 160 &(const bool){TA_FLAGS & TA_FLAG_DONT_CLOSE_HANDLE_ON_CORRUPT_OBJECT}}, 161 162 /* 163 * Extended propietary properties, name of properties must not begin with 164 * "gpd." 165 */ 166 #ifdef TA_CURRENT_TA_EXT_PROPERTIES 167 TA_CURRENT_TA_EXT_PROPERTIES 168 #endif 169 }; 170 171 const size_t ta_num_props = sizeof(ta_props) / sizeof(ta_props[0]); 172 173 #ifdef CFG_FTRACE_SUPPORT 174 struct __ftrace_info __ftrace_info = { 175 #ifdef __ILP32__ 176 .buf_start.ptr32 = { .lo = (uint32_t)&__ftrace_buf_start }, 177 .buf_end.ptr32 = { .lo = (uint32_t)__ftrace_buf_end }, 178 .ret_ptr.ptr32 = { .lo = (uint32_t)&__ftrace_return }, 179 #else 180 .buf_start.ptr64 = (uint64_t)&__ftrace_buf_start, 181 .buf_end.ptr64 = (uint64_t)__ftrace_buf_end, 182 .ret_ptr.ptr64 = (uint64_t)&__ftrace_return, 183 #endif 184 }; 185 #endif 186 187 int tahead_get_trace_level(void) 188 { 189 /* 190 * Store trace level in TA head structure, as ta_head.prop_tracelevel 191 */ 192 return TRACE_LEVEL; 193 } 194 195 #if __OPTEE_CORE_API_COMPAT_1_1 196 #undef TA_OpenSessionEntryPoint 197 #undef TA_InvokeCommandEntryPoint 198 #undef TEE_Param 199 TEE_Result TA_OpenSessionEntryPoint(uint32_t pt, 200 TEE_Param params[TEE_NUM_PARAMS], 201 void **sess_ctx) 202 { 203 return __ta_open_sess(pt, params, sess_ctx, 204 __GP11_TA_OpenSessionEntryPoint); 205 } 206 207 TEE_Result TA_InvokeCommandEntryPoint(void *sess_ctx, uint32_t cmd_id, 208 uint32_t pt, 209 TEE_Param params[TEE_NUM_PARAMS]) 210 { 211 return __ta_invoke_cmd(sess_ctx, cmd_id, pt, params, 212 __GP11_TA_InvokeCommandEntryPoint); 213 } 214 #endif 215