1b0104773SPascal Brand /* 2b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 3*a32a96edSJens Wiklander * Copyright (c) 2017, Linaro Limited 4b0104773SPascal Brand * All rights reserved. 5b0104773SPascal Brand * 6b0104773SPascal Brand * Redistribution and use in source and binary forms, with or without 7b0104773SPascal Brand * modification, are permitted provided that the following conditions are met: 8b0104773SPascal Brand * 9b0104773SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 10b0104773SPascal Brand * this list of conditions and the following disclaimer. 11b0104773SPascal Brand * 12b0104773SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 13b0104773SPascal Brand * this list of conditions and the following disclaimer in the documentation 14b0104773SPascal Brand * and/or other materials provided with the distribution. 15b0104773SPascal Brand * 16b0104773SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17b0104773SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18b0104773SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19b0104773SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20b0104773SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21b0104773SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22b0104773SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23b0104773SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24b0104773SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25b0104773SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26b0104773SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 27b0104773SPascal Brand */ 28*a32a96edSJens Wiklander #include <printk.h> 29*a32a96edSJens Wiklander #include <stdio.h> 30b0104773SPascal Brand #include <stdlib.h> 31b0104773SPascal Brand #include <string.h> 32b0104773SPascal Brand #include <tee_api_defines.h> 33*a32a96edSJens Wiklander #include <tee_api.h> 34b0104773SPascal Brand #include <tee_api_types.h> 35647f9c76SJerome Forissier #include <tee_arith_internal.h> 36*a32a96edSJens Wiklander #include <tee_internal_api_extensions.h> 37*a32a96edSJens Wiklander #include <tee_isocket.h> 38*a32a96edSJens Wiklander #include <user_ta_header.h> 39b0104773SPascal Brand #include <utee_syscalls.h> 40*a32a96edSJens Wiklander #include <util.h> 41b0104773SPascal Brand 42b0104773SPascal Brand #include "string_ext.h" 43b0104773SPascal Brand #include "base64.h" 44b0104773SPascal Brand 45b0104773SPascal Brand #define PROP_STR_MAX 80 46b0104773SPascal Brand 47b0104773SPascal Brand #define PROP_ENUMERATOR_NOT_STARTED 0xffffffff 48b0104773SPascal Brand 49b0104773SPascal Brand struct prop_enumerator { 5064a5011eSPascal Brand uint32_t idx; /* current index */ 5164a5011eSPascal Brand TEE_PropSetHandle prop_set; /* part of TEE_PROPSET_xxx */ 52b0104773SPascal Brand }; 53b0104773SPascal Brand 5464a5011eSPascal Brand const struct user_ta_property tee_props[] = { 5564a5011eSPascal Brand { 5664a5011eSPascal Brand "gpd.tee.arith.maxBigIntSize", 5764a5011eSPascal Brand USER_TA_PROP_TYPE_U32, 5864a5011eSPascal Brand &(const uint32_t){TEE_MAX_NUMBER_OF_SUPPORTED_BITS} 5964a5011eSPascal Brand }, 60*a32a96edSJens Wiklander { 61*a32a96edSJens Wiklander "gpd.tee.sockets.version", 62*a32a96edSJens Wiklander USER_TA_PROP_TYPE_U32, 63*a32a96edSJens Wiklander &(const uint32_t){TEE_ISOCKET_VERSION} 64*a32a96edSJens Wiklander }, 65*a32a96edSJens Wiklander { 66*a32a96edSJens Wiklander "gpd.tee.sockets.tcp.version", 67*a32a96edSJens Wiklander USER_TA_PROP_TYPE_U32, 68*a32a96edSJens Wiklander &(const uint32_t){TEE_ISOCKET_VERSION} 69*a32a96edSJens Wiklander }, 70b0104773SPascal Brand }; 71b0104773SPascal Brand 7264a5011eSPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, 73b0104773SPascal Brand const struct user_ta_property **eps, 74b0104773SPascal Brand size_t *eps_len) 75b0104773SPascal Brand { 76b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA) { 77b0104773SPascal Brand *eps = ta_props; 78b0104773SPascal Brand *eps_len = ta_num_props; 79b0104773SPascal Brand } else if (h == TEE_PROPSET_CURRENT_CLIENT) { 80b0104773SPascal Brand *eps = NULL; 81b0104773SPascal Brand *eps_len = 0; 82b0104773SPascal Brand } else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) { 8364a5011eSPascal Brand *eps = tee_props; 8464a5011eSPascal Brand *eps_len = ARRAY_SIZE(tee_props); 85b0104773SPascal Brand } else { 86b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 87b0104773SPascal Brand } 88b0104773SPascal Brand 89b0104773SPascal Brand return TEE_SUCCESS; 90b0104773SPascal Brand } 91b0104773SPascal Brand 92b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep, 93ff857a3aSPascal Brand enum user_ta_prop_type *type, 94ff857a3aSPascal Brand void *buf, uint32_t *len) 95b0104773SPascal Brand { 96b0104773SPascal Brand size_t l; 97b0104773SPascal Brand 98ff857a3aSPascal Brand *type = ep->type; 99ff857a3aSPascal Brand switch (*type) { 100b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 10164a5011eSPascal Brand l = sizeof(uint32_t); 102b0104773SPascal Brand break; 103b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 104b0104773SPascal Brand l = sizeof(uint32_t); 105b0104773SPascal Brand break; 106b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 107b0104773SPascal Brand l = sizeof(TEE_UUID); 108b0104773SPascal Brand break; 109b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 110b0104773SPascal Brand l = sizeof(TEE_Identity); 111b0104773SPascal Brand break; 112b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 113ff857a3aSPascal Brand /* take the leading 0 into account */ 114ff857a3aSPascal Brand l = strlen(ep->value) + 1; 115ff857a3aSPascal Brand break; 116b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 117ff857a3aSPascal Brand /* 118ff857a3aSPascal Brand * in case of TA property, a binary block is provided as a 119ff857a3aSPascal Brand * string, which is base64 encoded. We must first decode it, 120ff857a3aSPascal Brand * without taking into account the zero termination of the 121ff857a3aSPascal Brand * string 122ff857a3aSPascal Brand */ 123ff857a3aSPascal Brand l = *len; 124ff857a3aSPascal Brand if (!base64_dec(ep->value, strlen(ep->value), buf, &l) && 125ff857a3aSPascal Brand (l <= *len)) 126ff857a3aSPascal Brand return TEE_ERROR_GENERIC; 127ff857a3aSPascal Brand if (*len < l) { 128ff857a3aSPascal Brand *len = l; 129ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 130ff857a3aSPascal Brand } 131ff857a3aSPascal Brand 132ff857a3aSPascal Brand *len = l; 133b0104773SPascal Brand return TEE_SUCCESS; 134b0104773SPascal Brand default: 135b0104773SPascal Brand return TEE_ERROR_GENERIC; 136b0104773SPascal Brand } 137ff857a3aSPascal Brand 138ff857a3aSPascal Brand if (*len < l) { 139ff857a3aSPascal Brand *len = l; 140ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 141ff857a3aSPascal Brand } 142ff857a3aSPascal Brand 143ff857a3aSPascal Brand *len = l; 144ff857a3aSPascal Brand memcpy(buf, ep->value, l); 145b0104773SPascal Brand return TEE_SUCCESS; 146b0104773SPascal Brand } 147b0104773SPascal Brand 1488f07fe6fSJerome Forissier static TEE_Result propget_get_property(TEE_PropSetHandle h, const char *name, 149ff857a3aSPascal Brand enum user_ta_prop_type *type, 150ff857a3aSPascal Brand void *buf, uint32_t *len) 151b0104773SPascal Brand { 152b0104773SPascal Brand TEE_Result res; 153b0104773SPascal Brand const struct user_ta_property *eps; 154b0104773SPascal Brand size_t eps_len; 15564a5011eSPascal Brand uint32_t prop_type; 15664a5011eSPascal Brand uint32_t index; 157b0104773SPascal Brand 158b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA || h == TEE_PROPSET_CURRENT_CLIENT || 159b0104773SPascal Brand h == TEE_PROPSET_TEE_IMPLEMENTATION) { 160b0104773SPascal Brand size_t n; 161b0104773SPascal Brand 16264a5011eSPascal Brand res = propset_get(h, &eps, &eps_len); 163b0104773SPascal Brand if (res != TEE_SUCCESS) 164b0104773SPascal Brand return res; 165b0104773SPascal Brand 166b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 16764a5011eSPascal Brand if (!strcmp(name, eps[n].name)) 168ff857a3aSPascal Brand return propget_get_ext_prop(eps + n, type, 169ff857a3aSPascal Brand buf, len); 170b0104773SPascal Brand } 17164a5011eSPascal Brand 17264a5011eSPascal Brand /* get the index from the name */ 17364a5011eSPascal Brand res = utee_get_property_name_to_index((unsigned long)h, name, 17464a5011eSPascal Brand strlen(name) + 1, &index); 17564a5011eSPascal Brand if (res != TEE_SUCCESS) 17664a5011eSPascal Brand return res; 177ff857a3aSPascal Brand res = utee_get_property((unsigned long)h, index, NULL, NULL, 178ff857a3aSPascal Brand buf, len, &prop_type); 179b0104773SPascal Brand } else { 180b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)h; 181b0104773SPascal Brand uint32_t idx = pe->idx; 182b0104773SPascal Brand 183b0104773SPascal Brand if (idx == PROP_ENUMERATOR_NOT_STARTED) 184b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 185b0104773SPascal Brand 18664a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 187b0104773SPascal Brand if (res != TEE_SUCCESS) 188b0104773SPascal Brand return res; 189b0104773SPascal Brand 190b0104773SPascal Brand if (idx < eps_len) 191ff857a3aSPascal Brand return propget_get_ext_prop(eps + idx, type, buf, len); 19264a5011eSPascal Brand idx -= eps_len; 193b0104773SPascal Brand 19464a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, idx, 195ff857a3aSPascal Brand NULL, NULL, buf, len, &prop_type); 19664a5011eSPascal Brand if (res == TEE_ERROR_ITEM_NOT_FOUND) 19764a5011eSPascal Brand res = TEE_ERROR_BAD_PARAMETERS; 198b0104773SPascal Brand } 19964a5011eSPascal Brand 200ff857a3aSPascal Brand *type = prop_type; 20164a5011eSPascal Brand return res; 202b0104773SPascal Brand } 203b0104773SPascal Brand 204b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 2058f07fe6fSJerome Forissier const char *name, char *value, 2060dd3f3a4SPascal Brand uint32_t *value_len) 207b0104773SPascal Brand { 208b0104773SPascal Brand TEE_Result res; 209b0104773SPascal Brand size_t l; 210ff857a3aSPascal Brand enum user_ta_prop_type type; 211ff857a3aSPascal Brand void *tmp_buf = 0; 212ff857a3aSPascal Brand uint32_t tmp_len; 213ff857a3aSPascal Brand uint32_t uint32_val; 214ff857a3aSPascal Brand TEE_Identity *p_identity_val; 215b0104773SPascal Brand 2160dd3f3a4SPascal Brand if (!value || !value_len) { 217ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 218ff857a3aSPascal Brand goto out; 219ba675d69SCedric Chaumont } 220b0104773SPascal Brand 2210dd3f3a4SPascal Brand tmp_len = *value_len; 222ff857a3aSPascal Brand if (tmp_len < sizeof(TEE_Identity)) 223ff857a3aSPascal Brand tmp_len = sizeof(TEE_Identity); 224ff857a3aSPascal Brand tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 225ff857a3aSPascal Brand if (!tmp_buf) { 226ff857a3aSPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 227ff857a3aSPascal Brand goto out; 228ff857a3aSPascal Brand } 229b0104773SPascal Brand 230ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 231ff857a3aSPascal Brand tmp_buf, &tmp_len); 232ff857a3aSPascal Brand if (res != TEE_SUCCESS) { 233254e1d58SPascal Brand if (res == TEE_ERROR_SHORT_BUFFER) { 234254e1d58SPascal Brand if (type == USER_TA_PROP_TYPE_BINARY_BLOCK) { 235254e1d58SPascal Brand /* 236254e1d58SPascal Brand * in this case, we must enlarge the buffer 237254e1d58SPascal Brand * with the size of the of the base64 encoded 238254e1d58SPascal Brand * see base64_enc() function 239254e1d58SPascal Brand */ 240254e1d58SPascal Brand tmp_len = base64_enc_len(tmp_len); 241254e1d58SPascal Brand } 2420dd3f3a4SPascal Brand *value_len = tmp_len; 243254e1d58SPascal Brand } 244ff857a3aSPascal Brand goto out; 245ff857a3aSPascal Brand } 246b0104773SPascal Brand 247ff857a3aSPascal Brand switch (type) { 248b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 249ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 2500dd3f3a4SPascal Brand l = strlcpy(value, (uint32_val ? "true" : "false"), 2510dd3f3a4SPascal Brand *value_len); 252b0104773SPascal Brand break; 253b0104773SPascal Brand 254b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 255ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 2560dd3f3a4SPascal Brand l = snprintf(value, *value_len, "%u", uint32_val); 257b0104773SPascal Brand break; 258b0104773SPascal Brand 259b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 2600dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%pUl", tmp_buf); 261b0104773SPascal Brand break; 262b0104773SPascal Brand 263b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 264ff857a3aSPascal Brand p_identity_val = ((TEE_Identity *)tmp_buf); 2650dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%u:%pUl", 266ff857a3aSPascal Brand p_identity_val->login, 267ff857a3aSPascal Brand (void *)(&(p_identity_val->uuid))); 268b0104773SPascal Brand break; 269b0104773SPascal Brand 270b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 2710dd3f3a4SPascal Brand l = strlcpy(value, tmp_buf, *value_len); 272ff857a3aSPascal Brand break; 273ff857a3aSPascal Brand 274b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 2750dd3f3a4SPascal Brand l = *value_len; /* l includes the zero-termination */ 2760dd3f3a4SPascal Brand if (!base64_enc(tmp_buf, tmp_len, value, &l) && 2770dd3f3a4SPascal Brand (l <= *value_len)) { 278ff857a3aSPascal Brand res = TEE_ERROR_GENERIC; 279ff857a3aSPascal Brand goto out; 280ff857a3aSPascal Brand } 281ff857a3aSPascal Brand l--; /* remove the zero-termination that is added later */ 282b0104773SPascal Brand break; 283b0104773SPascal Brand 284b0104773SPascal Brand default: 285ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 286ba675d69SCedric Chaumont goto out; 287ff857a3aSPascal Brand } 288ba675d69SCedric Chaumont 289ff857a3aSPascal Brand l++; /* include zero termination */ 290ff857a3aSPascal Brand 2910dd3f3a4SPascal Brand if (l > *value_len) 292ff857a3aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 2930dd3f3a4SPascal Brand *value_len = l; 294ff857a3aSPascal Brand 295ba675d69SCedric Chaumont out: 296ff857a3aSPascal Brand if (tmp_buf) 297ff857a3aSPascal Brand TEE_Free(tmp_buf); 298ff857a3aSPascal Brand if (res != TEE_SUCCESS && 299ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 300ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 301ff857a3aSPascal Brand TEE_Panic(0); 302ff857a3aSPascal Brand 303ff857a3aSPascal Brand return res; 304b0104773SPascal Brand } 305b0104773SPascal Brand 306b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 3078f07fe6fSJerome Forissier const char *name, bool *value) 308b0104773SPascal Brand { 309b0104773SPascal Brand TEE_Result res; 310ff857a3aSPascal Brand enum user_ta_prop_type type; 311ff857a3aSPascal Brand uint32_t uint32_val; 312ff857a3aSPascal Brand uint32_t uint32_len = sizeof(uint32_val); 313ba675d69SCedric Chaumont if (value == NULL) { 314ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 315ff857a3aSPascal Brand goto out; 316ba675d69SCedric Chaumont } 317b0104773SPascal Brand 318ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BOOL; 319ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 320ff857a3aSPascal Brand &uint32_val, &uint32_len); 321ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BOOL) 322ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 323ff857a3aSPascal Brand if (res != TEE_SUCCESS) 324ba675d69SCedric Chaumont goto out; 325ba675d69SCedric Chaumont 326ff857a3aSPascal Brand *value = !!uint32_val; 327ff857a3aSPascal Brand 328ba675d69SCedric Chaumont out: 329ff857a3aSPascal Brand if (res != TEE_SUCCESS && 330ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 331ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 332ff857a3aSPascal Brand TEE_Panic(0); 333ff857a3aSPascal Brand 334ff857a3aSPascal Brand return res; 335b0104773SPascal Brand } 336b0104773SPascal Brand 337b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, 3388f07fe6fSJerome Forissier const char *name, uint32_t *value) 339b0104773SPascal Brand { 340b0104773SPascal Brand TEE_Result res; 341ff857a3aSPascal Brand enum user_ta_prop_type type; 342ff857a3aSPascal Brand uint32_t uint32_len = sizeof(uint32_t); 343b0104773SPascal Brand 3440dd3f3a4SPascal Brand if (!value) { 345ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 346ba675d69SCedric Chaumont goto out; 347ff857a3aSPascal Brand } 348ba675d69SCedric Chaumont 349ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_U32; 350ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 351ff857a3aSPascal Brand value, &uint32_len); 352ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_U32) 353ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 354ff857a3aSPascal Brand 355ba675d69SCedric Chaumont out: 356ff857a3aSPascal Brand if (res != TEE_SUCCESS && 357ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 358ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 359ff857a3aSPascal Brand TEE_Panic(0); 360ff857a3aSPascal Brand 361ff857a3aSPascal Brand return res; 362b0104773SPascal Brand } 363b0104773SPascal Brand 364b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 3658f07fe6fSJerome Forissier const char *name, void *value, 3660dd3f3a4SPascal Brand uint32_t *value_len) 367b0104773SPascal Brand { 368b0104773SPascal Brand TEE_Result res; 369ff857a3aSPascal Brand enum user_ta_prop_type type; 370b0104773SPascal Brand 3710dd3f3a4SPascal Brand if (!value || !value_len) { 372ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 373ba675d69SCedric Chaumont goto out; 374ff857a3aSPascal Brand } 375ba675d69SCedric Chaumont 376ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BINARY_BLOCK; 377ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 3780dd3f3a4SPascal Brand value, value_len); 379ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BINARY_BLOCK) 380ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 381ff857a3aSPascal Brand 382ba675d69SCedric Chaumont out: 383ff857a3aSPascal Brand if (res != TEE_SUCCESS && 384ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 385ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT && 386ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 387ff857a3aSPascal Brand TEE_Panic(0); 388ff857a3aSPascal Brand 389ff857a3aSPascal Brand return res; 390b0104773SPascal Brand } 391b0104773SPascal Brand 392b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 3938f07fe6fSJerome Forissier const char *name, TEE_UUID *value) 394b0104773SPascal Brand { 395b0104773SPascal Brand TEE_Result res; 396ff857a3aSPascal Brand enum user_ta_prop_type type; 397ff857a3aSPascal Brand uint32_t uuid_len = sizeof(TEE_UUID); 398b0104773SPascal Brand 3990dd3f3a4SPascal Brand if (!value) { 400ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 401ba675d69SCedric Chaumont goto out; 402ff857a3aSPascal Brand } 403ba675d69SCedric Chaumont 404ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_UUID; 405ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 406ff857a3aSPascal Brand value, &uuid_len); 407ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_UUID) 408ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 409ff857a3aSPascal Brand 410ba675d69SCedric Chaumont out: 411ff857a3aSPascal Brand if (res != TEE_SUCCESS && 412ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 413ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 414ff857a3aSPascal Brand TEE_Panic(0); 415ff857a3aSPascal Brand 416ff857a3aSPascal Brand return res; 417b0104773SPascal Brand } 418b0104773SPascal Brand 419b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, 4208f07fe6fSJerome Forissier const char *name, TEE_Identity *value) 421b0104773SPascal Brand { 422b0104773SPascal Brand TEE_Result res; 423ff857a3aSPascal Brand enum user_ta_prop_type type; 424ff857a3aSPascal Brand uint32_t identity_len = sizeof(TEE_Identity); 425b0104773SPascal Brand 4260dd3f3a4SPascal Brand if (!value) { 427ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 428ba675d69SCedric Chaumont goto out; 429ff857a3aSPascal Brand } 430ba675d69SCedric Chaumont 431ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_IDENTITY; 432ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 433ff857a3aSPascal Brand value, &identity_len); 434ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_IDENTITY) 435ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 436ff857a3aSPascal Brand 437ba675d69SCedric Chaumont out: 438ff857a3aSPascal Brand if (res != TEE_SUCCESS && 439ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 440ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 441ff857a3aSPascal Brand TEE_Panic(0); 442ff857a3aSPascal Brand 443ff857a3aSPascal Brand return res; 444b0104773SPascal Brand } 445b0104773SPascal Brand 446b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 447b0104773SPascal Brand { 448ba675d69SCedric Chaumont TEE_Result res; 449b0104773SPascal Brand struct prop_enumerator *pe; 450b0104773SPascal Brand 4510dd3f3a4SPascal Brand if (!enumerator) { 452ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 453ba675d69SCedric Chaumont goto err; 454ba675d69SCedric Chaumont } 455b0104773SPascal Brand 456b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 457b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 458ba675d69SCedric Chaumont if (pe == NULL) { 459ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 460ba675d69SCedric Chaumont goto err; 461ba675d69SCedric Chaumont } 462b0104773SPascal Brand 463b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 464b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 465ba675d69SCedric Chaumont 466ba675d69SCedric Chaumont goto out; 467ba675d69SCedric Chaumont 468ba675d69SCedric Chaumont err: 469ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 470ba675d69SCedric Chaumont return res; 471ba675d69SCedric Chaumont TEE_Panic(0); 472ba675d69SCedric Chaumont out: 473b0104773SPascal Brand return TEE_SUCCESS; 474b0104773SPascal Brand } 475b0104773SPascal Brand 476b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 477b0104773SPascal Brand { 478b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 479b0104773SPascal Brand 480b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 481b0104773SPascal Brand } 482b0104773SPascal Brand 483b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 484b0104773SPascal Brand { 485b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 486b0104773SPascal Brand 487b0104773SPascal Brand TEE_Free(pe); 488b0104773SPascal Brand } 489b0104773SPascal Brand 490b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 491b0104773SPascal Brand TEE_PropSetHandle propSet) 492b0104773SPascal Brand { 493b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 494b0104773SPascal Brand 4950dd3f3a4SPascal Brand if (!pe) 496b0104773SPascal Brand return; 497b0104773SPascal Brand 498b0104773SPascal Brand pe->idx = 0; 499b0104773SPascal Brand pe->prop_set = propSet; 500b0104773SPascal Brand } 501b0104773SPascal Brand 502b0104773SPascal Brand TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 5030dd3f3a4SPascal Brand void *name, uint32_t *name_len) 504b0104773SPascal Brand { 505b0104773SPascal Brand TEE_Result res; 506b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 507b0104773SPascal Brand const struct user_ta_property *eps; 508b0104773SPascal Brand size_t eps_len; 509b0104773SPascal Brand const char *str; 510b0104773SPascal Brand size_t bufferlen; 511b0104773SPascal Brand 5120dd3f3a4SPascal Brand if (!pe || !name || !name_len) { 513ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 514ba675d69SCedric Chaumont goto err; 515ba675d69SCedric Chaumont } 516b0104773SPascal Brand 5170dd3f3a4SPascal Brand bufferlen = *name_len; 51864a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 519b0104773SPascal Brand if (res != TEE_SUCCESS) 520ba675d69SCedric Chaumont goto err; 521b0104773SPascal Brand 52264a5011eSPascal Brand if (pe->idx < eps_len) { 52364a5011eSPascal Brand str = eps[pe->idx].name; 5240dd3f3a4SPascal Brand bufferlen = strlcpy(name, str, *name_len) + 1; 5250dd3f3a4SPascal Brand if (bufferlen > *name_len) 526ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 5270dd3f3a4SPascal Brand *name_len = bufferlen; 52864a5011eSPascal Brand } else { 52964a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, 53064a5011eSPascal Brand pe->idx - eps_len, 5310dd3f3a4SPascal Brand name, name_len, NULL, NULL, NULL); 53264a5011eSPascal Brand if (res != TEE_SUCCESS) 533ba675d69SCedric Chaumont goto err; 534ba675d69SCedric Chaumont } 535b0104773SPascal Brand 536ba675d69SCedric Chaumont err: 53764a5011eSPascal Brand if (res != TEE_SUCCESS && 53864a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 53964a5011eSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 540ba675d69SCedric Chaumont TEE_Panic(0); 54164a5011eSPascal Brand return res; 542b0104773SPascal Brand } 543b0104773SPascal Brand 544b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 545b0104773SPascal Brand { 546b0104773SPascal Brand TEE_Result res; 547b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 548b0104773SPascal Brand uint32_t next_idx; 549b0104773SPascal Brand const struct user_ta_property *eps; 550b0104773SPascal Brand size_t eps_len; 551b0104773SPascal Brand 5520dd3f3a4SPascal Brand if (!pe) { 553ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 55464a5011eSPascal Brand goto out; 555ba675d69SCedric Chaumont } 556b0104773SPascal Brand 557ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 558ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 55964a5011eSPascal Brand goto out; 560ba675d69SCedric Chaumont } 561b0104773SPascal Brand 56264a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 563b0104773SPascal Brand if (res != TEE_SUCCESS) 56464a5011eSPascal Brand goto out; 565b0104773SPascal Brand 566b0104773SPascal Brand next_idx = pe->idx + 1; 567b0104773SPascal Brand pe->idx = next_idx; 56864a5011eSPascal Brand if (next_idx < eps_len) 56964a5011eSPascal Brand res = TEE_SUCCESS; 57064a5011eSPascal Brand else 57164a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, 572ff857a3aSPascal Brand next_idx - eps_len, 573ff857a3aSPascal Brand NULL, NULL, NULL, NULL, NULL); 574b0104773SPascal Brand 575ba675d69SCedric Chaumont out: 57664a5011eSPascal Brand if (res != TEE_SUCCESS && 57764a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND) 57864a5011eSPascal Brand TEE_Panic(0); 57964a5011eSPascal Brand return res; 580b0104773SPascal Brand } 581