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