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_property_api.h"
13
14 #include <stdlib.h>
15 #include <string.h>
16 #include <pthread.h>
17 #include <securec.h>
18 #include <dlist.h>
19 #include <ipclib.h>
20
21 #include "tee_mem_mgmt_api.h"
22 #include "tee_bitmap.h"
23 #include "tee_log.h"
24 #include "tee_ss_agent_api.h"
25 #include "ta_framework.h"
26 #include <tee_huk_get_device_id.h>
27 #include "tee_property_inner.h"
28
29 #define PROP_ERROR (-1)
30 #define PROP_SUCCESS 0
31
32 #define TEE_INTERNAL_CORE_MAJOR_VERSION 1
33 #define TEE_INTERNAL_CORE_MINOR_VERSION 2
34 #define TEE_INTERNAL_CORE_MAINTENANCE_VERSION 0
35 #define TEE_INTERNAL_CORE_RESERVED_VERSION 0
36
37 // TEE_API_VERSION should match with TEE_INTERNAL_CORE_VERSION
38 #define TEE_API_VERSION "v1.2.0"
39 #define TEE_INTERNAL_CORE_VERSION \
40 ((TEE_INTERNAL_CORE_MAJOR_VERSION << 24) | (TEE_INTERNAL_CORE_MINOR_VERSION << 16) | \
41 (TEE_INTERNAL_CORE_MAINTENANCE_VERSION << 8) | TEE_INTERNAL_CORE_RESERVED_VERSION)
42 #define TEE_BUILD_VER "B309"
43
44 #define TEE_IMP_VERSION "TEE-1.0.0"
45
46 #define TEE_MANUFACTURER "TEE"
47 #define TEE_FIRMWARE_IMP_VERSION "ATF-1.5"
48 #define TEE_FIRMWARE_MANUFACTURER "TEE"
49
50 #define TEE_TIME_PROTECT_LEVEL 100
51 #define TA_TIME_PROTECT_LEVEL 100
52 #define MAX_BIG_INT_SIZE 32
53 #define STR_SUBFIX_LEN 1 // len for '\0'
54
55 // format: "identity:interger:uuid"
56 #define IDENTITY_STRING_LEN (IDENTITY_PREFIX_STRLEN + U32_DECIMAL_MAX_STRLEN + 1 + UUID_FORMAT_STRLEN)
57
58 static TEE_UUID g_device_id;
59
60 enum bool_prop_t {
61 PROP_INVALID = -1,
62 PROP_FALSE = 0,
63 PROP_TRUE = 1
64 };
65
66 enum prop_type {
67 T_STRING = 1,
68 T_BOOL,
69 T_U32,
70 T_U64,
71 T_BINARY,
72 T_UUID,
73 T_IDENTITY,
74 };
75
76 struct prop_item {
77 char *name;
78 enum prop_type type;
79 uintptr_t val;
80 uint32_t val_len;
81 struct dlist_node list;
82 };
83
84 struct prop_set {
85 Pseudo_PropSetHandle set;
86 struct dlist_node head;
87 };
88
89 #define PROP_SET 3
90 enum {
91 PROP_SET_TEE = 0,
92 PROP_SET_CLIENT = 1,
93 PROP_SET_TA = 2,
94 };
95 #define sel_prop_set(pesudo_handle) ((pesudo_handle) - (uint32_t)TEE_PROPSET_TEE_IMPLEMENTATION)
96
97 static struct prop_set g_property[PROP_SET] = {
98 { TEE_PROPSET_TEE_IMPLEMENTATION, { &(g_property[PROP_SET_TEE].head), &(g_property[PROP_SET_TEE].head) } },
99 { TEE_PROPSET_CURRENT_CLIENT, { &(g_property[PROP_SET_CLIENT].head), &(g_property[PROP_SET_CLIENT].head) } },
100 { TEE_PROPSET_CURRENT_TA, { &(g_property[PROP_SET_TA].head), &(g_property[PROP_SET_TA].head) } }
101 };
102
103 struct enum_handle {
104 Pseudo_PropSetHandle set;
105 struct prop_item *item;
106 uint32_t handle;
107 struct dlist_node list;
108 };
109
110 static bool g_init_done = false;
111
112 static dlist_head(g_enum_head);
113 #define TEE_PROPERTY_HANDLE_MAX 1024
114 #define PROPERTY_MAP_SIZE (TEE_PROPERTY_HANDLE_MAX / 8)
115 static uint8_t g_handle_bitmap[PROPERTY_MAP_SIZE];
116 static pthread_mutex_t g_bitmap_mutex = PTHREAD_MUTEX_INITIALIZER;
117
118 #define UUID_FORMAT_STRLEN 37
119 #define MAX_PROPERTY_NAME_LEN 255
120
121 // overwrite GP standard interface, enable it only in GP certificate
122 #ifndef SUPPORT_GP_PANIC
123 #define TEE_Panic(x) \
124 do { \
125 } while (0)
126 #endif
127
mutex_lock_ops(pthread_mutex_t * mtx)128 static int mutex_lock_ops(pthread_mutex_t *mtx)
129 {
130 int ret;
131 ret = pthread_mutex_lock(mtx);
132 if (ret == EOWNERDEAD) /* owner died, use consistent to recover and lock the mutex */
133 return pthread_mutex_consistent(mtx);
134
135 return ret;
136 }
137
add_prop_item(Pseudo_PropSetHandle set,const char * name,enum prop_type type,uintptr_t val,uint32_t val_len)138 static TEE_Result add_prop_item(Pseudo_PropSetHandle set, const char *name, enum prop_type type, uintptr_t val,
139 uint32_t val_len)
140 {
141 struct prop_item *item = NULL;
142 size_t len;
143
144 bool check = ((name == NULL) || (strnlen(name, MAX_PROPERTY_NAME_LEN) >= MAX_PROPERTY_NAME_LEN));
145 if (check) {
146 tloge("invalid property name\n");
147 return TEE_ERROR_BAD_PARAMETERS;
148 }
149
150 if (sel_prop_set(set) >= PROP_SET) {
151 tloge("invalid property set value\n");
152 return TEE_ERROR_GENERIC;
153 }
154
155 len = strlen(name) + STR_SUBFIX_LEN + val_len;
156 item = TEE_Malloc(sizeof(*item) + len, 0);
157 if (item == NULL)
158 return TEE_ERROR_OUT_OF_MEMORY;
159
160 item->name = (char *)(item + STR_SUBFIX_LEN);
161 item->val = (uintptr_t)(item->name + strlen(name) + STR_SUBFIX_LEN);
162 if (memcpy_s(item->name, len, name, len) != EOK) {
163 TEE_Free(item);
164 return TEE_ERROR_SECURITY;
165 }
166
167 item->type = type;
168 item->val_len = val_len;
169
170 if ((type == T_BOOL) || (type == T_U32)) {
171 item->val = val;
172 } else {
173 if (val_len != 0) {
174 if (memcpy_s((void *)(item->val), item->val_len, (void *)val, val_len) != EOK) {
175 tloge("copy item val failed\n");
176 TEE_Free(item);
177 return TEE_ERROR_SECURITY;
178 }
179 }
180 }
181
182 dlist_insert_tail(&item->list, &g_property[sel_prop_set(set)].head);
183 return TEE_SUCCESS;
184 }
185
186 struct init_property_set {
187 Pseudo_PropSetHandle set;
188 const char *name;
189 enum prop_type type;
190 uintptr_t val;
191 uint32_t val_len;
192 };
193
194 static const struct init_property_set g_property_set[] = {
195 { TEE_PROPSET_TEE_IMPLEMENTATION,
196 "gpd.tee.apiversion", T_STRING, (uintptr_t)TEE_API_VERSION, sizeof(TEE_API_VERSION)
197 },
198 { TEE_PROPSET_TEE_IMPLEMENTATION,
199 "gpd.tee.internalCore.version", T_U32, TEE_INTERNAL_CORE_VERSION, sizeof(uint32_t)
200 },
201 { TEE_PROPSET_TEE_IMPLEMENTATION,
202 "gpd.tee.description", T_STRING, (uintptr_t)TEE_BUILD_VER, sizeof(TEE_BUILD_VER)
203 },
204 { TEE_PROPSET_TEE_IMPLEMENTATION,
205 "gpd.tee.deviceID", T_UUID, (uintptr_t)&g_device_id, sizeof(TEE_UUID)
206 },
207 { TEE_PROPSET_TEE_IMPLEMENTATION,
208 "gpd.tee.systemTime.protectionLevel", T_U32, TEE_TIME_PROTECT_LEVEL, sizeof(uint32_t)
209 },
210 { TEE_PROPSET_TEE_IMPLEMENTATION,
211 "gpd.tee.TAPersistentTime.protectionLevel", T_U32, TA_TIME_PROTECT_LEVEL, sizeof(uint32_t)
212 },
213 { TEE_PROPSET_TEE_IMPLEMENTATION,
214 "gpd.tee.arith.maxBigIntSize", T_U32, MAX_BIG_INT_SIZE, sizeof(uint32_t)
215 },
216 { TEE_PROPSET_TEE_IMPLEMENTATION,
217 "gpd.tee.cryptography.ecc", T_BOOL, false, sizeof(uint32_t)
218 },
219 { TEE_PROPSET_TEE_IMPLEMENTATION,
220 "gpd.tee.cryptography.nist", T_BOOL, false, sizeof(uint32_t)
221 },
222 { TEE_PROPSET_TEE_IMPLEMENTATION,
223 "gpd.tee.cryptography.bsi-r", T_BOOL, false, sizeof(uint32_t)
224 },
225 { TEE_PROPSET_TEE_IMPLEMENTATION,
226 "gpd.tee.cryptography.bsi-t", T_BOOL, false, sizeof(uint32_t)
227 },
228 { TEE_PROPSET_TEE_IMPLEMENTATION,
229 "gpd.tee.cryptography.ietf", T_BOOL, false, sizeof(uint32_t)
230 },
231 { TEE_PROPSET_TEE_IMPLEMENTATION,
232 "gpd.tee.cryptography.octa", T_BOOL, false, sizeof(uint32_t)
233 },
234 { TEE_PROPSET_TEE_IMPLEMENTATION,
235 "gpd.tee.trustedStorage.antiRollback.protectionLevel", T_U32, 0, sizeof(uint32_t)
236 },
237 { TEE_PROPSET_TEE_IMPLEMENTATION,
238 "gpd.tee.trustedStorage.rollbackDetection.protectionLevel", T_U32, 0, sizeof(uint32_t)
239 },
240 { TEE_PROPSET_TEE_IMPLEMENTATION,
241 "gpd.tee.trustedos.implementation.version", T_STRING, (uintptr_t)TEE_IMP_VERSION, sizeof(TEE_IMP_VERSION)
242 },
243 { TEE_PROPSET_TEE_IMPLEMENTATION,
244 "gpd.tee.trustedos.implementation.binaryversion",
245 T_STRING, (uintptr_t)TEE_IMP_VERSION, sizeof(TEE_IMP_VERSION)
246 },
247 { TEE_PROPSET_TEE_IMPLEMENTATION,
248 "gpd.tee.trustedos.manufacturer", T_STRING, (uintptr_t)TEE_MANUFACTURER, sizeof(TEE_MANUFACTURER)
249 },
250 { TEE_PROPSET_TEE_IMPLEMENTATION,
251 "gpd.tee.firmware.implementation.version",
252 T_STRING, (uintptr_t)TEE_IMP_VERSION, sizeof(TEE_FIRMWARE_IMP_VERSION)
253 },
254 { TEE_PROPSET_TEE_IMPLEMENTATION,
255 "gpd.tee.firmware.implementation.binaryversion",
256 T_BINARY, (uintptr_t)TEE_IMP_VERSION, sizeof(TEE_FIRMWARE_IMP_VERSION)
257 },
258 { TEE_PROPSET_TEE_IMPLEMENTATION,
259 "gpd.tee.firmware.manufacturer",
260 T_STRING, (uintptr_t)TEE_FIRMWARE_MANUFACTURER, sizeof(TEE_FIRMWARE_MANUFACTURER)
261 },
262 { TEE_PROPSET_TEE_IMPLEMENTATION,
263 "gpd.tee.event.maxSources", T_U32, 0, sizeof(uint32_t)
264 },
265 { TEE_PROPSET_TEE_IMPLEMENTATION,
266 "gpd.tee.api_level", T_U32, TEE_MAX_API_LEVEL_CONFIG, sizeof(uint32_t)
267 },
268 };
269
create_client_identity(uint32_t login_method,const TEE_UUID * client_uuid)270 static TEE_Identity *create_client_identity(uint32_t login_method, const TEE_UUID *client_uuid)
271 {
272 TEE_Identity *identity = NULL;
273 if (client_uuid == NULL)
274 return NULL;
275
276 identity = TEE_Malloc(sizeof(*identity), 0);
277 if (identity == NULL) {
278 tloge("apply identity failed\n");
279 return NULL;
280 }
281
282 identity->login = login_method;
283 if (memcpy_s(&identity->uuid, sizeof(identity->uuid), client_uuid, sizeof(*client_uuid)) != EOK) {
284 tloge("create identity failed\n");
285 TEE_Free(identity);
286 return NULL;
287 }
288
289 return identity;
290 }
291
init_property(uint32_t login_method,const TEE_UUID * client_uuid,const struct ta_property * prop)292 void init_property(uint32_t login_method, const TEE_UUID *client_uuid, const struct ta_property *prop)
293 {
294 TEE_Result ret = TEE_SUCCESS;
295 TEE_Result id_ret;
296 uint32_t i;
297 if (prop == NULL) // client_uuid may be null, don't need to check it
298 return;
299
300 g_init_done = false;
301
302 if (mutex_lock_ops(&g_bitmap_mutex) != 0)
303 return;
304 set_bitmap(g_handle_bitmap, TEE_PROPERTY_HANDLE_MAX, 0);
305 (void)pthread_mutex_unlock(&g_bitmap_mutex);
306
307 id_ret = get_device_id_prop((uint8_t *)(&g_device_id), sizeof(g_device_id));
308 if (id_ret != TEE_SUCCESS) {
309 if (id_ret == TEE_ERROR_NOT_SUPPORTED)
310 tlogw("device id not supported\n");
311 else
312 tloge("get device id prop failed\n");
313 }
314 for (i = 0; i < sizeof(g_property_set) / sizeof(g_property_set[0]); i++)
315 ret |= add_prop_item(g_property_set[i].set, g_property_set[i].name, g_property_set[i].type,
316 g_property_set[i].val, g_property_set[i].val_len);
317
318 TEE_Identity *identity = create_client_identity(login_method, client_uuid);
319 ret |= add_prop_item(TEE_PROPSET_CURRENT_CLIENT, "gpd.client.identity", T_IDENTITY, (uintptr_t)identity,
320 (identity != NULL) ? sizeof(*identity) : 0);
321 ret |= add_prop_item(TEE_PROPSET_CURRENT_CLIENT, "gpd.client.endian", T_U32, 0, sizeof(uint32_t));
322 ret |= add_prop_item(TEE_PROPSET_CURRENT_TA, "gpd.ta.appID", T_UUID, (uintptr_t)(&prop->uuid), sizeof(TEE_UUID));
323 ret |=
324 add_prop_item(TEE_PROPSET_CURRENT_TA, "gpd.ta.singleInstance", T_BOOL, prop->single_instance, sizeof(uint32_t));
325 ret |= add_prop_item(TEE_PROPSET_CURRENT_TA, "gpd.ta.multiSession", T_BOOL, prop->multi_session, sizeof(uint32_t));
326 ret |=
327 add_prop_item(TEE_PROPSET_CURRENT_TA, "gpd.ta.instanceKeepAlive", T_BOOL, prop->keep_alive, sizeof(uint32_t));
328 ret |= add_prop_item(TEE_PROPSET_CURRENT_TA, "gpd.ta.dataSize", T_U32, prop->heap_size, sizeof(uint32_t));
329 ret |= add_prop_item(TEE_PROPSET_CURRENT_TA, "gpd.ta.stackSize", T_U32, prop->stack_size, sizeof(uint32_t));
330 ret |= add_prop_item(TEE_PROPSET_CURRENT_TA, "gpd.ta.endian", T_U32, 0, sizeof(uint32_t));
331 if (ret != TEE_SUCCESS)
332 tloge("fail to add some property\n");
333 g_init_done = true;
334 }
335
init_non_std_property(char * buff,uint32_t len)336 void init_non_std_property(char *buff, uint32_t len)
337 {
338 char *name = NULL;
339 char *new_name = NULL;
340 char *val = NULL;
341 uint32_t i;
342 uint32_t end_flag = 0;
343
344 if (buff == NULL || len > NOTIFY_MAX_LEN) {
345 tloge("invalid parameter\n");
346 return;
347 }
348
349 g_init_done = false;
350 val = buff;
351 name = buff;
352
353 for (i = 0; i < len; i++) {
354 if (*(buff + i) == ':') {
355 if ((uintptr_t)val <= (uintptr_t)name) {
356 *(buff + i) = '\0';
357 val = buff + i + 1;
358 }
359 } else if ((*(buff + i) == '\n') || (*(buff + i) == '\0')) {
360 if (*(buff + i) == '\0')
361 end_flag = 1;
362
363 *(buff + i) = '\0';
364 new_name = buff + i + 1;
365
366 if (add_prop_item(TEE_PROPSET_CURRENT_TA, name, T_STRING, (uintptr_t)val,
367 (uintptr_t)new_name - (uintptr_t)val) != TEE_SUCCESS)
368 tlogd("add non std property failed\n");
369
370 if (end_flag == 1)
371 break;
372
373 name = new_name;
374 }
375 }
376 g_init_done = true;
377 }
378
is_pseudo_handle(TEE_PropSetHandle handle)379 static bool is_pseudo_handle(TEE_PropSetHandle handle)
380 {
381 return handle >= TEE_PROPSET_TEE_IMPLEMENTATION;
382 }
383
is_valid_enum_handle(TEE_PropSetHandle handle)384 static bool is_valid_enum_handle(TEE_PropSetHandle handle)
385 {
386 if (handle == TEE_PROPSET_UNKNOW)
387 return false;
388
389 if (mutex_lock_ops(&g_bitmap_mutex) != 0)
390 return false;
391
392 bool ret = is_bit_seted(g_handle_bitmap, TEE_PROPERTY_HANDLE_MAX, handle);
393 (void)pthread_mutex_unlock(&g_bitmap_mutex);
394 return ret;
395 }
396
is_last_item(uint32_t set,const struct prop_item * item)397 static bool is_last_item(uint32_t set, const struct prop_item *item)
398 {
399 struct dlist_node *set_head = NULL;
400
401 if ((item == NULL) || (sel_prop_set(set) >= PROP_SET))
402 return false;
403
404 set_head = &(g_property[sel_prop_set(set)].head);
405
406 return item->list.next == set_head;
407 }
408
is_enumerator_started(const struct enum_handle * handle)409 static bool is_enumerator_started(const struct enum_handle *handle)
410 {
411 if (handle == NULL)
412 return false;
413
414 return handle->item != NULL;
415 }
416
find_pseuprop_item(TEE_PropSetHandle set,const char * name)417 static struct prop_item *find_pseuprop_item(TEE_PropSetHandle set, const char *name)
418 {
419 struct prop_item *i_item = NULL;
420 struct dlist_node *set_head = NULL;
421 bool find_flag = false;
422
423 if (name == NULL)
424 return NULL;
425 if (strnlen(name, MAX_PROPERTY_NAME_LEN) >= MAX_PROPERTY_NAME_LEN ||
426 strnlen(name, MAX_PROPERTY_NAME_LEN) == 0)
427 return NULL;
428
429 uint32_t index = sel_prop_set(set);
430 if (index >= (sizeof(g_property) / sizeof(g_property[0])))
431 return NULL;
432
433 set_head = &(g_property[index].head);
434 dlist_for_each_entry(i_item, set_head, struct prop_item, list) {
435 if (TEE_MemCompare(name, i_item->name, strlen(name) + 1) == 0) {
436 find_flag = true;
437 break;
438 }
439 }
440
441 if (!find_flag)
442 return NULL;
443
444 return i_item;
445 }
446
find_enum_handle(TEE_PropSetHandle enumerator)447 static struct enum_handle *find_enum_handle(TEE_PropSetHandle enumerator)
448 {
449 struct enum_handle *handle = NULL;
450
451 dlist_for_each_entry(handle, &g_enum_head, struct enum_handle, list) {
452 if (handle->handle == enumerator)
453 return handle;
454 }
455
456 return NULL;
457 }
458
get_prop_item(TEE_PropSetHandle enumerator,const char * name)459 static struct prop_item *get_prop_item(TEE_PropSetHandle enumerator, const char *name)
460 {
461 struct prop_item *item = NULL;
462 struct enum_handle *handle = NULL;
463
464 if (!g_init_done)
465 return NULL;
466 if (is_pseudo_handle(enumerator)) {
467 item = find_pseuprop_item(enumerator, name);
468 if (item == NULL)
469 return NULL;
470 } else {
471 if (!is_valid_enum_handle(enumerator))
472 return NULL;
473
474 handle = find_enum_handle(enumerator);
475 if (handle == NULL)
476 return NULL;
477
478 item = handle->item;
479 }
480
481 return item;
482 }
483
convert_uuid_to_str(const TEE_UUID * uuid,char * buff,uint32_t len)484 static void convert_uuid_to_str(const TEE_UUID *uuid, char *buff, uint32_t len)
485 {
486 if ((uuid == NULL) || (len < UUID_FORMAT_STRLEN)) {
487 tloge("invalid parameter\n");
488 return;
489 }
490
491 int ret = snprintf_s(buff, len, UUID_FORMAT_STRLEN, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
492 uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, uuid->clockSeqAndNode[0],
493 uuid->clockSeqAndNode[1], uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3],
494 uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5], uuid->clockSeqAndNode[6],
495 uuid->clockSeqAndNode[7]); // refer uuid format definitions
496 if (ret <= 0)
497 tloge("convert uuid to string failed\n");
498 }
499
500 #define ALP_TO_DIGIT_GAP 10
asc2hex(char a)501 static int8_t asc2hex(char a)
502 {
503 if ((a >= '0') && (a <= '9'))
504 return a - '0';
505 else if ((a >= 'a') && (a <= 'f'))
506 return (a - 'a') + ALP_TO_DIGIT_GAP;
507 else if ((a >= 'A') && (a <= 'F'))
508 return (a - 'A') + ALP_TO_DIGIT_GAP;
509
510 return PROP_ERROR;
511 }
512
513 #define CHAR_COUNT_PER_BYTE 2
514 #define HALF_BYTE_SIZE 4
get_byte_value_from_buff(const char * buff,uint32_t len,uint8_t * res)515 static int get_byte_value_from_buff(const char *buff, uint32_t len, uint8_t *res)
516 {
517 bool check = ((buff == NULL) || (len < CHAR_COUNT_PER_BYTE));
518 if (check) {
519 tloge("invalid parameter\n");
520 return PROP_ERROR;
521 }
522
523 int8_t h_val = asc2hex(*buff);
524 int8_t l_val = asc2hex(*(buff + 1));
525 if (((int)h_val == PROP_ERROR) || ((int)l_val == PROP_ERROR))
526 return PROP_ERROR;
527
528 *res = (uint8_t)(((uint8_t)h_val << HALF_BYTE_SIZE) | (uint8_t)l_val);
529 return PROP_SUCCESS;
530 }
531
532 #define ADD_POS_COUNT_IN_UUID 5
533 #define BYTE_COUNT_IN_UUID 16
534 #define BITS_COUNT_PER_BYTE 8
535
536 #define ADD_POS_INIT_INDEX 0
537 #define ADD_POS_FIRST_INDEX 1
538 #define ADD_POS_SECOND_INDEX 2
539 #define ADD_POS_THIRD_INDEX 3
540 #define ADD_POS_FOUR_INDEX 4
convert_str_to_uuid(const char * buff,uint32_t len,TEE_UUID * uuid)541 static int32_t convert_str_to_uuid(const char *buff, uint32_t len, TEE_UUID *uuid)
542 {
543 const char *p = buff;
544 uint8_t add_pos_array[ADD_POS_COUNT_IN_UUID] = { 8, 13, 18, 23, 36 }; // fixed values, refer UUID format definitions
545 uint8_t add_pos = 0;
546
547 uint8_t tmp_val;
548 uint8_t *set_val = NULL;
549 int i;
550
551 bool check = ((buff == NULL) || (uuid == NULL) || (len != UUID_FORMAT_STRLEN) || (*(buff + len - 1) != '\0'));
552 if (check) {
553 tloge("invalid parameter\n");
554 return PROP_ERROR;
555 }
556
557 set_val = uuid->clockSeqAndNode;
558 for (i = 0; i < BYTE_COUNT_IN_UUID; i++) {
559 if (get_byte_value_from_buff(p, len - (p - buff), &tmp_val) != 0)
560 return PROP_ERROR;
561
562 p += CHAR_COUNT_PER_BYTE;
563
564 switch (add_pos) {
565 case ADD_POS_INIT_INDEX:
566 uuid->timeLow = (uuid->timeLow << BITS_COUNT_PER_BYTE) + tmp_val;
567 break;
568 case ADD_POS_FIRST_INDEX:
569 uuid->timeMid = (uuid->timeMid << BITS_COUNT_PER_BYTE) + tmp_val;
570 break;
571 case ADD_POS_SECOND_INDEX:
572 uuid->timeHiAndVersion = (uuid->timeHiAndVersion << BITS_COUNT_PER_BYTE) + tmp_val;
573 break;
574 case ADD_POS_THIRD_INDEX:
575 case ADD_POS_FOUR_INDEX:
576 *set_val++ = tmp_val;
577 break;
578 default:
579 tloge("invalid uuid format\n");
580 return PROP_ERROR;
581 }
582
583 if ((uint8_t)(p - buff) == add_pos_array[add_pos]) {
584 if (*p != '-')
585 break;
586 p++;
587 add_pos++;
588 }
589 }
590 // not touch the end of buff
591 if (p != (buff + len - 1))
592 return PROP_ERROR;
593
594 return PROP_SUCCESS;
595 }
596
convert_str_to_identity(const char * buff,uint32_t len,TEE_Identity * identity)597 static int32_t convert_str_to_identity(const char *buff, uint32_t len, TEE_Identity *identity)
598 {
599 const char *p_login = buff;
600 const char *p_uuid = buff;
601 char *tmp_buff = NULL;
602 char *endptr = NULL;
603
604 bool check = ((buff == NULL) || (identity == NULL));
605 if (check) {
606 tloge("invalid parameter\n");
607 return PROP_ERROR;
608 }
609
610 if (*(buff + len - 1) != '\0')
611 return PROP_ERROR;
612
613 tmp_buff = TEE_Malloc(len, 0);
614 if (tmp_buff == NULL)
615 return PROP_ERROR;
616
617 if (memcpy_s(tmp_buff, len, buff, len) != EOK) {
618 TEE_Free(tmp_buff);
619 return PROP_ERROR;
620 }
621
622 while (*p_uuid++ != '\0') {
623 if (*p_uuid == ':') {
624 p_uuid++;
625 break;
626 }
627
628 if ((uint32_t)(p_uuid - p_login) > len) {
629 TEE_Free(tmp_buff);
630 return PROP_ERROR;
631 }
632 }
633
634 identity->login = strtoul(p_login, &endptr, 0);
635 if (endptr != (p_uuid - 1)) {
636 TEE_Free(tmp_buff);
637 return PROP_ERROR;
638 }
639
640 if (convert_str_to_uuid(p_uuid, len - (uint32_t)(p_uuid - p_login), &identity->uuid) != 0) {
641 TEE_Free(tmp_buff);
642 return PROP_ERROR;
643 }
644
645 TEE_Free(tmp_buff);
646 return PROP_SUCCESS;
647 }
648
convert_bool_str(const char * buff,uint32_t len)649 static enum bool_prop_t convert_bool_str(const char *buff, uint32_t len)
650 {
651 if (buff == NULL)
652 return PROP_INVALID;
653
654 if ((len == sizeof("true")) && (TEE_MemCompare(buff, "true", len) == 0))
655 return PROP_TRUE;
656 else if ((len == sizeof("false")) && (TEE_MemCompare(buff, "false", len) == 0))
657 return PROP_FALSE;
658
659 return PROP_INVALID;
660 }
661
662 #define IDENTITY_PREFIX_STRLEN 10 // format: "identity:interger:uuid"
663 #define U32_DECIMAL_MAX_STRLEN 11 // 0xffffffff have 10 digits
664 #define U64_DECIMAL_MAX_STRLEN 21 // 0xffffffffffffffff have 20 digits
665
copy_result_to_buff(const char * result_buff,size_t result_len,char * buff,size_t * buff_len)666 static TEE_Result copy_result_to_buff(const char *result_buff, size_t result_len, char *buff, size_t *buff_len)
667 {
668 bool check = ((result_buff == NULL) || (buff == NULL) || (buff_len == NULL));
669 if (check) {
670 tloge("invalid parameter\n");
671 return TEE_ERROR_BAD_PARAMETERS;
672 }
673
674 if (*buff_len < result_len) {
675 *buff_len = result_len;
676 return TEE_ERROR_SHORT_BUFFER;
677 }
678
679 if (memcpy_s(buff, *buff_len, result_buff, result_len) != EOK)
680 return TEE_ERROR_SECURITY;
681
682 return TEE_SUCCESS;
683 }
684
raw_item_to_str(const struct prop_item * item,char * buff,size_t * buff_len)685 static TEE_Result raw_item_to_str(const struct prop_item *item, char *buff, size_t *buff_len)
686 {
687 return copy_result_to_buff((const char *)item->val, item->val_len, buff, buff_len);
688 }
689
bool_item_to_str(const struct prop_item * item,char * buff,size_t * buff_len)690 static TEE_Result bool_item_to_str(const struct prop_item *item, char *buff, size_t *buff_len)
691 {
692 char *val_str = NULL;
693 size_t val_size;
694
695 if ((item->val) != 0) {
696 val_str = "true";
697 val_size = sizeof("true");
698 } else {
699 val_str = "false";
700 val_size = sizeof("false");
701 }
702 return copy_result_to_buff(val_str, val_size, buff, buff_len);
703 }
704
705 #define MAX_U32_DIGIT_STR_LEN 11
u32_item_to_string(const struct prop_item * item,char * buff,size_t * buff_len)706 static TEE_Result u32_item_to_string(const struct prop_item *item, char *buff, size_t *buff_len)
707 {
708 char *val_str = NULL;
709 size_t val_size;
710 char u32_buff[MAX_U32_DIGIT_STR_LEN] = { 0 };
711
712 if (snprintf_s(u32_buff, sizeof(u32_buff), sizeof(u32_buff) - 1, "%u", (uint32_t)item->val) < 0)
713 return TEE_ERROR_GENERIC;
714
715 val_str = u32_buff;
716 val_size = strlen(u32_buff) + 1;
717 return copy_result_to_buff(val_str, val_size, buff, buff_len);
718 }
719
u64_item_to_string(const struct prop_item * item,char * buff,size_t * buff_len)720 static TEE_Result u64_item_to_string(const struct prop_item *item, char *buff, size_t *buff_len)
721 {
722 char *val_str = NULL;
723 size_t val_size;
724 char u64_buff[U64_DECIMAL_MAX_STRLEN] = { 0 };
725
726 if (snprintf_s(u64_buff, sizeof(u64_buff), sizeof(u64_buff) - 1, "%llu", (unsigned long long)item->val) < 0)
727 return TEE_ERROR_GENERIC;
728
729 val_str = u64_buff;
730 val_size = strlen(u64_buff) + 1;
731 return copy_result_to_buff(val_str, val_size, buff, buff_len);
732 }
733
uuid_item_to_string(const struct prop_item * item,char * buff,size_t * buff_len)734 static TEE_Result uuid_item_to_string(const struct prop_item *item, char *buff, size_t *buff_len)
735 {
736 char uuid[UUID_FORMAT_STRLEN] = { 0 };
737
738 convert_uuid_to_str((const TEE_UUID *)item->val, uuid, sizeof(uuid));
739
740 return copy_result_to_buff(uuid, sizeof(uuid), buff, buff_len);
741 }
742
identity_item_to_string(const struct prop_item * item,char * buff,size_t * buff_len)743 static TEE_Result identity_item_to_string(const struct prop_item *item, char *buff, size_t *buff_len)
744 {
745 uint32_t add_pos = 0;
746 char u32_buff[U32_DECIMAL_MAX_STRLEN] = { 0 };
747 char uuid_buff[UUID_FORMAT_STRLEN] = { 0 };
748 char *identity_buff = NULL;
749 TEE_Result ret;
750
751 const TEE_Identity *identity = (const TEE_Identity *)(item->val);
752 if (identity == NULL) {
753 *buff = '\0';
754 return TEE_SUCCESS;
755 }
756
757 identity_buff = TEE_Malloc(IDENTITY_STRING_LEN, 0);
758 if (identity_buff == NULL) {
759 tloge("apply identity buff failed\n");
760 return TEE_ERROR_OUT_OF_MEMORY;
761 }
762
763 if (snprintf_s(u32_buff, sizeof(u32_buff), sizeof(u32_buff) - 1, "%u", identity->login) < 0) {
764 tloge("output u32 operation failed\n");
765 TEE_Free(identity_buff);
766 return TEE_ERROR_SECURITY;
767 }
768
769 convert_uuid_to_str(&identity->uuid, uuid_buff, UUID_FORMAT_STRLEN);
770 if (memcpy_s(identity_buff, IDENTITY_STRING_LEN, "identity:", strlen("identity:")) != EOK) {
771 tloge("copy itendity err2\n");
772 TEE_Free(identity_buff);
773 return TEE_ERROR_SECURITY;
774 }
775 add_pos += strlen("identity:");
776 if (memcpy_s(identity_buff + add_pos, IDENTITY_STRING_LEN - add_pos, u32_buff, strlen(u32_buff)) != EOK) {
777 tloge("copy identity err3\n");
778 TEE_Free(identity_buff);
779 return TEE_ERROR_SECURITY;
780 }
781 add_pos += (uint32_t)strlen(u32_buff);
782
783 *(identity_buff + add_pos) = ':';
784 add_pos++;
785
786 if (memcpy_s(identity_buff + add_pos, IDENTITY_STRING_LEN - add_pos, uuid_buff, UUID_FORMAT_STRLEN) != EOK) {
787 tloge("copy identity err4\n");
788 TEE_Free(identity_buff);
789 return TEE_ERROR_SECURITY;
790 }
791
792 ret = copy_result_to_buff(identity_buff, IDENTITY_STRING_LEN, buff, buff_len);
793 TEE_Free(identity_buff);
794
795 return ret;
796 }
797
798 typedef TEE_Result (*convert_item_to_str)(const struct prop_item *item, char *buff, size_t *buff_len);
799 struct type_func_mapping_t {
800 enum prop_type type;
801 convert_item_to_str func;
802 };
803
804 static const struct type_func_mapping_t g_type_func_map[] = {
805 { T_BINARY, raw_item_to_str },
806 { T_STRING, raw_item_to_str },
807 { T_BOOL, bool_item_to_str },
808 { T_U32, u32_item_to_string },
809 { T_U64, u64_item_to_string },
810 { T_UUID, uuid_item_to_string },
811 { T_IDENTITY, identity_item_to_string }
812 };
813
814 /*
815 * below APIs are defined by Global Platform or Platform SDK released previously
816 * for compatibility:
817 * don't change function name / return value type / parameters types / parameters names
818 */
TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,const char * name,char * valueBuffer,size_t * valueBufferLen)819 TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, const char *name, char *valueBuffer,
820 size_t *valueBufferLen)
821 {
822 struct prop_item *item = NULL;
823 TEE_Result ret = TEE_ERROR_ITEM_NOT_FOUND;
824 uint32_t i;
825
826 bool check = ((valueBuffer == NULL) || (valueBufferLen == NULL) || (*valueBufferLen == 0));
827 if (check) {
828 tloge("invalid parameter\n");
829 return TEE_ERROR_SHORT_BUFFER;
830 }
831
832 item = get_prop_item(propsetOrEnumerator, name);
833 if (item == NULL)
834 return TEE_ERROR_ITEM_NOT_FOUND;
835
836 for (i = 0; i < (sizeof(g_type_func_map) / sizeof(g_type_func_map[0])); i++) {
837 if (item->type == g_type_func_map[i].type) {
838 ret = g_type_func_map[i].func(item, valueBuffer, valueBufferLen);
839 break;
840 }
841 }
842
843 return ret;
844 }
845
TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator,const char * name,bool * value)846 TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, const char *name, bool *value)
847 {
848 struct prop_item *item = NULL;
849 int8_t ret;
850
851 if (value == NULL)
852 return TEE_ERROR_BAD_PARAMETERS;
853
854 item = get_prop_item(propsetOrEnumerator, name);
855 if (item == NULL)
856 return TEE_ERROR_ITEM_NOT_FOUND;
857
858 switch (item->type) {
859 case T_BOOL:
860 *value = (bool)(item->val);
861 break;
862 case T_STRING:
863 ret = convert_bool_str((char *)(item->val), item->val_len);
864 if (ret == PROP_INVALID)
865 return TEE_ERROR_BAD_FORMAT;
866
867 *value = (bool)ret;
868 break;
869 default:
870 return TEE_ERROR_BAD_FORMAT;
871 }
872
873 return TEE_SUCCESS;
874 }
875
TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator,const char * name,uint32_t * value)876 TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, const char *name, uint32_t *value)
877 {
878 struct prop_item *item = NULL;
879 char *endptr = NULL;
880 uint32_t tmp_val;
881
882 if (value == NULL) {
883 tloge("invalid parameter\n");
884 return TEE_ERROR_BAD_PARAMETERS;
885 }
886
887 item = get_prop_item(propsetOrEnumerator, name);
888 if (item == NULL)
889 return TEE_ERROR_ITEM_NOT_FOUND;
890
891 switch (item->type) {
892 case T_BOOL:
893 case T_U32:
894 *value = (uint32_t)(item->val);
895 break;
896 case T_STRING:
897 tmp_val = strtoul((char *)(item->val), &endptr, 0);
898
899 if (endptr != ((char *)(item->val) + item->val_len - 1))
900 return TEE_ERROR_BAD_FORMAT;
901
902 *value = tmp_val;
903 break;
904 default:
905 return TEE_ERROR_BAD_FORMAT;
906 }
907
908 return TEE_SUCCESS;
909 }
910
TEE_GetPropertyAsU64(TEE_PropSetHandle propsetOrEnumerator,const char * name,uint64_t * value)911 TEE_Result TEE_GetPropertyAsU64(TEE_PropSetHandle propsetOrEnumerator, const char *name, uint64_t *value)
912 {
913 struct prop_item *item = NULL;
914 char *endptr = NULL;
915 uint64_t tmp_val;
916
917 if (value == NULL) {
918 tloge("invalid parameter\n");
919 return TEE_ERROR_BAD_PARAMETERS;
920 }
921
922 item = get_prop_item(propsetOrEnumerator, name);
923 if (item == NULL)
924 return TEE_ERROR_ITEM_NOT_FOUND;
925
926 switch (item->type) {
927 case T_BOOL:
928 case T_U32:
929 case T_U64:
930 *value = (uint64_t)(item->val);
931 break;
932 case T_STRING:
933 tmp_val = (uint64_t)strtoull((char *)(item->val), &endptr, 0);
934
935 if (endptr != ((char *)(item->val) + item->val_len - 1))
936 return TEE_ERROR_BAD_FORMAT;
937
938 *value = tmp_val;
939 break;
940 default:
941 return TEE_ERROR_BAD_FORMAT;
942 }
943
944 return TEE_SUCCESS;
945 }
946
TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,const char * name,void * valueBuffer,size_t * valueBufferLen)947 TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, const char *name, void *valueBuffer,
948 size_t *valueBufferLen)
949 {
950 struct prop_item *item = NULL;
951 size_t val_size;
952
953 if ((valueBuffer == NULL) || (valueBufferLen == NULL)) {
954 tloge("invalid parameter\n");
955 return TEE_ERROR_SHORT_BUFFER;
956 }
957
958 item = get_prop_item(propsetOrEnumerator, name);
959 if (item == NULL)
960 return TEE_ERROR_ITEM_NOT_FOUND;
961
962 if ((item->type == T_BOOL) || (item->type == T_U32))
963 return TEE_ERROR_BAD_FORMAT;
964
965 val_size = item->val_len;
966
967 if (*valueBufferLen < val_size) {
968 *valueBufferLen = val_size;
969 return TEE_ERROR_SHORT_BUFFER;
970 }
971
972 if (memcpy_s(valueBuffer, val_size, (void *)(item->val), val_size) != EOK)
973 return TEE_ERROR_SECURITY;
974
975 *valueBufferLen = val_size;
976 return TEE_SUCCESS;
977 }
978
TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator,const char * name,TEE_UUID * value)979 TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, const char *name, TEE_UUID *value)
980 {
981 struct prop_item *item = NULL;
982 int32_t ret;
983 TEE_UUID uuid = { 0 };
984 errno_t rc;
985
986 if (value == NULL) {
987 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
988 return TEE_ERROR_BAD_PARAMETERS;
989 }
990
991 item = get_prop_item(propsetOrEnumerator, name);
992 if (item == NULL)
993 return TEE_ERROR_ITEM_NOT_FOUND;
994
995 switch (item->type) {
996 case T_UUID:
997 rc = memcpy_s(value, sizeof(*value), (void *)(item->val), sizeof(uuid));
998 if (rc != EOK) {
999 TEE_Panic(TEE_ERROR_SECURITY);
1000 return TEE_ERROR_SECURITY;
1001 }
1002 break;
1003 case T_STRING:
1004 ret = convert_str_to_uuid((char *)(item->val), item->val_len, &uuid);
1005 if (ret == PROP_ERROR)
1006 return TEE_ERROR_BAD_FORMAT;
1007
1008 rc = memcpy_s(value, sizeof(*value), &uuid, sizeof(uuid));
1009 if (rc != EOK) {
1010 TEE_Panic(TEE_ERROR_SECURITY);
1011 return TEE_ERROR_SECURITY;
1012 }
1013 break;
1014 default:
1015 return TEE_ERROR_BAD_FORMAT;
1016 }
1017
1018 return TEE_SUCCESS;
1019 }
1020
1021 #define CLOCK_SEQ_COUNT_IN_UUID 8
TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator,const char * name,TEE_Identity * identity)1022 TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, const char *name, TEE_Identity *identity)
1023 {
1024 struct prop_item *item = NULL;
1025
1026 if (identity == NULL) {
1027 tloge("invalid parameter\n");
1028 return TEE_ERROR_BAD_PARAMETERS;
1029 }
1030
1031 item = get_prop_item(propsetOrEnumerator, name);
1032 if (item == NULL)
1033 return TEE_ERROR_ITEM_NOT_FOUND;
1034
1035 switch (item->type) {
1036 case T_IDENTITY:
1037 if (item->val != 0) {
1038 if (memcpy_s(identity, sizeof(*identity), (void *)(item->val), sizeof(*identity)) != EOK)
1039 return TEE_ERROR_SECURITY;
1040 } else {
1041 (void)memset_s(identity, sizeof(*identity), 0, sizeof(*identity));
1042 }
1043 break;
1044 case T_STRING:
1045 if (convert_str_to_identity((char *)item->val, item->val_len, identity) != 0)
1046 return TEE_ERROR_BAD_FORMAT;
1047 break;
1048 default:
1049 return TEE_ERROR_BAD_FORMAT;
1050 }
1051
1052 return TEE_SUCCESS;
1053 }
1054
TEE_AllocatePropertyEnumerator(TEE_PropSetHandle * enumerator)1055 TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator)
1056 {
1057 struct enum_handle *handle = NULL;
1058 int32_t ret;
1059
1060 if (enumerator == NULL) {
1061 tloge("invalid parameter\n");
1062 return TEE_ERROR_BAD_PARAMETERS;
1063 }
1064
1065 handle = TEE_Malloc(sizeof(*handle), 0);
1066 if (handle == NULL)
1067 return TEE_ERROR_OUT_OF_MEMORY;
1068
1069 if (mutex_lock_ops(&g_bitmap_mutex) != 0) {
1070 TEE_Free(handle);
1071 return TEE_ERROR_GENERIC;
1072 }
1073 ret = get_valid_bit(g_handle_bitmap, TEE_PROPERTY_HANDLE_MAX);
1074 if (ret == PROP_ERROR) {
1075 (void)pthread_mutex_unlock(&g_bitmap_mutex);
1076 TEE_Free(handle);
1077 return TEE_ERROR_OUT_OF_MEMORY;
1078 }
1079
1080 handle->set = TEE_PROPSET_UNKNOW;
1081 handle->handle = (uint32_t)ret;
1082 set_bitmap(g_handle_bitmap, TEE_PROPERTY_HANDLE_MAX, handle->handle);
1083 (void)pthread_mutex_unlock(&g_bitmap_mutex);
1084 dlist_insert_tail(&handle->list, &g_enum_head);
1085
1086 *enumerator = (uint32_t)handle->handle;
1087 return TEE_SUCCESS;
1088 }
1089
TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator)1090 void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator)
1091 {
1092 if (!is_pseudo_handle(enumerator) || is_valid_enum_handle(enumerator)) {
1093 struct enum_handle *handle = find_enum_handle(enumerator);
1094 if (handle != NULL) {
1095 if (mutex_lock_ops(&g_bitmap_mutex) != 0)
1096 return;
1097 clear_bitmap(g_handle_bitmap, TEE_PROPERTY_HANDLE_MAX, enumerator);
1098 (void)pthread_mutex_unlock(&g_bitmap_mutex);
1099 dlist_delete(&handle->list);
1100 TEE_Free(handle);
1101 }
1102 }
1103 }
1104
TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator,TEE_PropSetHandle propSet)1105 void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, TEE_PropSetHandle propSet)
1106 {
1107 struct enum_handle *handle = NULL;
1108
1109 if (!is_pseudo_handle(propSet) || !is_valid_enum_handle(enumerator))
1110 return;
1111
1112 handle = find_enum_handle(enumerator);
1113 if (handle != NULL) {
1114 handle->set = (Pseudo_PropSetHandle)propSet;
1115 switch (handle->set) {
1116 case TEE_PROPSET_TEE_IMPLEMENTATION:
1117 handle->item = find_pseuprop_item(propSet, "gpd.tee.apiversion");
1118 break;
1119 case TEE_PROPSET_CURRENT_CLIENT:
1120 handle->item = find_pseuprop_item(propSet, "gpd.client.identity");
1121 break;
1122 case TEE_PROPSET_CURRENT_TA:
1123 handle->item = find_pseuprop_item(propSet, "gpd.ta.appID");
1124 break;
1125 default:
1126 tloge("invalid property type 0x%x\n", handle->set);
1127 break;
1128 }
1129 }
1130 }
1131
TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator)1132 void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator)
1133 {
1134 struct enum_handle *handle = NULL;
1135
1136 if (is_pseudo_handle(enumerator) || !is_valid_enum_handle(enumerator))
1137 return;
1138
1139 handle = find_enum_handle(enumerator);
1140 if (handle == NULL)
1141 return;
1142
1143 handle->set = TEE_PROPSET_UNKNOW;
1144 handle->item = NULL;
1145 }
1146
TEE_GetPropertyName(TEE_PropSetHandle enumerator,void * nameBuffer,size_t * nameBufferLen)1147 TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, void *nameBuffer, size_t *nameBufferLen)
1148 {
1149 struct enum_handle *handle = NULL;
1150 size_t name_size;
1151
1152 bool check = ((nameBuffer == NULL) || (nameBufferLen == NULL));
1153 if (check) {
1154 tloge("invalid parameter\n");
1155 return TEE_ERROR_BAD_PARAMETERS;
1156 }
1157
1158 check = (is_pseudo_handle(enumerator) || !is_valid_enum_handle(enumerator));
1159 if (check) {
1160 tloge("item no found\n");
1161 return TEE_ERROR_ITEM_NOT_FOUND;
1162 }
1163
1164 handle = find_enum_handle(enumerator);
1165 if (handle == NULL) {
1166 tloge("item no found\n");
1167 return TEE_ERROR_ITEM_NOT_FOUND;
1168 }
1169
1170 check = ((handle->set == TEE_PROPSET_UNKNOW) || (handle->item == NULL) || (handle->item->name == NULL) ||
1171 (strnlen(handle->item->name, MAX_PROPERTY_NAME_LEN) >= MAX_PROPERTY_NAME_LEN) ||
1172 (strnlen(handle->item->name, MAX_PROPERTY_NAME_LEN) == 0));
1173 if (check) {
1174 tloge("item no found or name invalid\n");
1175 return TEE_ERROR_ITEM_NOT_FOUND;
1176 }
1177
1178 name_size = strlen(handle->item->name) + 1;
1179 if (*nameBufferLen < name_size) {
1180 *nameBufferLen = name_size;
1181 return TEE_ERROR_SHORT_BUFFER;
1182 }
1183
1184 if (memcpy_s(nameBuffer, *nameBufferLen, handle->item->name, name_size) != EOK)
1185 return TEE_ERROR_GENERIC;
1186
1187 *nameBufferLen = name_size;
1188
1189 return TEE_SUCCESS;
1190 }
1191
TEE_GetNextProperty(TEE_PropSetHandle enumerator)1192 TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator)
1193 {
1194 struct enum_handle *handle = NULL;
1195
1196 if (is_pseudo_handle(enumerator) || !is_valid_enum_handle(enumerator))
1197 return TEE_ERROR_ITEM_NOT_FOUND;
1198
1199 handle = find_enum_handle(enumerator);
1200 if (handle == NULL)
1201 return TEE_ERROR_ITEM_NOT_FOUND;
1202
1203 if (!is_enumerator_started(handle))
1204 return TEE_ERROR_ITEM_NOT_FOUND;
1205
1206 if (is_last_item(handle->set, handle->item)) {
1207 handle->item = NULL;
1208 return TEE_ERROR_ITEM_NOT_FOUND;
1209 }
1210
1211 handle->item = dlist_entry(handle->item->list.next, struct prop_item, list);
1212 if (strcmp(handle->item->name, "") == 0) {
1213 tloge("next name is 0, error");
1214 return TEE_ERROR_ITEM_NOT_FOUND;
1215 }
1216 return TEE_SUCCESS;
1217 }
1218
tee_get_ta_api_level(void)1219 uint32_t tee_get_ta_api_level(void)
1220 {
1221 uint32_t value = 0;
1222
1223 if (TEE_GetPropertyAsU32(TEE_PROPSET_CURRENT_TA, "gpd.ta.api_level", &value) != TEE_SUCCESS)
1224 return API_LEVEL1_0;
1225
1226 return value;
1227 }
1228