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