xref: /optee_os/lib/libutee/tee_api_objects.c (revision a2e9a83066c0810060c222999b0004aedfa18fff)
1 /*
2  * Copyright (c) 2014, STMicroelectronics International N.V.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include <tee_api.h>
31 #include <utee_syscalls.h>
32 
33 #include <assert.h>
34 
35 #define TEE_USAGE_DEFAULT   0xffffffff
36 
37 #define TEE_ATTR_BIT_VALUE                  (1 << 29)
38 #define TEE_ATTR_BIT_PROTECTED              (1 << 28)
39 
40 /* Data and Key Storage API  - Generic Object Functions */
41 /*
42  * Use of this function is deprecated
43  * new code SHOULD use the TEE_GetObjectInfo1 function instead
44  * These functions will be removed at some future major revision of
45  * this specification
46  */
47 void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
48 {
49 	TEE_Result res;
50 
51 	res = utee_cryp_obj_get_info((uint32_t)object, objectInfo);
52 
53 	if (res != TEE_SUCCESS)
54 		TEE_Panic(res);
55 
56 	if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) {
57 		objectInfo->keySize = 0;
58 		objectInfo->maxKeySize = 0;
59 		objectInfo->objectUsage = 0;
60 		objectInfo->dataSize = 0;
61 		objectInfo->dataPosition = 0;
62 		objectInfo->handleFlags = 0;
63 	}
64 }
65 
66 TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
67 {
68 	TEE_Result res;
69 
70 	res = utee_cryp_obj_get_info((uint32_t)object, objectInfo);
71 
72 	if (res != TEE_SUCCESS &&
73 	    res != TEE_ERROR_CORRUPT_OBJECT &&
74 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
75 		TEE_Panic(res);
76 
77 	return res;
78 }
79 
80 /*
81  * Use of this function is deprecated
82  * new code SHOULD use the TEE_RestrictObjectUsage1 function instead
83  * These functions will be removed at some future major revision of
84  * this specification
85  */
86 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage)
87 {
88 	TEE_Result res;
89 	TEE_ObjectInfo objectInfo;
90 
91 	res = utee_cryp_obj_get_info((uint32_t)object, &objectInfo);
92 	if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT)
93 		return;
94 
95 	res = TEE_RestrictObjectUsage1(object, objectUsage);
96 
97 	if (res != TEE_SUCCESS)
98 		TEE_Panic(0);
99 }
100 
101 TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage)
102 {
103 	TEE_Result res;
104 
105 	res = utee_cryp_obj_restrict_usage((uint32_t)object, objectUsage);
106 
107 	if (res != TEE_SUCCESS &&
108 	    res != TEE_ERROR_CORRUPT_OBJECT &&
109 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
110 		TEE_Panic(res);
111 
112 	return res;
113 }
114 
115 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
116 					uint32_t attributeID, void *buffer,
117 					uint32_t *size)
118 {
119 	TEE_Result res;
120 	TEE_ObjectInfo info;
121 
122 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
123 	if (res != TEE_SUCCESS)
124 		goto exit;
125 
126 	/* This function only supports reference attributes */
127 	if ((attributeID & TEE_ATTR_BIT_VALUE)) {
128 		res = TEE_ERROR_BAD_PARAMETERS;
129 		goto exit;
130 	}
131 
132 	res = utee_cryp_obj_get_attr((uint32_t)object,
133 				     attributeID, buffer, size);
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(0);
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 	uint32_t size = sizeof(buf);
154 
155 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
156 	if (res != TEE_SUCCESS)
157 		goto exit;
158 
159 	/* This function only supports value attributes */
160 	if (!(attributeID & TEE_ATTR_BIT_VALUE)) {
161 		res = TEE_ERROR_BAD_PARAMETERS;
162 		goto exit;
163 	}
164 
165 	res = utee_cryp_obj_get_attr((uint32_t)object,
166 				     attributeID, buf, &size);
167 
168 exit:
169 	if (res != TEE_SUCCESS &&
170 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
171 	    res != TEE_ERROR_CORRUPT_OBJECT &&
172 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
173 		TEE_Panic(0);
174 
175 	if (size != sizeof(buf))
176 		TEE_Panic(0);
177 
178 	*a = buf[0];
179 	*b = buf[1];
180 
181 	return res;
182 }
183 
184 void TEE_CloseObject(TEE_ObjectHandle object)
185 {
186 	TEE_Result res;
187 
188 	if (object == TEE_HANDLE_NULL)
189 		return;
190 
191 	res = utee_cryp_obj_close((uint32_t)object);
192 	if (res != TEE_SUCCESS)
193 		TEE_Panic(0);
194 }
195 
196 /* Data and Key Storage API  - Transient Object Functions */
197 
198 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,
199 				       uint32_t maxKeySize,
200 				       TEE_ObjectHandle *object)
201 {
202 	TEE_Result res;
203 	uint32_t obj;
204 
205 	res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj);
206 
207 	if (res != TEE_SUCCESS &&
208 	    res != TEE_ERROR_OUT_OF_MEMORY &&
209 	    res != TEE_ERROR_NOT_SUPPORTED)
210 		TEE_Panic(0);
211 
212 	if (res == TEE_SUCCESS)
213 		*object = (TEE_ObjectHandle) obj;
214 
215 	return res;
216 }
217 
218 void TEE_FreeTransientObject(TEE_ObjectHandle object)
219 {
220 	TEE_Result res;
221 	TEE_ObjectInfo info;
222 
223 	if (object == TEE_HANDLE_NULL)
224 		return;
225 
226 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
227 	if (res != TEE_SUCCESS)
228 		TEE_Panic(0);
229 
230 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
231 		TEE_Panic(0);
232 
233 	res = utee_cryp_obj_close((uint32_t)object);
234 	if (res != TEE_SUCCESS)
235 		TEE_Panic(0);
236 }
237 
238 void TEE_ResetTransientObject(TEE_ObjectHandle object)
239 {
240 	TEE_Result res;
241 	TEE_ObjectInfo info;
242 
243 	if (object == TEE_HANDLE_NULL)
244 		return;
245 
246 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
247 	if (res != TEE_SUCCESS)
248 		TEE_Panic(0);
249 
250 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
251 		TEE_Panic(0);
252 
253 	res = utee_cryp_obj_reset((uint32_t)object);
254 	if (res != TEE_SUCCESS)
255 		TEE_Panic(0);
256 }
257 
258 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
259 				       TEE_Attribute *attrs,
260 				       uint32_t attrCount)
261 {
262 	TEE_Result res;
263 	TEE_ObjectInfo info;
264 
265 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
266 	if (res != TEE_SUCCESS)
267 		TEE_Panic(0);
268 
269 	/* Must be a transient object */
270 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
271 		TEE_Panic(0);
272 
273 	/* Must not be initialized already */
274 	if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
275 		TEE_Panic(0);
276 
277 	res = utee_cryp_obj_populate((uint32_t)object, attrs, attrCount);
278 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
279 		TEE_Panic(res);
280 	return res;
281 }
282 
283 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,
284 			  void *buffer, uint32_t length)
285 {
286 	if (attr == NULL)
287 		TEE_Panic(0);
288 	if ((attributeID & TEE_ATTR_BIT_VALUE) != 0)
289 		TEE_Panic(0);
290 	attr->attributeID = attributeID;
291 	attr->content.ref.buffer = buffer;
292 	attr->content.ref.length = length;
293 }
294 
295 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,
296 			    uint32_t a, uint32_t b)
297 {
298 	if (attr == NULL)
299 		TEE_Panic(0);
300 	if ((attributeID & TEE_ATTR_BIT_VALUE) == 0)
301 		TEE_Panic(0);
302 	attr->attributeID = attributeID;
303 	attr->content.value.a = a;
304 	attr->content.value.b = b;
305 }
306 
307 /*
308  * Use of this function is deprecated
309  * new code SHOULD use the TEE_CopyObjectAttributes1 function instead
310  * These functions will be removed at some future major revision of
311  * this specification
312  */
313 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
314 			      TEE_ObjectHandle srcObject)
315 {
316 	TEE_Result res;
317 	TEE_ObjectInfo src_info;
318 
319 	res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info);
320 	if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT)
321 		return;
322 
323 	res = TEE_CopyObjectAttributes1(destObject, srcObject);
324 	if (res != TEE_SUCCESS)
325 		TEE_Panic(0);
326 }
327 
328 TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject,
329 			      TEE_ObjectHandle srcObject)
330 {
331 	TEE_Result res;
332 	TEE_ObjectInfo dst_info;
333 	TEE_ObjectInfo src_info;
334 
335 	res = utee_cryp_obj_get_info((uint32_t)destObject, &dst_info);
336 	if (res != TEE_SUCCESS)
337 		goto exit;
338 
339 	res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info);
340 	if (res != TEE_SUCCESS)
341 		goto exit;
342 
343 	if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
344 		TEE_Panic(0);
345 
346 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT))
347 		TEE_Panic(0);
348 
349 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
350 		TEE_Panic(0);
351 
352 	res = utee_cryp_obj_copy((uint32_t)destObject, (uint32_t)srcObject);
353 
354 exit:
355 	if (res != TEE_SUCCESS &&
356 	    res != TEE_ERROR_CORRUPT_OBJECT &&
357 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
358 		TEE_Panic(res);
359 
360 	return res;
361 }
362 
363 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
364 			   TEE_Attribute *params, uint32_t paramCount)
365 {
366 	TEE_Result res;
367 
368 	res = utee_cryp_obj_generate_key((uint32_t)object, keySize,
369 					 params, paramCount);
370 
371 	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
372 		TEE_Panic(0);
373 
374 	return res;
375 }
376 
377 /* Data and Key Storage API  - Persistent Object Functions */
378 
379 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, void *objectID,
380 				    uint32_t objectIDLen, uint32_t flags,
381 				    TEE_ObjectHandle *object)
382 {
383 	TEE_Result res;
384 
385 	if (storageID != TEE_STORAGE_PRIVATE) {
386 		res = TEE_ERROR_ITEM_NOT_FOUND;
387 		goto out;
388 	}
389 
390 	if (!objectID) {
391 		res = TEE_ERROR_ITEM_NOT_FOUND;
392 		goto out;
393 	}
394 
395 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
396 		res = TEE_ERROR_BAD_PARAMETERS;
397 		goto out;
398 	}
399 
400 	if (!object) {
401 		res = TEE_ERROR_BAD_PARAMETERS;
402 		goto out;
403 	}
404 
405 	res = utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
406 				     object);
407 
408 out:
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(0);
416 
417 	return res;
418 }
419 
420 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, void *objectID,
421 				      uint32_t objectIDLen, uint32_t flags,
422 				      TEE_ObjectHandle attributes,
423 				      const void *initialData,
424 				      uint32_t initialDataLen,
425 				      TEE_ObjectHandle *object)
426 {
427 	TEE_Result res;
428 
429 	if (storageID != TEE_STORAGE_PRIVATE) {
430 		res = TEE_ERROR_ITEM_NOT_FOUND;
431 		goto err;
432 	}
433 
434 	if (!objectID) {
435 		res = TEE_ERROR_ITEM_NOT_FOUND;
436 		goto err;
437 	}
438 
439 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
440 		res = TEE_ERROR_BAD_PARAMETERS;
441 		goto err;
442 	}
443 
444 	if (!object) {
445 		res = TEE_ERROR_BAD_PARAMETERS;
446 		goto err;
447 	}
448 
449 	res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
450 				       attributes, initialData, initialDataLen,
451 				       object);
452 	if (res == TEE_SUCCESS)
453 		goto out;
454 err:
455 	if (res == TEE_ERROR_ITEM_NOT_FOUND ||
456 	    res == TEE_ERROR_ACCESS_CONFLICT ||
457 	    res == TEE_ERROR_OUT_OF_MEMORY ||
458 	    res == TEE_ERROR_STORAGE_NO_SPACE ||
459 	    res == TEE_ERROR_CORRUPT_OBJECT ||
460 	    res == TEE_ERROR_STORAGE_NOT_AVAILABLE)
461 		return res;
462 	TEE_Panic(0);
463 out:
464 	return TEE_SUCCESS;
465 }
466 
467 /*
468  * Use of this function is deprecated
469  * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
470  * These functions will be removed at some future major revision of
471  * this specification
472  */
473 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
474 {
475 	TEE_Result res;
476 
477 	if (object == TEE_HANDLE_NULL)
478 		return;
479 
480 	res = TEE_CloseAndDeletePersistentObject1(object);
481 
482 	if (res != TEE_SUCCESS)
483 		TEE_Panic(0);
484 }
485 
486 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
487 {
488 	TEE_Result res;
489 
490 	if (object == TEE_HANDLE_NULL)
491 		return TEE_ERROR_STORAGE_NOT_AVAILABLE;
492 
493 	res = utee_storage_obj_del(object);
494 
495 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
496 		TEE_Panic(0);
497 
498 	return res;
499 }
500 
501 
502 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
503 				      const void *newObjectID,
504 				      uint32_t newObjectIDLen)
505 {
506 	TEE_Result res;
507 
508 	if (object == TEE_HANDLE_NULL) {
509 		res = TEE_ERROR_ITEM_NOT_FOUND;
510 		goto out;
511 	}
512 
513 	if (!newObjectID) {
514 		res = TEE_ERROR_BAD_PARAMETERS;
515 		goto out;
516 	}
517 
518 	if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) {
519 		res = TEE_ERROR_BAD_PARAMETERS;
520 		goto out;
521 	}
522 
523 	res = utee_storage_obj_rename(object, newObjectID, 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(0);
531 
532 	return res;
533 }
534 
535 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
536 						  objectEnumerator)
537 {
538 	TEE_Result res;
539 
540 	if (!objectEnumerator)
541 		return TEE_ERROR_BAD_PARAMETERS;
542 
543 	res = utee_storage_alloc_enum(objectEnumerator);
544 
545 	if (res != TEE_SUCCESS)
546 		*objectEnumerator = TEE_HANDLE_NULL;
547 
548 	if (res != TEE_SUCCESS &&
549 	    res != TEE_ERROR_ACCESS_CONFLICT)
550 		TEE_Panic(0);
551 
552 	return res;
553 }
554 
555 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
556 {
557 	TEE_Result res;
558 
559 	if (objectEnumerator == TEE_HANDLE_NULL)
560 		return;
561 
562 	res = utee_storage_free_enum(objectEnumerator);
563 
564 	if (res != TEE_SUCCESS)
565 		TEE_Panic(0);
566 }
567 
568 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
569 {
570 	TEE_Result res;
571 
572 	if (objectEnumerator == TEE_HANDLE_NULL)
573 		return;
574 
575 	res = utee_storage_reset_enum(objectEnumerator);
576 
577 	if (res != TEE_SUCCESS)
578 		TEE_Panic(0);
579 }
580 
581 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
582 					       objectEnumerator,
583 					       uint32_t storageID)
584 {
585 	TEE_Result res;
586 
587 	if (storageID != TEE_STORAGE_PRIVATE)
588 		return TEE_ERROR_ITEM_NOT_FOUND;
589 
590 	res = utee_storage_start_enum(objectEnumerator, 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(0);
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 
607 	if (!objectID) {
608 		res = TEE_ERROR_BAD_PARAMETERS;
609 		goto out;
610 	}
611 
612 	if (!objectIDLen) {
613 		res = TEE_ERROR_BAD_PARAMETERS;
614 		goto out;
615 	}
616 
617 	res = utee_storage_next_enum(objectEnumerator, objectInfo, objectID,
618 				     objectIDLen);
619 
620 out:
621 	if (res != TEE_SUCCESS &&
622 	    res != TEE_ERROR_ITEM_NOT_FOUND &&
623 	    res != TEE_ERROR_CORRUPT_OBJECT &&
624 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
625 		TEE_Panic(0);
626 
627 	return res;
628 }
629 
630 /* Data and Key Storage API  - Data Stream Access Functions */
631 
632 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
633 			      uint32_t size, uint32_t *count)
634 {
635 	TEE_Result res;
636 
637 	if (object == TEE_HANDLE_NULL) {
638 		res = TEE_ERROR_BAD_PARAMETERS;
639 		goto out;
640 	}
641 
642 	res = utee_storage_obj_read(object, buffer, size, count);
643 
644 out:
645 	if (res != TEE_SUCCESS &&
646 	    res != TEE_ERROR_CORRUPT_OBJECT &&
647 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
648 		TEE_Panic(0);
649 
650 	return res;
651 }
652 
653 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void *buffer,
654 			       uint32_t size)
655 {
656 	TEE_Result res;
657 
658 	if (object == TEE_HANDLE_NULL) {
659 		res = TEE_ERROR_BAD_PARAMETERS;
660 		goto out;
661 	}
662 
663 	if (size > TEE_DATA_MAX_POSITION) {
664 		res = TEE_ERROR_OVERFLOW;
665 		goto out;
666 	}
667 
668 	res = utee_storage_obj_write(object, buffer, size);
669 
670 out:
671 	if (res != TEE_SUCCESS &&
672 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
673 	    res != TEE_ERROR_OVERFLOW &&
674 	    res != TEE_ERROR_CORRUPT_OBJECT &&
675 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
676 		TEE_Panic(0);
677 
678 	return res;
679 }
680 
681 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
682 {
683 	TEE_Result res;
684 
685 	if (object == TEE_HANDLE_NULL) {
686 		res = TEE_ERROR_BAD_PARAMETERS;
687 		goto out;
688 	}
689 
690 	res = utee_storage_obj_trunc(object, size);
691 
692 out:
693 	if (res != TEE_SUCCESS &&
694 	    res != TEE_ERROR_STORAGE_NO_SPACE &&
695 	    res != TEE_ERROR_CORRUPT_OBJECT &&
696 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
697 		TEE_Panic(0);
698 
699 	return res;
700 }
701 
702 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
703 			      TEE_Whence whence)
704 {
705 	TEE_Result res;
706 	TEE_ObjectInfo info;
707 
708 	if (object == TEE_HANDLE_NULL) {
709 		res = TEE_ERROR_BAD_PARAMETERS;
710 		goto out;
711 	}
712 
713 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
714 	if (res != TEE_SUCCESS)
715 		goto out;
716 
717 	switch (whence) {
718 	case TEE_DATA_SEEK_SET:
719 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) {
720 			res = TEE_ERROR_OVERFLOW;
721 			goto out;
722 		}
723 		break;
724 	case TEE_DATA_SEEK_CUR:
725 		if (offset > 0 &&
726 		    ((uint32_t)offset + info.dataPosition >
727 		     TEE_DATA_MAX_POSITION ||
728 		     (uint32_t)offset + info.dataPosition <
729 		     info.dataPosition)) {
730 			res = TEE_ERROR_OVERFLOW;
731 			goto out;
732 		}
733 		break;
734 	case TEE_DATA_SEEK_END:
735 		if (offset > 0 &&
736 		    ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
737 		     (uint32_t)offset + info.dataSize < info.dataSize)) {
738 			res = TEE_ERROR_OVERFLOW;
739 			goto out;
740 		}
741 		break;
742 	default:
743 		res = TEE_ERROR_ITEM_NOT_FOUND;
744 		goto out;
745 	}
746 
747 	res = utee_storage_obj_seek(object, offset, whence);
748 
749 out:
750 	if (res != TEE_SUCCESS &&
751 	    res != TEE_ERROR_OVERFLOW &&
752 	    res != TEE_ERROR_CORRUPT_OBJECT &&
753 	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
754 		TEE_Panic(0);
755 
756 	return res;
757 }
758