11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 4*6915bbbbSJens 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" 21*6915bbbbSJens Wiklander #include "string_ext.h" 22*6915bbbbSJens 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 }, 49b0104773SPascal Brand }; 50b0104773SPascal Brand 5164a5011eSPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, 52b0104773SPascal Brand const struct user_ta_property **eps, 53b0104773SPascal Brand size_t *eps_len) 54b0104773SPascal Brand { 55b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA) { 56b0104773SPascal Brand *eps = ta_props; 57b0104773SPascal Brand *eps_len = ta_num_props; 58b0104773SPascal Brand } else if (h == TEE_PROPSET_CURRENT_CLIENT) { 59b0104773SPascal Brand *eps = NULL; 60b0104773SPascal Brand *eps_len = 0; 61b0104773SPascal Brand } else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) { 6264a5011eSPascal Brand *eps = tee_props; 6364a5011eSPascal Brand *eps_len = ARRAY_SIZE(tee_props); 64b0104773SPascal Brand } else { 65b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 66b0104773SPascal Brand } 67b0104773SPascal Brand 68b0104773SPascal Brand return TEE_SUCCESS; 69b0104773SPascal Brand } 70b0104773SPascal Brand 71b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep, 72ff857a3aSPascal Brand enum user_ta_prop_type *type, 73ff857a3aSPascal Brand void *buf, uint32_t *len) 74b0104773SPascal Brand { 75b0104773SPascal Brand size_t l; 76b0104773SPascal Brand 77ff857a3aSPascal Brand *type = ep->type; 78ff857a3aSPascal Brand switch (*type) { 79b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 80d5d50c3cSJens Wiklander l = sizeof(bool); 81b0104773SPascal Brand break; 82b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 83b0104773SPascal Brand l = sizeof(uint32_t); 84b0104773SPascal Brand break; 85b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 86b0104773SPascal Brand l = sizeof(TEE_UUID); 87b0104773SPascal Brand break; 88b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 89b0104773SPascal Brand l = sizeof(TEE_Identity); 90b0104773SPascal Brand break; 91b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 92ff857a3aSPascal Brand /* take the leading 0 into account */ 93ff857a3aSPascal Brand l = strlen(ep->value) + 1; 94ff857a3aSPascal Brand break; 95b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 96ff857a3aSPascal Brand /* 97ff857a3aSPascal Brand * in case of TA property, a binary block is provided as a 98ff857a3aSPascal Brand * string, which is base64 encoded. We must first decode it, 99ff857a3aSPascal Brand * without taking into account the zero termination of the 100ff857a3aSPascal Brand * string 101ff857a3aSPascal Brand */ 102ff857a3aSPascal Brand l = *len; 10397b8ba50SJerome Forissier if (!_base64_dec(ep->value, strlen(ep->value), buf, &l) && 104ec930caeSJerome Forissier l <= *len) 105ff857a3aSPascal Brand return TEE_ERROR_GENERIC; 106ff857a3aSPascal Brand if (*len < l) { 107ff857a3aSPascal Brand *len = l; 108ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 109ff857a3aSPascal Brand } 110ff857a3aSPascal Brand 111ff857a3aSPascal Brand *len = l; 112b0104773SPascal Brand return TEE_SUCCESS; 113b0104773SPascal Brand default: 114b0104773SPascal Brand return TEE_ERROR_GENERIC; 115b0104773SPascal Brand } 116ff857a3aSPascal Brand 117ff857a3aSPascal Brand if (*len < l) { 118ff857a3aSPascal Brand *len = l; 119ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 120ff857a3aSPascal Brand } 121ff857a3aSPascal Brand 122ff857a3aSPascal Brand *len = l; 123ff857a3aSPascal Brand memcpy(buf, ep->value, l); 124b0104773SPascal Brand return TEE_SUCCESS; 125b0104773SPascal Brand } 126b0104773SPascal Brand 127*6915bbbbSJens Wiklander static bool is_propset_pseudo_handle(TEE_PropSetHandle h) 128*6915bbbbSJens Wiklander { 129*6915bbbbSJens Wiklander return h == TEE_PROPSET_CURRENT_TA || 130*6915bbbbSJens Wiklander h == TEE_PROPSET_CURRENT_CLIENT || 131*6915bbbbSJens Wiklander h == TEE_PROPSET_TEE_IMPLEMENTATION; 132*6915bbbbSJens Wiklander } 133*6915bbbbSJens Wiklander 1348f07fe6fSJerome Forissier static TEE_Result propget_get_property(TEE_PropSetHandle h, const char *name, 135ff857a3aSPascal Brand enum user_ta_prop_type *type, 136ff857a3aSPascal Brand void *buf, uint32_t *len) 137b0104773SPascal Brand { 138b0104773SPascal Brand TEE_Result res; 139b0104773SPascal Brand const struct user_ta_property *eps; 140b0104773SPascal Brand size_t eps_len; 14164a5011eSPascal Brand uint32_t prop_type; 14264a5011eSPascal Brand uint32_t index; 143b0104773SPascal Brand 144*6915bbbbSJens Wiklander if (is_propset_pseudo_handle(h)) { 145b0104773SPascal Brand size_t n; 146b0104773SPascal Brand 14764a5011eSPascal Brand res = propset_get(h, &eps, &eps_len); 148b0104773SPascal Brand if (res != TEE_SUCCESS) 149b0104773SPascal Brand return res; 150b0104773SPascal Brand 151b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 15264a5011eSPascal Brand if (!strcmp(name, eps[n].name)) 153ff857a3aSPascal Brand return propget_get_ext_prop(eps + n, type, 154ff857a3aSPascal Brand buf, len); 155b0104773SPascal Brand } 15664a5011eSPascal Brand 15764a5011eSPascal Brand /* get the index from the name */ 1582c028fdeSJerome Forissier res = _utee_get_property_name_to_index((unsigned long)h, name, 1592c028fdeSJerome Forissier strlen(name) + 1, 1602c028fdeSJerome Forissier &index); 16164a5011eSPascal Brand if (res != TEE_SUCCESS) 16264a5011eSPascal Brand return res; 1632c028fdeSJerome Forissier res = _utee_get_property((unsigned long)h, index, NULL, NULL, 164ff857a3aSPascal Brand buf, len, &prop_type); 165b0104773SPascal Brand } else { 166b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)h; 167b0104773SPascal Brand uint32_t idx = pe->idx; 168b0104773SPascal Brand 169b0104773SPascal Brand if (idx == PROP_ENUMERATOR_NOT_STARTED) 170b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 171b0104773SPascal Brand 17264a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 173b0104773SPascal Brand if (res != TEE_SUCCESS) 174b0104773SPascal Brand return res; 175b0104773SPascal Brand 176b0104773SPascal Brand if (idx < eps_len) 177ff857a3aSPascal Brand return propget_get_ext_prop(eps + idx, type, buf, len); 17864a5011eSPascal Brand idx -= eps_len; 179b0104773SPascal Brand 1802c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, idx, 181ff857a3aSPascal Brand NULL, NULL, buf, len, &prop_type); 18264a5011eSPascal Brand if (res == TEE_ERROR_ITEM_NOT_FOUND) 18364a5011eSPascal Brand res = TEE_ERROR_BAD_PARAMETERS; 184b0104773SPascal Brand } 18564a5011eSPascal Brand 186ff857a3aSPascal Brand *type = prop_type; 18764a5011eSPascal Brand return res; 188b0104773SPascal Brand } 189b0104773SPascal Brand 190b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 1918f07fe6fSJerome Forissier const char *name, char *value, 1920dd3f3a4SPascal Brand uint32_t *value_len) 193b0104773SPascal Brand { 194b0104773SPascal Brand TEE_Result res; 195b0104773SPascal Brand size_t l; 196ff857a3aSPascal Brand enum user_ta_prop_type type; 197ff857a3aSPascal Brand void *tmp_buf = 0; 198ff857a3aSPascal Brand uint32_t tmp_len; 199ff857a3aSPascal Brand uint32_t uint32_val; 200d5d50c3cSJens Wiklander bool bool_val; 201ff857a3aSPascal Brand TEE_Identity *p_identity_val; 202b0104773SPascal Brand 203*6915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 204*6915bbbbSJens Wiklander __utee_check_instring_annotation(name); 205*6915bbbbSJens Wiklander __utee_check_outstring_annotation(value, value_len); 206b0104773SPascal Brand 2070dd3f3a4SPascal Brand tmp_len = *value_len; 208ff857a3aSPascal Brand if (tmp_len < sizeof(TEE_Identity)) 209ff857a3aSPascal Brand tmp_len = sizeof(TEE_Identity); 210ff857a3aSPascal Brand tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 211ff857a3aSPascal Brand if (!tmp_buf) { 212ff857a3aSPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 213ff857a3aSPascal Brand goto out; 214ff857a3aSPascal Brand } 215b0104773SPascal Brand 216ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 217ff857a3aSPascal Brand tmp_buf, &tmp_len); 218ff857a3aSPascal Brand if (res != TEE_SUCCESS) { 219254e1d58SPascal Brand if (res == TEE_ERROR_SHORT_BUFFER) { 220254e1d58SPascal Brand if (type == USER_TA_PROP_TYPE_BINARY_BLOCK) { 221254e1d58SPascal Brand /* 222254e1d58SPascal Brand * in this case, we must enlarge the buffer 223254e1d58SPascal Brand * with the size of the of the base64 encoded 224254e1d58SPascal Brand * see base64_enc() function 225254e1d58SPascal Brand */ 22697b8ba50SJerome Forissier tmp_len = _base64_enc_len(tmp_len); 227254e1d58SPascal Brand } 2280dd3f3a4SPascal Brand *value_len = tmp_len; 229254e1d58SPascal Brand } 230ff857a3aSPascal Brand goto out; 231ff857a3aSPascal Brand } 232b0104773SPascal Brand 233ff857a3aSPascal Brand switch (type) { 234b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 235d5d50c3cSJens Wiklander bool_val = *((bool *)tmp_buf); 236d5d50c3cSJens Wiklander l = strlcpy(value, (bool_val ? "true" : "false"), *value_len); 237b0104773SPascal Brand break; 238b0104773SPascal Brand 239b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 240ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 2410dd3f3a4SPascal Brand l = snprintf(value, *value_len, "%u", uint32_val); 242b0104773SPascal Brand break; 243b0104773SPascal Brand 244b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 2450dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%pUl", tmp_buf); 246b0104773SPascal Brand break; 247b0104773SPascal Brand 248b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 249ff857a3aSPascal Brand p_identity_val = ((TEE_Identity *)tmp_buf); 2500dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%u:%pUl", 251ff857a3aSPascal Brand p_identity_val->login, 252ff857a3aSPascal Brand (void *)(&(p_identity_val->uuid))); 253b0104773SPascal Brand break; 254b0104773SPascal Brand 255b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 2560dd3f3a4SPascal Brand l = strlcpy(value, tmp_buf, *value_len); 257ff857a3aSPascal Brand break; 258ff857a3aSPascal Brand 259b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 2600dd3f3a4SPascal Brand l = *value_len; /* l includes the zero-termination */ 26197b8ba50SJerome Forissier if (!_base64_enc(tmp_buf, tmp_len, value, &l) && 262ec930caeSJerome Forissier l <= *value_len) { 263ff857a3aSPascal Brand res = TEE_ERROR_GENERIC; 264ff857a3aSPascal Brand goto out; 265ff857a3aSPascal Brand } 266ff857a3aSPascal Brand l--; /* remove the zero-termination that is added later */ 267b0104773SPascal Brand break; 268b0104773SPascal Brand 269b0104773SPascal Brand default: 270ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 271ba675d69SCedric Chaumont goto out; 272ff857a3aSPascal Brand } 273ba675d69SCedric Chaumont 274ff857a3aSPascal Brand l++; /* include zero termination */ 275ff857a3aSPascal Brand 2760dd3f3a4SPascal Brand if (l > *value_len) 277ff857a3aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 2780dd3f3a4SPascal Brand *value_len = l; 279ff857a3aSPascal Brand 280ba675d69SCedric Chaumont out: 281ff857a3aSPascal Brand if (tmp_buf) 282ff857a3aSPascal Brand TEE_Free(tmp_buf); 283ff857a3aSPascal Brand if (res != TEE_SUCCESS && 284ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 285ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 286ff857a3aSPascal Brand TEE_Panic(0); 287ff857a3aSPascal Brand 288ff857a3aSPascal Brand return res; 289b0104773SPascal Brand } 290b0104773SPascal Brand 291b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 2928f07fe6fSJerome Forissier const char *name, bool *value) 293b0104773SPascal Brand { 294b0104773SPascal Brand TEE_Result res; 295ff857a3aSPascal Brand enum user_ta_prop_type type; 296d5d50c3cSJens Wiklander uint32_t bool_len = sizeof(bool); 297*6915bbbbSJens Wiklander 298*6915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 299*6915bbbbSJens Wiklander __utee_check_instring_annotation(name); 300*6915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 301b0104773SPascal Brand 302ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BOOL; 303ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 304d5d50c3cSJens Wiklander value, &bool_len); 305ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BOOL) 306ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 307ff857a3aSPascal Brand if (res != TEE_SUCCESS) 308ba675d69SCedric Chaumont goto out; 309ba675d69SCedric Chaumont 310ba675d69SCedric Chaumont out: 311ff857a3aSPascal Brand if (res != TEE_SUCCESS && 312ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 313ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 314ff857a3aSPascal Brand TEE_Panic(0); 315ff857a3aSPascal Brand 316ff857a3aSPascal Brand return res; 317b0104773SPascal Brand } 318b0104773SPascal Brand 319b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, 3208f07fe6fSJerome Forissier const char *name, uint32_t *value) 321b0104773SPascal Brand { 322b0104773SPascal Brand TEE_Result res; 323ff857a3aSPascal Brand enum user_ta_prop_type type; 324ff857a3aSPascal Brand uint32_t uint32_len = sizeof(uint32_t); 325b0104773SPascal Brand 326*6915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 327*6915bbbbSJens Wiklander __utee_check_instring_annotation(name); 328*6915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 329ba675d69SCedric Chaumont 330ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_U32; 331ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 332ff857a3aSPascal Brand value, &uint32_len); 333ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_U32) 334ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 335ff857a3aSPascal Brand 336ff857a3aSPascal Brand if (res != TEE_SUCCESS && 337ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 338ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 339ff857a3aSPascal Brand TEE_Panic(0); 340ff857a3aSPascal Brand 341ff857a3aSPascal Brand return res; 342b0104773SPascal Brand } 343b0104773SPascal Brand 344b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 3458f07fe6fSJerome Forissier const char *name, void *value, 3460dd3f3a4SPascal Brand uint32_t *value_len) 347b0104773SPascal Brand { 348b0104773SPascal Brand TEE_Result res; 349ff857a3aSPascal Brand enum user_ta_prop_type type; 350b0104773SPascal Brand 351*6915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 352*6915bbbbSJens Wiklander __utee_check_instring_annotation(name); 353*6915bbbbSJens Wiklander __utee_check_outbuf_annotation(value, value_len); 354ba675d69SCedric Chaumont 355ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BINARY_BLOCK; 356ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 3570dd3f3a4SPascal Brand value, value_len); 358ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BINARY_BLOCK) 359ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 360ff857a3aSPascal Brand 361ff857a3aSPascal Brand if (res != TEE_SUCCESS && 362ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 363ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT && 364ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 365ff857a3aSPascal Brand TEE_Panic(0); 366ff857a3aSPascal Brand 367ff857a3aSPascal Brand return res; 368b0104773SPascal Brand } 369b0104773SPascal Brand 370b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 3718f07fe6fSJerome Forissier const char *name, TEE_UUID *value) 372b0104773SPascal Brand { 373b0104773SPascal Brand TEE_Result res; 374ff857a3aSPascal Brand enum user_ta_prop_type type; 375ff857a3aSPascal Brand uint32_t uuid_len = sizeof(TEE_UUID); 376b0104773SPascal Brand 377*6915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 378*6915bbbbSJens Wiklander __utee_check_instring_annotation(name); 379*6915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 380ba675d69SCedric Chaumont 381ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_UUID; 382ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 383ff857a3aSPascal Brand value, &uuid_len); 384ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_UUID) 385ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 386ff857a3aSPascal Brand 387ff857a3aSPascal Brand if (res != TEE_SUCCESS && 388ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 389ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 390ff857a3aSPascal Brand TEE_Panic(0); 391ff857a3aSPascal Brand 392ff857a3aSPascal Brand return res; 393b0104773SPascal Brand } 394b0104773SPascal Brand 395b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, 3968f07fe6fSJerome Forissier const char *name, TEE_Identity *value) 397b0104773SPascal Brand { 398b0104773SPascal Brand TEE_Result res; 399ff857a3aSPascal Brand enum user_ta_prop_type type; 400ff857a3aSPascal Brand uint32_t identity_len = sizeof(TEE_Identity); 401b0104773SPascal Brand 402*6915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 403*6915bbbbSJens Wiklander __utee_check_instring_annotation(name); 404*6915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 405ba675d69SCedric Chaumont 406ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_IDENTITY; 407ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 408ff857a3aSPascal Brand value, &identity_len); 409ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_IDENTITY) 410ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 411ff857a3aSPascal Brand 412ff857a3aSPascal Brand if (res != TEE_SUCCESS && 413ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 414ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 415ff857a3aSPascal Brand TEE_Panic(0); 416ff857a3aSPascal Brand 417ff857a3aSPascal Brand return res; 418b0104773SPascal Brand } 419b0104773SPascal Brand 420b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 421b0104773SPascal Brand { 422ba675d69SCedric Chaumont TEE_Result res; 423b0104773SPascal Brand struct prop_enumerator *pe; 424b0104773SPascal Brand 425*6915bbbbSJens Wiklander __utee_check_out_annotation(enumerator, sizeof(*enumerator)); 426b0104773SPascal Brand 427b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 428b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 429ba675d69SCedric Chaumont if (pe == NULL) { 430ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 431ba675d69SCedric Chaumont goto err; 432ba675d69SCedric Chaumont } 433b0104773SPascal Brand 434b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 435b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 436ba675d69SCedric Chaumont 437ba675d69SCedric Chaumont goto out; 438ba675d69SCedric Chaumont 439ba675d69SCedric Chaumont err: 440ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 441ba675d69SCedric Chaumont return res; 442ba675d69SCedric Chaumont TEE_Panic(0); 443ba675d69SCedric Chaumont out: 444b0104773SPascal Brand return TEE_SUCCESS; 445b0104773SPascal Brand } 446b0104773SPascal Brand 447b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 448b0104773SPascal Brand { 449b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 450b0104773SPascal Brand 451b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 452b0104773SPascal Brand } 453b0104773SPascal Brand 454b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 455b0104773SPascal Brand { 456b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 457b0104773SPascal Brand 458b0104773SPascal Brand TEE_Free(pe); 459b0104773SPascal Brand } 460b0104773SPascal Brand 461b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 462b0104773SPascal Brand TEE_PropSetHandle propSet) 463b0104773SPascal Brand { 464b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 465b0104773SPascal Brand 4660dd3f3a4SPascal Brand if (!pe) 467b0104773SPascal Brand return; 468b0104773SPascal Brand 469b0104773SPascal Brand pe->idx = 0; 470b0104773SPascal Brand pe->prop_set = propSet; 471b0104773SPascal Brand } 472b0104773SPascal Brand 473b0104773SPascal Brand TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 4740dd3f3a4SPascal Brand void *name, uint32_t *name_len) 475b0104773SPascal Brand { 476b0104773SPascal Brand TEE_Result res; 477b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 478b0104773SPascal Brand const struct user_ta_property *eps; 479b0104773SPascal Brand size_t eps_len; 480b0104773SPascal Brand const char *str; 481b0104773SPascal Brand size_t bufferlen; 482b0104773SPascal Brand 483*6915bbbbSJens Wiklander if (!pe) { 484ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 485ba675d69SCedric Chaumont goto err; 486ba675d69SCedric Chaumont } 487*6915bbbbSJens Wiklander __utee_check_outstring_annotation(name, name_len); 488b0104773SPascal Brand 4890dd3f3a4SPascal Brand bufferlen = *name_len; 49064a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 491b0104773SPascal Brand if (res != TEE_SUCCESS) 492ba675d69SCedric Chaumont goto err; 493b0104773SPascal Brand 49464a5011eSPascal Brand if (pe->idx < eps_len) { 49564a5011eSPascal Brand str = eps[pe->idx].name; 4960dd3f3a4SPascal Brand bufferlen = strlcpy(name, str, *name_len) + 1; 4970dd3f3a4SPascal Brand if (bufferlen > *name_len) 498ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 4990dd3f3a4SPascal Brand *name_len = bufferlen; 50064a5011eSPascal Brand } else { 5012c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 5022c028fdeSJerome Forissier pe->idx - eps_len, name, name_len, 5032c028fdeSJerome Forissier NULL, NULL, NULL); 50464a5011eSPascal Brand if (res != TEE_SUCCESS) 505ba675d69SCedric Chaumont goto err; 506ba675d69SCedric Chaumont } 507b0104773SPascal Brand 508ba675d69SCedric Chaumont err: 50964a5011eSPascal Brand if (res != TEE_SUCCESS && 51064a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 51164a5011eSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 512ba675d69SCedric Chaumont TEE_Panic(0); 51364a5011eSPascal Brand return res; 514b0104773SPascal Brand } 515b0104773SPascal Brand 516b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 517b0104773SPascal Brand { 518b0104773SPascal Brand TEE_Result res; 519b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 520b0104773SPascal Brand uint32_t next_idx; 521b0104773SPascal Brand const struct user_ta_property *eps; 522b0104773SPascal Brand size_t eps_len; 523b0104773SPascal Brand 5240dd3f3a4SPascal Brand if (!pe) { 525ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 52664a5011eSPascal Brand goto out; 527ba675d69SCedric Chaumont } 528b0104773SPascal Brand 529ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 530ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 53164a5011eSPascal Brand goto out; 532ba675d69SCedric Chaumont } 533b0104773SPascal Brand 53464a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 535b0104773SPascal Brand if (res != TEE_SUCCESS) 53664a5011eSPascal Brand goto out; 537b0104773SPascal Brand 538b0104773SPascal Brand next_idx = pe->idx + 1; 539b0104773SPascal Brand pe->idx = next_idx; 54064a5011eSPascal Brand if (next_idx < eps_len) 54164a5011eSPascal Brand res = TEE_SUCCESS; 54264a5011eSPascal Brand else 5432c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 5442c028fdeSJerome Forissier next_idx - eps_len, NULL, NULL, NULL, 5452c028fdeSJerome Forissier NULL, NULL); 546b0104773SPascal Brand 547ba675d69SCedric Chaumont out: 54864a5011eSPascal Brand if (res != TEE_SUCCESS && 54964a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND) 55064a5011eSPascal Brand TEE_Panic(0); 55164a5011eSPascal Brand return res; 552b0104773SPascal Brand } 553