1 /** 2 * @file tlcTeeKeymaster_if.c 3 * @brief Contains trustlet connector interface implementations to 4 * handle key operations with TEE Keymaster trustlet 5 * 6 * Copyright Giesecke & Devrient GmbH 2012 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote 17 * products derived from this software without specific prior 18 * written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 26 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <stdlib.h> 34 35 #include "MobiCoreDriverApi.h" 36 #include "tlTeeKeymaster_Api.h" 37 #include "tlcTeeKeymaster_log.h" 38 #include "tlcTeeKeymaster_if.h" 39 40 41 /* Global definitions */ 42 static const uint32_t DEVICE_ID = MC_DEVICE_ID_DEFAULT; 43 static const mcUuid_t uuid = TEE_KEYMASTER_TL_UUID; 44 45 /** 46 * TEE_Open 47 * 48 * Open session to the TEE Keymaster trustlet 49 * 50 * @param pSessionHandle [out] Return pointer to the session handle 51 */ 52 static tciMessage_ptr TEE_Open( 53 mcSessionHandle_t *pSessionHandle 54 ){ 55 tciMessage_ptr pTci = NULL; 56 mcResult_t mcRet; 57 58 do 59 { 60 61 /* Validate session handle */ 62 if (!pSessionHandle) 63 { 64 LOG_E("TEE_Open(): Invalid session handle\n"); 65 break; 66 } 67 68 /* Initialize session handle data */ 69 bzero(pSessionHandle, sizeof(mcSessionHandle_t)); 70 71 /* Open MobiCore device */ 72 mcRet = mcOpenDevice(DEVICE_ID); 73 if (MC_DRV_OK != mcRet) 74 { 75 LOG_E("TEE_Open(): mcOpenDevice returned: %d\n", mcRet); 76 break; 77 } 78 79 /* Allocating WSM for TCI */ 80 mcRet = mcMallocWsm(DEVICE_ID, 0, sizeof(tciMessage_t), (uint8_t **) &pTci, 0); 81 if (MC_DRV_OK != mcRet) 82 { 83 LOG_E("TEE_Open(): mcMallocWsm returned: %d\n", mcRet); 84 break; 85 } 86 87 /* Open session the TEE Keymaster trustlet */ 88 pSessionHandle->deviceId = DEVICE_ID; 89 mcRet = mcOpenSession(pSessionHandle, 90 &uuid, 91 (uint8_t *) pTci, 92 (uint32_t) sizeof(tciMessage_t)); 93 if (MC_DRV_OK != mcRet) 94 { 95 LOG_E("TEE_Open(): mcOpenSession returned: %d\n", mcRet); 96 break; 97 } 98 99 } while (false); 100 101 return pTci; 102 } 103 104 105 /** 106 * TEE_Close 107 * 108 * Close session to the TEE Keymaster trustlet 109 * 110 * @param sessionHandle [in] Session handle 111 */ 112 static void TEE_Close( 113 mcSessionHandle_t sessionHandle 114 ){ 115 teeResult_t ret = TEE_ERR_NONE; 116 mcResult_t mcRet; 117 118 do { 119 120 /* Close session */ 121 mcRet = mcCloseSession(&sessionHandle); 122 if (MC_DRV_OK != mcRet) 123 { 124 LOG_E("TEE_Close(): mcCloseSession returned: %d\n", mcRet); 125 ret = TEE_ERR_SESSION; 126 break; 127 } 128 129 /* Close MobiCore device */ 130 mcRet = mcCloseDevice(DEVICE_ID); 131 if (MC_DRV_OK != mcRet) 132 { 133 LOG_E("TEE_Close(): mcCloseDevice returned: %d\n", mcRet); 134 ret = TEE_ERR_MC_DEVICE; 135 } 136 137 } while (false); 138 } 139 140 141 /** 142 * TEE_RSAGenerateKeyPair 143 * 144 * Generates RSA key pair and returns key pair data as wrapped object 145 * 146 * @param keyType [in] Key pair type. RSA or RSACRT 147 * @param keyData [in] Pointer to the key data buffer 148 * @param keyDataLength [in] Key data buffer length 149 * @param keySize [in] Key size 150 * @param exponent [in] Exponent number 151 * @param soLen [out] Key data secure object length 152 */ 153 teeResult_t TEE_RSAGenerateKeyPair( 154 teeRsaKeyPairType_t keyType, 155 uint8_t* keyData, 156 uint32_t keyDataLength, 157 uint32_t keySize, 158 uint32_t exponent, 159 uint32_t* soLen 160 ){ 161 teeResult_t ret = TEE_ERR_NONE; 162 tciMessage_ptr pTci = NULL; 163 mcSessionHandle_t sessionHandle; 164 mcBulkMap_t mapInfo; 165 mcResult_t mcRet; 166 167 do { 168 169 /* Open session to the trustlet */ 170 pTci = TEE_Open(&sessionHandle); 171 if (!pTci) { 172 ret = TEE_ERR_MEMORY; 173 break; 174 } 175 176 /* Map memory to the secure world */ 177 mcRet = mcMap(&sessionHandle, keyData, keyDataLength, &mapInfo); 178 if (MC_DRV_OK != mcRet) { 179 ret = TEE_ERR_MAP; 180 break; 181 } 182 183 /* Update TCI buffer */ 184 pTci->command.header.commandId = CMD_ID_TEE_RSA_GEN_KEY_PAIR; 185 pTci->rsagenkey.type = keyType; 186 pTci->rsagenkey.keysize = keySize; 187 pTci->rsagenkey.keydata = (uint32_t)mapInfo.sVirtualAddr; 188 pTci->rsagenkey.keydatalen = keyDataLength; 189 pTci->rsagenkey.exponent = exponent; 190 191 /* Notify the trustlet */ 192 mcRet = mcNotify(&sessionHandle); 193 if (MC_DRV_OK != mcRet) 194 { 195 ret = TEE_ERR_NOTIFICATION; 196 break; 197 } 198 199 /* Wait for response from the trustlet */ 200 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 201 { 202 ret = TEE_ERR_NOTIFICATION; 203 break; 204 } 205 206 /* Unmap memory */ 207 mcRet = mcUnmap(&sessionHandle, keyData, &mapInfo); 208 if (MC_DRV_OK != mcRet) 209 { 210 ret = TEE_ERR_MAP; 211 break; 212 } 213 214 if (RET_OK != pTci->response.header.returnCode) 215 { 216 LOG_E("TEE_RSAGenerateKeyPair(): TEE Keymaster trustlet returned: 0x%.8x\n", 217 pTci->response.header.returnCode); 218 ret = TEE_ERR_FAIL; 219 break; 220 } 221 222 /* Update secure object length */ 223 *soLen = pTci->rsagenkey.solen; 224 225 } while (false); 226 227 /* Close session to the trustlet */ 228 TEE_Close(sessionHandle); 229 230 return ret; 231 } 232 233 234 /** 235 * TEE_RSASign 236 * 237 * Signs given plain data and returns signature data 238 * 239 * @param keyData [in] Pointer to key data buffer 240 * @param keyDataLength [in] Key data buffer length 241 * @param plainData [in] Pointer to plain data to be signed 242 * @param plainDataLength [in] Plain data length 243 * @param signatureData [out] Pointer to signature data 244 * @param signatureDataLength [out] Signature data length 245 * @param algorithm [in] RSA signature algorithm 246 */ 247 teeResult_t TEE_RSASign( 248 const uint8_t* keyData, 249 const uint32_t keyDataLength, 250 const uint8_t* plainData, 251 const uint32_t plainDataLength, 252 uint8_t* signatureData, 253 uint32_t* signatureDataLength, 254 teeRsaSigAlg_t algorithm 255 ){ 256 teeResult_t ret = TEE_ERR_NONE; 257 tciMessage_ptr pTci = NULL; 258 mcSessionHandle_t sessionHandle; 259 mcBulkMap_t keyMapInfo; 260 mcBulkMap_t plainMapInfo; 261 mcBulkMap_t signatureMapInfo; 262 mcResult_t mcRet; 263 264 do { 265 266 /* Open session to the trustlet */ 267 pTci = TEE_Open(&sessionHandle); 268 if (!pTci) { 269 ret = TEE_ERR_MEMORY; 270 break; 271 } 272 273 /* Map memory to the secure world */ 274 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo); 275 if (MC_DRV_OK != mcRet) { 276 ret = TEE_ERR_MAP; 277 break; 278 } 279 280 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo); 281 if (MC_DRV_OK != mcRet) { 282 ret = TEE_ERR_MAP; 283 break; 284 } 285 286 mcRet = mcMap(&sessionHandle, (void*)signatureData, *signatureDataLength, &signatureMapInfo); 287 if (MC_DRV_OK != mcRet) { 288 ret = TEE_ERR_MAP; 289 break; 290 } 291 292 /* Update TCI buffer */ 293 pTci->command.header.commandId = CMD_ID_TEE_RSA_SIGN; 294 pTci->rsasign.keydata = (uint32_t)keyMapInfo.sVirtualAddr; 295 pTci->rsasign.keydatalen = keyDataLength; 296 297 pTci->rsasign.plaindata = (uint32_t)plainMapInfo.sVirtualAddr; 298 pTci->rsasign.plaindatalen = plainDataLength; 299 300 pTci->rsasign.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr; 301 pTci->rsasign.signaturedatalen = *signatureDataLength; 302 303 pTci->rsasign.algorithm = algorithm; 304 305 /* Notify the trustlet */ 306 mcRet = mcNotify(&sessionHandle); 307 if (MC_DRV_OK != mcRet) 308 { 309 ret = TEE_ERR_NOTIFICATION; 310 break; 311 } 312 313 /* Wait for response from the trustlet */ 314 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 315 { 316 ret = TEE_ERR_NOTIFICATION; 317 break; 318 } 319 320 /* Unmap memory */ 321 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo); 322 if (MC_DRV_OK != mcRet) 323 { 324 ret = TEE_ERR_MAP; 325 break; 326 } 327 328 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo); 329 if (MC_DRV_OK != mcRet) 330 { 331 ret = TEE_ERR_MAP; 332 break; 333 } 334 335 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo); 336 if (MC_DRV_OK != mcRet) 337 { 338 ret = TEE_ERR_MAP; 339 break; 340 } 341 342 if (RET_OK != pTci->response.header.returnCode) 343 { 344 LOG_E("TEE_RSASign(): TEE Keymaster trustlet returned: 0x%.8x\n", 345 pTci->response.header.returnCode); 346 ret = TEE_ERR_FAIL; 347 break; 348 } 349 350 /* Retrieve signature data length */ 351 *signatureDataLength = pTci->rsasign.signaturedatalen; 352 353 } while (false); 354 355 /* Close session to the trustlet */ 356 TEE_Close(sessionHandle); 357 358 return ret; 359 } 360 361 362 /** 363 * TEE_RSAVerify 364 * 365 * Verifies given data with RSA public key and return status 366 * 367 * @param keyData [in] Pointer to key data buffer 368 * @param keyDataLength [in] Key data buffer length 369 * @param plainData [in] Pointer to plain data to be signed 370 * @param plainDataLength [in] Plain data length 371 * @param signatureData [in] Pointer to signed data 372 * @param signatureData [in] Plain data length 373 * @param algorithm [in] RSA signature algorithm 374 * @param validity [out] Signature validity 375 */ 376 teeResult_t TEE_RSAVerify( 377 const uint8_t* keyData, 378 const uint32_t keyDataLength, 379 const uint8_t* plainData, 380 const uint32_t plainDataLength, 381 const uint8_t* signatureData, 382 const uint32_t signatureDataLength, 383 teeRsaSigAlg_t algorithm, 384 bool *validity 385 ){ 386 teeResult_t ret = TEE_ERR_NONE; 387 tciMessage_ptr pTci = NULL; 388 mcSessionHandle_t sessionHandle; 389 mcBulkMap_t keyMapInfo; 390 mcBulkMap_t plainMapInfo; 391 mcBulkMap_t signatureMapInfo; 392 mcResult_t mcRet; 393 394 do { 395 396 /* Open session to the trustlet */ 397 pTci = TEE_Open(&sessionHandle); 398 if (!pTci) { 399 ret = TEE_ERR_MEMORY; 400 break; 401 } 402 403 /* Map memory to the secure world */ 404 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo); 405 if (MC_DRV_OK != mcRet) { 406 ret = TEE_ERR_MAP; 407 break; 408 } 409 410 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo); 411 if (MC_DRV_OK != mcRet) { 412 ret = TEE_ERR_MAP; 413 break; 414 } 415 416 mcRet = mcMap(&sessionHandle, (void*)signatureData, signatureDataLength, &signatureMapInfo); 417 if (MC_DRV_OK != mcRet) { 418 ret = TEE_ERR_MAP; 419 break; 420 } 421 422 /* Update TCI buffer */ 423 pTci->command.header.commandId = CMD_ID_TEE_RSA_VERIFY; 424 pTci->rsaverify.keydata = (uint32_t)keyMapInfo.sVirtualAddr; 425 pTci->rsaverify.keydatalen = keyDataLength; 426 427 pTci->rsaverify.plaindata = (uint32_t)plainMapInfo.sVirtualAddr; 428 pTci->rsaverify.plaindatalen = plainDataLength; 429 430 pTci->rsaverify.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr; 431 pTci->rsaverify.signaturedatalen = signatureDataLength; 432 433 pTci->rsaverify.algorithm = algorithm; 434 pTci->rsaverify.validity = false; 435 436 /* Notify the trustlet */ 437 mcRet = mcNotify(&sessionHandle); 438 if (MC_DRV_OK != mcRet) 439 { 440 ret = TEE_ERR_NOTIFICATION; 441 break; 442 } 443 444 /* Wait for response from the trustlet */ 445 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 446 { 447 ret = TEE_ERR_NOTIFICATION; 448 break; 449 } 450 451 /* Unmap memory */ 452 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo); 453 if (MC_DRV_OK != mcRet) 454 { 455 ret = TEE_ERR_MAP; 456 break; 457 } 458 459 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo); 460 if (MC_DRV_OK != mcRet) 461 { 462 ret = TEE_ERR_MAP; 463 break; 464 } 465 466 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo); 467 if (MC_DRV_OK != mcRet) 468 { 469 ret = TEE_ERR_MAP; 470 break; 471 } 472 473 if (RET_OK != pTci->response.header.returnCode) 474 { 475 LOG_E("TEE_RSAVerify(): TEE Keymaster trustlet returned: 0x%.8x\n", 476 pTci->response.header.returnCode); 477 ret = TEE_ERR_FAIL; 478 break; 479 } 480 481 *validity = pTci->rsaverify.validity; 482 483 } while (false); 484 485 /* Close session to the trustlet */ 486 TEE_Close(sessionHandle); 487 488 return ret; 489 } 490 491 492 /** 493 * TEE_HMACKeyGenerate 494 * 495 * Generates random key for HMAC calculation and returns key data as wrapped object 496 * (key is encrypted) 497 * 498 * @param keyData [out] Pointer to key data 499 * @param keyDataLength [in] Key data buffer length 500 * @param soLen [out] Key data secure object length 501 */ 502 teeResult_t TEE_HMACKeyGenerate( 503 uint8_t* keyData, 504 uint32_t keyDataLength, 505 uint32_t* soLen 506 ){ 507 teeResult_t ret = TEE_ERR_NONE; 508 tciMessage_ptr pTci = NULL; 509 mcSessionHandle_t sessionHandle; 510 mcBulkMap_t keyMapInfo; 511 mcResult_t mcRet; 512 513 do { 514 515 /* Open session to the trustlet */ 516 pTci = TEE_Open(&sessionHandle); 517 if (!pTci) { 518 ret = TEE_ERR_MEMORY; 519 break; 520 } 521 522 /* Map memory to the secure world */ 523 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo); 524 if (MC_DRV_OK != mcRet) { 525 ret = TEE_ERR_MAP; 526 break; 527 } 528 529 /* Update TCI buffer */ 530 pTci->command.header.commandId = CMD_ID_TEE_HMAC_GEN_KEY; 531 pTci->hmacgenkey.keydata = (uint32_t)keyMapInfo.sVirtualAddr; 532 pTci->hmacgenkey.keydatalen = keyDataLength; 533 534 /* Notify the trustlet */ 535 mcRet = mcNotify(&sessionHandle); 536 if (MC_DRV_OK != mcRet) 537 { 538 ret = TEE_ERR_NOTIFICATION; 539 break; 540 } 541 542 /* Wait for response from the trustlet */ 543 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 544 { 545 ret = TEE_ERR_NOTIFICATION; 546 break; 547 } 548 549 /* Unmap memory */ 550 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo); 551 if (MC_DRV_OK != mcRet) 552 { 553 ret = TEE_ERR_MAP; 554 break; 555 } 556 557 if (RET_OK != pTci->response.header.returnCode) 558 { 559 LOG_E("TEE_RSAVerify(): TEE Keymaster trustlet returned: 0x%.8x\n", 560 pTci->response.header.returnCode); 561 ret = TEE_ERR_FAIL; 562 } 563 564 /* Update secure object length */ 565 *soLen = pTci->hmacgenkey.solen; 566 567 }while (false); 568 569 /* Close session to the trustlet */ 570 TEE_Close(sessionHandle); 571 572 return ret; 573 } 574 575 /** 576 * TEE_HMACSign 577 * 578 * Signs given plain data and returns HMAC signature data 579 * 580 * @param keyData [in] Pointer to key data buffer 581 * @param keyDataLength [in] Key data buffer length 582 * @param plainData [in] Pointer to plain data to be signed 583 * @param plainDataLength [in] Plain data length 584 * @param signatureData [out] Pointer to signature data 585 * @param signatureDataLength [out] Signature data length 586 * @param digest [in] Digest type 587 */ 588 teeResult_t TEE_HMACSign( 589 const uint8_t* keyData, 590 const uint32_t keyDataLength, 591 const uint8_t* plainData, 592 const uint32_t plainDataLength, 593 uint8_t* signatureData, 594 uint32_t* signatureDataLength, 595 teeDigest_t digest 596 ){ 597 teeResult_t ret = TEE_ERR_NONE; 598 tciMessage_ptr pTci = NULL; 599 mcSessionHandle_t sessionHandle; 600 mcBulkMap_t keyMapInfo; 601 mcBulkMap_t plainMapInfo; 602 mcBulkMap_t signatureMapInfo; 603 mcResult_t mcRet; 604 605 do { 606 607 /* Open session to the trustlet */ 608 pTci = TEE_Open(&sessionHandle); 609 if (!pTci) { 610 ret = TEE_ERR_MEMORY; 611 break; 612 } 613 614 /* Map memory to the secure world */ 615 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo); 616 if (MC_DRV_OK != mcRet) { 617 ret = TEE_ERR_MAP; 618 break; 619 } 620 621 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo); 622 if (MC_DRV_OK != mcRet) { 623 ret = TEE_ERR_MAP; 624 break; 625 } 626 627 mcRet = mcMap(&sessionHandle, (void*)signatureData, *signatureDataLength, &signatureMapInfo); 628 if (MC_DRV_OK != mcRet) { 629 ret = TEE_ERR_MAP; 630 break; 631 } 632 633 /* Update TCI buffer */ 634 pTci->command.header.commandId = CMD_ID_TEE_HMAC_SIGN; 635 pTci->hmacsign.keydata = (uint32_t)keyMapInfo.sVirtualAddr; 636 pTci->hmacsign.keydatalen = keyDataLength; 637 638 pTci->hmacsign.plaindata = (uint32_t)plainMapInfo.sVirtualAddr; 639 pTci->hmacsign.plaindatalen = plainDataLength; 640 641 pTci->hmacsign.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr; 642 pTci->hmacsign.signaturedatalen = *signatureDataLength; 643 644 pTci->hmacsign.digest = digest; 645 646 /* Notify the trustlet */ 647 mcRet = mcNotify(&sessionHandle); 648 if (MC_DRV_OK != mcRet) 649 { 650 ret = TEE_ERR_NOTIFICATION; 651 break; 652 } 653 654 /* Wait for response from the trustlet */ 655 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 656 { 657 ret = TEE_ERR_NOTIFICATION; 658 break; 659 } 660 661 /* Unmap memory */ 662 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo); 663 if (MC_DRV_OK != mcRet) 664 { 665 ret = TEE_ERR_MAP; 666 break; 667 } 668 669 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo); 670 if (MC_DRV_OK != mcRet) 671 { 672 ret = TEE_ERR_MAP; 673 break; 674 } 675 676 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo); 677 if (MC_DRV_OK != mcRet) 678 { 679 ret = TEE_ERR_MAP; 680 break; 681 } 682 683 if (RET_OK != pTci->response.header.returnCode) 684 { 685 LOG_E("TEE_HMACSign(): TEE Keymaster trustlet returned: 0x%.8x\n", 686 pTci->response.header.returnCode); 687 ret = TEE_ERR_FAIL; 688 break; 689 } 690 691 /* Retrieve signature data length */ 692 *signatureDataLength = pTci->hmacsign.signaturedatalen; 693 694 } while (false); 695 696 /* Close session to the trustlet */ 697 TEE_Close(sessionHandle); 698 699 return ret; 700 } 701 702 703 /** 704 * TEE_HMACVerify 705 * 706 * Verifies given data HMAC key data and return status 707 * 708 * @param plainData [in] Pointer to plain data to be signed 709 * @param plainDataLength [in] Plain data length 710 * @param signatureData [in] Pointer to signed data 711 * @param signatureData [in] Plain data length 712 * @param digest [in] Digest type 713 * @param validity [out] Signature validity 714 */ 715 teeResult_t TEE_HMACVerify( 716 const uint8_t* keyData, 717 const uint32_t keyDataLength, 718 const uint8_t* plainData, 719 const uint32_t plainDataLength, 720 const uint8_t* signatureData, 721 const uint32_t signatureDataLength, 722 teeDigest_t digest, 723 bool *validity 724 ){ 725 teeResult_t ret = TEE_ERR_NONE; 726 tciMessage_ptr pTci = NULL; 727 mcSessionHandle_t sessionHandle; 728 mcBulkMap_t keyMapInfo; 729 mcBulkMap_t plainMapInfo; 730 mcBulkMap_t signatureMapInfo; 731 mcResult_t mcRet; 732 733 do { 734 735 /* Open session to the trustlet */ 736 pTci = TEE_Open(&sessionHandle); 737 if (!pTci) { 738 ret = TEE_ERR_MEMORY; 739 break; 740 } 741 742 /* Map memory to the secure world */ 743 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo); 744 if (MC_DRV_OK != mcRet) { 745 ret = TEE_ERR_MAP; 746 break; 747 } 748 749 mcRet = mcMap(&sessionHandle, (void*)plainData, plainDataLength, &plainMapInfo); 750 if (MC_DRV_OK != mcRet) { 751 ret = TEE_ERR_MAP; 752 break; 753 } 754 755 mcRet = mcMap(&sessionHandle, (void*)signatureData, signatureDataLength, &signatureMapInfo); 756 if (MC_DRV_OK != mcRet) { 757 ret = TEE_ERR_MAP; 758 break; 759 } 760 761 /* Update TCI buffer */ 762 pTci->command.header.commandId = CMD_ID_TEE_HMAC_VERIFY; 763 pTci->hmacverify.keydata = (uint32_t)keyMapInfo.sVirtualAddr; 764 pTci->hmacverify.keydatalen = keyDataLength; 765 766 pTci->hmacverify.plaindata = (uint32_t)plainMapInfo.sVirtualAddr; 767 pTci->hmacverify.plaindatalen = plainDataLength; 768 769 pTci->hmacverify.signaturedata = (uint32_t)signatureMapInfo.sVirtualAddr; 770 pTci->hmacverify.signaturedatalen = signatureDataLength; 771 772 pTci->hmacverify.digest = digest; 773 pTci->hmacverify.validity = false; 774 775 /* Notify the trustlet */ 776 mcRet = mcNotify(&sessionHandle); 777 if (MC_DRV_OK != mcRet) 778 { 779 ret = TEE_ERR_NOTIFICATION; 780 break; 781 } 782 783 /* Wait for response from the trustlet */ 784 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 785 { 786 ret = TEE_ERR_NOTIFICATION; 787 break; 788 } 789 790 /* Unmap memory */ 791 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo); 792 if (MC_DRV_OK != mcRet) 793 { 794 ret = TEE_ERR_MAP; 795 break; 796 } 797 798 mcRet = mcUnmap(&sessionHandle, (void*)plainData, &plainMapInfo); 799 if (MC_DRV_OK != mcRet) 800 { 801 ret = TEE_ERR_MAP; 802 break; 803 } 804 805 mcRet = mcUnmap(&sessionHandle, (void*)signatureData, &signatureMapInfo); 806 if (MC_DRV_OK != mcRet) 807 { 808 ret = TEE_ERR_MAP; 809 break; 810 } 811 812 if (RET_OK != pTci->response.header.returnCode) 813 { 814 LOG_E("TEE_HMACVerify(): TEE Keymaster trustlet returned: 0x%.8x\n", 815 pTci->response.header.returnCode); 816 ret = TEE_ERR_FAIL; 817 break; 818 } 819 820 *validity = pTci->hmacverify.validity; 821 822 } while (false); 823 824 /* Close session to the trustlet */ 825 TEE_Close(sessionHandle); 826 827 return ret; 828 } 829 830 831 /** 832 * TEE_KeyImport 833 * 834 * Imports key data and returns key data as secure object 835 * 836 * Key data needs to be in the following format 837 * 838 * RSA key data: 839 * |--key metadata--|--public modulus--|--public exponent--|--private exponent--| 840 * 841 * RSA CRT key data: 842 * |--key metadata--|--public modulus--|--public exponent--|--P--|--Q--|--DP--|--DQ--|--Qinv--| 843 * 844 * Where: 845 * P: secret prime factor 846 * Q: secret prime factor 847 * DP: d mod (p-1) 848 * DQ: d mod (q-1) 849 * Qinv: q^-1 mod p 850 * 851 * @param keyData [in] Pointer to key data 852 * @param keyDataLength [in] Key data length 853 * @param soData [out] Pointer to wrapped key data 854 * @param soDataLength [out] Wrapped key data length 855 */ 856 teeResult_t TEE_KeyImport( 857 const uint8_t* keyData, 858 const uint32_t keyDataLength, 859 uint8_t* soData, 860 uint32_t* soDataLength 861 ){ 862 teeResult_t ret = TEE_ERR_NONE; 863 tciMessage_ptr pTci = NULL; 864 mcSessionHandle_t sessionHandle; 865 mcBulkMap_t keyMapInfo; 866 mcBulkMap_t soMapInfo; 867 mcResult_t mcRet; 868 869 do { 870 871 /* Open session to the trustlet */ 872 pTci = TEE_Open(&sessionHandle); 873 if (!pTci) { 874 ret = TEE_ERR_MEMORY; 875 break; 876 } 877 878 /* Map memory to the secure world */ 879 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo); 880 if (MC_DRV_OK != mcRet) { 881 ret = TEE_ERR_MAP; 882 break; 883 } 884 885 mcRet = mcMap(&sessionHandle, (void*)soData, *soDataLength, &soMapInfo); 886 if (MC_DRV_OK != mcRet) { 887 ret = TEE_ERR_MAP; 888 break; 889 } 890 891 /* Update TCI buffer */ 892 pTci->command.header.commandId = CMD_ID_TEE_KEY_IMPORT; 893 pTci->keyimport.keydata = (uint32_t)keyMapInfo.sVirtualAddr; 894 pTci->keyimport.keydatalen = keyDataLength; 895 pTci->keyimport.sodata = (uint32_t)soMapInfo.sVirtualAddr; 896 pTci->keyimport.sodatalen = *soDataLength; 897 898 /* Notify the trustlet */ 899 mcRet = mcNotify(&sessionHandle); 900 if (MC_DRV_OK != mcRet) 901 { 902 ret = TEE_ERR_NOTIFICATION; 903 break; 904 } 905 906 /* Wait for response from the trustlet */ 907 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 908 { 909 ret = TEE_ERR_NOTIFICATION; 910 break; 911 } 912 913 /* Unmap memory */ 914 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo); 915 if (MC_DRV_OK != mcRet) 916 { 917 ret = TEE_ERR_MAP; 918 break; 919 } 920 921 mcRet = mcUnmap(&sessionHandle, (void*)soData, &soMapInfo); 922 if (MC_DRV_OK != mcRet) 923 { 924 ret = TEE_ERR_MAP; 925 break; 926 } 927 928 if (RET_OK != pTci->response.header.returnCode) 929 { 930 LOG_E("TEE_KeyWrap(): TEE Keymaster trustlet returned: 0x%.8x\n", 931 pTci->response.header.returnCode); 932 ret = TEE_ERR_FAIL; 933 break; 934 } 935 936 /* Update secure object length */ 937 *soDataLength = pTci->keyimport.sodatalen; 938 939 } while (false); 940 941 /* Close session to the trustlet */ 942 TEE_Close(sessionHandle); 943 944 return ret; 945 } 946 947 948 /** * TEE_GetPubKey 949 * 950 * Retrieves public key daya (modulus and exponent) from wrapped key data 951 * 952 * @param keyData [in] Pointer to key data 953 * @param keyDataLength [in] Key data length 954 * @param modulus [out] Pointer to public key modulus data 955 * @param modulusLength [out] Modulus data length 956 * @param exponent [out] Pointer to public key exponent data 957 * @param exponentLength [out] Exponent data length 958 */ 959 teeResult_t TEE_GetPubKey( 960 const uint8_t* keyData, 961 const uint32_t keyDataLength, 962 uint8_t* modulus, 963 uint32_t* modulusLength, 964 uint8_t* exponent, 965 uint32_t* exponentLength 966 ){ 967 teeResult_t ret = TEE_ERR_NONE; 968 tciMessage_ptr pTci = NULL; 969 mcSessionHandle_t sessionHandle; 970 mcBulkMap_t keyMapInfo; 971 mcBulkMap_t modMapInfo; 972 mcBulkMap_t expMapInfo; 973 mcResult_t mcRet; 974 975 do { 976 977 /* Open session to the trustlet */ 978 pTci = TEE_Open(&sessionHandle); 979 if (!pTci) { 980 ret = TEE_ERR_MEMORY; 981 break; 982 } 983 984 /* Map memory to the secure world */ 985 mcRet = mcMap(&sessionHandle, (void*)keyData, keyDataLength, &keyMapInfo); 986 if (MC_DRV_OK != mcRet) { 987 ret = TEE_ERR_MAP; 988 break; 989 } 990 991 mcRet = mcMap(&sessionHandle, (void*)modulus, *modulusLength, &modMapInfo); 992 if (MC_DRV_OK != mcRet) { 993 ret = TEE_ERR_MAP; 994 break; 995 } 996 997 mcRet = mcMap(&sessionHandle, (void*)exponent, *exponentLength, &expMapInfo); 998 if (MC_DRV_OK != mcRet) { 999 ret = TEE_ERR_MAP; 1000 break; 1001 } 1002 1003 /* Update TCI buffer */ 1004 pTci->command.header.commandId = CMD_ID_TEE_GET_PUB_KEY; 1005 pTci->getpubkey.keydata = (uint32_t)keyMapInfo.sVirtualAddr; 1006 pTci->getpubkey.keydatalen = keyDataLength; 1007 pTci->getpubkey.modulus = (uint32_t)modMapInfo.sVirtualAddr; 1008 pTci->getpubkey.moduluslen = *modulusLength; 1009 pTci->getpubkey.exponent = (uint32_t)expMapInfo.sVirtualAddr; 1010 pTci->getpubkey.exponentlen = *exponentLength; 1011 1012 /* Notify the trustlet */ 1013 mcRet = mcNotify(&sessionHandle); 1014 if (MC_DRV_OK != mcRet) 1015 { 1016 ret = TEE_ERR_NOTIFICATION; 1017 break; 1018 } 1019 1020 /* Wait for response from the trustlet */ 1021 if (MC_DRV_OK != mcWaitNotification(&sessionHandle, MC_INFINITE_TIMEOUT)) 1022 { 1023 ret = TEE_ERR_NOTIFICATION; 1024 break; 1025 } 1026 1027 /* Unmap memory */ 1028 mcRet = mcUnmap(&sessionHandle, (void*)keyData, &keyMapInfo); 1029 if (MC_DRV_OK != mcRet) 1030 { 1031 ret = TEE_ERR_MAP; 1032 break; 1033 } 1034 1035 mcRet = mcUnmap(&sessionHandle, (void*)modulus, &modMapInfo); 1036 if (MC_DRV_OK != mcRet) 1037 { 1038 ret = TEE_ERR_MAP; 1039 break; 1040 } 1041 1042 mcRet = mcUnmap(&sessionHandle, (void*)exponent, &expMapInfo); 1043 if (MC_DRV_OK != mcRet) 1044 { 1045 ret = TEE_ERR_MAP; 1046 break; 1047 } 1048 1049 if (RET_OK != pTci->response.header.returnCode) 1050 { 1051 LOG_E("TEE_GetPubKey(): TEE Keymaster trustlet returned: 0x%.8x\n", 1052 pTci->response.header.returnCode); 1053 ret = TEE_ERR_FAIL; 1054 break; 1055 } 1056 1057 /* Update modulus and exponent lengths */ 1058 *modulusLength = pTci->getpubkey.moduluslen; 1059 *exponentLength = pTci->getpubkey.exponentlen; 1060 1061 } while (false); 1062 1063 /* Close session to the trustlet */ 1064 TEE_Close(sessionHandle); 1065 1066 return ret; 1067 } 1068