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