• 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 "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