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, 100 objectUsage); 101 102 if (res != TEE_SUCCESS && 103 res != TEE_ERROR_CORRUPT_OBJECT && 104 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 105 TEE_Panic(res); 106 107 return res; 108 } 109 110 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 111 uint32_t attributeID, void *buffer, 112 uint32_t *size) 113 { 114 TEE_Result res; 115 TEE_ObjectInfo info; 116 uint64_t sz; 117 118 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 119 if (res != TEE_SUCCESS) 120 goto exit; 121 122 /* This function only supports reference attributes */ 123 if ((attributeID & TEE_ATTR_BIT_VALUE)) { 124 res = TEE_ERROR_BAD_PARAMETERS; 125 goto exit; 126 } 127 128 sz = *size; 129 res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, 130 buffer, &sz); 131 *size = sz; 132 133 exit: 134 if (res != TEE_SUCCESS && 135 res != TEE_ERROR_ITEM_NOT_FOUND && 136 res != TEE_ERROR_SHORT_BUFFER && 137 res != TEE_ERROR_CORRUPT_OBJECT && 138 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 139 TEE_Panic(res); 140 141 return res; 142 } 143 144 TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object, 145 uint32_t attributeID, uint32_t *a, 146 uint32_t *b) 147 { 148 TEE_Result res; 149 TEE_ObjectInfo info; 150 uint32_t buf[2]; 151 uint64_t size = sizeof(buf); 152 153 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 154 if (res != TEE_SUCCESS) 155 goto exit; 156 157 /* This function only supports value attributes */ 158 if (!(attributeID & TEE_ATTR_BIT_VALUE)) { 159 res = TEE_ERROR_BAD_PARAMETERS; 160 goto exit; 161 } 162 163 res = _utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf, 164 &size); 165 166 exit: 167 if (res != TEE_SUCCESS && 168 res != TEE_ERROR_ITEM_NOT_FOUND && 169 res != TEE_ERROR_CORRUPT_OBJECT && 170 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 171 TEE_Panic(res); 172 173 if (size != sizeof(buf)) 174 TEE_Panic(0); 175 176 if (res == TEE_SUCCESS) { 177 if (a) 178 *a = buf[0]; 179 if (b) 180 *b = buf[1]; 181 } 182 183 return res; 184 } 185 186 void TEE_CloseObject(TEE_ObjectHandle object) 187 { 188 TEE_Result res; 189 190 if (object == TEE_HANDLE_NULL) 191 return; 192 193 res = _utee_cryp_obj_close((unsigned long)object); 194 if (res != TEE_SUCCESS) 195 TEE_Panic(res); 196 } 197 198 /* Data and Key Storage API - Transient Object Functions */ 199 200 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 201 uint32_t maxKeySize, 202 TEE_ObjectHandle *object) 203 { 204 TEE_Result res; 205 uint32_t obj; 206 207 res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 208 209 if (res != TEE_SUCCESS && 210 res != TEE_ERROR_OUT_OF_MEMORY && 211 res != TEE_ERROR_NOT_SUPPORTED) 212 TEE_Panic(res); 213 214 if (res == TEE_SUCCESS) 215 *object = (TEE_ObjectHandle)(uintptr_t)obj; 216 217 return res; 218 } 219 220 void TEE_FreeTransientObject(TEE_ObjectHandle object) 221 { 222 TEE_Result res; 223 TEE_ObjectInfo info; 224 225 if (object == TEE_HANDLE_NULL) 226 return; 227 228 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 229 if (res != TEE_SUCCESS) 230 TEE_Panic(res); 231 232 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 233 TEE_Panic(0); 234 235 res = _utee_cryp_obj_close((unsigned long)object); 236 if (res != TEE_SUCCESS) 237 TEE_Panic(res); 238 } 239 240 void TEE_ResetTransientObject(TEE_ObjectHandle object) 241 { 242 TEE_Result res; 243 TEE_ObjectInfo info; 244 245 if (object == TEE_HANDLE_NULL) 246 return; 247 248 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 249 if (res != TEE_SUCCESS) 250 TEE_Panic(res); 251 252 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 253 TEE_Panic(0); 254 255 res = _utee_cryp_obj_reset((unsigned long)object); 256 if (res != TEE_SUCCESS) 257 TEE_Panic(res); 258 } 259 260 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 261 const TEE_Attribute *attrs, 262 uint32_t attrCount) 263 { 264 TEE_Result res; 265 TEE_ObjectInfo info; 266 struct utee_attribute ua[attrCount]; 267 268 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 269 if (res != TEE_SUCCESS) 270 TEE_Panic(res); 271 272 /* Must be a transient object */ 273 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 274 TEE_Panic(0); 275 276 /* Must not be initialized already */ 277 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 278 TEE_Panic(0); 279 280 __utee_from_attr(ua, attrs, attrCount); 281 res = _utee_cryp_obj_populate((unsigned long)object, ua, 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 const 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 = (void *)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((unsigned long)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(res); 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((unsigned long)destObject, &dst_info); 340 if (res != TEE_SUCCESS) 341 goto exit; 342 343 res = _utee_cryp_obj_get_info((unsigned long)srcObject, &src_info); 344 if (res != TEE_SUCCESS) 345 goto exit; 346 347 if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 348 TEE_Panic(0); 349 350 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) 351 TEE_Panic(0); 352 353 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 354 TEE_Panic(0); 355 356 res = _utee_cryp_obj_copy((unsigned long)destObject, 357 (unsigned long)srcObject); 358 359 exit: 360 if (res != TEE_SUCCESS && 361 res != TEE_ERROR_CORRUPT_OBJECT && 362 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 363 TEE_Panic(res); 364 365 return res; 366 } 367 368 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 369 const TEE_Attribute *params, uint32_t paramCount) 370 { 371 TEE_Result res; 372 struct utee_attribute ua[paramCount]; 373 374 __utee_from_attr(ua, params, paramCount); 375 res = _utee_cryp_obj_generate_key((unsigned long)object, keySize, 376 ua, paramCount); 377 378 if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 379 TEE_Panic(res); 380 381 return res; 382 } 383 384 /* Data and Key Storage API - Persistent Object Functions */ 385 386 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, 387 uint32_t objectIDLen, uint32_t flags, 388 TEE_ObjectHandle *object) 389 { 390 TEE_Result res; 391 uint32_t obj; 392 393 if (!objectID) { 394 res = TEE_ERROR_ITEM_NOT_FOUND; 395 goto exit; 396 } 397 398 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) { 399 res = TEE_ERROR_BAD_PARAMETERS; 400 goto exit; 401 } 402 403 res = _utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 404 &obj); 405 if (res == TEE_SUCCESS) 406 *object = (TEE_ObjectHandle)(uintptr_t)obj; 407 408 exit: 409 if (res != TEE_SUCCESS && 410 res != TEE_ERROR_ITEM_NOT_FOUND && 411 res != TEE_ERROR_ACCESS_CONFLICT && 412 res != TEE_ERROR_OUT_OF_MEMORY && 413 res != TEE_ERROR_CORRUPT_OBJECT && 414 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 415 TEE_Panic(res); 416 417 if (res != TEE_SUCCESS) 418 *object = TEE_HANDLE_NULL; 419 420 return res; 421 } 422 423 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, 424 uint32_t objectIDLen, uint32_t flags, 425 TEE_ObjectHandle attributes, 426 const void *initialData, 427 uint32_t initialDataLen, 428 TEE_ObjectHandle *object) 429 { 430 TEE_Result res; 431 uint32_t obj; 432 433 if (!objectID) { 434 res = TEE_ERROR_ITEM_NOT_FOUND; 435 goto exit; 436 } 437 438 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) { 439 res = TEE_ERROR_BAD_PARAMETERS; 440 goto exit; 441 } 442 443 res = _utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 444 (unsigned long)attributes, initialData, 445 initialDataLen, &obj); 446 447 if (res == TEE_SUCCESS) 448 *object = (TEE_ObjectHandle)(uintptr_t)obj; 449 450 exit: 451 if (res != TEE_SUCCESS && 452 res != TEE_ERROR_ITEM_NOT_FOUND && 453 res != TEE_ERROR_ACCESS_CONFLICT && 454 res != TEE_ERROR_OUT_OF_MEMORY && 455 res != TEE_ERROR_STORAGE_NO_SPACE && 456 res != TEE_ERROR_CORRUPT_OBJECT && 457 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 458 TEE_Panic(res); 459 460 if (res != TEE_SUCCESS) 461 *object = TEE_HANDLE_NULL; 462 463 return res; 464 } 465 466 /* 467 * Use of this function is deprecated 468 * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead 469 * These functions will be removed at some future major revision of 470 * this specification 471 */ 472 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 473 { 474 TEE_Result res; 475 476 if (object == TEE_HANDLE_NULL) 477 return; 478 479 res = TEE_CloseAndDeletePersistentObject1(object); 480 481 if (res != TEE_SUCCESS) 482 TEE_Panic(0); 483 } 484 485 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object) 486 { 487 TEE_Result res; 488 489 if (object == TEE_HANDLE_NULL) 490 return TEE_ERROR_STORAGE_NOT_AVAILABLE; 491 492 res = _utee_storage_obj_del((unsigned long)object); 493 494 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 495 TEE_Panic(res); 496 497 return res; 498 } 499 500 501 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 502 const void *newObjectID, 503 uint32_t newObjectIDLen) 504 { 505 TEE_Result res; 506 507 if (object == TEE_HANDLE_NULL) { 508 res = TEE_ERROR_ITEM_NOT_FOUND; 509 goto out; 510 } 511 512 if (!newObjectID) { 513 res = TEE_ERROR_BAD_PARAMETERS; 514 goto out; 515 } 516 517 if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) { 518 res = TEE_ERROR_BAD_PARAMETERS; 519 goto out; 520 } 521 522 res = _utee_storage_obj_rename((unsigned long)object, newObjectID, 523 newObjectIDLen); 524 525 out: 526 if (res != TEE_SUCCESS && 527 res != TEE_ERROR_ACCESS_CONFLICT && 528 res != TEE_ERROR_CORRUPT_OBJECT && 529 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 530 TEE_Panic(res); 531 532 return res; 533 } 534 535 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 536 objectEnumerator) 537 { 538 TEE_Result res; 539 uint32_t oe; 540 541 if (!objectEnumerator) 542 return TEE_ERROR_BAD_PARAMETERS; 543 544 res = _utee_storage_alloc_enum(&oe); 545 546 if (res != TEE_SUCCESS) 547 oe = TEE_HANDLE_NULL; 548 549 *objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe; 550 551 if (res != TEE_SUCCESS && 552 res != TEE_ERROR_ACCESS_CONFLICT) 553 TEE_Panic(res); 554 555 return res; 556 } 557 558 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 559 { 560 TEE_Result res; 561 562 if (objectEnumerator == TEE_HANDLE_NULL) 563 return; 564 565 res = _utee_storage_free_enum((unsigned long)objectEnumerator); 566 567 if (res != TEE_SUCCESS) 568 TEE_Panic(res); 569 } 570 571 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 572 { 573 TEE_Result res; 574 575 if (objectEnumerator == TEE_HANDLE_NULL) 576 return; 577 578 res = _utee_storage_reset_enum((unsigned long)objectEnumerator); 579 580 if (res != TEE_SUCCESS) 581 TEE_Panic(res); 582 } 583 584 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 585 objectEnumerator, 586 uint32_t storageID) 587 { 588 TEE_Result res; 589 590 res = _utee_storage_start_enum((unsigned long)objectEnumerator, 591 storageID); 592 593 if (res != TEE_SUCCESS && 594 res != TEE_ERROR_ITEM_NOT_FOUND && 595 res != TEE_ERROR_CORRUPT_OBJECT && 596 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 597 TEE_Panic(res); 598 599 return res; 600 } 601 602 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, 603 TEE_ObjectInfo *objectInfo, 604 void *objectID, uint32_t *objectIDLen) 605 { 606 TEE_Result res; 607 uint64_t len; 608 TEE_ObjectInfo local_info; 609 TEE_ObjectInfo *pt_info; 610 611 if (!objectID) { 612 res = TEE_ERROR_BAD_PARAMETERS; 613 goto out; 614 } 615 616 if (!objectIDLen) { 617 res = TEE_ERROR_BAD_PARAMETERS; 618 goto out; 619 } 620 621 if (objectInfo) 622 pt_info = objectInfo; 623 else 624 pt_info = &local_info; 625 len = *objectIDLen; 626 res = _utee_storage_next_enum((unsigned long)objectEnumerator, 627 pt_info, objectID, &len); 628 *objectIDLen = len; 629 630 out: 631 if (res != TEE_SUCCESS && 632 res != TEE_ERROR_ITEM_NOT_FOUND && 633 res != TEE_ERROR_CORRUPT_OBJECT && 634 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 635 TEE_Panic(res); 636 637 return res; 638 } 639 640 /* Data and Key Storage API - Data Stream Access Functions */ 641 642 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 643 uint32_t size, uint32_t *count) 644 { 645 TEE_Result res; 646 uint64_t cnt64; 647 648 if (object == TEE_HANDLE_NULL) { 649 res = TEE_ERROR_BAD_PARAMETERS; 650 goto out; 651 } 652 653 cnt64 = *count; 654 res = _utee_storage_obj_read((unsigned long)object, buffer, size, 655 &cnt64); 656 *count = cnt64; 657 658 out: 659 if (res != TEE_SUCCESS && 660 res != TEE_ERROR_CORRUPT_OBJECT && 661 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 662 TEE_Panic(res); 663 664 return res; 665 } 666 667 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer, 668 uint32_t size) 669 { 670 TEE_Result res; 671 672 if (object == TEE_HANDLE_NULL) { 673 res = TEE_ERROR_BAD_PARAMETERS; 674 goto out; 675 } 676 677 if (size > TEE_DATA_MAX_POSITION) { 678 res = TEE_ERROR_OVERFLOW; 679 goto out; 680 } 681 682 res = _utee_storage_obj_write((unsigned long)object, buffer, size); 683 684 out: 685 if (res != TEE_SUCCESS && 686 res != TEE_ERROR_STORAGE_NO_SPACE && 687 res != TEE_ERROR_OVERFLOW && 688 res != TEE_ERROR_CORRUPT_OBJECT && 689 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 690 TEE_Panic(res); 691 692 return res; 693 } 694 695 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 696 { 697 TEE_Result res; 698 699 if (object == TEE_HANDLE_NULL) { 700 res = TEE_ERROR_BAD_PARAMETERS; 701 goto out; 702 } 703 704 res = _utee_storage_obj_trunc((unsigned long)object, size); 705 706 out: 707 if (res != TEE_SUCCESS && 708 res != TEE_ERROR_STORAGE_NO_SPACE && 709 res != TEE_ERROR_CORRUPT_OBJECT && 710 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 711 TEE_Panic(res); 712 713 return res; 714 } 715 716 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 717 TEE_Whence whence) 718 { 719 TEE_Result res; 720 TEE_ObjectInfo info; 721 722 if (object == TEE_HANDLE_NULL) { 723 res = TEE_ERROR_BAD_PARAMETERS; 724 goto out; 725 } 726 727 res = _utee_cryp_obj_get_info((unsigned long)object, &info); 728 if (res != TEE_SUCCESS) 729 goto out; 730 731 switch (whence) { 732 case TEE_DATA_SEEK_SET: 733 if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) { 734 res = TEE_ERROR_OVERFLOW; 735 goto out; 736 } 737 break; 738 case TEE_DATA_SEEK_CUR: 739 if (offset > 0 && 740 ((uint32_t)offset + info.dataPosition > 741 TEE_DATA_MAX_POSITION || 742 (uint32_t)offset + info.dataPosition < 743 info.dataPosition)) { 744 res = TEE_ERROR_OVERFLOW; 745 goto out; 746 } 747 break; 748 case TEE_DATA_SEEK_END: 749 if (offset > 0 && 750 ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION || 751 (uint32_t)offset + info.dataSize < info.dataSize)) { 752 res = TEE_ERROR_OVERFLOW; 753 goto out; 754 } 755 break; 756 default: 757 res = TEE_ERROR_ITEM_NOT_FOUND; 758 goto out; 759 } 760 761 res = _utee_storage_obj_seek((unsigned long)object, offset, whence); 762 763 out: 764 if (res != TEE_SUCCESS && 765 res != TEE_ERROR_OVERFLOW && 766 res != TEE_ERROR_CORRUPT_OBJECT && 767 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 768 TEE_Panic(res); 769 770 return res; 771 } 772