1 /* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <stdlib.h> 28 #include <string.h> 29 30 #include <tee_api.h> 31 #include <utee_syscalls.h> 32 33 #include <assert.h> 34 35 #define TEE_USAGE_DEFAULT 0xffffffff 36 37 #define TEE_ATTR_BIT_VALUE (1 << 29) 38 #define TEE_ATTR_BIT_PROTECTED (1 << 28) 39 40 /* Data and Key Storage API - Generic Object Functions */ 41 /* 42 * Use of this function is deprecated 43 * new code SHOULD use the TEE_GetObjectInfo1 function instead 44 * These functions will be removed at some future major revision of 45 * this specification 46 */ 47 void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 48 { 49 TEE_Result res; 50 51 res = utee_cryp_obj_get_info((uint32_t)object, objectInfo); 52 53 if (res != TEE_SUCCESS) 54 TEE_Panic(res); 55 56 if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) { 57 objectInfo->keySize = 0; 58 objectInfo->maxKeySize = 0; 59 objectInfo->objectUsage = 0; 60 objectInfo->dataSize = 0; 61 objectInfo->dataPosition = 0; 62 objectInfo->handleFlags = 0; 63 } 64 } 65 66 TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo) 67 { 68 TEE_Result res; 69 70 res = utee_cryp_obj_get_info((uint32_t)object, objectInfo); 71 72 if (res != TEE_SUCCESS && 73 res != TEE_ERROR_CORRUPT_OBJECT && 74 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 75 TEE_Panic(res); 76 77 return res; 78 } 79 80 /* 81 * Use of this function is deprecated 82 * new code SHOULD use the TEE_RestrictObjectUsage1 function instead 83 * These functions will be removed at some future major revision of 84 * this specification 85 */ 86 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) 87 { 88 TEE_Result res; 89 TEE_ObjectInfo objectInfo; 90 91 res = utee_cryp_obj_get_info((uint32_t)object, &objectInfo); 92 if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT) 93 return; 94 95 res = TEE_RestrictObjectUsage1(object, objectUsage); 96 97 if (res != TEE_SUCCESS) 98 TEE_Panic(0); 99 } 100 101 TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage) 102 { 103 TEE_Result res; 104 105 res = utee_cryp_obj_restrict_usage((uint32_t)object, objectUsage); 106 107 if (res != TEE_SUCCESS && 108 res != TEE_ERROR_CORRUPT_OBJECT && 109 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 110 TEE_Panic(res); 111 112 return res; 113 } 114 115 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 116 uint32_t attributeID, void *buffer, 117 uint32_t *size) 118 { 119 TEE_Result res; 120 TEE_ObjectInfo info; 121 122 res = utee_cryp_obj_get_info((uint32_t)object, &info); 123 if (res != TEE_SUCCESS) 124 goto exit; 125 126 /* This function only supports reference attributes */ 127 if ((attributeID & TEE_ATTR_BIT_VALUE)) { 128 res = TEE_ERROR_BAD_PARAMETERS; 129 goto exit; 130 } 131 132 res = utee_cryp_obj_get_attr((uint32_t)object, 133 attributeID, buffer, size); 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(0); 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 uint32_t size = sizeof(buf); 154 155 res = utee_cryp_obj_get_info((uint32_t)object, &info); 156 if (res != TEE_SUCCESS) 157 goto exit; 158 159 /* This function only supports value attributes */ 160 if (!(attributeID & TEE_ATTR_BIT_VALUE)) { 161 res = TEE_ERROR_BAD_PARAMETERS; 162 goto exit; 163 } 164 165 res = utee_cryp_obj_get_attr((uint32_t)object, 166 attributeID, buf, &size); 167 168 exit: 169 if (res != TEE_SUCCESS && 170 res != TEE_ERROR_ITEM_NOT_FOUND && 171 res != TEE_ERROR_CORRUPT_OBJECT && 172 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 173 TEE_Panic(0); 174 175 if (size != sizeof(buf)) 176 TEE_Panic(0); 177 178 *a = buf[0]; 179 *b = buf[1]; 180 181 return res; 182 } 183 184 void TEE_CloseObject(TEE_ObjectHandle object) 185 { 186 TEE_Result res; 187 188 if (object == TEE_HANDLE_NULL) 189 return; 190 191 res = utee_cryp_obj_close((uint32_t)object); 192 if (res != TEE_SUCCESS) 193 TEE_Panic(0); 194 } 195 196 /* Data and Key Storage API - Transient Object Functions */ 197 198 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 199 uint32_t maxKeySize, 200 TEE_ObjectHandle *object) 201 { 202 TEE_Result res; 203 uint32_t obj; 204 205 res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 206 207 if (res != TEE_SUCCESS && 208 res != TEE_ERROR_OUT_OF_MEMORY && 209 res != TEE_ERROR_NOT_SUPPORTED) 210 TEE_Panic(0); 211 212 if (res == TEE_SUCCESS) 213 *object = (TEE_ObjectHandle) obj; 214 215 return res; 216 } 217 218 void TEE_FreeTransientObject(TEE_ObjectHandle object) 219 { 220 TEE_Result res; 221 TEE_ObjectInfo info; 222 223 if (object == TEE_HANDLE_NULL) 224 return; 225 226 res = utee_cryp_obj_get_info((uint32_t)object, &info); 227 if (res != TEE_SUCCESS) 228 TEE_Panic(0); 229 230 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 231 TEE_Panic(0); 232 233 res = utee_cryp_obj_close((uint32_t)object); 234 if (res != TEE_SUCCESS) 235 TEE_Panic(0); 236 } 237 238 void TEE_ResetTransientObject(TEE_ObjectHandle object) 239 { 240 TEE_Result res; 241 TEE_ObjectInfo info; 242 243 if (object == TEE_HANDLE_NULL) 244 return; 245 246 res = utee_cryp_obj_get_info((uint32_t)object, &info); 247 if (res != TEE_SUCCESS) 248 TEE_Panic(0); 249 250 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 251 TEE_Panic(0); 252 253 res = utee_cryp_obj_reset((uint32_t)object); 254 if (res != TEE_SUCCESS) 255 TEE_Panic(0); 256 } 257 258 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 259 TEE_Attribute *attrs, 260 uint32_t attrCount) 261 { 262 TEE_Result res; 263 TEE_ObjectInfo info; 264 265 res = utee_cryp_obj_get_info((uint32_t)object, &info); 266 if (res != TEE_SUCCESS) 267 TEE_Panic(0); 268 269 /* Must be a transient object */ 270 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 271 TEE_Panic(0); 272 273 /* Must not be initialized already */ 274 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 275 TEE_Panic(0); 276 277 res = utee_cryp_obj_populate((uint32_t)object, attrs, attrCount); 278 if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 279 TEE_Panic(res); 280 return res; 281 } 282 283 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID, 284 void *buffer, uint32_t length) 285 { 286 if (attr == NULL) 287 TEE_Panic(0); 288 if ((attributeID & TEE_ATTR_BIT_VALUE) != 0) 289 TEE_Panic(0); 290 attr->attributeID = attributeID; 291 attr->content.ref.buffer = buffer; 292 attr->content.ref.length = length; 293 } 294 295 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, 296 uint32_t a, uint32_t b) 297 { 298 if (attr == NULL) 299 TEE_Panic(0); 300 if ((attributeID & TEE_ATTR_BIT_VALUE) == 0) 301 TEE_Panic(0); 302 attr->attributeID = attributeID; 303 attr->content.value.a = a; 304 attr->content.value.b = b; 305 } 306 307 /* 308 * Use of this function is deprecated 309 * new code SHOULD use the TEE_CopyObjectAttributes1 function instead 310 * These functions will be removed at some future major revision of 311 * this specification 312 */ 313 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, 314 TEE_ObjectHandle srcObject) 315 { 316 TEE_Result res; 317 TEE_ObjectInfo src_info; 318 319 res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info); 320 if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT) 321 return; 322 323 res = TEE_CopyObjectAttributes1(destObject, srcObject); 324 if (res != TEE_SUCCESS) 325 TEE_Panic(0); 326 } 327 328 TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject, 329 TEE_ObjectHandle srcObject) 330 { 331 TEE_Result res; 332 TEE_ObjectInfo dst_info; 333 TEE_ObjectInfo src_info; 334 335 res = utee_cryp_obj_get_info((uint32_t)destObject, &dst_info); 336 if (res != TEE_SUCCESS) 337 goto exit; 338 339 res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info); 340 if (res != TEE_SUCCESS) 341 goto exit; 342 343 if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 344 TEE_Panic(0); 345 346 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) 347 TEE_Panic(0); 348 349 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) 350 TEE_Panic(0); 351 352 res = utee_cryp_obj_copy((uint32_t)destObject, (uint32_t)srcObject); 353 354 exit: 355 if (res != TEE_SUCCESS && 356 res != TEE_ERROR_CORRUPT_OBJECT && 357 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 358 TEE_Panic(res); 359 360 return res; 361 } 362 363 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 364 TEE_Attribute *params, uint32_t paramCount) 365 { 366 TEE_Result res; 367 368 res = utee_cryp_obj_generate_key((uint32_t)object, keySize, 369 params, paramCount); 370 371 if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 372 TEE_Panic(0); 373 374 return res; 375 } 376 377 /* Data and Key Storage API - Persistent Object Functions */ 378 379 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, void *objectID, 380 uint32_t objectIDLen, uint32_t flags, 381 TEE_ObjectHandle *object) 382 { 383 TEE_Result res; 384 385 if (storageID != TEE_STORAGE_PRIVATE) { 386 res = TEE_ERROR_ITEM_NOT_FOUND; 387 goto out; 388 } 389 390 if (!objectID) { 391 res = TEE_ERROR_ITEM_NOT_FOUND; 392 goto out; 393 } 394 395 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) { 396 res = TEE_ERROR_BAD_PARAMETERS; 397 goto out; 398 } 399 400 if (!object) { 401 res = TEE_ERROR_BAD_PARAMETERS; 402 goto out; 403 } 404 405 res = utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 406 object); 407 408 out: 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(0); 416 417 return res; 418 } 419 420 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, void *objectID, 421 uint32_t objectIDLen, uint32_t flags, 422 TEE_ObjectHandle attributes, 423 const void *initialData, 424 uint32_t initialDataLen, 425 TEE_ObjectHandle *object) 426 { 427 TEE_Result res; 428 429 if (storageID != TEE_STORAGE_PRIVATE) { 430 res = TEE_ERROR_ITEM_NOT_FOUND; 431 goto err; 432 } 433 434 if (!objectID) { 435 res = TEE_ERROR_ITEM_NOT_FOUND; 436 goto err; 437 } 438 439 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) { 440 res = TEE_ERROR_BAD_PARAMETERS; 441 goto err; 442 } 443 444 if (!object) { 445 res = TEE_ERROR_BAD_PARAMETERS; 446 goto err; 447 } 448 449 res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 450 attributes, initialData, initialDataLen, 451 object); 452 if (res == TEE_SUCCESS) 453 goto out; 454 err: 455 if (res == TEE_ERROR_ITEM_NOT_FOUND || 456 res == TEE_ERROR_ACCESS_CONFLICT || 457 res == TEE_ERROR_OUT_OF_MEMORY || 458 res == TEE_ERROR_STORAGE_NO_SPACE || 459 res == TEE_ERROR_CORRUPT_OBJECT || 460 res == TEE_ERROR_STORAGE_NOT_AVAILABLE) 461 return res; 462 TEE_Panic(0); 463 out: 464 return TEE_SUCCESS; 465 } 466 467 /* 468 * Use of this function is deprecated 469 * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead 470 * These functions will be removed at some future major revision of 471 * this specification 472 */ 473 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 474 { 475 TEE_Result res; 476 477 if (object == TEE_HANDLE_NULL) 478 return; 479 480 res = TEE_CloseAndDeletePersistentObject1(object); 481 482 if (res != TEE_SUCCESS) 483 TEE_Panic(0); 484 } 485 486 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object) 487 { 488 TEE_Result res; 489 490 if (object == TEE_HANDLE_NULL) 491 return TEE_ERROR_STORAGE_NOT_AVAILABLE; 492 493 res = utee_storage_obj_del(object); 494 495 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 496 TEE_Panic(0); 497 498 return res; 499 } 500 501 502 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 503 const void *newObjectID, 504 uint32_t newObjectIDLen) 505 { 506 TEE_Result res; 507 508 if (object == TEE_HANDLE_NULL) { 509 res = TEE_ERROR_ITEM_NOT_FOUND; 510 goto out; 511 } 512 513 if (!newObjectID) { 514 res = TEE_ERROR_BAD_PARAMETERS; 515 goto out; 516 } 517 518 if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) { 519 res = TEE_ERROR_BAD_PARAMETERS; 520 goto out; 521 } 522 523 res = utee_storage_obj_rename(object, newObjectID, 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(0); 531 532 return res; 533 } 534 535 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 536 objectEnumerator) 537 { 538 TEE_Result res; 539 540 if (!objectEnumerator) 541 return TEE_ERROR_BAD_PARAMETERS; 542 543 res = utee_storage_alloc_enum(objectEnumerator); 544 545 if (res != TEE_SUCCESS) 546 *objectEnumerator = TEE_HANDLE_NULL; 547 548 if (res != TEE_SUCCESS && 549 res != TEE_ERROR_ACCESS_CONFLICT) 550 TEE_Panic(0); 551 552 return res; 553 } 554 555 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 556 { 557 TEE_Result res; 558 559 if (objectEnumerator == TEE_HANDLE_NULL) 560 return; 561 562 res = utee_storage_free_enum(objectEnumerator); 563 564 if (res != TEE_SUCCESS) 565 TEE_Panic(0); 566 } 567 568 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 569 { 570 TEE_Result res; 571 572 if (objectEnumerator == TEE_HANDLE_NULL) 573 return; 574 575 res = utee_storage_reset_enum(objectEnumerator); 576 577 if (res != TEE_SUCCESS) 578 TEE_Panic(0); 579 } 580 581 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 582 objectEnumerator, 583 uint32_t storageID) 584 { 585 TEE_Result res; 586 587 if (storageID != TEE_STORAGE_PRIVATE) 588 return TEE_ERROR_ITEM_NOT_FOUND; 589 590 res = utee_storage_start_enum(objectEnumerator, 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(0); 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 607 if (!objectID) { 608 res = TEE_ERROR_BAD_PARAMETERS; 609 goto out; 610 } 611 612 if (!objectIDLen) { 613 res = TEE_ERROR_BAD_PARAMETERS; 614 goto out; 615 } 616 617 res = utee_storage_next_enum(objectEnumerator, objectInfo, objectID, 618 objectIDLen); 619 620 out: 621 if (res != TEE_SUCCESS && 622 res != TEE_ERROR_ITEM_NOT_FOUND && 623 res != TEE_ERROR_CORRUPT_OBJECT && 624 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 625 TEE_Panic(0); 626 627 return res; 628 } 629 630 /* Data and Key Storage API - Data Stream Access Functions */ 631 632 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 633 uint32_t size, uint32_t *count) 634 { 635 TEE_Result res; 636 637 if (object == TEE_HANDLE_NULL) { 638 res = TEE_ERROR_BAD_PARAMETERS; 639 goto out; 640 } 641 642 res = utee_storage_obj_read(object, buffer, size, count); 643 644 out: 645 if (res != TEE_SUCCESS && 646 res != TEE_ERROR_CORRUPT_OBJECT && 647 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 648 TEE_Panic(0); 649 650 return res; 651 } 652 653 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void *buffer, 654 uint32_t size) 655 { 656 TEE_Result res; 657 658 if (object == TEE_HANDLE_NULL) { 659 res = TEE_ERROR_BAD_PARAMETERS; 660 goto out; 661 } 662 663 if (size > TEE_DATA_MAX_POSITION) { 664 res = TEE_ERROR_OVERFLOW; 665 goto out; 666 } 667 668 res = utee_storage_obj_write(object, buffer, size); 669 670 out: 671 if (res != TEE_SUCCESS && 672 res != TEE_ERROR_STORAGE_NO_SPACE && 673 res != TEE_ERROR_OVERFLOW && 674 res != TEE_ERROR_CORRUPT_OBJECT && 675 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 676 TEE_Panic(0); 677 678 return res; 679 } 680 681 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 682 { 683 TEE_Result res; 684 685 if (object == TEE_HANDLE_NULL) { 686 res = TEE_ERROR_BAD_PARAMETERS; 687 goto out; 688 } 689 690 res = utee_storage_obj_trunc(object, size); 691 692 out: 693 if (res != TEE_SUCCESS && 694 res != TEE_ERROR_STORAGE_NO_SPACE && 695 res != TEE_ERROR_CORRUPT_OBJECT && 696 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 697 TEE_Panic(0); 698 699 return res; 700 } 701 702 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 703 TEE_Whence whence) 704 { 705 TEE_Result res; 706 TEE_ObjectInfo info; 707 708 if (object == TEE_HANDLE_NULL) { 709 res = TEE_ERROR_BAD_PARAMETERS; 710 goto out; 711 } 712 713 res = utee_cryp_obj_get_info((uint32_t)object, &info); 714 if (res != TEE_SUCCESS) 715 goto out; 716 717 switch (whence) { 718 case TEE_DATA_SEEK_SET: 719 if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) { 720 res = TEE_ERROR_OVERFLOW; 721 goto out; 722 } 723 break; 724 case TEE_DATA_SEEK_CUR: 725 if (offset > 0 && 726 ((uint32_t)offset + info.dataPosition > 727 TEE_DATA_MAX_POSITION || 728 (uint32_t)offset + info.dataPosition < 729 info.dataPosition)) { 730 res = TEE_ERROR_OVERFLOW; 731 goto out; 732 } 733 break; 734 case TEE_DATA_SEEK_END: 735 if (offset > 0 && 736 ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION || 737 (uint32_t)offset + info.dataSize < info.dataSize)) { 738 res = TEE_ERROR_OVERFLOW; 739 goto out; 740 } 741 break; 742 default: 743 res = TEE_ERROR_ITEM_NOT_FOUND; 744 goto out; 745 } 746 747 res = utee_storage_obj_seek(object, offset, whence); 748 749 out: 750 if (res != TEE_SUCCESS && 751 res != TEE_ERROR_OVERFLOW && 752 res != TEE_ERROR_CORRUPT_OBJECT && 753 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 754 TEE_Panic(0); 755 756 return res; 757 } 758