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 void __utee_from_attr(struct utee_attribute *ua, const TEE_Attribute *attrs, 15 uint32_t attr_count) 16 { 17 size_t n; 18 19 for (n = 0; n < attr_count; n++) { 20 ua[n].attribute_id = attrs[n].attributeID; 21 if (attrs[n].attributeID & TEE_ATTR_FLAG_VALUE) { 22 ua[n].a = attrs[n].content.value.a; 23 ua[n].b = attrs[n].content.value.b; 24 } else { 25 ua[n].a = (uintptr_t)attrs[n].content.ref.buffer; 26 ua[n].b = attrs[n].content.ref.length; 27 } 28 } 29 } 30 31 /* Data and Key Storage API - Generic Object Functions */ 32 /* 33 * Use of this function is deprecated 34 * new code SHOULD use the TEE_GetObjectInfo1 function instead 35 * These functions will be removed at some future major revision of 36 * this specification 37 */ 38 void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 39 { 40 TEE_Result res; 41 42 res = _utee_cryp_obj_get_info((unsigned long)object, objectInfo); 43 44 if (res != TEE_SUCCESS) 45 TEE_Panic(res); 46 47 if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) { 48 objectInfo->keySize = 0; 49 objectInfo->maxKeySize = 0; 50 objectInfo->objectUsage = 0; 51 objectInfo->dataSize = 0; 52 objectInfo->dataPosition = 0; 53 objectInfo->handleFlags = 0; 54 } 55 } 56 57 TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 58 { 59 TEE_Result res; 60 61 res = _utee_cryp_obj_get_info((unsigned long)object, objectInfo); 62 63 if (res != TEE_SUCCESS && 64 res != TEE_ERROR_CORRUPT_OBJECT && 65 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 66 TEE_Panic(res); 67 68 return res; 69 } 70 71 /* 72 * Use of this function is deprecated 73 * new code SHOULD use the TEE_RestrictObjectUsage1 function instead 74 * These functions will be removed at some future major revision of 75 * this specification 76 */ 77 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) 78 { 79 TEE_Result res; 80 TEE_ObjectInfo objectInfo; 81 82 res = _utee_cryp_obj_get_info((unsigned long)object, &objectInfo); 83 if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT) 84 return; 85 86 res = TEE_RestrictObjectUsage1(object, objectUsage); 87 88 if (res != TEE_SUCCESS) 89 TEE_Panic(res); 90 } 91 92 TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage) 93 { 94 TEE_Result res; 95 96 res = _utee_cryp_obj_restrict_usage((unsigned long)object, 97 objectUsage); 98 99 if (res != TEE_SUCCESS && 100 res != TEE_ERROR_CORRUPT_OBJECT && 101 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 102 TEE_Panic(res); 103 104 return res; 105 } 106 107 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 108 uint32_t attributeID, void *buffer, 109 uint32_t *size) 110 { 111 TEE_Result res; 112 TEE_ObjectInfo info; 113 uint64_t sz; 114 115 __utee_check_inout_annotation(size, sizeof(*size)); 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_FLAG_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 if (a) 153 __utee_check_out_annotation(a, sizeof(*a)); 154 if (b) 155 __utee_check_out_annotation(b, sizeof(*b)); 156 157 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 158 if (res != TEE_SUCCESS) 159 goto exit; 160 161 /* This function only supports value attributes */ 162 if (!(attributeID & TEE_ATTR_FLAG_VALUE)) { 163 res = TEE_ERROR_BAD_PARAMETERS; 164 goto exit; 165 } 166 167 res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf, 168 &size); 169 170 exit: 171 if (res != TEE_SUCCESS && 172 res != TEE_ERROR_ITEM_NOT_FOUND && 173 res != TEE_ERROR_CORRUPT_OBJECT && 174 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 175 TEE_Panic(res); 176 177 if (size != sizeof(buf)) 178 TEE_Panic(0); 179 180 if (res == TEE_SUCCESS) { 181 if (a) 182 *a = buf[0]; 183 if (b) 184 *b = buf[1]; 185 } 186 187 return res; 188 } 189 190 void TEE_CloseObject(TEE_ObjectHandle object) 191 { 192 TEE_Result res; 193 194 if (object == TEE_HANDLE_NULL) 195 return; 196 197 res = _utee_cryp_obj_close((unsigned long)object); 198 if (res != TEE_SUCCESS) 199 TEE_Panic(res); 200 } 201 202 /* Data and Key Storage API - Transient Object Functions */ 203 204 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 205 uint32_t maxKeySize, 206 TEE_ObjectHandle *object) 207 { 208 TEE_Result res; 209 uint32_t obj; 210 211 __utee_check_out_annotation(object, sizeof(*object)); 212 213 res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 214 215 if (res != TEE_SUCCESS && 216 res != TEE_ERROR_OUT_OF_MEMORY && 217 res != TEE_ERROR_NOT_SUPPORTED) 218 TEE_Panic(res); 219 220 if (res == TEE_SUCCESS) 221 *object = (TEE_ObjectHandle)(uintptr_t)obj; 222 223 return res; 224 } 225 226 void TEE_FreeTransientObject(TEE_ObjectHandle object) 227 { 228 TEE_Result res; 229 TEE_ObjectInfo info; 230 231 if (object == TEE_HANDLE_NULL) 232 return; 233 234 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 235 if (res != TEE_SUCCESS) 236 TEE_Panic(res); 237 238 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 239 TEE_Panic(0); 240 241 res = _utee_cryp_obj_close((unsigned long)object); 242 if (res != TEE_SUCCESS) 243 TEE_Panic(res); 244 } 245 246 void TEE_ResetTransientObject(TEE_ObjectHandle object) 247 { 248 TEE_Result res; 249 TEE_ObjectInfo info; 250 251 if (object == TEE_HANDLE_NULL) 252 return; 253 254 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 255 if (res != TEE_SUCCESS) 256 TEE_Panic(res); 257 258 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 259 TEE_Panic(0); 260 261 res = _utee_cryp_obj_reset((unsigned long)object); 262 if (res != TEE_SUCCESS) 263 TEE_Panic(res); 264 } 265 266 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 267 const TEE_Attribute *attrs, 268 uint32_t attrCount) 269 { 270 TEE_Result res; 271 TEE_ObjectInfo info; 272 struct utee_attribute ua[attrCount]; 273 274 __utee_check_attr_in_annotation(attrs, attrCount); 275 276 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 277 if (res != TEE_SUCCESS) 278 TEE_Panic(res); 279 280 /* Must be a transient object */ 281 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 282 TEE_Panic(0); 283 284 /* Must not be initialized already */ 285 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 286 TEE_Panic(0); 287 288 __utee_from_attr(ua, attrs, attrCount); 289 res = _utee_cryp_obj_populate((unsigned long)object, ua, attrCount); 290 if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 291 TEE_Panic(res); 292 return res; 293 } 294 295 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID, 296 const void *buffer, uint32_t length) 297 { 298 __utee_check_out_annotation(attr, sizeof(*attr)); 299 300 if ((attributeID & TEE_ATTR_FLAG_VALUE) != 0) 301 TEE_Panic(0); 302 attr->attributeID = attributeID; 303 attr->content.ref.buffer = (void *)buffer; 304 attr->content.ref.length = length; 305 } 306 307 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, 308 uint32_t a, uint32_t b) 309 { 310 __utee_check_out_annotation(attr, sizeof(*attr)); 311 312 if ((attributeID & TEE_ATTR_FLAG_VALUE) == 0) 313 TEE_Panic(0); 314 attr->attributeID = attributeID; 315 attr->content.value.a = a; 316 attr->content.value.b = b; 317 } 318 319 /* 320 * Use of this function is deprecated 321 * new code SHOULD use the TEE_CopyObjectAttributes1 function instead 322 * These functions will be removed at some future major revision of 323 * this specification 324 */ 325 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, 326 TEE_ObjectHandle srcObject) 327 { 328 TEE_Result res; 329 TEE_ObjectInfo src_info; 330 331 res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 332 if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT) 333 return; 334 335 res = TEE_CopyObjectAttributes1(destObject, srcObject); 336 if (res != TEE_SUCCESS) 337 TEE_Panic(res); 338 } 339 340 TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject, 341 TEE_ObjectHandle srcObject) 342 { 343 TEE_Result res; 344 TEE_ObjectInfo dst_info; 345 TEE_ObjectInfo src_info; 346 347 res = _utee_cryp_obj_get_info((unsigned long)destObject, &dst_info); 348 if (res != TEE_SUCCESS) 349 goto exit; 350 351 res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 352 if (res != TEE_SUCCESS) 353 goto exit; 354 355 if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 356 TEE_Panic(0); 357 358 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) 359 TEE_Panic(0); 360 361 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 362 TEE_Panic(0); 363 364 res = _utee_cryp_obj_copy((unsigned long)destObject, 365 (unsigned long)srcObject); 366 367 exit: 368 if (res != TEE_SUCCESS && 369 res != TEE_ERROR_CORRUPT_OBJECT && 370 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 371 TEE_Panic(res); 372 373 return res; 374 } 375 376 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 377 const TEE_Attribute *params, uint32_t paramCount) 378 { 379 TEE_Result res; 380 struct utee_attribute ua[paramCount]; 381 382 __utee_check_attr_in_annotation(params, paramCount); 383 384 __utee_from_attr(ua, params, paramCount); 385 res = _utee_cryp_obj_generate_key((unsigned long)object, keySize, 386 ua, paramCount); 387 388 if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 389 TEE_Panic(res); 390 391 return res; 392 } 393 394 /* Data and Key Storage API - Persistent Object Functions */ 395 396 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, 397 uint32_t objectIDLen, uint32_t flags, 398 TEE_ObjectHandle *object) 399 { 400 TEE_Result res; 401 uint32_t obj; 402 403 __utee_check_out_annotation(object, sizeof(*object)); 404 405 res = _utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 406 &obj); 407 if (res == TEE_SUCCESS) 408 *object = (TEE_ObjectHandle)(uintptr_t)obj; 409 410 if (res != TEE_SUCCESS && 411 res != TEE_ERROR_ITEM_NOT_FOUND && 412 res != TEE_ERROR_ACCESS_CONFLICT && 413 res != TEE_ERROR_OUT_OF_MEMORY && 414 res != TEE_ERROR_CORRUPT_OBJECT && 415 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 416 TEE_Panic(res); 417 418 if (res != TEE_SUCCESS) 419 *object = TEE_HANDLE_NULL; 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 __utee_check_out_annotation(object, sizeof(*object)); 435 436 res = _utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 437 (unsigned long)attributes, initialData, 438 initialDataLen, &obj); 439 440 if (res == TEE_SUCCESS) 441 *object = (TEE_ObjectHandle)(uintptr_t)obj; 442 443 if (res != TEE_SUCCESS && 444 res != TEE_ERROR_ITEM_NOT_FOUND && 445 res != TEE_ERROR_ACCESS_CONFLICT && 446 res != TEE_ERROR_OUT_OF_MEMORY && 447 res != TEE_ERROR_STORAGE_NO_SPACE && 448 res != TEE_ERROR_CORRUPT_OBJECT && 449 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 450 TEE_Panic(res); 451 452 if (res != TEE_SUCCESS) 453 *object = TEE_HANDLE_NULL; 454 455 return res; 456 } 457 458 /* 459 * Use of this function is deprecated 460 * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead 461 * These functions will be removed at some future major revision of 462 * this specification 463 */ 464 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 465 { 466 TEE_Result res; 467 468 if (object == TEE_HANDLE_NULL) 469 return; 470 471 res = TEE_CloseAndDeletePersistentObject1(object); 472 473 if (res != TEE_SUCCESS) 474 TEE_Panic(0); 475 } 476 477 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object) 478 { 479 TEE_Result res; 480 481 if (object == TEE_HANDLE_NULL) 482 return TEE_SUCCESS; 483 484 res = _utee_storage_obj_del((unsigned long)object); 485 486 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 487 TEE_Panic(res); 488 489 return res; 490 } 491 492 493 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 494 const void *newObjectID, 495 uint32_t newObjectIDLen) 496 { 497 TEE_Result res; 498 499 if (object == TEE_HANDLE_NULL) { 500 res = TEE_ERROR_ITEM_NOT_FOUND; 501 goto out; 502 } 503 504 res = _utee_storage_obj_rename((unsigned long)object, newObjectID, 505 newObjectIDLen); 506 507 out: 508 if (res != TEE_SUCCESS && 509 res != TEE_ERROR_ACCESS_CONFLICT && 510 res != TEE_ERROR_CORRUPT_OBJECT && 511 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 512 TEE_Panic(res); 513 514 return res; 515 } 516 517 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 518 objectEnumerator) 519 { 520 TEE_Result res; 521 uint32_t oe; 522 523 __utee_check_out_annotation(objectEnumerator, 524 sizeof(*objectEnumerator)); 525 526 res = _utee_storage_alloc_enum(&oe); 527 528 if (res != TEE_SUCCESS) 529 oe = TEE_HANDLE_NULL; 530 531 *objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe; 532 533 if (res != TEE_SUCCESS && 534 res != TEE_ERROR_ACCESS_CONFLICT) 535 TEE_Panic(res); 536 537 return res; 538 } 539 540 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 541 { 542 TEE_Result res; 543 544 if (objectEnumerator == TEE_HANDLE_NULL) 545 return; 546 547 res = _utee_storage_free_enum((unsigned long)objectEnumerator); 548 549 if (res != TEE_SUCCESS) 550 TEE_Panic(res); 551 } 552 553 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 554 { 555 TEE_Result res; 556 557 if (objectEnumerator == TEE_HANDLE_NULL) 558 return; 559 560 res = _utee_storage_reset_enum((unsigned long)objectEnumerator); 561 562 if (res != TEE_SUCCESS) 563 TEE_Panic(res); 564 } 565 566 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 567 objectEnumerator, 568 uint32_t storageID) 569 { 570 TEE_Result res; 571 572 res = _utee_storage_start_enum((unsigned long)objectEnumerator, 573 storageID); 574 575 if (res != TEE_SUCCESS && 576 res != TEE_ERROR_ITEM_NOT_FOUND && 577 res != TEE_ERROR_CORRUPT_OBJECT && 578 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 579 TEE_Panic(res); 580 581 return res; 582 } 583 584 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, 585 TEE_ObjectInfo *objectInfo, 586 void *objectID, uint32_t *objectIDLen) 587 { 588 TEE_Result res; 589 uint64_t len; 590 TEE_ObjectInfo local_info; 591 TEE_ObjectInfo *pt_info; 592 593 if (objectInfo) 594 __utee_check_out_annotation(objectInfo, sizeof(*objectInfo)); 595 __utee_check_out_annotation(objectIDLen, sizeof(*objectIDLen)); 596 597 if (!objectID) { 598 res = TEE_ERROR_BAD_PARAMETERS; 599 goto out; 600 } 601 602 if (objectInfo) 603 pt_info = objectInfo; 604 else 605 pt_info = &local_info; 606 len = *objectIDLen; 607 res = _utee_storage_next_enum((unsigned long)objectEnumerator, 608 pt_info, objectID, &len); 609 *objectIDLen = len; 610 611 out: 612 if (res != TEE_SUCCESS && 613 res != TEE_ERROR_ITEM_NOT_FOUND && 614 res != TEE_ERROR_CORRUPT_OBJECT && 615 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 616 TEE_Panic(res); 617 618 return res; 619 } 620 621 /* Data and Key Storage API - Data Stream Access Functions */ 622 623 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 624 uint32_t size, uint32_t *count) 625 { 626 TEE_Result res; 627 uint64_t cnt64; 628 629 if (object == TEE_HANDLE_NULL) { 630 res = TEE_ERROR_BAD_PARAMETERS; 631 goto out; 632 } 633 __utee_check_out_annotation(count, sizeof(*count)); 634 635 cnt64 = *count; 636 res = _utee_storage_obj_read((unsigned long)object, buffer, size, 637 &cnt64); 638 *count = cnt64; 639 640 out: 641 if (res != TEE_SUCCESS && 642 res != TEE_ERROR_CORRUPT_OBJECT && 643 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 644 TEE_Panic(res); 645 646 return res; 647 } 648 649 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, 650 uint32_t size) 651 { 652 TEE_Result res; 653 654 if (object == TEE_HANDLE_NULL) { 655 res = TEE_ERROR_BAD_PARAMETERS; 656 goto out; 657 } 658 659 if (size > TEE_DATA_MAX_POSITION) { 660 res = TEE_ERROR_OVERFLOW; 661 goto out; 662 } 663 664 res = _utee_storage_obj_write((unsigned long)object, buffer, size); 665 666 out: 667 if (res != TEE_SUCCESS && 668 res != TEE_ERROR_STORAGE_NO_SPACE && 669 res != TEE_ERROR_OVERFLOW && 670 res != TEE_ERROR_CORRUPT_OBJECT && 671 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 672 TEE_Panic(res); 673 674 return res; 675 } 676 677 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 678 { 679 TEE_Result res; 680 681 if (object == TEE_HANDLE_NULL) { 682 res = TEE_ERROR_BAD_PARAMETERS; 683 goto out; 684 } 685 686 res = _utee_storage_obj_trunc((unsigned long)object, size); 687 688 out: 689 if (res != TEE_SUCCESS && 690 res != TEE_ERROR_STORAGE_NO_SPACE && 691 res != TEE_ERROR_CORRUPT_OBJECT && 692 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 693 TEE_Panic(res); 694 695 return res; 696 } 697 698 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 699 TEE_Whence whence) 700 { 701 TEE_Result res; 702 TEE_ObjectInfo info; 703 704 if (object == TEE_HANDLE_NULL) { 705 res = TEE_ERROR_BAD_PARAMETERS; 706 goto out; 707 } 708 709 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 710 if (res != TEE_SUCCESS) 711 goto out; 712 713 switch (whence) { 714 case TEE_DATA_SEEK_SET: 715 if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) { 716 res = TEE_ERROR_OVERFLOW; 717 goto out; 718 } 719 break; 720 case TEE_DATA_SEEK_CUR: 721 if (offset > 0 && 722 ((uint32_t)offset + info.dataPosition > 723 TEE_DATA_MAX_POSITION || 724 (uint32_t)offset + info.dataPosition < 725 info.dataPosition)) { 726 res = TEE_ERROR_OVERFLOW; 727 goto out; 728 } 729 break; 730 case TEE_DATA_SEEK_END: 731 if (offset > 0 && 732 ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION || 733 (uint32_t)offset + info.dataSize < info.dataSize)) { 734 res = TEE_ERROR_OVERFLOW; 735 goto out; 736 } 737 break; 738 default: 739 res = TEE_ERROR_ITEM_NOT_FOUND; 740 goto out; 741 } 742 743 res = _utee_storage_obj_seek((unsigned long)object, offset, whence); 744 745 out: 746 if (res != TEE_SUCCESS && 747 res != TEE_ERROR_OVERFLOW && 748 res != TEE_ERROR_CORRUPT_OBJECT && 749 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 750 TEE_Panic(res); 751 752 return res; 753 } 754