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