xref: /optee_os/lib/libutee/tee_api_objects.c (revision 75d6a373a0c0520395d998c36b14fda93c8ce168)
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