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