xref: /optee_os/lib/libutee/tee_api_objects.c (revision 3d3b05918ec9052ba13de82fbcaba204766eb636)
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 out;
395 	}
396 
397 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
398 		res = TEE_ERROR_BAD_PARAMETERS;
399 		goto out;
400 	}
401 
402 	if (!object) {
403 		res = TEE_ERROR_BAD_PARAMETERS;
404 		goto out;
405 	}
406 
407 	res = utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
408 				     &obj);
409 	if (res == TEE_SUCCESS)
410 		*object = (TEE_ObjectHandle)(uintptr_t)obj;
411 
412 out:
413 	if (res != TEE_SUCCESS &&
414 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
415 	    res != TEE_ERROR_ACCESS_CONFLICT &&
416 	    res != TEE_ERROR_OUT_OF_MEMORY &&
417 	    res != TEE_ERROR_CORRUPT_OBJECT &&
418 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
419 		TEE_Panic(res);
420 
421 	if (res != TEE_SUCCESS && object)
422 		*object = TEE_HANDLE_NULL;
423 
424 	return res;
425 }
426 
427 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID,
428 				      uint32_t objectIDLen, uint32_t flags,
429 				      TEE_ObjectHandle attributes,
430 				      const void *initialData,
431 				      uint32_t initialDataLen,
432 				      TEE_ObjectHandle *object)
433 {
434 	TEE_Result res;
435 	uint32_t obj;
436 
437 	if (!objectID) {
438 		res = TEE_ERROR_ITEM_NOT_FOUND;
439 		goto err;
440 	}
441 
442 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
443 		res = TEE_ERROR_BAD_PARAMETERS;
444 		goto err;
445 	}
446 
447 	res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
448 				      (unsigned long)attributes, initialData,
449 				      initialDataLen, &obj);
450 	if (res == TEE_SUCCESS) {
451 		if (object)
452 			*object = (TEE_ObjectHandle)(uintptr_t)obj;
453 		else
454 			res = utee_cryp_obj_close(obj);
455 		if (res == TEE_SUCCESS)
456 			goto out;
457 	}
458 err:
459 	if (object)
460 		*object = TEE_HANDLE_NULL;
461 	if (res == TEE_ERROR_ITEM_NOT_FOUND ||
462 	    res == TEE_ERROR_ACCESS_CONFLICT ||
463 	    res == TEE_ERROR_OUT_OF_MEMORY ||
464 	    res == TEE_ERROR_STORAGE_NO_SPACE ||
465 	    res == TEE_ERROR_CORRUPT_OBJECT ||
466 	    res == TEE_ERROR_STORAGE_NOT_AVAILABLE)
467 		return res;
468 	TEE_Panic(res);
469 out:
470 	return TEE_SUCCESS;
471 }
472 
473 /*
474  * Use of this function is deprecated
475  * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
476  * These functions will be removed at some future major revision of
477  * this specification
478  */
479 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
480 {
481 	TEE_Result res;
482 
483 	if (object == TEE_HANDLE_NULL)
484 		return;
485 
486 	res = TEE_CloseAndDeletePersistentObject1(object);
487 
488 	if (res != TEE_SUCCESS)
489 		TEE_Panic(0);
490 }
491 
492 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
493 {
494 	TEE_Result res;
495 
496 	if (object == TEE_HANDLE_NULL)
497 		return TEE_ERROR_STORAGE_NOT_AVAILABLE;
498 
499 	res = utee_storage_obj_del((unsigned long)object);
500 
501 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
502 		TEE_Panic(res);
503 
504 	return res;
505 }
506 
507 
508 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
509 				      const void *newObjectID,
510 				      uint32_t newObjectIDLen)
511 {
512 	TEE_Result res;
513 
514 	if (object == TEE_HANDLE_NULL) {
515 		res = TEE_ERROR_ITEM_NOT_FOUND;
516 		goto out;
517 	}
518 
519 	if (!newObjectID) {
520 		res = TEE_ERROR_BAD_PARAMETERS;
521 		goto out;
522 	}
523 
524 	if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) {
525 		res = TEE_ERROR_BAD_PARAMETERS;
526 		goto out;
527 	}
528 
529 	res = utee_storage_obj_rename((unsigned long)object, newObjectID,
530 				      newObjectIDLen);
531 
532 out:
533 	if (res != TEE_SUCCESS &&
534 	    res != TEE_ERROR_ACCESS_CONFLICT &&
535 	    res != TEE_ERROR_CORRUPT_OBJECT &&
536 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
537 		TEE_Panic(res);
538 
539 	return res;
540 }
541 
542 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
543 						  objectEnumerator)
544 {
545 	TEE_Result res;
546 	uint32_t oe;
547 
548 	if (!objectEnumerator)
549 		return TEE_ERROR_BAD_PARAMETERS;
550 
551 	res = utee_storage_alloc_enum(&oe);
552 
553 	if (res != TEE_SUCCESS)
554 		oe = TEE_HANDLE_NULL;
555 
556 	*objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe;
557 
558 	if (res != TEE_SUCCESS &&
559 	    res != TEE_ERROR_ACCESS_CONFLICT)
560 		TEE_Panic(res);
561 
562 	return res;
563 }
564 
565 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
566 {
567 	TEE_Result res;
568 
569 	if (objectEnumerator == TEE_HANDLE_NULL)
570 		return;
571 
572 	res = utee_storage_free_enum((unsigned long)objectEnumerator);
573 
574 	if (res != TEE_SUCCESS)
575 		TEE_Panic(res);
576 }
577 
578 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
579 {
580 	TEE_Result res;
581 
582 	if (objectEnumerator == TEE_HANDLE_NULL)
583 		return;
584 
585 	res = utee_storage_reset_enum((unsigned long)objectEnumerator);
586 
587 	if (res != TEE_SUCCESS)
588 		TEE_Panic(res);
589 }
590 
591 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
592 					       objectEnumerator,
593 					       uint32_t storageID)
594 {
595 	TEE_Result res;
596 
597 	res = utee_storage_start_enum((unsigned long)objectEnumerator,
598 				      storageID);
599 
600 	if (res != TEE_SUCCESS &&
601 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
602 	    res != TEE_ERROR_CORRUPT_OBJECT &&
603 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
604 		TEE_Panic(res);
605 
606 	return res;
607 }
608 
609 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
610 				       TEE_ObjectInfo *objectInfo,
611 				       void *objectID, uint32_t *objectIDLen)
612 {
613 	TEE_Result res;
614 	uint64_t len;
615 	TEE_ObjectInfo local_info;
616 	TEE_ObjectInfo *pt_info;
617 
618 	if (!objectID) {
619 		res = TEE_ERROR_BAD_PARAMETERS;
620 		goto out;
621 	}
622 
623 	if (!objectIDLen) {
624 		res = TEE_ERROR_BAD_PARAMETERS;
625 		goto out;
626 	}
627 
628 	if (objectInfo)
629 		pt_info = objectInfo;
630 	else
631 		pt_info = &local_info;
632 	len = *objectIDLen;
633 	res = utee_storage_next_enum((unsigned long)objectEnumerator,
634 				     pt_info, objectID, &len);
635 	*objectIDLen = len;
636 
637 out:
638 	if (res != TEE_SUCCESS &&
639 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
640 	    res != TEE_ERROR_CORRUPT_OBJECT &&
641 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
642 		TEE_Panic(res);
643 
644 	return res;
645 }
646 
647 /* Data and Key Storage API  - Data Stream Access Functions */
648 
649 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
650 			      uint32_t size, uint32_t *count)
651 {
652 	TEE_Result res;
653 	uint64_t cnt64;
654 
655 	if (object == TEE_HANDLE_NULL) {
656 		res = TEE_ERROR_BAD_PARAMETERS;
657 		goto out;
658 	}
659 
660 	cnt64 = *count;
661 	res = utee_storage_obj_read((unsigned long)object, buffer, size,
662 				    &cnt64);
663 	*count = cnt64;
664 
665 out:
666 	if (res != TEE_SUCCESS &&
667 	    res != TEE_ERROR_CORRUPT_OBJECT &&
668 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
669 		TEE_Panic(res);
670 
671 	return res;
672 }
673 
674 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer,
675 			       uint32_t size)
676 {
677 	TEE_Result res;
678 
679 	if (object == TEE_HANDLE_NULL) {
680 		res = TEE_ERROR_BAD_PARAMETERS;
681 		goto out;
682 	}
683 
684 	if (size > TEE_DATA_MAX_POSITION) {
685 		res = TEE_ERROR_OVERFLOW;
686 		goto out;
687 	}
688 
689 	res = utee_storage_obj_write((unsigned long)object, buffer, size);
690 
691 out:
692 	if (res != TEE_SUCCESS &&
693 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
694 	    res != TEE_ERROR_OVERFLOW &&
695 	    res != TEE_ERROR_CORRUPT_OBJECT &&
696 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
697 		TEE_Panic(res);
698 
699 	return res;
700 }
701 
702 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
703 {
704 	TEE_Result res;
705 
706 	if (object == TEE_HANDLE_NULL) {
707 		res = TEE_ERROR_BAD_PARAMETERS;
708 		goto out;
709 	}
710 
711 	res = utee_storage_obj_trunc((unsigned long)object, size);
712 
713 out:
714 	if (res != TEE_SUCCESS &&
715 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
716 	    res != TEE_ERROR_CORRUPT_OBJECT &&
717 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
718 		TEE_Panic(res);
719 
720 	return res;
721 }
722 
723 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
724 			      TEE_Whence whence)
725 {
726 	TEE_Result res;
727 	TEE_ObjectInfo info;
728 
729 	if (object == TEE_HANDLE_NULL) {
730 		res = TEE_ERROR_BAD_PARAMETERS;
731 		goto out;
732 	}
733 
734 	res = utee_cryp_obj_get_info((unsigned long)object, &info);
735 	if (res != TEE_SUCCESS)
736 		goto out;
737 
738 	switch (whence) {
739 	case TEE_DATA_SEEK_SET:
740 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) {
741 			res = TEE_ERROR_OVERFLOW;
742 			goto out;
743 		}
744 		break;
745 	case TEE_DATA_SEEK_CUR:
746 		if (offset > 0 &&
747 		    ((uint32_t)offset + info.dataPosition >
748 		     TEE_DATA_MAX_POSITION ||
749 		     (uint32_t)offset + info.dataPosition <
750 		     info.dataPosition)) {
751 			res = TEE_ERROR_OVERFLOW;
752 			goto out;
753 		}
754 		break;
755 	case TEE_DATA_SEEK_END:
756 		if (offset > 0 &&
757 		    ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
758 		     (uint32_t)offset + info.dataSize < info.dataSize)) {
759 			res = TEE_ERROR_OVERFLOW;
760 			goto out;
761 		}
762 		break;
763 	default:
764 		res = TEE_ERROR_ITEM_NOT_FOUND;
765 		goto out;
766 	}
767 
768 	res = utee_storage_obj_seek((unsigned long)object, offset, whence);
769 
770 out:
771 	if (res != TEE_SUCCESS &&
772 	    res != TEE_ERROR_OVERFLOW &&
773 	    res != TEE_ERROR_CORRUPT_OBJECT &&
774 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
775 		TEE_Panic(res);
776 
777 	return res;
778 }
779