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 { 40*75d6a373SJens Wiklander struct utee_object_info info = { }; 41*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 42b0104773SPascal Brand 43*75d6a373SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)object, &info); 447583c59eSCedric Chaumont 45b0104773SPascal Brand if (res != TEE_SUCCESS) 46b0104773SPascal Brand TEE_Panic(res); 477583c59eSCedric Chaumont 48*75d6a373SJens Wiklander if (info.obj_type == TEE_TYPE_CORRUPTED_OBJECT) { 497583c59eSCedric Chaumont objectInfo->keySize = 0; 507583c59eSCedric Chaumont objectInfo->maxKeySize = 0; 517583c59eSCedric Chaumont objectInfo->objectUsage = 0; 527583c59eSCedric Chaumont objectInfo->dataSize = 0; 537583c59eSCedric Chaumont objectInfo->dataPosition = 0; 547583c59eSCedric Chaumont objectInfo->handleFlags = 0; 55*75d6a373SJens Wiklander } else { 56*75d6a373SJens Wiklander objectInfo->objectType = info.obj_type; 57*75d6a373SJens Wiklander objectInfo->keySize = info.obj_size; 58*75d6a373SJens Wiklander objectInfo->maxKeySize = info.max_obj_size; 59*75d6a373SJens Wiklander objectInfo->objectUsage = info.obj_usage; 60*75d6a373SJens Wiklander objectInfo->dataSize = info.data_size; 61*75d6a373SJens Wiklander objectInfo->dataPosition = info.data_pos; 62*75d6a373SJens Wiklander objectInfo->handleFlags = info.handle_flags; 637583c59eSCedric Chaumont } 64b0104773SPascal Brand } 65b0104773SPascal Brand 667583c59eSCedric Chaumont TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 677583c59eSCedric Chaumont { 68*75d6a373SJens Wiklander struct utee_object_info info = { }; 69*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 707583c59eSCedric Chaumont 71*75d6a373SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)object, &info); 727583c59eSCedric Chaumont 73a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 74a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 75a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 767583c59eSCedric Chaumont TEE_Panic(res); 777583c59eSCedric Chaumont 78*75d6a373SJens Wiklander objectInfo->objectType = info.obj_type; 79*75d6a373SJens Wiklander objectInfo->keySize = info.obj_size; 80*75d6a373SJens Wiklander objectInfo->maxKeySize = info.max_obj_size; 81*75d6a373SJens Wiklander objectInfo->objectUsage = info.obj_usage; 82*75d6a373SJens Wiklander objectInfo->dataSize = info.data_size; 83*75d6a373SJens Wiklander objectInfo->dataPosition = info.data_pos; 84*75d6a373SJens Wiklander objectInfo->handleFlags = info.handle_flags; 85*75d6a373SJens Wiklander 867583c59eSCedric Chaumont return res; 877583c59eSCedric Chaumont } 887583c59eSCedric Chaumont 897583c59eSCedric Chaumont /* 907583c59eSCedric Chaumont * Use of this function is deprecated 917583c59eSCedric Chaumont * new code SHOULD use the TEE_RestrictObjectUsage1 function instead 927583c59eSCedric Chaumont * These functions will be removed at some future major revision of 937583c59eSCedric Chaumont * this specification 947583c59eSCedric Chaumont */ 95b0104773SPascal Brand void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) 96b0104773SPascal Brand { 97*75d6a373SJens Wiklander struct utee_object_info info = { }; 98*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 997583c59eSCedric Chaumont 100*75d6a373SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)object, &info); 101*75d6a373SJens Wiklander if (info.obj_type == TEE_TYPE_CORRUPTED_OBJECT) 1027583c59eSCedric Chaumont return; 1037583c59eSCedric Chaumont 1047583c59eSCedric Chaumont res = TEE_RestrictObjectUsage1(object, objectUsage); 105b0104773SPascal Brand 106b0104773SPascal Brand if (res != TEE_SUCCESS) 107b36311adSJerome Forissier TEE_Panic(res); 108b0104773SPascal Brand } 109b0104773SPascal Brand 1107583c59eSCedric Chaumont TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage) 1117583c59eSCedric Chaumont { 1127583c59eSCedric Chaumont TEE_Result res; 1137583c59eSCedric Chaumont 1142c028fdeSJerome Forissier res = _utee_cryp_obj_restrict_usage((unsigned long)object, 1152c028fdeSJerome Forissier objectUsage); 1167583c59eSCedric Chaumont 117a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 118a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 119a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 120a2e9a830SCedric Chaumont TEE_Panic(res); 1217583c59eSCedric Chaumont 1227583c59eSCedric Chaumont return res; 1237583c59eSCedric Chaumont } 1247583c59eSCedric Chaumont 125b0104773SPascal Brand TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 126b0104773SPascal Brand uint32_t attributeID, void *buffer, 12779a3c601SCedric Chaumont uint32_t *size) 128b0104773SPascal Brand { 129*75d6a373SJens Wiklander struct utee_object_info info = { }; 130*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 131*75d6a373SJens Wiklander uint64_t sz = 0; 132b0104773SPascal Brand 1336915bbbbSJens Wiklander __utee_check_inout_annotation(size, sizeof(*size)); 1346915bbbbSJens Wiklander 1352c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 136b0104773SPascal Brand if (res != TEE_SUCCESS) 137a2e9a830SCedric Chaumont goto exit; 138b0104773SPascal Brand 139b0104773SPascal Brand /* This function only supports reference attributes */ 140b9416909SJens Wiklander if ((attributeID & TEE_ATTR_FLAG_VALUE)) { 141a2e9a830SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 142a2e9a830SCedric Chaumont goto exit; 143a2e9a830SCedric Chaumont } 144b0104773SPascal Brand 145e86f1266SJens Wiklander sz = *size; 1462c028fdeSJerome Forissier res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, 147e86f1266SJens Wiklander buffer, &sz); 148e86f1266SJens Wiklander *size = sz; 149b0104773SPascal Brand 150a2e9a830SCedric Chaumont exit: 1510ed6a6caSCedric Chaumont if (res != TEE_SUCCESS && 1520ed6a6caSCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 1530ed6a6caSCedric Chaumont res != TEE_ERROR_SHORT_BUFFER && 1540ed6a6caSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 1550ed6a6caSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 156b36311adSJerome Forissier TEE_Panic(res); 157b0104773SPascal Brand 158b0104773SPascal Brand return res; 159b0104773SPascal Brand } 160b0104773SPascal Brand 161b0104773SPascal Brand TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object, 162b0104773SPascal Brand uint32_t attributeID, uint32_t *a, 163b0104773SPascal Brand uint32_t *b) 164b0104773SPascal Brand { 165*75d6a373SJens Wiklander struct utee_object_info info = { }; 166*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 167b0104773SPascal Brand uint32_t buf[2]; 168e86f1266SJens Wiklander uint64_t size = sizeof(buf); 169b0104773SPascal Brand 1706915bbbbSJens Wiklander if (a) 1716915bbbbSJens Wiklander __utee_check_out_annotation(a, sizeof(*a)); 1726915bbbbSJens Wiklander if (b) 1736915bbbbSJens Wiklander __utee_check_out_annotation(b, sizeof(*b)); 1746915bbbbSJens Wiklander 1752c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 176b0104773SPascal Brand if (res != TEE_SUCCESS) 177a2e9a830SCedric Chaumont goto exit; 178b0104773SPascal Brand 179b0104773SPascal Brand /* This function only supports value attributes */ 180b9416909SJens Wiklander if (!(attributeID & TEE_ATTR_FLAG_VALUE)) { 181a2e9a830SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 182a2e9a830SCedric Chaumont goto exit; 183a2e9a830SCedric Chaumont } 184b0104773SPascal Brand 1852c028fdeSJerome Forissier res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf, 186e86f1266SJens Wiklander &size); 187b0104773SPascal Brand 188a2e9a830SCedric Chaumont exit: 1890ed6a6caSCedric Chaumont if (res != TEE_SUCCESS && 1900ed6a6caSCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 1910ed6a6caSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 1920ed6a6caSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 193b36311adSJerome Forissier TEE_Panic(res); 194b0104773SPascal Brand 195b0104773SPascal Brand if (size != sizeof(buf)) 196b0104773SPascal Brand TEE_Panic(0); 197b0104773SPascal Brand 198be96c837SJerome Forissier if (res == TEE_SUCCESS) { 199b9d8f134SJerome Forissier if (a) 200b0104773SPascal Brand *a = buf[0]; 201b9d8f134SJerome Forissier if (b) 202b0104773SPascal Brand *b = buf[1]; 203be96c837SJerome Forissier } 204b0104773SPascal Brand 205b0104773SPascal Brand return res; 206b0104773SPascal Brand } 207b0104773SPascal Brand 208b0104773SPascal Brand void TEE_CloseObject(TEE_ObjectHandle object) 209b0104773SPascal Brand { 210b0104773SPascal Brand TEE_Result res; 211b0104773SPascal Brand 212b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 213b0104773SPascal Brand return; 214b0104773SPascal Brand 2152c028fdeSJerome Forissier res = _utee_cryp_obj_close((unsigned long)object); 216b0104773SPascal Brand if (res != TEE_SUCCESS) 217b36311adSJerome Forissier TEE_Panic(res); 218b0104773SPascal Brand } 219b0104773SPascal Brand 220b0104773SPascal Brand /* Data and Key Storage API - Transient Object Functions */ 221b0104773SPascal Brand 222b0104773SPascal Brand TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 22379a3c601SCedric Chaumont uint32_t maxKeySize, 224b0104773SPascal Brand TEE_ObjectHandle *object) 225b0104773SPascal Brand { 226b0104773SPascal Brand TEE_Result res; 227b0104773SPascal Brand uint32_t obj; 228b0104773SPascal Brand 2296915bbbbSJens Wiklander __utee_check_out_annotation(object, sizeof(*object)); 2306915bbbbSJens Wiklander 2312c028fdeSJerome Forissier res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 232aeb0d927SCedric Chaumont 233aeb0d927SCedric Chaumont if (res != TEE_SUCCESS && 234aeb0d927SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 235aeb0d927SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 236b36311adSJerome Forissier TEE_Panic(res); 237aeb0d927SCedric Chaumont 238b0104773SPascal Brand if (res == TEE_SUCCESS) 239e86f1266SJens Wiklander *object = (TEE_ObjectHandle)(uintptr_t)obj; 2400ed6a6caSCedric Chaumont 241b0104773SPascal Brand return res; 242b0104773SPascal Brand } 243b0104773SPascal Brand 244b0104773SPascal Brand void TEE_FreeTransientObject(TEE_ObjectHandle object) 245b0104773SPascal Brand { 246*75d6a373SJens Wiklander struct utee_object_info info = { }; 247*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 248b0104773SPascal Brand 249b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 250b0104773SPascal Brand return; 251b0104773SPascal Brand 2522c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 253b0104773SPascal Brand if (res != TEE_SUCCESS) 254b36311adSJerome Forissier TEE_Panic(res); 255b0104773SPascal Brand 256*75d6a373SJens Wiklander if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 257b0104773SPascal Brand TEE_Panic(0); 258b0104773SPascal Brand 2592c028fdeSJerome Forissier res = _utee_cryp_obj_close((unsigned long)object); 260b0104773SPascal Brand if (res != TEE_SUCCESS) 261b36311adSJerome Forissier TEE_Panic(res); 262b0104773SPascal Brand } 263b0104773SPascal Brand 264b0104773SPascal Brand void TEE_ResetTransientObject(TEE_ObjectHandle object) 265b0104773SPascal Brand { 266*75d6a373SJens Wiklander struct utee_object_info info = { }; 267*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 268b0104773SPascal Brand 269b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 270b0104773SPascal Brand return; 271b0104773SPascal Brand 2722c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 273b0104773SPascal Brand if (res != TEE_SUCCESS) 274b36311adSJerome Forissier TEE_Panic(res); 275b0104773SPascal Brand 276*75d6a373SJens Wiklander if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 277b0104773SPascal Brand TEE_Panic(0); 278b0104773SPascal Brand 2792c028fdeSJerome Forissier res = _utee_cryp_obj_reset((unsigned long)object); 280b0104773SPascal Brand if (res != TEE_SUCCESS) 281b36311adSJerome Forissier TEE_Panic(res); 282b0104773SPascal Brand } 283b0104773SPascal Brand 284b0104773SPascal Brand TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 2858f07fe6fSJerome Forissier const TEE_Attribute *attrs, 286b0104773SPascal Brand uint32_t attrCount) 287b0104773SPascal Brand { 288e86f1266SJens Wiklander struct utee_attribute ua[attrCount]; 289*75d6a373SJens Wiklander struct utee_object_info info = { }; 290*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 291b0104773SPascal Brand 2926915bbbbSJens Wiklander __utee_check_attr_in_annotation(attrs, attrCount); 2936915bbbbSJens Wiklander 2942c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 295b0104773SPascal Brand if (res != TEE_SUCCESS) 296b36311adSJerome Forissier TEE_Panic(res); 297b0104773SPascal Brand 298b0104773SPascal Brand /* Must be a transient object */ 299*75d6a373SJens Wiklander if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 300b0104773SPascal Brand TEE_Panic(0); 301b0104773SPascal Brand 302b0104773SPascal Brand /* Must not be initialized already */ 303*75d6a373SJens Wiklander if ((info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 304b0104773SPascal Brand TEE_Panic(0); 305b0104773SPascal Brand 306e86f1266SJens Wiklander __utee_from_attr(ua, attrs, attrCount); 3072c028fdeSJerome Forissier res = _utee_cryp_obj_populate((unsigned long)object, ua, attrCount); 308b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 309b0104773SPascal Brand TEE_Panic(res); 310b0104773SPascal Brand return res; 311b0104773SPascal Brand } 312b0104773SPascal Brand 313b0104773SPascal Brand void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID, 3148f07fe6fSJerome Forissier const void *buffer, uint32_t length) 315b0104773SPascal Brand { 3166915bbbbSJens Wiklander __utee_check_out_annotation(attr, sizeof(*attr)); 3176915bbbbSJens Wiklander 318b9416909SJens Wiklander if ((attributeID & TEE_ATTR_FLAG_VALUE) != 0) 319b0104773SPascal Brand TEE_Panic(0); 320b0104773SPascal Brand attr->attributeID = attributeID; 3218f07fe6fSJerome Forissier attr->content.ref.buffer = (void *)buffer; 322b0104773SPascal Brand attr->content.ref.length = length; 323b0104773SPascal Brand } 324b0104773SPascal Brand 325b0104773SPascal Brand void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, 326b0104773SPascal Brand uint32_t a, uint32_t b) 327b0104773SPascal Brand { 3286915bbbbSJens Wiklander __utee_check_out_annotation(attr, sizeof(*attr)); 3296915bbbbSJens Wiklander 330b9416909SJens Wiklander if ((attributeID & TEE_ATTR_FLAG_VALUE) == 0) 331b0104773SPascal Brand TEE_Panic(0); 332b0104773SPascal Brand attr->attributeID = attributeID; 333b0104773SPascal Brand attr->content.value.a = a; 334b0104773SPascal Brand attr->content.value.b = b; 335b0104773SPascal Brand } 336b0104773SPascal Brand 3377583c59eSCedric Chaumont /* 3387583c59eSCedric Chaumont * Use of this function is deprecated 3397583c59eSCedric Chaumont * new code SHOULD use the TEE_CopyObjectAttributes1 function instead 3407583c59eSCedric Chaumont * These functions will be removed at some future major revision of 3417583c59eSCedric Chaumont * this specification 3427583c59eSCedric Chaumont */ 343b0104773SPascal Brand void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, 344b0104773SPascal Brand TEE_ObjectHandle srcObject) 345b0104773SPascal Brand { 346*75d6a373SJens Wiklander struct utee_object_info src_info = { }; 347*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 3487583c59eSCedric Chaumont 3492c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 350*75d6a373SJens Wiklander if (src_info.obj_type == TEE_TYPE_CORRUPTED_OBJECT) 3517583c59eSCedric Chaumont return; 3527583c59eSCedric Chaumont 3537583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(destObject, srcObject); 3547583c59eSCedric Chaumont if (res != TEE_SUCCESS) 355b36311adSJerome Forissier TEE_Panic(res); 3567583c59eSCedric Chaumont } 3577583c59eSCedric Chaumont 3587583c59eSCedric Chaumont TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject, 3597583c59eSCedric Chaumont TEE_ObjectHandle srcObject) 3607583c59eSCedric Chaumont { 361*75d6a373SJens Wiklander struct utee_object_info dst_info = { }; 362*75d6a373SJens Wiklander struct utee_object_info src_info = { }; 363*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 364b0104773SPascal Brand 3652c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)destObject, &dst_info); 366b0104773SPascal Brand if (res != TEE_SUCCESS) 367a2e9a830SCedric Chaumont goto exit; 368b0104773SPascal Brand 3692c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 370b0104773SPascal Brand if (res != TEE_SUCCESS) 371a2e9a830SCedric Chaumont goto exit; 372b0104773SPascal Brand 373*75d6a373SJens Wiklander if (!(src_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED)) 374b0104773SPascal Brand TEE_Panic(0); 375a2e9a830SCedric Chaumont 376*75d6a373SJens Wiklander if ((dst_info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT)) 377b0104773SPascal Brand TEE_Panic(0); 378a2e9a830SCedric Chaumont 379*75d6a373SJens Wiklander if ((dst_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED)) 380b0104773SPascal Brand TEE_Panic(0); 381b0104773SPascal Brand 3822c028fdeSJerome Forissier res = _utee_cryp_obj_copy((unsigned long)destObject, 383e86f1266SJens Wiklander (unsigned long)srcObject); 3847583c59eSCedric Chaumont 385a2e9a830SCedric Chaumont exit: 386a2e9a830SCedric Chaumont if (res != TEE_SUCCESS && 387a2e9a830SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 388a2e9a830SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 389a2e9a830SCedric Chaumont TEE_Panic(res); 3907583c59eSCedric Chaumont 3917583c59eSCedric Chaumont return res; 392b0104773SPascal Brand } 393b0104773SPascal Brand 394b0104773SPascal Brand TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 3958f07fe6fSJerome Forissier const TEE_Attribute *params, uint32_t paramCount) 396b0104773SPascal Brand { 397b0104773SPascal Brand TEE_Result res; 398e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 399b0104773SPascal Brand 4006915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 4016915bbbbSJens Wiklander 402e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 4032c028fdeSJerome Forissier res = _utee_cryp_obj_generate_key((unsigned long)object, keySize, 404e86f1266SJens Wiklander ua, paramCount); 405b0104773SPascal Brand 406aeb0d927SCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 407b36311adSJerome Forissier TEE_Panic(res); 408b0104773SPascal Brand 409b0104773SPascal Brand return res; 410b0104773SPascal Brand } 411b0104773SPascal Brand 412b0104773SPascal Brand /* Data and Key Storage API - Persistent Object Functions */ 413b0104773SPascal Brand 4148f07fe6fSJerome Forissier TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, 41579a3c601SCedric Chaumont uint32_t objectIDLen, uint32_t flags, 416b0104773SPascal Brand TEE_ObjectHandle *object) 417b0104773SPascal Brand { 4189b520646SCedric Chaumont TEE_Result res; 419e86f1266SJens Wiklander uint32_t obj; 420b0104773SPascal Brand 4212138a6f8SStefan Schmidt __utee_check_out_annotation(object, sizeof(*object)); 4222138a6f8SStefan Schmidt 4232c028fdeSJerome Forissier res = _utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 424e86f1266SJens Wiklander &obj); 425e86f1266SJens Wiklander if (res == TEE_SUCCESS) 426e86f1266SJens Wiklander *object = (TEE_ObjectHandle)(uintptr_t)obj; 4279b520646SCedric Chaumont 4289b520646SCedric Chaumont if (res != TEE_SUCCESS && 4299b520646SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 4309b520646SCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT && 4319b520646SCedric Chaumont res != TEE_ERROR_OUT_OF_MEMORY && 4329b520646SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 4339b520646SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 434b36311adSJerome Forissier TEE_Panic(res); 435b0104773SPascal Brand 436172d637bSCedric Auger if (res != TEE_SUCCESS) 43769a3d6beSDaniel Glöckner *object = TEE_HANDLE_NULL; 43869a3d6beSDaniel Glöckner 4399b520646SCedric Chaumont return res; 440b0104773SPascal Brand } 441b0104773SPascal Brand 4428f07fe6fSJerome Forissier TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, 44379a3c601SCedric Chaumont uint32_t objectIDLen, uint32_t flags, 444b0104773SPascal Brand TEE_ObjectHandle attributes, 445b0104773SPascal Brand const void *initialData, 44679a3c601SCedric Chaumont uint32_t initialDataLen, 447b0104773SPascal Brand TEE_ObjectHandle *object) 448b0104773SPascal Brand { 44984431ae3SCedric Chaumont TEE_Result res; 450e86f1266SJens Wiklander uint32_t obj; 451b0104773SPascal Brand 4526915bbbbSJens Wiklander __utee_check_out_annotation(object, sizeof(*object)); 453b0104773SPascal Brand 4542c028fdeSJerome Forissier res = _utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 455e86f1266SJens Wiklander (unsigned long)attributes, initialData, 456e86f1266SJens Wiklander initialDataLen, &obj); 457172d637bSCedric Auger 4581c96fa7fSPascal Brand if (res == TEE_SUCCESS) 459172d637bSCedric Auger *object = (TEE_ObjectHandle)(uintptr_t)obj; 460172d637bSCedric Auger 461172d637bSCedric Auger if (res != TEE_SUCCESS && 462172d637bSCedric Auger res != TEE_ERROR_ITEM_NOT_FOUND && 463172d637bSCedric Auger res != TEE_ERROR_ACCESS_CONFLICT && 464172d637bSCedric Auger res != TEE_ERROR_OUT_OF_MEMORY && 465172d637bSCedric Auger res != TEE_ERROR_STORAGE_NO_SPACE && 466172d637bSCedric Auger res != TEE_ERROR_CORRUPT_OBJECT && 467172d637bSCedric Auger res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 468b36311adSJerome Forissier TEE_Panic(res); 469172d637bSCedric Auger 470172d637bSCedric Auger if (res != TEE_SUCCESS) 471172d637bSCedric Auger *object = TEE_HANDLE_NULL; 472172d637bSCedric Auger 473172d637bSCedric Auger return res; 474b0104773SPascal Brand } 475b0104773SPascal Brand 4767583c59eSCedric Chaumont /* 4777583c59eSCedric Chaumont * Use of this function is deprecated 4787583c59eSCedric Chaumont * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead 4797583c59eSCedric Chaumont * These functions will be removed at some future major revision of 4807583c59eSCedric Chaumont * this specification 4817583c59eSCedric Chaumont */ 482b0104773SPascal Brand void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 483b0104773SPascal Brand { 484b0104773SPascal Brand TEE_Result res; 485b0104773SPascal Brand 486b0104773SPascal Brand if (object == TEE_HANDLE_NULL) 487b0104773SPascal Brand return; 488b0104773SPascal Brand 4897583c59eSCedric Chaumont res = TEE_CloseAndDeletePersistentObject1(object); 490b0104773SPascal Brand 491b0104773SPascal Brand if (res != TEE_SUCCESS) 492b0104773SPascal Brand TEE_Panic(0); 493b0104773SPascal Brand } 494b0104773SPascal Brand 4957583c59eSCedric Chaumont TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object) 4967583c59eSCedric Chaumont { 4977583c59eSCedric Chaumont TEE_Result res; 4987583c59eSCedric Chaumont 4997583c59eSCedric Chaumont if (object == TEE_HANDLE_NULL) 50046cfd17cSJens Wiklander return TEE_SUCCESS; 5017583c59eSCedric Chaumont 5022c028fdeSJerome Forissier res = _utee_storage_obj_del((unsigned long)object); 5037583c59eSCedric Chaumont 5047583c59eSCedric Chaumont if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 505b36311adSJerome Forissier TEE_Panic(res); 5067583c59eSCedric Chaumont 5077583c59eSCedric Chaumont return res; 5087583c59eSCedric Chaumont } 5097583c59eSCedric Chaumont 5107583c59eSCedric Chaumont 511b0104773SPascal Brand TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 512b0104773SPascal Brand const void *newObjectID, 51379a3c601SCedric Chaumont uint32_t newObjectIDLen) 514b0104773SPascal Brand { 515b0104773SPascal Brand TEE_Result res; 516b0104773SPascal Brand 517a76bf53fSCedric Chaumont if (object == TEE_HANDLE_NULL) { 518a76bf53fSCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 519a76bf53fSCedric Chaumont goto out; 520a76bf53fSCedric Chaumont } 521b0104773SPascal Brand 5222c028fdeSJerome Forissier res = _utee_storage_obj_rename((unsigned long)object, newObjectID, 523e86f1266SJens Wiklander newObjectIDLen); 524b0104773SPascal Brand 525a76bf53fSCedric Chaumont out: 526a76bf53fSCedric Chaumont if (res != TEE_SUCCESS && 527a76bf53fSCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT && 528a76bf53fSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 529a76bf53fSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 530b36311adSJerome Forissier TEE_Panic(res); 531b0104773SPascal Brand 532b0104773SPascal Brand return res; 533b0104773SPascal Brand } 534b0104773SPascal Brand 535b0104773SPascal Brand TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 536b0104773SPascal Brand objectEnumerator) 537b0104773SPascal Brand { 538b0104773SPascal Brand TEE_Result res; 539e86f1266SJens Wiklander uint32_t oe; 540b0104773SPascal Brand 5416915bbbbSJens Wiklander __utee_check_out_annotation(objectEnumerator, 5426915bbbbSJens Wiklander sizeof(*objectEnumerator)); 543b0104773SPascal Brand 5442c028fdeSJerome Forissier res = _utee_storage_alloc_enum(&oe); 545b0104773SPascal Brand 546b0104773SPascal Brand if (res != TEE_SUCCESS) 547e86f1266SJens Wiklander oe = TEE_HANDLE_NULL; 548e86f1266SJens Wiklander 549e86f1266SJens Wiklander *objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe; 550b0104773SPascal Brand 55115cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 55215cd3c30SCedric Chaumont res != TEE_ERROR_ACCESS_CONFLICT) 553b36311adSJerome Forissier TEE_Panic(res); 55415cd3c30SCedric Chaumont 555b0104773SPascal Brand return res; 556b0104773SPascal Brand } 557b0104773SPascal Brand 558b0104773SPascal Brand void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 559b0104773SPascal Brand { 560b0104773SPascal Brand TEE_Result res; 561b0104773SPascal Brand 562b0104773SPascal Brand if (objectEnumerator == TEE_HANDLE_NULL) 563b0104773SPascal Brand return; 564b0104773SPascal Brand 5652c028fdeSJerome Forissier res = _utee_storage_free_enum((unsigned long)objectEnumerator); 566b0104773SPascal Brand 567b0104773SPascal Brand if (res != TEE_SUCCESS) 568b36311adSJerome Forissier TEE_Panic(res); 569b0104773SPascal Brand } 570b0104773SPascal Brand 571b0104773SPascal Brand void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 572b0104773SPascal Brand { 573b0104773SPascal Brand TEE_Result res; 574b0104773SPascal Brand 575b0104773SPascal Brand if (objectEnumerator == TEE_HANDLE_NULL) 576b0104773SPascal Brand return; 577b0104773SPascal Brand 5782c028fdeSJerome Forissier res = _utee_storage_reset_enum((unsigned long)objectEnumerator); 579b0104773SPascal Brand 580b0104773SPascal Brand if (res != TEE_SUCCESS) 581b36311adSJerome Forissier TEE_Panic(res); 582b0104773SPascal Brand } 583b0104773SPascal Brand 584b0104773SPascal Brand TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 585b0104773SPascal Brand objectEnumerator, 586b0104773SPascal Brand uint32_t storageID) 587b0104773SPascal Brand { 588b0104773SPascal Brand TEE_Result res; 589b0104773SPascal Brand 5902c028fdeSJerome Forissier res = _utee_storage_start_enum((unsigned long)objectEnumerator, 591e86f1266SJens Wiklander storageID); 592b0104773SPascal Brand 59315cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 59415cd3c30SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 59515cd3c30SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 59615cd3c30SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 597b36311adSJerome Forissier TEE_Panic(res); 598b0104773SPascal Brand 599b0104773SPascal Brand return res; 600b0104773SPascal Brand } 601b0104773SPascal Brand 602b0104773SPascal Brand TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, 603b0104773SPascal Brand TEE_ObjectInfo *objectInfo, 60479a3c601SCedric Chaumont void *objectID, uint32_t *objectIDLen) 605b0104773SPascal Brand { 606*75d6a373SJens Wiklander struct utee_object_info info = { }; 607*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 608*75d6a373SJens Wiklander uint64_t len = 0; 609b0104773SPascal Brand 6106915bbbbSJens Wiklander if (objectInfo) 6116915bbbbSJens Wiklander __utee_check_out_annotation(objectInfo, sizeof(*objectInfo)); 6126915bbbbSJens Wiklander __utee_check_out_annotation(objectIDLen, sizeof(*objectIDLen)); 61315cd3c30SCedric Chaumont 6146915bbbbSJens Wiklander if (!objectID) { 61515cd3c30SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 61615cd3c30SCedric Chaumont goto out; 61715cd3c30SCedric Chaumont } 61815cd3c30SCedric Chaumont 619e86f1266SJens Wiklander len = *objectIDLen; 6202c028fdeSJerome Forissier res = _utee_storage_next_enum((unsigned long)objectEnumerator, 621*75d6a373SJens Wiklander &info, objectID, &len); 622*75d6a373SJens Wiklander if (objectInfo) { 623*75d6a373SJens Wiklander objectInfo->objectType = info.obj_type; 624*75d6a373SJens Wiklander objectInfo->keySize = info.obj_size; 625*75d6a373SJens Wiklander objectInfo->maxKeySize = info.max_obj_size; 626*75d6a373SJens Wiklander objectInfo->objectUsage = info.obj_usage; 627*75d6a373SJens Wiklander objectInfo->dataSize = info.data_size; 628*75d6a373SJens Wiklander objectInfo->dataPosition = info.data_pos; 629*75d6a373SJens Wiklander objectInfo->handleFlags = info.handle_flags; 630*75d6a373SJens Wiklander } 631e86f1266SJens Wiklander *objectIDLen = len; 632b0104773SPascal Brand 63315cd3c30SCedric Chaumont out: 63415cd3c30SCedric Chaumont if (res != TEE_SUCCESS && 63515cd3c30SCedric Chaumont res != TEE_ERROR_ITEM_NOT_FOUND && 63615cd3c30SCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 63715cd3c30SCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 638b36311adSJerome Forissier TEE_Panic(res); 639b0104773SPascal Brand 640b0104773SPascal Brand return res; 641b0104773SPascal Brand } 642b0104773SPascal Brand 643b0104773SPascal Brand /* Data and Key Storage API - Data Stream Access Functions */ 644b0104773SPascal Brand 645b0104773SPascal Brand TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 64679a3c601SCedric Chaumont uint32_t size, uint32_t *count) 647b0104773SPascal Brand { 648b0104773SPascal Brand TEE_Result res; 649e86f1266SJens Wiklander uint64_t cnt64; 650b0104773SPascal Brand 651ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 652ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 653ae1289baSCedric Chaumont goto out; 654ae1289baSCedric Chaumont } 6556915bbbbSJens Wiklander __utee_check_out_annotation(count, sizeof(*count)); 656b0104773SPascal Brand 657e86f1266SJens Wiklander cnt64 = *count; 6582c028fdeSJerome Forissier res = _utee_storage_obj_read((unsigned long)object, buffer, size, 659e86f1266SJens Wiklander &cnt64); 660e86f1266SJens Wiklander *count = cnt64; 661b0104773SPascal Brand 662ae1289baSCedric Chaumont out: 663ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 664ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 665ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 666b36311adSJerome Forissier TEE_Panic(res); 667b0104773SPascal Brand 668b0104773SPascal Brand return res; 669b0104773SPascal Brand } 670b0104773SPascal Brand 6718f07fe6fSJerome Forissier TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, 67279a3c601SCedric Chaumont uint32_t size) 673b0104773SPascal Brand { 674b0104773SPascal Brand TEE_Result res; 675b0104773SPascal Brand 676ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 677ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 678ae1289baSCedric Chaumont goto out; 679ae1289baSCedric Chaumont } 680ae1289baSCedric Chaumont 681ae1289baSCedric Chaumont if (size > TEE_DATA_MAX_POSITION) { 682ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 683ae1289baSCedric Chaumont goto out; 684ae1289baSCedric Chaumont } 685b0104773SPascal Brand 6862c028fdeSJerome Forissier res = _utee_storage_obj_write((unsigned long)object, buffer, size); 687b0104773SPascal Brand 688ae1289baSCedric Chaumont out: 689ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 690ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE && 691ae1289baSCedric Chaumont res != TEE_ERROR_OVERFLOW && 692ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 693ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 694b36311adSJerome Forissier TEE_Panic(res); 695b0104773SPascal Brand 696b0104773SPascal Brand return res; 697b0104773SPascal Brand } 698b0104773SPascal Brand 699b0104773SPascal Brand TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 700b0104773SPascal Brand { 701b0104773SPascal Brand TEE_Result res; 702b0104773SPascal Brand 703ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 704ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 705ae1289baSCedric Chaumont goto out; 706ae1289baSCedric Chaumont } 707b0104773SPascal Brand 7082c028fdeSJerome Forissier res = _utee_storage_obj_trunc((unsigned long)object, size); 709b0104773SPascal Brand 710ae1289baSCedric Chaumont out: 711ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 712ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NO_SPACE && 713ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 714ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 715b36311adSJerome Forissier TEE_Panic(res); 716b0104773SPascal Brand 717b0104773SPascal Brand return res; 718b0104773SPascal Brand } 719b0104773SPascal Brand 720b0104773SPascal Brand TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 721b0104773SPascal Brand TEE_Whence whence) 722b0104773SPascal Brand { 723*75d6a373SJens Wiklander struct utee_object_info info = { }; 724*75d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 725b0104773SPascal Brand 726ae1289baSCedric Chaumont if (object == TEE_HANDLE_NULL) { 727ae1289baSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 728ae1289baSCedric Chaumont goto out; 729ae1289baSCedric Chaumont } 730b0104773SPascal Brand 7312c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)object, &info); 732b0104773SPascal Brand if (res != TEE_SUCCESS) 733ae1289baSCedric Chaumont goto out; 734b0104773SPascal Brand 735b0104773SPascal Brand switch (whence) { 736b0104773SPascal Brand case TEE_DATA_SEEK_SET: 737ae1289baSCedric Chaumont if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) { 738ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 739ae1289baSCedric Chaumont goto out; 740ae1289baSCedric Chaumont } 741b0104773SPascal Brand break; 742b0104773SPascal Brand case TEE_DATA_SEEK_CUR: 743b0104773SPascal Brand if (offset > 0 && 744*75d6a373SJens Wiklander ((uint32_t)offset + info.data_pos > TEE_DATA_MAX_POSITION || 745*75d6a373SJens Wiklander (uint32_t)offset + info.data_pos < info.data_pos)) { 746ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 747ae1289baSCedric Chaumont goto out; 748ae1289baSCedric Chaumont } 749b0104773SPascal Brand break; 750b0104773SPascal Brand case TEE_DATA_SEEK_END: 751b0104773SPascal Brand if (offset > 0 && 752*75d6a373SJens Wiklander ((uint32_t)offset + info.data_size > 753*75d6a373SJens Wiklander TEE_DATA_MAX_POSITION || 754*75d6a373SJens Wiklander (uint32_t)offset + info.data_size < info.data_size)) { 755ae1289baSCedric Chaumont res = TEE_ERROR_OVERFLOW; 756ae1289baSCedric Chaumont goto out; 757ae1289baSCedric Chaumont } 758b0104773SPascal Brand break; 759b0104773SPascal Brand default: 760ae1289baSCedric Chaumont res = TEE_ERROR_ITEM_NOT_FOUND; 761ae1289baSCedric Chaumont goto out; 762b0104773SPascal Brand } 763b0104773SPascal Brand 7642c028fdeSJerome Forissier res = _utee_storage_obj_seek((unsigned long)object, offset, whence); 765b0104773SPascal Brand 766ae1289baSCedric Chaumont out: 767ae1289baSCedric Chaumont if (res != TEE_SUCCESS && 768ae1289baSCedric Chaumont res != TEE_ERROR_OVERFLOW && 769ae1289baSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 770ae1289baSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 771b36311adSJerome Forissier TEE_Panic(res); 772b0104773SPascal Brand 773b0104773SPascal Brand return res; 774b0104773SPascal Brand } 775