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