xref: /optee_os/ta/user_ta_header.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
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