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 }, 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; 85*6551d565SJens Wiklander case USER_TA_PROP_TYPE_U64: 86*6551d565SJens Wiklander l = sizeof(uint64_t); 87*6551d565SJens Wiklander break; 88b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 89b0104773SPascal Brand l = sizeof(TEE_UUID); 90b0104773SPascal Brand break; 91b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 92b0104773SPascal Brand l = sizeof(TEE_Identity); 93b0104773SPascal Brand break; 94b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 95ff857a3aSPascal Brand /* take the leading 0 into account */ 96ff857a3aSPascal Brand l = strlen(ep->value) + 1; 97ff857a3aSPascal Brand break; 98b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 99ff857a3aSPascal Brand /* 100ff857a3aSPascal Brand * in case of TA property, a binary block is provided as a 101ff857a3aSPascal Brand * string, which is base64 encoded. We must first decode it, 102ff857a3aSPascal Brand * without taking into account the zero termination of the 103ff857a3aSPascal Brand * string 104ff857a3aSPascal Brand */ 105ff857a3aSPascal Brand l = *len; 10697b8ba50SJerome Forissier if (!_base64_dec(ep->value, strlen(ep->value), buf, &l) && 107ec930caeSJerome Forissier l <= *len) 108ff857a3aSPascal Brand return TEE_ERROR_GENERIC; 109ff857a3aSPascal Brand if (*len < l) { 110ff857a3aSPascal Brand *len = l; 111ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 112ff857a3aSPascal Brand } 113ff857a3aSPascal Brand 114ff857a3aSPascal Brand *len = l; 115b0104773SPascal Brand return TEE_SUCCESS; 116b0104773SPascal Brand default: 117b0104773SPascal Brand return TEE_ERROR_GENERIC; 118b0104773SPascal Brand } 119ff857a3aSPascal Brand 120ff857a3aSPascal Brand if (*len < l) { 121ff857a3aSPascal Brand *len = l; 122ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 123ff857a3aSPascal Brand } 124ff857a3aSPascal Brand 125ff857a3aSPascal Brand *len = l; 126ff857a3aSPascal Brand memcpy(buf, ep->value, l); 127b0104773SPascal Brand return TEE_SUCCESS; 128b0104773SPascal Brand } 129b0104773SPascal Brand 1306915bbbbSJens Wiklander static bool is_propset_pseudo_handle(TEE_PropSetHandle h) 1316915bbbbSJens Wiklander { 1326915bbbbSJens Wiklander return h == TEE_PROPSET_CURRENT_TA || 1336915bbbbSJens Wiklander h == TEE_PROPSET_CURRENT_CLIENT || 1346915bbbbSJens Wiklander h == TEE_PROPSET_TEE_IMPLEMENTATION; 1356915bbbbSJens Wiklander } 1366915bbbbSJens Wiklander 1378f07fe6fSJerome Forissier static TEE_Result propget_get_property(TEE_PropSetHandle h, const char *name, 138ff857a3aSPascal Brand enum user_ta_prop_type *type, 139ff857a3aSPascal Brand void *buf, uint32_t *len) 140b0104773SPascal Brand { 141b0104773SPascal Brand TEE_Result res; 142b0104773SPascal Brand const struct user_ta_property *eps; 143b0104773SPascal Brand size_t eps_len; 14464a5011eSPascal Brand uint32_t prop_type; 14564a5011eSPascal Brand uint32_t index; 146b0104773SPascal Brand 1476915bbbbSJens Wiklander if (is_propset_pseudo_handle(h)) { 148b0104773SPascal Brand size_t n; 149b0104773SPascal Brand 15064a5011eSPascal Brand res = propset_get(h, &eps, &eps_len); 151b0104773SPascal Brand if (res != TEE_SUCCESS) 152b0104773SPascal Brand return res; 153b0104773SPascal Brand 154b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 15564a5011eSPascal Brand if (!strcmp(name, eps[n].name)) 156ff857a3aSPascal Brand return propget_get_ext_prop(eps + n, type, 157ff857a3aSPascal Brand buf, len); 158b0104773SPascal Brand } 15964a5011eSPascal Brand 16064a5011eSPascal Brand /* get the index from the name */ 1612c028fdeSJerome Forissier res = _utee_get_property_name_to_index((unsigned long)h, name, 1622c028fdeSJerome Forissier strlen(name) + 1, 1632c028fdeSJerome Forissier &index); 16464a5011eSPascal Brand if (res != TEE_SUCCESS) 16564a5011eSPascal Brand return res; 1662c028fdeSJerome Forissier res = _utee_get_property((unsigned long)h, index, NULL, NULL, 167ff857a3aSPascal Brand buf, len, &prop_type); 168b0104773SPascal Brand } else { 169b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)h; 170b0104773SPascal Brand uint32_t idx = pe->idx; 171b0104773SPascal Brand 172b0104773SPascal Brand if (idx == PROP_ENUMERATOR_NOT_STARTED) 173b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 174b0104773SPascal Brand 17564a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 176b0104773SPascal Brand if (res != TEE_SUCCESS) 177b0104773SPascal Brand return res; 178b0104773SPascal Brand 179b0104773SPascal Brand if (idx < eps_len) 180ff857a3aSPascal Brand return propget_get_ext_prop(eps + idx, type, buf, len); 18164a5011eSPascal Brand idx -= eps_len; 182b0104773SPascal Brand 1832c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, idx, 184ff857a3aSPascal Brand NULL, NULL, buf, len, &prop_type); 18564a5011eSPascal Brand if (res == TEE_ERROR_ITEM_NOT_FOUND) 18664a5011eSPascal Brand res = TEE_ERROR_BAD_PARAMETERS; 187b0104773SPascal Brand } 18864a5011eSPascal Brand 189ff857a3aSPascal Brand *type = prop_type; 19064a5011eSPascal Brand return res; 191b0104773SPascal Brand } 192b0104773SPascal Brand 193b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 1948f07fe6fSJerome Forissier const char *name, char *value, 195*6551d565SJens Wiklander size_t *value_len) 196b0104773SPascal Brand { 197b0104773SPascal Brand TEE_Result res; 198b0104773SPascal Brand size_t l; 199ff857a3aSPascal Brand enum user_ta_prop_type type; 200ff857a3aSPascal Brand void *tmp_buf = 0; 201ff857a3aSPascal Brand uint32_t tmp_len; 202ff857a3aSPascal Brand uint32_t uint32_val; 203d5d50c3cSJens Wiklander bool bool_val; 204ff857a3aSPascal Brand TEE_Identity *p_identity_val; 205b0104773SPascal Brand 2066915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 2076915bbbbSJens Wiklander __utee_check_instring_annotation(name); 2086915bbbbSJens Wiklander __utee_check_outstring_annotation(value, value_len); 209b0104773SPascal Brand 2100dd3f3a4SPascal Brand tmp_len = *value_len; 211ff857a3aSPascal Brand if (tmp_len < sizeof(TEE_Identity)) 212ff857a3aSPascal Brand tmp_len = sizeof(TEE_Identity); 213ff857a3aSPascal Brand tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 214ff857a3aSPascal Brand if (!tmp_buf) { 215ff857a3aSPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 216ff857a3aSPascal Brand goto out; 217ff857a3aSPascal Brand } 218b0104773SPascal Brand 219ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 220ff857a3aSPascal Brand tmp_buf, &tmp_len); 221ff857a3aSPascal Brand if (res != TEE_SUCCESS) { 222254e1d58SPascal Brand if (res == TEE_ERROR_SHORT_BUFFER) { 223254e1d58SPascal Brand if (type == USER_TA_PROP_TYPE_BINARY_BLOCK) { 224254e1d58SPascal Brand /* 225254e1d58SPascal Brand * in this case, we must enlarge the buffer 226254e1d58SPascal Brand * with the size of the of the base64 encoded 227254e1d58SPascal Brand * see base64_enc() function 228254e1d58SPascal Brand */ 22997b8ba50SJerome Forissier tmp_len = _base64_enc_len(tmp_len); 230254e1d58SPascal Brand } 2310dd3f3a4SPascal Brand *value_len = tmp_len; 232254e1d58SPascal Brand } 233ff857a3aSPascal Brand goto out; 234ff857a3aSPascal Brand } 235b0104773SPascal Brand 236ff857a3aSPascal Brand switch (type) { 237b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 238d5d50c3cSJens Wiklander bool_val = *((bool *)tmp_buf); 239d5d50c3cSJens Wiklander l = strlcpy(value, (bool_val ? "true" : "false"), *value_len); 240b0104773SPascal Brand break; 241b0104773SPascal Brand 242b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 243ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 2440dd3f3a4SPascal Brand l = snprintf(value, *value_len, "%u", uint32_val); 245b0104773SPascal Brand break; 246b0104773SPascal Brand 247b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 2480dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%pUl", tmp_buf); 249b0104773SPascal Brand break; 250b0104773SPascal Brand 251b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 252ff857a3aSPascal Brand p_identity_val = ((TEE_Identity *)tmp_buf); 2530dd3f3a4SPascal Brand l = snprintk(value, *value_len, "%u:%pUl", 254ff857a3aSPascal Brand p_identity_val->login, 255ff857a3aSPascal Brand (void *)(&(p_identity_val->uuid))); 256b0104773SPascal Brand break; 257b0104773SPascal Brand 258b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 2590dd3f3a4SPascal Brand l = strlcpy(value, tmp_buf, *value_len); 260ff857a3aSPascal Brand break; 261ff857a3aSPascal Brand 262b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 2630dd3f3a4SPascal Brand l = *value_len; /* l includes the zero-termination */ 26497b8ba50SJerome Forissier if (!_base64_enc(tmp_buf, tmp_len, value, &l) && 265ec930caeSJerome Forissier l <= *value_len) { 266ff857a3aSPascal Brand res = TEE_ERROR_GENERIC; 267ff857a3aSPascal Brand goto out; 268ff857a3aSPascal Brand } 269ff857a3aSPascal Brand l--; /* remove the zero-termination that is added later */ 270b0104773SPascal Brand break; 271b0104773SPascal Brand 272b0104773SPascal Brand default: 273ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 274ba675d69SCedric Chaumont goto out; 275ff857a3aSPascal Brand } 276ba675d69SCedric Chaumont 277ff857a3aSPascal Brand l++; /* include zero termination */ 278ff857a3aSPascal Brand 2790dd3f3a4SPascal Brand if (l > *value_len) 280ff857a3aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 2810dd3f3a4SPascal Brand *value_len = l; 282ff857a3aSPascal Brand 283ba675d69SCedric Chaumont out: 284ff857a3aSPascal Brand if (tmp_buf) 285ff857a3aSPascal Brand TEE_Free(tmp_buf); 286ff857a3aSPascal Brand if (res != TEE_SUCCESS && 287ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 288ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 289ff857a3aSPascal Brand TEE_Panic(0); 290ff857a3aSPascal Brand 291ff857a3aSPascal Brand return res; 292b0104773SPascal Brand } 293b0104773SPascal Brand 294*6551d565SJens Wiklander TEE_Result __GP11_TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 295*6551d565SJens Wiklander const char *name, char *valueBuffer, 296*6551d565SJens Wiklander uint32_t *valueBufferLen) 297*6551d565SJens Wiklander { 298*6551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 299*6551d565SJens Wiklander size_t l = 0; 300*6551d565SJens Wiklander 301*6551d565SJens Wiklander __utee_check_gp11_outstring_annotation(valueBuffer, valueBufferLen); 302*6551d565SJens Wiklander l = *valueBufferLen; 303*6551d565SJens Wiklander res = TEE_GetPropertyAsString(propsetOrEnumerator, name, valueBuffer, 304*6551d565SJens Wiklander &l); 305*6551d565SJens Wiklander *valueBufferLen = l; 306*6551d565SJens Wiklander return res; 307*6551d565SJens Wiklander } 308*6551d565SJens Wiklander 309b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 3108f07fe6fSJerome Forissier const char *name, bool *value) 311b0104773SPascal Brand { 312b0104773SPascal Brand TEE_Result res; 313ff857a3aSPascal Brand enum user_ta_prop_type type; 314d5d50c3cSJens Wiklander uint32_t bool_len = sizeof(bool); 3156915bbbbSJens Wiklander 3166915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 3176915bbbbSJens Wiklander __utee_check_instring_annotation(name); 3186915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 319b0104773SPascal Brand 320ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BOOL; 321ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 322d5d50c3cSJens Wiklander value, &bool_len); 323ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BOOL) 324ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 325ff857a3aSPascal Brand if (res != TEE_SUCCESS) 326ba675d69SCedric Chaumont goto out; 327ba675d69SCedric Chaumont 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 3446915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 3456915bbbbSJens Wiklander __utee_check_instring_annotation(name); 3466915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 347ba675d69SCedric Chaumont 348ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_U32; 349ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 350ff857a3aSPascal Brand value, &uint32_len); 351ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_U32) 352ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 353ff857a3aSPascal Brand 354ff857a3aSPascal Brand if (res != TEE_SUCCESS && 355ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 356ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 357ff857a3aSPascal Brand TEE_Panic(0); 358ff857a3aSPascal Brand 359ff857a3aSPascal Brand return res; 360b0104773SPascal Brand } 361b0104773SPascal Brand 362*6551d565SJens Wiklander TEE_Result TEE_GetPropertyAsU64(TEE_PropSetHandle propsetOrEnumerator, 363*6551d565SJens Wiklander const char *name, uint64_t *value) 364b0104773SPascal Brand { 365b0104773SPascal Brand TEE_Result res; 366ff857a3aSPascal Brand enum user_ta_prop_type type; 367*6551d565SJens Wiklander uint32_t uint64_len = sizeof(*value); 368b0104773SPascal Brand 3696915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 3706915bbbbSJens Wiklander __utee_check_instring_annotation(name); 371*6551d565SJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 372*6551d565SJens Wiklander 373*6551d565SJens Wiklander type = USER_TA_PROP_TYPE_U64; 374*6551d565SJens Wiklander res = propget_get_property(propsetOrEnumerator, name, &type, 375*6551d565SJens Wiklander value, &uint64_len); 376*6551d565SJens Wiklander if (type != USER_TA_PROP_TYPE_U64) 377*6551d565SJens Wiklander res = TEE_ERROR_BAD_FORMAT; 378*6551d565SJens Wiklander 379*6551d565SJens Wiklander if (res != TEE_SUCCESS && 380*6551d565SJens Wiklander res != TEE_ERROR_ITEM_NOT_FOUND && 381*6551d565SJens Wiklander res != TEE_ERROR_BAD_FORMAT) 382*6551d565SJens Wiklander TEE_Panic(0); 383*6551d565SJens Wiklander 384*6551d565SJens Wiklander return res; 385*6551d565SJens Wiklander } 386*6551d565SJens Wiklander 387*6551d565SJens Wiklander TEE_Result 388*6551d565SJens Wiklander __GP11_TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 389*6551d565SJens Wiklander const char *name, void *value, 390*6551d565SJens Wiklander uint32_t *value_len) 391*6551d565SJens Wiklander { 392*6551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 393*6551d565SJens Wiklander enum user_ta_prop_type type = USER_TA_PROP_TYPE_BOOL; 394*6551d565SJens Wiklander 395*6551d565SJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 396*6551d565SJens Wiklander __utee_check_instring_annotation(name); 397*6551d565SJens Wiklander __utee_check_gp11_outbuf_annotation(value, value_len); 398ba675d69SCedric Chaumont 399ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BINARY_BLOCK; 400ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 4010dd3f3a4SPascal Brand value, value_len); 402ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BINARY_BLOCK) 403ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 404ff857a3aSPascal Brand 405ff857a3aSPascal Brand if (res != TEE_SUCCESS && 406ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 407ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT && 408ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 409ff857a3aSPascal Brand TEE_Panic(0); 410ff857a3aSPascal Brand 411ff857a3aSPascal Brand return res; 412b0104773SPascal Brand } 413b0104773SPascal Brand 414*6551d565SJens Wiklander TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 415*6551d565SJens Wiklander const char *name, void *value, 416*6551d565SJens Wiklander size_t *value_len) 417*6551d565SJens Wiklander { 418*6551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 419*6551d565SJens Wiklander uint32_t l = 0; 420*6551d565SJens Wiklander 421*6551d565SJens Wiklander __utee_check_outbuf_annotation(value, value_len); 422*6551d565SJens Wiklander l = *value_len; 423*6551d565SJens Wiklander res = __GP11_TEE_GetPropertyAsBinaryBlock(propsetOrEnumerator, name, 424*6551d565SJens Wiklander value, &l); 425*6551d565SJens Wiklander *value_len = l; 426*6551d565SJens Wiklander return res; 427*6551d565SJens Wiklander } 428*6551d565SJens Wiklander 429b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 4308f07fe6fSJerome Forissier const char *name, TEE_UUID *value) 431b0104773SPascal Brand { 432b0104773SPascal Brand TEE_Result res; 433ff857a3aSPascal Brand enum user_ta_prop_type type; 434ff857a3aSPascal Brand uint32_t uuid_len = sizeof(TEE_UUID); 435b0104773SPascal Brand 4366915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 4376915bbbbSJens Wiklander __utee_check_instring_annotation(name); 4386915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 439ba675d69SCedric Chaumont 440ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_UUID; 441ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 442ff857a3aSPascal Brand value, &uuid_len); 443ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_UUID) 444ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 445ff857a3aSPascal Brand 446ff857a3aSPascal Brand if (res != TEE_SUCCESS && 447ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 448ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 449ff857a3aSPascal Brand TEE_Panic(0); 450ff857a3aSPascal Brand 451ff857a3aSPascal Brand return res; 452b0104773SPascal Brand } 453b0104773SPascal Brand 454b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, 4558f07fe6fSJerome Forissier const char *name, TEE_Identity *value) 456b0104773SPascal Brand { 457b0104773SPascal Brand TEE_Result res; 458ff857a3aSPascal Brand enum user_ta_prop_type type; 459ff857a3aSPascal Brand uint32_t identity_len = sizeof(TEE_Identity); 460b0104773SPascal Brand 4616915bbbbSJens Wiklander if (is_propset_pseudo_handle(propsetOrEnumerator)) 4626915bbbbSJens Wiklander __utee_check_instring_annotation(name); 4636915bbbbSJens Wiklander __utee_check_out_annotation(value, sizeof(*value)); 464ba675d69SCedric Chaumont 465ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_IDENTITY; 466ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 467ff857a3aSPascal Brand value, &identity_len); 468ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_IDENTITY) 469ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 470ff857a3aSPascal Brand 471ff857a3aSPascal Brand if (res != TEE_SUCCESS && 472ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 473ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 474ff857a3aSPascal Brand TEE_Panic(0); 475ff857a3aSPascal Brand 476ff857a3aSPascal Brand return res; 477b0104773SPascal Brand } 478b0104773SPascal Brand 479b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 480b0104773SPascal Brand { 481ba675d69SCedric Chaumont TEE_Result res; 482b0104773SPascal Brand struct prop_enumerator *pe; 483b0104773SPascal Brand 4846915bbbbSJens Wiklander __utee_check_out_annotation(enumerator, sizeof(*enumerator)); 485b0104773SPascal Brand 486b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 487b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 488ba675d69SCedric Chaumont if (pe == NULL) { 489ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 490ba675d69SCedric Chaumont goto err; 491ba675d69SCedric Chaumont } 492b0104773SPascal Brand 493b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 494b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 495ba675d69SCedric Chaumont 496ba675d69SCedric Chaumont goto out; 497ba675d69SCedric Chaumont 498ba675d69SCedric Chaumont err: 499ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 500ba675d69SCedric Chaumont return res; 501ba675d69SCedric Chaumont TEE_Panic(0); 502ba675d69SCedric Chaumont out: 503b0104773SPascal Brand return TEE_SUCCESS; 504b0104773SPascal Brand } 505b0104773SPascal Brand 506b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 507b0104773SPascal Brand { 508b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 509b0104773SPascal Brand 510b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 511b0104773SPascal Brand } 512b0104773SPascal Brand 513b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 514b0104773SPascal Brand { 515b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 516b0104773SPascal Brand 517b0104773SPascal Brand TEE_Free(pe); 518b0104773SPascal Brand } 519b0104773SPascal Brand 520b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 521b0104773SPascal Brand TEE_PropSetHandle propSet) 522b0104773SPascal Brand { 523b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 524b0104773SPascal Brand 5250dd3f3a4SPascal Brand if (!pe) 526b0104773SPascal Brand return; 527b0104773SPascal Brand 528b0104773SPascal Brand pe->idx = 0; 529b0104773SPascal Brand pe->prop_set = propSet; 530b0104773SPascal Brand } 531b0104773SPascal Brand 532*6551d565SJens Wiklander TEE_Result __GP11_TEE_GetPropertyName(TEE_PropSetHandle enumerator, 5330dd3f3a4SPascal Brand void *name, uint32_t *name_len) 534b0104773SPascal Brand { 535b0104773SPascal Brand TEE_Result res; 536b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 537b0104773SPascal Brand const struct user_ta_property *eps; 538b0104773SPascal Brand size_t eps_len; 539b0104773SPascal Brand const char *str; 540b0104773SPascal Brand size_t bufferlen; 541b0104773SPascal Brand 5426915bbbbSJens Wiklander if (!pe) { 543ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 544ba675d69SCedric Chaumont goto err; 545ba675d69SCedric Chaumont } 546*6551d565SJens Wiklander __utee_check_gp11_outstring_annotation(name, name_len); 547b0104773SPascal Brand 5480dd3f3a4SPascal Brand bufferlen = *name_len; 54964a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 550b0104773SPascal Brand if (res != TEE_SUCCESS) 551ba675d69SCedric Chaumont goto err; 552b0104773SPascal Brand 55364a5011eSPascal Brand if (pe->idx < eps_len) { 55464a5011eSPascal Brand str = eps[pe->idx].name; 5550dd3f3a4SPascal Brand bufferlen = strlcpy(name, str, *name_len) + 1; 5560dd3f3a4SPascal Brand if (bufferlen > *name_len) 557ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 5580dd3f3a4SPascal Brand *name_len = bufferlen; 55964a5011eSPascal Brand } else { 5602c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 5612c028fdeSJerome Forissier pe->idx - eps_len, name, name_len, 5622c028fdeSJerome Forissier NULL, NULL, NULL); 56364a5011eSPascal Brand if (res != TEE_SUCCESS) 564ba675d69SCedric Chaumont goto err; 565ba675d69SCedric Chaumont } 566b0104773SPascal Brand 567ba675d69SCedric Chaumont err: 56864a5011eSPascal Brand if (res != TEE_SUCCESS && 56964a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 57064a5011eSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 571ba675d69SCedric Chaumont TEE_Panic(0); 57264a5011eSPascal Brand return res; 573b0104773SPascal Brand } 574b0104773SPascal Brand 575*6551d565SJens Wiklander TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 576*6551d565SJens Wiklander void *nameBuffer, size_t *nameBufferLen) 577*6551d565SJens Wiklander { 578*6551d565SJens Wiklander TEE_Result res = TEE_SUCCESS; 579*6551d565SJens Wiklander uint32_t l = 0; 580*6551d565SJens Wiklander 581*6551d565SJens Wiklander __utee_check_outstring_annotation(nameBuffer, nameBufferLen); 582*6551d565SJens Wiklander l = *nameBufferLen; 583*6551d565SJens Wiklander res = __GP11_TEE_GetPropertyName(enumerator, nameBuffer, &l); 584*6551d565SJens Wiklander *nameBufferLen = l; 585*6551d565SJens Wiklander return res; 586*6551d565SJens Wiklander } 587*6551d565SJens Wiklander 588b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 589b0104773SPascal Brand { 590b0104773SPascal Brand TEE_Result res; 591b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 592b0104773SPascal Brand uint32_t next_idx; 593b0104773SPascal Brand const struct user_ta_property *eps; 594b0104773SPascal Brand size_t eps_len; 595b0104773SPascal Brand 5960dd3f3a4SPascal Brand if (!pe) { 597ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 59864a5011eSPascal Brand goto out; 599ba675d69SCedric Chaumont } 600b0104773SPascal Brand 601ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 602ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 60364a5011eSPascal Brand goto out; 604ba675d69SCedric Chaumont } 605b0104773SPascal Brand 60664a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 607b0104773SPascal Brand if (res != TEE_SUCCESS) 60864a5011eSPascal Brand goto out; 609b0104773SPascal Brand 610b0104773SPascal Brand next_idx = pe->idx + 1; 611b0104773SPascal Brand pe->idx = next_idx; 61264a5011eSPascal Brand if (next_idx < eps_len) 61364a5011eSPascal Brand res = TEE_SUCCESS; 61464a5011eSPascal Brand else 6152c028fdeSJerome Forissier res = _utee_get_property((unsigned long)pe->prop_set, 6162c028fdeSJerome Forissier next_idx - eps_len, NULL, NULL, NULL, 6172c028fdeSJerome Forissier NULL, NULL); 618b0104773SPascal Brand 619ba675d69SCedric Chaumont out: 62064a5011eSPascal Brand if (res != TEE_SUCCESS && 62164a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND) 62264a5011eSPascal Brand TEE_Panic(0); 62364a5011eSPascal Brand return res; 624b0104773SPascal Brand } 625