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 
13 #include "tee_agent.h"
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <pthread.h>
17 #include <signal.h>
18 #include <sys/ioctl.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <time.h>
22 #include <unistd.h>
23 #include "tee_ca_daemon.h"
24 #include "fs_work_agent.h"
25 #include "late_init_agent.h"
26 #include "misc_work_agent.h"
27 #include "secfile_load_agent.h"
28 #include "tc_ns_client.h"
29 #include "tee_load_dynamic_drv.h"
30 #include "tee_log.h"
31 #include "tcu_authentication.h"
32 
33 #ifdef LOG_TAG
34 #undef LOG_TAG
35 #endif
36 #define LOG_TAG "teecd"
37 
38 /* smc dev */
39 static int g_fsFd   = -1;
40 static int g_miscFd = -1;
41 
GetMiscFd(void)42 int GetMiscFd(void)
43 {
44     return g_miscFd;
45 }
46 
GetFsFd(void)47 int GetFsFd(void)
48 {
49     return g_fsFd;
50 }
51 
AgentInit(unsigned int id,void ** control)52 static int AgentInit(unsigned int id, void **control)
53 {
54     int ret;
55     struct AgentIoctlArgs args = { 0 };
56 
57     if (control == NULL) {
58         return -1;
59     }
60     int fd = open(TC_PRIVATE_DEV_NAME, O_RDWR);
61     if (fd < 0) {
62         tloge("open tee client dev failed, fd is %d\n", fd);
63         return -1;
64     }
65 
66     /* register agent */
67     args.id         = id;
68     args.bufferSize = TRANS_BUFF_SIZE;
69     ret             = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_REGISTER_AGENT, &args);
70     if (ret) {
71         (void)close(fd);
72         tloge("ioctl failed\n");
73         return -1;
74     }
75 
76     *control = args.buffer;
77     return fd;
78 }
79 
AgentExit(unsigned int id,int fd)80 static void AgentExit(unsigned int id, int fd)
81 {
82     int ret;
83 
84     if (fd == -1) {
85         return;
86     }
87 
88     ret = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_UNREGISTER_AGENT, id);
89     if (ret) {
90         tloge("ioctl failed\n");
91     }
92 
93     (void)close(fd);
94 }
95 
96 static struct SecStorageType *g_fsControl                = NULL;
97 static struct MiscControlType *g_miscControl             = NULL;
98 static struct SecAgentControlType *g_secLoadAgentControl = NULL;
99 
100 static int g_fsThreadFlag = 0;
101 
ProcessAgentInit(void)102 static int ProcessAgentInit(void)
103 {
104     int ret;
105     g_fsFd = AgentInit(AGENT_FS_ID, (void **)(&g_fsControl));
106     if (g_fsFd < 0) {
107         tloge("fs agent init failed\n");
108         g_fsThreadFlag = 0;
109     } else {
110         g_fsThreadFlag = 1;
111     }
112 
113     g_miscFd = AgentInit(AGENT_MISC_ID, (void **)(&g_miscControl));
114     if (g_miscFd < 0) {
115         tloge("misc agent init failed\n");
116         goto ERROR1;
117     }
118 
119     ret = AgentInit(SECFILE_LOAD_AGENT_ID, (void **)(&g_secLoadAgentControl));
120     if (ret < 0) {
121         tloge("secfile load agent init failed\n");
122         goto ERROR2;
123     }
124 
125     SetSecLoadAgentFd(ret);
126 
127     return 0;
128 ERROR2:
129     AgentExit(AGENT_MISC_ID, g_miscFd);
130     g_miscFd      = -1;
131     g_miscControl = NULL;
132 
133 ERROR1:
134     if (g_fsThreadFlag == 1) {
135         AgentExit(AGENT_FS_ID, g_fsFd);
136         g_fsFd         = -1;
137         g_fsControl    = NULL;
138         g_fsThreadFlag = 0;
139     }
140     return -1;
141 }
142 
ProcessAgentExit(void)143 static void ProcessAgentExit(void)
144 {
145     if (g_fsThreadFlag == 1) {
146         AgentExit(AGENT_FS_ID, g_fsFd);
147         g_fsFd      = -1;
148         g_fsControl = NULL;
149     }
150 
151     AgentExit(AGENT_MISC_ID, g_miscFd);
152     g_miscFd      = -1;
153     g_miscControl = NULL;
154 
155     AgentExit(SECFILE_LOAD_AGENT_ID, GetSecLoadAgentFd());
156     SetSecLoadAgentFd(-1);
157     g_secLoadAgentControl = NULL;
158 }
159 
SyncSysTimeToSecure(void)160 static int SyncSysTimeToSecure(void)
161 {
162     TC_NS_Time tcNsTime;
163     struct timeval timeVal;
164 
165     int ret = gettimeofday(&timeVal, NULL);
166     if (ret != 0) {
167         tloge("get system time failed ret=0x%x\n", ret);
168         return ret;
169     }
170     if (timeVal.tv_sec < 0xFFFFF) {
171         return -1;
172     }
173     tcNsTime.seconds = (uint32_t)timeVal.tv_sec;
174     tcNsTime.millis  = (uint32_t)timeVal.tv_usec / 1000;
175 
176     int fd = open(TC_PRIVATE_DEV_NAME, O_RDWR);
177     if (fd < 0) {
178         tloge("Failed to open %s: %d\n", TC_PRIVATE_DEV_NAME, errno);
179         return fd;
180     }
181     ret = ioctl(fd, (int)TC_NS_CLIENT_IOCTL_SYC_SYS_TIME, &tcNsTime);
182     if (ret != 0) {
183         tloge("failed to send sys time to teeos\n");
184     }
185 
186     close(fd);
187     return ret;
188 }
189 
TrySyncSysTimeToSecure(void)190 void TrySyncSysTimeToSecure(void)
191 {
192     static int syncSysTimed = 0;
193 
194     if (syncSysTimed == 0) {
195         int ret = SyncSysTimeToSecure();
196         if (ret != 0) {
197             tloge("failed to sync sys time to secure\n");
198         } else {
199             syncSysTimed = 1;
200         }
201     }
202 }
203 
main(void)204 int main(void)
205 {
206     pthread_t fsThread               = (pthread_t)-1;
207     pthread_t miscThread             = (pthread_t)-1;
208     pthread_t caDaemonThread         = (pthread_t)-1;
209     pthread_t lateInitThread         = (pthread_t)-1;
210     pthread_t secfileLoadAgentThread = (pthread_t)-1;
211 
212     /* Trans the xml file to tzdriver: */
213     (void)TcuAuthentication(HASH_TYPE_VENDOR);
214 
215     int ret = ProcessAgentInit();
216     if (ret) {
217         return ret;
218     }
219 
220     TrySyncSysTimeToSecure();
221 
222     LoadDynamicDir();
223 
224     (void)pthread_create(&caDaemonThread, NULL, CaServerWorkThread, NULL);
225 
226     SetFileNumLimit();
227 
228     if (g_fsThreadFlag == 1) {
229         (void)pthread_create(&fsThread, NULL, FsWorkThread, g_fsControl);
230     }
231 
232     (void)pthread_create(&miscThread, NULL, MiscWorkThread, g_miscControl);
233 
234     (void)pthread_create(&lateInitThread, NULL, InitLateWorkThread, NULL);
235     (void)pthread_create(&secfileLoadAgentThread, NULL, SecfileLoadAgentThread, g_secLoadAgentControl);
236 
237     if (g_fsThreadFlag == 1) {
238         (void)pthread_join(fsThread, NULL);
239     }
240     (void)pthread_join(miscThread, NULL);
241     (void)pthread_join(caDaemonThread, NULL);
242 
243     (void)pthread_join(lateInitThread, NULL);
244     (void)pthread_join(secfileLoadAgentThread, NULL);
245 
246     ProcessAgentExit();
247     return 0;
248 }
249