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> 37b0104773SPascal Brand 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 { 48b0104773SPascal Brand uint32_t idx; 49b0104773SPascal Brand TEE_PropSetHandle prop_set; 50b0104773SPascal Brand }; 51b0104773SPascal Brand 52b0104773SPascal Brand struct prop_value { 53b0104773SPascal Brand enum user_ta_prop_type type; 54b0104773SPascal Brand union { 55b0104773SPascal Brand bool 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 63b0104773SPascal Brand typedef TEE_Result(*ta_propget_func_t) (struct prop_value *pv); 64b0104773SPascal Brand 65b0104773SPascal Brand struct prop_set { 66b0104773SPascal Brand const char *str; 67b0104773SPascal Brand ta_propget_func_t get; 68b0104773SPascal Brand }; 69b0104773SPascal Brand 70b0104773SPascal Brand static TEE_Result propget_gpd_ta_app_id(struct prop_value *pv) 71b0104773SPascal Brand { 72b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_UUID; 73b0104773SPascal Brand return utee_get_property(UTEE_PROP_TA_APP_ID, &pv->u.uuid_val, 74b0104773SPascal Brand sizeof(pv->u.uuid_val)); 75b0104773SPascal Brand } 76b0104773SPascal Brand 77b0104773SPascal Brand static TEE_Result propget_gpd_client_identity(struct prop_value *pv) 78b0104773SPascal Brand { 79b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_IDENTITY; 80b0104773SPascal Brand return utee_get_property(UTEE_PROP_CLIENT_ID, &pv->u.identity_val, 81b0104773SPascal Brand sizeof(pv->u.identity_val)); 82b0104773SPascal Brand } 83b0104773SPascal Brand 84b0104773SPascal Brand static TEE_Result propget_gpd_tee_api_version(struct prop_value *pv) 85b0104773SPascal Brand { 86b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_STRING; 87b0104773SPascal Brand return utee_get_property(UTEE_PROP_TEE_API_VERSION, &pv->u.str_val, 88b0104773SPascal Brand sizeof(pv->u.str_val)); 89b0104773SPascal Brand } 90b0104773SPascal Brand 91b0104773SPascal Brand static TEE_Result propget_gpd_tee_description(struct prop_value *pv) 92b0104773SPascal Brand { 93b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_STRING; 94b0104773SPascal Brand return utee_get_property(UTEE_PROP_TEE_DESCR, &pv->u.str_val, 95b0104773SPascal Brand sizeof(pv->u.str_val)); 96b0104773SPascal Brand } 97b0104773SPascal Brand 98b0104773SPascal Brand static TEE_Result propget_gpd_tee_device_id(struct prop_value *pv) 99b0104773SPascal Brand { 100b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_UUID; 101b0104773SPascal Brand return utee_get_property(UTEE_PROP_TEE_DEV_ID, &pv->u.uuid_val, 102b0104773SPascal Brand sizeof(pv->u.uuid_val)); 103b0104773SPascal Brand } 104b0104773SPascal Brand 105b0104773SPascal Brand static TEE_Result propget_gpd_tee_sys_time_protection_level(struct prop_value 106b0104773SPascal Brand *pv) 107b0104773SPascal Brand { 108b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_U32; 109b0104773SPascal Brand return utee_get_property(UTEE_PROP_TEE_SYS_TIME_PROT_LEVEL, 110b0104773SPascal Brand &pv->u.int_val, sizeof(pv->u.int_val)); 111b0104773SPascal Brand } 112b0104773SPascal Brand 113b0104773SPascal Brand static TEE_Result propget_gpd_tee_ta_time_protection_level(struct prop_value 114b0104773SPascal Brand *pv) 115b0104773SPascal Brand { 116b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_U32; 117b0104773SPascal Brand return utee_get_property(UTEE_PROP_TEE_TA_TIME_PROT_LEVEL, 118b0104773SPascal Brand &pv->u.int_val, sizeof(pv->u.int_val)); 119b0104773SPascal Brand } 120b0104773SPascal Brand 121b0104773SPascal Brand static TEE_Result propget_gpd_tee_arith_max_big_int_size(struct prop_value *pv) 122b0104773SPascal Brand { 123b0104773SPascal Brand pv->type = USER_TA_PROP_TYPE_U32; 124647f9c76SJerome Forissier pv->u.int_val = TEE_MAX_NUMBER_OF_SUPPORTED_BITS; 125647f9c76SJerome Forissier return TEE_SUCCESS; 126b0104773SPascal Brand } 127b0104773SPascal Brand 128b0104773SPascal Brand static const struct prop_set propset_current_ta[] = { 129b0104773SPascal Brand {"gpd.ta.appID", propget_gpd_ta_app_id}, 130b0104773SPascal Brand }; 131b0104773SPascal Brand 132b0104773SPascal Brand static const size_t propset_current_ta_len = 133b0104773SPascal Brand sizeof(propset_current_ta) / sizeof(propset_current_ta[0]); 134b0104773SPascal Brand 135b0104773SPascal Brand static const struct prop_set propset_current_client[] = { 136b0104773SPascal Brand {"gpd.client.identity", propget_gpd_client_identity}, 137b0104773SPascal Brand }; 138b0104773SPascal Brand 139b0104773SPascal Brand static const size_t propset_current_client_len = 140b0104773SPascal Brand sizeof(propset_current_client) / sizeof(propset_current_client[0]); 141b0104773SPascal Brand 142b0104773SPascal Brand static const struct prop_set propset_implementation[] = { 143b0104773SPascal Brand {"gpd.tee.apiversion", propget_gpd_tee_api_version}, 144b0104773SPascal Brand {"gpd.tee.description", propget_gpd_tee_description}, 145b0104773SPascal Brand {"gpd.tee.deviceID", propget_gpd_tee_device_id}, 146b0104773SPascal Brand {"gpd.tee.systemTime.protectionLevel", 147b0104773SPascal Brand propget_gpd_tee_sys_time_protection_level}, 148b0104773SPascal Brand {"gpd.tee.TAPersistentTime.protectionLevel", 149b0104773SPascal Brand propget_gpd_tee_ta_time_protection_level}, 150b0104773SPascal Brand {"gpd.tee.arith.maxBigIntSize", propget_gpd_tee_arith_max_big_int_size}, 151b0104773SPascal Brand }; 152b0104773SPascal Brand 153b0104773SPascal Brand static const size_t propset_implementation_len = 154b0104773SPascal Brand sizeof(propset_implementation) / sizeof(propset_implementation[0]); 155b0104773SPascal Brand 156b0104773SPascal Brand static TEE_Result propset_get(TEE_PropSetHandle h, const struct prop_set **ps, 157b0104773SPascal Brand size_t *ps_len, 158b0104773SPascal Brand const struct user_ta_property **eps, 159b0104773SPascal Brand size_t *eps_len) 160b0104773SPascal Brand { 161b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA) { 162b0104773SPascal Brand *ps = propset_current_ta; 163b0104773SPascal Brand *ps_len = propset_current_ta_len; 164b0104773SPascal Brand *eps = ta_props; 165b0104773SPascal Brand *eps_len = ta_num_props; 166b0104773SPascal Brand } else if (h == TEE_PROPSET_CURRENT_CLIENT) { 167b0104773SPascal Brand *ps = propset_current_client; 168b0104773SPascal Brand *ps_len = propset_current_client_len; 169b0104773SPascal Brand *eps = NULL; 170b0104773SPascal Brand *eps_len = 0; 171b0104773SPascal Brand } else if (h == TEE_PROPSET_TEE_IMPLEMENTATION) { 172b0104773SPascal Brand *ps = propset_implementation; 173b0104773SPascal Brand *ps_len = propset_implementation_len; 174b0104773SPascal Brand *eps = NULL; 175b0104773SPascal Brand *eps_len = 0; 176b0104773SPascal Brand } else { 177b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 178b0104773SPascal Brand } 179b0104773SPascal Brand 180b0104773SPascal Brand return TEE_SUCCESS; 181b0104773SPascal Brand } 182b0104773SPascal Brand 183b0104773SPascal Brand static TEE_Result propget_get_ext_prop(const struct user_ta_property *ep, 184b0104773SPascal Brand struct prop_value *pv) 185b0104773SPascal Brand { 186b0104773SPascal Brand size_t l; 187b0104773SPascal Brand 188b0104773SPascal Brand pv->type = ep->type; 189b0104773SPascal Brand switch (ep->type) { 190b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 191b0104773SPascal Brand l = sizeof(bool); 192b0104773SPascal Brand break; 193b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 194b0104773SPascal Brand l = sizeof(uint32_t); 195b0104773SPascal Brand break; 196b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 197b0104773SPascal Brand l = sizeof(TEE_UUID); 198b0104773SPascal Brand break; 199b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 200b0104773SPascal Brand l = sizeof(TEE_Identity); 201b0104773SPascal Brand break; 202b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 203b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 204b0104773SPascal Brand /* Handle too large strings by truncating them */ 205b0104773SPascal Brand strlcpy(pv->u.str_val, ep->value, sizeof(pv->u.str_val)); 206b0104773SPascal Brand return TEE_SUCCESS; 207b0104773SPascal Brand default: 208b0104773SPascal Brand return TEE_ERROR_GENERIC; 209b0104773SPascal Brand } 210b0104773SPascal Brand memcpy(&pv->u, ep->value, l); 211b0104773SPascal Brand return TEE_SUCCESS; 212b0104773SPascal Brand } 213b0104773SPascal Brand 214b0104773SPascal Brand static TEE_Result propget_get_property(TEE_PropSetHandle h, char *name, 215b0104773SPascal Brand struct prop_value *pv) 216b0104773SPascal Brand { 217b0104773SPascal Brand TEE_Result res; 218b0104773SPascal Brand const struct prop_set *ps; 219b0104773SPascal Brand size_t ps_len; 220b0104773SPascal Brand const struct user_ta_property *eps; 221b0104773SPascal Brand size_t eps_len; 222b0104773SPascal Brand 223b0104773SPascal Brand if (h == TEE_PROPSET_CURRENT_TA || h == TEE_PROPSET_CURRENT_CLIENT || 224b0104773SPascal Brand h == TEE_PROPSET_TEE_IMPLEMENTATION) { 225b0104773SPascal Brand size_t n; 226b0104773SPascal Brand 227b0104773SPascal Brand res = propset_get(h, &ps, &ps_len, &eps, &eps_len); 228b0104773SPascal Brand if (res != TEE_SUCCESS) 229b0104773SPascal Brand return res; 230b0104773SPascal Brand 231b0104773SPascal Brand for (n = 0; n < ps_len; n++) { 232b0104773SPascal Brand if (strcmp(name, ps[n].str) == 0) 233b0104773SPascal Brand return ps[n].get(pv); 234b0104773SPascal Brand } 235b0104773SPascal Brand for (n = 0; n < eps_len; n++) { 236b0104773SPascal Brand if (strcmp(name, eps[n].name) == 0) 237b0104773SPascal Brand return propget_get_ext_prop(eps + n, pv); 238b0104773SPascal Brand } 239b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 240b0104773SPascal Brand } else { 241b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)h; 242b0104773SPascal Brand uint32_t idx = pe->idx; 243b0104773SPascal Brand 244b0104773SPascal Brand if (idx == PROP_ENUMERATOR_NOT_STARTED) 245b0104773SPascal Brand return TEE_ERROR_ITEM_NOT_FOUND; 246b0104773SPascal Brand 247b0104773SPascal Brand res = propset_get(pe->prop_set, &ps, &ps_len, &eps, &eps_len); 248b0104773SPascal Brand if (res != TEE_SUCCESS) 249b0104773SPascal Brand return res; 250b0104773SPascal Brand 251b0104773SPascal Brand if (idx < ps_len) 252b0104773SPascal Brand return ps[idx].get(pv); 253b0104773SPascal Brand 254b0104773SPascal Brand idx -= ps_len; 255b0104773SPascal Brand if (idx < eps_len) 256b0104773SPascal Brand return propget_get_ext_prop(eps + idx, pv); 257b0104773SPascal Brand 258b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 259b0104773SPascal Brand } 260b0104773SPascal Brand } 261b0104773SPascal Brand 262b0104773SPascal Brand TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator, 263b0104773SPascal Brand char *name, char *valueBuffer, 26479a3c601SCedric Chaumont uint32_t *valueBufferLen) 265b0104773SPascal Brand { 266b0104773SPascal Brand TEE_Result res; 267b0104773SPascal Brand struct prop_value pv; 268b0104773SPascal Brand size_t l; 269b0104773SPascal Brand size_t bufferlen; 270b0104773SPascal Brand 271*ba675d69SCedric Chaumont if (valueBuffer == NULL || valueBufferLen == NULL) { 272*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 273*ba675d69SCedric Chaumont goto err; 274*ba675d69SCedric Chaumont } 275b0104773SPascal Brand 276b0104773SPascal Brand bufferlen = *valueBufferLen; 277b0104773SPascal Brand 278b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 279b0104773SPascal Brand if (res != TEE_SUCCESS) 280*ba675d69SCedric Chaumont goto err; 281b0104773SPascal Brand 282b0104773SPascal Brand switch (pv.type) { 283b0104773SPascal Brand case USER_TA_PROP_TYPE_BOOL: 284b0104773SPascal Brand l = strlcpy(valueBuffer, pv.u.bool_val ? "true" : "false", 285b0104773SPascal Brand bufferlen); 286b0104773SPascal Brand break; 287b0104773SPascal Brand 288b0104773SPascal Brand case USER_TA_PROP_TYPE_U32: 289b0104773SPascal Brand l = snprintf(valueBuffer, bufferlen, "%u", 290b0104773SPascal Brand (unsigned int)pv.u.int_val); 291b0104773SPascal Brand break; 292b0104773SPascal Brand 293b0104773SPascal Brand case USER_TA_PROP_TYPE_UUID: 294b0104773SPascal Brand l = snprintf(valueBuffer, bufferlen, 295b0104773SPascal Brand "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", 296b0104773SPascal Brand (unsigned int)pv.u.uuid_val.timeLow, 297b0104773SPascal Brand pv.u.uuid_val.timeMid, 298b0104773SPascal Brand pv.u.uuid_val.timeHiAndVersion, 299b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[0], 300b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[1], 301b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[2], 302b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[3], 303b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[4], 304b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[5], 305b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[6], 306b0104773SPascal Brand pv.u.uuid_val.clockSeqAndNode[7]); 307b0104773SPascal Brand break; 308b0104773SPascal Brand 309b0104773SPascal Brand case USER_TA_PROP_TYPE_IDENTITY: 310b0104773SPascal Brand l = snprintf(valueBuffer, bufferlen, 311b0104773SPascal Brand "%u:%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", 312b0104773SPascal Brand (unsigned int)pv.u.identity_val.login, 313b0104773SPascal Brand (unsigned int)pv.u.identity_val.uuid.timeLow, 314b0104773SPascal Brand pv.u.identity_val.uuid.timeMid, 315b0104773SPascal Brand pv.u.identity_val.uuid.timeHiAndVersion, 316b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[0], 317b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[1], 318b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[2], 319b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[3], 320b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[4], 321b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[5], 322b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[6], 323b0104773SPascal Brand pv.u.identity_val.uuid.clockSeqAndNode[7]); 324b0104773SPascal Brand break; 325b0104773SPascal Brand 326b0104773SPascal Brand case USER_TA_PROP_TYPE_STRING: 327b0104773SPascal Brand case USER_TA_PROP_TYPE_BINARY_BLOCK: 328b0104773SPascal Brand l = strlcpy(valueBuffer, pv.u.str_val, bufferlen); 329b0104773SPascal Brand break; 330b0104773SPascal Brand 331b0104773SPascal Brand default: 332*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 333*ba675d69SCedric Chaumont goto err; 334b0104773SPascal Brand } 335b0104773SPascal Brand 336b0104773SPascal Brand /* The size "must account for the zero terminator" */ 337b0104773SPascal Brand *valueBufferLen = l + 1; 338b0104773SPascal Brand 339*ba675d69SCedric Chaumont if (l >= bufferlen) { 340*ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 341*ba675d69SCedric Chaumont goto err; 342*ba675d69SCedric Chaumont } 343b0104773SPascal Brand 344*ba675d69SCedric Chaumont goto out; 345*ba675d69SCedric Chaumont 346*ba675d69SCedric Chaumont err: 347*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 348*ba675d69SCedric Chaumont res == TEE_ERROR_SHORT_BUFFER) 349*ba675d69SCedric Chaumont return res; 350*ba675d69SCedric Chaumont TEE_Panic(0); 351*ba675d69SCedric Chaumont out: 352b0104773SPascal Brand return TEE_SUCCESS; 353b0104773SPascal Brand } 354b0104773SPascal Brand 355b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator, 356b0104773SPascal Brand char *name, bool *value) 357b0104773SPascal Brand { 358b0104773SPascal Brand TEE_Result res; 359b0104773SPascal Brand struct prop_value pv; 360b0104773SPascal Brand 361*ba675d69SCedric Chaumont if (value == NULL) { 362*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 363*ba675d69SCedric Chaumont goto err; 364*ba675d69SCedric Chaumont } 365b0104773SPascal Brand 366b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 367b0104773SPascal Brand if (res != TEE_SUCCESS) 368*ba675d69SCedric Chaumont goto err; 369b0104773SPascal Brand 370*ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_BOOL) { 371*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 372*ba675d69SCedric Chaumont goto err; 373*ba675d69SCedric Chaumont } 374b0104773SPascal Brand 375b0104773SPascal Brand *value = pv.u.bool_val; 376*ba675d69SCedric Chaumont 377*ba675d69SCedric Chaumont goto out; 378*ba675d69SCedric Chaumont 379*ba675d69SCedric Chaumont err: 380*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 381*ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 382*ba675d69SCedric Chaumont return res; 383*ba675d69SCedric Chaumont TEE_Panic(0); 384*ba675d69SCedric Chaumont out: 385b0104773SPascal Brand return TEE_SUCCESS; 386b0104773SPascal Brand } 387b0104773SPascal Brand 388b0104773SPascal Brand TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator, 389b0104773SPascal Brand char *name, uint32_t *value) 390b0104773SPascal Brand { 391b0104773SPascal Brand TEE_Result res; 392b0104773SPascal Brand struct prop_value pv; 393b0104773SPascal Brand 394*ba675d69SCedric Chaumont if (value == NULL) { 395*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 396*ba675d69SCedric Chaumont goto err; 397*ba675d69SCedric Chaumont } 398b0104773SPascal Brand 399b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 400b0104773SPascal Brand if (res != TEE_SUCCESS) 401*ba675d69SCedric Chaumont goto err; 402b0104773SPascal Brand 403*ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_U32) { 404*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 405*ba675d69SCedric Chaumont goto err; 406*ba675d69SCedric Chaumont } 407b0104773SPascal Brand 408b0104773SPascal Brand *value = pv.u.int_val; 409*ba675d69SCedric Chaumont 410*ba675d69SCedric Chaumont goto out; 411*ba675d69SCedric Chaumont 412*ba675d69SCedric Chaumont err: 413*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 414*ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 415*ba675d69SCedric Chaumont return res; 416*ba675d69SCedric Chaumont TEE_Panic(0); 417*ba675d69SCedric Chaumont out: 418b0104773SPascal Brand return TEE_SUCCESS; 419b0104773SPascal Brand } 420b0104773SPascal Brand 421b0104773SPascal Brand TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator, 422b0104773SPascal Brand char *name, void *valueBuffer, 42379a3c601SCedric Chaumont uint32_t *valueBufferLen) 424b0104773SPascal Brand { 425b0104773SPascal Brand TEE_Result res; 426b0104773SPascal Brand struct prop_value pv; 427b0104773SPascal Brand void *val; 428b0104773SPascal Brand int val_len; 4297f74c64aSPascal Brand size_t size; 430b0104773SPascal Brand 431*ba675d69SCedric Chaumont if (valueBuffer == NULL || valueBufferLen == NULL) { 432*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 433*ba675d69SCedric Chaumont goto err; 434*ba675d69SCedric Chaumont } 435b0104773SPascal Brand 436b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 437b0104773SPascal Brand if (res != TEE_SUCCESS) 438*ba675d69SCedric Chaumont goto err; 439b0104773SPascal Brand 440*ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_BINARY_BLOCK) { 441*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 442*ba675d69SCedric Chaumont goto err; 443*ba675d69SCedric Chaumont } 444b0104773SPascal Brand 445b0104773SPascal Brand val = pv.u.str_val; 446b0104773SPascal Brand val_len = strlen(val); 4477f74c64aSPascal Brand size = *valueBufferLen; 448*ba675d69SCedric Chaumont if (!base64_dec(val, val_len, valueBuffer, &size)) { 4497f74c64aSPascal Brand res = TEE_ERROR_SHORT_BUFFER; 450*ba675d69SCedric Chaumont goto err; 451*ba675d69SCedric Chaumont } 452*ba675d69SCedric Chaumont 4537f74c64aSPascal Brand *valueBufferLen = size; 454*ba675d69SCedric Chaumont 455*ba675d69SCedric Chaumont goto out; 456*ba675d69SCedric Chaumont 457*ba675d69SCedric Chaumont err: 458*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 459*ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT || 460*ba675d69SCedric Chaumont res == TEE_ERROR_SHORT_BUFFER) 4617f74c64aSPascal Brand return res; 462*ba675d69SCedric Chaumont TEE_Panic(0); 463*ba675d69SCedric Chaumont out: 464*ba675d69SCedric Chaumont return TEE_SUCCESS; 465b0104773SPascal Brand } 466b0104773SPascal Brand 467b0104773SPascal Brand TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator, 468b0104773SPascal Brand char *name, TEE_UUID *value) 469b0104773SPascal Brand { 470b0104773SPascal Brand TEE_Result res; 471b0104773SPascal Brand struct prop_value pv; 472b0104773SPascal Brand 473*ba675d69SCedric Chaumont if (value == NULL) { 474*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 475*ba675d69SCedric Chaumont goto err; 476*ba675d69SCedric Chaumont } 477b0104773SPascal Brand 478b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 479b0104773SPascal Brand if (res != TEE_SUCCESS) 480*ba675d69SCedric Chaumont goto err; 481b0104773SPascal Brand 482*ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_UUID) { 483*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 484*ba675d69SCedric Chaumont goto err; 485*ba675d69SCedric Chaumont } 486b0104773SPascal Brand 487b0104773SPascal Brand *value = pv.u.uuid_val; /* struct copy */ 488*ba675d69SCedric Chaumont 489*ba675d69SCedric Chaumont goto out; 490*ba675d69SCedric Chaumont 491*ba675d69SCedric Chaumont err: 492*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 493*ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 494*ba675d69SCedric Chaumont return res; 495*ba675d69SCedric Chaumont TEE_Panic(0); 496*ba675d69SCedric Chaumont out: 497b0104773SPascal Brand return TEE_SUCCESS; 498b0104773SPascal Brand } 499b0104773SPascal Brand 500b0104773SPascal Brand TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator, 501b0104773SPascal Brand char *name, TEE_Identity *value) 502b0104773SPascal Brand { 503b0104773SPascal Brand TEE_Result res; 504b0104773SPascal Brand struct prop_value pv; 505b0104773SPascal Brand 506*ba675d69SCedric Chaumont if (value == NULL) { 507*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 508*ba675d69SCedric Chaumont goto err; 509*ba675d69SCedric Chaumont } 510b0104773SPascal Brand 511b0104773SPascal Brand res = propget_get_property(propsetOrEnumerator, name, &pv); 512b0104773SPascal Brand if (res != TEE_SUCCESS) 513*ba675d69SCedric Chaumont goto err; 514b0104773SPascal Brand 515*ba675d69SCedric Chaumont if (pv.type != USER_TA_PROP_TYPE_IDENTITY) { 516*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_FORMAT; 517*ba675d69SCedric Chaumont goto err; 518*ba675d69SCedric Chaumont } 519b0104773SPascal Brand 520b0104773SPascal Brand *value = pv.u.identity_val; /* struct copy */ 521*ba675d69SCedric Chaumont 522*ba675d69SCedric Chaumont goto out; 523*ba675d69SCedric Chaumont 524*ba675d69SCedric Chaumont err: 525*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 526*ba675d69SCedric Chaumont res == TEE_ERROR_BAD_FORMAT) 527*ba675d69SCedric Chaumont return res; 528*ba675d69SCedric Chaumont TEE_Panic(0); 529*ba675d69SCedric Chaumont out: 530b0104773SPascal Brand return TEE_SUCCESS; 531b0104773SPascal Brand } 532b0104773SPascal Brand 533b0104773SPascal Brand TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) 534b0104773SPascal Brand { 535*ba675d69SCedric Chaumont TEE_Result res; 536b0104773SPascal Brand struct prop_enumerator *pe; 537b0104773SPascal Brand 538*ba675d69SCedric Chaumont if (enumerator == NULL) { 539*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 540*ba675d69SCedric Chaumont goto err; 541*ba675d69SCedric Chaumont } 542b0104773SPascal Brand 543b0104773SPascal Brand pe = TEE_Malloc(sizeof(struct prop_enumerator), 544b0104773SPascal Brand TEE_USER_MEM_HINT_NO_FILL_ZERO); 545*ba675d69SCedric Chaumont if (pe == NULL) { 546*ba675d69SCedric Chaumont res = TEE_ERROR_OUT_OF_MEMORY; 547*ba675d69SCedric Chaumont goto err; 548*ba675d69SCedric Chaumont } 549b0104773SPascal Brand 550b0104773SPascal Brand *enumerator = (TEE_PropSetHandle) pe; 551b0104773SPascal Brand TEE_ResetPropertyEnumerator(*enumerator); 552*ba675d69SCedric Chaumont 553*ba675d69SCedric Chaumont goto out; 554*ba675d69SCedric Chaumont 555*ba675d69SCedric Chaumont err: 556*ba675d69SCedric Chaumont if (res == TEE_ERROR_OUT_OF_MEMORY) 557*ba675d69SCedric Chaumont return res; 558*ba675d69SCedric Chaumont TEE_Panic(0); 559*ba675d69SCedric Chaumont out: 560b0104773SPascal Brand return TEE_SUCCESS; 561b0104773SPascal Brand } 562b0104773SPascal Brand 563b0104773SPascal Brand void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) 564b0104773SPascal Brand { 565b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 566b0104773SPascal Brand 567b0104773SPascal Brand pe->idx = PROP_ENUMERATOR_NOT_STARTED; 568b0104773SPascal Brand } 569b0104773SPascal Brand 570b0104773SPascal Brand void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) 571b0104773SPascal Brand { 572b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 573b0104773SPascal Brand 574b0104773SPascal Brand TEE_Free(pe); 575b0104773SPascal Brand } 576b0104773SPascal Brand 577b0104773SPascal Brand void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator, 578b0104773SPascal Brand TEE_PropSetHandle propSet) 579b0104773SPascal Brand { 580b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 581b0104773SPascal Brand 582b0104773SPascal Brand if (pe == NULL) 583b0104773SPascal Brand return; 584b0104773SPascal Brand 585b0104773SPascal Brand pe->idx = 0; 586b0104773SPascal Brand pe->prop_set = propSet; 587b0104773SPascal Brand } 588b0104773SPascal Brand 589b0104773SPascal Brand TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, 59079a3c601SCedric Chaumont void *nameBuffer, uint32_t *nameBufferLen) 591b0104773SPascal Brand { 592b0104773SPascal Brand TEE_Result res; 593b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 594b0104773SPascal Brand const struct prop_set *ps; 595b0104773SPascal Brand size_t ps_len; 596b0104773SPascal Brand const struct user_ta_property *eps; 597b0104773SPascal Brand size_t eps_len; 598b0104773SPascal Brand size_t l; 599b0104773SPascal Brand const char *str; 600b0104773SPascal Brand size_t bufferlen; 601b0104773SPascal Brand 602*ba675d69SCedric Chaumont if (pe == NULL || nameBuffer == NULL || nameBufferLen == NULL) { 603*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 604*ba675d69SCedric Chaumont goto err; 605*ba675d69SCedric Chaumont } 606b0104773SPascal Brand 607b0104773SPascal Brand bufferlen = *nameBufferLen; 608b0104773SPascal Brand res = propset_get(pe->prop_set, &ps, &ps_len, &eps, &eps_len); 609b0104773SPascal Brand if (res != TEE_SUCCESS) 610*ba675d69SCedric Chaumont goto err; 611b0104773SPascal Brand 612b0104773SPascal Brand if (pe->idx < ps_len) 613b0104773SPascal Brand str = ps[pe->idx].str; 614b0104773SPascal Brand else if ((pe->idx - ps_len) < eps_len) 615b0104773SPascal Brand str = ta_props[pe->idx - ps_len].name; 616*ba675d69SCedric Chaumont else { 617*ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 618*ba675d69SCedric Chaumont goto err; 619*ba675d69SCedric Chaumont } 620b0104773SPascal Brand 621b0104773SPascal Brand l = strlcpy(nameBuffer, str, bufferlen); 622b0104773SPascal Brand 623b0104773SPascal Brand /* The size "must account for the zero terminator" */ 624b0104773SPascal Brand *nameBufferLen = l + 1; 625b0104773SPascal Brand 626*ba675d69SCedric Chaumont if (l >= bufferlen) { 627*ba675d69SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 628*ba675d69SCedric Chaumont goto err; 629*ba675d69SCedric Chaumont } 630b0104773SPascal Brand 631*ba675d69SCedric Chaumont goto out; 632*ba675d69SCedric Chaumont 633*ba675d69SCedric Chaumont err: 634*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 635*ba675d69SCedric Chaumont res == TEE_ERROR_SHORT_BUFFER) 636*ba675d69SCedric Chaumont return res; 637*ba675d69SCedric Chaumont TEE_Panic(0); 638*ba675d69SCedric Chaumont out: 639b0104773SPascal Brand return TEE_SUCCESS; 640b0104773SPascal Brand } 641b0104773SPascal Brand 642b0104773SPascal Brand TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) 643b0104773SPascal Brand { 644b0104773SPascal Brand TEE_Result res; 645b0104773SPascal Brand struct prop_enumerator *pe = (struct prop_enumerator *)enumerator; 646b0104773SPascal Brand uint32_t next_idx; 647b0104773SPascal Brand const struct prop_set *ps; 648b0104773SPascal Brand size_t ps_len; 649b0104773SPascal Brand const struct user_ta_property *eps; 650b0104773SPascal Brand size_t eps_len; 651b0104773SPascal Brand 652*ba675d69SCedric Chaumont if (pe == NULL) { 653*ba675d69SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 654*ba675d69SCedric Chaumont goto err; 655*ba675d69SCedric Chaumont } 656b0104773SPascal Brand 657*ba675d69SCedric Chaumont if (pe->idx == PROP_ENUMERATOR_NOT_STARTED) { 658*ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 659*ba675d69SCedric Chaumont goto err; 660*ba675d69SCedric Chaumont } 661b0104773SPascal Brand 662b0104773SPascal Brand res = propset_get(pe->prop_set, &ps, &ps_len, &eps, &eps_len); 663b0104773SPascal Brand if (res != TEE_SUCCESS) 664*ba675d69SCedric Chaumont goto err; 665b0104773SPascal Brand 666b0104773SPascal Brand next_idx = pe->idx + 1; 667b0104773SPascal Brand pe->idx = next_idx; 668*ba675d69SCedric Chaumont if (next_idx >= (ps_len + eps_len)) { 669*ba675d69SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 670*ba675d69SCedric Chaumont goto err; 671*ba675d69SCedric Chaumont } 672b0104773SPascal Brand 673*ba675d69SCedric Chaumont goto out; 674*ba675d69SCedric Chaumont 675*ba675d69SCedric Chaumont err: 676*ba675d69SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND) 677*ba675d69SCedric Chaumont return res; 678*ba675d69SCedric Chaumont TEE_Panic(0); 679*ba675d69SCedric Chaumont out: 680b0104773SPascal Brand return TEE_SUCCESS; 681b0104773SPascal Brand } 682