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