xref: /optee_os/lib/libutee/tee_api_objects.c (revision b9416909794c36c55f30037dafae0e8a8e780599)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include <tee_api.h>
9 #include <utee_syscalls.h>
10 #include "tee_api_private.h"
11 
12 #define TEE_USAGE_DEFAULT   0xffffffff
13 
14 void __utee_from_attr(struct utee_attribute *ua, const TEE_Attribute *attrs,
15 			uint32_t attr_count)
16 {
17 	size_t n;
18 
19 	for (n = 0; n < attr_count; n++) {
20 		ua[n].attribute_id = attrs[n].attributeID;
21 		if (attrs[n].attributeID & TEE_ATTR_FLAG_VALUE) {
22 			ua[n].a = attrs[n].content.value.a;
23 			ua[n].b = attrs[n].content.value.b;
24 		} else {
25 			ua[n].a = (uintptr_t)attrs[n].content.ref.buffer;
26 			ua[n].b = attrs[n].content.ref.length;
27 		}
28 	}
29 }
30 
31 /* Data and Key Storage API  - Generic Object Functions */
32 /*
33  * Use of this function is deprecated
34  * new code SHOULD use the TEE_GetObjectInfo1 function instead
35  * These functions will be removed at some future major revision of
36  * this specification
37  */
38 void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
39 {
40 	TEE_Result res;
41 
42 	res = _utee_cryp_obj_get_info((unsigned long)object, objectInfo);
43 
44 	if (res != TEE_SUCCESS)
45 		TEE_Panic(res);
46 
47 	if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) {
48 		objectInfo->keySize = 0;
49 		objectInfo->maxKeySize = 0;
50 		objectInfo->objectUsage = 0;
51 		objectInfo->dataSize = 0;
52 		objectInfo->dataPosition = 0;
53 		objectInfo->handleFlags = 0;
54 	}
55 }
56 
57 TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
58 {
59 	TEE_Result res;
60 
61 	res = _utee_cryp_obj_get_info((unsigned long)object, objectInfo);
62 
63 	if (res != TEE_SUCCESS &&
64 	    res != TEE_ERROR_CORRUPT_OBJECT &&
65 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
66 		TEE_Panic(res);
67 
68 	return res;
69 }
70 
71 /*
72  * Use of this function is deprecated
73  * new code SHOULD use the TEE_RestrictObjectUsage1 function instead
74  * These functions will be removed at some future major revision of
75  * this specification
76  */
77 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage)
78 {
79 	TEE_Result res;
80 	TEE_ObjectInfo objectInfo;
81 
82 	res = _utee_cryp_obj_get_info((unsigned long)object, &objectInfo);
83 	if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT)
84 		return;
85 
86 	res = TEE_RestrictObjectUsage1(object, objectUsage);
87 
88 	if (res != TEE_SUCCESS)
89 		TEE_Panic(res);
90 }
91 
92 TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage)
93 {
94 	TEE_Result res;
95 
96 	res = _utee_cryp_obj_restrict_usage((unsigned long)object,
97 					    objectUsage);
98 
99 	if (res != TEE_SUCCESS &&
100 	    res != TEE_ERROR_CORRUPT_OBJECT &&
101 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
102 		TEE_Panic(res);
103 
104 	return res;
105 }
106 
107 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
108 					uint32_t attributeID, void *buffer,
109 					uint32_t *size)
110 {
111 	TEE_Result res;
112 	TEE_ObjectInfo info;
113 	uint64_t sz;
114 
115 	__utee_check_inout_annotation(size, sizeof(*size));
116 
117 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
118 	if (res != TEE_SUCCESS)
119 		goto exit;
120 
121 	/* This function only supports reference attributes */
122 	if ((attributeID & TEE_ATTR_FLAG_VALUE)) {
123 		res = TEE_ERROR_BAD_PARAMETERS;
124 		goto exit;
125 	}
126 
127 	sz = *size;
128 	res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID,
129 				      buffer, &sz);
130 	*size = sz;
131 
132 exit:
133 	if (res != TEE_SUCCESS &&
134 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
135 	    res != TEE_ERROR_SHORT_BUFFER &&
136 	    res != TEE_ERROR_CORRUPT_OBJECT &&
137 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
138 		TEE_Panic(res);
139 
140 	return res;
141 }
142 
143 TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
144 				       uint32_t attributeID, uint32_t *a,
145 				       uint32_t *b)
146 {
147 	TEE_Result res;
148 	TEE_ObjectInfo info;
149 	uint32_t buf[2];
150 	uint64_t size = sizeof(buf);
151 
152 	if (a)
153 		__utee_check_out_annotation(a, sizeof(*a));
154 	if (b)
155 		__utee_check_out_annotation(b, sizeof(*b));
156 
157 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
158 	if (res != TEE_SUCCESS)
159 		goto exit;
160 
161 	/* This function only supports value attributes */
162 	if (!(attributeID & TEE_ATTR_FLAG_VALUE)) {
163 		res = TEE_ERROR_BAD_PARAMETERS;
164 		goto exit;
165 	}
166 
167 	res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf,
168 				      &size);
169 
170 exit:
171 	if (res != TEE_SUCCESS &&
172 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
173 	    res != TEE_ERROR_CORRUPT_OBJECT &&
174 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
175 		TEE_Panic(res);
176 
177 	if (size != sizeof(buf))
178 		TEE_Panic(0);
179 
180 	if (res == TEE_SUCCESS) {
181 		if (a)
182 			*a = buf[0];
183 		if (b)
184 			*b = buf[1];
185 	}
186 
187 	return res;
188 }
189 
190 void TEE_CloseObject(TEE_ObjectHandle object)
191 {
192 	TEE_Result res;
193 
194 	if (object == TEE_HANDLE_NULL)
195 		return;
196 
197 	res = _utee_cryp_obj_close((unsigned long)object);
198 	if (res != TEE_SUCCESS)
199 		TEE_Panic(res);
200 }
201 
202 /* Data and Key Storage API  - Transient Object Functions */
203 
204 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,
205 				       uint32_t maxKeySize,
206 				       TEE_ObjectHandle *object)
207 {
208 	TEE_Result res;
209 	uint32_t obj;
210 
211 	__utee_check_out_annotation(object, sizeof(*object));
212 
213 	res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj);
214 
215 	if (res != TEE_SUCCESS &&
216 	    res != TEE_ERROR_OUT_OF_MEMORY &&
217 	    res != TEE_ERROR_NOT_SUPPORTED)
218 		TEE_Panic(res);
219 
220 	if (res == TEE_SUCCESS)
221 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
222 
223 	return res;
224 }
225 
226 void TEE_FreeTransientObject(TEE_ObjectHandle object)
227 {
228 	TEE_Result res;
229 	TEE_ObjectInfo info;
230 
231 	if (object == TEE_HANDLE_NULL)
232 		return;
233 
234 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
235 	if (res != TEE_SUCCESS)
236 		TEE_Panic(res);
237 
238 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
239 		TEE_Panic(0);
240 
241 	res = _utee_cryp_obj_close((unsigned long)object);
242 	if (res != TEE_SUCCESS)
243 		TEE_Panic(res);
244 }
245 
246 void TEE_ResetTransientObject(TEE_ObjectHandle object)
247 {
248 	TEE_Result res;
249 	TEE_ObjectInfo info;
250 
251 	if (object == TEE_HANDLE_NULL)
252 		return;
253 
254 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
255 	if (res != TEE_SUCCESS)
256 		TEE_Panic(res);
257 
258 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
259 		TEE_Panic(0);
260 
261 	res = _utee_cryp_obj_reset((unsigned long)object);
262 	if (res != TEE_SUCCESS)
263 		TEE_Panic(res);
264 }
265 
266 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
267 				       const TEE_Attribute *attrs,
268 				       uint32_t attrCount)
269 {
270 	TEE_Result res;
271 	TEE_ObjectInfo info;
272 	struct utee_attribute ua[attrCount];
273 
274 	__utee_check_attr_in_annotation(attrs, attrCount);
275 
276 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
277 	if (res != TEE_SUCCESS)
278 		TEE_Panic(res);
279 
280 	/* Must be a transient object */
281 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
282 		TEE_Panic(0);
283 
284 	/* Must not be initialized already */
285 	if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
286 		TEE_Panic(0);
287 
288 	__utee_from_attr(ua, attrs, attrCount);
289 	res = _utee_cryp_obj_populate((unsigned long)object, ua, attrCount);
290 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
291 		TEE_Panic(res);
292 	return res;
293 }
294 
295 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,
296 			  const void *buffer, uint32_t length)
297 {
298 	__utee_check_out_annotation(attr, sizeof(*attr));
299 
300 	if ((attributeID & TEE_ATTR_FLAG_VALUE) != 0)
301 		TEE_Panic(0);
302 	attr->attributeID = attributeID;
303 	attr->content.ref.buffer = (void *)buffer;
304 	attr->content.ref.length = length;
305 }
306 
307 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,
308 			    uint32_t a, uint32_t b)
309 {
310 	__utee_check_out_annotation(attr, sizeof(*attr));
311 
312 	if ((attributeID & TEE_ATTR_FLAG_VALUE) == 0)
313 		TEE_Panic(0);
314 	attr->attributeID = attributeID;
315 	attr->content.value.a = a;
316 	attr->content.value.b = b;
317 }
318 
319 /*
320  * Use of this function is deprecated
321  * new code SHOULD use the TEE_CopyObjectAttributes1 function instead
322  * These functions will be removed at some future major revision of
323  * this specification
324  */
325 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
326 			      TEE_ObjectHandle srcObject)
327 {
328 	TEE_Result res;
329 	TEE_ObjectInfo src_info;
330 
331 	res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
332 	if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT)
333 		return;
334 
335 	res = TEE_CopyObjectAttributes1(destObject, srcObject);
336 	if (res != TEE_SUCCESS)
337 		TEE_Panic(res);
338 }
339 
340 TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject,
341 			      TEE_ObjectHandle srcObject)
342 {
343 	TEE_Result res;
344 	TEE_ObjectInfo dst_info;
345 	TEE_ObjectInfo src_info;
346 
347 	res = _utee_cryp_obj_get_info((unsigned long)destObject, &dst_info);
348 	if (res != TEE_SUCCESS)
349 		goto exit;
350 
351 	res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
352 	if (res != TEE_SUCCESS)
353 		goto exit;
354 
355 	if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
356 		TEE_Panic(0);
357 
358 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT))
359 		TEE_Panic(0);
360 
361 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
362 		TEE_Panic(0);
363 
364 	res = _utee_cryp_obj_copy((unsigned long)destObject,
365 				  (unsigned long)srcObject);
366 
367 exit:
368 	if (res != TEE_SUCCESS &&
369 	    res != TEE_ERROR_CORRUPT_OBJECT &&
370 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
371 		TEE_Panic(res);
372 
373 	return res;
374 }
375 
376 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
377 			   const TEE_Attribute *params, uint32_t paramCount)
378 {
379 	TEE_Result res;
380 	struct utee_attribute ua[paramCount];
381 
382 	__utee_check_attr_in_annotation(params, paramCount);
383 
384 	__utee_from_attr(ua, params, paramCount);
385 	res = _utee_cryp_obj_generate_key((unsigned long)object, keySize,
386 					  ua, paramCount);
387 
388 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
389 		TEE_Panic(res);
390 
391 	return res;
392 }
393 
394 /* Data and Key Storage API  - Persistent Object Functions */
395 
396 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID,
397 				    uint32_t objectIDLen, uint32_t flags,
398 				    TEE_ObjectHandle *object)
399 {
400 	TEE_Result res;
401 	uint32_t obj;
402 
403 	if (!objectID) {
404 		res = TEE_ERROR_ITEM_NOT_FOUND;
405 		goto exit;
406 	}
407 
408 	res = _utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
409 				     &obj);
410 	if (res == TEE_SUCCESS)
411 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
412 
413 exit:
414 	if (res != TEE_SUCCESS &&
415 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
416 	    res != TEE_ERROR_ACCESS_CONFLICT &&
417 	    res != TEE_ERROR_OUT_OF_MEMORY &&
418 	    res != TEE_ERROR_CORRUPT_OBJECT &&
419 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
420 		TEE_Panic(res);
421 
422 	if (res != TEE_SUCCESS)
423 		*object = TEE_HANDLE_NULL;
424 
425 	return res;
426 }
427 
428 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID,
429 				      uint32_t objectIDLen, uint32_t flags,
430 				      TEE_ObjectHandle attributes,
431 				      const void *initialData,
432 				      uint32_t initialDataLen,
433 				      TEE_ObjectHandle *object)
434 {
435 	TEE_Result res;
436 	uint32_t obj;
437 
438 	if (!objectID) {
439 		res = TEE_ERROR_ITEM_NOT_FOUND;
440 		goto exit;
441 	}
442 
443 	__utee_check_out_annotation(object, sizeof(*object));
444 
445 	res = _utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
446 				       (unsigned long)attributes, initialData,
447 				       initialDataLen, &obj);
448 
449 	if (res == TEE_SUCCESS)
450 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
451 
452 exit:
453 	if (res != TEE_SUCCESS &&
454 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
455 	    res != TEE_ERROR_ACCESS_CONFLICT &&
456 	    res != TEE_ERROR_OUT_OF_MEMORY &&
457 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
458 	    res != TEE_ERROR_CORRUPT_OBJECT &&
459 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
460 		TEE_Panic(res);
461 
462 	if (res != TEE_SUCCESS)
463 		*object = TEE_HANDLE_NULL;
464 
465 	return res;
466 }
467 
468 /*
469  * Use of this function is deprecated
470  * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
471  * These functions will be removed at some future major revision of
472  * this specification
473  */
474 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
475 {
476 	TEE_Result res;
477 
478 	if (object == TEE_HANDLE_NULL)
479 		return;
480 
481 	res = TEE_CloseAndDeletePersistentObject1(object);
482 
483 	if (res != TEE_SUCCESS)
484 		TEE_Panic(0);
485 }
486 
487 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
488 {
489 	TEE_Result res;
490 
491 	if (object == TEE_HANDLE_NULL)
492 		return TEE_SUCCESS;
493 
494 	res = _utee_storage_obj_del((unsigned long)object);
495 
496 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
497 		TEE_Panic(res);
498 
499 	return res;
500 }
501 
502 
503 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
504 				      const void *newObjectID,
505 				      uint32_t newObjectIDLen)
506 {
507 	TEE_Result res;
508 
509 	if (object == TEE_HANDLE_NULL) {
510 		res = TEE_ERROR_ITEM_NOT_FOUND;
511 		goto out;
512 	}
513 
514 	res = _utee_storage_obj_rename((unsigned long)object, newObjectID,
515 				       newObjectIDLen);
516 
517 out:
518 	if (res != TEE_SUCCESS &&
519 	    res != TEE_ERROR_ACCESS_CONFLICT &&
520 	    res != TEE_ERROR_CORRUPT_OBJECT &&
521 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
522 		TEE_Panic(res);
523 
524 	return res;
525 }
526 
527 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
528 						  objectEnumerator)
529 {
530 	TEE_Result res;
531 	uint32_t oe;
532 
533 	__utee_check_out_annotation(objectEnumerator,
534 				    sizeof(*objectEnumerator));
535 
536 	res = _utee_storage_alloc_enum(&oe);
537 
538 	if (res != TEE_SUCCESS)
539 		oe = TEE_HANDLE_NULL;
540 
541 	*objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe;
542 
543 	if (res != TEE_SUCCESS &&
544 	    res != TEE_ERROR_ACCESS_CONFLICT)
545 		TEE_Panic(res);
546 
547 	return res;
548 }
549 
550 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
551 {
552 	TEE_Result res;
553 
554 	if (objectEnumerator == TEE_HANDLE_NULL)
555 		return;
556 
557 	res = _utee_storage_free_enum((unsigned long)objectEnumerator);
558 
559 	if (res != TEE_SUCCESS)
560 		TEE_Panic(res);
561 }
562 
563 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
564 {
565 	TEE_Result res;
566 
567 	if (objectEnumerator == TEE_HANDLE_NULL)
568 		return;
569 
570 	res = _utee_storage_reset_enum((unsigned long)objectEnumerator);
571 
572 	if (res != TEE_SUCCESS)
573 		TEE_Panic(res);
574 }
575 
576 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
577 					       objectEnumerator,
578 					       uint32_t storageID)
579 {
580 	TEE_Result res;
581 
582 	res = _utee_storage_start_enum((unsigned long)objectEnumerator,
583 				       storageID);
584 
585 	if (res != TEE_SUCCESS &&
586 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
587 	    res != TEE_ERROR_CORRUPT_OBJECT &&
588 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
589 		TEE_Panic(res);
590 
591 	return res;
592 }
593 
594 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
595 				       TEE_ObjectInfo *objectInfo,
596 				       void *objectID, uint32_t *objectIDLen)
597 {
598 	TEE_Result res;
599 	uint64_t len;
600 	TEE_ObjectInfo local_info;
601 	TEE_ObjectInfo *pt_info;
602 
603 	if (objectInfo)
604 		__utee_check_out_annotation(objectInfo, sizeof(*objectInfo));
605 	__utee_check_out_annotation(objectIDLen, sizeof(*objectIDLen));
606 
607 	if (!objectID) {
608 		res = TEE_ERROR_BAD_PARAMETERS;
609 		goto out;
610 	}
611 
612 	if (objectInfo)
613 		pt_info = objectInfo;
614 	else
615 		pt_info = &local_info;
616 	len = *objectIDLen;
617 	res = _utee_storage_next_enum((unsigned long)objectEnumerator,
618 				      pt_info, objectID, &len);
619 	*objectIDLen = len;
620 
621 out:
622 	if (res != TEE_SUCCESS &&
623 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
624 	    res != TEE_ERROR_CORRUPT_OBJECT &&
625 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
626 		TEE_Panic(res);
627 
628 	return res;
629 }
630 
631 /* Data and Key Storage API  - Data Stream Access Functions */
632 
633 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
634 			      uint32_t size, uint32_t *count)
635 {
636 	TEE_Result res;
637 	uint64_t cnt64;
638 
639 	if (object == TEE_HANDLE_NULL) {
640 		res = TEE_ERROR_BAD_PARAMETERS;
641 		goto out;
642 	}
643 	__utee_check_out_annotation(count, sizeof(*count));
644 
645 	cnt64 = *count;
646 	res = _utee_storage_obj_read((unsigned long)object, buffer, size,
647 				     &cnt64);
648 	*count = cnt64;
649 
650 out:
651 	if (res != TEE_SUCCESS &&
652 	    res != TEE_ERROR_CORRUPT_OBJECT &&
653 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
654 		TEE_Panic(res);
655 
656 	return res;
657 }
658 
659 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer,
660 			       uint32_t size)
661 {
662 	TEE_Result res;
663 
664 	if (object == TEE_HANDLE_NULL) {
665 		res = TEE_ERROR_BAD_PARAMETERS;
666 		goto out;
667 	}
668 
669 	if (size > TEE_DATA_MAX_POSITION) {
670 		res = TEE_ERROR_OVERFLOW;
671 		goto out;
672 	}
673 
674 	res = _utee_storage_obj_write((unsigned long)object, buffer, size);
675 
676 out:
677 	if (res != TEE_SUCCESS &&
678 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
679 	    res != TEE_ERROR_OVERFLOW &&
680 	    res != TEE_ERROR_CORRUPT_OBJECT &&
681 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
682 		TEE_Panic(res);
683 
684 	return res;
685 }
686 
687 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
688 {
689 	TEE_Result res;
690 
691 	if (object == TEE_HANDLE_NULL) {
692 		res = TEE_ERROR_BAD_PARAMETERS;
693 		goto out;
694 	}
695 
696 	res = _utee_storage_obj_trunc((unsigned long)object, size);
697 
698 out:
699 	if (res != TEE_SUCCESS &&
700 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
701 	    res != TEE_ERROR_CORRUPT_OBJECT &&
702 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
703 		TEE_Panic(res);
704 
705 	return res;
706 }
707 
708 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
709 			      TEE_Whence whence)
710 {
711 	TEE_Result res;
712 	TEE_ObjectInfo info;
713 
714 	if (object == TEE_HANDLE_NULL) {
715 		res = TEE_ERROR_BAD_PARAMETERS;
716 		goto out;
717 	}
718 
719 	res = _utee_cryp_obj_get_info((unsigned long)object, &info);
720 	if (res != TEE_SUCCESS)
721 		goto out;
722 
723 	switch (whence) {
724 	case TEE_DATA_SEEK_SET:
725 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) {
726 			res = TEE_ERROR_OVERFLOW;
727 			goto out;
728 		}
729 		break;
730 	case TEE_DATA_SEEK_CUR:
731 		if (offset > 0 &&
732 		    ((uint32_t)offset + info.dataPosition >
733 		     TEE_DATA_MAX_POSITION ||
734 		     (uint32_t)offset + info.dataPosition <
735 		     info.dataPosition)) {
736 			res = TEE_ERROR_OVERFLOW;
737 			goto out;
738 		}
739 		break;
740 	case TEE_DATA_SEEK_END:
741 		if (offset > 0 &&
742 		    ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
743 		     (uint32_t)offset + info.dataSize < info.dataSize)) {
744 			res = TEE_ERROR_OVERFLOW;
745 			goto out;
746 		}
747 		break;
748 	default:
749 		res = TEE_ERROR_ITEM_NOT_FOUND;
750 		goto out;
751 	}
752 
753 	res = _utee_storage_obj_seek((unsigned long)object, offset, whence);
754 
755 out:
756 	if (res != TEE_SUCCESS &&
757 	    res != TEE_ERROR_OVERFLOW &&
758 	    res != TEE_ERROR_CORRUPT_OBJECT &&
759 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
760 		TEE_Panic(res);
761 
762 	return res;
763 }
764