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