xref: /optee_os/lib/libutee/tee_api_objects.c (revision 84431ae3c2986ea4ae4de3e67d17e4c0d2d22517)
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 	TEE_Result res;
418 
419 	if (storageID != TEE_STORAGE_PRIVATE) {
420 		res = TEE_ERROR_ITEM_NOT_FOUND;
421 		goto err;
422 	}
423 
424 	if (objectID == NULL) {
425 		res = TEE_ERROR_ITEM_NOT_FOUND;
426 		goto err;
427 	}
428 
429 	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
430 		res = TEE_ERROR_BAD_PARAMETERS;
431 		goto err;
432 	}
433 
434 	if (object == NULL) {
435 		res = TEE_ERROR_BAD_PARAMETERS;
436 		goto err;
437 	}
438 
439 	res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
440 				       attributes, initialData, initialDataLen,
441 				       object);
442 	if (res == TEE_SUCCESS)
443 		goto out;
444 err:
445 	if (res == TEE_ERROR_ITEM_NOT_FOUND ||
446 	    res == TEE_ERROR_ACCESS_CONFLICT ||
447 	    res == TEE_ERROR_OUT_OF_MEMORY ||
448 	    res == TEE_ERROR_STORAGE_NO_SPACE ||
449 	    res == TEE_ERROR_CORRUPT_OBJECT ||
450 	    res == TEE_ERROR_STORAGE_NOT_AVAILABLE)
451 		return res;
452 	TEE_Panic(0);
453 out:
454 	return TEE_SUCCESS;
455 }
456 
457 /*
458  * Use of this function is deprecated
459  * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
460  * These functions will be removed at some future major revision of
461  * this specification
462  */
463 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
464 {
465 	TEE_Result res;
466 
467 	if (object == TEE_HANDLE_NULL)
468 		return;
469 
470 	res = TEE_CloseAndDeletePersistentObject1(object);
471 
472 	if (res != TEE_SUCCESS)
473 		TEE_Panic(0);
474 }
475 
476 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
477 {
478 	TEE_Result res;
479 
480 	if (object == TEE_HANDLE_NULL)
481 		return TEE_ERROR_STORAGE_NOT_AVAILABLE;
482 
483 	res = utee_storage_obj_del(object);
484 
485 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
486 		TEE_Panic(0);
487 
488 	return res;
489 }
490 
491 
492 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
493 				      const void *newObjectID,
494 				      uint32_t newObjectIDLen)
495 {
496 	TEE_Result res;
497 
498 	if (object == TEE_HANDLE_NULL)
499 		return TEE_ERROR_ITEM_NOT_FOUND;
500 
501 	if (newObjectID == NULL)
502 		return TEE_ERROR_BAD_PARAMETERS;
503 
504 	if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN)
505 		TEE_Panic(0);
506 
507 	res = utee_storage_obj_rename(object, newObjectID, newObjectIDLen);
508 
509 	if (res != TEE_SUCCESS && res != TEE_ERROR_ACCESS_CONFLICT)
510 		TEE_Panic(0);
511 
512 	return res;
513 }
514 
515 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
516 						  objectEnumerator)
517 {
518 	TEE_Result res;
519 
520 	if (objectEnumerator == NULL)
521 		return TEE_ERROR_BAD_PARAMETERS;
522 
523 	res = utee_storage_alloc_enum(objectEnumerator);
524 
525 	if (res != TEE_SUCCESS)
526 		*objectEnumerator = TEE_HANDLE_NULL;
527 
528 	return res;
529 }
530 
531 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
532 {
533 	TEE_Result res;
534 
535 	if (objectEnumerator == TEE_HANDLE_NULL)
536 		return;
537 
538 	res = utee_storage_free_enum(objectEnumerator);
539 
540 	if (res != TEE_SUCCESS)
541 		TEE_Panic(0);
542 }
543 
544 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
545 {
546 	TEE_Result res;
547 
548 	if (objectEnumerator == TEE_HANDLE_NULL)
549 		return;
550 
551 	res = utee_storage_reset_enum(objectEnumerator);
552 
553 	if (res != TEE_SUCCESS)
554 		TEE_Panic(0);
555 }
556 
557 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
558 					       objectEnumerator,
559 					       uint32_t storageID)
560 {
561 	TEE_Result res;
562 
563 	if (storageID != TEE_STORAGE_PRIVATE)
564 		return TEE_ERROR_ITEM_NOT_FOUND;
565 
566 	res = utee_storage_start_enum(objectEnumerator, storageID);
567 
568 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
569 		TEE_Panic(0);
570 
571 	return res;
572 }
573 
574 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
575 				       TEE_ObjectInfo *objectInfo,
576 				       void *objectID, uint32_t *objectIDLen)
577 {
578 	TEE_Result res;
579 
580 	res =
581 	    utee_storage_next_enum(objectEnumerator, objectInfo, objectID,
582 				   objectIDLen);
583 
584 	if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
585 		TEE_Panic(0);
586 
587 	return res;
588 }
589 
590 /* Data and Key Storage API  - Data Stream Access Functions */
591 
592 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
593 			      uint32_t size, uint32_t *count)
594 {
595 	TEE_Result res;
596 
597 	if (object == TEE_HANDLE_NULL)
598 		TEE_Panic(0);
599 
600 	res = utee_storage_obj_read(object, buffer, size, count);
601 
602 	if (res != TEE_SUCCESS)
603 		TEE_Panic(0);
604 
605 	return res;
606 }
607 
608 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void *buffer,
609 			       uint32_t size)
610 {
611 	TEE_Result res;
612 
613 	if (object == TEE_HANDLE_NULL)
614 		TEE_Panic(0);
615 
616 	res = utee_storage_obj_write(object, buffer, size);
617 
618 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE)
619 		TEE_Panic(0);
620 
621 	return res;
622 }
623 
624 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
625 {
626 	TEE_Result res;
627 
628 	if (object == TEE_HANDLE_NULL)
629 		TEE_Panic(0);
630 
631 	res = utee_storage_obj_trunc(object, size);
632 
633 	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE)
634 		TEE_Panic(0);
635 
636 	return res;
637 }
638 
639 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
640 			      TEE_Whence whence)
641 {
642 	TEE_Result res;
643 	TEE_ObjectInfo info;
644 
645 	if (object == TEE_HANDLE_NULL)
646 		TEE_Panic(0);
647 
648 	res = utee_cryp_obj_get_info((uint32_t)object, &info);
649 	if (res != TEE_SUCCESS)
650 		TEE_Panic(0);
651 
652 	switch (whence) {
653 	case TEE_DATA_SEEK_SET:
654 		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION)
655 			return TEE_ERROR_OVERFLOW;
656 		break;
657 	case TEE_DATA_SEEK_CUR:
658 		if (offset > 0 &&
659 		    ((uint32_t)offset + info.dataPosition >
660 		     TEE_DATA_MAX_POSITION ||
661 		     (uint32_t)offset + info.dataPosition <
662 		     info.dataPosition))
663 			return TEE_ERROR_OVERFLOW;
664 		break;
665 	case TEE_DATA_SEEK_END:
666 		if (offset > 0 &&
667 		    ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
668 		     (uint32_t)offset + info.dataSize < info.dataSize))
669 			return TEE_ERROR_OVERFLOW;
670 		break;
671 	default:
672 		TEE_Panic(0);
673 	}
674 
675 	res = utee_storage_obj_seek(object, offset, whence);
676 
677 	if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW)
678 		TEE_Panic(0);
679 
680 	return res;
681 }
682