• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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