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 "gtask_adapt.h"
13 #include <mem_ops.h>
14 #include <ipclib_hal.h>
15 #include "securec.h"
16 #include "init.h"
17 #include "tee_inner_uuid.h"
18 #include "service_manager.h"
19
get_ta_info(uint32_t task_id,bool * ta_64bit,TEE_UUID * uuid)20 int get_ta_info(uint32_t task_id, bool *ta_64bit, TEE_UUID *uuid)
21 {
22 struct session_struct *sess = NULL;
23 struct service_struct *serv = NULL;
24 TEE_UUID gtask_uuid = TEE_SERVICE_GLOBAL;
25
26 if (task_id == 0) {
27 /* gtask */
28 if (ta_64bit != NULL)
29 #ifdef __aarch64__
30 *ta_64bit = true;
31 #else
32 *ta_64bit = false;
33 #endif
34 if (uuid != NULL)
35 *uuid = gtask_uuid;
36 return 0;
37 }
38
39 if (!find_task(task_id, &serv, &sess)) {
40 tloge("cannot find task_id:%u\n", task_id);
41 return -1;
42 }
43
44 if (uuid != NULL)
45 *uuid = serv->property.uuid;
46
47 if (ta_64bit != NULL) {
48 if (serv->ta_64bit) {
49 *ta_64bit = true; /* TA is 64 bit */
50 } else {
51 *ta_64bit = false; /* TA is 32 bit */
52 }
53 }
54
55 if (ta_64bit != NULL)
56 tlogd("taskid:%d name:%s 64bit:%d\n", task_id, serv->name, *ta_64bit);
57
58 return 0;
59 }
60
ta_to_global_msg_len(bool ta_is_64)61 static uint32_t ta_to_global_msg_len(bool ta_is_64)
62 {
63 if (ta_is_64) {
64 return sizeof(struct ta_to_global_msg_64);
65 } else {
66 return sizeof(struct ta_to_global_msg_32);
67 }
68 }
69
convert_ta2gtask_msg_handle(const uint8_t * msg_buf,bool ta_is_64,ta_to_global_msg * msg)70 static int convert_ta2gtask_msg_handle(const uint8_t *msg_buf, bool ta_is_64, ta_to_global_msg *msg)
71 {
72 const struct ta_to_global_msg_32 *msg_32 = NULL;
73
74 if (!ta_is_64) {
75 /* TA is 32 bit */
76 msg_32 = (const struct ta_to_global_msg_32 *)(uintptr_t)msg_buf;
77 msg->ret = msg_32->ret;
78 msg->agent_id = msg_32->agent_id;
79 msg->session_context = (uint64_t)(msg_32->session_context);
80 msg->ta2ta_from_taskid = msg_32->ta2ta_from_taskid;
81 } else {
82 /* TA is 64 bit */
83 errno_t rc = memcpy_s(msg, sizeof(*msg), msg_buf, sizeof(struct ta_to_global_msg_64));
84 if (rc != EOK) {
85 tloge("[error]memcpy_s failed, rc=%d, line:%d.\n", rc, __LINE__);
86 return -1;
87 }
88 }
89
90 return 0;
91 }
92
93 /* struct ta_to_global_msg */
convert_ta2gtask_msg(const uint8_t * msg_buf,uint32_t msg_size,uint32_t taskid,ta_to_global_msg * msg)94 int convert_ta2gtask_msg(const uint8_t *msg_buf, uint32_t msg_size, uint32_t taskid, ta_to_global_msg *msg)
95 {
96 bool ta_is_64 = false;
97 uint32_t ta_msg_size;
98
99 if ((msg_buf == NULL) || (msg == NULL)) {
100 tloge("msg buf is invalid\n");
101 return -1;
102 }
103
104 if (get_ta_info(taskid, &ta_is_64, NULL) != 0) {
105 tloge("get ta type failed\n");
106 return -1;
107 }
108
109 ta_msg_size = ta_to_global_msg_len(ta_is_64);
110 if (msg_size < ta_msg_size) {
111 tloge("invalid msg size.\n");
112 return -1;
113 }
114
115 return convert_ta2gtask_msg_handle(msg_buf, ta_is_64, msg);
116 }
117
118 /* struct global_to_ta_msg */
send_global2ta_msg_handle(const global_to_ta_msg * msg,bool ta_is_64,uint32_t cmd,uint32_t taskid)119 static uint32_t send_global2ta_msg_handle(const global_to_ta_msg *msg, bool ta_is_64, uint32_t cmd, uint32_t taskid)
120 {
121 if (!ta_is_64) {
122 /* TA is 32 bit */
123 struct global_to_ta_msg_32 msg_32 = { 0 };
124
125 msg_32.ret = msg->ret;
126 msg_32.session_id = msg->session_id;
127 msg_32.session_type = msg->session_type;
128 msg_32.cmd_id = msg->cmd_id;
129 msg_32.param_type = msg->param_type;
130 msg_32.params = (uint32_t)msg->params;
131 msg_32.session_context = (uint32_t)msg->session_context;
132 msg_32.dev_id = msg->dev_id;
133 msg_32.first_session = msg->first_session;
134 msg_32.last_session = msg->last_session;
135 msg_32.started = msg->started;
136 msg_32.stack_size = msg->stack_size;
137 return ipc_msg_snd(cmd, taskid, &msg_32, sizeof(msg_32));
138 }
139
140 /* TA is 64 bit */
141 return ipc_msg_snd(cmd, taskid, msg, sizeof(*msg));
142 }
143
144 /* struct global_to_ta_msg */
send_global2ta_msg(const global_to_ta_msg * msg,uint32_t cmd,uint32_t taskid,const bool * ta_64bit)145 TEE_Result send_global2ta_msg(const global_to_ta_msg *msg, uint32_t cmd, uint32_t taskid, const bool *ta_64bit)
146 {
147 bool ta_is_64 = false;
148
149 if (msg == NULL) {
150 tloge("msg is invalid\n");
151 return TEE_ERROR_BAD_PARAMETERS;
152 }
153
154 if (ta_64bit == NULL) {
155 if (get_ta_info(taskid, &ta_is_64, NULL) != 0) {
156 tloge("get ta type failed\n");
157 return TEE_ERROR_GENERIC;
158 }
159 } else {
160 /* send to service_thread which not add to session list */
161 ta_is_64 = *ta_64bit;
162 }
163
164 uint32_t ret = send_global2ta_msg_handle(msg, ta_is_64, cmd, taskid);
165 if (ret != SRE_OK) {
166 tloge("send global to ta msg failed, ta taskid is 0x%x\n", taskid);
167 return TEE_ERROR_GENERIC;
168 }
169
170 return TEE_SUCCESS;
171 }
172
send_ta_init_msg(const ta_init_msg * msg,bool ta_is_64,uint32_t cmd,uint32_t taskid)173 TEE_Result send_ta_init_msg(const ta_init_msg *msg, bool ta_is_64, uint32_t cmd, uint32_t taskid)
174 {
175 uint32_t ret;
176
177 if (msg == NULL) {
178 tloge("msg is invalid\n");
179 return TEE_ERROR_GENERIC;
180 }
181
182 if (!ta_is_64) {
183 /* TA is 32 bit */
184 struct ta_init_msg_32 msg_32 = { 0 };
185
186 msg_32.fs_mem = (uint32_t)msg->fs_mem;
187 msg_32.misc_mem = (uint32_t)msg->misc_mem;
188 msg_32.prop.uuid = msg->prop.uuid;
189 msg_32.prop.stack_size = msg->prop.stack_size;
190 msg_32.prop.heap_size = msg->prop.heap_size;
191 msg_32.prop.single_instance = msg->prop.single_instance;
192 msg_32.prop.multi_session = msg->prop.multi_session;
193 msg_32.prop.keep_alive = msg->prop.keep_alive;
194 msg_32.prop.ssa_enum_enable = msg->prop.ssa_enum_enable;
195 msg_32.prop.other_buff = (uint32_t)msg->prop.other_buff;
196 msg_32.prop.other_len = msg->prop.other_len;
197 msg_32.login_method = msg->login_method;
198 msg_32.time_data = (uint32_t)msg->time_data;
199 msg_32.sys_time = msg->sys_time;
200 msg_32.rtc_time = msg->rtc_time;
201
202 ret = ipc_msg_snd(cmd, taskid, &msg_32, sizeof(msg_32));
203 } else {
204 /* TA is 64 bit */
205 ret = ipc_msg_snd(cmd, taskid, msg, sizeof(*msg));
206 }
207 if (ret != SRE_OK) {
208 tloge("send init msg to ta failed, task id is 0x%x\n", taskid);
209 return TEE_ERROR_GENERIC;
210 }
211 return TEE_SUCCESS;
212 }
213
get_tee_param_len(bool ta_is_64)214 uint32_t get_tee_param_len(bool ta_is_64)
215 {
216 if (ta_is_64) {
217 return sizeof(tee_param_64);
218 } else {
219 return sizeof(tee_param_32);
220 }
221 }
222
alloc_tee_param_for_ta(uint32_t taskid,struct pam_node * node)223 TEE_Result alloc_tee_param_for_ta(uint32_t taskid, struct pam_node *node)
224 {
225 bool ta_is_64 = false;
226 TEE_UUID ta_uuid = {0};
227
228 if (node == NULL) {
229 tloge("invalid node\n");
230 return TEE_ERROR_GENERIC;
231 }
232
233 if (get_ta_info(taskid, &ta_is_64, &ta_uuid) != 0) {
234 tloge("get ta type failed, taskid:%u\n", taskid);
235 return TEE_ERROR_GENERIC;
236 }
237
238 /* separate TEE_Param mem for ta */
239 void *p_for_ta = (void *)alloc_sharemem_aux(&ta_uuid, (get_tee_param_len(ta_is_64) * TEE_PARAM_NUM));
240 if (p_for_ta == NULL) {
241 tloge("p_for_ta alloc failed\n");
242 return TEE_ERROR_OUT_OF_MEMORY;
243 }
244 node->p_for_ta = p_for_ta;
245 node->param_type = ta_is_64;
246
247 return TEE_SUCCESS;
248 }
249