131b31015Sliushiwei // SPDX-License-Identifier: BSD-2-Clause
231b31015Sliushiwei /*
331b31015Sliushiwei * Copyright (c) 2014, STMicroelectronics International N.V.
431b31015Sliushiwei */
531b31015Sliushiwei #include <compiler.h>
631b31015Sliushiwei #include <config.h>
731b31015Sliushiwei #include <malloc.h>
831b31015Sliushiwei #include <tee_ta_api.h>
931b31015Sliushiwei #include <tee_internal_api_extensions.h>
1031b31015Sliushiwei #include <trace.h>
1131b31015Sliushiwei #include <user_ta_header.h>
1231b31015Sliushiwei #include <user_ta_header_defines.h>
1331b31015Sliushiwei #include <utee_syscalls.h>
1431b31015Sliushiwei
1531b31015Sliushiwei extern void *__stack_chk_guard;
1631b31015Sliushiwei
1731b31015Sliushiwei int trace_level = TRACE_LEVEL;
1831b31015Sliushiwei
1931b31015Sliushiwei const char trace_ext_prefix[] = "TA";
2031b31015Sliushiwei
2131b31015Sliushiwei #ifndef TA_VERSION
2231b31015Sliushiwei #define TA_VERSION "Undefined version"
2331b31015Sliushiwei #endif
2431b31015Sliushiwei
2531b31015Sliushiwei #ifndef TA_DESCRIPTION
2631b31015Sliushiwei #define TA_DESCRIPTION "Undefined description"
2731b31015Sliushiwei #endif
2831b31015Sliushiwei
2931b31015Sliushiwei /* exprted to user_ta_header.c, built within TA */
3031b31015Sliushiwei struct utee_params;
3131b31015Sliushiwei
3231b31015Sliushiwei #ifdef ARM32
3331b31015Sliushiwei #define _C_FUNCTION(name) name##_c
3431b31015Sliushiwei #else
3531b31015Sliushiwei #define _C_FUNCTION(name) name
3631b31015Sliushiwei #endif /* ARM32 */
3731b31015Sliushiwei
3831b31015Sliushiwei /* From libutee */
3931b31015Sliushiwei TEE_Result __utee_entry(unsigned long func, unsigned long session_id,
4031b31015Sliushiwei struct utee_params *up, unsigned long cmd_id);
4131b31015Sliushiwei
4219662e41SJerome Forissier void __noreturn __no_stack_protector
4319662e41SJerome Forissier _C_FUNCTION(__ta_entry)(unsigned long func,
4431b31015Sliushiwei unsigned long session_id,
4531b31015Sliushiwei struct utee_params *up,
4631b31015Sliushiwei unsigned long cmd_id);
4731b31015Sliushiwei
4819662e41SJerome Forissier void __noreturn __no_stack_protector
_C_FUNCTION(__ta_entry)4919662e41SJerome Forissier _C_FUNCTION(__ta_entry)(unsigned long func,
5031b31015Sliushiwei unsigned long session_id,
5131b31015Sliushiwei struct utee_params *up,
5231b31015Sliushiwei unsigned long cmd_id)
5331b31015Sliushiwei {
5431b31015Sliushiwei static bool stack_canary_inited;
5531b31015Sliushiwei TEE_Result res = TEE_ERROR_GENERIC;
5631b31015Sliushiwei
5731b31015Sliushiwei if (IS_ENABLED(_CFG_TA_STACK_PROTECTOR) && !stack_canary_inited) {
5831b31015Sliushiwei uintptr_t canary = 0;
5931b31015Sliushiwei
6031b31015Sliushiwei res = _utee_cryp_random_number_generate(&canary,
6131b31015Sliushiwei sizeof(canary));
6231b31015Sliushiwei if (res != TEE_SUCCESS)
6331b31015Sliushiwei _utee_return(res);
6431b31015Sliushiwei
6531b31015Sliushiwei /* Leave null byte in canary to prevent string base exploit */
6631b31015Sliushiwei canary &= ~0xffUL;
6731b31015Sliushiwei
6831b31015Sliushiwei __stack_chk_guard = (void *)canary;
6931b31015Sliushiwei stack_canary_inited = true;
7031b31015Sliushiwei }
7131b31015Sliushiwei
7231b31015Sliushiwei res = __utee_entry(func, session_id, up, cmd_id);
7331b31015Sliushiwei
7431b31015Sliushiwei #if defined(CFG_FTRACE_SUPPORT)
7531b31015Sliushiwei /*
7631b31015Sliushiwei * __ta_entry is the first TA API called from TEE core. As it being
7731b31015Sliushiwei * __noreturn API, we need to call ftrace_return in this API just
7831b31015Sliushiwei * before _utee_return syscall to get proper ftrace call graph.
7931b31015Sliushiwei */
8031b31015Sliushiwei ftrace_return();
8131b31015Sliushiwei #endif
8231b31015Sliushiwei
8331b31015Sliushiwei _utee_return(res);
8431b31015Sliushiwei }
8531b31015Sliushiwei
8631b31015Sliushiwei /*
8731b31015Sliushiwei * According to GP Internal API, TA_STACK_SIZE corresponds to the stack
8831b31015Sliushiwei * size used by the TA code itself and does not include stack space
8931b31015Sliushiwei * possibly used by the Trusted Core Framework.
9031b31015Sliushiwei * Hence, stack_size which is the size of the stack to use,
9131b31015Sliushiwei * must be enlarged
9231b31015Sliushiwei * It has been set to 2048 to include trace framework and invoke commands
9331b31015Sliushiwei */
9431b31015Sliushiwei #define TA_FRAMEWORK_STACK_SIZE 2048
9531b31015Sliushiwei
9631b31015Sliushiwei const struct ta_head ta_head __section(".ta_head") = {
9731b31015Sliushiwei /* UUID, unique to each TA */
9831b31015Sliushiwei .uuid = TA_UUID,
9931b31015Sliushiwei /*
10031b31015Sliushiwei * According to GP Internal API, TA_FRAMEWORK_STACK_SIZE corresponds to
10131b31015Sliushiwei * the stack size used by the TA code itself and does not include stack
10231b31015Sliushiwei * space possibly used by the Trusted Core Framework.
10331b31015Sliushiwei * Hence, stack_size which is the size of the stack to use,
10431b31015Sliushiwei * must be enlarged
10531b31015Sliushiwei */
10631b31015Sliushiwei .stack_size = TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
10731b31015Sliushiwei .flags = TA_FLAGS,
10831b31015Sliushiwei /*
10931b31015Sliushiwei * The TA entry doesn't go via this field any longer, to be able to
11031b31015Sliushiwei * reliably check that an old TA isn't loaded set this field to a
11131b31015Sliushiwei * fixed value.
11231b31015Sliushiwei */
11331b31015Sliushiwei .depr_entry = UINT64_MAX,
11431b31015Sliushiwei };
11531b31015Sliushiwei
11631b31015Sliushiwei /* Keeping the heap in bss */
11731b31015Sliushiwei #if TA_DATA_SIZE < MALLOC_INITIAL_POOL_MIN_SIZE
11831b31015Sliushiwei #error TA_DATA_SIZE too small
11931b31015Sliushiwei #endif
12031b31015Sliushiwei
12131b31015Sliushiwei uint8_t ta_heap[TA_DATA_SIZE];
12231b31015Sliushiwei const size_t ta_heap_size = sizeof(ta_heap);
12331b31015Sliushiwei
12431b31015Sliushiwei #ifndef TA_NO_SHARE_DATA_SIZE
12531b31015Sliushiwei #define TA_NO_SHARE_DATA_SIZE 0
12631b31015Sliushiwei #endif
12731b31015Sliushiwei #if TA_NO_SHARE_DATA_SIZE && \
12831b31015Sliushiwei TA_NO_SHARE_DATA_SIZE < MALLOC_INITIAL_POOL_MIN_SIZE
12931b31015Sliushiwei #error TA_NO_SHARE_DATA_SIZE too small
13031b31015Sliushiwei #endif
13131b31015Sliushiwei
13231b31015Sliushiwei uint8_t __ta_no_share_heap[TA_NO_SHARE_DATA_SIZE];
13331b31015Sliushiwei const size_t __ta_no_share_heap_size = sizeof(__ta_no_share_heap);
13431b31015Sliushiwei
13531b31015Sliushiwei const struct user_ta_property ta_props[] = {
13631b31015Sliushiwei {TA_PROP_STR_SINGLE_INSTANCE, USER_TA_PROP_TYPE_BOOL,
13731b31015Sliushiwei &(const bool){(TA_FLAGS & TA_FLAG_SINGLE_INSTANCE) != 0}},
13831b31015Sliushiwei
13931b31015Sliushiwei {TA_PROP_STR_MULTI_SESSION, USER_TA_PROP_TYPE_BOOL,
14031b31015Sliushiwei &(const bool){(TA_FLAGS & TA_FLAG_MULTI_SESSION) != 0}},
14131b31015Sliushiwei
14231b31015Sliushiwei {TA_PROP_STR_KEEP_ALIVE, USER_TA_PROP_TYPE_BOOL,
14331b31015Sliushiwei &(const bool){(TA_FLAGS & TA_FLAG_INSTANCE_KEEP_ALIVE) != 0}},
14431b31015Sliushiwei
145*941a58d7SJens Wiklander {TA_PROP_STR_KEEP_CRASHED, USER_TA_PROP_TYPE_BOOL,
146*941a58d7SJens Wiklander &(const bool){(TA_FLAGS & TA_FLAG_INSTANCE_KEEP_CRASHED) != 0}},
147*941a58d7SJens Wiklander
14831b31015Sliushiwei {TA_PROP_STR_DATA_SIZE, USER_TA_PROP_TYPE_U32,
14931b31015Sliushiwei &(const uint32_t){TA_DATA_SIZE}},
15031b31015Sliushiwei
15131b31015Sliushiwei {TA_PROP_STR_STACK_SIZE, USER_TA_PROP_TYPE_U32,
15231b31015Sliushiwei &(const uint32_t){TA_STACK_SIZE}},
15331b31015Sliushiwei
15431b31015Sliushiwei {TA_PROP_STR_VERSION, USER_TA_PROP_TYPE_STRING,
15531b31015Sliushiwei TA_VERSION},
15631b31015Sliushiwei
15731b31015Sliushiwei {TA_PROP_STR_DESCRIPTION, USER_TA_PROP_TYPE_STRING,
15831b31015Sliushiwei TA_DESCRIPTION},
15931b31015Sliushiwei
16031b31015Sliushiwei /* Only little-endian supported */
16131b31015Sliushiwei {TA_PROP_STR_ENDIAN, USER_TA_PROP_TYPE_U32, &(const uint32_t){0}},
16231b31015Sliushiwei
16331b31015Sliushiwei {TA_PROP_STR_DOES_NOT_CLOSE_HANDLE_ON_CORRUPT_OBJECT,
16431b31015Sliushiwei USER_TA_PROP_TYPE_BOOL,
16531b31015Sliushiwei &(const bool){TA_FLAGS & TA_FLAG_DONT_CLOSE_HANDLE_ON_CORRUPT_OBJECT}},
16631b31015Sliushiwei
16731b31015Sliushiwei /*
16831b31015Sliushiwei * Extended propietary properties, name of properties must not begin with
16931b31015Sliushiwei * "gpd."
17031b31015Sliushiwei */
17131b31015Sliushiwei #ifdef TA_CURRENT_TA_EXT_PROPERTIES
17231b31015Sliushiwei TA_CURRENT_TA_EXT_PROPERTIES
17331b31015Sliushiwei #endif
17431b31015Sliushiwei };
17531b31015Sliushiwei
17631b31015Sliushiwei const size_t ta_num_props = sizeof(ta_props) / sizeof(ta_props[0]);
17731b31015Sliushiwei
17831b31015Sliushiwei #ifdef CFG_FTRACE_SUPPORT
17931b31015Sliushiwei struct __ftrace_info __ftrace_info = {
18031b31015Sliushiwei #ifdef __ILP32__
18131b31015Sliushiwei .buf_start.ptr32 = { .lo = (uint32_t)&__ftrace_buf_start },
18231b31015Sliushiwei .buf_end.ptr32 = { .lo = (uint32_t)__ftrace_buf_end },
18331b31015Sliushiwei .ret_ptr.ptr32 = { .lo = (uint32_t)&__ftrace_return },
18431b31015Sliushiwei #else
18531b31015Sliushiwei .buf_start.ptr64 = (uint64_t)&__ftrace_buf_start,
18631b31015Sliushiwei .buf_end.ptr64 = (uint64_t)__ftrace_buf_end,
18731b31015Sliushiwei .ret_ptr.ptr64 = (uint64_t)&__ftrace_return,
18831b31015Sliushiwei #endif
18931b31015Sliushiwei };
19031b31015Sliushiwei #endif
19131b31015Sliushiwei
tahead_get_trace_level(void)19231b31015Sliushiwei int tahead_get_trace_level(void)
19331b31015Sliushiwei {
19431b31015Sliushiwei /*
19531b31015Sliushiwei * Store trace level in TA head structure, as ta_head.prop_tracelevel
19631b31015Sliushiwei */
19731b31015Sliushiwei return TRACE_LEVEL;
19831b31015Sliushiwei }
19931b31015Sliushiwei
20031b31015Sliushiwei #if __OPTEE_CORE_API_COMPAT_1_1
20131b31015Sliushiwei #undef TA_OpenSessionEntryPoint
20231b31015Sliushiwei #undef TA_InvokeCommandEntryPoint
20331b31015Sliushiwei #undef TEE_Param
TA_OpenSessionEntryPoint(uint32_t pt,TEE_Param params[TEE_NUM_PARAMS],void ** sess_ctx)20431b31015Sliushiwei TEE_Result TA_OpenSessionEntryPoint(uint32_t pt,
20531b31015Sliushiwei TEE_Param params[TEE_NUM_PARAMS],
20631b31015Sliushiwei void **sess_ctx)
20731b31015Sliushiwei {
20831b31015Sliushiwei return __ta_open_sess(pt, params, sess_ctx,
20931b31015Sliushiwei __GP11_TA_OpenSessionEntryPoint);
21031b31015Sliushiwei }
21131b31015Sliushiwei
TA_InvokeCommandEntryPoint(void * sess_ctx,uint32_t cmd_id,uint32_t pt,TEE_Param params[TEE_NUM_PARAMS])21231b31015Sliushiwei TEE_Result TA_InvokeCommandEntryPoint(void *sess_ctx, uint32_t cmd_id,
21331b31015Sliushiwei uint32_t pt,
21431b31015Sliushiwei TEE_Param params[TEE_NUM_PARAMS])
21531b31015Sliushiwei {
21631b31015Sliushiwei return __ta_invoke_cmd(sess_ctx, cmd_id, pt, params,
21731b31015Sliushiwei __GP11_TA_InvokeCommandEntryPoint);
21831b31015Sliushiwei }
21931b31015Sliushiwei #endif
220