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 */
39static int g_fsFd   = -1;
40static int g_miscFd = -1;
41
42int GetMiscFd(void)
43{
44    return g_miscFd;
45}
46
47int GetFsFd(void)
48{
49    return g_fsFd;
50}
51
52static 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
80static 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
96static struct SecStorageType *g_fsControl                = NULL;
97static struct MiscControlType *g_miscControl             = NULL;
98static struct SecAgentControlType *g_secLoadAgentControl = NULL;
99
100static int g_fsThreadFlag = 0;
101
102static 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;
128ERROR2:
129    AgentExit(AGENT_MISC_ID, g_miscFd);
130    g_miscFd      = -1;
131    g_miscControl = NULL;
132
133ERROR1:
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
143static 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
160static 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
190void 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
204int 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