11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 46915bbbbSJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 5b0104773SPascal Brand */ 6a32a96edSJens Wiklander #include <printk.h> 7a32a96edSJens Wiklander #include <stdio.h> 8b0104773SPascal Brand #include <stdlib.h> 9b0104773SPascal Brand #include <string.h> 10b0104773SPascal Brand #include <tee_api_defines.h> 11a32a96edSJens Wiklander #include <tee_api.h> 12b0104773SPascal Brand #include <tee_api_types.h> 13647f9c76SJerome Forissier #include <tee_arith_internal.h> 14a32a96edSJens Wiklander #include <tee_internal_api_extensions.h> 15a32a96edSJens Wiklander #include <tee_isocket.h> 16a32a96edSJens Wiklander #include <user_ta_header.h> 17b0104773SPascal Brand #include <utee_syscalls.h> 18a32a96edSJens Wiklander #include <util.h> 19b0104773SPascal Brand 20b0104773SPascal Brand #include "base64.h" 216915bbbbSJens Wiklander #include "string_ext.h" 226915bbbbSJens Wiklander #include "tee_api_private.h" 23b0104773SPascal Brand 24b0104773SPascal Brand #define PROP_STR_MAX 80 25b0104773SPascal Brand 26b0104773SPascal Brand #define PROP_ENUMERATOR_NOT_STARTED 0xffffffff 27b0104773SPascal Brand 28b0104773SPascal Brand struct prop_enumerator { 2964a5011eSPascal Brand uint32_t idx; /* current index */ 3064a5011eSPascal Brand TEE_PropSetHandle prop_set; /* part of TEE_PROPSET_xxx */ 31b0104773SPascal Brand }; 32b0104773SPascal Brand 3364a5011eSPascal Brand const struct user_ta_property tee_props[] = { 3464a5011eSPascal Brand { 3564a5011eSPascal Brand "gpd.tee.arith.maxBigIntSize", 3664a5011eSPascal Brand USER_TA_PROP_TYPE_U32, 37e3458e03SJerome Forissier &(const uint32_t){CFG_TA_BIGNUM_MAX_BITS} 3864a5011eSPascal Brand }, 39a32a96edSJens Wiklander { 40a32a96edSJens Wiklander "gpd.tee.sockets.version", 41a32a96edSJens Wiklander USER_TA_PROP_TYPE_U32, 42a32a96edSJens Wiklander &(const uint32_t){TEE_ISOCKET_VERSION} 43a32a96edSJens Wiklander }, 44a32a96edSJens Wiklander { 45a32a96edSJens Wiklander "gpd.tee.sockets.tcp.version", 46a32a96edSJens Wiklander USER_TA_PROP_TYPE_U32, 47a32a96edSJens Wiklander &(const uint32_t){TEE_ISOCKET_VERSION} 48a32a96edSJens Wiklander }, 49094120adSJens Wiklander { 50094120adSJens Wiklander "gpd.tee.internalCore.version", 51094120adSJens Wiklander USER_TA_PROP_TYPE_U32, 52094120adSJens Wiklander &(const uint32_t){TEE_CORE_API_VERSION} 53094120adSJens Wiklander }, 54b0104773SPascal Brand }; 55b0104773SPascal Brand 5664a5011eSPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, 57b0104773SPascal Brand const struct user_ta_property **eps, 58b0104773SPascal Brand size_t *eps_len) 59b0104773SPascal Brand { 60b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA) { 61b0104773SPascal Brand *eps = ta_props; 62b0104773SPascal Brand *eps_len = ta_num_props; 63b0104773SPascal Brand } else if (h == TEE_PROPSET_CURRENT_CLIENT) { 64b0104773SPascal Brand *eps = NULL; 65b0104773SPascal Brand *eps_len = 0; 66b0104773SPascal Brand } else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) { 6764a5011eSPascal Brand *eps = tee_props; 6864a5011eSPascal Brand *eps_len = ARRAY_SIZE(tee_props); 69b0104773SPascal Brand } else { 70b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 71b0104773SPascal Brand } 72b0104773SPascal Brand 73b0104773SPascal Brand return TEE_SUCCESS; 74b0104773SPascal Brand } 75b0104773SPascal Brand 76b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep, 77ff857a3aSPascal Brand enum user_ta_prop_type *type, 78ff857a3aSPascal Brand void *buf, uint32_t *len) 79b0104773SPascal Brand { 80b0104773SPascal Brand size_t l; 81b0104773SPascal Brand 82ff857a3aSPascal Brand *type = ep->type; 83ff857a3aSPascal Brand switch (*type) { 84b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 85d5d50c3cSJens Wiklander l = sizeof(bool); 86b0104773SPascal Brand break; 87b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 88b0104773SPascal Brand l = sizeof(uint32_t); 89b0104773SPascal Brand break; 906551d565SJens Wiklander case USER_TA_PROP_TYPE_U64: 916551d565SJens Wiklander l = sizeof(uint64_t); 926551d565SJens Wiklander break; 93b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 94b0104773SPascal Brand l = sizeof(TEE_UUID); 95b0104773SPascal Brand break; 96b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 97b0104773SPascal Brand l = sizeof(TEE_Identity); 98b0104773SPascal Brand break; 99b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 100ff857a3aSPascal Brand /* take the leading 0 into account */ 101ff857a3aSPascal Brand l = strlen(ep->value) + 1; 102ff857a3aSPascal Brand break; 103b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 104ff857a3aSPascal Brand /* 105ff857a3aSPascal Brand * in case of TA property, a binary block is provided as a 106ff857a3aSPascal Brand * string, which is base64 encoded. We must first decode it, 107ff857a3aSPascal Brand * without taking into account the zero termination of the 108ff857a3aSPascal Brand * string 109ff857a3aSPascal Brand */ 110ff857a3aSPascal Brand l = *len; 11197b8ba50SJerome Forissier if (!_base64_dec(ep->value, strlen(ep->value), buf, &l) && 112ec930caeSJerome Forissier l <= *len) 113ff857a3aSPascal Brand return TEE_ERROR_GENERIC; 114ff857a3aSPascal Brand if (*len < l) { 115ff857a3aSPascal Brand *len = l; 116ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 117ff857a3aSPascal Brand } 118ff857a3aSPascal Brand 119ff857a3aSPascal Brand *len = l; 120b0104773SPascal Brand return TEE_SUCCESS; 121b0104773SPascal Brand default: 122b0104773SPascal Brand return TEE_ERROR_GENERIC; 123b0104773SPascal Brand } 124ff857a3aSPascal Brand 125ff857a3aSPascal Brand if (*len < l) { 126ff857a3aSPascal Brand *len = l; 127ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 128ff857a3aSPascal Brand } 129ff857a3aSPascal Brand 130ff857a3aSPascal Brand *len = l; 131ff857a3aSPascal Brand memcpy(buf, ep->value, l); 132b0104773SPascal Brand return TEE_SUCCESS; 133b0104773SPascal Brand } 134b0104773SPascal Brand 1356915bbbbSJens Wiklander static bool is_propset_pseudo_handle(TEE_PropSetHandle h) 1366915bbbbSJens Wiklander { 1376915bbbbSJens Wiklander return h == TEE_PROPSET_CURRENT_TA || 1386915bbbbSJens Wiklander h == TEE_PROPSET_CURRENT_CLIENT || 1396915bbbbSJens Wiklander h == TEE_PROPSET_TEE_IMPLEMENTATION; 1406915bbbbSJens Wiklander } 1416915bbbbSJens Wiklander 1428f07fe6fSJerome Forissier static TEE_Result propget_get_property(TEE_PropSetHandle h, const char *name, 143ff857a3aSPascal Brand enum user_ta_prop_type *type, 144ff857a3aSPascal Brand void *buf, uint32_t *len) 145b0104773SPascal Brand { 146b0104773SPascal Brand TEE_Result res; 147b0104773SPascal Brand const struct user_ta_property *eps; 148b0104773SPascal Brand size_t eps_len; 14964a5011eSPascal Brand uint32_t prop_type; 15064a5011eSPascal Brand uint32_t index; 151b0104773SPascal Brand 1526915bbbbSJens Wiklander if (is_propset_pseudo_handle(h)) { 153b0104773SPascal Brand size_t n; 154b0104773SPascal Brand 15564a5011eSPascal Brand res = propset_get(h, &eps, &eps_len); 156b0104773SPascal Brand if (res != TEE_SUCCESS) 157b0104773SPascal Brand return res; 158b0104773SPascal Brand 159b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 16064a5011eSPascal Brand if (!strcmp(name, eps[n].name)) 161ff857a3aSPascal Brand return propget_get_ext_prop(eps + n, type, 162ff857a3aSPascal Brand buf, len); 163b0104773SPascal Brand } 16464a5011eSPascal Brand 16564a5011eSPascal Brand /* get the index from the name */ 1662c028fdeSJerome Forissier res = _utee_get_property_name_to_index((unsigned long)h, name, 1672c028fdeSJerome Forissier strlen(name) + 1, 1682c028fdeSJerome Forissier &index); 16964a5011eSPascal Brand if (res != TEE_SUCCESS) 17064a5011eSPascal Brand return res; 1712c028fdeSJerome Forissier res = _utee_get_property((unsigned long)h, index, NULL, NULL, 172ff857a3aSPascal Brand buf, len, &prop_type); 173b0104773SPascal Brand } else { 174b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)h; 175b0104773SPascal Brand uint32_t idx = pe->idx; 176b0104773SPascal Brand 177b0104773SPascal Brand if (idx == PROP_ENUMERATOR_NOT_STARTED) 178b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 179b0104773SPascal Brand 18064a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 181b0104773SPascal Brand if (res != TEE_SUCCESS) 182b0104773SPascal Brand return res; 183b0104773SPascal Brand 184b0104773SPascal Brand if (idx < eps_len) 185ff857a3aSPascal Brand return propget_get_ext_prop(eps + idx, type, buf, len); 18664a5011eSPascal Brand idx -= eps_len; 187b0104773SPascal Brand 1882c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, idx, 189ff857a3aSPascal Brand NULL, NULL, buf, len, &prop_type); 19064a5011eSPascal Brand if (res == TEE_ERROR_ITEM_NOT_FOUND) 19164a5011eSPascal Brand res = TEE_ERROR_BAD_PARAMETERS; 192b0104773SPascal Brand } 19364a5011eSPascal Brand 194ff857a3aSPascal Brand *type = prop_type; 19564a5011eSPascal Brand return res; 196b0104773SPascal Brand } 197b0104773SPascal Brand 198b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 1998f07fe6fSJerome Forissier const char *name, char *value, 2006551d565SJens Wiklander size_t *value_len) 201b0104773SPascal Brand { 202*4d6266daSClement Faure TEE_Result res = TEE_ERROR_GENERIC; 203*4d6266daSClement Faure size_t l = 0; 204a1f2c430SClement Faure enum user_ta_prop_type type = USER_TA_PROP_TYPE_INVALID; 205ff857a3aSPascal Brand void *tmp_buf = 0; 206*4d6266daSClement Faure uint32_t tmp_len = 0; 207*4d6266daSClement Faure uint32_t uint32_val = 0; 208*4d6266daSClement Faure bool bool_val = false; 209*4d6266daSClement Faure TEE_Identity *p_identity_val = NULL; 210b0104773SPascal Brand 2116915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 2126915bbbbSJens Wiklander __utee_check_instring_annotation(name); 2136915bbbbSJens Wiklander __utee_check_outstring_annotation(value, value_len); 214b0104773SPascal Brand 2150dd3f3a4SPascal Brand tmp_len = *value_len; 216ff857a3aSPascal Brand if (tmp_len < sizeof(TEE_Identity)) 217ff857a3aSPascal Brand tmp_len = sizeof(TEE_Identity); 218ff857a3aSPascal Brand tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 219ff857a3aSPascal Brand if (!tmp_buf) { 220ff857a3aSPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 221ff857a3aSPascal Brand goto out; 222ff857a3aSPascal Brand } 223b0104773SPascal Brand 224ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 225ff857a3aSPascal Brand tmp_buf, &tmp_len); 226ff857a3aSPascal Brand if (res != TEE_SUCCESS) { 227254e1d58SPascal Brand if (res == TEE_ERROR_SHORT_BUFFER) { 228254e1d58SPascal Brand if (type == USER_TA_PROP_TYPE_BINARY_BLOCK) { 229254e1d58SPascal Brand /* 230254e1d58SPascal Brand * in this case, we must enlarge the buffer 231254e1d58SPascal Brand * with the size of the of the base64 encoded 232254e1d58SPascal Brand * see base64_enc() function 233254e1d58SPascal Brand */ 23497b8ba50SJerome Forissier tmp_len = _base64_enc_len(tmp_len); 235254e1d58SPascal Brand } 2360dd3f3a4SPascal Brand *value_len = tmp_len; 237254e1d58SPascal Brand } 238ff857a3aSPascal Brand goto out; 239ff857a3aSPascal Brand } 240b0104773SPascal Brand 241ff857a3aSPascal Brand switch (type) { 242b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 243d5d50c3cSJens Wiklander bool_val = *((bool *)tmp_buf); 244d5d50c3cSJens Wiklander l = strlcpy(value, (bool_val ? "true" : "false"), *value_len); 245b0104773SPascal Brand break; 246b0104773SPascal Brand 247b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 248ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 2490dd3f3a4SPascal Brand l = snprintf(value, *value_len, "%u", uint32_val); 250b0104773SPascal Brand break; 251b0104773SPascal Brand 252b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 2530dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%pUl", tmp_buf); 254b0104773SPascal Brand break; 255b0104773SPascal Brand 256b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 257ff857a3aSPascal Brand p_identity_val = ((TEE_Identity *)tmp_buf); 2580dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%u:%pUl", 259ff857a3aSPascal Brand p_identity_val->login, 260ff857a3aSPascal Brand (void *)(&(p_identity_val->uuid))); 261b0104773SPascal Brand break; 262b0104773SPascal Brand 263b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 2640dd3f3a4SPascal Brand l = strlcpy(value, tmp_buf, *value_len); 265ff857a3aSPascal Brand break; 266ff857a3aSPascal Brand 267b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 2680dd3f3a4SPascal Brand l = *value_len; /* l includes the zero-termination */ 26997b8ba50SJerome Forissier if (!_base64_enc(tmp_buf, tmp_len, value, &l) && 270ec930caeSJerome Forissier l <= *value_len) { 271ff857a3aSPascal Brand res = TEE_ERROR_GENERIC; 272ff857a3aSPascal Brand goto out; 273ff857a3aSPascal Brand } 274ff857a3aSPascal Brand l--; /* remove the zero-termination that is added later */ 275b0104773SPascal Brand break; 276b0104773SPascal Brand 277b0104773SPascal Brand default: 278ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 279ba675d69SCedric Chaumont goto out; 280ff857a3aSPascal Brand } 281ba675d69SCedric Chaumont 282ff857a3aSPascal Brand l++; /* include zero termination */ 283ff857a3aSPascal Brand 2840dd3f3a4SPascal Brand if (l > *value_len) 285ff857a3aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 2860dd3f3a4SPascal Brand *value_len = l; 287ff857a3aSPascal Brand 288ba675d69SCedric Chaumont out: 289ff857a3aSPascal Brand if (tmp_buf) 290ff857a3aSPascal Brand TEE_Free(tmp_buf); 291ff857a3aSPascal Brand if (res != TEE_SUCCESS && 292ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 293ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 294ff857a3aSPascal Brand TEE_Panic(0); 295ff857a3aSPascal Brand 296ff857a3aSPascal Brand return res; 297b0104773SPascal Brand } 298b0104773SPascal Brand 2996551d565SJens Wiklander TEE_Result __GP11_TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 3006551d565SJens Wiklander const char *name, char *valueBuffer, 3016551d565SJens Wiklander uint32_t *valueBufferLen) 3026551d565SJens Wiklander { 3036551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 3046551d565SJens Wiklander size_t l = 0; 3056551d565SJens Wiklander 3066551d565SJens Wiklander __utee_check_gp11_outstring_annotation(valueBuffer, valueBufferLen); 3076551d565SJens Wiklander l = *valueBufferLen; 3086551d565SJens Wiklander res = TEE_GetPropertyAsString(propsetOrEnumerator, name, valueBuffer, 3096551d565SJens Wiklander &l); 3106551d565SJens Wiklander *valueBufferLen = l; 3116551d565SJens Wiklander return res; 3126551d565SJens Wiklander } 3136551d565SJens Wiklander 314b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 3158f07fe6fSJerome Forissier const char *name, bool *value) 316b0104773SPascal Brand { 317b0104773SPascal Brand TEE_Result res; 318ff857a3aSPascal Brand enum user_ta_prop_type type; 319d5d50c3cSJens Wiklander uint32_t bool_len = sizeof(bool); 3206915bbbbSJens Wiklander 3216915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 3226915bbbbSJens Wiklander __utee_check_instring_annotation(name); 3236915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 324b0104773SPascal Brand 325ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BOOL; 326ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 327d5d50c3cSJens Wiklander value, &bool_len); 328ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BOOL) 329ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 330ff857a3aSPascal Brand if (res != TEE_SUCCESS) 331ba675d69SCedric Chaumont goto out; 332ba675d69SCedric Chaumont 333ba675d69SCedric Chaumont out: 334ff857a3aSPascal Brand if (res != TEE_SUCCESS && 335ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 336ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 337ff857a3aSPascal Brand TEE_Panic(0); 338ff857a3aSPascal Brand 339ff857a3aSPascal Brand return res; 340b0104773SPascal Brand } 341b0104773SPascal Brand 342b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, 3438f07fe6fSJerome Forissier const char *name, uint32_t *value) 344b0104773SPascal Brand { 345b0104773SPascal Brand TEE_Result res; 346ff857a3aSPascal Brand enum user_ta_prop_type type; 347ff857a3aSPascal Brand uint32_t uint32_len = sizeof(uint32_t); 348b0104773SPascal Brand 3496915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 3506915bbbbSJens Wiklander __utee_check_instring_annotation(name); 3516915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 352ba675d69SCedric Chaumont 353ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_U32; 354ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 355ff857a3aSPascal Brand value, &uint32_len); 356ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_U32) 357ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 358ff857a3aSPascal Brand 359ff857a3aSPascal Brand if (res != TEE_SUCCESS && 360ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 361ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 362ff857a3aSPascal Brand TEE_Panic(0); 363ff857a3aSPascal Brand 364ff857a3aSPascal Brand return res; 365b0104773SPascal Brand } 366b0104773SPascal Brand 3676551d565SJens Wiklander TEE_Result TEE_GetPropertyAsU64(TEE_PropSetHandle propsetOrEnumerator, 3686551d565SJens Wiklander const char *name, uint64_t *value) 369b0104773SPascal Brand { 370b0104773SPascal Brand TEE_Result res; 371ff857a3aSPascal Brand enum user_ta_prop_type type; 3726551d565SJens Wiklander uint32_t uint64_len = sizeof(*value); 373b0104773SPascal Brand 3746915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 3756915bbbbSJens Wiklander __utee_check_instring_annotation(name); 3766551d565SJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 3776551d565SJens Wiklander 3786551d565SJens Wiklander type = USER_TA_PROP_TYPE_U64; 3796551d565SJens Wiklander res = propget_get_property(propsetOrEnumerator, name, &type, 3806551d565SJens Wiklander value, &uint64_len); 3816551d565SJens Wiklander if (type != USER_TA_PROP_TYPE_U64) 3826551d565SJens Wiklander res = TEE_ERROR_BAD_FORMAT; 3836551d565SJens Wiklander 3846551d565SJens Wiklander if (res != TEE_SUCCESS && 3856551d565SJens Wiklander res != TEE_ERROR_ITEM_NOT_FOUND && 3866551d565SJens Wiklander res != TEE_ERROR_BAD_FORMAT) 3876551d565SJens Wiklander TEE_Panic(0); 3886551d565SJens Wiklander 3896551d565SJens Wiklander return res; 3906551d565SJens Wiklander } 3916551d565SJens Wiklander 3926551d565SJens Wiklander TEE_Result 3936551d565SJens Wiklander __GP11_TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 3946551d565SJens Wiklander const char *name, void *value, 3956551d565SJens Wiklander uint32_t *value_len) 3966551d565SJens Wiklander { 3976551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 3986551d565SJens Wiklander enum user_ta_prop_type type = USER_TA_PROP_TYPE_BOOL; 3996551d565SJens Wiklander 4006551d565SJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 4016551d565SJens Wiklander __utee_check_instring_annotation(name); 4026551d565SJens Wiklander __utee_check_gp11_outbuf_annotation(value, value_len); 403ba675d69SCedric Chaumont 404ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BINARY_BLOCK; 405ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 4060dd3f3a4SPascal Brand value, value_len); 407ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BINARY_BLOCK) 408ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 409ff857a3aSPascal Brand 410ff857a3aSPascal Brand if (res != TEE_SUCCESS && 411ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 412ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT && 413ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 414ff857a3aSPascal Brand TEE_Panic(0); 415ff857a3aSPascal Brand 416ff857a3aSPascal Brand return res; 417b0104773SPascal Brand } 418b0104773SPascal Brand 4196551d565SJens Wiklander TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 4206551d565SJens Wiklander const char *name, void *value, 4216551d565SJens Wiklander size_t *value_len) 4226551d565SJens Wiklander { 4236551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 4246551d565SJens Wiklander uint32_t l = 0; 4256551d565SJens Wiklander 4266551d565SJens Wiklander __utee_check_outbuf_annotation(value, value_len); 4276551d565SJens Wiklander l = *value_len; 4286551d565SJens Wiklander res = __GP11_TEE_GetPropertyAsBinaryBlock(propsetOrEnumerator, name, 4296551d565SJens Wiklander value, &l); 4306551d565SJens Wiklander *value_len = l; 4316551d565SJens Wiklander return res; 4326551d565SJens Wiklander } 4336551d565SJens Wiklander 434b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 4358f07fe6fSJerome Forissier const char *name, TEE_UUID *value) 436b0104773SPascal Brand { 437b0104773SPascal Brand TEE_Result res; 438ff857a3aSPascal Brand enum user_ta_prop_type type; 439ff857a3aSPascal Brand uint32_t uuid_len = sizeof(TEE_UUID); 440b0104773SPascal Brand 4416915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 4426915bbbbSJens Wiklander __utee_check_instring_annotation(name); 4436915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 444ba675d69SCedric Chaumont 445ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_UUID; 446ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 447ff857a3aSPascal Brand value, &uuid_len); 448ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_UUID) 449ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 450ff857a3aSPascal Brand 451ff857a3aSPascal Brand if (res != TEE_SUCCESS && 452ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 453ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 454ff857a3aSPascal Brand TEE_Panic(0); 455ff857a3aSPascal Brand 456ff857a3aSPascal Brand return res; 457b0104773SPascal Brand } 458b0104773SPascal Brand 459b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, 4608f07fe6fSJerome Forissier const char *name, TEE_Identity *value) 461b0104773SPascal Brand { 462b0104773SPascal Brand TEE_Result res; 463ff857a3aSPascal Brand enum user_ta_prop_type type; 464ff857a3aSPascal Brand uint32_t identity_len = sizeof(TEE_Identity); 465b0104773SPascal Brand 4666915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 4676915bbbbSJens Wiklander __utee_check_instring_annotation(name); 4686915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 469ba675d69SCedric Chaumont 470ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_IDENTITY; 471ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 472ff857a3aSPascal Brand value, &identity_len); 473ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_IDENTITY) 474ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 475ff857a3aSPascal Brand 476ff857a3aSPascal Brand if (res != TEE_SUCCESS && 477ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 478ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 479ff857a3aSPascal Brand TEE_Panic(0); 480ff857a3aSPascal Brand 481ff857a3aSPascal Brand return res; 482b0104773SPascal Brand } 483b0104773SPascal Brand 484b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 485b0104773SPascal Brand { 486ba675d69SCedric Chaumont TEE_Result res; 487b0104773SPascal Brand struct prop_enumerator *pe; 488b0104773SPascal Brand 4896915bbbbSJens Wiklander __utee_check_out_annotation(enumerator, sizeof(*enumerator)); 490b0104773SPascal Brand 491b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 492b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 493ba675d69SCedric Chaumont if (pe == NULL) { 494ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 495ba675d69SCedric Chaumont goto err; 496ba675d69SCedric Chaumont } 497b0104773SPascal Brand 498b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 499b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 500ba675d69SCedric Chaumont 501ba675d69SCedric Chaumont goto out; 502ba675d69SCedric Chaumont 503ba675d69SCedric Chaumont err: 504ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 505ba675d69SCedric Chaumont return res; 506ba675d69SCedric Chaumont TEE_Panic(0); 507ba675d69SCedric Chaumont out: 508b0104773SPascal Brand return TEE_SUCCESS; 509b0104773SPascal Brand } 510b0104773SPascal Brand 511b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 512b0104773SPascal Brand { 513b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 514b0104773SPascal Brand 515b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 516b0104773SPascal Brand } 517b0104773SPascal Brand 518b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 519b0104773SPascal Brand { 520b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 521b0104773SPascal Brand 522b0104773SPascal Brand TEE_Free(pe); 523b0104773SPascal Brand } 524b0104773SPascal Brand 525b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 526b0104773SPascal Brand TEE_PropSetHandle propSet) 527b0104773SPascal Brand { 528b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 529b0104773SPascal Brand 5300dd3f3a4SPascal Brand if (!pe) 531b0104773SPascal Brand return; 532b0104773SPascal Brand 533b0104773SPascal Brand pe->idx = 0; 534b0104773SPascal Brand pe->prop_set = propSet; 535b0104773SPascal Brand } 536b0104773SPascal Brand 5376551d565SJens Wiklander TEE_Result __GP11_TEE_GetPropertyName(TEE_PropSetHandle enumerator, 5380dd3f3a4SPascal Brand void *name, uint32_t *name_len) 539b0104773SPascal Brand { 540b0104773SPascal Brand TEE_Result res; 541b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 542b0104773SPascal Brand const struct user_ta_property *eps; 543b0104773SPascal Brand size_t eps_len; 544b0104773SPascal Brand const char *str; 545b0104773SPascal Brand size_t bufferlen; 546b0104773SPascal Brand 5476915bbbbSJens Wiklander if (!pe) { 548ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 549ba675d69SCedric Chaumont goto err; 550ba675d69SCedric Chaumont } 5516551d565SJens Wiklander __utee_check_gp11_outstring_annotation(name, name_len); 552b0104773SPascal Brand 5530dd3f3a4SPascal Brand bufferlen = *name_len; 55464a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 555b0104773SPascal Brand if (res != TEE_SUCCESS) 556ba675d69SCedric Chaumont goto err; 557b0104773SPascal Brand 55864a5011eSPascal Brand if (pe->idx < eps_len) { 55964a5011eSPascal Brand str = eps[pe->idx].name; 5600dd3f3a4SPascal Brand bufferlen = strlcpy(name, str, *name_len) + 1; 5610dd3f3a4SPascal Brand if (bufferlen > *name_len) 562ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 5630dd3f3a4SPascal Brand *name_len = bufferlen; 56464a5011eSPascal Brand } else { 5652c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 5662c028fdeSJerome Forissier pe->idx - eps_len, name, name_len, 5672c028fdeSJerome Forissier NULL, NULL, NULL); 56864a5011eSPascal Brand if (res != TEE_SUCCESS) 569ba675d69SCedric Chaumont goto err; 570ba675d69SCedric Chaumont } 571b0104773SPascal Brand 572ba675d69SCedric Chaumont err: 57364a5011eSPascal Brand if (res != TEE_SUCCESS && 57464a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 57564a5011eSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 576ba675d69SCedric Chaumont TEE_Panic(0); 57764a5011eSPascal Brand return res; 578b0104773SPascal Brand } 579b0104773SPascal Brand 5806551d565SJens Wiklander TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 5816551d565SJens Wiklander void *nameBuffer, size_t *nameBufferLen) 5826551d565SJens Wiklander { 5836551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 5846551d565SJens Wiklander uint32_t l = 0; 5856551d565SJens Wiklander 5866551d565SJens Wiklander __utee_check_outstring_annotation(nameBuffer, nameBufferLen); 5876551d565SJens Wiklander l = *nameBufferLen; 5886551d565SJens Wiklander res = __GP11_TEE_GetPropertyName(enumerator, nameBuffer, &l); 5896551d565SJens Wiklander *nameBufferLen = l; 5906551d565SJens Wiklander return res; 5916551d565SJens Wiklander } 5926551d565SJens Wiklander 593b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 594b0104773SPascal Brand { 595b0104773SPascal Brand TEE_Result res; 596b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 597b0104773SPascal Brand uint32_t next_idx; 598b0104773SPascal Brand const struct user_ta_property *eps; 599b0104773SPascal Brand size_t eps_len; 600b0104773SPascal Brand 6010dd3f3a4SPascal Brand if (!pe) { 602ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 60364a5011eSPascal Brand goto out; 604ba675d69SCedric Chaumont } 605b0104773SPascal Brand 606ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 607ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 60864a5011eSPascal Brand goto out; 609ba675d69SCedric Chaumont } 610b0104773SPascal Brand 61164a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 612b0104773SPascal Brand if (res != TEE_SUCCESS) 61364a5011eSPascal Brand goto out; 614b0104773SPascal Brand 615b0104773SPascal Brand next_idx = pe->idx + 1; 616b0104773SPascal Brand pe->idx = next_idx; 61764a5011eSPascal Brand if (next_idx < eps_len) 61864a5011eSPascal Brand res = TEE_SUCCESS; 61964a5011eSPascal Brand else 6202c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 6212c028fdeSJerome Forissier next_idx - eps_len, NULL, NULL, NULL, 6222c028fdeSJerome Forissier NULL, NULL); 623b0104773SPascal Brand 624ba675d69SCedric Chaumont out: 62564a5011eSPascal Brand if (res != TEE_SUCCESS && 62664a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND) 62764a5011eSPascal Brand TEE_Panic(0); 62864a5011eSPascal Brand return res; 629b0104773SPascal Brand } 630