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 14e86f1266SJens Wiklander void __utee_from_attr(struct utee_attribute *ua, const TEE_Attribute *attrs, 15e86f1266SJens Wiklander uint32_t attr_count) 16e86f1266SJens Wiklander { 17e86f1266SJens Wiklander size_t n; 18e86f1266SJens Wiklander 19e86f1266SJens Wiklander for (n = 0; n < attr_count; n++) { 20e86f1266SJens Wiklander ua[n].attribute_id = attrs[n].attributeID; 21b9416909SJens Wiklander if (attrs[n].attributeID & TEE_ATTR_FLAG_VALUE) { 22e86f1266SJens Wiklander ua[n].a = attrs[n].content.value.a; 23e86f1266SJens Wiklander ua[n].b = attrs[n].content.value.b; 24e86f1266SJens Wiklander } else { 25e86f1266SJens Wiklander ua[n].a = (uintptr_t)attrs[n].content.ref.buffer; 26e86f1266SJens Wiklander ua[n].b = attrs[n].content.ref.length; 27e86f1266SJens Wiklander } 28e86f1266SJens Wiklander } 29e86f1266SJens Wiklander } 30e86f1266SJens Wiklander 31b0104773SPascal Brand /* Data and Key Storage API - Generic Object Functions */ 327583c59eSCedric Chaumont /* 337583c59eSCedric Chaumont * Use of this function is deprecated 347583c59eSCedric Chaumont * new code SHOULD use the TEE_GetObjectInfo1 function instead 357583c59eSCedric Chaumont * These functions will be removed at some future major revision of 367583c59eSCedric Chaumont * this specification 377583c59eSCedric Chaumont */ 38b0104773SPascal Brand void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 39b0104773SPascal Brand { 40b0104773SPascal Brand TEE_Result res; 41b0104773SPascal Brand 422c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, objectInfo); 437583c59eSCedric Chaumont 44b0104773SPascal Brand if (res != TEE_SUCCESS) 45b0104773SPascal Brand TEE_Panic(res); 467583c59eSCedric Chaumont 477583c59eSCedric Chaumont if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) { 487583c59eSCedric Chaumont objectInfo->keySize = 0; 497583c59eSCedric Chaumont objectInfo->maxKeySize = 0; 507583c59eSCedric Chaumont objectInfo->objectUsage = 0; 517583c59eSCedric Chaumont objectInfo->dataSize = 0; 527583c59eSCedric Chaumont objectInfo->dataPosition = 0; 537583c59eSCedric Chaumont objectInfo->handleFlags = 0; 547583c59eSCedric Chaumont } 55b0104773SPascal Brand } 56b0104773SPascal Brand 577583c59eSCedric Chaumont TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 587583c59eSCedric Chaumont { 597583c59eSCedric Chaumont TEE_Result res; 607583c59eSCedric Chaumont 612c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, objectInfo); 627583c59eSCedric Chaumont 63a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 64a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 65a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 667583c59eSCedric Chaumont TEE_Panic(res); 677583c59eSCedric Chaumont 687583c59eSCedric Chaumont return res; 697583c59eSCedric Chaumont } 707583c59eSCedric Chaumont 717583c59eSCedric Chaumont /* 727583c59eSCedric Chaumont * Use of this function is deprecated 737583c59eSCedric Chaumont * new code SHOULD use the TEE_RestrictObjectUsage1 function instead 747583c59eSCedric Chaumont * These functions will be removed at some future major revision of 757583c59eSCedric Chaumont * this specification 767583c59eSCedric Chaumont */ 77b0104773SPascal Brand void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) 78b0104773SPascal Brand { 79b0104773SPascal Brand TEE_Result res; 807583c59eSCedric Chaumont TEE_ObjectInfo objectInfo; 817583c59eSCedric Chaumont 822c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &objectInfo); 837583c59eSCedric Chaumont if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT) 847583c59eSCedric Chaumont return; 857583c59eSCedric Chaumont 867583c59eSCedric Chaumont res = TEE_RestrictObjectUsage1(object, objectUsage); 87b0104773SPascal Brand 88b0104773SPascal Brand if (res != TEE_SUCCESS) 89b36311adSJerome Forissier TEE_Panic(res); 90b0104773SPascal Brand } 91b0104773SPascal Brand 927583c59eSCedric Chaumont TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage) 937583c59eSCedric Chaumont { 947583c59eSCedric Chaumont TEE_Result res; 957583c59eSCedric Chaumont 962c028fdeSJerome Forissier res = _utee_cryp_obj_restrict_usage((unsigned long)object, 972c028fdeSJerome Forissier objectUsage); 987583c59eSCedric Chaumont 99a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 100a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 101a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 102a2e9a830SCedric Chaumont TEE_Panic(res); 1037583c59eSCedric Chaumont 1047583c59eSCedric Chaumont return res; 1057583c59eSCedric Chaumont } 1067583c59eSCedric Chaumont 107b0104773SPascal Brand TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 108b0104773SPascal Brand uint32_t attributeID, void *buffer, 10979a3c601SCedric Chaumont uint32_t *size) 110b0104773SPascal Brand { 111b0104773SPascal Brand TEE_Result res; 112b0104773SPascal Brand TEE_ObjectInfo info; 113e86f1266SJens Wiklander uint64_t sz; 114b0104773SPascal Brand 1156915bbbbSJens Wiklander __utee_check_inout_annotation(size, sizeof(*size)); 1166915bbbbSJens Wiklander 1172c028fdeSJerome Forissier 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 */ 122b9416909SJens Wiklander if ((attributeID & TEE_ATTR_FLAG_VALUE)) { 123a2e9a830SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 124a2e9a830SCedric Chaumont goto exit; 125a2e9a830SCedric Chaumont } 126b0104773SPascal Brand 127e86f1266SJens Wiklander sz = *size; 1282c028fdeSJerome Forissier 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 1526915bbbbSJens Wiklander if (a) 1536915bbbbSJens Wiklander __utee_check_out_annotation(a, sizeof(*a)); 1546915bbbbSJens Wiklander if (b) 1556915bbbbSJens Wiklander __utee_check_out_annotation(b, sizeof(*b)); 1566915bbbbSJens Wiklander 1572c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 158b0104773SPascal Brand if (res != TEE_SUCCESS) 159a2e9a830SCedric Chaumont goto exit; 160b0104773SPascal Brand 161b0104773SPascal Brand /* This function only supports value attributes */ 162b9416909SJens Wiklander if (!(attributeID & TEE_ATTR_FLAG_VALUE)) { 163a2e9a830SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 164a2e9a830SCedric Chaumont goto exit; 165a2e9a830SCedric Chaumont } 166b0104773SPascal Brand 1672c028fdeSJerome Forissier res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf, 168e86f1266SJens Wiklander &size); 169b0104773SPascal Brand 170a2e9a830SCedric Chaumont exit: 1710ed6a6caSCedric Chaumont if (res != TEE_SUCCESS && 1720ed6a6caSCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 1730ed6a6caSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 1740ed6a6caSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 175b36311adSJerome Forissier TEE_Panic(res); 176b0104773SPascal Brand 177b0104773SPascal Brand if (size != sizeof(buf)) 178b0104773SPascal Brand TEE_Panic(0); 179b0104773SPascal Brand 180be96c837SJerome Forissier if (res == TEE_SUCCESS) { 181b9d8f134SJerome Forissier if (a) 182b0104773SPascal Brand *a = buf[0]; 183b9d8f134SJerome Forissier if (b) 184b0104773SPascal Brand *b = buf[1]; 185be96c837SJerome Forissier } 186b0104773SPascal Brand 187b0104773SPascal Brand return res; 188b0104773SPascal Brand } 189b0104773SPascal Brand 190b0104773SPascal Brand void TEE_CloseObject(TEE_ObjectHandle object) 191b0104773SPascal Brand { 192b0104773SPascal Brand TEE_Result res; 193b0104773SPascal Brand 194b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 195b0104773SPascal Brand return; 196b0104773SPascal Brand 1972c028fdeSJerome Forissier res = _utee_cryp_obj_close((unsigned long)object); 198b0104773SPascal Brand if (res != TEE_SUCCESS) 199b36311adSJerome Forissier TEE_Panic(res); 200b0104773SPascal Brand } 201b0104773SPascal Brand 202b0104773SPascal Brand /* Data and Key Storage API - Transient Object Functions */ 203b0104773SPascal Brand 204b0104773SPascal Brand TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 20579a3c601SCedric Chaumont uint32_t maxKeySize, 206b0104773SPascal Brand TEE_ObjectHandle *object) 207b0104773SPascal Brand { 208b0104773SPascal Brand TEE_Result res; 209b0104773SPascal Brand uint32_t obj; 210b0104773SPascal Brand 2116915bbbbSJens Wiklander __utee_check_out_annotation(object, sizeof(*object)); 2126915bbbbSJens Wiklander 2132c028fdeSJerome Forissier res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 214aeb0d927SCedric Chaumont 215aeb0d927SCedric Chaumont if (res != TEE_SUCCESS && 216aeb0d927SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 217aeb0d927SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 218b36311adSJerome Forissier TEE_Panic(res); 219aeb0d927SCedric Chaumont 220b0104773SPascal Brand if (res == TEE_SUCCESS) 221e86f1266SJens Wiklander *object = (TEE_ObjectHandle)(uintptr_t)obj; 2220ed6a6caSCedric Chaumont 223b0104773SPascal Brand return res; 224b0104773SPascal Brand } 225b0104773SPascal Brand 226b0104773SPascal Brand void TEE_FreeTransientObject(TEE_ObjectHandle object) 227b0104773SPascal Brand { 228b0104773SPascal Brand TEE_Result res; 229b0104773SPascal Brand TEE_ObjectInfo info; 230b0104773SPascal Brand 231b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 232b0104773SPascal Brand return; 233b0104773SPascal Brand 2342c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 235b0104773SPascal Brand if (res != TEE_SUCCESS) 236b36311adSJerome Forissier TEE_Panic(res); 237b0104773SPascal Brand 238b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 239b0104773SPascal Brand TEE_Panic(0); 240b0104773SPascal Brand 2412c028fdeSJerome Forissier res = _utee_cryp_obj_close((unsigned long)object); 242b0104773SPascal Brand if (res != TEE_SUCCESS) 243b36311adSJerome Forissier TEE_Panic(res); 244b0104773SPascal Brand } 245b0104773SPascal Brand 246b0104773SPascal Brand void TEE_ResetTransientObject(TEE_ObjectHandle object) 247b0104773SPascal Brand { 248b0104773SPascal Brand TEE_Result res; 249b0104773SPascal Brand TEE_ObjectInfo info; 250b0104773SPascal Brand 251b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 252b0104773SPascal Brand return; 253b0104773SPascal Brand 2542c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 255b0104773SPascal Brand if (res != TEE_SUCCESS) 256b36311adSJerome Forissier TEE_Panic(res); 257b0104773SPascal Brand 258b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 259b0104773SPascal Brand TEE_Panic(0); 260b0104773SPascal Brand 2612c028fdeSJerome Forissier res = _utee_cryp_obj_reset((unsigned long)object); 262b0104773SPascal Brand if (res != TEE_SUCCESS) 263b36311adSJerome Forissier TEE_Panic(res); 264b0104773SPascal Brand } 265b0104773SPascal Brand 266b0104773SPascal Brand TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 2678f07fe6fSJerome Forissier const TEE_Attribute *attrs, 268b0104773SPascal Brand uint32_t attrCount) 269b0104773SPascal Brand { 270b0104773SPascal Brand TEE_Result res; 271b0104773SPascal Brand TEE_ObjectInfo info; 272e86f1266SJens Wiklander struct utee_attribute ua[attrCount]; 273b0104773SPascal Brand 2746915bbbbSJens Wiklander __utee_check_attr_in_annotation(attrs, attrCount); 2756915bbbbSJens Wiklander 2762c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 277b0104773SPascal Brand if (res != TEE_SUCCESS) 278b36311adSJerome Forissier TEE_Panic(res); 279b0104773SPascal Brand 280b0104773SPascal Brand /* Must be a transient object */ 281b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 282b0104773SPascal Brand TEE_Panic(0); 283b0104773SPascal Brand 284b0104773SPascal Brand /* Must not be initialized already */ 285b0104773SPascal Brand if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 286b0104773SPascal Brand TEE_Panic(0); 287b0104773SPascal Brand 288e86f1266SJens Wiklander __utee_from_attr(ua, attrs, attrCount); 2892c028fdeSJerome Forissier res = _utee_cryp_obj_populate((unsigned long)object, ua, attrCount); 290b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 291b0104773SPascal Brand TEE_Panic(res); 292b0104773SPascal Brand return res; 293b0104773SPascal Brand } 294b0104773SPascal Brand 295b0104773SPascal Brand void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID, 2968f07fe6fSJerome Forissier const void *buffer, uint32_t length) 297b0104773SPascal Brand { 2986915bbbbSJens Wiklander __utee_check_out_annotation(attr, sizeof(*attr)); 2996915bbbbSJens Wiklander 300b9416909SJens Wiklander if ((attributeID & TEE_ATTR_FLAG_VALUE) != 0) 301b0104773SPascal Brand TEE_Panic(0); 302b0104773SPascal Brand attr->attributeID = attributeID; 3038f07fe6fSJerome Forissier attr->content.ref.buffer = (void *)buffer; 304b0104773SPascal Brand attr->content.ref.length = length; 305b0104773SPascal Brand } 306b0104773SPascal Brand 307b0104773SPascal Brand void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, 308b0104773SPascal Brand uint32_t a, uint32_t b) 309b0104773SPascal Brand { 3106915bbbbSJens Wiklander __utee_check_out_annotation(attr, sizeof(*attr)); 3116915bbbbSJens Wiklander 312b9416909SJens Wiklander if ((attributeID & TEE_ATTR_FLAG_VALUE) == 0) 313b0104773SPascal Brand TEE_Panic(0); 314b0104773SPascal Brand attr->attributeID = attributeID; 315b0104773SPascal Brand attr->content.value.a = a; 316b0104773SPascal Brand attr->content.value.b = b; 317b0104773SPascal Brand } 318b0104773SPascal Brand 3197583c59eSCedric Chaumont /* 3207583c59eSCedric Chaumont * Use of this function is deprecated 3217583c59eSCedric Chaumont * new code SHOULD use the TEE_CopyObjectAttributes1 function instead 3227583c59eSCedric Chaumont * These functions will be removed at some future major revision of 3237583c59eSCedric Chaumont * this specification 3247583c59eSCedric Chaumont */ 325b0104773SPascal Brand void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, 326b0104773SPascal Brand TEE_ObjectHandle srcObject) 327b0104773SPascal Brand { 328b0104773SPascal Brand TEE_Result res; 3297583c59eSCedric Chaumont TEE_ObjectInfo src_info; 3307583c59eSCedric Chaumont 3312c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 3327583c59eSCedric Chaumont if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT) 3337583c59eSCedric Chaumont return; 3347583c59eSCedric Chaumont 3357583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(destObject, srcObject); 3367583c59eSCedric Chaumont if (res != TEE_SUCCESS) 337b36311adSJerome Forissier TEE_Panic(res); 3387583c59eSCedric Chaumont } 3397583c59eSCedric Chaumont 3407583c59eSCedric Chaumont TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject, 3417583c59eSCedric Chaumont TEE_ObjectHandle srcObject) 3427583c59eSCedric Chaumont { 3437583c59eSCedric Chaumont TEE_Result res; 344b0104773SPascal Brand TEE_ObjectInfo dst_info; 345b0104773SPascal Brand TEE_ObjectInfo src_info; 346b0104773SPascal Brand 3472c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)destObject, &dst_info); 348b0104773SPascal Brand if (res != TEE_SUCCESS) 349a2e9a830SCedric Chaumont goto exit; 350b0104773SPascal Brand 3512c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 352b0104773SPascal Brand if (res != TEE_SUCCESS) 353a2e9a830SCedric Chaumont goto exit; 354b0104773SPascal Brand 355a2e9a830SCedric Chaumont if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 356b0104773SPascal Brand TEE_Panic(0); 357a2e9a830SCedric Chaumont 358a2e9a830SCedric Chaumont if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) 359b0104773SPascal Brand TEE_Panic(0); 360a2e9a830SCedric Chaumont 361a2e9a830SCedric Chaumont if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 362b0104773SPascal Brand TEE_Panic(0); 363b0104773SPascal Brand 3642c028fdeSJerome Forissier res = _utee_cryp_obj_copy((unsigned long)destObject, 365e86f1266SJens Wiklander (unsigned long)srcObject); 3667583c59eSCedric Chaumont 367a2e9a830SCedric Chaumont exit: 368a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 369a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 370a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 371a2e9a830SCedric Chaumont TEE_Panic(res); 3727583c59eSCedric Chaumont 3737583c59eSCedric Chaumont return res; 374b0104773SPascal Brand } 375b0104773SPascal Brand 376b0104773SPascal Brand TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 3778f07fe6fSJerome Forissier const TEE_Attribute *params, uint32_t paramCount) 378b0104773SPascal Brand { 379b0104773SPascal Brand TEE_Result res; 380e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 381b0104773SPascal Brand 3826915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 3836915bbbbSJens Wiklander 384e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 3852c028fdeSJerome Forissier res = _utee_cryp_obj_generate_key((unsigned long)object, keySize, 386e86f1266SJens Wiklander ua, paramCount); 387b0104773SPascal Brand 388aeb0d927SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 389b36311adSJerome Forissier TEE_Panic(res); 390b0104773SPascal Brand 391b0104773SPascal Brand return res; 392b0104773SPascal Brand } 393b0104773SPascal Brand 394b0104773SPascal Brand /* Data and Key Storage API - Persistent Object Functions */ 395b0104773SPascal Brand 3968f07fe6fSJerome Forissier TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, 39779a3c601SCedric Chaumont uint32_t objectIDLen, uint32_t flags, 398b0104773SPascal Brand TEE_ObjectHandle *object) 399b0104773SPascal Brand { 4009b520646SCedric Chaumont TEE_Result res; 401e86f1266SJens Wiklander uint32_t obj; 402b0104773SPascal Brand 4039b520646SCedric Chaumont if (!objectID) { 4049b520646SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 405172d637bSCedric Auger goto exit; 4069b520646SCedric Chaumont } 4079b520646SCedric Chaumont 408*2138a6f8SStefan Schmidt __utee_check_out_annotation(object, sizeof(*object)); 409*2138a6f8SStefan Schmidt 4102c028fdeSJerome Forissier res = _utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 411e86f1266SJens Wiklander &obj); 412e86f1266SJens Wiklander if (res == TEE_SUCCESS) 413e86f1266SJens Wiklander *object = (TEE_ObjectHandle)(uintptr_t)obj; 4149b520646SCedric Chaumont 415172d637bSCedric Auger exit: 4169b520646SCedric Chaumont if (res != TEE_SUCCESS && 4179b520646SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 4189b520646SCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT && 4199b520646SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 4209b520646SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 4219b520646SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 422b36311adSJerome Forissier TEE_Panic(res); 423b0104773SPascal Brand 424172d637bSCedric Auger if (res != TEE_SUCCESS) 42569a3d6beSDaniel Glöckner *object = TEE_HANDLE_NULL; 42669a3d6beSDaniel Glöckner 4279b520646SCedric Chaumont return res; 428b0104773SPascal Brand } 429b0104773SPascal Brand 4308f07fe6fSJerome Forissier TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, 43179a3c601SCedric Chaumont uint32_t objectIDLen, uint32_t flags, 432b0104773SPascal Brand TEE_ObjectHandle attributes, 433b0104773SPascal Brand const void *initialData, 43479a3c601SCedric Chaumont uint32_t initialDataLen, 435b0104773SPascal Brand TEE_ObjectHandle *object) 436b0104773SPascal Brand { 43784431ae3SCedric Chaumont TEE_Result res; 438e86f1266SJens Wiklander uint32_t obj; 439b0104773SPascal Brand 440aeb0d927SCedric Chaumont if (!objectID) { 44184431ae3SCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 442172d637bSCedric Auger goto exit; 44384431ae3SCedric Chaumont } 444b0104773SPascal Brand 4456915bbbbSJens Wiklander __utee_check_out_annotation(object, sizeof(*object)); 446b0104773SPascal Brand 4472c028fdeSJerome Forissier res = _utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 448e86f1266SJens Wiklander (unsigned long)attributes, initialData, 449e86f1266SJens Wiklander initialDataLen, &obj); 450172d637bSCedric Auger 4511c96fa7fSPascal Brand if (res == TEE_SUCCESS) 452172d637bSCedric Auger *object = (TEE_ObjectHandle)(uintptr_t)obj; 453172d637bSCedric Auger 454172d637bSCedric Auger exit: 455172d637bSCedric Auger if (res != TEE_SUCCESS && 456172d637bSCedric Auger res != TEE_ERROR_ITEM_NOT_FOUND && 457172d637bSCedric Auger res != TEE_ERROR_ACCESS_CONFLICT && 458172d637bSCedric Auger res != TEE_ERROR_OUT_OF_MEMORY && 459172d637bSCedric Auger res != TEE_ERROR_STORAGE_NO_SPACE && 460172d637bSCedric Auger res != TEE_ERROR_CORRUPT_OBJECT && 461172d637bSCedric Auger res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 462b36311adSJerome Forissier TEE_Panic(res); 463172d637bSCedric Auger 464172d637bSCedric Auger if (res != TEE_SUCCESS) 465172d637bSCedric Auger *object = TEE_HANDLE_NULL; 466172d637bSCedric Auger 467172d637bSCedric Auger return res; 468b0104773SPascal Brand } 469b0104773SPascal Brand 4707583c59eSCedric Chaumont /* 4717583c59eSCedric Chaumont * Use of this function is deprecated 4727583c59eSCedric Chaumont * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead 4737583c59eSCedric Chaumont * These functions will be removed at some future major revision of 4747583c59eSCedric Chaumont * this specification 4757583c59eSCedric Chaumont */ 476b0104773SPascal Brand void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 477b0104773SPascal Brand { 478b0104773SPascal Brand TEE_Result res; 479b0104773SPascal Brand 480b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 481b0104773SPascal Brand return; 482b0104773SPascal Brand 4837583c59eSCedric Chaumont res = TEE_CloseAndDeletePersistentObject1(object); 484b0104773SPascal Brand 485b0104773SPascal Brand if (res != TEE_SUCCESS) 486b0104773SPascal Brand TEE_Panic(0); 487b0104773SPascal Brand } 488b0104773SPascal Brand 4897583c59eSCedric Chaumont TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object) 4907583c59eSCedric Chaumont { 4917583c59eSCedric Chaumont TEE_Result res; 4927583c59eSCedric Chaumont 4937583c59eSCedric Chaumont if (object == TEE_HANDLE_NULL) 49446cfd17cSJens Wiklander return TEE_SUCCESS; 4957583c59eSCedric Chaumont 4962c028fdeSJerome Forissier res = _utee_storage_obj_del((unsigned long)object); 4977583c59eSCedric Chaumont 4987583c59eSCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 499b36311adSJerome Forissier TEE_Panic(res); 5007583c59eSCedric Chaumont 5017583c59eSCedric Chaumont return res; 5027583c59eSCedric Chaumont } 5037583c59eSCedric Chaumont 5047583c59eSCedric Chaumont 505b0104773SPascal Brand TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 506b0104773SPascal Brand const void *newObjectID, 50779a3c601SCedric Chaumont uint32_t newObjectIDLen) 508b0104773SPascal Brand { 509b0104773SPascal Brand TEE_Result res; 510b0104773SPascal Brand 511a76bf53fSCedric Chaumont if (object == TEE_HANDLE_NULL) { 512a76bf53fSCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 513a76bf53fSCedric Chaumont goto out; 514a76bf53fSCedric Chaumont } 515b0104773SPascal Brand 5162c028fdeSJerome Forissier res = _utee_storage_obj_rename((unsigned long)object, newObjectID, 517e86f1266SJens Wiklander newObjectIDLen); 518b0104773SPascal Brand 519a76bf53fSCedric Chaumont out: 520a76bf53fSCedric Chaumont if (res != TEE_SUCCESS && 521a76bf53fSCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT && 522a76bf53fSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 523a76bf53fSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 524b36311adSJerome Forissier TEE_Panic(res); 525b0104773SPascal Brand 526b0104773SPascal Brand return res; 527b0104773SPascal Brand } 528b0104773SPascal Brand 529b0104773SPascal Brand TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 530b0104773SPascal Brand objectEnumerator) 531b0104773SPascal Brand { 532b0104773SPascal Brand TEE_Result res; 533e86f1266SJens Wiklander uint32_t oe; 534b0104773SPascal Brand 5356915bbbbSJens Wiklander __utee_check_out_annotation(objectEnumerator, 5366915bbbbSJens Wiklander sizeof(*objectEnumerator)); 537b0104773SPascal Brand 5382c028fdeSJerome Forissier res = _utee_storage_alloc_enum(&oe); 539b0104773SPascal Brand 540b0104773SPascal Brand if (res != TEE_SUCCESS) 541e86f1266SJens Wiklander oe = TEE_HANDLE_NULL; 542e86f1266SJens Wiklander 543e86f1266SJens Wiklander *objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe; 544b0104773SPascal Brand 54515cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 54615cd3c30SCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT) 547b36311adSJerome Forissier TEE_Panic(res); 54815cd3c30SCedric Chaumont 549b0104773SPascal Brand return res; 550b0104773SPascal Brand } 551b0104773SPascal Brand 552b0104773SPascal Brand void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 553b0104773SPascal Brand { 554b0104773SPascal Brand TEE_Result res; 555b0104773SPascal Brand 556b0104773SPascal Brand if (objectEnumerator == TEE_HANDLE_NULL) 557b0104773SPascal Brand return; 558b0104773SPascal Brand 5592c028fdeSJerome Forissier res = _utee_storage_free_enum((unsigned long)objectEnumerator); 560b0104773SPascal Brand 561b0104773SPascal Brand if (res != TEE_SUCCESS) 562b36311adSJerome Forissier TEE_Panic(res); 563b0104773SPascal Brand } 564b0104773SPascal Brand 565b0104773SPascal Brand void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 566b0104773SPascal Brand { 567b0104773SPascal Brand TEE_Result res; 568b0104773SPascal Brand 569b0104773SPascal Brand if (objectEnumerator == TEE_HANDLE_NULL) 570b0104773SPascal Brand return; 571b0104773SPascal Brand 5722c028fdeSJerome Forissier res = _utee_storage_reset_enum((unsigned long)objectEnumerator); 573b0104773SPascal Brand 574b0104773SPascal Brand if (res != TEE_SUCCESS) 575b36311adSJerome Forissier TEE_Panic(res); 576b0104773SPascal Brand } 577b0104773SPascal Brand 578b0104773SPascal Brand TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 579b0104773SPascal Brand objectEnumerator, 580b0104773SPascal Brand uint32_t storageID) 581b0104773SPascal Brand { 582b0104773SPascal Brand TEE_Result res; 583b0104773SPascal Brand 5842c028fdeSJerome Forissier res = _utee_storage_start_enum((unsigned long)objectEnumerator, 585e86f1266SJens Wiklander storageID); 586b0104773SPascal Brand 58715cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 58815cd3c30SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 58915cd3c30SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 59015cd3c30SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 591b36311adSJerome Forissier TEE_Panic(res); 592b0104773SPascal Brand 593b0104773SPascal Brand return res; 594b0104773SPascal Brand } 595b0104773SPascal Brand 596b0104773SPascal Brand TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, 597b0104773SPascal Brand TEE_ObjectInfo *objectInfo, 59879a3c601SCedric Chaumont void *objectID, uint32_t *objectIDLen) 599b0104773SPascal Brand { 600b0104773SPascal Brand TEE_Result res; 601e86f1266SJens Wiklander uint64_t len; 6022342799fSPascal Brand TEE_ObjectInfo local_info; 6032342799fSPascal Brand TEE_ObjectInfo *pt_info; 604b0104773SPascal Brand 6056915bbbbSJens Wiklander if (objectInfo) 6066915bbbbSJens Wiklander __utee_check_out_annotation(objectInfo, sizeof(*objectInfo)); 6076915bbbbSJens Wiklander __utee_check_out_annotation(objectIDLen, sizeof(*objectIDLen)); 60815cd3c30SCedric Chaumont 6096915bbbbSJens Wiklander if (!objectID) { 61015cd3c30SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 61115cd3c30SCedric Chaumont goto out; 61215cd3c30SCedric Chaumont } 61315cd3c30SCedric Chaumont 6142342799fSPascal Brand if (objectInfo) 6152342799fSPascal Brand pt_info = objectInfo; 6162342799fSPascal Brand else 6172342799fSPascal Brand pt_info = &local_info; 618e86f1266SJens Wiklander len = *objectIDLen; 6192c028fdeSJerome Forissier res = _utee_storage_next_enum((unsigned long)objectEnumerator, 6202342799fSPascal Brand pt_info, objectID, &len); 621e86f1266SJens Wiklander *objectIDLen = len; 622b0104773SPascal Brand 62315cd3c30SCedric Chaumont out: 62415cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 62515cd3c30SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 62615cd3c30SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 62715cd3c30SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 628b36311adSJerome Forissier TEE_Panic(res); 629b0104773SPascal Brand 630b0104773SPascal Brand return res; 631b0104773SPascal Brand } 632b0104773SPascal Brand 633b0104773SPascal Brand /* Data and Key Storage API - Data Stream Access Functions */ 634b0104773SPascal Brand 635b0104773SPascal Brand TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 63679a3c601SCedric Chaumont uint32_t size, uint32_t *count) 637b0104773SPascal Brand { 638b0104773SPascal Brand TEE_Result res; 639e86f1266SJens Wiklander uint64_t cnt64; 640b0104773SPascal Brand 641ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 642ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 643ae1289baSCedric Chaumont goto out; 644ae1289baSCedric Chaumont } 6456915bbbbSJens Wiklander __utee_check_out_annotation(count, sizeof(*count)); 646b0104773SPascal Brand 647e86f1266SJens Wiklander cnt64 = *count; 6482c028fdeSJerome Forissier res = _utee_storage_obj_read((unsigned long)object, buffer, size, 649e86f1266SJens Wiklander &cnt64); 650e86f1266SJens Wiklander *count = cnt64; 651b0104773SPascal Brand 652ae1289baSCedric Chaumont out: 653ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 654ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 655ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 656b36311adSJerome Forissier TEE_Panic(res); 657b0104773SPascal Brand 658b0104773SPascal Brand return res; 659b0104773SPascal Brand } 660b0104773SPascal Brand 6618f07fe6fSJerome Forissier TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, 66279a3c601SCedric Chaumont uint32_t size) 663b0104773SPascal Brand { 664b0104773SPascal Brand TEE_Result res; 665b0104773SPascal Brand 666ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 667ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 668ae1289baSCedric Chaumont goto out; 669ae1289baSCedric Chaumont } 670ae1289baSCedric Chaumont 671ae1289baSCedric Chaumont if (size > TEE_DATA_MAX_POSITION) { 672ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 673ae1289baSCedric Chaumont goto out; 674ae1289baSCedric Chaumont } 675b0104773SPascal Brand 6762c028fdeSJerome Forissier res = _utee_storage_obj_write((unsigned long)object, buffer, size); 677b0104773SPascal Brand 678ae1289baSCedric Chaumont out: 679ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 680ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE && 681ae1289baSCedric Chaumont res != TEE_ERROR_OVERFLOW && 682ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 683ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 684b36311adSJerome Forissier TEE_Panic(res); 685b0104773SPascal Brand 686b0104773SPascal Brand return res; 687b0104773SPascal Brand } 688b0104773SPascal Brand 689b0104773SPascal Brand TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 690b0104773SPascal Brand { 691b0104773SPascal Brand TEE_Result res; 692b0104773SPascal Brand 693ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 694ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 695ae1289baSCedric Chaumont goto out; 696ae1289baSCedric Chaumont } 697b0104773SPascal Brand 6982c028fdeSJerome Forissier res = _utee_storage_obj_trunc((unsigned long)object, size); 699b0104773SPascal Brand 700ae1289baSCedric Chaumont out: 701ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 702ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE && 703ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 704ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 705b36311adSJerome Forissier TEE_Panic(res); 706b0104773SPascal Brand 707b0104773SPascal Brand return res; 708b0104773SPascal Brand } 709b0104773SPascal Brand 710b0104773SPascal Brand TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 711b0104773SPascal Brand TEE_Whence whence) 712b0104773SPascal Brand { 713b0104773SPascal Brand TEE_Result res; 714b0104773SPascal Brand TEE_ObjectInfo info; 715b0104773SPascal Brand 716ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 717ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 718ae1289baSCedric Chaumont goto out; 719ae1289baSCedric Chaumont } 720b0104773SPascal Brand 7212c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 722b0104773SPascal Brand if (res != TEE_SUCCESS) 723ae1289baSCedric Chaumont goto out; 724b0104773SPascal Brand 725b0104773SPascal Brand switch (whence) { 726b0104773SPascal Brand case TEE_DATA_SEEK_SET: 727ae1289baSCedric Chaumont if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) { 728ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 729ae1289baSCedric Chaumont goto out; 730ae1289baSCedric Chaumont } 731b0104773SPascal Brand break; 732b0104773SPascal Brand case TEE_DATA_SEEK_CUR: 733b0104773SPascal Brand if (offset > 0 && 734b0104773SPascal Brand ((uint32_t)offset + info.dataPosition > 735b0104773SPascal Brand TEE_DATA_MAX_POSITION || 736b0104773SPascal Brand (uint32_t)offset + info.dataPosition < 737ae1289baSCedric Chaumont info.dataPosition)) { 738ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 739ae1289baSCedric Chaumont goto out; 740ae1289baSCedric Chaumont } 741b0104773SPascal Brand break; 742b0104773SPascal Brand case TEE_DATA_SEEK_END: 743b0104773SPascal Brand if (offset > 0 && 744b0104773SPascal Brand ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION || 745ae1289baSCedric Chaumont (uint32_t)offset + info.dataSize < info.dataSize)) { 746ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 747ae1289baSCedric Chaumont goto out; 748ae1289baSCedric Chaumont } 749b0104773SPascal Brand break; 750b0104773SPascal Brand default: 751ae1289baSCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 752ae1289baSCedric Chaumont goto out; 753b0104773SPascal Brand } 754b0104773SPascal Brand 7552c028fdeSJerome Forissier res = _utee_storage_obj_seek((unsigned long)object, offset, whence); 756b0104773SPascal Brand 757ae1289baSCedric Chaumont out: 758ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 759ae1289baSCedric Chaumont res != TEE_ERROR_OVERFLOW && 760ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 761ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 762b36311adSJerome Forissier TEE_Panic(res); 763b0104773SPascal Brand 764b0104773SPascal Brand return res; 765b0104773SPascal Brand } 766