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_ext_api.h"
14 #include <tee_log.h>
15 #include <securec.h>
16 #include "tee_time_api.h"
17 #include "tee_rtc_time_api.h"
18 #include "tee_trusted_storage_api.h"
19 #include "tee_mem_mgmt_api.h"
20 #include "test_time_api_func.h"
21
TestGetSystemTime(TEE_Param params[4])22 static TEE_Result TestGetSystemTime(TEE_Param params[4])
23 {
24 tlogi("[%s] begin:", __FUNCTION__);
25
26 TEE_Time time = {0};
27 TEE_GetSystemTime(&time);
28 params[1].value.a = time.seconds;
29 tlogi("GetSystemTime: %us %ums", time.seconds, time.millis);
30 return TEE_SUCCESS;
31 }
32
TestGetREETime(TEE_Param params[4])33 static TEE_Result TestGetREETime(TEE_Param params[4])
34 {
35 tlogi("[%s] begin:", __FUNCTION__);
36
37 TEE_Time time = {0};
38 TEE_GetREETime(&time);
39 params[1].value.a = time.seconds;
40 tlogi("GetREETime: %us %ums", time.seconds, time.millis);
41 return TEE_SUCCESS;
42 }
43
TestGetSecureRtcTime(TEE_Param params[4])44 static TEE_Result TestGetSecureRtcTime(TEE_Param params[4])
45 {
46 tlogi("[%s] begin:", __FUNCTION__);
47
48 uint32_t seconds = tee_get_secure_rtc_time();
49 if (seconds == 0) {
50 tloge("tee_get_secure_rtc_time failed, get secure rtc time is zero.\n");
51 return TEE_ERROR_TIME_NEEDS_RESET;
52 }
53 params[1].value.a = seconds;
54 tlogi("call tee_get_secure_rtc_time success! seconds = %d", seconds);
55
56 return TEE_SUCCESS;
57 }
58
CheckTimeInterval(uint64_t startTime,uint64_t endTime,uint32_t waitTime)59 static TEE_Result CheckTimeInterval(uint64_t startTime, uint64_t endTime, uint32_t waitTime)
60 {
61 if (endTime == startTime) {
62 tloge("endTime (%llu) == startTime (%llu)\n", endTime, startTime);
63 return TEE_ERROR_GENERIC;
64 }
65
66 if ((endTime - startTime) < (uint64_t)waitTime) {
67 uint64_t subTime = endTime - startTime;
68 tloge("(endTime (%llu) - startTime (%llu) = subTime(%llu)) < waitTime (%u)\n",
69 endTime, startTime, subTime, waitTime);
70 return TEE_ERROR_GENERIC;
71 }
72
73 if ((endTime - startTime - waitTime) > (uint64_t)(waitTime / 10)) { /* 误差10%以内可接受 */
74 tloge("(endTime (%llu) - startTime (%llu)) > (waitTime (%u) + TEE_TEST_TIMER_BASE), "
75 "and over 10\% tolerance\n", endTime, startTime, waitTime);
76 return TEE_ERROR_GENERIC;
77 }
78
79 return TEE_SUCCESS;
80 }
81
82 #define TEST_TYPE 1613 // set this value to avoid conflict with other timer,this type value should globally unique
TestCreateDestoryExpireRemainTimer(TEE_Param params[4])83 static TEE_Result TestCreateDestoryExpireRemainTimer(TEE_Param params[4])
84 {
85 tlogi("[%s] begin:", __FUNCTION__);
86
87 TEE_Result ret = TEE_SUCCESS;
88
89 TEE_timer_property timer_property = { 0 };
90 uint32_t time_seconds = params[1].value.b; // CA set Timer duration
91 uint32_t time_seconds_ex, time_seconds_re;
92 timer_property.type = TEST_TYPE;
93 timer_property.timer_class = 3;
94
95 ret = tee_ext_create_timer(time_seconds, &timer_property);
96 if (ret != TEE_SUCCESS) {
97 tloge("tee_ext_create_timer failed! ret = 0x%x\n", ret);
98 return ret;
99 }
100 tlogi("tee_ext_create_timer success! timer_id = %d\n", timer_property.timer_id);
101
102 const uint32_t waitTime = 500;
103 TEE_Wait(waitTime);
104 ret = tee_ext_get_timer_expire(&timer_property, &time_seconds_ex);
105 if (ret != TEE_SUCCESS) {
106 tloge("tee_ext_get_timer_expire failed! ret = 0x%x\n", ret);
107 return ret;
108 }
109 params[1].value.a = time_seconds_ex;
110 tlogi("tee_ext_get_timer_expire success! expire time = %d\n", time_seconds_ex);
111
112 ret = tee_ext_get_timer_remain(&timer_property, &time_seconds_re);
113 if (ret != TEE_SUCCESS) {
114 tloge("tee_ext_get_timer_remain failed! ret = 0x%x\n", ret);
115 return ret;
116 }
117 params[1].value.b = time_seconds_re;
118 tlogi("tee_ext_get_timer_remain success! remain time = %d\n", time_seconds_re);
119
120 ret = tee_ext_destory_timer(&timer_property);
121 if (ret != TEE_SUCCESS) {
122 tloge("tee_ext_destory_timer failed! ret = 0x%x\n", ret);
123 return ret;
124 }
125 tlogi("tee_ext_destory_timer success!");
126
127 return TEE_SUCCESS;
128 }
129
TestTEEWait()130 static TEE_Result TestTEEWait()
131 {
132 tlogi("[%s] begin:", __FUNCTION__);
133
134 TEE_Time startTime, endTime;
135 const uint32_t waitTime = 5000;
136 TEE_GetSystemTime(&startTime);
137 tlogi("begin wait %ums", waitTime);
138 TEE_Result ret = TEE_Wait(waitTime);
139 if (ret != TEE_SUCCESS) {
140 tloge("TEE_Wait fail, ret = 0x%x", ret);
141 return ret;
142 }
143 TEE_GetSystemTime(&endTime);
144
145 uint64_t startTimeWithMs = startTime.seconds * MILLISECOND + startTime.millis;
146 uint64_t endTimeWithMs = endTime.seconds * MILLISECOND + endTime.millis;
147 ret = CheckTimeInterval(startTimeWithMs, endTimeWithMs, waitTime);
148 if (ret != TEE_SUCCESS) {
149 tloge("TEE_Wait check time interval fail.");
150 }
151
152 tlogi("[%s] end. ret = 0x%x.", __FUNCTION__, ret);
153 return ret;
154 }
155
RemovePersistentTimeFile(void)156 static void RemovePersistentTimeFile(void)
157 {
158 TEE_ObjectHandle object = NULL;
159 TEE_Result ret = TEE_OpenPersistentObject(TEE_OBJECT_STORAGE_PRIVATE, PERSISTENT_TIME_BASE_FILE,
160 strlen(PERSISTENT_TIME_BASE_FILE), TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE_META, &object);
161 if (ret == TEE_SUCCESS) {
162 tlogi("persistent time file is exist\n");
163 TEE_CloseAndDeletePersistentObject1(object);
164 tlogi("fremove time file\n");
165 } else {
166 tlogi("persistent time file is not exist!\n");
167 }
168 }
169
TestGetPersistentTime()170 static TEE_Result TestGetPersistentTime()
171 {
172 tlogi("[%s] begin:", __FUNCTION__);
173 TEE_Time time;
174 RemovePersistentTimeFile();
175 TEE_Result ret = TEE_GetTAPersistentTime(&time);
176 if (ret != TEE_ERROR_TIME_NOT_SET) {
177 tloge("GetTAPersistentTime fail after remove persistent time file; before set time. ret = 0x%x", ret);
178 if (ret != TEE_SUCCESS)
179 return TEE_ERROR_NOT_SUPPORTED;
180 else
181 return TEE_ERROR_GENERIC;
182 }
183
184 TEE_Time setTime = {
185 .seconds = RESERVED10S,
186 .millis = 0,
187 };
188 ret = TEE_SetTAPersistentTime(&setTime);
189 if (ret != TEE_SUCCESS) {
190 tloge("set time fail ret = 0x%x", ret);
191 return TEE_ERROR_GENERIC;
192 }
193
194 tlogi("begin wait %us", WAIT5S);
195 TEE_Wait(MILLISECOND * WAIT5S);
196 TEE_Time getTime = {0};
197 ret = TEE_GetTAPersistentTime(&getTime);
198 if (ret != TEE_SUCCESS ||
199 (getTime.seconds != RESERVED10S + WAIT5S && getTime.seconds != RESERVED10S + WAIT5S + 1)) {
200 tloge("get time fail. ret = 0x%x, get time is %us %ums", ret, getTime.seconds, getTime.millis);
201 return TEE_ERROR_GENERIC;
202 }
203
204 tlogi("[%s] end.", __FUNCTION__);
205 return TEE_SUCCESS;
206 }
207
TestSetPersistentTime()208 static TEE_Result TestSetPersistentTime()
209 {
210 tlogi("[%s] begin:", __FUNCTION__);
211 RemovePersistentTimeFile();
212 TEE_Time setTime = {
213 .seconds = RESERVED10S,
214 .millis = 0,
215 };
216 TEE_Result ret = TEE_SetTAPersistentTime(&setTime);
217 if (ret != TEE_SUCCESS) {
218 tloge("set time fail ret = 0x%x", ret);
219 return ret;
220 }
221
222 TEE_Time getTime = {0};
223 ret = TEE_GetTAPersistentTime(&getTime);
224 if (ret != TEE_SUCCESS || (getTime.seconds != RESERVED10S && getTime.seconds != RESERVED10S + 1)) {
225 tloge("get time fail. ret = 0x%x, get time is %us %ums", ret, getTime.seconds, getTime.millis);
226 return TEE_ERROR_GENERIC;
227 }
228
229 tlogi("begin wait %us", WAIT5S);
230 TEE_Wait(MILLISECOND * WAIT5S);
231 setTime.seconds = RESERVED10S;
232 ret = TEE_SetTAPersistentTime(&setTime); // Repeated setting, can be overwritten
233 if (ret != TEE_SUCCESS) {
234 tloge("set time fail ret = 0x%x", ret);
235 return TEE_ERROR_GENERIC;
236 }
237
238 (void)memset_s(&getTime, sizeof(getTime), 0, sizeof(getTime));
239 ret = TEE_GetTAPersistentTime(&getTime);
240 if (ret != TEE_SUCCESS || (getTime.seconds != RESERVED10S && getTime.seconds != RESERVED10S + 1)) {
241 tloge("get time fail. ret = 0x%x, get time is %us %ums", ret, getTime.seconds, getTime.millis);
242 return TEE_ERROR_GENERIC;
243 }
244
245 tlogi("[%s] end. ret = 0x%x.", __FUNCTION__, ret);
246 return ret;
247 }
248
TestOnlyGetPersistentTime()249 static TEE_Result TestOnlyGetPersistentTime()
250 {
251 tlogi("[%s] begin:", __FUNCTION__);
252 TEE_Time time;
253 TEE_Result ret;
254 ret = TEE_GetTAPersistentTime(&time);
255 tlogi("only get persistent time, not check. ret = 0x%x, seconds = %u, millis = %u\n", ret, time.seconds,
256 time.millis);
257
258 return TEE_SUCCESS;
259 }
260
TestPersistentTimeWithException()261 static TEE_Result TestPersistentTimeWithException()
262 {
263 tlogi("[%s] begin:", __FUNCTION__);
264 TEE_Time time;
265 RemovePersistentTimeFile();
266 TEE_Time setTime = {
267 .seconds = UINT32_MAX - RESERVED10S,
268 .millis = 0,
269 };
270 TEE_Result ret = TEE_SetTAPersistentTime(&setTime);
271 if (ret != TEE_SUCCESS) {
272 tloge("set time fail ret = 0x%x", ret);
273 return ret;
274 }
275
276 tlogi("before wait for %ds", WAIT5S);
277 TEE_Wait(MILLISECOND * WAIT5S);
278 ret = TEE_GetTAPersistentTime(&time);
279 if (ret != TEE_SUCCESS || time.seconds > UINT32_MAX - RESERVED10S + WAIT5S + 1 ||
280 time.seconds < UINT32_MAX - RESERVED10S + WAIT5S - 1) {
281 tloge("get time fail. ret = 0x%x, get time is %us %ums", ret, time.seconds, time.millis);
282 return TEE_ERROR_GENERIC;
283 }
284
285 TEE_Wait(MILLISECOND * RESERVED10S); // get time is UINT32_MAX - 10s + 5s + 10s > UINT32_MAX; get time is 5s
286 ret = TEE_GetTAPersistentTime(&time);
287 if (ret != TEE_ERROR_OVERFLOW || time.seconds > WAIT5S + 1 || time.seconds < WAIT5S - 1) {
288 tloge("get time for overflow fail, ret = 0x%x, get time is %us, %ums", ret, time.seconds, time.millis);
289 return TEE_ERROR_GENERIC;
290 }
291
292 // set time value max
293 time.seconds = UINT32_MAX;
294 time.millis = UINT32_MAX;
295 ret = TEE_SetTAPersistentTime(&time);
296 if (ret != TEE_SUCCESS) {
297 tloge("set time with max time value failed ret = 0x%x\n", ret);
298 return TEE_ERROR_GENERIC;
299 }
300
301 tlogi("[%s] end.", __FUNCTION__);
302 return TEE_SUCCESS;
303 }
304
TestTimeApi(uint32_t cmdId,TEE_Param params[4])305 TEE_Result TestTimeApi(uint32_t cmdId, TEE_Param params[4])
306 {
307 tlogi("%s begin: cmdId is %d.", __FUNCTION__, cmdId);
308 TEE_Result ret = TEE_SUCCESS;
309
310 switch (cmdId) {
311 case CMD_ID_TEST_GET_SYSTEM_TIME:
312 ret = TestGetSystemTime(params);
313 break;
314 case CMD_ID_TEST_GET_REE_TIME:
315 ret = TestGetREETime(params);
316 break;
317 case CMD_ID_TEST_GET_REE_TIME_STR:
318 ret = TestGetREETimeStr(params);
319 break;
320 case CMD_ID_TEST_GET_SECURE_RTC_TIME:
321 ret = TestGetSecureRtcTime(params);
322 break;
323 case CMD_ID_TEST_OPERATE_TIMER:
324 ret = TestCreateDestoryExpireRemainTimer(params);
325 break;
326 case CMD_ID_TEST_TEE_WAIT:
327 ret = TestTEEWait();
328 break;
329 case CMD_ID_ONLY_GET_PERSISTENT_TIME:
330 ret = TestOnlyGetPersistentTime();
331 break;
332 case CMD_ID_TEST_GET_PERSISTENT_TIME:
333 ret = TestGetPersistentTime();
334 break;
335 case CMD_ID_TEST_SET_PERSISTENT_TIME:
336 ret = TestSetPersistentTime();
337 break;
338 case CMD_ID_TEST_PERSISTENT_TIME_WITH_EXCEPTION:
339 ret = TestPersistentTimeWithException();
340 break;
341 default:
342 tlogi("unknown command id, cmdId: %u\n", cmdId);
343 return TEE_ERROR_INVALID_CMD;
344 }
345
346 tlogi("[%s] end. ret = 0x%x.", __FUNCTION__, ret);
347 return ret;
348 }