11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 4b0104773SPascal Brand */ 5b0104773SPascal Brand #include <stdlib.h> 6b0104773SPascal Brand #include <string.h> 7b0104773SPascal Brand 8b0104773SPascal Brand #include <tee_api.h> 9b0104773SPascal Brand #include <utee_syscalls.h> 10e86f1266SJens Wiklander #include "tee_api_private.h" 11b0104773SPascal Brand 12b0104773SPascal Brand #define TEE_USAGE_DEFAULT 0xffffffff 13b0104773SPascal Brand 14b0104773SPascal Brand #define TEE_ATTR_BIT_VALUE (1 << 29) 15b0104773SPascal Brand #define TEE_ATTR_BIT_PROTECTED (1 << 28) 16b0104773SPascal Brand 17e86f1266SJens Wiklander void __utee_from_attr(struct utee_attribute *ua, const TEE_Attribute *attrs, 18e86f1266SJens Wiklander uint32_t attr_count) 19e86f1266SJens Wiklander { 20e86f1266SJens Wiklander size_t n; 21e86f1266SJens Wiklander 22e86f1266SJens Wiklander for (n = 0; n < attr_count; n++) { 23e86f1266SJens Wiklander ua[n].attribute_id = attrs[n].attributeID; 24e86f1266SJens Wiklander if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) { 25e86f1266SJens Wiklander ua[n].a = attrs[n].content.value.a; 26e86f1266SJens Wiklander ua[n].b = attrs[n].content.value.b; 27e86f1266SJens Wiklander } else { 28e86f1266SJens Wiklander ua[n].a = (uintptr_t)attrs[n].content.ref.buffer; 29e86f1266SJens Wiklander ua[n].b = attrs[n].content.ref.length; 30e86f1266SJens Wiklander } 31e86f1266SJens Wiklander } 32e86f1266SJens Wiklander } 33e86f1266SJens Wiklander 34b0104773SPascal Brand /* Data and Key Storage API - Generic Object Functions */ 357583c59eSCedric Chaumont /* 367583c59eSCedric Chaumont * Use of this function is deprecated 377583c59eSCedric Chaumont * new code SHOULD use the TEE_GetObjectInfo1 function instead 387583c59eSCedric Chaumont * These functions will be removed at some future major revision of 397583c59eSCedric Chaumont * this specification 407583c59eSCedric Chaumont */ 41b0104773SPascal Brand void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 42b0104773SPascal Brand { 43b0104773SPascal Brand TEE_Result res; 44b0104773SPascal Brand 45e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, objectInfo); 467583c59eSCedric Chaumont 47b0104773SPascal Brand if (res != TEE_SUCCESS) 48b0104773SPascal Brand TEE_Panic(res); 497583c59eSCedric Chaumont 507583c59eSCedric Chaumont if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) { 517583c59eSCedric Chaumont objectInfo->keySize = 0; 527583c59eSCedric Chaumont objectInfo->maxKeySize = 0; 537583c59eSCedric Chaumont objectInfo->objectUsage = 0; 547583c59eSCedric Chaumont objectInfo->dataSize = 0; 557583c59eSCedric Chaumont objectInfo->dataPosition = 0; 567583c59eSCedric Chaumont objectInfo->handleFlags = 0; 577583c59eSCedric Chaumont } 58b0104773SPascal Brand } 59b0104773SPascal Brand 607583c59eSCedric Chaumont TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 617583c59eSCedric Chaumont { 627583c59eSCedric Chaumont TEE_Result res; 637583c59eSCedric Chaumont 64e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, objectInfo); 657583c59eSCedric Chaumont 66a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 67a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 68a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 697583c59eSCedric Chaumont TEE_Panic(res); 707583c59eSCedric Chaumont 717583c59eSCedric Chaumont return res; 727583c59eSCedric Chaumont } 737583c59eSCedric Chaumont 747583c59eSCedric Chaumont /* 757583c59eSCedric Chaumont * Use of this function is deprecated 767583c59eSCedric Chaumont * new code SHOULD use the TEE_RestrictObjectUsage1 function instead 777583c59eSCedric Chaumont * These functions will be removed at some future major revision of 787583c59eSCedric Chaumont * this specification 797583c59eSCedric Chaumont */ 80b0104773SPascal Brand void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) 81b0104773SPascal Brand { 82b0104773SPascal Brand TEE_Result res; 837583c59eSCedric Chaumont TEE_ObjectInfo objectInfo; 847583c59eSCedric Chaumont 85e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, &objectInfo); 867583c59eSCedric Chaumont if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT) 877583c59eSCedric Chaumont return; 887583c59eSCedric Chaumont 897583c59eSCedric Chaumont res = TEE_RestrictObjectUsage1(object, objectUsage); 90b0104773SPascal Brand 91b0104773SPascal Brand if (res != TEE_SUCCESS) 92b36311adSJerome Forissier TEE_Panic(res); 93b0104773SPascal Brand } 94b0104773SPascal Brand 957583c59eSCedric Chaumont TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage) 967583c59eSCedric Chaumont { 977583c59eSCedric Chaumont TEE_Result res; 987583c59eSCedric Chaumont 99e86f1266SJens Wiklander res = utee_cryp_obj_restrict_usage((unsigned long)object, objectUsage); 1007583c59eSCedric Chaumont 101a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 102a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 103a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 104a2e9a830SCedric Chaumont TEE_Panic(res); 1057583c59eSCedric Chaumont 1067583c59eSCedric Chaumont return res; 1077583c59eSCedric Chaumont } 1087583c59eSCedric Chaumont 109b0104773SPascal Brand TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 110b0104773SPascal Brand uint32_t attributeID, void *buffer, 11179a3c601SCedric Chaumont uint32_t *size) 112b0104773SPascal Brand { 113b0104773SPascal Brand TEE_Result res; 114b0104773SPascal Brand TEE_ObjectInfo info; 115e86f1266SJens Wiklander uint64_t sz; 116b0104773SPascal Brand 117e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, &info); 118b0104773SPascal Brand if (res != TEE_SUCCESS) 119a2e9a830SCedric Chaumont goto exit; 120b0104773SPascal Brand 121b0104773SPascal Brand /* This function only supports reference attributes */ 122a2e9a830SCedric Chaumont if ((attributeID & TEE_ATTR_BIT_VALUE)) { 123a2e9a830SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 124a2e9a830SCedric Chaumont goto exit; 125a2e9a830SCedric Chaumont } 126b0104773SPascal Brand 127e86f1266SJens Wiklander sz = *size; 128e86f1266SJens Wiklander res = utee_cryp_obj_get_attr((unsigned long)object, attributeID, 129e86f1266SJens Wiklander buffer, &sz); 130e86f1266SJens Wiklander *size = sz; 131b0104773SPascal Brand 132a2e9a830SCedric Chaumont exit: 1330ed6a6caSCedric Chaumont if (res != TEE_SUCCESS && 1340ed6a6caSCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 1350ed6a6caSCedric Chaumont res != TEE_ERROR_SHORT_BUFFER && 1360ed6a6caSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 1370ed6a6caSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 138b36311adSJerome Forissier TEE_Panic(res); 139b0104773SPascal Brand 140b0104773SPascal Brand return res; 141b0104773SPascal Brand } 142b0104773SPascal Brand 143b0104773SPascal Brand TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object, 144b0104773SPascal Brand uint32_t attributeID, uint32_t *a, 145b0104773SPascal Brand uint32_t *b) 146b0104773SPascal Brand { 147b0104773SPascal Brand TEE_Result res; 148b0104773SPascal Brand TEE_ObjectInfo info; 149b0104773SPascal Brand uint32_t buf[2]; 150e86f1266SJens Wiklander uint64_t size = sizeof(buf); 151b0104773SPascal Brand 152e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, &info); 153b0104773SPascal Brand if (res != TEE_SUCCESS) 154a2e9a830SCedric Chaumont goto exit; 155b0104773SPascal Brand 156b0104773SPascal Brand /* This function only supports value attributes */ 157a2e9a830SCedric Chaumont if (!(attributeID & TEE_ATTR_BIT_VALUE)) { 158a2e9a830SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 159a2e9a830SCedric Chaumont goto exit; 160a2e9a830SCedric Chaumont } 161b0104773SPascal Brand 162e86f1266SJens Wiklander res = utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf, 163e86f1266SJens Wiklander &size); 164b0104773SPascal Brand 165a2e9a830SCedric Chaumont exit: 1660ed6a6caSCedric Chaumont if (res != TEE_SUCCESS && 1670ed6a6caSCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 1680ed6a6caSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 1690ed6a6caSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 170b36311adSJerome Forissier TEE_Panic(res); 171b0104773SPascal Brand 172b0104773SPascal Brand if (size != sizeof(buf)) 173b0104773SPascal Brand TEE_Panic(0); 174b0104773SPascal Brand 175be96c837SJerome Forissier if (res == TEE_SUCCESS) { 176b9d8f134SJerome Forissier if (a) 177b0104773SPascal Brand *a = buf[0]; 178b9d8f134SJerome Forissier if (b) 179b0104773SPascal Brand *b = buf[1]; 180be96c837SJerome Forissier } 181b0104773SPascal Brand 182b0104773SPascal Brand return res; 183b0104773SPascal Brand } 184b0104773SPascal Brand 185b0104773SPascal Brand void TEE_CloseObject(TEE_ObjectHandle object) 186b0104773SPascal Brand { 187b0104773SPascal Brand TEE_Result res; 188b0104773SPascal Brand 189b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 190b0104773SPascal Brand return; 191b0104773SPascal Brand 192e86f1266SJens Wiklander res = utee_cryp_obj_close((unsigned long)object); 193b0104773SPascal Brand if (res != TEE_SUCCESS) 194b36311adSJerome Forissier TEE_Panic(res); 195b0104773SPascal Brand } 196b0104773SPascal Brand 197b0104773SPascal Brand /* Data and Key Storage API - Transient Object Functions */ 198b0104773SPascal Brand 199b0104773SPascal Brand TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 20079a3c601SCedric Chaumont uint32_t maxKeySize, 201b0104773SPascal Brand TEE_ObjectHandle *object) 202b0104773SPascal Brand { 203b0104773SPascal Brand TEE_Result res; 204b0104773SPascal Brand uint32_t obj; 205b0104773SPascal Brand 20679a3c601SCedric Chaumont res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 207aeb0d927SCedric Chaumont 208aeb0d927SCedric Chaumont if (res != TEE_SUCCESS && 209aeb0d927SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 210aeb0d927SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 211b36311adSJerome Forissier TEE_Panic(res); 212aeb0d927SCedric Chaumont 213b0104773SPascal Brand if (res == TEE_SUCCESS) 214e86f1266SJens Wiklander *object = (TEE_ObjectHandle)(uintptr_t)obj; 2150ed6a6caSCedric Chaumont 216b0104773SPascal Brand return res; 217b0104773SPascal Brand } 218b0104773SPascal Brand 219b0104773SPascal Brand void TEE_FreeTransientObject(TEE_ObjectHandle object) 220b0104773SPascal Brand { 221b0104773SPascal Brand TEE_Result res; 222b0104773SPascal Brand TEE_ObjectInfo info; 223b0104773SPascal Brand 224b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 225b0104773SPascal Brand return; 226b0104773SPascal Brand 227e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, &info); 228b0104773SPascal Brand if (res != TEE_SUCCESS) 229b36311adSJerome Forissier TEE_Panic(res); 230b0104773SPascal Brand 231b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 232b0104773SPascal Brand TEE_Panic(0); 233b0104773SPascal Brand 234e86f1266SJens Wiklander res = utee_cryp_obj_close((unsigned long)object); 235b0104773SPascal Brand if (res != TEE_SUCCESS) 236b36311adSJerome Forissier TEE_Panic(res); 237b0104773SPascal Brand } 238b0104773SPascal Brand 239b0104773SPascal Brand void TEE_ResetTransientObject(TEE_ObjectHandle object) 240b0104773SPascal Brand { 241b0104773SPascal Brand TEE_Result res; 242b0104773SPascal Brand TEE_ObjectInfo info; 243b0104773SPascal Brand 244b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 245b0104773SPascal Brand return; 246b0104773SPascal Brand 247e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, &info); 248b0104773SPascal Brand if (res != TEE_SUCCESS) 249b36311adSJerome Forissier TEE_Panic(res); 250b0104773SPascal Brand 251b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 252b0104773SPascal Brand TEE_Panic(0); 253b0104773SPascal Brand 254e86f1266SJens Wiklander res = utee_cryp_obj_reset((unsigned long)object); 255b0104773SPascal Brand if (res != TEE_SUCCESS) 256b36311adSJerome Forissier TEE_Panic(res); 257b0104773SPascal Brand } 258b0104773SPascal Brand 259b0104773SPascal Brand TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 2608f07fe6fSJerome Forissier const TEE_Attribute *attrs, 261b0104773SPascal Brand uint32_t attrCount) 262b0104773SPascal Brand { 263b0104773SPascal Brand TEE_Result res; 264b0104773SPascal Brand TEE_ObjectInfo info; 265e86f1266SJens Wiklander struct utee_attribute ua[attrCount]; 266b0104773SPascal Brand 267e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, &info); 268b0104773SPascal Brand if (res != TEE_SUCCESS) 269b36311adSJerome Forissier TEE_Panic(res); 270b0104773SPascal Brand 271b0104773SPascal Brand /* Must be a transient object */ 272b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 273b0104773SPascal Brand TEE_Panic(0); 274b0104773SPascal Brand 275b0104773SPascal Brand /* Must not be initialized already */ 276b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 277b0104773SPascal Brand TEE_Panic(0); 278b0104773SPascal Brand 279e86f1266SJens Wiklander __utee_from_attr(ua, attrs, attrCount); 280e86f1266SJens Wiklander res = utee_cryp_obj_populate((unsigned long)object, ua, attrCount); 281b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 282b0104773SPascal Brand TEE_Panic(res); 283b0104773SPascal Brand return res; 284b0104773SPascal Brand } 285b0104773SPascal Brand 286b0104773SPascal Brand void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID, 2878f07fe6fSJerome Forissier const void *buffer, uint32_t length) 288b0104773SPascal Brand { 289b0104773SPascal Brand if (attr == NULL) 290b0104773SPascal Brand TEE_Panic(0); 291b0104773SPascal Brand if ((attributeID & TEE_ATTR_BIT_VALUE) != 0) 292b0104773SPascal Brand TEE_Panic(0); 293b0104773SPascal Brand attr->attributeID = attributeID; 2948f07fe6fSJerome Forissier attr->content.ref.buffer = (void *)buffer; 295b0104773SPascal Brand attr->content.ref.length = length; 296b0104773SPascal Brand } 297b0104773SPascal Brand 298b0104773SPascal Brand void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, 299b0104773SPascal Brand uint32_t a, uint32_t b) 300b0104773SPascal Brand { 301b0104773SPascal Brand if (attr == NULL) 302b0104773SPascal Brand TEE_Panic(0); 303b0104773SPascal Brand if ((attributeID & TEE_ATTR_BIT_VALUE) == 0) 304b0104773SPascal Brand TEE_Panic(0); 305b0104773SPascal Brand attr->attributeID = attributeID; 306b0104773SPascal Brand attr->content.value.a = a; 307b0104773SPascal Brand attr->content.value.b = b; 308b0104773SPascal Brand } 309b0104773SPascal Brand 3107583c59eSCedric Chaumont /* 3117583c59eSCedric Chaumont * Use of this function is deprecated 3127583c59eSCedric Chaumont * new code SHOULD use the TEE_CopyObjectAttributes1 function instead 3137583c59eSCedric Chaumont * These functions will be removed at some future major revision of 3147583c59eSCedric Chaumont * this specification 3157583c59eSCedric Chaumont */ 316b0104773SPascal Brand void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, 317b0104773SPascal Brand TEE_ObjectHandle srcObject) 318b0104773SPascal Brand { 319b0104773SPascal Brand TEE_Result res; 3207583c59eSCedric Chaumont TEE_ObjectInfo src_info; 3217583c59eSCedric Chaumont 322e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 3237583c59eSCedric Chaumont if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT) 3247583c59eSCedric Chaumont return; 3257583c59eSCedric Chaumont 3267583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(destObject, srcObject); 3277583c59eSCedric Chaumont if (res != TEE_SUCCESS) 328b36311adSJerome Forissier TEE_Panic(res); 3297583c59eSCedric Chaumont } 3307583c59eSCedric Chaumont 3317583c59eSCedric Chaumont TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject, 3327583c59eSCedric Chaumont TEE_ObjectHandle srcObject) 3337583c59eSCedric Chaumont { 3347583c59eSCedric Chaumont TEE_Result res; 335b0104773SPascal Brand TEE_ObjectInfo dst_info; 336b0104773SPascal Brand TEE_ObjectInfo src_info; 337b0104773SPascal Brand 338e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)destObject, &dst_info); 339b0104773SPascal Brand if (res != TEE_SUCCESS) 340a2e9a830SCedric Chaumont goto exit; 341b0104773SPascal Brand 342e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 343b0104773SPascal Brand if (res != TEE_SUCCESS) 344a2e9a830SCedric Chaumont goto exit; 345b0104773SPascal Brand 346a2e9a830SCedric Chaumont if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 347b0104773SPascal Brand TEE_Panic(0); 348a2e9a830SCedric Chaumont 349a2e9a830SCedric Chaumont if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) 350b0104773SPascal Brand TEE_Panic(0); 351a2e9a830SCedric Chaumont 352a2e9a830SCedric Chaumont if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 353b0104773SPascal Brand TEE_Panic(0); 354b0104773SPascal Brand 355e86f1266SJens Wiklander res = utee_cryp_obj_copy((unsigned long)destObject, 356e86f1266SJens Wiklander (unsigned long)srcObject); 3577583c59eSCedric Chaumont 358a2e9a830SCedric Chaumont exit: 359a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 360a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 361a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 362a2e9a830SCedric Chaumont TEE_Panic(res); 3637583c59eSCedric Chaumont 3647583c59eSCedric Chaumont return res; 365b0104773SPascal Brand } 366b0104773SPascal Brand 367b0104773SPascal Brand TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 3688f07fe6fSJerome Forissier const TEE_Attribute *params, uint32_t paramCount) 369b0104773SPascal Brand { 370b0104773SPascal Brand TEE_Result res; 371e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 372b0104773SPascal Brand 373e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 374e86f1266SJens Wiklander res = utee_cryp_obj_generate_key((unsigned long)object, keySize, 375e86f1266SJens Wiklander ua, paramCount); 376b0104773SPascal Brand 377aeb0d927SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 378b36311adSJerome Forissier TEE_Panic(res); 379b0104773SPascal Brand 380b0104773SPascal Brand return res; 381b0104773SPascal Brand } 382b0104773SPascal Brand 383b0104773SPascal Brand /* Data and Key Storage API - Persistent Object Functions */ 384b0104773SPascal Brand 3858f07fe6fSJerome Forissier TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, 38679a3c601SCedric Chaumont uint32_t objectIDLen, uint32_t flags, 387b0104773SPascal Brand TEE_ObjectHandle *object) 388b0104773SPascal Brand { 3899b520646SCedric Chaumont TEE_Result res; 390e86f1266SJens Wiklander uint32_t obj; 391b0104773SPascal Brand 3929b520646SCedric Chaumont if (!objectID) { 3939b520646SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 3949b520646SCedric Chaumont goto out; 3959b520646SCedric Chaumont } 3969b520646SCedric Chaumont 3979b520646SCedric Chaumont if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) { 3989b520646SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 3999b520646SCedric Chaumont goto out; 4009b520646SCedric Chaumont } 4019b520646SCedric Chaumont 4029b520646SCedric Chaumont if (!object) { 4039b520646SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 4049b520646SCedric Chaumont goto out; 4059b520646SCedric Chaumont } 4069b520646SCedric Chaumont 4079b520646SCedric Chaumont res = utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 408e86f1266SJens Wiklander &obj); 409e86f1266SJens Wiklander if (res == TEE_SUCCESS) 410e86f1266SJens Wiklander *object = (TEE_ObjectHandle)(uintptr_t)obj; 4119b520646SCedric Chaumont 4129b520646SCedric Chaumont out: 4139b520646SCedric Chaumont if (res != TEE_SUCCESS && 4149b520646SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 4159b520646SCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT && 4169b520646SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 4179b520646SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 4189b520646SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 419b36311adSJerome Forissier TEE_Panic(res); 420b0104773SPascal Brand 421*69a3d6beSDaniel Glöckner if (res != TEE_SUCCESS && object) 422*69a3d6beSDaniel Glöckner *object = TEE_HANDLE_NULL; 423*69a3d6beSDaniel Glöckner 4249b520646SCedric Chaumont return res; 425b0104773SPascal Brand } 426b0104773SPascal Brand 4278f07fe6fSJerome Forissier TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, 42879a3c601SCedric Chaumont uint32_t objectIDLen, uint32_t flags, 429b0104773SPascal Brand TEE_ObjectHandle attributes, 430b0104773SPascal Brand const void *initialData, 43179a3c601SCedric Chaumont uint32_t initialDataLen, 432b0104773SPascal Brand TEE_ObjectHandle *object) 433b0104773SPascal Brand { 43484431ae3SCedric Chaumont TEE_Result res; 435e86f1266SJens Wiklander uint32_t obj; 436b0104773SPascal Brand 437aeb0d927SCedric Chaumont if (!objectID) { 43884431ae3SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 43984431ae3SCedric Chaumont goto err; 44084431ae3SCedric Chaumont } 441b0104773SPascal Brand 44284431ae3SCedric Chaumont if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) { 44384431ae3SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 44484431ae3SCedric Chaumont goto err; 44584431ae3SCedric Chaumont } 446b0104773SPascal Brand 44784431ae3SCedric Chaumont res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 448e86f1266SJens Wiklander (unsigned long)attributes, initialData, 449e86f1266SJens Wiklander initialDataLen, &obj); 450e86f1266SJens Wiklander if (res == TEE_SUCCESS) { 4511c96fa7fSPascal Brand if (object) 452e86f1266SJens Wiklander *object = (TEE_ObjectHandle)(uintptr_t)obj; 4531c96fa7fSPascal Brand else 4541c96fa7fSPascal Brand res = utee_cryp_obj_close(obj); 4551c96fa7fSPascal Brand if (res == TEE_SUCCESS) 45684431ae3SCedric Chaumont goto out; 457e86f1266SJens Wiklander } 45884431ae3SCedric Chaumont err: 4591c96fa7fSPascal Brand if (object) 4601c96fa7fSPascal Brand *object = TEE_HANDLE_NULL; 46184431ae3SCedric Chaumont if (res == TEE_ERROR_ITEM_NOT_FOUND || 46284431ae3SCedric Chaumont res == TEE_ERROR_ACCESS_CONFLICT || 46384431ae3SCedric Chaumont res == TEE_ERROR_OUT_OF_MEMORY || 46484431ae3SCedric Chaumont res == TEE_ERROR_STORAGE_NO_SPACE || 46584431ae3SCedric Chaumont res == TEE_ERROR_CORRUPT_OBJECT || 46684431ae3SCedric Chaumont res == TEE_ERROR_STORAGE_NOT_AVAILABLE) 46784431ae3SCedric Chaumont return res; 468b36311adSJerome Forissier TEE_Panic(res); 46984431ae3SCedric Chaumont out: 47084431ae3SCedric Chaumont return TEE_SUCCESS; 471b0104773SPascal Brand } 472b0104773SPascal Brand 4737583c59eSCedric Chaumont /* 4747583c59eSCedric Chaumont * Use of this function is deprecated 4757583c59eSCedric Chaumont * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead 4767583c59eSCedric Chaumont * These functions will be removed at some future major revision of 4777583c59eSCedric Chaumont * this specification 4787583c59eSCedric Chaumont */ 479b0104773SPascal Brand void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 480b0104773SPascal Brand { 481b0104773SPascal Brand TEE_Result res; 482b0104773SPascal Brand 483b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 484b0104773SPascal Brand return; 485b0104773SPascal Brand 4867583c59eSCedric Chaumont res = TEE_CloseAndDeletePersistentObject1(object); 487b0104773SPascal Brand 488b0104773SPascal Brand if (res != TEE_SUCCESS) 489b0104773SPascal Brand TEE_Panic(0); 490b0104773SPascal Brand } 491b0104773SPascal Brand 4927583c59eSCedric Chaumont TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object) 4937583c59eSCedric Chaumont { 4947583c59eSCedric Chaumont TEE_Result res; 4957583c59eSCedric Chaumont 4967583c59eSCedric Chaumont if (object == TEE_HANDLE_NULL) 4977583c59eSCedric Chaumont return TEE_ERROR_STORAGE_NOT_AVAILABLE; 4987583c59eSCedric Chaumont 499e86f1266SJens Wiklander res = utee_storage_obj_del((unsigned long)object); 5007583c59eSCedric Chaumont 5017583c59eSCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 502b36311adSJerome Forissier TEE_Panic(res); 5037583c59eSCedric Chaumont 5047583c59eSCedric Chaumont return res; 5057583c59eSCedric Chaumont } 5067583c59eSCedric Chaumont 5077583c59eSCedric Chaumont 508b0104773SPascal Brand TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 509b0104773SPascal Brand const void *newObjectID, 51079a3c601SCedric Chaumont uint32_t newObjectIDLen) 511b0104773SPascal Brand { 512b0104773SPascal Brand TEE_Result res; 513b0104773SPascal Brand 514a76bf53fSCedric Chaumont if (object == TEE_HANDLE_NULL) { 515a76bf53fSCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 516a76bf53fSCedric Chaumont goto out; 517a76bf53fSCedric Chaumont } 518b0104773SPascal Brand 519a76bf53fSCedric Chaumont if (!newObjectID) { 520a76bf53fSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 521a76bf53fSCedric Chaumont goto out; 522a76bf53fSCedric Chaumont } 523b0104773SPascal Brand 524a76bf53fSCedric Chaumont if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) { 525a76bf53fSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 526a76bf53fSCedric Chaumont goto out; 527a76bf53fSCedric Chaumont } 528b0104773SPascal Brand 529e86f1266SJens Wiklander res = utee_storage_obj_rename((unsigned long)object, newObjectID, 530e86f1266SJens Wiklander newObjectIDLen); 531b0104773SPascal Brand 532a76bf53fSCedric Chaumont out: 533a76bf53fSCedric Chaumont if (res != TEE_SUCCESS && 534a76bf53fSCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT && 535a76bf53fSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 536a76bf53fSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 537b36311adSJerome Forissier TEE_Panic(res); 538b0104773SPascal Brand 539b0104773SPascal Brand return res; 540b0104773SPascal Brand } 541b0104773SPascal Brand 542b0104773SPascal Brand TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 543b0104773SPascal Brand objectEnumerator) 544b0104773SPascal Brand { 545b0104773SPascal Brand TEE_Result res; 546e86f1266SJens Wiklander uint32_t oe; 547b0104773SPascal Brand 54815cd3c30SCedric Chaumont if (!objectEnumerator) 549b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 550b0104773SPascal Brand 551e86f1266SJens Wiklander res = utee_storage_alloc_enum(&oe); 552b0104773SPascal Brand 553b0104773SPascal Brand if (res != TEE_SUCCESS) 554e86f1266SJens Wiklander oe = TEE_HANDLE_NULL; 555e86f1266SJens Wiklander 556e86f1266SJens Wiklander *objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe; 557b0104773SPascal Brand 55815cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 55915cd3c30SCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT) 560b36311adSJerome Forissier TEE_Panic(res); 56115cd3c30SCedric Chaumont 562b0104773SPascal Brand return res; 563b0104773SPascal Brand } 564b0104773SPascal Brand 565b0104773SPascal Brand void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 566b0104773SPascal Brand { 567b0104773SPascal Brand TEE_Result res; 568b0104773SPascal Brand 569b0104773SPascal Brand if (objectEnumerator == TEE_HANDLE_NULL) 570b0104773SPascal Brand return; 571b0104773SPascal Brand 572e86f1266SJens Wiklander res = utee_storage_free_enum((unsigned long)objectEnumerator); 573b0104773SPascal Brand 574b0104773SPascal Brand if (res != TEE_SUCCESS) 575b36311adSJerome Forissier TEE_Panic(res); 576b0104773SPascal Brand } 577b0104773SPascal Brand 578b0104773SPascal Brand void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 579b0104773SPascal Brand { 580b0104773SPascal Brand TEE_Result res; 581b0104773SPascal Brand 582b0104773SPascal Brand if (objectEnumerator == TEE_HANDLE_NULL) 583b0104773SPascal Brand return; 584b0104773SPascal Brand 585e86f1266SJens Wiklander res = utee_storage_reset_enum((unsigned long)objectEnumerator); 586b0104773SPascal Brand 587b0104773SPascal Brand if (res != TEE_SUCCESS) 588b36311adSJerome Forissier TEE_Panic(res); 589b0104773SPascal Brand } 590b0104773SPascal Brand 591b0104773SPascal Brand TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 592b0104773SPascal Brand objectEnumerator, 593b0104773SPascal Brand uint32_t storageID) 594b0104773SPascal Brand { 595b0104773SPascal Brand TEE_Result res; 596b0104773SPascal Brand 597e86f1266SJens Wiklander res = utee_storage_start_enum((unsigned long)objectEnumerator, 598e86f1266SJens Wiklander storageID); 599b0104773SPascal Brand 60015cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 60115cd3c30SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 60215cd3c30SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 60315cd3c30SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 604b36311adSJerome Forissier TEE_Panic(res); 605b0104773SPascal Brand 606b0104773SPascal Brand return res; 607b0104773SPascal Brand } 608b0104773SPascal Brand 609b0104773SPascal Brand TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, 610b0104773SPascal Brand TEE_ObjectInfo *objectInfo, 61179a3c601SCedric Chaumont void *objectID, uint32_t *objectIDLen) 612b0104773SPascal Brand { 613b0104773SPascal Brand TEE_Result res; 614e86f1266SJens Wiklander uint64_t len; 6152342799fSPascal Brand TEE_ObjectInfo local_info; 6162342799fSPascal Brand TEE_ObjectInfo *pt_info; 617b0104773SPascal Brand 61815cd3c30SCedric Chaumont if (!objectID) { 61915cd3c30SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 62015cd3c30SCedric Chaumont goto out; 62115cd3c30SCedric Chaumont } 62215cd3c30SCedric Chaumont 62315cd3c30SCedric Chaumont if (!objectIDLen) { 62415cd3c30SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 62515cd3c30SCedric Chaumont goto out; 62615cd3c30SCedric Chaumont } 62715cd3c30SCedric Chaumont 6282342799fSPascal Brand if (objectInfo) 6292342799fSPascal Brand pt_info = objectInfo; 6302342799fSPascal Brand else 6312342799fSPascal Brand pt_info = &local_info; 632e86f1266SJens Wiklander len = *objectIDLen; 633e86f1266SJens Wiklander res = utee_storage_next_enum((unsigned long)objectEnumerator, 6342342799fSPascal Brand pt_info, objectID, &len); 635e86f1266SJens Wiklander *objectIDLen = len; 636b0104773SPascal Brand 63715cd3c30SCedric Chaumont out: 63815cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 63915cd3c30SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 64015cd3c30SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 64115cd3c30SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 642b36311adSJerome Forissier TEE_Panic(res); 643b0104773SPascal Brand 644b0104773SPascal Brand return res; 645b0104773SPascal Brand } 646b0104773SPascal Brand 647b0104773SPascal Brand /* Data and Key Storage API - Data Stream Access Functions */ 648b0104773SPascal Brand 649b0104773SPascal Brand TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 65079a3c601SCedric Chaumont uint32_t size, uint32_t *count) 651b0104773SPascal Brand { 652b0104773SPascal Brand TEE_Result res; 653e86f1266SJens Wiklander uint64_t cnt64; 654b0104773SPascal Brand 655ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 656ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 657ae1289baSCedric Chaumont goto out; 658ae1289baSCedric Chaumont } 659b0104773SPascal Brand 660e86f1266SJens Wiklander cnt64 = *count; 661e86f1266SJens Wiklander res = utee_storage_obj_read((unsigned long)object, buffer, size, 662e86f1266SJens Wiklander &cnt64); 663e86f1266SJens Wiklander *count = cnt64; 664b0104773SPascal Brand 665ae1289baSCedric Chaumont out: 666ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 667ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 668ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 669b36311adSJerome Forissier TEE_Panic(res); 670b0104773SPascal Brand 671b0104773SPascal Brand return res; 672b0104773SPascal Brand } 673b0104773SPascal Brand 6748f07fe6fSJerome Forissier TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, 67579a3c601SCedric Chaumont uint32_t size) 676b0104773SPascal Brand { 677b0104773SPascal Brand TEE_Result res; 678b0104773SPascal Brand 679ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 680ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 681ae1289baSCedric Chaumont goto out; 682ae1289baSCedric Chaumont } 683ae1289baSCedric Chaumont 684ae1289baSCedric Chaumont if (size > TEE_DATA_MAX_POSITION) { 685ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 686ae1289baSCedric Chaumont goto out; 687ae1289baSCedric Chaumont } 688b0104773SPascal Brand 689e86f1266SJens Wiklander res = utee_storage_obj_write((unsigned long)object, buffer, size); 690b0104773SPascal Brand 691ae1289baSCedric Chaumont out: 692ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 693ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE && 694ae1289baSCedric Chaumont res != TEE_ERROR_OVERFLOW && 695ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 696ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 697b36311adSJerome Forissier TEE_Panic(res); 698b0104773SPascal Brand 699b0104773SPascal Brand return res; 700b0104773SPascal Brand } 701b0104773SPascal Brand 702b0104773SPascal Brand TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 703b0104773SPascal Brand { 704b0104773SPascal Brand TEE_Result res; 705b0104773SPascal Brand 706ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 707ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 708ae1289baSCedric Chaumont goto out; 709ae1289baSCedric Chaumont } 710b0104773SPascal Brand 711e86f1266SJens Wiklander res = utee_storage_obj_trunc((unsigned long)object, size); 712b0104773SPascal Brand 713ae1289baSCedric Chaumont out: 714ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 715ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE && 716ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 717ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 718b36311adSJerome Forissier TEE_Panic(res); 719b0104773SPascal Brand 720b0104773SPascal Brand return res; 721b0104773SPascal Brand } 722b0104773SPascal Brand 723b0104773SPascal Brand TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 724b0104773SPascal Brand TEE_Whence whence) 725b0104773SPascal Brand { 726b0104773SPascal Brand TEE_Result res; 727b0104773SPascal Brand TEE_ObjectInfo info; 728b0104773SPascal Brand 729ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 730ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 731ae1289baSCedric Chaumont goto out; 732ae1289baSCedric Chaumont } 733b0104773SPascal Brand 734e86f1266SJens Wiklander res = utee_cryp_obj_get_info((unsigned long)object, &info); 735b0104773SPascal Brand if (res != TEE_SUCCESS) 736ae1289baSCedric Chaumont goto out; 737b0104773SPascal Brand 738b0104773SPascal Brand switch (whence) { 739b0104773SPascal Brand case TEE_DATA_SEEK_SET: 740ae1289baSCedric Chaumont if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) { 741ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 742ae1289baSCedric Chaumont goto out; 743ae1289baSCedric Chaumont } 744b0104773SPascal Brand break; 745b0104773SPascal Brand case TEE_DATA_SEEK_CUR: 746b0104773SPascal Brand if (offset > 0 && 747b0104773SPascal Brand ((uint32_t)offset + info.dataPosition > 748b0104773SPascal Brand TEE_DATA_MAX_POSITION || 749b0104773SPascal Brand (uint32_t)offset + info.dataPosition < 750ae1289baSCedric Chaumont info.dataPosition)) { 751ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 752ae1289baSCedric Chaumont goto out; 753ae1289baSCedric Chaumont } 754b0104773SPascal Brand break; 755b0104773SPascal Brand case TEE_DATA_SEEK_END: 756b0104773SPascal Brand if (offset > 0 && 757b0104773SPascal Brand ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION || 758ae1289baSCedric Chaumont (uint32_t)offset + info.dataSize < info.dataSize)) { 759ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 760ae1289baSCedric Chaumont goto out; 761ae1289baSCedric Chaumont } 762b0104773SPascal Brand break; 763b0104773SPascal Brand default: 764ae1289baSCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 765ae1289baSCedric Chaumont goto out; 766b0104773SPascal Brand } 767b0104773SPascal Brand 768e86f1266SJens Wiklander res = utee_storage_obj_seek((unsigned long)object, offset, whence); 769b0104773SPascal Brand 770ae1289baSCedric Chaumont out: 771ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 772ae1289baSCedric Chaumont res != TEE_ERROR_OVERFLOW && 773ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 774ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 775b36311adSJerome Forissier TEE_Panic(res); 776b0104773SPascal Brand 777b0104773SPascal Brand return res; 778b0104773SPascal Brand } 779