1b0104773SPascal Brand /* 2b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 3b0104773SPascal Brand * All rights reserved. 4b0104773SPascal Brand * 5b0104773SPascal Brand * Redistribution and use in source and binary forms, with or without 6b0104773SPascal Brand * modification, are permitted provided that the following conditions are met: 7b0104773SPascal Brand * 8b0104773SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 9b0104773SPascal Brand * this list of conditions and the following disclaimer. 10b0104773SPascal Brand * 11b0104773SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 12b0104773SPascal Brand * this list of conditions and the following disclaimer in the documentation 13b0104773SPascal Brand * and/or other materials provided with the distribution. 14b0104773SPascal Brand * 15b0104773SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16b0104773SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17b0104773SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18b0104773SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19b0104773SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20b0104773SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21b0104773SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22b0104773SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23b0104773SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24b0104773SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25b0104773SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 26b0104773SPascal Brand */ 27b0104773SPascal Brand #include <tee_api.h> 28b0104773SPascal Brand 29b0104773SPascal Brand #include <stdlib.h> 30b0104773SPascal Brand #include <string.h> 31b0104773SPascal Brand #include <stdio.h> 32b0104773SPascal Brand #include <tee_api_defines.h> 33b0104773SPascal Brand #include <tee_api_types.h> 34b0104773SPascal Brand #include <user_ta_header.h> 35b0104773SPascal Brand #include <tee_internal_api_extensions.h> 36647f9c76SJerome Forissier #include <tee_arith_internal.h> 37*64a5011eSPascal Brand #include <util.h> 38b0104773SPascal Brand #include <utee_syscalls.h> 39b0104773SPascal Brand 40b0104773SPascal Brand #include "string_ext.h" 41b0104773SPascal Brand #include "base64.h" 42b0104773SPascal Brand 43b0104773SPascal Brand #define PROP_STR_MAX 80 44b0104773SPascal Brand 45b0104773SPascal Brand #define PROP_ENUMERATOR_NOT_STARTED 0xffffffff 46b0104773SPascal Brand 47b0104773SPascal Brand struct prop_enumerator { 48*64a5011eSPascal Brand uint32_t idx; /* current index */ 49*64a5011eSPascal Brand TEE_PropSetHandle prop_set; /* part of TEE_PROPSET_xxx */ 50b0104773SPascal Brand }; 51b0104773SPascal Brand 52b0104773SPascal Brand struct prop_value { 53b0104773SPascal Brand enum user_ta_prop_type type; 54b0104773SPascal Brand union { 55*64a5011eSPascal Brand uint32_t bool_val; 56b0104773SPascal Brand uint32_t int_val; 57b0104773SPascal Brand TEE_UUID uuid_val; 58b0104773SPascal Brand TEE_Identity identity_val; 59b0104773SPascal Brand char str_val[PROP_STR_MAX]; 60b0104773SPascal Brand } u; 61b0104773SPascal Brand }; 62b0104773SPascal Brand 63*64a5011eSPascal Brand const struct user_ta_property tee_props[] = { 64*64a5011eSPascal Brand { 65*64a5011eSPascal Brand "gpd.tee.arith.maxBigIntSize", 66*64a5011eSPascal Brand USER_TA_PROP_TYPE_U32, 67*64a5011eSPascal Brand &(const uint32_t){TEE_MAX_NUMBER_OF_SUPPORTED_BITS} 68*64a5011eSPascal Brand }, 69b0104773SPascal Brand }; 70b0104773SPascal Brand 71*64a5011eSPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, 72b0104773SPascal Brand const struct user_ta_property **eps, 73b0104773SPascal Brand size_t *eps_len) 74b0104773SPascal Brand { 75b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA) { 76b0104773SPascal Brand *eps = ta_props; 77b0104773SPascal Brand *eps_len = ta_num_props; 78b0104773SPascal Brand } else if (h == TEE_PROPSET_CURRENT_CLIENT) { 79b0104773SPascal Brand *eps = NULL; 80b0104773SPascal Brand *eps_len = 0; 81b0104773SPascal Brand } else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) { 82*64a5011eSPascal Brand *eps = tee_props; 83*64a5011eSPascal Brand *eps_len = ARRAY_SIZE(tee_props); 84b0104773SPascal Brand } else { 85b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 86b0104773SPascal Brand } 87b0104773SPascal Brand 88b0104773SPascal Brand return TEE_SUCCESS; 89b0104773SPascal Brand } 90b0104773SPascal Brand 91b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep, 92b0104773SPascal Brand struct prop_value *pv) 93b0104773SPascal Brand { 94b0104773SPascal Brand size_t l; 95b0104773SPascal Brand 96b0104773SPascal Brand pv->type = ep->type; 97b0104773SPascal Brand switch (ep->type) { 98b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 99*64a5011eSPascal Brand l = sizeof(uint32_t); 100b0104773SPascal Brand break; 101b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 102b0104773SPascal Brand l = sizeof(uint32_t); 103b0104773SPascal Brand break; 104b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 105b0104773SPascal Brand l = sizeof(TEE_UUID); 106b0104773SPascal Brand break; 107b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 108b0104773SPascal Brand l = sizeof(TEE_Identity); 109b0104773SPascal Brand break; 110b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 111b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 112b0104773SPascal Brand /* Handle too large strings by truncating them */ 113b0104773SPascal Brand strlcpy(pv->u.str_val, ep->value, sizeof(pv->u.str_val)); 114b0104773SPascal Brand return TEE_SUCCESS; 115b0104773SPascal Brand default: 116b0104773SPascal Brand return TEE_ERROR_GENERIC; 117b0104773SPascal Brand } 118b0104773SPascal Brand memcpy(&pv->u, ep->value, l); 119b0104773SPascal Brand return TEE_SUCCESS; 120b0104773SPascal Brand } 121b0104773SPascal Brand 122b0104773SPascal Brand static TEE_Result propget_get_property(TEE_PropSetHandle h, char *name, 123b0104773SPascal Brand struct prop_value *pv) 124b0104773SPascal Brand { 125b0104773SPascal Brand TEE_Result res; 126b0104773SPascal Brand const struct user_ta_property *eps; 127b0104773SPascal Brand size_t eps_len; 128*64a5011eSPascal Brand uint32_t prop_type; 129*64a5011eSPascal Brand uint32_t index; 130*64a5011eSPascal Brand uint32_t size; 131b0104773SPascal Brand 132b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA || h == TEE_PROPSET_CURRENT_CLIENT || 133b0104773SPascal Brand h == TEE_PROPSET_TEE_IMPLEMENTATION) { 134b0104773SPascal Brand size_t n; 135b0104773SPascal Brand 136*64a5011eSPascal Brand res = propset_get(h, &eps, &eps_len); 137b0104773SPascal Brand if (res != TEE_SUCCESS) 138b0104773SPascal Brand return res; 139b0104773SPascal Brand 140b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 141*64a5011eSPascal Brand if (!strcmp(name, eps[n].name)) 142b0104773SPascal Brand return propget_get_ext_prop(eps + n, pv); 143b0104773SPascal Brand } 144*64a5011eSPascal Brand 145*64a5011eSPascal Brand /* get the index from the name */ 146*64a5011eSPascal Brand res = utee_get_property_name_to_index((unsigned long)h, name, 147*64a5011eSPascal Brand strlen(name) + 1, &index); 148*64a5011eSPascal Brand if (res != TEE_SUCCESS) 149*64a5011eSPascal Brand return res; 150*64a5011eSPascal Brand size = sizeof(pv->u); 151*64a5011eSPascal Brand res = utee_get_property((unsigned long)h, index, 0, 0, 152*64a5011eSPascal Brand &pv->u, &size, &prop_type); 153b0104773SPascal Brand } else { 154b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)h; 155b0104773SPascal Brand uint32_t idx = pe->idx; 156b0104773SPascal Brand 157b0104773SPascal Brand if (idx == PROP_ENUMERATOR_NOT_STARTED) 158b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 159b0104773SPascal Brand 160*64a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 161b0104773SPascal Brand if (res != TEE_SUCCESS) 162b0104773SPascal Brand return res; 163b0104773SPascal Brand 164b0104773SPascal Brand if (idx < eps_len) 165b0104773SPascal Brand return propget_get_ext_prop(eps + idx, pv); 166*64a5011eSPascal Brand idx -= eps_len; 167b0104773SPascal Brand 168*64a5011eSPascal Brand size = sizeof(pv->u); 169*64a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, idx, 170*64a5011eSPascal Brand 0, 0, &pv->u, &size, &prop_type); 171*64a5011eSPascal Brand if (res == TEE_ERROR_ITEM_NOT_FOUND) 172*64a5011eSPascal Brand res = TEE_ERROR_BAD_PARAMETERS; 173b0104773SPascal Brand } 174*64a5011eSPascal Brand 175*64a5011eSPascal Brand if (res == TEE_SUCCESS) 176*64a5011eSPascal Brand pv->type = prop_type; 177*64a5011eSPascal Brand return res; 178b0104773SPascal Brand } 179b0104773SPascal Brand 180b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 181b0104773SPascal Brand char *name, char *valueBuffer, 18279a3c601SCedric Chaumont uint32_t *valueBufferLen) 183b0104773SPascal Brand { 184b0104773SPascal Brand TEE_Result res; 185b0104773SPascal Brand struct prop_value pv; 186b0104773SPascal Brand size_t l; 187b0104773SPascal Brand size_t bufferlen; 188b0104773SPascal Brand 189ba675d69SCedric Chaumont if (valueBuffer == NULL || valueBufferLen == NULL) { 190ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 191ba675d69SCedric Chaumont goto err; 192ba675d69SCedric Chaumont } 193b0104773SPascal Brand 194b0104773SPascal Brand bufferlen = *valueBufferLen; 195b0104773SPascal Brand 196b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 197b0104773SPascal Brand if (res != TEE_SUCCESS) 198ba675d69SCedric Chaumont goto err; 199b0104773SPascal Brand 200b0104773SPascal Brand switch (pv.type) { 201b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 202b0104773SPascal Brand l = strlcpy(valueBuffer, pv.u.bool_val ? "true" : "false", 203b0104773SPascal Brand bufferlen); 204b0104773SPascal Brand break; 205b0104773SPascal Brand 206b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 207b0104773SPascal Brand l = snprintf(valueBuffer, bufferlen, "%u", 208b0104773SPascal Brand (unsigned int)pv.u.int_val); 209b0104773SPascal Brand break; 210b0104773SPascal Brand 211b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 212b0104773SPascal Brand l = snprintf(valueBuffer, bufferlen, 213b0104773SPascal Brand "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", 214b0104773SPascal Brand (unsigned int)pv.u.uuid_val.timeLow, 215b0104773SPascal Brand pv.u.uuid_val.timeMid, 216b0104773SPascal Brand pv.u.uuid_val.timeHiAndVersion, 217b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[0], 218b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[1], 219b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[2], 220b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[3], 221b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[4], 222b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[5], 223b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[6], 224b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[7]); 225b0104773SPascal Brand break; 226b0104773SPascal Brand 227b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 228b0104773SPascal Brand l = snprintf(valueBuffer, bufferlen, 229b0104773SPascal Brand "%u:%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", 230b0104773SPascal Brand (unsigned int)pv.u.identity_val.login, 231b0104773SPascal Brand (unsigned int)pv.u.identity_val.uuid.timeLow, 232b0104773SPascal Brand pv.u.identity_val.uuid.timeMid, 233b0104773SPascal Brand pv.u.identity_val.uuid.timeHiAndVersion, 234b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[0], 235b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[1], 236b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[2], 237b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[3], 238b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[4], 239b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[5], 240b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[6], 241b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[7]); 242b0104773SPascal Brand break; 243b0104773SPascal Brand 244b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 245b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 246b0104773SPascal Brand l = strlcpy(valueBuffer, pv.u.str_val, bufferlen); 247b0104773SPascal Brand break; 248b0104773SPascal Brand 249b0104773SPascal Brand default: 250ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 251ba675d69SCedric Chaumont goto err; 252b0104773SPascal Brand } 253b0104773SPascal Brand 254b0104773SPascal Brand /* The size "must account for the zero terminator" */ 255b0104773SPascal Brand *valueBufferLen = l + 1; 256b0104773SPascal Brand 257ba675d69SCedric Chaumont if (l >= bufferlen) { 258ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 259ba675d69SCedric Chaumont goto err; 260ba675d69SCedric Chaumont } 261b0104773SPascal Brand 262ba675d69SCedric Chaumont goto out; 263ba675d69SCedric Chaumont 264ba675d69SCedric Chaumont err: 265ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 266ba675d69SCedric Chaumont res == TEE_ERROR_SHORT_BUFFER) 267ba675d69SCedric Chaumont return res; 268ba675d69SCedric Chaumont TEE_Panic(0); 269ba675d69SCedric Chaumont out: 270b0104773SPascal Brand return TEE_SUCCESS; 271b0104773SPascal Brand } 272b0104773SPascal Brand 273b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 274b0104773SPascal Brand char *name, bool *value) 275b0104773SPascal Brand { 276b0104773SPascal Brand TEE_Result res; 277b0104773SPascal Brand struct prop_value pv; 278b0104773SPascal Brand 279ba675d69SCedric Chaumont if (value == NULL) { 280ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 281ba675d69SCedric Chaumont goto err; 282ba675d69SCedric Chaumont } 283b0104773SPascal Brand 284b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 285b0104773SPascal Brand if (res != TEE_SUCCESS) 286ba675d69SCedric Chaumont goto err; 287b0104773SPascal Brand 288ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_BOOL) { 289ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 290ba675d69SCedric Chaumont goto err; 291ba675d69SCedric Chaumont } 292b0104773SPascal Brand 293*64a5011eSPascal Brand *value = !!pv.u.bool_val; 294ba675d69SCedric Chaumont 295ba675d69SCedric Chaumont goto out; 296ba675d69SCedric Chaumont 297ba675d69SCedric Chaumont err: 298ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 299ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 300ba675d69SCedric Chaumont return res; 301ba675d69SCedric Chaumont TEE_Panic(0); 302ba675d69SCedric Chaumont out: 303b0104773SPascal Brand return TEE_SUCCESS; 304b0104773SPascal Brand } 305b0104773SPascal Brand 306b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, 307b0104773SPascal Brand char *name, uint32_t *value) 308b0104773SPascal Brand { 309b0104773SPascal Brand TEE_Result res; 310b0104773SPascal Brand struct prop_value pv; 311b0104773SPascal Brand 312ba675d69SCedric Chaumont if (value == NULL) { 313ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 314ba675d69SCedric Chaumont goto err; 315ba675d69SCedric Chaumont } 316b0104773SPascal Brand 317b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 318b0104773SPascal Brand if (res != TEE_SUCCESS) 319ba675d69SCedric Chaumont goto err; 320b0104773SPascal Brand 321ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_U32) { 322ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 323ba675d69SCedric Chaumont goto err; 324ba675d69SCedric Chaumont } 325b0104773SPascal Brand 326b0104773SPascal Brand *value = pv.u.int_val; 327ba675d69SCedric Chaumont 328ba675d69SCedric Chaumont goto out; 329ba675d69SCedric Chaumont 330ba675d69SCedric Chaumont err: 331ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 332ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 333ba675d69SCedric Chaumont return res; 334ba675d69SCedric Chaumont TEE_Panic(0); 335ba675d69SCedric Chaumont out: 336b0104773SPascal Brand return TEE_SUCCESS; 337b0104773SPascal Brand } 338b0104773SPascal Brand 339b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 340b0104773SPascal Brand char *name, void *valueBuffer, 34179a3c601SCedric Chaumont uint32_t *valueBufferLen) 342b0104773SPascal Brand { 343b0104773SPascal Brand TEE_Result res; 344b0104773SPascal Brand struct prop_value pv; 345b0104773SPascal Brand void *val; 346b0104773SPascal Brand int val_len; 3477f74c64aSPascal Brand size_t size; 348b0104773SPascal Brand 349ba675d69SCedric Chaumont if (valueBuffer == NULL || valueBufferLen == NULL) { 350ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 351ba675d69SCedric Chaumont goto err; 352ba675d69SCedric Chaumont } 353b0104773SPascal Brand 354b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 355b0104773SPascal Brand if (res != TEE_SUCCESS) 356ba675d69SCedric Chaumont goto err; 357b0104773SPascal Brand 358ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_BINARY_BLOCK) { 359ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 360ba675d69SCedric Chaumont goto err; 361ba675d69SCedric Chaumont } 362b0104773SPascal Brand 363b0104773SPascal Brand val = pv.u.str_val; 364b0104773SPascal Brand val_len = strlen(val); 3657f74c64aSPascal Brand size = *valueBufferLen; 366ba675d69SCedric Chaumont if (!base64_dec(val, val_len, valueBuffer, &size)) { 3677f74c64aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 368ba675d69SCedric Chaumont goto err; 369ba675d69SCedric Chaumont } 370ba675d69SCedric Chaumont 3717f74c64aSPascal Brand *valueBufferLen = size; 372ba675d69SCedric Chaumont 373ba675d69SCedric Chaumont goto out; 374ba675d69SCedric Chaumont 375ba675d69SCedric Chaumont err: 376ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 377ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT || 378ba675d69SCedric Chaumont res == TEE_ERROR_SHORT_BUFFER) 3797f74c64aSPascal Brand return res; 380ba675d69SCedric Chaumont TEE_Panic(0); 381ba675d69SCedric Chaumont out: 382ba675d69SCedric Chaumont return TEE_SUCCESS; 383b0104773SPascal Brand } 384b0104773SPascal Brand 385b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 386b0104773SPascal Brand char *name, TEE_UUID *value) 387b0104773SPascal Brand { 388b0104773SPascal Brand TEE_Result res; 389b0104773SPascal Brand struct prop_value pv; 390b0104773SPascal Brand 391ba675d69SCedric Chaumont if (value == NULL) { 392ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 393ba675d69SCedric Chaumont goto err; 394ba675d69SCedric Chaumont } 395b0104773SPascal Brand 396b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 397b0104773SPascal Brand if (res != TEE_SUCCESS) 398ba675d69SCedric Chaumont goto err; 399b0104773SPascal Brand 400ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_UUID) { 401ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 402ba675d69SCedric Chaumont goto err; 403ba675d69SCedric Chaumont } 404b0104773SPascal Brand 405b0104773SPascal Brand *value = pv.u.uuid_val; /* struct copy */ 406ba675d69SCedric Chaumont 407ba675d69SCedric Chaumont goto out; 408ba675d69SCedric Chaumont 409ba675d69SCedric Chaumont err: 410ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 411ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 412ba675d69SCedric Chaumont return res; 413ba675d69SCedric Chaumont TEE_Panic(0); 414ba675d69SCedric Chaumont out: 415b0104773SPascal Brand return TEE_SUCCESS; 416b0104773SPascal Brand } 417b0104773SPascal Brand 418b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, 419b0104773SPascal Brand char *name, TEE_Identity *value) 420b0104773SPascal Brand { 421b0104773SPascal Brand TEE_Result res; 422b0104773SPascal Brand struct prop_value pv; 423b0104773SPascal Brand 424ba675d69SCedric Chaumont if (value == NULL) { 425ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 426ba675d69SCedric Chaumont goto err; 427ba675d69SCedric Chaumont } 428b0104773SPascal Brand 429b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 430b0104773SPascal Brand if (res != TEE_SUCCESS) 431ba675d69SCedric Chaumont goto err; 432b0104773SPascal Brand 433ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_IDENTITY) { 434ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 435ba675d69SCedric Chaumont goto err; 436ba675d69SCedric Chaumont } 437b0104773SPascal Brand 438b0104773SPascal Brand *value = pv.u.identity_val; /* struct copy */ 439ba675d69SCedric Chaumont 440ba675d69SCedric Chaumont goto out; 441ba675d69SCedric Chaumont 442ba675d69SCedric Chaumont err: 443ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 444ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 445ba675d69SCedric Chaumont return res; 446ba675d69SCedric Chaumont TEE_Panic(0); 447ba675d69SCedric Chaumont out: 448b0104773SPascal Brand return TEE_SUCCESS; 449b0104773SPascal Brand } 450b0104773SPascal Brand 451b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 452b0104773SPascal Brand { 453ba675d69SCedric Chaumont TEE_Result res; 454b0104773SPascal Brand struct prop_enumerator *pe; 455b0104773SPascal Brand 456ba675d69SCedric Chaumont if (enumerator == NULL) { 457ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 458ba675d69SCedric Chaumont goto err; 459ba675d69SCedric Chaumont } 460b0104773SPascal Brand 461b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 462b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 463ba675d69SCedric Chaumont if (pe == NULL) { 464ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 465ba675d69SCedric Chaumont goto err; 466ba675d69SCedric Chaumont } 467b0104773SPascal Brand 468b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 469b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 470ba675d69SCedric Chaumont 471ba675d69SCedric Chaumont goto out; 472ba675d69SCedric Chaumont 473ba675d69SCedric Chaumont err: 474ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 475ba675d69SCedric Chaumont return res; 476ba675d69SCedric Chaumont TEE_Panic(0); 477ba675d69SCedric Chaumont out: 478b0104773SPascal Brand return TEE_SUCCESS; 479b0104773SPascal Brand } 480b0104773SPascal Brand 481b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 482b0104773SPascal Brand { 483b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 484b0104773SPascal Brand 485b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 486b0104773SPascal Brand } 487b0104773SPascal Brand 488b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 489b0104773SPascal Brand { 490b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 491b0104773SPascal Brand 492b0104773SPascal Brand TEE_Free(pe); 493b0104773SPascal Brand } 494b0104773SPascal Brand 495b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 496b0104773SPascal Brand TEE_PropSetHandle propSet) 497b0104773SPascal Brand { 498b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 499b0104773SPascal Brand 500b0104773SPascal Brand if (pe == NULL) 501b0104773SPascal Brand return; 502b0104773SPascal Brand 503b0104773SPascal Brand pe->idx = 0; 504b0104773SPascal Brand pe->prop_set = propSet; 505b0104773SPascal Brand } 506b0104773SPascal Brand 507b0104773SPascal Brand TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 50879a3c601SCedric Chaumont void *nameBuffer, uint32_t *nameBufferLen) 509b0104773SPascal Brand { 510b0104773SPascal Brand TEE_Result res; 511b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 512b0104773SPascal Brand const struct user_ta_property *eps; 513b0104773SPascal Brand size_t eps_len; 514b0104773SPascal Brand const char *str; 515b0104773SPascal Brand size_t bufferlen; 516b0104773SPascal Brand 517ba675d69SCedric Chaumont if (pe == NULL || nameBuffer == NULL || nameBufferLen == NULL) { 518ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 519ba675d69SCedric Chaumont goto err; 520ba675d69SCedric Chaumont } 521b0104773SPascal Brand 522b0104773SPascal Brand bufferlen = *nameBufferLen; 523*64a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 524b0104773SPascal Brand if (res != TEE_SUCCESS) 525ba675d69SCedric Chaumont goto err; 526b0104773SPascal Brand 527*64a5011eSPascal Brand if (pe->idx < eps_len) { 528*64a5011eSPascal Brand str = eps[pe->idx].name; 529*64a5011eSPascal Brand bufferlen = strlcpy(nameBuffer, str, *nameBufferLen); 530*64a5011eSPascal Brand if (bufferlen >= *nameBufferLen) 531ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 532*64a5011eSPascal Brand *nameBufferLen = bufferlen; 533*64a5011eSPascal Brand } else { 534*64a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, 535*64a5011eSPascal Brand pe->idx - eps_len, 536*64a5011eSPascal Brand nameBuffer, nameBufferLen, 537*64a5011eSPascal Brand 0, 0, 0); 538*64a5011eSPascal Brand if (res != TEE_SUCCESS) 539ba675d69SCedric Chaumont goto err; 540ba675d69SCedric Chaumont } 541b0104773SPascal Brand 542ba675d69SCedric Chaumont err: 543*64a5011eSPascal Brand if (res != TEE_SUCCESS && 544*64a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 545*64a5011eSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 546ba675d69SCedric Chaumont TEE_Panic(0); 547*64a5011eSPascal Brand return res; 548b0104773SPascal Brand } 549b0104773SPascal Brand 550b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 551b0104773SPascal Brand { 552b0104773SPascal Brand TEE_Result res; 553b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 554b0104773SPascal Brand uint32_t next_idx; 555b0104773SPascal Brand const struct user_ta_property *eps; 556b0104773SPascal Brand size_t eps_len; 557b0104773SPascal Brand 558ba675d69SCedric Chaumont if (pe == NULL) { 559ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 560*64a5011eSPascal Brand goto out; 561ba675d69SCedric Chaumont } 562b0104773SPascal Brand 563ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 564ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 565*64a5011eSPascal Brand goto out; 566ba675d69SCedric Chaumont } 567b0104773SPascal Brand 568*64a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 569b0104773SPascal Brand if (res != TEE_SUCCESS) 570*64a5011eSPascal Brand goto out; 571b0104773SPascal Brand 572b0104773SPascal Brand next_idx = pe->idx + 1; 573b0104773SPascal Brand pe->idx = next_idx; 574*64a5011eSPascal Brand if (next_idx < eps_len) 575*64a5011eSPascal Brand res = TEE_SUCCESS; 576*64a5011eSPascal Brand else 577*64a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, 578*64a5011eSPascal Brand next_idx - eps_len, 0, 0, 0, 0, 0); 579b0104773SPascal Brand 580ba675d69SCedric Chaumont out: 581*64a5011eSPascal Brand if (res != TEE_SUCCESS && 582*64a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND) 583*64a5011eSPascal Brand TEE_Panic(0); 584*64a5011eSPascal Brand return res; 585b0104773SPascal Brand } 586