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