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> 32*ff857a3aSPascal Brand #include <printk.h> 33b0104773SPascal Brand #include <tee_api_defines.h> 34b0104773SPascal Brand #include <tee_api_types.h> 35b0104773SPascal Brand #include <user_ta_header.h> 36b0104773SPascal Brand #include <tee_internal_api_extensions.h> 37647f9c76SJerome Forissier #include <tee_arith_internal.h> 3864a5011eSPascal Brand #include <util.h> 39b0104773SPascal Brand #include <utee_syscalls.h> 40b0104773SPascal Brand 41b0104773SPascal Brand #include "string_ext.h" 42b0104773SPascal Brand #include "base64.h" 43b0104773SPascal Brand 44b0104773SPascal Brand #define PROP_STR_MAX 80 45b0104773SPascal Brand 46b0104773SPascal Brand #define PROP_ENUMERATOR_NOT_STARTED 0xffffffff 47b0104773SPascal Brand 48b0104773SPascal Brand struct prop_enumerator { 4964a5011eSPascal Brand uint32_t idx; /* current index */ 5064a5011eSPascal Brand TEE_PropSetHandle prop_set; /* part of TEE_PROPSET_xxx */ 51b0104773SPascal Brand }; 52b0104773SPascal Brand 5364a5011eSPascal Brand const struct user_ta_property tee_props[] = { 5464a5011eSPascal Brand { 5564a5011eSPascal Brand "gpd.tee.arith.maxBigIntSize", 5664a5011eSPascal Brand USER_TA_PROP_TYPE_U32, 5764a5011eSPascal Brand &(const uint32_t){TEE_MAX_NUMBER_OF_SUPPORTED_BITS} 5864a5011eSPascal Brand }, 59b0104773SPascal Brand }; 60b0104773SPascal Brand 6164a5011eSPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, 62b0104773SPascal Brand const struct user_ta_property **eps, 63b0104773SPascal Brand size_t *eps_len) 64b0104773SPascal Brand { 65b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA) { 66b0104773SPascal Brand *eps = ta_props; 67b0104773SPascal Brand *eps_len = ta_num_props; 68b0104773SPascal Brand } else if (h == TEE_PROPSET_CURRENT_CLIENT) { 69b0104773SPascal Brand *eps = NULL; 70b0104773SPascal Brand *eps_len = 0; 71b0104773SPascal Brand } else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) { 7264a5011eSPascal Brand *eps = tee_props; 7364a5011eSPascal Brand *eps_len = ARRAY_SIZE(tee_props); 74b0104773SPascal Brand } else { 75b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 76b0104773SPascal Brand } 77b0104773SPascal Brand 78b0104773SPascal Brand return TEE_SUCCESS; 79b0104773SPascal Brand } 80b0104773SPascal Brand 81b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep, 82*ff857a3aSPascal Brand enum user_ta_prop_type *type, 83*ff857a3aSPascal Brand void *buf, uint32_t *len) 84b0104773SPascal Brand { 85b0104773SPascal Brand size_t l; 86b0104773SPascal Brand 87*ff857a3aSPascal Brand *type = ep->type; 88*ff857a3aSPascal Brand switch (*type) { 89b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 9064a5011eSPascal Brand l = sizeof(uint32_t); 91b0104773SPascal Brand break; 92b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 93b0104773SPascal Brand l = sizeof(uint32_t); 94b0104773SPascal Brand break; 95b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 96b0104773SPascal Brand l = sizeof(TEE_UUID); 97b0104773SPascal Brand break; 98b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 99b0104773SPascal Brand l = sizeof(TEE_Identity); 100b0104773SPascal Brand break; 101b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 102*ff857a3aSPascal Brand /* take the leading 0 into account */ 103*ff857a3aSPascal Brand l = strlen(ep->value) + 1; 104*ff857a3aSPascal Brand break; 105b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 106*ff857a3aSPascal Brand /* 107*ff857a3aSPascal Brand * in case of TA property, a binary block is provided as a 108*ff857a3aSPascal Brand * string, which is base64 encoded. We must first decode it, 109*ff857a3aSPascal Brand * without taking into account the zero termination of the 110*ff857a3aSPascal Brand * string 111*ff857a3aSPascal Brand */ 112*ff857a3aSPascal Brand l = *len; 113*ff857a3aSPascal Brand if (!base64_dec(ep->value, strlen(ep->value), buf, &l) && 114*ff857a3aSPascal Brand (l <= *len)) 115*ff857a3aSPascal Brand return TEE_ERROR_GENERIC; 116*ff857a3aSPascal Brand if (*len < l) { 117*ff857a3aSPascal Brand *len = l; 118*ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 119*ff857a3aSPascal Brand } 120*ff857a3aSPascal Brand 121*ff857a3aSPascal Brand *len = l; 122b0104773SPascal Brand return TEE_SUCCESS; 123b0104773SPascal Brand default: 124b0104773SPascal Brand return TEE_ERROR_GENERIC; 125b0104773SPascal Brand } 126*ff857a3aSPascal Brand 127*ff857a3aSPascal Brand if (*len < l) { 128*ff857a3aSPascal Brand *len = l; 129*ff857a3aSPascal Brand return TEE_ERROR_SHORT_BUFFER; 130*ff857a3aSPascal Brand } 131*ff857a3aSPascal Brand 132*ff857a3aSPascal Brand *len = l; 133*ff857a3aSPascal Brand memcpy(buf, ep->value, l); 134b0104773SPascal Brand return TEE_SUCCESS; 135b0104773SPascal Brand } 136b0104773SPascal Brand 137b0104773SPascal Brand static TEE_Result propget_get_property(TEE_PropSetHandle h, char *name, 138*ff857a3aSPascal Brand enum user_ta_prop_type *type, 139*ff857a3aSPascal 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 147b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA || h == TEE_PROPSET_CURRENT_CLIENT || 148b0104773SPascal Brand h == TEE_PROPSET_TEE_IMPLEMENTATION) { 149b0104773SPascal Brand size_t n; 150b0104773SPascal Brand 15164a5011eSPascal Brand res = propset_get(h, &eps, &eps_len); 152b0104773SPascal Brand if (res != TEE_SUCCESS) 153b0104773SPascal Brand return res; 154b0104773SPascal Brand 155b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 15664a5011eSPascal Brand if (!strcmp(name, eps[n].name)) 157*ff857a3aSPascal Brand return propget_get_ext_prop(eps + n, type, 158*ff857a3aSPascal Brand buf, len); 159b0104773SPascal Brand } 16064a5011eSPascal Brand 16164a5011eSPascal Brand /* get the index from the name */ 16264a5011eSPascal Brand res = utee_get_property_name_to_index((unsigned long)h, name, 16364a5011eSPascal Brand strlen(name) + 1, &index); 16464a5011eSPascal Brand if (res != TEE_SUCCESS) 16564a5011eSPascal Brand return res; 166*ff857a3aSPascal Brand res = utee_get_property((unsigned long)h, index, NULL, NULL, 167*ff857a3aSPascal 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) 180*ff857a3aSPascal Brand return propget_get_ext_prop(eps + idx, type, buf, len); 18164a5011eSPascal Brand idx -= eps_len; 182b0104773SPascal Brand 18364a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, idx, 184*ff857a3aSPascal 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 189*ff857a3aSPascal Brand *type = prop_type; 19064a5011eSPascal Brand return res; 191b0104773SPascal Brand } 192b0104773SPascal Brand 193b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 194b0104773SPascal Brand char *name, char *valueBuffer, 19579a3c601SCedric Chaumont uint32_t *valueBufferLen) 196b0104773SPascal Brand { 197b0104773SPascal Brand TEE_Result res; 198b0104773SPascal Brand size_t l; 199*ff857a3aSPascal Brand enum user_ta_prop_type type; 200*ff857a3aSPascal Brand void *tmp_buf = 0; 201*ff857a3aSPascal Brand uint32_t tmp_len; 202*ff857a3aSPascal Brand uint32_t uint32_val; 203*ff857a3aSPascal Brand TEE_Identity *p_identity_val; 204b0104773SPascal Brand 205ba675d69SCedric Chaumont if (valueBuffer == NULL || valueBufferLen == NULL) { 206ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 207*ff857a3aSPascal Brand goto out; 208ba675d69SCedric Chaumont } 209b0104773SPascal Brand 210*ff857a3aSPascal Brand tmp_len = *valueBufferLen; 211*ff857a3aSPascal Brand if (tmp_len < sizeof(TEE_Identity)) 212*ff857a3aSPascal Brand tmp_len = sizeof(TEE_Identity); 213*ff857a3aSPascal Brand tmp_buf = TEE_Malloc(tmp_len, TEE_USER_MEM_HINT_NO_FILL_ZERO); 214*ff857a3aSPascal Brand if (!tmp_buf) { 215*ff857a3aSPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 216*ff857a3aSPascal Brand goto out; 217*ff857a3aSPascal Brand } 218b0104773SPascal Brand 219*ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 220*ff857a3aSPascal Brand tmp_buf, &tmp_len); 221*ff857a3aSPascal Brand if (res != TEE_SUCCESS) { 222*ff857a3aSPascal Brand if (res == TEE_ERROR_SHORT_BUFFER) 223*ff857a3aSPascal Brand *valueBufferLen = tmp_len; 224*ff857a3aSPascal Brand goto out; 225*ff857a3aSPascal Brand } 226b0104773SPascal Brand 227*ff857a3aSPascal Brand switch (type) { 228b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 229*ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 230*ff857a3aSPascal Brand l = strlcpy(valueBuffer, (uint32_val ? "true" : "false"), 231*ff857a3aSPascal Brand *valueBufferLen); 232b0104773SPascal Brand break; 233b0104773SPascal Brand 234b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 235*ff857a3aSPascal Brand uint32_val = *((uint32_t *)tmp_buf); 236*ff857a3aSPascal Brand l = snprintf(valueBuffer, *valueBufferLen, "%u", uint32_val); 237b0104773SPascal Brand break; 238b0104773SPascal Brand 239b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 240*ff857a3aSPascal Brand l = snprintk(valueBuffer, *valueBufferLen, "%pUl", tmp_buf); 241b0104773SPascal Brand break; 242b0104773SPascal Brand 243b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 244*ff857a3aSPascal Brand p_identity_val = ((TEE_Identity *)tmp_buf); 245*ff857a3aSPascal Brand l = snprintk(valueBuffer, *valueBufferLen, "%u:%pUl", 246*ff857a3aSPascal Brand p_identity_val->login, 247*ff857a3aSPascal Brand (void *)(&(p_identity_val->uuid))); 248b0104773SPascal Brand break; 249b0104773SPascal Brand 250b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 251*ff857a3aSPascal Brand l = strlcpy(valueBuffer, tmp_buf, *valueBufferLen); 252*ff857a3aSPascal Brand break; 253*ff857a3aSPascal Brand 254b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 255*ff857a3aSPascal Brand l = *valueBufferLen; /* l includes the zero-termination */ 256*ff857a3aSPascal Brand if (!base64_enc(tmp_buf, tmp_len, valueBuffer, &l) && 257*ff857a3aSPascal Brand (l <= *valueBufferLen)) { 258*ff857a3aSPascal Brand res = TEE_ERROR_GENERIC; 259*ff857a3aSPascal Brand goto out; 260*ff857a3aSPascal Brand } 261*ff857a3aSPascal Brand l--; /* remove the zero-termination that is added later */ 262b0104773SPascal Brand break; 263b0104773SPascal Brand 264b0104773SPascal Brand default: 265ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 266ba675d69SCedric Chaumont goto out; 267*ff857a3aSPascal Brand } 268ba675d69SCedric Chaumont 269*ff857a3aSPascal Brand l++; /* include zero termination */ 270*ff857a3aSPascal Brand 271*ff857a3aSPascal Brand if (l > *valueBufferLen) 272*ff857a3aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 273*ff857a3aSPascal Brand *valueBufferLen = l; 274*ff857a3aSPascal Brand 275ba675d69SCedric Chaumont out: 276*ff857a3aSPascal Brand if (tmp_buf) 277*ff857a3aSPascal Brand TEE_Free(tmp_buf); 278*ff857a3aSPascal Brand if (res != TEE_SUCCESS && 279*ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 280*ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 281*ff857a3aSPascal Brand TEE_Panic(0); 282*ff857a3aSPascal Brand 283*ff857a3aSPascal Brand return res; 284b0104773SPascal Brand } 285b0104773SPascal Brand 286b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 287b0104773SPascal Brand char *name, bool *value) 288b0104773SPascal Brand { 289b0104773SPascal Brand TEE_Result res; 290*ff857a3aSPascal Brand enum user_ta_prop_type type; 291*ff857a3aSPascal Brand uint32_t uint32_val; 292*ff857a3aSPascal Brand uint32_t uint32_len = sizeof(uint32_val); 293ba675d69SCedric Chaumont if (value == NULL) { 294ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 295*ff857a3aSPascal Brand goto out; 296ba675d69SCedric Chaumont } 297b0104773SPascal Brand 298*ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BOOL; 299*ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 300*ff857a3aSPascal Brand &uint32_val, &uint32_len); 301*ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BOOL) 302ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 303*ff857a3aSPascal Brand if (res != TEE_SUCCESS) 304ba675d69SCedric Chaumont goto out; 305ba675d69SCedric Chaumont 306*ff857a3aSPascal Brand *value = !!uint32_val; 307*ff857a3aSPascal Brand 308ba675d69SCedric Chaumont out: 309*ff857a3aSPascal Brand if (res != TEE_SUCCESS && 310*ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 311*ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 312*ff857a3aSPascal Brand TEE_Panic(0); 313*ff857a3aSPascal Brand 314*ff857a3aSPascal Brand return res; 315b0104773SPascal Brand } 316b0104773SPascal Brand 317b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, 318b0104773SPascal Brand char *name, uint32_t *value) 319b0104773SPascal Brand { 320b0104773SPascal Brand TEE_Result res; 321*ff857a3aSPascal Brand enum user_ta_prop_type type; 322*ff857a3aSPascal Brand uint32_t uint32_len = sizeof(uint32_t); 323b0104773SPascal Brand 324ba675d69SCedric Chaumont if (value == NULL) { 325ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 326ba675d69SCedric Chaumont goto out; 327*ff857a3aSPascal Brand } 328ba675d69SCedric Chaumont 329*ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_U32; 330*ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 331*ff857a3aSPascal Brand value, &uint32_len); 332*ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_U32) 333*ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 334*ff857a3aSPascal Brand 335ba675d69SCedric Chaumont out: 336*ff857a3aSPascal Brand if (res != TEE_SUCCESS && 337*ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 338*ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 339*ff857a3aSPascal Brand TEE_Panic(0); 340*ff857a3aSPascal Brand 341*ff857a3aSPascal Brand return res; 342b0104773SPascal Brand } 343b0104773SPascal Brand 344b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 345b0104773SPascal Brand char *name, void *valueBuffer, 34679a3c601SCedric Chaumont uint32_t *valueBufferLen) 347b0104773SPascal Brand { 348b0104773SPascal Brand TEE_Result res; 349*ff857a3aSPascal Brand enum user_ta_prop_type type; 350b0104773SPascal Brand 351ba675d69SCedric Chaumont if (valueBuffer == NULL || valueBufferLen == NULL) { 352ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 353ba675d69SCedric Chaumont goto out; 354*ff857a3aSPascal Brand } 355ba675d69SCedric Chaumont 356*ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_BINARY_BLOCK; 357*ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 358*ff857a3aSPascal Brand valueBuffer, valueBufferLen); 359*ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_BINARY_BLOCK) 360*ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 361*ff857a3aSPascal Brand 362ba675d69SCedric Chaumont out: 363*ff857a3aSPascal Brand if (res != TEE_SUCCESS && 364*ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 365*ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT && 366*ff857a3aSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 367*ff857a3aSPascal Brand TEE_Panic(0); 368*ff857a3aSPascal Brand 369*ff857a3aSPascal Brand return res; 370b0104773SPascal Brand } 371b0104773SPascal Brand 372b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 373b0104773SPascal Brand char *name, TEE_UUID *value) 374b0104773SPascal Brand { 375b0104773SPascal Brand TEE_Result res; 376*ff857a3aSPascal Brand enum user_ta_prop_type type; 377*ff857a3aSPascal Brand uint32_t uuid_len = sizeof(TEE_UUID); 378b0104773SPascal Brand 379ba675d69SCedric Chaumont if (value == NULL) { 380ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 381ba675d69SCedric Chaumont goto out; 382*ff857a3aSPascal Brand } 383ba675d69SCedric Chaumont 384*ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_UUID; 385*ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 386*ff857a3aSPascal Brand value, &uuid_len); 387*ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_UUID) 388*ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 389*ff857a3aSPascal Brand 390ba675d69SCedric Chaumont out: 391*ff857a3aSPascal Brand if (res != TEE_SUCCESS && 392*ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 393*ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 394*ff857a3aSPascal Brand TEE_Panic(0); 395*ff857a3aSPascal Brand 396*ff857a3aSPascal Brand return res; 397b0104773SPascal Brand } 398b0104773SPascal Brand 399b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, 400b0104773SPascal Brand char *name, TEE_Identity *value) 401b0104773SPascal Brand { 402b0104773SPascal Brand TEE_Result res; 403*ff857a3aSPascal Brand enum user_ta_prop_type type; 404*ff857a3aSPascal Brand uint32_t identity_len = sizeof(TEE_Identity); 405b0104773SPascal Brand 406ba675d69SCedric Chaumont if (value == NULL) { 407ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 408ba675d69SCedric Chaumont goto out; 409*ff857a3aSPascal Brand } 410ba675d69SCedric Chaumont 411*ff857a3aSPascal Brand type = USER_TA_PROP_TYPE_IDENTITY; 412*ff857a3aSPascal Brand res = propget_get_property(propsetOrEnumerator, name, &type, 413*ff857a3aSPascal Brand value, &identity_len); 414*ff857a3aSPascal Brand if (type != USER_TA_PROP_TYPE_IDENTITY) 415*ff857a3aSPascal Brand res = TEE_ERROR_BAD_FORMAT; 416*ff857a3aSPascal Brand 417ba675d69SCedric Chaumont out: 418*ff857a3aSPascal Brand if (res != TEE_SUCCESS && 419*ff857a3aSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 420*ff857a3aSPascal Brand res != TEE_ERROR_BAD_FORMAT) 421*ff857a3aSPascal Brand TEE_Panic(0); 422*ff857a3aSPascal Brand 423*ff857a3aSPascal Brand return res; 424b0104773SPascal Brand } 425b0104773SPascal Brand 426b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 427b0104773SPascal Brand { 428ba675d69SCedric Chaumont TEE_Result res; 429b0104773SPascal Brand struct prop_enumerator *pe; 430b0104773SPascal Brand 431ba675d69SCedric Chaumont if (enumerator == NULL) { 432ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 433ba675d69SCedric Chaumont goto err; 434ba675d69SCedric Chaumont } 435b0104773SPascal Brand 436b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 437b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 438ba675d69SCedric Chaumont if (pe == NULL) { 439ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 440ba675d69SCedric Chaumont goto err; 441ba675d69SCedric Chaumont } 442b0104773SPascal Brand 443b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 444b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 445ba675d69SCedric Chaumont 446ba675d69SCedric Chaumont goto out; 447ba675d69SCedric Chaumont 448ba675d69SCedric Chaumont err: 449ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 450ba675d69SCedric Chaumont return res; 451ba675d69SCedric Chaumont TEE_Panic(0); 452ba675d69SCedric Chaumont out: 453b0104773SPascal Brand return TEE_SUCCESS; 454b0104773SPascal Brand } 455b0104773SPascal Brand 456b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 457b0104773SPascal Brand { 458b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 459b0104773SPascal Brand 460b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 461b0104773SPascal Brand } 462b0104773SPascal Brand 463b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 464b0104773SPascal Brand { 465b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 466b0104773SPascal Brand 467b0104773SPascal Brand TEE_Free(pe); 468b0104773SPascal Brand } 469b0104773SPascal Brand 470b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 471b0104773SPascal Brand TEE_PropSetHandle propSet) 472b0104773SPascal Brand { 473b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 474b0104773SPascal Brand 475b0104773SPascal Brand if (pe == NULL) 476b0104773SPascal Brand return; 477b0104773SPascal Brand 478b0104773SPascal Brand pe->idx = 0; 479b0104773SPascal Brand pe->prop_set = propSet; 480b0104773SPascal Brand } 481b0104773SPascal Brand 482b0104773SPascal Brand TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 48379a3c601SCedric Chaumont void *nameBuffer, uint32_t *nameBufferLen) 484b0104773SPascal Brand { 485b0104773SPascal Brand TEE_Result res; 486b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 487b0104773SPascal Brand const struct user_ta_property *eps; 488b0104773SPascal Brand size_t eps_len; 489b0104773SPascal Brand const char *str; 490b0104773SPascal Brand size_t bufferlen; 491b0104773SPascal Brand 492ba675d69SCedric Chaumont if (pe == NULL || nameBuffer == NULL || nameBufferLen == NULL) { 493ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 494ba675d69SCedric Chaumont goto err; 495ba675d69SCedric Chaumont } 496b0104773SPascal Brand 497b0104773SPascal Brand bufferlen = *nameBufferLen; 49864a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 499b0104773SPascal Brand if (res != TEE_SUCCESS) 500ba675d69SCedric Chaumont goto err; 501b0104773SPascal Brand 50264a5011eSPascal Brand if (pe->idx < eps_len) { 50364a5011eSPascal Brand str = eps[pe->idx].name; 504*ff857a3aSPascal Brand bufferlen = strlcpy(nameBuffer, str, *nameBufferLen) + 1; 505*ff857a3aSPascal Brand if (bufferlen > *nameBufferLen) 506ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 50764a5011eSPascal Brand *nameBufferLen = bufferlen; 50864a5011eSPascal Brand } else { 50964a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, 51064a5011eSPascal Brand pe->idx - eps_len, 51164a5011eSPascal Brand nameBuffer, nameBufferLen, 512*ff857a3aSPascal Brand NULL, NULL, NULL); 51364a5011eSPascal Brand if (res != TEE_SUCCESS) 514ba675d69SCedric Chaumont goto err; 515ba675d69SCedric Chaumont } 516b0104773SPascal Brand 517ba675d69SCedric Chaumont err: 51864a5011eSPascal Brand if (res != TEE_SUCCESS && 51964a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND && 52064a5011eSPascal Brand res != TEE_ERROR_SHORT_BUFFER) 521ba675d69SCedric Chaumont TEE_Panic(0); 52264a5011eSPascal Brand return res; 523b0104773SPascal Brand } 524b0104773SPascal Brand 525b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 526b0104773SPascal Brand { 527b0104773SPascal Brand TEE_Result res; 528b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 529b0104773SPascal Brand uint32_t next_idx; 530b0104773SPascal Brand const struct user_ta_property *eps; 531b0104773SPascal Brand size_t eps_len; 532b0104773SPascal Brand 533ba675d69SCedric Chaumont if (pe == NULL) { 534ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 53564a5011eSPascal Brand goto out; 536ba675d69SCedric Chaumont } 537b0104773SPascal Brand 538ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 539ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 54064a5011eSPascal Brand goto out; 541ba675d69SCedric Chaumont } 542b0104773SPascal Brand 54364a5011eSPascal Brand res = propset_get(pe->prop_set, &eps, &eps_len); 544b0104773SPascal Brand if (res != TEE_SUCCESS) 54564a5011eSPascal Brand goto out; 546b0104773SPascal Brand 547b0104773SPascal Brand next_idx = pe->idx + 1; 548b0104773SPascal Brand pe->idx = next_idx; 54964a5011eSPascal Brand if (next_idx < eps_len) 55064a5011eSPascal Brand res = TEE_SUCCESS; 55164a5011eSPascal Brand else 55264a5011eSPascal Brand res = utee_get_property((unsigned long)pe->prop_set, 553*ff857a3aSPascal Brand next_idx - eps_len, 554*ff857a3aSPascal Brand NULL, NULL, NULL, NULL, NULL); 555b0104773SPascal Brand 556ba675d69SCedric Chaumont out: 55764a5011eSPascal Brand if (res != TEE_SUCCESS && 55864a5011eSPascal Brand res != TEE_ERROR_ITEM_NOT_FOUND) 55964a5011eSPascal Brand TEE_Panic(0); 56064a5011eSPascal Brand return res; 561b0104773SPascal Brand } 562