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