• 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_misc.h"
13 #include <securec.h>
14 #include <tee_log.h>
15 #include <ta_framework.h>
16 #include <tee_agent.h>
17 
18 #define BOOTLOADER_INFO_NUMS 68
19 #define TIME_STR_NUMS        30
20 #define ERROR_RET            (-1)
21 #define SUCC_RET             0
22 
23 enum misc_cmd_t {
24     SEC_GET_TIME = 1,
25 };
26 
27 struct misc_control_t {
28     enum misc_cmd_t cmd;
29     int32_t ret;
30     int32_t magic;
31     union args {
32         /* for bootloader lock status in nv partition */
33         struct {
34             uint8_t bootloader_info[BOOTLOADER_INFO_NUMS];
35         } nv_info;
36         struct {
37             uint32_t seconds;
38             uint32_t millis;
39             char time_str[TIME_STR_NUMS];
40         } get_time;
41     } args;
42 };
43 
44 static struct misc_control_t *g_trans_control = NULL; /* agent trans buffer */
45 
46 /* before call this function, you should lock the agent fist */
tee_get_misc_buffer(void)47 int32_t tee_get_misc_buffer(void)
48 {
49     TEE_Result ret;
50     void *buffer    = NULL;
51     uint32_t length = 0;
52 
53     ret = tee_get_agent_buffer(TEE_MISC_AGENT_ID, &buffer, &length);
54     if (ret != TEE_SUCCESS || (buffer == NULL) || (length < sizeof(*g_trans_control))) {
55         tloge("get misc agent buffer fail, ret=0x%x, length=%u\n", ret, length);
56         return ERROR_RET;
57     }
58 
59     g_trans_control        = buffer;
60     g_trans_control->magic = TEE_MISC_AGENT_ID;
61 
62     return SUCC_RET;
63 }
64 
handle_time_str(char * time_str,uint32_t time_str_len)65 static int32_t handle_time_str(char *time_str, uint32_t time_str_len)
66 {
67     errno_t rc;
68 
69     if (time_str == NULL)
70         return SUCC_RET;
71 
72     if (time_str_len < sizeof(g_trans_control->args.get_time.time_str)) {
73         tloge("time str len %u is invalid\n", time_str_len);
74         return ERROR_RET;
75     }
76 
77     rc = strncpy_s(time_str, (size_t)time_str_len, g_trans_control->args.get_time.time_str,
78                    sizeof(g_trans_control->args.get_time.time_str) - 1);
79     if (rc != EOK) {
80         tloge("str cpy failed\n");
81         return ERROR_RET;
82     }
83 
84     return SUCC_RET;
85 }
86 
get_time_of_data(uint32_t * seconds,uint32_t * millis,char * time_str,uint32_t time_str_len)87 int32_t get_time_of_data(uint32_t *seconds, uint32_t *millis, char *time_str, uint32_t time_str_len)
88 {
89     uint32_t sec;
90     uint32_t mil_sec;
91     int32_t ret = ERROR_RET;
92 
93     /* obtaion misc agent work lock */
94     TEE_Result result = tee_agent_lock(TEE_MISC_AGENT_ID);
95     if (result != TEE_SUCCESS) {
96         tloge("get misc agent lock failed\n");
97         return ERROR_RET;
98     }
99     if (tee_get_misc_buffer() != 0)
100         goto END;
101 
102     g_trans_control->magic = 0;
103     g_trans_control->cmd = SEC_GET_TIME;
104     /* call ns agent */
105     result = tee_send_agent_cmd(TEE_MISC_AGENT_ID);
106     if (result != TEE_SUCCESS) {
107         tloge("send cmd to misc agent failed\n");
108         goto END;
109     }
110     if (g_trans_control->magic != TEE_MISC_AGENT_ID) {
111         tloge("teecd was killed, just return error\n");
112         g_trans_control->magic = 0;
113         goto END;
114     }
115 
116     if (g_trans_control->ret == 0) {
117         sec     = g_trans_control->args.get_time.seconds;
118         mil_sec = g_trans_control->args.get_time.millis;
119         if (handle_time_str(time_str, time_str_len) != 0)
120             goto END;
121     } else {
122         sec     = 0;
123         mil_sec = 0;
124     }
125 
126     if (seconds != NULL)
127         *seconds = sec;
128     if (millis != NULL)
129         *millis = mil_sec;
130 
131     ret = g_trans_control->ret;
132 END:
133     g_trans_control = NULL;
134     /* we dont care return value here */
135     (void)tee_agent_unlock(TEE_MISC_AGENT_ID);
136     return ret;
137 }
138