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
_C_FUNCTION(__ta_entry)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
tahead_get_trace_level(void)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
TA_OpenSessionEntryPoint(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS],void ** sess_ctx)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
TA_InvokeCommandEntryPoint(void * sess_ctx,uint32_t cmd_id,uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])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