xref: /optee_os/lib/libutee/tee_api_objects.c (revision 4f4374c8555bb3308d5d646b41df5e53c52ee7e5)
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 
31*4f4374c8SJens Wiklander void __utee_from_gp11_attr(struct utee_attribute *ua,
32*4f4374c8SJens Wiklander 			   const __GP11_TEE_Attribute *attrs,
33*4f4374c8SJens Wiklander 			   uint32_t attr_count)
34*4f4374c8SJens Wiklander {
35*4f4374c8SJens Wiklander 	size_t n = 0;
36*4f4374c8SJens Wiklander 
37*4f4374c8SJens Wiklander 	for (n = 0; n < attr_count; n++) {
38*4f4374c8SJens Wiklander 		ua[n].attribute_id = attrs[n].attributeID;
39*4f4374c8SJens Wiklander 		if (attrs[n].attributeID & TEE_ATTR_FLAG_VALUE) {
40*4f4374c8SJens Wiklander 			ua[n].a = attrs[n].content.value.a;
41*4f4374c8SJens Wiklander 			ua[n].b = attrs[n].content.value.b;
42*4f4374c8SJens Wiklander 		} else {
43*4f4374c8SJens Wiklander 			ua[n].a = (uintptr_t)attrs[n].content.ref.buffer;
44*4f4374c8SJens Wiklander 			ua[n].b = attrs[n].content.ref.length;
45*4f4374c8SJens Wiklander 		}
46*4f4374c8SJens Wiklander 	}
47*4f4374c8SJens Wiklander }
48*4f4374c8SJens Wiklander 
49b0104773SPascal Brand /* Data and Key Storage API  - Generic Object Functions */
507583c59eSCedric Chaumont /*
517583c59eSCedric Chaumont  * Use of this function is deprecated
527583c59eSCedric Chaumont  * new code SHOULD use the TEE_GetObjectInfo1 function instead
537583c59eSCedric Chaumont  * These functions will be removed at some future major revision of
547583c59eSCedric Chaumont  * this specification
557583c59eSCedric Chaumont  */
56b0104773SPascal Brand void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
57b0104773SPascal Brand {
5875d6a373SJens Wiklander 	struct utee_object_info info = { };
5975d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
60b0104773SPascal Brand 
6175d6a373SJens Wiklander 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
627583c59eSCedric Chaumont 
63b0104773SPascal Brand 	if (res != TEE_SUCCESS)
64b0104773SPascal Brand 		TEE_Panic(res);
657583c59eSCedric Chaumont 
6675d6a373SJens Wiklander 	if (info.obj_type == TEE_TYPE_CORRUPTED_OBJECT) {
67d372a47cSJens Wiklander 		objectInfo->objectSize = 0;
68d372a47cSJens Wiklander 		objectInfo->maxObjectSize = 0;
69d372a47cSJens Wiklander 		objectInfo->objectUsage = 0;
70d372a47cSJens Wiklander 		objectInfo->dataSize = 0;
71d372a47cSJens Wiklander 		objectInfo->dataPosition = 0;
72d372a47cSJens Wiklander 		objectInfo->handleFlags = 0;
73d372a47cSJens Wiklander 	} else {
74d372a47cSJens Wiklander 		objectInfo->objectType = info.obj_type;
75d372a47cSJens Wiklander 		objectInfo->objectSize = info.obj_size;
76d372a47cSJens Wiklander 		objectInfo->maxObjectSize = info.max_obj_size;
77d372a47cSJens Wiklander 		objectInfo->objectUsage = info.obj_usage;
78d372a47cSJens Wiklander 		objectInfo->dataSize = info.data_size;
79d372a47cSJens Wiklander 		objectInfo->dataPosition = info.data_pos;
80d372a47cSJens Wiklander 		objectInfo->handleFlags = info.handle_flags;
81d372a47cSJens Wiklander 	}
82d372a47cSJens Wiklander }
83d372a47cSJens Wiklander 
84d372a47cSJens Wiklander void __GP11_TEE_GetObjectInfo(TEE_ObjectHandle object,
85d372a47cSJens Wiklander 			      __GP11_TEE_ObjectInfo *objectInfo)
86d372a47cSJens Wiklander {
87d372a47cSJens Wiklander 	struct utee_object_info info = { };
88d372a47cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
89d372a47cSJens Wiklander 
90d372a47cSJens Wiklander 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
91d372a47cSJens Wiklander 
92d372a47cSJens Wiklander 	if (res != TEE_SUCCESS)
93d372a47cSJens Wiklander 		TEE_Panic(res);
94d372a47cSJens Wiklander 
95d372a47cSJens Wiklander 	if (info.obj_type == TEE_TYPE_CORRUPTED_OBJECT) {
967583c59eSCedric Chaumont 		objectInfo->keySize = 0;
977583c59eSCedric Chaumont 		objectInfo->maxKeySize = 0;
987583c59eSCedric Chaumont 		objectInfo->objectUsage = 0;
997583c59eSCedric Chaumont 		objectInfo->dataSize = 0;
1007583c59eSCedric Chaumont 		objectInfo->dataPosition = 0;
1017583c59eSCedric Chaumont 		objectInfo->handleFlags = 0;
10275d6a373SJens Wiklander 	} else {
10375d6a373SJens Wiklander 		objectInfo->objectType = info.obj_type;
10475d6a373SJens Wiklander 		objectInfo->keySize = info.obj_size;
10575d6a373SJens Wiklander 		objectInfo->maxKeySize = info.max_obj_size;
10675d6a373SJens Wiklander 		objectInfo->objectUsage = info.obj_usage;
10775d6a373SJens Wiklander 		objectInfo->dataSize = info.data_size;
10875d6a373SJens Wiklander 		objectInfo->dataPosition = info.data_pos;
10975d6a373SJens Wiklander 		objectInfo->handleFlags = info.handle_flags;
1107583c59eSCedric Chaumont 	}
111b0104773SPascal Brand }
112b0104773SPascal Brand 
113d372a47cSJens Wiklander TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object,
114d372a47cSJens Wiklander 			      TEE_ObjectInfo *objectInfo)
115d372a47cSJens Wiklander {
116d372a47cSJens Wiklander 	struct utee_object_info info = { };
117d372a47cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
118d372a47cSJens Wiklander 
119d372a47cSJens Wiklander 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
120d372a47cSJens Wiklander 
121d372a47cSJens Wiklander 	if (res != TEE_SUCCESS &&
122d372a47cSJens Wiklander 	    res != TEE_ERROR_CORRUPT_OBJECT &&
123d372a47cSJens Wiklander 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
124d372a47cSJens Wiklander 		TEE_Panic(res);
125d372a47cSJens Wiklander 
126d372a47cSJens Wiklander 	objectInfo->objectType = info.obj_type;
127d372a47cSJens Wiklander 	objectInfo->objectSize = info.obj_size;
128d372a47cSJens Wiklander 	objectInfo->maxObjectSize = info.max_obj_size;
129d372a47cSJens Wiklander 	objectInfo->objectUsage = info.obj_usage;
130d372a47cSJens Wiklander 	objectInfo->dataSize = info.data_size;
131d372a47cSJens Wiklander 	objectInfo->dataPosition = info.data_pos;
132d372a47cSJens Wiklander 	objectInfo->handleFlags = info.handle_flags;
133d372a47cSJens Wiklander 
134d372a47cSJens Wiklander 	return res;
135d372a47cSJens Wiklander }
136d372a47cSJens Wiklander 
137d372a47cSJens Wiklander TEE_Result __GP11_TEE_GetObjectInfo1(TEE_ObjectHandle object,
138d372a47cSJens Wiklander 				     __GP11_TEE_ObjectInfo *objectInfo)
1397583c59eSCedric Chaumont {
14075d6a373SJens Wiklander 	struct utee_object_info info = { };
14175d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
1427583c59eSCedric Chaumont 
14375d6a373SJens Wiklander 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
1447583c59eSCedric Chaumont 
145a2e9a830SCedric Chaumont 	if (res != TEE_SUCCESS &&
146a2e9a830SCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
147a2e9a830SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
1487583c59eSCedric Chaumont 		TEE_Panic(res);
1497583c59eSCedric Chaumont 
15075d6a373SJens Wiklander 	objectInfo->objectType = info.obj_type;
15175d6a373SJens Wiklander 	objectInfo->keySize = info.obj_size;
15275d6a373SJens Wiklander 	objectInfo->maxKeySize = info.max_obj_size;
15375d6a373SJens Wiklander 	objectInfo->objectUsage = info.obj_usage;
15475d6a373SJens Wiklander 	objectInfo->dataSize = info.data_size;
15575d6a373SJens Wiklander 	objectInfo->dataPosition = info.data_pos;
15675d6a373SJens Wiklander 	objectInfo->handleFlags = info.handle_flags;
15775d6a373SJens Wiklander 
1587583c59eSCedric Chaumont 	return res;
1597583c59eSCedric Chaumont }
1607583c59eSCedric Chaumont 
1617583c59eSCedric Chaumont /*
1627583c59eSCedric Chaumont  * Use of this function is deprecated
1637583c59eSCedric Chaumont  * new code SHOULD use the TEE_RestrictObjectUsage1 function instead
1647583c59eSCedric Chaumont  * These functions will be removed at some future major revision of
1657583c59eSCedric Chaumont  * this specification
1667583c59eSCedric Chaumont  */
167b0104773SPascal Brand void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage)
168b0104773SPascal Brand {
16975d6a373SJens Wiklander 	struct utee_object_info info = { };
17075d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
1717583c59eSCedric Chaumont 
17275d6a373SJens Wiklander 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
17375d6a373SJens Wiklander 	if (info.obj_type == TEE_TYPE_CORRUPTED_OBJECT)
1747583c59eSCedric Chaumont 		return;
1757583c59eSCedric Chaumont 
1767583c59eSCedric Chaumont 	res = TEE_RestrictObjectUsage1(object, objectUsage);
177b0104773SPascal Brand 
178b0104773SPascal Brand 	if (res != TEE_SUCCESS)
179b36311adSJerome Forissier 		TEE_Panic(res);
180b0104773SPascal Brand }
181b0104773SPascal Brand 
1827583c59eSCedric Chaumont TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage)
1837583c59eSCedric Chaumont {
1847583c59eSCedric Chaumont 	TEE_Result res;
1857583c59eSCedric Chaumont 
1862c028fdeSJerome Forissier 	res = _utee_cryp_obj_restrict_usage((unsigned long)object,
1872c028fdeSJerome Forissier 					    objectUsage);
1887583c59eSCedric Chaumont 
189a2e9a830SCedric Chaumont 	if (res != TEE_SUCCESS &&
190a2e9a830SCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
191a2e9a830SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
192a2e9a830SCedric Chaumont 		TEE_Panic(res);
1937583c59eSCedric Chaumont 
1947583c59eSCedric Chaumont 	return res;
1957583c59eSCedric Chaumont }
1967583c59eSCedric Chaumont 
197b0104773SPascal Brand TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
198b0104773SPascal Brand 					uint32_t attributeID, void *buffer,
19979a3c601SCedric Chaumont 					uint32_t *size)
200b0104773SPascal Brand {
20175d6a373SJens Wiklander 	struct utee_object_info info = { };
20275d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
20375d6a373SJens Wiklander 	uint64_t sz = 0;
204b0104773SPascal Brand 
2056915bbbbSJens Wiklander 	__utee_check_inout_annotation(size, sizeof(*size));
2066915bbbbSJens Wiklander 
2072c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
208b0104773SPascal Brand 	if (res != TEE_SUCCESS)
209a2e9a830SCedric Chaumont 		goto exit;
210b0104773SPascal Brand 
211b0104773SPascal Brand 	/* This function only supports reference attributes */
212b9416909SJens Wiklander 	if ((attributeID & TEE_ATTR_FLAG_VALUE)) {
213a2e9a830SCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
214a2e9a830SCedric Chaumont 		goto exit;
215a2e9a830SCedric Chaumont 	}
216b0104773SPascal Brand 
217e86f1266SJens Wiklander 	sz = *size;
2182c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID,
219e86f1266SJens Wiklander 				      buffer, &sz);
220e86f1266SJens Wiklander 	*size = sz;
221b0104773SPascal Brand 
222a2e9a830SCedric Chaumont exit:
2230ed6a6caSCedric Chaumont 	if (res != TEE_SUCCESS &&
2240ed6a6caSCedric Chaumont 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
2250ed6a6caSCedric Chaumont 	    res != TEE_ERROR_SHORT_BUFFER &&
2260ed6a6caSCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
2270ed6a6caSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
228b36311adSJerome Forissier 		TEE_Panic(res);
229b0104773SPascal Brand 
230b0104773SPascal Brand 	return res;
231b0104773SPascal Brand }
232b0104773SPascal Brand 
233b0104773SPascal Brand TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
234b0104773SPascal Brand 				       uint32_t attributeID, uint32_t *a,
235b0104773SPascal Brand 				       uint32_t *b)
236b0104773SPascal Brand {
23775d6a373SJens Wiklander 	struct utee_object_info info = { };
23875d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
239b0104773SPascal Brand 	uint32_t buf[2];
240e86f1266SJens Wiklander 	uint64_t size = sizeof(buf);
241b0104773SPascal Brand 
2426915bbbbSJens Wiklander 	if (a)
2436915bbbbSJens Wiklander 		__utee_check_out_annotation(a, sizeof(*a));
2446915bbbbSJens Wiklander 	if (b)
2456915bbbbSJens Wiklander 		__utee_check_out_annotation(b, sizeof(*b));
2466915bbbbSJens Wiklander 
2472c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
248b0104773SPascal Brand 	if (res != TEE_SUCCESS)
249a2e9a830SCedric Chaumont 		goto exit;
250b0104773SPascal Brand 
251b0104773SPascal Brand 	/* This function only supports value attributes */
252b9416909SJens Wiklander 	if (!(attributeID & TEE_ATTR_FLAG_VALUE)) {
253a2e9a830SCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
254a2e9a830SCedric Chaumont 		goto exit;
255a2e9a830SCedric Chaumont 	}
256b0104773SPascal Brand 
2572c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf,
258e86f1266SJens Wiklander 				      &size);
259b0104773SPascal Brand 
260a2e9a830SCedric Chaumont exit:
2610ed6a6caSCedric Chaumont 	if (res != TEE_SUCCESS &&
2620ed6a6caSCedric Chaumont 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
2630ed6a6caSCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
2640ed6a6caSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
265b36311adSJerome Forissier 		TEE_Panic(res);
266b0104773SPascal Brand 
267b0104773SPascal Brand 	if (size != sizeof(buf))
268b0104773SPascal Brand 		TEE_Panic(0);
269b0104773SPascal Brand 
270be96c837SJerome Forissier 	if (res == TEE_SUCCESS) {
271b9d8f134SJerome Forissier 		if (a)
272b0104773SPascal Brand 			*a = buf[0];
273b9d8f134SJerome Forissier 		if (b)
274b0104773SPascal Brand 			*b = buf[1];
275be96c837SJerome Forissier 	}
276b0104773SPascal Brand 
277b0104773SPascal Brand 	return res;
278b0104773SPascal Brand }
279b0104773SPascal Brand 
280b0104773SPascal Brand void TEE_CloseObject(TEE_ObjectHandle object)
281b0104773SPascal Brand {
282b0104773SPascal Brand 	TEE_Result res;
283b0104773SPascal Brand 
284b0104773SPascal Brand 	if (object == TEE_HANDLE_NULL)
285b0104773SPascal Brand 		return;
286b0104773SPascal Brand 
2872c028fdeSJerome Forissier 	res = _utee_cryp_obj_close((unsigned long)object);
288b0104773SPascal Brand 	if (res != TEE_SUCCESS)
289b36311adSJerome Forissier 		TEE_Panic(res);
290b0104773SPascal Brand }
291b0104773SPascal Brand 
292b0104773SPascal Brand /* Data and Key Storage API  - Transient Object Functions */
293b0104773SPascal Brand 
294b0104773SPascal Brand TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,
29579a3c601SCedric Chaumont 				       uint32_t maxKeySize,
296b0104773SPascal Brand 				       TEE_ObjectHandle *object)
297b0104773SPascal Brand {
298b0104773SPascal Brand 	TEE_Result res;
299b0104773SPascal Brand 	uint32_t obj;
300b0104773SPascal Brand 
3016915bbbbSJens Wiklander 	__utee_check_out_annotation(object, sizeof(*object));
3026915bbbbSJens Wiklander 
3032c028fdeSJerome Forissier 	res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj);
304aeb0d927SCedric Chaumont 
305aeb0d927SCedric Chaumont 	if (res != TEE_SUCCESS &&
306aeb0d927SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
307aeb0d927SCedric Chaumont 	    res != TEE_ERROR_NOT_SUPPORTED)
308b36311adSJerome Forissier 		TEE_Panic(res);
309aeb0d927SCedric Chaumont 
310b0104773SPascal Brand 	if (res == TEE_SUCCESS)
311e86f1266SJens Wiklander 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
3120ed6a6caSCedric Chaumont 
313b0104773SPascal Brand 	return res;
314b0104773SPascal Brand }
315b0104773SPascal Brand 
316b0104773SPascal Brand void TEE_FreeTransientObject(TEE_ObjectHandle object)
317b0104773SPascal Brand {
31875d6a373SJens Wiklander 	struct utee_object_info info = { };
31975d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
320b0104773SPascal Brand 
321b0104773SPascal Brand 	if (object == TEE_HANDLE_NULL)
322b0104773SPascal Brand 		return;
323b0104773SPascal Brand 
3242c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
325b0104773SPascal Brand 	if (res != TEE_SUCCESS)
326b36311adSJerome Forissier 		TEE_Panic(res);
327b0104773SPascal Brand 
32875d6a373SJens Wiklander 	if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
329b0104773SPascal Brand 		TEE_Panic(0);
330b0104773SPascal Brand 
3312c028fdeSJerome Forissier 	res = _utee_cryp_obj_close((unsigned long)object);
332b0104773SPascal Brand 	if (res != TEE_SUCCESS)
333b36311adSJerome Forissier 		TEE_Panic(res);
334b0104773SPascal Brand }
335b0104773SPascal Brand 
336b0104773SPascal Brand void TEE_ResetTransientObject(TEE_ObjectHandle object)
337b0104773SPascal Brand {
33875d6a373SJens Wiklander 	struct utee_object_info info = { };
33975d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
340b0104773SPascal Brand 
341b0104773SPascal Brand 	if (object == TEE_HANDLE_NULL)
342b0104773SPascal Brand 		return;
343b0104773SPascal Brand 
3442c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
345b0104773SPascal Brand 	if (res != TEE_SUCCESS)
346b36311adSJerome Forissier 		TEE_Panic(res);
347b0104773SPascal Brand 
34875d6a373SJens Wiklander 	if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
349b0104773SPascal Brand 		TEE_Panic(0);
350b0104773SPascal Brand 
3512c028fdeSJerome Forissier 	res = _utee_cryp_obj_reset((unsigned long)object);
352b0104773SPascal Brand 	if (res != TEE_SUCCESS)
353b36311adSJerome Forissier 		TEE_Panic(res);
354b0104773SPascal Brand }
355b0104773SPascal Brand 
356b0104773SPascal Brand TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
3578f07fe6fSJerome Forissier 				       const TEE_Attribute *attrs,
358b0104773SPascal Brand 				       uint32_t attrCount)
359b0104773SPascal Brand {
360e86f1266SJens Wiklander 	struct utee_attribute ua[attrCount];
36175d6a373SJens Wiklander 	struct utee_object_info info = { };
36275d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
363b0104773SPascal Brand 
3646915bbbbSJens Wiklander 	__utee_check_attr_in_annotation(attrs, attrCount);
3656915bbbbSJens Wiklander 
3662c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
367b0104773SPascal Brand 	if (res != TEE_SUCCESS)
368b36311adSJerome Forissier 		TEE_Panic(res);
369b0104773SPascal Brand 
370b0104773SPascal Brand 	/* Must be a transient object */
37175d6a373SJens Wiklander 	if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
372b0104773SPascal Brand 		TEE_Panic(0);
373b0104773SPascal Brand 
374b0104773SPascal Brand 	/* Must not be initialized already */
37575d6a373SJens Wiklander 	if ((info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
376b0104773SPascal Brand 		TEE_Panic(0);
377b0104773SPascal Brand 
378e86f1266SJens Wiklander 	__utee_from_attr(ua, attrs, attrCount);
3792c028fdeSJerome Forissier 	res = _utee_cryp_obj_populate((unsigned long)object, ua, attrCount);
380b0104773SPascal Brand 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
381b0104773SPascal Brand 		TEE_Panic(res);
382b0104773SPascal Brand 	return res;
383b0104773SPascal Brand }
384b0104773SPascal Brand 
385*4f4374c8SJens Wiklander TEE_Result __GP11_TEE_PopulateTransientObject(TEE_ObjectHandle object,
386*4f4374c8SJens Wiklander 					      const __GP11_TEE_Attribute *attrs,
387*4f4374c8SJens Wiklander 					      uint32_t attrCount)
388*4f4374c8SJens Wiklander {
389*4f4374c8SJens Wiklander 	struct utee_attribute ua[attrCount];
390*4f4374c8SJens Wiklander 	struct utee_object_info info = { };
391*4f4374c8SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
392*4f4374c8SJens Wiklander 
393*4f4374c8SJens Wiklander 	__utee_check_gp11_attr_in_annotation(attrs, attrCount);
394*4f4374c8SJens Wiklander 
395*4f4374c8SJens Wiklander 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
396*4f4374c8SJens Wiklander 	if (res != TEE_SUCCESS)
397*4f4374c8SJens Wiklander 		TEE_Panic(res);
398*4f4374c8SJens Wiklander 
399*4f4374c8SJens Wiklander 	/* Must be a transient object */
400*4f4374c8SJens Wiklander 	if ((info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
401*4f4374c8SJens Wiklander 		TEE_Panic(0);
402*4f4374c8SJens Wiklander 
403*4f4374c8SJens Wiklander 	/* Must not be initialized already */
404*4f4374c8SJens Wiklander 	if ((info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
405*4f4374c8SJens Wiklander 		TEE_Panic(0);
406*4f4374c8SJens Wiklander 
407*4f4374c8SJens Wiklander 	__utee_from_gp11_attr(ua, attrs, attrCount);
408*4f4374c8SJens Wiklander 	res = _utee_cryp_obj_populate((unsigned long)object, ua, attrCount);
409*4f4374c8SJens Wiklander 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
410*4f4374c8SJens Wiklander 		TEE_Panic(res);
411*4f4374c8SJens Wiklander 	return res;
412*4f4374c8SJens Wiklander }
413*4f4374c8SJens Wiklander 
414b0104773SPascal Brand void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,
4158f07fe6fSJerome Forissier 			  const void *buffer, uint32_t length)
416b0104773SPascal Brand {
4176915bbbbSJens Wiklander 	__utee_check_out_annotation(attr, sizeof(*attr));
4186915bbbbSJens Wiklander 
419b9416909SJens Wiklander 	if ((attributeID & TEE_ATTR_FLAG_VALUE) != 0)
420b0104773SPascal Brand 		TEE_Panic(0);
421b0104773SPascal Brand 	attr->attributeID = attributeID;
4228f07fe6fSJerome Forissier 	attr->content.ref.buffer = (void *)buffer;
423b0104773SPascal Brand 	attr->content.ref.length = length;
424b0104773SPascal Brand }
425b0104773SPascal Brand 
426*4f4374c8SJens Wiklander void __GP11_TEE_InitRefAttribute(__GP11_TEE_Attribute *attr,
427*4f4374c8SJens Wiklander 				 uint32_t attributeID,
428*4f4374c8SJens Wiklander 				 const void *buffer, uint32_t length)
429*4f4374c8SJens Wiklander {
430*4f4374c8SJens Wiklander 	__utee_check_out_annotation(attr, sizeof(*attr));
431*4f4374c8SJens Wiklander 
432*4f4374c8SJens Wiklander 	if ((attributeID & TEE_ATTR_FLAG_VALUE) != 0)
433*4f4374c8SJens Wiklander 		TEE_Panic(0);
434*4f4374c8SJens Wiklander 	attr->attributeID = attributeID;
435*4f4374c8SJens Wiklander 	attr->content.ref.buffer = (void *)buffer;
436*4f4374c8SJens Wiklander 	attr->content.ref.length = length;
437*4f4374c8SJens Wiklander }
438*4f4374c8SJens Wiklander 
439b0104773SPascal Brand void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,
440b0104773SPascal Brand 			    uint32_t a, uint32_t b)
441b0104773SPascal Brand {
4426915bbbbSJens Wiklander 	__utee_check_out_annotation(attr, sizeof(*attr));
4436915bbbbSJens Wiklander 
444b9416909SJens Wiklander 	if ((attributeID & TEE_ATTR_FLAG_VALUE) == 0)
445b0104773SPascal Brand 		TEE_Panic(0);
446b0104773SPascal Brand 	attr->attributeID = attributeID;
447b0104773SPascal Brand 	attr->content.value.a = a;
448b0104773SPascal Brand 	attr->content.value.b = b;
449b0104773SPascal Brand }
450b0104773SPascal Brand 
451*4f4374c8SJens Wiklander void __GP11_TEE_InitValueAttribute(__GP11_TEE_Attribute *attr,
452*4f4374c8SJens Wiklander 				   uint32_t attributeID,
453*4f4374c8SJens Wiklander 				   uint32_t a, uint32_t b)
454*4f4374c8SJens Wiklander {
455*4f4374c8SJens Wiklander 	__utee_check_out_annotation(attr, sizeof(*attr));
456*4f4374c8SJens Wiklander 
457*4f4374c8SJens Wiklander 	if ((attributeID & TEE_ATTR_FLAG_VALUE) == 0)
458*4f4374c8SJens Wiklander 		TEE_Panic(0);
459*4f4374c8SJens Wiklander 	attr->attributeID = attributeID;
460*4f4374c8SJens Wiklander 	attr->content.value.a = a;
461*4f4374c8SJens Wiklander 	attr->content.value.b = b;
462*4f4374c8SJens Wiklander }
463*4f4374c8SJens Wiklander 
4647583c59eSCedric Chaumont /*
4657583c59eSCedric Chaumont  * Use of this function is deprecated
4667583c59eSCedric Chaumont  * new code SHOULD use the TEE_CopyObjectAttributes1 function instead
4677583c59eSCedric Chaumont  * These functions will be removed at some future major revision of
4687583c59eSCedric Chaumont  * this specification
4697583c59eSCedric Chaumont  */
470b0104773SPascal Brand void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
471b0104773SPascal Brand 			      TEE_ObjectHandle srcObject)
472b0104773SPascal Brand {
47375d6a373SJens Wiklander 	struct utee_object_info src_info = { };
47475d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
4757583c59eSCedric Chaumont 
4762c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
47775d6a373SJens Wiklander 	if (src_info.obj_type == TEE_TYPE_CORRUPTED_OBJECT)
4787583c59eSCedric Chaumont 		return;
4797583c59eSCedric Chaumont 
4807583c59eSCedric Chaumont 	res = TEE_CopyObjectAttributes1(destObject, srcObject);
4817583c59eSCedric Chaumont 	if (res != TEE_SUCCESS)
482b36311adSJerome Forissier 		TEE_Panic(res);
4837583c59eSCedric Chaumont }
4847583c59eSCedric Chaumont 
4857583c59eSCedric Chaumont TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject,
4867583c59eSCedric Chaumont 			      TEE_ObjectHandle srcObject)
4877583c59eSCedric Chaumont {
48875d6a373SJens Wiklander 	struct utee_object_info dst_info = { };
48975d6a373SJens Wiklander 	struct utee_object_info src_info = { };
49075d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
491b0104773SPascal Brand 
4922c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)destObject, &dst_info);
493b0104773SPascal Brand 	if (res != TEE_SUCCESS)
494a2e9a830SCedric Chaumont 		goto exit;
495b0104773SPascal Brand 
4962c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
497b0104773SPascal Brand 	if (res != TEE_SUCCESS)
498a2e9a830SCedric Chaumont 		goto exit;
499b0104773SPascal Brand 
50075d6a373SJens Wiklander 	if (!(src_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED))
501b0104773SPascal Brand 		TEE_Panic(0);
502a2e9a830SCedric Chaumont 
50375d6a373SJens Wiklander 	if ((dst_info.handle_flags & TEE_HANDLE_FLAG_PERSISTENT))
504b0104773SPascal Brand 		TEE_Panic(0);
505a2e9a830SCedric Chaumont 
50675d6a373SJens Wiklander 	if ((dst_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED))
507b0104773SPascal Brand 		TEE_Panic(0);
508b0104773SPascal Brand 
5092c028fdeSJerome Forissier 	res = _utee_cryp_obj_copy((unsigned long)destObject,
510e86f1266SJens Wiklander 				  (unsigned long)srcObject);
5117583c59eSCedric Chaumont 
512a2e9a830SCedric Chaumont exit:
513a2e9a830SCedric Chaumont 	if (res != TEE_SUCCESS &&
514a2e9a830SCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
515a2e9a830SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
516a2e9a830SCedric Chaumont 		TEE_Panic(res);
5177583c59eSCedric Chaumont 
5187583c59eSCedric Chaumont 	return res;
519b0104773SPascal Brand }
520b0104773SPascal Brand 
521b0104773SPascal Brand TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
5228f07fe6fSJerome Forissier 			   const TEE_Attribute *params, uint32_t paramCount)
523b0104773SPascal Brand {
524b0104773SPascal Brand 	TEE_Result res;
525e86f1266SJens Wiklander 	struct utee_attribute ua[paramCount];
526b0104773SPascal Brand 
5276915bbbbSJens Wiklander 	__utee_check_attr_in_annotation(params, paramCount);
5286915bbbbSJens Wiklander 
529e86f1266SJens Wiklander 	__utee_from_attr(ua, params, paramCount);
5302c028fdeSJerome Forissier 	res = _utee_cryp_obj_generate_key((unsigned long)object, keySize,
531e86f1266SJens Wiklander 					  ua, paramCount);
532b0104773SPascal Brand 
533aeb0d927SCedric Chaumont 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
534b36311adSJerome Forissier 		TEE_Panic(res);
535b0104773SPascal Brand 
536b0104773SPascal Brand 	return res;
537b0104773SPascal Brand }
538b0104773SPascal Brand 
539*4f4374c8SJens Wiklander TEE_Result __GP11_TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
540*4f4374c8SJens Wiklander 				  const __GP11_TEE_Attribute *params,
541*4f4374c8SJens Wiklander 				  uint32_t paramCount)
542*4f4374c8SJens Wiklander {
543*4f4374c8SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
544*4f4374c8SJens Wiklander 	struct utee_attribute ua[paramCount];
545*4f4374c8SJens Wiklander 
546*4f4374c8SJens Wiklander 	__utee_check_gp11_attr_in_annotation(params, paramCount);
547*4f4374c8SJens Wiklander 
548*4f4374c8SJens Wiklander 	__utee_from_gp11_attr(ua, params, paramCount);
549*4f4374c8SJens Wiklander 	res = _utee_cryp_obj_generate_key((unsigned long)object, keySize,
550*4f4374c8SJens Wiklander 					  ua, paramCount);
551*4f4374c8SJens Wiklander 
552*4f4374c8SJens Wiklander 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
553*4f4374c8SJens Wiklander 		TEE_Panic(res);
554*4f4374c8SJens Wiklander 
555*4f4374c8SJens Wiklander 	return res;
556*4f4374c8SJens Wiklander }
557*4f4374c8SJens Wiklander 
558b0104773SPascal Brand /* Data and Key Storage API  - Persistent Object Functions */
559b0104773SPascal Brand 
5608f07fe6fSJerome Forissier TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID,
56179a3c601SCedric Chaumont 				    uint32_t objectIDLen, uint32_t flags,
562b0104773SPascal Brand 				    TEE_ObjectHandle *object)
563b0104773SPascal Brand {
5649b520646SCedric Chaumont 	TEE_Result res;
565e86f1266SJens Wiklander 	uint32_t obj;
566b0104773SPascal Brand 
5672138a6f8SStefan Schmidt 	__utee_check_out_annotation(object, sizeof(*object));
5682138a6f8SStefan Schmidt 
5692c028fdeSJerome Forissier 	res = _utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
570e86f1266SJens Wiklander 				     &obj);
571e86f1266SJens Wiklander 	if (res == TEE_SUCCESS)
572e86f1266SJens Wiklander 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
5739b520646SCedric Chaumont 
5749b520646SCedric Chaumont 	if (res != TEE_SUCCESS &&
5759b520646SCedric Chaumont 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
5769b520646SCedric Chaumont 	    res != TEE_ERROR_ACCESS_CONFLICT &&
5779b520646SCedric Chaumont 	    res != TEE_ERROR_OUT_OF_MEMORY &&
5789b520646SCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
5799b520646SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
580b36311adSJerome Forissier 		TEE_Panic(res);
581b0104773SPascal Brand 
582172d637bSCedric Auger 	if (res != TEE_SUCCESS)
58369a3d6beSDaniel Glöckner 		*object = TEE_HANDLE_NULL;
58469a3d6beSDaniel Glöckner 
5859b520646SCedric Chaumont 	return res;
586b0104773SPascal Brand }
587b0104773SPascal Brand 
5888f07fe6fSJerome Forissier TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID,
58979a3c601SCedric Chaumont 				      uint32_t objectIDLen, uint32_t flags,
590b0104773SPascal Brand 				      TEE_ObjectHandle attributes,
591b0104773SPascal Brand 				      const void *initialData,
59279a3c601SCedric Chaumont 				      uint32_t initialDataLen,
593b0104773SPascal Brand 				      TEE_ObjectHandle *object)
594b0104773SPascal Brand {
59584431ae3SCedric Chaumont 	TEE_Result res;
596e86f1266SJens Wiklander 	uint32_t obj;
597b0104773SPascal Brand 
5986915bbbbSJens Wiklander 	__utee_check_out_annotation(object, sizeof(*object));
599b0104773SPascal Brand 
6002c028fdeSJerome Forissier 	res = _utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
601e86f1266SJens Wiklander 				       (unsigned long)attributes, initialData,
602e86f1266SJens Wiklander 				       initialDataLen, &obj);
603172d637bSCedric Auger 
6041c96fa7fSPascal Brand 	if (res == TEE_SUCCESS)
605172d637bSCedric Auger 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
606172d637bSCedric Auger 
607172d637bSCedric Auger 	if (res != TEE_SUCCESS &&
608172d637bSCedric Auger 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
609172d637bSCedric Auger 	    res != TEE_ERROR_ACCESS_CONFLICT &&
610172d637bSCedric Auger 	    res != TEE_ERROR_OUT_OF_MEMORY &&
611172d637bSCedric Auger 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
612172d637bSCedric Auger 	    res != TEE_ERROR_CORRUPT_OBJECT &&
613172d637bSCedric Auger 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
614b36311adSJerome Forissier 		TEE_Panic(res);
615172d637bSCedric Auger 
616172d637bSCedric Auger 	if (res != TEE_SUCCESS)
617172d637bSCedric Auger 		*object = TEE_HANDLE_NULL;
618172d637bSCedric Auger 
619172d637bSCedric Auger 	return res;
620b0104773SPascal Brand }
621b0104773SPascal Brand 
6227583c59eSCedric Chaumont /*
6237583c59eSCedric Chaumont  * Use of this function is deprecated
6247583c59eSCedric Chaumont  * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
6257583c59eSCedric Chaumont  * These functions will be removed at some future major revision of
6267583c59eSCedric Chaumont  * this specification
6277583c59eSCedric Chaumont  */
628b0104773SPascal Brand void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
629b0104773SPascal Brand {
630b0104773SPascal Brand 	TEE_Result res;
631b0104773SPascal Brand 
632b0104773SPascal Brand 	if (object == TEE_HANDLE_NULL)
633b0104773SPascal Brand 		return;
634b0104773SPascal Brand 
6357583c59eSCedric Chaumont 	res = TEE_CloseAndDeletePersistentObject1(object);
636b0104773SPascal Brand 
637b0104773SPascal Brand 	if (res != TEE_SUCCESS)
638b0104773SPascal Brand 		TEE_Panic(0);
639b0104773SPascal Brand }
640b0104773SPascal Brand 
6417583c59eSCedric Chaumont TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
6427583c59eSCedric Chaumont {
6437583c59eSCedric Chaumont 	TEE_Result res;
6447583c59eSCedric Chaumont 
6457583c59eSCedric Chaumont 	if (object == TEE_HANDLE_NULL)
64646cfd17cSJens Wiklander 		return TEE_SUCCESS;
6477583c59eSCedric Chaumont 
6482c028fdeSJerome Forissier 	res = _utee_storage_obj_del((unsigned long)object);
6497583c59eSCedric Chaumont 
6507583c59eSCedric Chaumont 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
651b36311adSJerome Forissier 		TEE_Panic(res);
6527583c59eSCedric Chaumont 
6537583c59eSCedric Chaumont 	return res;
6547583c59eSCedric Chaumont }
6557583c59eSCedric Chaumont 
6567583c59eSCedric Chaumont 
657b0104773SPascal Brand TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
658b0104773SPascal Brand 				      const void *newObjectID,
65979a3c601SCedric Chaumont 				      uint32_t newObjectIDLen)
660b0104773SPascal Brand {
661b0104773SPascal Brand 	TEE_Result res;
662b0104773SPascal Brand 
663a76bf53fSCedric Chaumont 	if (object == TEE_HANDLE_NULL) {
664a76bf53fSCedric Chaumont 		res = TEE_ERROR_ITEM_NOT_FOUND;
665a76bf53fSCedric Chaumont 		goto out;
666a76bf53fSCedric Chaumont 	}
667b0104773SPascal Brand 
6682c028fdeSJerome Forissier 	res = _utee_storage_obj_rename((unsigned long)object, newObjectID,
669e86f1266SJens Wiklander 				       newObjectIDLen);
670b0104773SPascal Brand 
671a76bf53fSCedric Chaumont out:
672a76bf53fSCedric Chaumont 	if (res != TEE_SUCCESS &&
673a76bf53fSCedric Chaumont 	    res != TEE_ERROR_ACCESS_CONFLICT &&
674a76bf53fSCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
675a76bf53fSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
676b36311adSJerome Forissier 		TEE_Panic(res);
677b0104773SPascal Brand 
678b0104773SPascal Brand 	return res;
679b0104773SPascal Brand }
680b0104773SPascal Brand 
681b0104773SPascal Brand TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
682b0104773SPascal Brand 						  objectEnumerator)
683b0104773SPascal Brand {
684b0104773SPascal Brand 	TEE_Result res;
685e86f1266SJens Wiklander 	uint32_t oe;
686b0104773SPascal Brand 
6876915bbbbSJens Wiklander 	__utee_check_out_annotation(objectEnumerator,
6886915bbbbSJens Wiklander 				    sizeof(*objectEnumerator));
689b0104773SPascal Brand 
6902c028fdeSJerome Forissier 	res = _utee_storage_alloc_enum(&oe);
691b0104773SPascal Brand 
692b0104773SPascal Brand 	if (res != TEE_SUCCESS)
693e86f1266SJens Wiklander 		oe = TEE_HANDLE_NULL;
694e86f1266SJens Wiklander 
695e86f1266SJens Wiklander 	*objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe;
696b0104773SPascal Brand 
69715cd3c30SCedric Chaumont 	if (res != TEE_SUCCESS &&
69815cd3c30SCedric Chaumont 	    res != TEE_ERROR_ACCESS_CONFLICT)
699b36311adSJerome Forissier 		TEE_Panic(res);
70015cd3c30SCedric Chaumont 
701b0104773SPascal Brand 	return res;
702b0104773SPascal Brand }
703b0104773SPascal Brand 
704b0104773SPascal Brand void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
705b0104773SPascal Brand {
706b0104773SPascal Brand 	TEE_Result res;
707b0104773SPascal Brand 
708b0104773SPascal Brand 	if (objectEnumerator == TEE_HANDLE_NULL)
709b0104773SPascal Brand 		return;
710b0104773SPascal Brand 
7112c028fdeSJerome Forissier 	res = _utee_storage_free_enum((unsigned long)objectEnumerator);
712b0104773SPascal Brand 
713b0104773SPascal Brand 	if (res != TEE_SUCCESS)
714b36311adSJerome Forissier 		TEE_Panic(res);
715b0104773SPascal Brand }
716b0104773SPascal Brand 
717b0104773SPascal Brand void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
718b0104773SPascal Brand {
719b0104773SPascal Brand 	TEE_Result res;
720b0104773SPascal Brand 
721b0104773SPascal Brand 	if (objectEnumerator == TEE_HANDLE_NULL)
722b0104773SPascal Brand 		return;
723b0104773SPascal Brand 
7242c028fdeSJerome Forissier 	res = _utee_storage_reset_enum((unsigned long)objectEnumerator);
725b0104773SPascal Brand 
726b0104773SPascal Brand 	if (res != TEE_SUCCESS)
727b36311adSJerome Forissier 		TEE_Panic(res);
728b0104773SPascal Brand }
729b0104773SPascal Brand 
730b0104773SPascal Brand TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
731b0104773SPascal Brand 					       objectEnumerator,
732b0104773SPascal Brand 					       uint32_t storageID)
733b0104773SPascal Brand {
734b0104773SPascal Brand 	TEE_Result res;
735b0104773SPascal Brand 
7362c028fdeSJerome Forissier 	res = _utee_storage_start_enum((unsigned long)objectEnumerator,
737e86f1266SJens Wiklander 				       storageID);
738b0104773SPascal Brand 
73915cd3c30SCedric Chaumont 	if (res != TEE_SUCCESS &&
74015cd3c30SCedric Chaumont 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
74115cd3c30SCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
74215cd3c30SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
743b36311adSJerome Forissier 		TEE_Panic(res);
744b0104773SPascal Brand 
745b0104773SPascal Brand 	return res;
746b0104773SPascal Brand }
747b0104773SPascal Brand 
748b0104773SPascal Brand TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
749b0104773SPascal Brand 				       TEE_ObjectInfo *objectInfo,
75079a3c601SCedric Chaumont 				       void *objectID, uint32_t *objectIDLen)
751b0104773SPascal Brand {
75275d6a373SJens Wiklander 	struct utee_object_info info = { };
75375d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
75475d6a373SJens Wiklander 	uint64_t len = 0;
755b0104773SPascal Brand 
7566915bbbbSJens Wiklander 	if (objectInfo)
7576915bbbbSJens Wiklander 		__utee_check_out_annotation(objectInfo, sizeof(*objectInfo));
7586915bbbbSJens Wiklander 	__utee_check_out_annotation(objectIDLen, sizeof(*objectIDLen));
75915cd3c30SCedric Chaumont 
7606915bbbbSJens Wiklander 	if (!objectID) {
76115cd3c30SCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
76215cd3c30SCedric Chaumont 		goto out;
76315cd3c30SCedric Chaumont 	}
76415cd3c30SCedric Chaumont 
765e86f1266SJens Wiklander 	len = *objectIDLen;
7662c028fdeSJerome Forissier 	res = _utee_storage_next_enum((unsigned long)objectEnumerator,
76775d6a373SJens Wiklander 				      &info, objectID, &len);
76875d6a373SJens Wiklander 	if (objectInfo) {
76975d6a373SJens Wiklander 		objectInfo->objectType = info.obj_type;
770d372a47cSJens Wiklander 		objectInfo->objectSize = info.obj_size;
771d372a47cSJens Wiklander 		objectInfo->maxObjectSize = info.max_obj_size;
772d372a47cSJens Wiklander 		objectInfo->objectUsage = info.obj_usage;
773d372a47cSJens Wiklander 		objectInfo->dataSize = info.data_size;
774d372a47cSJens Wiklander 		objectInfo->dataPosition = info.data_pos;
775d372a47cSJens Wiklander 		objectInfo->handleFlags = info.handle_flags;
776d372a47cSJens Wiklander 	}
777d372a47cSJens Wiklander 	*objectIDLen = len;
778d372a47cSJens Wiklander 
779d372a47cSJens Wiklander out:
780d372a47cSJens Wiklander 	if (res != TEE_SUCCESS &&
781d372a47cSJens Wiklander 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
782d372a47cSJens Wiklander 	    res != TEE_ERROR_CORRUPT_OBJECT &&
783d372a47cSJens Wiklander 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
784d372a47cSJens Wiklander 		TEE_Panic(res);
785d372a47cSJens Wiklander 
786d372a47cSJens Wiklander 	return res;
787d372a47cSJens Wiklander }
788d372a47cSJens Wiklander 
789d372a47cSJens Wiklander TEE_Result
790d372a47cSJens Wiklander __GP11_TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
791d372a47cSJens Wiklander 				   __GP11_TEE_ObjectInfo *objectInfo,
792d372a47cSJens Wiklander 				   void *objectID, uint32_t *objectIDLen)
793d372a47cSJens Wiklander {
794d372a47cSJens Wiklander 	struct utee_object_info info = { };
795d372a47cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
796d372a47cSJens Wiklander 	uint64_t len = 0;
797d372a47cSJens Wiklander 
798d372a47cSJens Wiklander 	if (objectInfo)
799d372a47cSJens Wiklander 		__utee_check_out_annotation(objectInfo, sizeof(*objectInfo));
800d372a47cSJens Wiklander 	__utee_check_out_annotation(objectIDLen, sizeof(*objectIDLen));
801d372a47cSJens Wiklander 
802d372a47cSJens Wiklander 	if (!objectID) {
803d372a47cSJens Wiklander 		res = TEE_ERROR_BAD_PARAMETERS;
804d372a47cSJens Wiklander 		goto out;
805d372a47cSJens Wiklander 	}
806d372a47cSJens Wiklander 
807d372a47cSJens Wiklander 	len = *objectIDLen;
808d372a47cSJens Wiklander 	res = _utee_storage_next_enum((unsigned long)objectEnumerator,
809d372a47cSJens Wiklander 				      &info, objectID, &len);
810d372a47cSJens Wiklander 	if (objectInfo) {
811d372a47cSJens Wiklander 		objectInfo->objectType = info.obj_type;
81275d6a373SJens Wiklander 		objectInfo->keySize = info.obj_size;
81375d6a373SJens Wiklander 		objectInfo->maxKeySize = info.max_obj_size;
81475d6a373SJens Wiklander 		objectInfo->objectUsage = info.obj_usage;
81575d6a373SJens Wiklander 		objectInfo->dataSize = info.data_size;
81675d6a373SJens Wiklander 		objectInfo->dataPosition = info.data_pos;
81775d6a373SJens Wiklander 		objectInfo->handleFlags = info.handle_flags;
81875d6a373SJens Wiklander 	}
819e86f1266SJens Wiklander 	*objectIDLen = len;
820b0104773SPascal Brand 
82115cd3c30SCedric Chaumont out:
82215cd3c30SCedric Chaumont 	if (res != TEE_SUCCESS &&
82315cd3c30SCedric Chaumont 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
82415cd3c30SCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
82515cd3c30SCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
826b36311adSJerome Forissier 		TEE_Panic(res);
827b0104773SPascal Brand 
828b0104773SPascal Brand 	return res;
829b0104773SPascal Brand }
830b0104773SPascal Brand 
831b0104773SPascal Brand /* Data and Key Storage API  - Data Stream Access Functions */
832b0104773SPascal Brand 
833b0104773SPascal Brand TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
83479a3c601SCedric Chaumont 			      uint32_t size, uint32_t *count)
835b0104773SPascal Brand {
836b0104773SPascal Brand 	TEE_Result res;
837e86f1266SJens Wiklander 	uint64_t cnt64;
838b0104773SPascal Brand 
839ae1289baSCedric Chaumont 	if (object == TEE_HANDLE_NULL) {
840ae1289baSCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
841ae1289baSCedric Chaumont 		goto out;
842ae1289baSCedric Chaumont 	}
8436915bbbbSJens Wiklander 	__utee_check_out_annotation(count, sizeof(*count));
844b0104773SPascal Brand 
845e86f1266SJens Wiklander 	cnt64 = *count;
8462c028fdeSJerome Forissier 	res = _utee_storage_obj_read((unsigned long)object, buffer, size,
847e86f1266SJens Wiklander 				     &cnt64);
848e86f1266SJens Wiklander 	*count = cnt64;
849b0104773SPascal Brand 
850ae1289baSCedric Chaumont out:
851ae1289baSCedric Chaumont 	if (res != TEE_SUCCESS &&
852ae1289baSCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
853ae1289baSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
854b36311adSJerome Forissier 		TEE_Panic(res);
855b0104773SPascal Brand 
856b0104773SPascal Brand 	return res;
857b0104773SPascal Brand }
858b0104773SPascal Brand 
8598f07fe6fSJerome Forissier TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer,
86079a3c601SCedric Chaumont 			       uint32_t size)
861b0104773SPascal Brand {
862b0104773SPascal Brand 	TEE_Result res;
863b0104773SPascal Brand 
864ae1289baSCedric Chaumont 	if (object == TEE_HANDLE_NULL) {
865ae1289baSCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
866ae1289baSCedric Chaumont 		goto out;
867ae1289baSCedric Chaumont 	}
868ae1289baSCedric Chaumont 
869ae1289baSCedric Chaumont 	if (size > TEE_DATA_MAX_POSITION) {
870ae1289baSCedric Chaumont 		res = TEE_ERROR_OVERFLOW;
871ae1289baSCedric Chaumont 		goto out;
872ae1289baSCedric Chaumont 	}
873b0104773SPascal Brand 
8742c028fdeSJerome Forissier 	res = _utee_storage_obj_write((unsigned long)object, buffer, size);
875b0104773SPascal Brand 
876ae1289baSCedric Chaumont out:
877ae1289baSCedric Chaumont 	if (res != TEE_SUCCESS &&
878ae1289baSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
879ae1289baSCedric Chaumont 	    res != TEE_ERROR_OVERFLOW &&
880ae1289baSCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
881ae1289baSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
882b36311adSJerome Forissier 		TEE_Panic(res);
883b0104773SPascal Brand 
884b0104773SPascal Brand 	return res;
885b0104773SPascal Brand }
886b0104773SPascal Brand 
887b0104773SPascal Brand TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
888b0104773SPascal Brand {
889b0104773SPascal Brand 	TEE_Result res;
890b0104773SPascal Brand 
891ae1289baSCedric Chaumont 	if (object == TEE_HANDLE_NULL) {
892ae1289baSCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
893ae1289baSCedric Chaumont 		goto out;
894ae1289baSCedric Chaumont 	}
895b0104773SPascal Brand 
8962c028fdeSJerome Forissier 	res = _utee_storage_obj_trunc((unsigned long)object, size);
897b0104773SPascal Brand 
898ae1289baSCedric Chaumont out:
899ae1289baSCedric Chaumont 	if (res != TEE_SUCCESS &&
900ae1289baSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
901ae1289baSCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
902ae1289baSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
903b36311adSJerome Forissier 		TEE_Panic(res);
904b0104773SPascal Brand 
905b0104773SPascal Brand 	return res;
906b0104773SPascal Brand }
907b0104773SPascal Brand 
908b0104773SPascal Brand TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
909b0104773SPascal Brand 			      TEE_Whence whence)
910b0104773SPascal Brand {
91175d6a373SJens Wiklander 	struct utee_object_info info = { };
91275d6a373SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
913b0104773SPascal Brand 
914ae1289baSCedric Chaumont 	if (object == TEE_HANDLE_NULL) {
915ae1289baSCedric Chaumont 		res = TEE_ERROR_BAD_PARAMETERS;
916ae1289baSCedric Chaumont 		goto out;
917ae1289baSCedric Chaumont 	}
918b0104773SPascal Brand 
9192c028fdeSJerome Forissier 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
920b0104773SPascal Brand 	if (res != TEE_SUCCESS)
921ae1289baSCedric Chaumont 		goto out;
922b0104773SPascal Brand 
923b0104773SPascal Brand 	switch (whence) {
924b0104773SPascal Brand 	case TEE_DATA_SEEK_SET:
925ae1289baSCedric Chaumont 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) {
926ae1289baSCedric Chaumont 			res = TEE_ERROR_OVERFLOW;
927ae1289baSCedric Chaumont 			goto out;
928ae1289baSCedric Chaumont 		}
929b0104773SPascal Brand 		break;
930b0104773SPascal Brand 	case TEE_DATA_SEEK_CUR:
931b0104773SPascal Brand 		if (offset > 0 &&
93275d6a373SJens Wiklander 		    ((uint32_t)offset + info.data_pos > TEE_DATA_MAX_POSITION ||
93375d6a373SJens Wiklander 		     (uint32_t)offset + info.data_pos < info.data_pos)) {
934ae1289baSCedric Chaumont 			res = TEE_ERROR_OVERFLOW;
935ae1289baSCedric Chaumont 			goto out;
936ae1289baSCedric Chaumont 		}
937b0104773SPascal Brand 		break;
938b0104773SPascal Brand 	case TEE_DATA_SEEK_END:
939b0104773SPascal Brand 		if (offset > 0 &&
94075d6a373SJens Wiklander 		    ((uint32_t)offset + info.data_size >
94175d6a373SJens Wiklander 		     TEE_DATA_MAX_POSITION ||
94275d6a373SJens Wiklander 		     (uint32_t)offset + info.data_size < info.data_size)) {
943ae1289baSCedric Chaumont 			res = TEE_ERROR_OVERFLOW;
944ae1289baSCedric Chaumont 			goto out;
945ae1289baSCedric Chaumont 		}
946b0104773SPascal Brand 		break;
947b0104773SPascal Brand 	default:
948ae1289baSCedric Chaumont 		res = TEE_ERROR_ITEM_NOT_FOUND;
949ae1289baSCedric Chaumont 		goto out;
950b0104773SPascal Brand 	}
951b0104773SPascal Brand 
9522c028fdeSJerome Forissier 	res = _utee_storage_obj_seek((unsigned long)object, offset, whence);
953b0104773SPascal Brand 
954ae1289baSCedric Chaumont out:
955ae1289baSCedric Chaumont 	if (res != TEE_SUCCESS &&
956ae1289baSCedric Chaumont 	    res != TEE_ERROR_OVERFLOW &&
957ae1289baSCedric Chaumont 	    res != TEE_ERROR_CORRUPT_OBJECT &&
958ae1289baSCedric Chaumont 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
959b36311adSJerome Forissier 		TEE_Panic(res);
960b0104773SPascal Brand 
961b0104773SPascal Brand 	return res;
962b0104773SPascal Brand }
963