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