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