xref: /optee_os/lib/libutee/tee_api_objects.c (revision 0ed6a6cae32ff852c94cd8480b7012f678be67cf)
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 	if (res == TEE_SUCCESS)
217 		*object = (TEE_ObjectHandle) obj;
218 
219 	return res;
220 }
221 
222 void TEE_FreeTransientObject(TEE_ObjectHandle object)
223 {
224 	TEE_Result res;
225 	TEE_ObjectInfo info;
226 
227 	if (object == TEE_HANDLE_NULL)
228 		return;
229 
230 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
231 	if (res != TEE_SUCCESS)
232 		TEE_Panic(0);
233 
234 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
235 		TEE_Panic(0);
236 
237 	res = utee_cryp_obj_close((uint32_t)object);
238 	if (res != TEE_SUCCESS)
239 		TEE_Panic(0);
240 }
241 
242 void TEE_ResetTransientObject(TEE_ObjectHandle object)
243 {
244 	TEE_Result res;
245 	TEE_ObjectInfo info;
246 
247 	if (object == TEE_HANDLE_NULL)
248 		return;
249 
250 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
251 	if (res != TEE_SUCCESS)
252 		TEE_Panic(0);
253 
254 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
255 		TEE_Panic(0);
256 
257 	res = utee_cryp_obj_reset((uint32_t)object);
258 	if (res != TEE_SUCCESS)
259 		TEE_Panic(0);
260 }
261 
262 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
263 				       TEE_Attribute *attrs,
264 				       uint32_t attrCount)
265 {
266 	TEE_Result res;
267 	TEE_ObjectInfo info;
268 
269 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
270 	if (res != TEE_SUCCESS)
271 		TEE_Panic(0);
272 
273 	/* Must be a transient object */
274 	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
275 		TEE_Panic(0);
276 
277 	/* Must not be initialized already */
278 	if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
279 		TEE_Panic(0);
280 
281 	res = utee_cryp_obj_populate((uint32_t)object, attrs, 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 			  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 = 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((uint32_t)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(0);
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((uint32_t)destObject, &dst_info);
340 	if (res != TEE_SUCCESS)
341 		goto err;
342 
343 	res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info);
344 	if (res != TEE_SUCCESS)
345 		goto err;
346 
347 	if ((src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
348 		TEE_Panic(0);
349 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
350 		TEE_Panic(0);
351 	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
352 		TEE_Panic(0);
353 
354 	res = utee_cryp_obj_copy((uint32_t)destObject, (uint32_t)srcObject);
355 	if (res != TEE_SUCCESS)
356 		TEE_Panic(0);
357 
358 	goto out;
359 
360 err:
361 	if (res == TEE_ERROR_CORRUPT_OBJECT) {
362 		res = utee_storage_obj_del(srcObject);
363 		if (res != TEE_SUCCESS)
364 			TEE_Panic(0);
365 		return TEE_ERROR_CORRUPT_OBJECT;
366 	}
367 	if (res == TEE_ERROR_STORAGE_NOT_AVAILABLE)
368 		return res;
369 	TEE_Panic(0);
370 out:
371 	return TEE_SUCCESS;
372 }
373 
374 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
375 			   TEE_Attribute *params, uint32_t paramCount)
376 {
377 	TEE_Result res;
378 
379 	res = utee_cryp_obj_generate_key((uint32_t)object, keySize,
380 					 params, paramCount);
381 
382 	if (res != TEE_SUCCESS)
383 		TEE_Panic(0);
384 
385 	return res;
386 }
387 
388 /* Data and Key Storage API  - Persistent Object Functions */
389 
390 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, void *objectID,
391 				    uint32_t objectIDLen, uint32_t flags,
392 				    TEE_ObjectHandle *object)
393 {
394 	if (storageID != TEE_STORAGE_PRIVATE)
395 		return TEE_ERROR_ITEM_NOT_FOUND;
396 
397 	if (objectID == NULL)
398 		return TEE_ERROR_ITEM_NOT_FOUND;
399 
400 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN)
401 		TEE_Panic(0);
402 
403 	if (object == NULL)
404 		return TEE_ERROR_BAD_PARAMETERS;
405 
406 	return utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
407 				     object);
408 }
409 
410 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, void *objectID,
411 				      uint32_t objectIDLen, uint32_t flags,
412 				      TEE_ObjectHandle attributes,
413 				      const void *initialData,
414 				      uint32_t initialDataLen,
415 				      TEE_ObjectHandle *object)
416 {
417 	if (storageID != TEE_STORAGE_PRIVATE)
418 		return TEE_ERROR_ITEM_NOT_FOUND;
419 
420 	if (objectID == NULL)
421 		return TEE_ERROR_ITEM_NOT_FOUND;
422 
423 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN)
424 		TEE_Panic(0);
425 
426 	if (object == NULL)
427 		return TEE_ERROR_BAD_PARAMETERS;
428 
429 	return utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
430 				       attributes, initialData, initialDataLen,
431 				       object);
432 }
433 
434 /*
435  * Use of this function is deprecated
436  * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
437  * These functions will be removed at some future major revision of
438  * this specification
439  */
440 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
441 {
442 	TEE_Result res;
443 
444 	if (object == TEE_HANDLE_NULL)
445 		return;
446 
447 	res = TEE_CloseAndDeletePersistentObject1(object);
448 
449 	if (res != TEE_SUCCESS)
450 		TEE_Panic(0);
451 }
452 
453 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
454 {
455 	TEE_Result res;
456 
457 	if (object == TEE_HANDLE_NULL)
458 		return TEE_ERROR_STORAGE_NOT_AVAILABLE;
459 
460 	res = utee_storage_obj_del(object);
461 
462 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
463 		TEE_Panic(0);
464 
465 	return res;
466 }
467 
468 
469 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
470 				      const void *newObjectID,
471 				      uint32_t newObjectIDLen)
472 {
473 	TEE_Result res;
474 
475 	if (object == TEE_HANDLE_NULL)
476 		return TEE_ERROR_ITEM_NOT_FOUND;
477 
478 	if (newObjectID == NULL)
479 		return TEE_ERROR_BAD_PARAMETERS;
480 
481 	if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN)
482 		TEE_Panic(0);
483 
484 	res = utee_storage_obj_rename(object, newObjectID, newObjectIDLen);
485 
486 	if (res != TEE_SUCCESS && res != TEE_ERROR_ACCESS_CONFLICT)
487 		TEE_Panic(0);
488 
489 	return res;
490 }
491 
492 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
493 						  objectEnumerator)
494 {
495 	TEE_Result res;
496 
497 	if (objectEnumerator == NULL)
498 		return TEE_ERROR_BAD_PARAMETERS;
499 
500 	res = utee_storage_alloc_enum(objectEnumerator);
501 
502 	if (res != TEE_SUCCESS)
503 		*objectEnumerator = TEE_HANDLE_NULL;
504 
505 	return res;
506 }
507 
508 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
509 {
510 	TEE_Result res;
511 
512 	if (objectEnumerator == TEE_HANDLE_NULL)
513 		return;
514 
515 	res = utee_storage_free_enum(objectEnumerator);
516 
517 	if (res != TEE_SUCCESS)
518 		TEE_Panic(0);
519 }
520 
521 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
522 {
523 	TEE_Result res;
524 
525 	if (objectEnumerator == TEE_HANDLE_NULL)
526 		return;
527 
528 	res = utee_storage_reset_enum(objectEnumerator);
529 
530 	if (res != TEE_SUCCESS)
531 		TEE_Panic(0);
532 }
533 
534 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
535 					       objectEnumerator,
536 					       uint32_t storageID)
537 {
538 	TEE_Result res;
539 
540 	if (storageID != TEE_STORAGE_PRIVATE)
541 		return TEE_ERROR_ITEM_NOT_FOUND;
542 
543 	res = utee_storage_start_enum(objectEnumerator, storageID);
544 
545 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
546 		TEE_Panic(0);
547 
548 	return res;
549 }
550 
551 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
552 				       TEE_ObjectInfo *objectInfo,
553 				       void *objectID, uint32_t *objectIDLen)
554 {
555 	TEE_Result res;
556 
557 	res =
558 	    utee_storage_next_enum(objectEnumerator, objectInfo, objectID,
559 				   objectIDLen);
560 
561 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
562 		TEE_Panic(0);
563 
564 	return res;
565 }
566 
567 /* Data and Key Storage API  - Data Stream Access Functions */
568 
569 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
570 			      uint32_t size, uint32_t *count)
571 {
572 	TEE_Result res;
573 
574 	if (object == TEE_HANDLE_NULL)
575 		TEE_Panic(0);
576 
577 	res = utee_storage_obj_read(object, buffer, size, count);
578 
579 	if (res != TEE_SUCCESS)
580 		TEE_Panic(0);
581 
582 	return res;
583 }
584 
585 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void *buffer,
586 			       uint32_t size)
587 {
588 	TEE_Result res;
589 
590 	if (object == TEE_HANDLE_NULL)
591 		TEE_Panic(0);
592 
593 	res = utee_storage_obj_write(object, buffer, size);
594 
595 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE)
596 		TEE_Panic(0);
597 
598 	return res;
599 }
600 
601 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
602 {
603 	TEE_Result res;
604 
605 	if (object == TEE_HANDLE_NULL)
606 		TEE_Panic(0);
607 
608 	res = utee_storage_obj_trunc(object, size);
609 
610 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE)
611 		TEE_Panic(0);
612 
613 	return res;
614 }
615 
616 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
617 			      TEE_Whence whence)
618 {
619 	TEE_Result res;
620 	TEE_ObjectInfo info;
621 
622 	if (object == TEE_HANDLE_NULL)
623 		TEE_Panic(0);
624 
625 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
626 	if (res != TEE_SUCCESS)
627 		TEE_Panic(0);
628 
629 	switch (whence) {
630 	case TEE_DATA_SEEK_SET:
631 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION)
632 			return TEE_ERROR_OVERFLOW;
633 		break;
634 	case TEE_DATA_SEEK_CUR:
635 		if (offset > 0 &&
636 		    ((uint32_t)offset + info.dataPosition >
637 		     TEE_DATA_MAX_POSITION ||
638 		     (uint32_t)offset + info.dataPosition <
639 		     info.dataPosition))
640 			return TEE_ERROR_OVERFLOW;
641 		break;
642 	case TEE_DATA_SEEK_END:
643 		if (offset > 0 &&
644 		    ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
645 		     (uint32_t)offset + info.dataSize < info.dataSize))
646 			return TEE_ERROR_OVERFLOW;
647 		break;
648 	default:
649 		TEE_Panic(0);
650 	}
651 
652 	res = utee_storage_obj_seek(object, offset, whence);
653 
654 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW)
655 		TEE_Panic(0);
656 
657 	return res;
658 }
659