1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include "tee_init.h"
13
14 #include <securec.h>
15
16 #include <unistd.h>
17 #include "spawn_ext.h"
18 #include "tee_defines.h"
19 #include "tee_obj.h"
20 #include "tee_reserved_api.h"
21 #include "tee_log.h"
22 #include "tee_ext_api.h"
23 #include "tee_mem_mgmt_api.h"
24 #include "tee_ta2ta.h"
25
26 /* TLS support for running_info per session */
27 static pthread_key_t g_info_key;
28 static bool g_info_key_state = false;
29 /*
30 * For compatible reason, an old TA may not use the tls to set running info,
31 * we will use the global value.
32 */
33 static struct running_info g_running_info;
34
init_tls_running_info_key(void)35 static bool init_tls_running_info_key(void)
36 {
37 if (!g_info_key_state) {
38 if (pthread_key_create(&g_info_key, NULL) == 0)
39 g_info_key_state = true;
40 else
41 tloge("create info key failed\n");
42 }
43
44 return g_info_key_state;
45 }
46
47 /* It only affect running_info, ignore this error. */
tee_pre_init(int32_t init_build,const struct ta_init_msg * init_msg)48 void tee_pre_init(int32_t init_build, const struct ta_init_msg *init_msg)
49 {
50 struct running_info *info = NULL;
51
52 if ((init_build == 0) && (init_msg != NULL)) {
53 if (memcpy_s(&g_running_info.uuid, sizeof(g_running_info.uuid), &(init_msg->prop.uuid),
54 sizeof(init_msg->prop.uuid)) != EOK) {
55 tloge("copy data failed\n");
56 return;
57 }
58 }
59
60 if (!init_tls_running_info_key()) {
61 tloge("init tls running info key failed\n");
62 return;
63 }
64
65 info = TEE_Malloc(sizeof(*info), 0);
66 if (info == NULL) {
67 tloge("alloc info failed\n");
68 return;
69 }
70 info->session_id = 0;
71 (void)pthread_setspecific(g_info_key, info); /* only has one return value */
72
73 add_tls_info(info);
74 }
75
76 /* tee lib inititial, 1 TA's instance call 1 time only */
tee_init(const struct ta_init_msg * init_msg)77 TEE_Result tee_init(const struct ta_init_msg *init_msg)
78 {
79 if (init_msg == NULL)
80 return TEE_ERROR_BAD_PARAMETERS;
81
82 if (memcpy_s(&g_running_info.uuid, sizeof(g_running_info.uuid), &(init_msg->prop.uuid),
83 sizeof(init_msg->prop.uuid)) != EOK) {
84 tloge("copy data failed\n");
85 return TEE_ERROR_SECURITY;
86 }
87
88 /* Notice: there's one ipc with ssa in init_property */
89 init_property(init_msg->login_method, NULL, &init_msg->prop);
90 init_tee_internal_api();
91 tee_log_init(&init_msg->prop.uuid);
92 TEE_Result ret = tee_obj_init();
93 if (ret != TEE_SUCCESS) {
94 tloge("tee obj init failed\n");
95 return ret;
96 }
97
98 return TEE_SUCCESS;
99 }
100
tee_exit(void)101 void tee_exit(void)
102 {
103 /* for backward compatible */
104 }
105
tee_session_init(uint32_t session_id)106 void tee_session_init(uint32_t session_id)
107 {
108 add_session_cancel_state(session_id);
109 }
110
tee_session_exit(uint32_t session_id)111 void tee_session_exit(uint32_t session_id)
112 {
113 struct running_info *info = NULL;
114
115 del_session_cancel_state(session_id);
116
117 info = get_tls_running_info();
118 if (info != NULL) {
119 delete_tls_info(session_id);
120 info = NULL;
121 }
122 if (g_info_key_state)
123 (void)pthread_setspecific(g_info_key, NULL); /* only has one return value */
124 }
125
tee_init_context(uint32_t session_id,uint32_t dev_id)126 void tee_init_context(uint32_t session_id, uint32_t dev_id)
127 {
128 struct running_info *info = NULL;
129
130 info = get_tls_running_info();
131 if (info != NULL) {
132 info->dev_id = dev_id;
133 info->session_id = session_id;
134 }
135 }
136
get_current_dev_id(void)137 uint32_t get_current_dev_id(void)
138 {
139 struct running_info *info = NULL;
140
141 info = get_tls_running_info();
142 if (info != NULL)
143 return info->dev_id;
144 else
145 return INVALID_DEV_ID;
146 }
147
set_global_handle(uint32_t handle)148 void set_global_handle(uint32_t handle)
149 {
150 struct running_info *info = NULL;
151
152 info = get_tls_running_info();
153 if (info != NULL)
154 info->global_handle = handle;
155 }
156
157 /* TA's global variable can be modified by TA, So here Must return GLOBAL_HANDLE(0) */
get_global_handle(void)158 uint32_t get_global_handle(void)
159 {
160 return GLOBAL_HANDLE;
161 }
162
set_current_session_type(uint32_t session_type)163 void set_current_session_type(uint32_t session_type)
164 {
165 struct running_info *info = NULL;
166
167 info = get_tls_running_info();
168 if (info != NULL)
169 info->session_type = session_type;
170 }
171
get_tls_running_info(void)172 struct running_info *get_tls_running_info(void)
173 {
174 if (!g_info_key_state)
175 return &g_running_info;
176
177 return pthread_getspecific(g_info_key);
178 }
179
set_running_uuid(void)180 void set_running_uuid(void)
181 {
182 struct running_info *info = NULL;
183 spawn_uuid_t uuid = {0};
184 pid_t pid;
185
186 pid = getpid();
187 if (pid < 0) {
188 tloge("get pid is error\n");
189 return;
190 }
191
192 int32_t ret = getuuid(pid, &uuid);
193 if (ret < 0) {
194 tloge("get uuid is error\n");
195 return;
196 }
197
198 info = get_tls_running_info();
199 if (info != NULL)
200 info->uuid = uuid.uuid;
201 }
202
get_running_uuid(void)203 TEE_UUID *get_running_uuid(void)
204 {
205 return &g_running_info.uuid;
206 }
207