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