11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 4a32a96edSJens Wiklander * Copyright (c) 2017, 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 "string_ext.h" 21b0104773SPascal Brand #include "base64.h" 22b0104773SPascal Brand 23b0104773SPascal Brand #define PROP_STR_MAX 80 24b0104773SPascal Brand 25b0104773SPascal Brand #define PROP_ENUMERATOR_NOT_STARTED 0xffffffff 26b0104773SPascal Brand 27b0104773SPascal Brand struct prop_enumerator { 2864a5011eSPascal Brand uint32_t idx; /* current index */ 2964a5011eSPascal Brand TEE_PropSetHandle prop_set; /* part of TEE_PROPSET_xxx */ 30b0104773SPascal Brand }; 31b0104773SPascal Brand 3264a5011eSPascal Brand const struct user_ta_property tee_props[] = { 3364a5011eSPascal Brand { 3464a5011eSPascal Brand "gpd.tee.arith.maxBigIntSize", 3564a5011eSPascal Brand USER_TA_PROP_TYPE_U32, 36e3458e03SJerome Forissier &(const uint32_t){CFG_TA_BIGNUM_MAX_BITS} 3764a5011eSPascal Brand }, 38a32a96edSJens Wiklander { 39a32a96edSJens Wiklander "gpd.tee.sockets.version", 40a32a96edSJens Wiklander USER_TA_PROP_TYPE_U32, 41a32a96edSJens Wiklander &(const uint32_t){TEE_ISOCKET_VERSION} 42a32a96edSJens Wiklander }, 43a32a96edSJens Wiklander { 44a32a96edSJens Wiklander "gpd.tee.sockets.tcp.version", 45a32a96edSJens Wiklander USER_TA_PROP_TYPE_U32, 46a32a96edSJens Wiklander &(const uint32_t){TEE_ISOCKET_VERSION} 47a32a96edSJens Wiklander }, 48b0104773SPascal Brand }; 49b0104773SPascal Brand 5064a5011eSPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, 51b0104773SPascal Brand const struct user_ta_property **eps, 52b0104773SPascal Brand size_t *eps_len) 53b0104773SPascal Brand { 54b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA) { 55b0104773SPascal Brand *eps = ta_props; 56b0104773SPascal Brand *eps_len = ta_num_props; 57b0104773SPascal Brand } else if (h == TEE_PROPSET_CURRENT_CLIENT) { 58b0104773SPascal Brand *eps = NULL; 59b0104773SPascal Brand *eps_len = 0; 60b0104773SPascal Brand } else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) { 6164a5011eSPascal Brand *eps = tee_props; 6264a5011eSPascal Brand *eps_len = ARRAY_SIZE(tee_props); 63b0104773SPascal Brand } else { 64b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 65b0104773SPascal Brand } 66b0104773SPascal Brand 67b0104773SPascal Brand return TEE_SUCCESS; 68b0104773SPascal Brand } 69b0104773SPascal Brand 70b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep, 71ff857a3aSPascal Brand enum user_ta_prop_type *type, 72ff857a3aSPascal Brand void *buf, uint32_t *len) 73b0104773SPascal Brand { 74b0104773SPascal Brand size_t l; 75b0104773SPascal Brand 76ff857a3aSPascal Brand *type = ep->type; 77ff857a3aSPascal Brand switch (*type) { 78b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 79d5d50c3cSJens Wiklander l = sizeof(bool); 80b0104773SPascal Brand break; 81b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 82b0104773SPascal Brand l = sizeof(uint32_t); 83b0104773SPascal Brand break; 84b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 85b0104773SPascal Brand l = sizeof(TEE_UUID); 86b0104773SPascal Brand break; 87b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 88b0104773SPascal Brand l = sizeof(TEE_Identity); 89b0104773SPascal Brand break; 90b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 91ff857a3aSPascal Brand /* take the leading 0 into account */ 92ff857a3aSPascal Brand l = strlen(ep->value) + 1; 93ff857a3aSPascal Brand break; 94b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 95ff857a3aSPascal Brand /* 96ff857a3aSPascal Brand * in case of TA property, a binary block is provided as a 97ff857a3aSPascal Brand * string, which is base64 encoded. We must first decode it, 98ff857a3aSPascal Brand * without taking into account the zero termination of the 99ff857a3aSPascal Brand * string 100ff857a3aSPascal Brand */ 101ff857a3aSPascal Brand l = *len; 102ff857a3aSPascal Brand if (!base64_dec(ep->value, strlen(ep->value), buf, &l) && 103*ec930caeSJerome Forissier l <= *len) 104ff857a3aSPascal Brand return TEE_ERROR_GENERIC; 105ff857a3aSPascal Brand if (*len < l) { 106ff857a3aSPascal Brand *len = l; 107ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 108ff857a3aSPascal Brand } 109ff857a3aSPascal Brand 110ff857a3aSPascal Brand *len = l; 111b0104773SPascal Brand return TEE_SUCCESS; 112b0104773SPascal Brand default: 113b0104773SPascal Brand return TEE_ERROR_GENERIC; 114b0104773SPascal Brand } 115ff857a3aSPascal Brand 116ff857a3aSPascal Brand if (*len < l) { 117ff857a3aSPascal Brand *len = l; 118ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 119ff857a3aSPascal Brand } 120ff857a3aSPascal Brand 121ff857a3aSPascal Brand *len = l; 122ff857a3aSPascal Brand memcpy(buf, ep->value, l); 123b0104773SPascal Brand return TEE_SUCCESS; 124b0104773SPascal Brand } 125b0104773SPascal Brand 1268f07fe6fSJerome Forissier static TEE_Result propget_get_property(TEE_PropSetHandle h, const char *name, 127ff857a3aSPascal Brand enum user_ta_prop_type *type, 128ff857a3aSPascal Brand void *buf, uint32_t *len) 129b0104773SPascal Brand { 130b0104773SPascal Brand TEE_Result res; 131b0104773SPascal Brand const struct user_ta_property *eps; 132b0104773SPascal Brand size_t eps_len; 13364a5011eSPascal Brand uint32_t prop_type; 13464a5011eSPascal Brand uint32_t index; 135b0104773SPascal Brand 136b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA || h == TEE_PROPSET_CURRENT_CLIENT || 137b0104773SPascal Brand h == TEE_PROPSET_TEE_IMPLEMENTATION) { 138b0104773SPascal Brand size_t n; 139b0104773SPascal Brand 14064a5011eSPascal Brand res = propset_get(h, &eps, &eps_len); 141b0104773SPascal Brand if (res != TEE_SUCCESS) 142b0104773SPascal Brand return res; 143b0104773SPascal Brand 144b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 14564a5011eSPascal Brand if (!strcmp(name, eps[n].name)) 146ff857a3aSPascal Brand return propget_get_ext_prop(eps + n, type, 147ff857a3aSPascal Brand buf, len); 148b0104773SPascal Brand } 14964a5011eSPascal Brand 15064a5011eSPascal Brand /* get the index from the name */ 1512c028fdeSJerome Forissier res = _utee_get_property_name_to_index((unsigned long)h, name, 1522c028fdeSJerome Forissier strlen(name) + 1, 1532c028fdeSJerome Forissier &index); 15464a5011eSPascal Brand if (res != TEE_SUCCESS) 15564a5011eSPascal Brand return res; 1562c028fdeSJerome Forissier res = _utee_get_property((unsigned long)h, index, NULL, NULL, 157ff857a3aSPascal Brand buf, len, &prop_type); 158b0104773SPascal Brand } else { 159b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)h; 160b0104773SPascal Brand uint32_t idx = pe->idx; 161b0104773SPascal Brand 162b0104773SPascal Brand if (idx == PROP_ENUMERATOR_NOT_STARTED) 163b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 164b0104773SPascal Brand 16564a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 166b0104773SPascal Brand if (res != TEE_SUCCESS) 167b0104773SPascal Brand return res; 168b0104773SPascal Brand 169b0104773SPascal Brand if (idx < eps_len) 170ff857a3aSPascal Brand return propget_get_ext_prop(eps + idx, type, buf, len); 17164a5011eSPascal Brand idx -= eps_len; 172b0104773SPascal Brand 1732c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, idx, 174ff857a3aSPascal Brand NULL, NULL, buf, len, &prop_type); 17564a5011eSPascal Brand if (res == TEE_ERROR_ITEM_NOT_FOUND) 17664a5011eSPascal Brand res = TEE_ERROR_BAD_PARAMETERS; 177b0104773SPascal Brand } 17864a5011eSPascal Brand 179ff857a3aSPascal Brand *type = prop_type; 18064a5011eSPascal Brand return res; 181b0104773SPascal Brand } 182b0104773SPascal Brand 183b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 1848f07fe6fSJerome Forissier const char *name, char *value, 1850dd3f3a4SPascal Brand uint32_t *value_len) 186b0104773SPascal Brand { 187b0104773SPascal Brand TEE_Result res; 188b0104773SPascal Brand size_t l; 189ff857a3aSPascal Brand enum user_ta_prop_type type; 190ff857a3aSPascal Brand void *tmp_buf = 0; 191ff857a3aSPascal Brand uint32_t tmp_len; 192ff857a3aSPascal Brand uint32_t uint32_val; 193d5d50c3cSJens Wiklander bool bool_val; 194ff857a3aSPascal Brand TEE_Identity *p_identity_val; 195b0104773SPascal Brand 1960dd3f3a4SPascal Brand if (!value || !value_len) { 197ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 198ff857a3aSPascal Brand goto out; 199ba675d69SCedric Chaumont } 200b0104773SPascal Brand 2010dd3f3a4SPascal Brand tmp_len = *value_len; 202ff857a3aSPascal Brand if (tmp_len < sizeof(TEE_Identity)) 203ff857a3aSPascal Brand tmp_len = sizeof(TEE_Identity); 204ff857a3aSPascal Brand tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 205ff857a3aSPascal Brand if (!tmp_buf) { 206ff857a3aSPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 207ff857a3aSPascal Brand goto out; 208ff857a3aSPascal Brand } 209b0104773SPascal Brand 210ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 211ff857a3aSPascal Brand tmp_buf, &tmp_len); 212ff857a3aSPascal Brand if (res != TEE_SUCCESS) { 213254e1d58SPascal Brand if (res == TEE_ERROR_SHORT_BUFFER) { 214254e1d58SPascal Brand if (type == USER_TA_PROP_TYPE_BINARY_BLOCK) { 215254e1d58SPascal Brand /* 216254e1d58SPascal Brand * in this case, we must enlarge the buffer 217254e1d58SPascal Brand * with the size of the of the base64 encoded 218254e1d58SPascal Brand * see base64_enc() function 219254e1d58SPascal Brand */ 220254e1d58SPascal Brand tmp_len = base64_enc_len(tmp_len); 221254e1d58SPascal Brand } 2220dd3f3a4SPascal Brand *value_len = tmp_len; 223254e1d58SPascal Brand } 224ff857a3aSPascal Brand goto out; 225ff857a3aSPascal Brand } 226b0104773SPascal Brand 227ff857a3aSPascal Brand switch (type) { 228b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 229d5d50c3cSJens Wiklander bool_val = *((bool *)tmp_buf); 230d5d50c3cSJens Wiklander l = strlcpy(value, (bool_val ? "true" : "false"), *value_len); 231b0104773SPascal Brand break; 232b0104773SPascal Brand 233b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 234ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 2350dd3f3a4SPascal Brand l = snprintf(value, *value_len, "%u", uint32_val); 236b0104773SPascal Brand break; 237b0104773SPascal Brand 238b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 2390dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%pUl", tmp_buf); 240b0104773SPascal Brand break; 241b0104773SPascal Brand 242b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 243ff857a3aSPascal Brand p_identity_val = ((TEE_Identity *)tmp_buf); 2440dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%u:%pUl", 245ff857a3aSPascal Brand p_identity_val->login, 246ff857a3aSPascal Brand (void *)(&(p_identity_val->uuid))); 247b0104773SPascal Brand break; 248b0104773SPascal Brand 249b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 2500dd3f3a4SPascal Brand l = strlcpy(value, tmp_buf, *value_len); 251ff857a3aSPascal Brand break; 252ff857a3aSPascal Brand 253b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 2540dd3f3a4SPascal Brand l = *value_len; /* l includes the zero-termination */ 2550dd3f3a4SPascal Brand if (!base64_enc(tmp_buf, tmp_len, value, &l) && 256*ec930caeSJerome Forissier l <= *value_len) { 257ff857a3aSPascal Brand res = TEE_ERROR_GENERIC; 258ff857a3aSPascal Brand goto out; 259ff857a3aSPascal Brand } 260ff857a3aSPascal Brand l--; /* remove the zero-termination that is added later */ 261b0104773SPascal Brand break; 262b0104773SPascal Brand 263b0104773SPascal Brand default: 264ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 265ba675d69SCedric Chaumont goto out; 266ff857a3aSPascal Brand } 267ba675d69SCedric Chaumont 268ff857a3aSPascal Brand l++; /* include zero termination */ 269ff857a3aSPascal Brand 2700dd3f3a4SPascal Brand if (l > *value_len) 271ff857a3aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 2720dd3f3a4SPascal Brand *value_len = l; 273ff857a3aSPascal Brand 274ba675d69SCedric Chaumont out: 275ff857a3aSPascal Brand if (tmp_buf) 276ff857a3aSPascal Brand TEE_Free(tmp_buf); 277ff857a3aSPascal Brand if (res != TEE_SUCCESS && 278ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 279ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 280ff857a3aSPascal Brand TEE_Panic(0); 281ff857a3aSPascal Brand 282ff857a3aSPascal Brand return res; 283b0104773SPascal Brand } 284b0104773SPascal Brand 285b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 2868f07fe6fSJerome Forissier const char *name, bool *value) 287b0104773SPascal Brand { 288b0104773SPascal Brand TEE_Result res; 289ff857a3aSPascal Brand enum user_ta_prop_type type; 290d5d50c3cSJens Wiklander uint32_t bool_len = sizeof(bool); 291ba675d69SCedric Chaumont if (value == NULL) { 292ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 293ff857a3aSPascal Brand goto out; 294ba675d69SCedric Chaumont } 295b0104773SPascal Brand 296ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BOOL; 297ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 298d5d50c3cSJens Wiklander value, &bool_len); 299ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BOOL) 300ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 301ff857a3aSPascal Brand if (res != TEE_SUCCESS) 302ba675d69SCedric Chaumont goto out; 303ba675d69SCedric Chaumont 304ba675d69SCedric Chaumont out: 305ff857a3aSPascal Brand if (res != TEE_SUCCESS && 306ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 307ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 308ff857a3aSPascal Brand TEE_Panic(0); 309ff857a3aSPascal Brand 310ff857a3aSPascal Brand return res; 311b0104773SPascal Brand } 312b0104773SPascal Brand 313b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, 3148f07fe6fSJerome Forissier const char *name, uint32_t *value) 315b0104773SPascal Brand { 316b0104773SPascal Brand TEE_Result res; 317ff857a3aSPascal Brand enum user_ta_prop_type type; 318ff857a3aSPascal Brand uint32_t uint32_len = sizeof(uint32_t); 319b0104773SPascal Brand 3200dd3f3a4SPascal Brand if (!value) { 321ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 322ba675d69SCedric Chaumont goto out; 323ff857a3aSPascal Brand } 324ba675d69SCedric Chaumont 325ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_U32; 326ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 327ff857a3aSPascal Brand value, &uint32_len); 328ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_U32) 329ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 330ff857a3aSPascal Brand 331ba675d69SCedric Chaumont out: 332ff857a3aSPascal Brand if (res != TEE_SUCCESS && 333ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 334ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 335ff857a3aSPascal Brand TEE_Panic(0); 336ff857a3aSPascal Brand 337ff857a3aSPascal Brand return res; 338b0104773SPascal Brand } 339b0104773SPascal Brand 340b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 3418f07fe6fSJerome Forissier const char *name, void *value, 3420dd3f3a4SPascal Brand uint32_t *value_len) 343b0104773SPascal Brand { 344b0104773SPascal Brand TEE_Result res; 345ff857a3aSPascal Brand enum user_ta_prop_type type; 346b0104773SPascal Brand 347614e8b8aSEtienne Carriere if (!value_len) { 348ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 349ba675d69SCedric Chaumont goto out; 350ff857a3aSPascal Brand } 351ba675d69SCedric Chaumont 352ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BINARY_BLOCK; 353ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 3540dd3f3a4SPascal Brand value, value_len); 355ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BINARY_BLOCK) 356ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 357ff857a3aSPascal Brand 358ba675d69SCedric Chaumont out: 359ff857a3aSPascal Brand if (res != TEE_SUCCESS && 360ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 361ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT && 362ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 363ff857a3aSPascal Brand TEE_Panic(0); 364ff857a3aSPascal Brand 365ff857a3aSPascal Brand return res; 366b0104773SPascal Brand } 367b0104773SPascal Brand 368b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 3698f07fe6fSJerome Forissier const char *name, TEE_UUID *value) 370b0104773SPascal Brand { 371b0104773SPascal Brand TEE_Result res; 372ff857a3aSPascal Brand enum user_ta_prop_type type; 373ff857a3aSPascal Brand uint32_t uuid_len = sizeof(TEE_UUID); 374b0104773SPascal Brand 3750dd3f3a4SPascal Brand if (!value) { 376ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 377ba675d69SCedric Chaumont goto out; 378ff857a3aSPascal Brand } 379ba675d69SCedric Chaumont 380ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_UUID; 381ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 382ff857a3aSPascal Brand value, &uuid_len); 383ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_UUID) 384ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 385ff857a3aSPascal Brand 386ba675d69SCedric Chaumont out: 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 4020dd3f3a4SPascal Brand if (!value) { 403ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 404ba675d69SCedric Chaumont goto out; 405ff857a3aSPascal Brand } 406ba675d69SCedric Chaumont 407ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_IDENTITY; 408ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 409ff857a3aSPascal Brand value, &identity_len); 410ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_IDENTITY) 411ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 412ff857a3aSPascal Brand 413ba675d69SCedric Chaumont out: 414ff857a3aSPascal Brand if (res != TEE_SUCCESS && 415ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 416ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 417ff857a3aSPascal Brand TEE_Panic(0); 418ff857a3aSPascal Brand 419ff857a3aSPascal Brand return res; 420b0104773SPascal Brand } 421b0104773SPascal Brand 422b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 423b0104773SPascal Brand { 424ba675d69SCedric Chaumont TEE_Result res; 425b0104773SPascal Brand struct prop_enumerator *pe; 426b0104773SPascal Brand 4270dd3f3a4SPascal Brand if (!enumerator) { 428ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 429ba675d69SCedric Chaumont goto err; 430ba675d69SCedric Chaumont } 431b0104773SPascal Brand 432b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 433b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 434ba675d69SCedric Chaumont if (pe == NULL) { 435ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 436ba675d69SCedric Chaumont goto err; 437ba675d69SCedric Chaumont } 438b0104773SPascal Brand 439b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 440b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 441ba675d69SCedric Chaumont 442ba675d69SCedric Chaumont goto out; 443ba675d69SCedric Chaumont 444ba675d69SCedric Chaumont err: 445ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 446ba675d69SCedric Chaumont return res; 447ba675d69SCedric Chaumont TEE_Panic(0); 448ba675d69SCedric Chaumont out: 449b0104773SPascal Brand return TEE_SUCCESS; 450b0104773SPascal Brand } 451b0104773SPascal Brand 452b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 453b0104773SPascal Brand { 454b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 455b0104773SPascal Brand 456b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 457b0104773SPascal Brand } 458b0104773SPascal Brand 459b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 460b0104773SPascal Brand { 461b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 462b0104773SPascal Brand 463b0104773SPascal Brand TEE_Free(pe); 464b0104773SPascal Brand } 465b0104773SPascal Brand 466b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 467b0104773SPascal Brand TEE_PropSetHandle propSet) 468b0104773SPascal Brand { 469b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 470b0104773SPascal Brand 4710dd3f3a4SPascal Brand if (!pe) 472b0104773SPascal Brand return; 473b0104773SPascal Brand 474b0104773SPascal Brand pe->idx = 0; 475b0104773SPascal Brand pe->prop_set = propSet; 476b0104773SPascal Brand } 477b0104773SPascal Brand 478b0104773SPascal Brand TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 4790dd3f3a4SPascal Brand void *name, uint32_t *name_len) 480b0104773SPascal Brand { 481b0104773SPascal Brand TEE_Result res; 482b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 483b0104773SPascal Brand const struct user_ta_property *eps; 484b0104773SPascal Brand size_t eps_len; 485b0104773SPascal Brand const char *str; 486b0104773SPascal Brand size_t bufferlen; 487b0104773SPascal Brand 4880dd3f3a4SPascal Brand if (!pe || !name || !name_len) { 489ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 490ba675d69SCedric Chaumont goto err; 491ba675d69SCedric Chaumont } 492b0104773SPascal Brand 4930dd3f3a4SPascal Brand bufferlen = *name_len; 49464a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 495b0104773SPascal Brand if (res != TEE_SUCCESS) 496ba675d69SCedric Chaumont goto err; 497b0104773SPascal Brand 49864a5011eSPascal Brand if (pe->idx < eps_len) { 49964a5011eSPascal Brand str = eps[pe->idx].name; 5000dd3f3a4SPascal Brand bufferlen = strlcpy(name, str, *name_len) + 1; 5010dd3f3a4SPascal Brand if (bufferlen > *name_len) 502ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 5030dd3f3a4SPascal Brand *name_len = bufferlen; 50464a5011eSPascal Brand } else { 5052c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 5062c028fdeSJerome Forissier pe->idx - eps_len, name, name_len, 5072c028fdeSJerome Forissier NULL, NULL, NULL); 50864a5011eSPascal Brand if (res != TEE_SUCCESS) 509ba675d69SCedric Chaumont goto err; 510ba675d69SCedric Chaumont } 511b0104773SPascal Brand 512ba675d69SCedric Chaumont err: 51364a5011eSPascal Brand if (res != TEE_SUCCESS && 51464a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 51564a5011eSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 516ba675d69SCedric Chaumont TEE_Panic(0); 51764a5011eSPascal Brand return res; 518b0104773SPascal Brand } 519b0104773SPascal Brand 520b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 521b0104773SPascal Brand { 522b0104773SPascal Brand TEE_Result res; 523b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 524b0104773SPascal Brand uint32_t next_idx; 525b0104773SPascal Brand const struct user_ta_property *eps; 526b0104773SPascal Brand size_t eps_len; 527b0104773SPascal Brand 5280dd3f3a4SPascal Brand if (!pe) { 529ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 53064a5011eSPascal Brand goto out; 531ba675d69SCedric Chaumont } 532b0104773SPascal Brand 533ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 534ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 53564a5011eSPascal Brand goto out; 536ba675d69SCedric Chaumont } 537b0104773SPascal Brand 53864a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 539b0104773SPascal Brand if (res != TEE_SUCCESS) 54064a5011eSPascal Brand goto out; 541b0104773SPascal Brand 542b0104773SPascal Brand next_idx = pe->idx + 1; 543b0104773SPascal Brand pe->idx = next_idx; 54464a5011eSPascal Brand if (next_idx < eps_len) 54564a5011eSPascal Brand res = TEE_SUCCESS; 54664a5011eSPascal Brand else 5472c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 5482c028fdeSJerome Forissier next_idx - eps_len, NULL, NULL, NULL, 5492c028fdeSJerome Forissier NULL, NULL); 550b0104773SPascal Brand 551ba675d69SCedric Chaumont out: 55264a5011eSPascal Brand if (res != TEE_SUCCESS && 55364a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND) 55464a5011eSPascal Brand TEE_Panic(0); 55564a5011eSPascal Brand return res; 556b0104773SPascal Brand } 557