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