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