• 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 
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 }