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_ERROR_CORRUPT_OBJECT) { 73 res = utee_storage_obj_del(object); 74 if (res != TEE_SUCCESS) 75 TEE_Panic(0); 76 return TEE_ERROR_CORRUPT_OBJECT; 77 } 78 79 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 80 TEE_Panic(res); 81 82 return res; 83 } 84 85 /* 86 * Use of this function is deprecated 87 * new code SHOULD use the TEE_RestrictObjectUsage1 function instead 88 * These functions will be removed at some future major revision of 89 * this specification 90 */ 91 void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) 92 { 93 TEE_Result res; 94 TEE_ObjectInfo objectInfo; 95 96 res = utee_cryp_obj_get_info((uint32_t)object, &objectInfo); 97 if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT) 98 return; 99 100 res = TEE_RestrictObjectUsage1(object, objectUsage); 101 102 if (res != TEE_SUCCESS) 103 TEE_Panic(0); 104 } 105 106 TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage) 107 { 108 TEE_Result res; 109 110 res = utee_cryp_obj_restrict_usage((uint32_t)object, objectUsage); 111 112 if (res == TEE_ERROR_CORRUPT_OBJECT) { 113 res = utee_storage_obj_del(object); 114 if (res != TEE_SUCCESS) 115 TEE_Panic(0); 116 return TEE_ERROR_CORRUPT_OBJECT; 117 } 118 119 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 120 TEE_Panic(0); 121 122 return res; 123 } 124 125 TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, 126 uint32_t attributeID, void *buffer, 127 uint32_t *size) 128 { 129 TEE_Result res; 130 TEE_ObjectInfo info; 131 132 res = utee_cryp_obj_get_info((uint32_t)object, &info); 133 if (res != TEE_SUCCESS) 134 TEE_Panic(0); 135 136 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) 137 TEE_Panic(0); 138 139 /* This function only supports reference attributes */ 140 if ((attributeID & TEE_ATTR_BIT_VALUE) != 0) 141 TEE_Panic(0); 142 143 res = utee_cryp_obj_get_attr((uint32_t)object, 144 attributeID, buffer, size); 145 146 if (res != TEE_SUCCESS && 147 res != TEE_ERROR_ITEM_NOT_FOUND && 148 res != TEE_ERROR_SHORT_BUFFER && 149 res != TEE_ERROR_CORRUPT_OBJECT && 150 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 151 TEE_Panic(0); 152 153 return res; 154 } 155 156 TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object, 157 uint32_t attributeID, uint32_t *a, 158 uint32_t *b) 159 { 160 TEE_Result res; 161 TEE_ObjectInfo info; 162 uint32_t buf[2]; 163 uint32_t size = sizeof(buf); 164 165 res = utee_cryp_obj_get_info((uint32_t)object, &info); 166 if (res != TEE_SUCCESS) 167 TEE_Panic(0); 168 169 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) 170 TEE_Panic(0); 171 172 /* This function only supports value attributes */ 173 if ((attributeID & TEE_ATTR_BIT_VALUE) == 0) 174 TEE_Panic(0); 175 176 res = utee_cryp_obj_get_attr((uint32_t)object, 177 attributeID, buf, &size); 178 179 if (res != TEE_SUCCESS && 180 res != TEE_ERROR_ITEM_NOT_FOUND && 181 res != TEE_ERROR_CORRUPT_OBJECT && 182 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 183 TEE_Panic(0); 184 185 if (size != sizeof(buf)) 186 TEE_Panic(0); 187 188 *a = buf[0]; 189 *b = buf[1]; 190 191 return res; 192 } 193 194 void TEE_CloseObject(TEE_ObjectHandle object) 195 { 196 TEE_Result res; 197 198 if (object == TEE_HANDLE_NULL) 199 return; 200 201 res = utee_cryp_obj_close((uint32_t)object); 202 if (res != TEE_SUCCESS) 203 TEE_Panic(0); 204 } 205 206 /* Data and Key Storage API - Transient Object Functions */ 207 208 TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType, 209 uint32_t maxKeySize, 210 TEE_ObjectHandle *object) 211 { 212 TEE_Result res; 213 uint32_t obj; 214 215 res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj); 216 if (res == TEE_SUCCESS) 217 *object = (TEE_ObjectHandle) obj; 218 219 return res; 220 } 221 222 void TEE_FreeTransientObject(TEE_ObjectHandle object) 223 { 224 TEE_Result res; 225 TEE_ObjectInfo info; 226 227 if (object == TEE_HANDLE_NULL) 228 return; 229 230 res = utee_cryp_obj_get_info((uint32_t)object, &info); 231 if (res != TEE_SUCCESS) 232 TEE_Panic(0); 233 234 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 235 TEE_Panic(0); 236 237 res = utee_cryp_obj_close((uint32_t)object); 238 if (res != TEE_SUCCESS) 239 TEE_Panic(0); 240 } 241 242 void TEE_ResetTransientObject(TEE_ObjectHandle object) 243 { 244 TEE_Result res; 245 TEE_ObjectInfo info; 246 247 if (object == TEE_HANDLE_NULL) 248 return; 249 250 res = utee_cryp_obj_get_info((uint32_t)object, &info); 251 if (res != TEE_SUCCESS) 252 TEE_Panic(0); 253 254 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 255 TEE_Panic(0); 256 257 res = utee_cryp_obj_reset((uint32_t)object); 258 if (res != TEE_SUCCESS) 259 TEE_Panic(0); 260 } 261 262 TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, 263 TEE_Attribute *attrs, 264 uint32_t attrCount) 265 { 266 TEE_Result res; 267 TEE_ObjectInfo info; 268 269 res = utee_cryp_obj_get_info((uint32_t)object, &info); 270 if (res != TEE_SUCCESS) 271 TEE_Panic(0); 272 273 /* Must be a transient object */ 274 if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 275 TEE_Panic(0); 276 277 /* Must not be initialized already */ 278 if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 279 TEE_Panic(0); 280 281 res = utee_cryp_obj_populate((uint32_t)object, attrs, attrCount); 282 if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS) 283 TEE_Panic(res); 284 return res; 285 } 286 287 void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID, 288 void *buffer, uint32_t length) 289 { 290 if (attr == NULL) 291 TEE_Panic(0); 292 if ((attributeID & TEE_ATTR_BIT_VALUE) != 0) 293 TEE_Panic(0); 294 attr->attributeID = attributeID; 295 attr->content.ref.buffer = buffer; 296 attr->content.ref.length = length; 297 } 298 299 void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID, 300 uint32_t a, uint32_t b) 301 { 302 if (attr == NULL) 303 TEE_Panic(0); 304 if ((attributeID & TEE_ATTR_BIT_VALUE) == 0) 305 TEE_Panic(0); 306 attr->attributeID = attributeID; 307 attr->content.value.a = a; 308 attr->content.value.b = b; 309 } 310 311 /* 312 * Use of this function is deprecated 313 * new code SHOULD use the TEE_CopyObjectAttributes1 function instead 314 * These functions will be removed at some future major revision of 315 * this specification 316 */ 317 void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, 318 TEE_ObjectHandle srcObject) 319 { 320 TEE_Result res; 321 TEE_ObjectInfo src_info; 322 323 res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info); 324 if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT) 325 return; 326 327 res = TEE_CopyObjectAttributes1(destObject, srcObject); 328 if (res != TEE_SUCCESS) 329 TEE_Panic(0); 330 } 331 332 TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject, 333 TEE_ObjectHandle srcObject) 334 { 335 TEE_Result res; 336 TEE_ObjectInfo dst_info; 337 TEE_ObjectInfo src_info; 338 339 res = utee_cryp_obj_get_info((uint32_t)destObject, &dst_info); 340 if (res != TEE_SUCCESS) 341 goto err; 342 343 res = utee_cryp_obj_get_info((uint32_t)srcObject, &src_info); 344 if (res != TEE_SUCCESS) 345 goto err; 346 347 if ((src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) 348 TEE_Panic(0); 349 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0) 350 TEE_Panic(0); 351 if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 352 TEE_Panic(0); 353 354 res = utee_cryp_obj_copy((uint32_t)destObject, (uint32_t)srcObject); 355 if (res != TEE_SUCCESS) 356 TEE_Panic(0); 357 358 goto out; 359 360 err: 361 if (res == TEE_ERROR_CORRUPT_OBJECT) { 362 res = utee_storage_obj_del(srcObject); 363 if (res != TEE_SUCCESS) 364 TEE_Panic(0); 365 return TEE_ERROR_CORRUPT_OBJECT; 366 } 367 if (res == TEE_ERROR_STORAGE_NOT_AVAILABLE) 368 return res; 369 TEE_Panic(0); 370 out: 371 return TEE_SUCCESS; 372 } 373 374 TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, 375 TEE_Attribute *params, uint32_t paramCount) 376 { 377 TEE_Result res; 378 379 res = utee_cryp_obj_generate_key((uint32_t)object, keySize, 380 params, paramCount); 381 382 if (res != TEE_SUCCESS) 383 TEE_Panic(0); 384 385 return res; 386 } 387 388 /* Data and Key Storage API - Persistent Object Functions */ 389 390 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, void *objectID, 391 uint32_t objectIDLen, uint32_t flags, 392 TEE_ObjectHandle *object) 393 { 394 if (storageID != TEE_STORAGE_PRIVATE) 395 return TEE_ERROR_ITEM_NOT_FOUND; 396 397 if (objectID == NULL) 398 return TEE_ERROR_ITEM_NOT_FOUND; 399 400 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) 401 TEE_Panic(0); 402 403 if (object == NULL) 404 return TEE_ERROR_BAD_PARAMETERS; 405 406 return utee_storage_obj_open(storageID, objectID, objectIDLen, flags, 407 object); 408 } 409 410 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, void *objectID, 411 uint32_t objectIDLen, uint32_t flags, 412 TEE_ObjectHandle attributes, 413 const void *initialData, 414 uint32_t initialDataLen, 415 TEE_ObjectHandle *object) 416 { 417 TEE_Result res; 418 419 if (storageID != TEE_STORAGE_PRIVATE) { 420 res = TEE_ERROR_ITEM_NOT_FOUND; 421 goto err; 422 } 423 424 if (objectID == NULL) { 425 res = TEE_ERROR_ITEM_NOT_FOUND; 426 goto err; 427 } 428 429 if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) { 430 res = TEE_ERROR_BAD_PARAMETERS; 431 goto err; 432 } 433 434 if (object == NULL) { 435 res = TEE_ERROR_BAD_PARAMETERS; 436 goto err; 437 } 438 439 res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags, 440 attributes, initialData, initialDataLen, 441 object); 442 if (res == TEE_SUCCESS) 443 goto out; 444 err: 445 if (res == TEE_ERROR_ITEM_NOT_FOUND || 446 res == TEE_ERROR_ACCESS_CONFLICT || 447 res == TEE_ERROR_OUT_OF_MEMORY || 448 res == TEE_ERROR_STORAGE_NO_SPACE || 449 res == TEE_ERROR_CORRUPT_OBJECT || 450 res == TEE_ERROR_STORAGE_NOT_AVAILABLE) 451 return res; 452 TEE_Panic(0); 453 out: 454 return TEE_SUCCESS; 455 } 456 457 /* 458 * Use of this function is deprecated 459 * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead 460 * These functions will be removed at some future major revision of 461 * this specification 462 */ 463 void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) 464 { 465 TEE_Result res; 466 467 if (object == TEE_HANDLE_NULL) 468 return; 469 470 res = TEE_CloseAndDeletePersistentObject1(object); 471 472 if (res != TEE_SUCCESS) 473 TEE_Panic(0); 474 } 475 476 TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object) 477 { 478 TEE_Result res; 479 480 if (object == TEE_HANDLE_NULL) 481 return TEE_ERROR_STORAGE_NOT_AVAILABLE; 482 483 res = utee_storage_obj_del(object); 484 485 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 486 TEE_Panic(0); 487 488 return res; 489 } 490 491 492 TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, 493 const void *newObjectID, 494 uint32_t newObjectIDLen) 495 { 496 TEE_Result res; 497 498 if (object == TEE_HANDLE_NULL) 499 return TEE_ERROR_ITEM_NOT_FOUND; 500 501 if (newObjectID == NULL) 502 return TEE_ERROR_BAD_PARAMETERS; 503 504 if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) 505 TEE_Panic(0); 506 507 res = utee_storage_obj_rename(object, newObjectID, newObjectIDLen); 508 509 if (res != TEE_SUCCESS && res != TEE_ERROR_ACCESS_CONFLICT) 510 TEE_Panic(0); 511 512 return res; 513 } 514 515 TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle * 516 objectEnumerator) 517 { 518 TEE_Result res; 519 520 if (objectEnumerator == NULL) 521 return TEE_ERROR_BAD_PARAMETERS; 522 523 res = utee_storage_alloc_enum(objectEnumerator); 524 525 if (res != TEE_SUCCESS) 526 *objectEnumerator = TEE_HANDLE_NULL; 527 528 return res; 529 } 530 531 void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 532 { 533 TEE_Result res; 534 535 if (objectEnumerator == TEE_HANDLE_NULL) 536 return; 537 538 res = utee_storage_free_enum(objectEnumerator); 539 540 if (res != TEE_SUCCESS) 541 TEE_Panic(0); 542 } 543 544 void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) 545 { 546 TEE_Result res; 547 548 if (objectEnumerator == TEE_HANDLE_NULL) 549 return; 550 551 res = utee_storage_reset_enum(objectEnumerator); 552 553 if (res != TEE_SUCCESS) 554 TEE_Panic(0); 555 } 556 557 TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle 558 objectEnumerator, 559 uint32_t storageID) 560 { 561 TEE_Result res; 562 563 if (storageID != TEE_STORAGE_PRIVATE) 564 return TEE_ERROR_ITEM_NOT_FOUND; 565 566 res = utee_storage_start_enum(objectEnumerator, storageID); 567 568 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND) 569 TEE_Panic(0); 570 571 return res; 572 } 573 574 TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, 575 TEE_ObjectInfo *objectInfo, 576 void *objectID, uint32_t *objectIDLen) 577 { 578 TEE_Result res; 579 580 res = 581 utee_storage_next_enum(objectEnumerator, objectInfo, objectID, 582 objectIDLen); 583 584 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND) 585 TEE_Panic(0); 586 587 return res; 588 } 589 590 /* Data and Key Storage API - Data Stream Access Functions */ 591 592 TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer, 593 uint32_t size, uint32_t *count) 594 { 595 TEE_Result res; 596 597 if (object == TEE_HANDLE_NULL) 598 TEE_Panic(0); 599 600 res = utee_storage_obj_read(object, buffer, size, count); 601 602 if (res != TEE_SUCCESS) 603 TEE_Panic(0); 604 605 return res; 606 } 607 608 TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void *buffer, 609 uint32_t size) 610 { 611 TEE_Result res; 612 613 if (object == TEE_HANDLE_NULL) 614 TEE_Panic(0); 615 616 res = utee_storage_obj_write(object, buffer, size); 617 618 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE) 619 TEE_Panic(0); 620 621 return res; 622 } 623 624 TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) 625 { 626 TEE_Result res; 627 628 if (object == TEE_HANDLE_NULL) 629 TEE_Panic(0); 630 631 res = utee_storage_obj_trunc(object, size); 632 633 if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NO_SPACE) 634 TEE_Panic(0); 635 636 return res; 637 } 638 639 TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, 640 TEE_Whence whence) 641 { 642 TEE_Result res; 643 TEE_ObjectInfo info; 644 645 if (object == TEE_HANDLE_NULL) 646 TEE_Panic(0); 647 648 res = utee_cryp_obj_get_info((uint32_t)object, &info); 649 if (res != TEE_SUCCESS) 650 TEE_Panic(0); 651 652 switch (whence) { 653 case TEE_DATA_SEEK_SET: 654 if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) 655 return TEE_ERROR_OVERFLOW; 656 break; 657 case TEE_DATA_SEEK_CUR: 658 if (offset > 0 && 659 ((uint32_t)offset + info.dataPosition > 660 TEE_DATA_MAX_POSITION || 661 (uint32_t)offset + info.dataPosition < 662 info.dataPosition)) 663 return TEE_ERROR_OVERFLOW; 664 break; 665 case TEE_DATA_SEEK_END: 666 if (offset > 0 && 667 ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION || 668 (uint32_t)offset + info.dataSize < info.dataSize)) 669 return TEE_ERROR_OVERFLOW; 670 break; 671 default: 672 TEE_Panic(0); 673 } 674 675 res = utee_storage_obj_seek(object, offset, whence); 676 677 if (res != TEE_SUCCESS && res != TEE_ERROR_OVERFLOW) 678 TEE_Panic(0); 679 680 return res; 681 } 682