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