1 /* 2 * The Initial Developer of the Original Code is International 3 * Business Machines Corporation. Portions created by IBM 4 * Corporation are Copyright (C) 2005 International Business 5 * Machines Corporation. All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the Common Public License as published by 9 * IBM Corporation; either version 1 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * Common Public License for more details. 16 * 17 * You should have received a copy of the Common Public License 18 * along with this program; if not, a copy can be viewed at 19 * http://www.opensource.org/licenses/cpl1.0.php. 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <pthread.h> 27 #include <string.h> 28 29 #include <sys/types.h> 30 #include <sys/stat.h> 31 #include <uuid/uuid.h> 32 #include <fcntl.h> 33 #include <errno.h> 34 #include <pwd.h> 35 #include <syslog.h> 36 37 #include <tss/platform.h> 38 #include <tss/tss_defines.h> 39 #include <tss/tss_typedef.h> 40 #include <tss/tss_structs.h> 41 #include <tss/tss_error.h> 42 #include <tss/tcs_error.h> 43 #include <tss/tspi.h> 44 #include <trousers/trousers.h> 45 46 #include "tpmtok_int.h" 47 #include "tpmtok_defs.h" 48 49 extern void stlogit(char *fmt, ...); 50 51 CK_RV token_rng(TSS_HCONTEXT, CK_BYTE *, CK_ULONG); 52 int tok_slot2local(CK_SLOT_ID); 53 CK_RV token_specific_session(CK_SLOT_ID); 54 CK_RV token_specific_final(void); 55 56 CK_RV 57 token_specific_rsa_decrypt( 58 TSS_HCONTEXT, 59 CK_BYTE *, 60 CK_ULONG, 61 CK_BYTE *, 62 CK_ULONG *, 63 OBJECT *); 64 65 CK_RV 66 token_specific_rsa_encrypt( 67 TSS_HCONTEXT, 68 CK_BYTE *, 69 CK_ULONG, 70 CK_BYTE *, 71 CK_ULONG *, 72 OBJECT *); 73 74 CK_RV 75 token_specific_rsa_sign( 76 TSS_HCONTEXT, 77 CK_BYTE *, 78 CK_ULONG, 79 CK_BYTE *, 80 CK_ULONG *, 81 OBJECT *); 82 83 CK_RV 84 token_specific_rsa_verify(TSS_HCONTEXT, CK_BYTE *, 85 CK_ULONG, CK_BYTE *, CK_ULONG, OBJECT *); 86 87 CK_RV 88 token_specific_rsa_generate_keypair(TSS_HCONTEXT, 89 TEMPLATE *, 90 TEMPLATE *); 91 92 CK_RV 93 token_specific_sha_init(DIGEST_CONTEXT *); 94 95 CK_RV 96 token_specific_sha_update(DIGEST_CONTEXT *, 97 CK_BYTE *, 98 CK_ULONG); 99 100 CK_RV 101 token_specific_sha_final(DIGEST_CONTEXT *, 102 CK_BYTE *, 103 CK_ULONG *); 104 105 CK_RV token_specific_login(TSS_HCONTEXT, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG); 106 CK_RV token_specific_logout(TSS_HCONTEXT); 107 CK_RV token_specific_init_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG); 108 CK_RV token_specific_set_pin(ST_SESSION_HANDLE, CK_CHAR_PTR, 109 CK_ULONG, CK_CHAR_PTR, CK_ULONG); 110 CK_RV token_specific_verify_so_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG); 111 112 static CK_RV 113 token_specific_init(char *, CK_SLOT_ID, TSS_HCONTEXT *); 114 115 struct token_specific_struct token_specific = { 116 "TPM_Debug", 117 &token_specific_init, 118 NULL, 119 &token_rng, 120 &token_specific_session, 121 &token_specific_final, 122 &token_specific_rsa_decrypt, 123 &token_specific_rsa_encrypt, 124 &token_specific_rsa_sign, 125 &token_specific_rsa_verify, 126 &token_specific_rsa_generate_keypair, 127 NULL, 128 NULL, 129 NULL, 130 &token_specific_login, 131 &token_specific_logout, 132 &token_specific_init_pin, 133 &token_specific_set_pin, 134 &token_specific_verify_so_pin 135 }; 136 137 /* The context we'll use globally to connect to the TSP */ 138 139 /* TSP key handles */ 140 TSS_HKEY hPublicRootKey = NULL_HKEY; 141 TSS_HKEY hPublicLeafKey = NULL_HKEY; 142 TSS_HKEY hPrivateRootKey = NULL_HKEY; 143 TSS_HKEY hPrivateLeafKey = NULL_HKEY; 144 145 TSS_UUID publicRootKeyUUID; 146 TSS_UUID publicLeafKeyUUID; 147 TSS_UUID privateRootKeyUUID; 148 TSS_UUID privateLeafKeyUUID; 149 150 /* TSP policy handles */ 151 TSS_HPOLICY hDefaultPolicy = NULL_HPOLICY; 152 153 /* PKCS#11 key handles */ 154 CK_OBJECT_HANDLE ckPublicRootKey = 0; 155 CK_OBJECT_HANDLE ckPublicLeafKey = 0; 156 CK_OBJECT_HANDLE ckPrivateRootKey = 0; 157 CK_OBJECT_HANDLE ckPrivateLeafKey = 0; 158 159 int not_initialized = 0; 160 161 CK_BYTE current_user_pin_sha[SHA1_DIGEST_LENGTH]; 162 CK_BYTE current_so_pin_sha[SHA1_DIGEST_LENGTH]; 163 164 static TPM_CAP_VERSION_INFO tpmvinfo; 165 166 static CK_RV 167 verify_user_pin(TSS_HCONTEXT, CK_BYTE *); 168 169 static void 170 local_uuid_clear(TSS_UUID *uuid) 171 { 172 if (uuid == NULL) 173 return; 174 (void) memset(uuid, 0, sizeof (TSS_UUID)); 175 } 176 177 178 /* convert from TSS_UUID to uuid_t */ 179 static void 180 tss_uuid_convert_from(TSS_UUID *uu, uuid_t ptr) 181 { 182 uint_t tmp; 183 uchar_t *out = ptr; 184 185 tmp = ntohl(uu->ulTimeLow); 186 out[3] = (uchar_t)tmp; 187 tmp >>= 8; 188 out[2] = (uchar_t)tmp; 189 tmp >>= 8; 190 out[1] = (uchar_t)tmp; 191 tmp >>= 8; 192 out[0] = (uchar_t)tmp; 193 194 tmp = ntohs(uu->usTimeMid); 195 out[5] = (uchar_t)tmp; 196 tmp >>= 8; 197 out[4] = (uchar_t)tmp; 198 199 tmp = ntohs(uu->usTimeHigh); 200 out[7] = (uchar_t)tmp; 201 tmp >>= 8; 202 out[6] = (uchar_t)tmp; 203 204 tmp = uu->bClockSeqHigh; 205 out[8] = (uchar_t)tmp; 206 tmp = uu->bClockSeqLow; 207 out[9] = (uchar_t)tmp; 208 209 (void) memcpy(out+10, uu->rgbNode, 6); 210 } 211 212 /* convert from uuid_t to TSS_UUID */ 213 static void 214 tss_uuid_convert_to(TSS_UUID *uuid, uuid_t in) 215 { 216 uchar_t *ptr; 217 uint32_t ltmp; 218 uint16_t stmp; 219 220 ptr = in; 221 222 ltmp = *ptr++; 223 ltmp = (ltmp << 8) | *ptr++; 224 ltmp = (ltmp << 8) | *ptr++; 225 ltmp = (ltmp << 8) | *ptr++; 226 uuid->ulTimeLow = ntohl(ltmp); 227 228 stmp = *ptr++; 229 stmp = (stmp << 8) | *ptr++; 230 uuid->usTimeMid = ntohs(stmp); 231 232 stmp = *ptr++; 233 stmp = (stmp << 8) | *ptr++; 234 uuid->usTimeHigh = ntohs(stmp); 235 236 uuid->bClockSeqHigh = *ptr++; 237 238 uuid->bClockSeqLow = *ptr++; 239 240 (void) memcpy(uuid->rgbNode, ptr, 6); 241 } 242 243 static void 244 local_uuid_copy(TSS_UUID *dst, TSS_UUID *src) 245 { 246 uuid_t udst, usrc; 247 248 tss_uuid_convert_from(dst, udst); 249 tss_uuid_convert_from(src, usrc); 250 251 uuid_copy(udst, usrc); 252 253 tss_uuid_convert_to(dst, udst); 254 } 255 256 static void 257 local_uuid_generate(TSS_UUID *uu) 258 { 259 uuid_t newuuid; 260 261 uuid_generate(newuuid); 262 263 tss_uuid_convert_to(uu, newuuid); 264 } 265 266 static int 267 local_copy_file(char *dst, char *src) 268 { 269 FILE *fdest, *fsrc; 270 char line[BUFSIZ]; 271 272 fdest = fopen(dst, "w"); 273 if (fdest == NULL) 274 return (-1); 275 276 fsrc = fopen(src, "r"); 277 if (fsrc == NULL) { 278 (void) fclose(fdest); 279 return (-1); 280 } 281 282 while (fread(line, sizeof (line), 1, fsrc)) 283 (void) fprintf(fdest, "%s\n", line); 284 (void) fclose(fsrc); 285 (void) fclose(fdest); 286 return (0); 287 } 288 289 static int 290 remove_uuid(char *keyname) 291 { 292 int ret = 0; 293 FILE *fp, *newfp; 294 char fname[MAXPATHLEN]; 295 char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ]; 296 char *tmpfname; 297 char *p = get_tpm_keystore_path(); 298 299 if (p == NULL) 300 return (-1); 301 302 (void) snprintf(fname, sizeof (fname), 303 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 304 305 fp = fopen(fname, "r"); 306 if (fp == NULL) { 307 return (-1); 308 } 309 310 tmpfname = tempnam("/tmp", "tpmtok"); 311 newfp = fopen(tmpfname, "w+"); 312 if (newfp == NULL) { 313 free(tmpfname); 314 (void) fclose(fp); 315 return (-1); 316 } 317 318 while (!feof(fp)) { 319 (void) fgets(line, sizeof (line), fp); 320 if (sscanf(line, "%1024s %1024s", key, idstr) == 2) { 321 if (strcmp(key, keyname)) 322 (void) fprintf(newfp, "%s\n", line); 323 } 324 } 325 326 (void) fclose(fp); 327 (void) fclose(newfp); 328 if (local_copy_file(fname, tmpfname) == 0) 329 (void) unlink(tmpfname); 330 331 free(tmpfname); 332 333 return (ret); 334 } 335 336 static int 337 find_uuid(char *keyname, TSS_UUID *uu) 338 { 339 int ret = 0, found = 0; 340 FILE *fp = NULL; 341 char fname[MAXPATHLEN]; 342 char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ]; 343 uuid_t uuid; 344 char *p = get_tpm_keystore_path(); 345 346 if (p == NULL) 347 return (-1); 348 349 tss_uuid_convert_from(uu, uuid); 350 351 (void) snprintf(fname, sizeof (fname), 352 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 353 354 /* Open UUID Index file */ 355 fp = fopen(fname, "r"); 356 if (fp == NULL) { 357 if (errno == ENOENT) { 358 /* initialize the file */ 359 fp = fopen(fname, "w"); 360 if (fp != NULL) 361 (void) fclose(fp); 362 } 363 return (-1); 364 } 365 366 while (!feof(fp)) { 367 (void) fgets(line, sizeof (line), fp); 368 if (sscanf(line, "%1024s %1024s", key, idstr) == 2) { 369 if (strcmp(key, keyname) == 0) { 370 ret = uuid_parse(idstr, uuid); 371 if (ret == 0) { 372 found = 1; 373 tss_uuid_convert_to(uu, 374 uuid); 375 } 376 break; 377 } 378 } 379 } 380 (void) fclose(fp); 381 382 if (!found) 383 ret = -1; 384 return (ret); 385 } 386 387 static int 388 local_uuid_is_null(TSS_UUID *uu) 389 { 390 uuid_t uuid; 391 int nulluuid; 392 393 tss_uuid_convert_from(uu, uuid); 394 395 nulluuid = uuid_is_null(uuid); 396 return (nulluuid); 397 } 398 399 static int 400 add_uuid(char *keyname, TSS_UUID *uu) 401 { 402 FILE *fp = NULL; 403 char fname[MAXPATHLEN]; 404 char idstr[BUFSIZ]; 405 uuid_t uuid; 406 char *p = get_tpm_keystore_path(); 407 408 if (p == NULL) 409 return (-1); 410 411 tss_uuid_convert_from(uu, uuid); 412 413 if (uuid_is_null(uuid)) 414 return (-1); 415 416 uuid_unparse(uuid, idstr); 417 418 (void) snprintf(fname, sizeof (fname), 419 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 420 421 fp = fopen(fname, "a"); 422 if (fp == NULL) 423 return (-1); 424 425 (void) fprintf(fp, "%s %s\n", keyname, idstr); 426 (void) fclose(fp); 427 428 return (0); 429 } 430 431 432 static UINT32 433 util_get_keysize_flag(CK_ULONG size) 434 { 435 switch (size) { 436 case 512: 437 return (TSS_KEY_SIZE_512); 438 break; 439 case 1024: 440 return (TSS_KEY_SIZE_1024); 441 break; 442 case 2048: 443 return (TSS_KEY_SIZE_2048); 444 break; 445 default: 446 break; 447 } 448 449 return (0); 450 } 451 452 /* make sure the public exponent attribute is 65537 */ 453 static CK_ULONG 454 util_check_public_exponent(TEMPLATE *tmpl) 455 { 456 CK_BBOOL flag; 457 CK_ATTRIBUTE *publ_exp_attr; 458 CK_BYTE pubexp_bytes[] = { 1, 0, 1 }; 459 CK_ULONG publ_exp, rc = 1; 460 461 flag = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, 462 &publ_exp_attr); 463 if (!flag) { 464 LogError1("Couldn't find public exponent attribute"); 465 return (CKR_TEMPLATE_INCOMPLETE); 466 } 467 468 switch (publ_exp_attr->ulValueLen) { 469 case 3: 470 rc = memcmp(pubexp_bytes, publ_exp_attr->pValue, 3); 471 break; 472 case sizeof (CK_ULONG): 473 publ_exp = *((CK_ULONG *)publ_exp_attr->pValue); 474 if (publ_exp == 65537) 475 rc = 0; 476 break; 477 default: 478 break; 479 } 480 481 return (rc); 482 } 483 484 TSS_RESULT 485 set_public_modulus(TSS_HCONTEXT hContext, TSS_HKEY hKey, 486 unsigned long size_n, unsigned char *n) 487 { 488 UINT64 offset; 489 UINT32 blob_size; 490 BYTE *blob, pub_blob[1024]; 491 TCPA_PUBKEY pub_key; 492 TSS_RESULT result; 493 494 /* Get the TCPA_PUBKEY blob from the key object. */ 495 result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 496 TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blob_size, &blob); 497 if (result != TSS_SUCCESS) { 498 stlogit("Tspi_GetAttribData failed: rc=0x%0x - %s\n", 499 result, Trspi_Error_String(result)); 500 return (result); 501 } 502 503 offset = 0; 504 result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pub_key); 505 if (result != TSS_SUCCESS) { 506 stlogit("Trspi_UnloadBlob_PUBKEY failed: rc=0x%0x - %s\n", 507 result, Trspi_Error_String(result)); 508 return (result); 509 } 510 511 Tspi_Context_FreeMemory(hContext, blob); 512 /* Free the first dangling reference, putting 'n' in its place */ 513 free(pub_key.pubKey.key); 514 pub_key.pubKey.keyLength = size_n; 515 pub_key.pubKey.key = n; 516 517 offset = 0; 518 Trspi_LoadBlob_PUBKEY(&offset, pub_blob, &pub_key); 519 520 /* Free the second dangling reference */ 521 free(pub_key.algorithmParms.parms); 522 523 /* set the public key data in the TSS object */ 524 result = Tspi_SetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 525 TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, (UINT32)offset, pub_blob); 526 if (result != TSS_SUCCESS) { 527 stlogit("Tspi_SetAttribData failed: rc=0x%0x - %s\n", 528 result, Trspi_Error_String(result)); 529 return (result); 530 } 531 532 return (result); 533 } 534 535 /* 536 * Get details about the TPM to put into the token_info structure. 537 */ 538 CK_RV 539 token_get_tpm_info(TSS_HCONTEXT hContext, TOKEN_DATA *td) 540 { 541 TSS_RESULT result; 542 TPM_CAPABILITY_AREA capArea = TSS_TPMCAP_VERSION_VAL; 543 UINT32 datalen; 544 BYTE *data; 545 TSS_HTPM hTPM; 546 547 if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) { 548 stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s", 549 result, Trspi_Error_String(result)); 550 return (CKR_FUNCTION_FAILED); 551 } 552 if ((result = Tspi_TPM_GetCapability(hTPM, 553 capArea, 0, NULL, &datalen, &data)) != 0 || datalen == 0 || 554 data == NULL) { 555 stlogit("Tspi_Context_GetCapability: 0x%0x - %s", 556 result, Trspi_Error_String(result)); 557 return (CKR_FUNCTION_FAILED); 558 } 559 if (datalen > sizeof (tpmvinfo)) { 560 Tspi_Context_FreeMemory(hContext, data); 561 return (CKR_FUNCTION_FAILED); 562 } 563 564 (void) memcpy(&tpmvinfo, (void *)data, sizeof (tpmvinfo)); 565 566 bzero(td->token_info.manufacturerID, 567 sizeof (td->token_info.manufacturerID)); 568 569 (void) memset(td->token_info.manufacturerID, ' ', 570 sizeof (td->token_info.manufacturerID) - 1); 571 (void) memcpy(td->token_info.manufacturerID, 572 tpmvinfo.tpmVendorID, sizeof (tpmvinfo.tpmVendorID)); 573 574 (void) memset(td->token_info.label, ' ', 575 sizeof (td->token_info.label) - 1); 576 (void) memcpy(td->token_info.label, "TPM", 6); 577 578 td->token_info.hardwareVersion.major = tpmvinfo.version.major; 579 td->token_info.hardwareVersion.minor = tpmvinfo.version.minor; 580 td->token_info.firmwareVersion.major = tpmvinfo.version.revMajor; 581 td->token_info.firmwareVersion.minor = tpmvinfo.version.revMinor; 582 583 Tspi_Context_FreeMemory(hContext, data); 584 return (CKR_OK); 585 } 586 587 /*ARGSUSED*/ 588 CK_RV 589 token_specific_session(CK_SLOT_ID slotid) 590 { 591 return (CKR_OK); 592 } 593 594 CK_RV 595 token_rng(TSS_HCONTEXT hContext, CK_BYTE *output, CK_ULONG bytes) 596 { 597 TSS_RESULT rc; 598 TSS_HTPM hTPM; 599 BYTE *random_bytes = NULL; 600 601 if ((rc = Tspi_Context_GetTpmObject(hContext, &hTPM))) { 602 stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s", 603 rc, Trspi_Error_String(rc)); 604 return (CKR_FUNCTION_FAILED); 605 } 606 607 if ((rc = Tspi_TPM_GetRandom(hTPM, bytes, &random_bytes))) { 608 stlogit("Tspi_TPM_GetRandom: 0x%0x - %s", 609 rc, Trspi_Error_String(rc)); 610 return (CKR_FUNCTION_FAILED); 611 } 612 613 (void) memcpy(output, random_bytes, bytes); 614 Tspi_Context_FreeMemory(hContext, random_bytes); 615 616 return (CKR_OK); 617 } 618 619 TSS_RESULT 620 open_tss_context(TSS_HCONTEXT *pContext) 621 { 622 TSS_RESULT result; 623 624 if ((result = Tspi_Context_Create(pContext))) { 625 stlogit("Tspi_Context_Create: 0x%0x - %s", 626 result, Trspi_Error_String(result)); 627 return (CKR_FUNCTION_FAILED); 628 } 629 630 if ((result = Tspi_Context_Connect(*pContext, NULL))) { 631 stlogit("Tspi_Context_Connect: 0x%0x - %s", 632 result, Trspi_Error_String(result)); 633 return (CKR_FUNCTION_FAILED); 634 } 635 return (result); 636 } 637 638 /*ARGSUSED*/ 639 static CK_RV 640 token_specific_init(char *Correlator, CK_SLOT_ID SlotNumber, 641 TSS_HCONTEXT *hContext) 642 { 643 TSS_RESULT result; 644 645 result = open_tss_context(hContext); 646 if (result) 647 return (CKR_FUNCTION_FAILED); 648 649 if ((result = Tspi_Context_GetDefaultPolicy(*hContext, 650 &hDefaultPolicy))) { 651 stlogit("Tspi_Context_GetDefaultPolicy: 0x%0x - %s", 652 result, Trspi_Error_String(result)); 653 return (CKR_FUNCTION_FAILED); 654 } 655 656 local_uuid_clear(&publicRootKeyUUID); 657 local_uuid_clear(&privateRootKeyUUID); 658 local_uuid_clear(&publicLeafKeyUUID); 659 local_uuid_clear(&privateLeafKeyUUID); 660 661 result = token_get_tpm_info(*hContext, nv_token_data); 662 return (result); 663 } 664 665 /* 666 * Try to find the opaque key blob data for a token object. 667 */ 668 static CK_RV 669 token_get_key_blob(CK_OBJECT_HANDLE ckKey, CK_ULONG *blob_size, 670 CK_BYTE **ret_blob) 671 { 672 CK_RV rc = CKR_OK; 673 CK_BYTE_PTR blob = NULL; 674 CK_ATTRIBUTE tmpl[] = { 675 {CKA_IBM_OPAQUE, NULL_PTR, 0} 676 }; 677 SESSION dummy_sess; 678 679 /* set up dummy session */ 680 (void) memset(&dummy_sess, 0, sizeof (SESSION)); 681 dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS; 682 683 /* find object the first time to return the size of the buffer needed */ 684 if ((rc = object_mgr_get_attribute_values(&dummy_sess, ckKey, 685 tmpl, 1))) { 686 return (rc); 687 } 688 689 blob = malloc(tmpl[0].ulValueLen); 690 if (blob == NULL) { 691 rc = CKR_HOST_MEMORY; 692 return (rc); 693 } 694 695 tmpl[0].pValue = blob; 696 /* find object the 2nd time to fill the buffer with data */ 697 if ((rc = object_mgr_get_attribute_values(&dummy_sess, ckKey, 698 tmpl, 1))) { 699 return (rc); 700 } 701 702 *ret_blob = blob; 703 *blob_size = tmpl[0].ulValueLen; 704 done: 705 return (rc); 706 } 707 708 /* 709 * Given a modulus and prime from an RSA key, create a TSS_HKEY object by 710 * wrapping the RSA key with a key from the TPM (SRK or other previously stored 711 * key). 712 */ 713 static CK_RV 714 token_wrap_sw_key( 715 TSS_HCONTEXT hContext, 716 int size_n, 717 unsigned char *n, 718 int size_p, 719 unsigned char *p, 720 TSS_HKEY hParentKey, 721 TSS_FLAG initFlags, 722 TSS_HKEY *phKey) 723 { 724 TSS_RESULT result; 725 TSS_HPOLICY hPolicy; 726 UINT32 key_size; 727 728 key_size = util_get_keysize_flag(size_n * 8); 729 if (initFlags == 0) { 730 return (CKR_FUNCTION_FAILED); 731 } 732 733 /* create the TSS key object */ 734 result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, 735 TSS_KEY_MIGRATABLE | initFlags | key_size, phKey); 736 if (result != TSS_SUCCESS) { 737 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 738 result, Trspi_Error_String(result)); 739 return (CKR_FUNCTION_FAILED); 740 } 741 742 result = set_public_modulus(hContext, *phKey, size_n, n); 743 if (result != TSS_SUCCESS) { 744 Tspi_Context_CloseObject(hContext, *phKey); 745 *phKey = NULL_HKEY; 746 return (CKR_FUNCTION_FAILED); 747 } 748 749 /* set the private key data in the TSS object */ 750 result = Tspi_SetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB, 751 TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, size_p, p); 752 if (result != TSS_SUCCESS) { 753 stlogit("Tspi_SetAttribData: 0x%x - %s", 754 result, Trspi_Error_String(result)); 755 Tspi_Context_CloseObject(hContext, *phKey); 756 *phKey = NULL_HKEY; 757 return (CKR_FUNCTION_FAILED); 758 } 759 760 result = Tspi_Context_CreateObject(hContext, 761 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, &hPolicy); 762 if (result != TSS_SUCCESS) { 763 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 764 result, Trspi_Error_String(result)); 765 Tspi_Context_CloseObject(hContext, *phKey); 766 *phKey = NULL_HKEY; 767 return (CKR_FUNCTION_FAILED); 768 } 769 770 result = Tspi_Policy_AssignToObject(hPolicy, *phKey); 771 if (result != TSS_SUCCESS) { 772 stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s\n", 773 result, Trspi_Error_String(result)); 774 Tspi_Context_CloseObject(hContext, *phKey); 775 Tspi_Context_CloseObject(hContext, hPolicy); 776 *phKey = NULL_HKEY; 777 return (CKR_FUNCTION_FAILED); 778 } 779 780 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL); 781 if (result != TSS_SUCCESS) { 782 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s\n", 783 result, Trspi_Error_String(result)); 784 Tspi_Context_CloseObject(hContext, *phKey); 785 Tspi_Context_CloseObject(hContext, hPolicy); 786 *phKey = NULL_HKEY; 787 return (CKR_FUNCTION_FAILED); 788 } 789 790 if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) { 791 if ((result = Tspi_SetAttribUint32(*phKey, 792 TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_ENCSCHEME, 793 TSS_ES_RSAESPKCSV15))) { 794 stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n", 795 result, Trspi_Error_String(result)); 796 Tspi_Context_CloseObject(hContext, *phKey); 797 Tspi_Context_CloseObject(hContext, hPolicy); 798 return (CKR_FUNCTION_FAILED); 799 } 800 801 if ((result = Tspi_SetAttribUint32(*phKey, 802 TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME, 803 TSS_SS_RSASSAPKCS1V15_DER))) { 804 stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n", 805 result, Trspi_Error_String(result)); 806 Tspi_Context_CloseObject(hContext, *phKey); 807 Tspi_Context_CloseObject(hContext, hPolicy); 808 return (CKR_FUNCTION_FAILED); 809 } 810 } 811 812 result = Tspi_Key_WrapKey(*phKey, hParentKey, NULL_HPCRS); 813 if (result != TSS_SUCCESS) { 814 stlogit("Tspi_Key_WrapKey: 0x%0x - %s", 815 result, Trspi_Error_String(result)); 816 Tspi_Context_CloseObject(hContext, *phKey); 817 *phKey = NULL_HKEY; 818 return (CKR_FUNCTION_FAILED); 819 } 820 821 return (CKR_OK); 822 } 823 824 /* 825 * Create a TPM key blob for an imported key. This function is only called when 826 * a key is in active use, so any failure should trickle through. 827 */ 828 static CK_RV 829 token_wrap_key_object(TSS_HCONTEXT hContext, 830 CK_OBJECT_HANDLE ckObject, 831 TSS_HKEY hParentKey, TSS_HKEY *phKey) 832 { 833 CK_RV rc = CKR_OK; 834 CK_ATTRIBUTE *attr = NULL, *new_attr, *prime_attr; 835 CK_ULONG class, key_type; 836 OBJECT *obj; 837 838 TSS_RESULT result; 839 TSS_FLAG initFlags = 0; 840 BYTE *rgbBlob; 841 UINT32 ulBlobLen; 842 843 if ((rc = object_mgr_find_in_map1(hContext, ckObject, &obj))) { 844 return (rc); 845 } 846 847 /* if the object isn't a key, fail */ 848 if (template_attribute_find(obj->template, CKA_KEY_TYPE, 849 &attr) == FALSE) { 850 return (CKR_TEMPLATE_INCOMPLETE); 851 } 852 853 key_type = *((CK_ULONG *)attr->pValue); 854 855 if (key_type != CKK_RSA) { 856 return (CKR_TEMPLATE_INCONSISTENT); 857 } 858 859 if (template_attribute_find(obj->template, CKA_CLASS, 860 &attr) == FALSE) { 861 return (CKR_TEMPLATE_INCOMPLETE); 862 } 863 864 class = *((CK_ULONG *)attr->pValue); 865 866 if (class == CKO_PRIVATE_KEY) { 867 /* 868 * In order to create a full TSS key blob using a PKCS#11 869 * private key object, we need one of the two primes, the 870 * modulus and the private exponent and we need the public 871 * exponent to be correct. 872 */ 873 874 /* 875 * Check the least likely attribute to exist first, the 876 * primes. 877 */ 878 if (template_attribute_find(obj->template, CKA_PRIME_1, 879 &prime_attr) == FALSE) { 880 if (template_attribute_find(obj->template, 881 CKA_PRIME_2, &prime_attr) == FALSE) { 882 return (CKR_TEMPLATE_INCOMPLETE); 883 } 884 } 885 886 /* Make sure the public exponent is usable */ 887 if ((rc = util_check_public_exponent(obj->template))) { 888 return (CKR_TEMPLATE_INCONSISTENT); 889 } 890 891 /* get the modulus */ 892 if (template_attribute_find(obj->template, CKA_MODULUS, 893 &attr) == FALSE) { 894 return (CKR_TEMPLATE_INCOMPLETE); 895 } 896 897 /* make sure the key size is usable */ 898 initFlags = util_get_keysize_flag(attr->ulValueLen * 8); 899 if (initFlags == 0) { 900 return (CKR_TEMPLATE_INCONSISTENT); 901 } 902 903 /* generate the software based key */ 904 if ((rc = token_wrap_sw_key(hContext, 905 (int)attr->ulValueLen, attr->pValue, 906 (int)prime_attr->ulValueLen, prime_attr->pValue, 907 hParentKey, TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION, 908 phKey))) { 909 return (rc); 910 } 911 } else if (class == CKO_PUBLIC_KEY) { 912 /* Make sure the public exponent is usable */ 913 if ((util_check_public_exponent(obj->template))) { 914 return (CKR_TEMPLATE_INCONSISTENT); 915 } 916 917 /* grab the modulus to put into the TSS key object */ 918 if (template_attribute_find(obj->template, 919 CKA_MODULUS, &attr) == FALSE) { 920 return (CKR_TEMPLATE_INCONSISTENT); 921 } 922 923 /* make sure the key size is usable */ 924 initFlags = util_get_keysize_flag(attr->ulValueLen * 8); 925 if (initFlags == 0) { 926 return (CKR_TEMPLATE_INCONSISTENT); 927 } 928 929 initFlags |= TSS_KEY_TYPE_LEGACY | TSS_KEY_MIGRATABLE | 930 TSS_KEY_NO_AUTHORIZATION; 931 932 if ((result = Tspi_Context_CreateObject(hContext, 933 TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) { 934 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 935 result, Trspi_Error_String(result)); 936 return (result); 937 } 938 939 if ((result = set_public_modulus(hContext, *phKey, 940 attr->ulValueLen, attr->pValue))) { 941 Tspi_Context_CloseObject(hContext, *phKey); 942 *phKey = NULL_HKEY; 943 return (CKR_FUNCTION_FAILED); 944 } 945 } else { 946 return (CKR_FUNCTION_FAILED); 947 } 948 949 /* grab the entire key blob to put into the PKCS#11 object */ 950 if ((result = Tspi_GetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB, 951 TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { 952 stlogit("Tspi_GetAttribData: 0x%0x - %s", 953 result, Trspi_Error_String(result)); 954 return (CKR_FUNCTION_FAILED); 955 } 956 957 /* insert the key blob into the object */ 958 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, 959 &new_attr))) { 960 Tspi_Context_FreeMemory(hContext, rgbBlob); 961 return (rc); 962 } 963 (void) template_update_attribute(obj->template, new_attr); 964 Tspi_Context_FreeMemory(hContext, rgbBlob); 965 966 /* 967 * If this is a token object, save it with the new attribute 968 * so that we don't have to go down this path again. 969 */ 970 if (!object_is_session_object(obj)) { 971 rc = save_token_object(hContext, obj); 972 } 973 974 return (rc); 975 } 976 977 static TSS_RESULT 978 tss_assign_secret_key_policy(TSS_HCONTEXT hContext, TSS_HKEY hKey, 979 CK_CHAR *passHash) 980 { 981 TSS_RESULT result; 982 TSS_HPOLICY hPolicy; 983 984 if ((result = Tspi_Context_CreateObject(hContext, 985 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { 986 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 987 result, Trspi_Error_String(result)); 988 return (result); 989 } 990 if ((result = Tspi_Policy_AssignToObject(hPolicy, hKey))) { 991 stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s", 992 result, Trspi_Error_String(result)); 993 goto done; 994 } 995 if (passHash == NULL) { 996 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 997 0, NULL); 998 } else { 999 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 1000 SHA1_DIGEST_LENGTH, passHash); 1001 } 1002 if (result != TSS_SUCCESS) { 1003 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1004 result, Trspi_Error_String(result)); 1005 goto done; 1006 } 1007 done: 1008 if (result != TSS_SUCCESS) 1009 Tspi_Context_CloseObject(hContext, hPolicy); 1010 return (result); 1011 } 1012 1013 /* 1014 * Take a key from the TSS store (on-disk) and load it into the TPM, wrapped 1015 * by an already TPM-resident key and protected with a PIN (optional). 1016 */ 1017 static CK_RV 1018 token_load_key( 1019 TSS_HCONTEXT hContext, 1020 CK_OBJECT_HANDLE ckKey, 1021 TSS_HKEY hParentKey, 1022 CK_CHAR_PTR passHash, 1023 TSS_HKEY *phKey) 1024 { 1025 TSS_RESULT result; 1026 CK_BYTE *blob = NULL; 1027 CK_ULONG ulBlobSize = 0; 1028 CK_RV rc; 1029 1030 if ((rc = token_get_key_blob(ckKey, &ulBlobSize, &blob))) { 1031 if (rc != CKR_ATTRIBUTE_TYPE_INVALID) { 1032 return (rc); 1033 } 1034 /* 1035 * The key blob wasn't found, load the parts of the key 1036 * from the object DB and create a new key object that 1037 * gets loaded into the TPM, wrapped with the parent key. 1038 */ 1039 if ((rc = token_wrap_key_object(hContext, ckKey, 1040 hParentKey, phKey))) { 1041 return (rc); 1042 } 1043 } 1044 1045 if (blob != NULL) { 1046 /* load the key into the TPM, wrapped with parent key */ 1047 if ((result = Tspi_Context_LoadKeyByBlob(hContext, 1048 hParentKey, ulBlobSize, blob, phKey))) { 1049 stlogit("Tspi_Context_LoadKeyByBlob: 0x%x - %s", 1050 result, Trspi_Error_String(result)); 1051 goto done; 1052 } 1053 } 1054 /* 1055 * Assign the PIN hash (optional) to the newly loaded key object, 1056 * if this PIN is incorrect, the TPM will not be able to decrypt 1057 * the private key and use it. 1058 */ 1059 result = tss_assign_secret_key_policy(hContext, *phKey, passHash); 1060 done: 1061 free(blob); 1062 return (result); 1063 } 1064 1065 /* 1066 * Load the SRK into the TPM by referencing its well-known UUID and using the 1067 * default SRK PIN (20 bytes of 0x00). 1068 * 1069 * NOTE - if the SRK PIN is changed by an administrative tool, this code will 1070 * fail because it assumes that the well-known PIN is still being used. 1071 */ 1072 static TSS_RESULT 1073 token_load_srk(TSS_HCONTEXT hContext, TSS_HKEY *hSRK) 1074 { 1075 TSS_HPOLICY hPolicy; 1076 TSS_RESULT result; 1077 TSS_UUID SRK_UUID = TSS_UUID_SRK; 1078 BYTE wellKnown[] = TSS_WELL_KNOWN_SECRET; 1079 TSS_HTPM hTPM; 1080 1081 if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) { 1082 stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s", 1083 result, Trspi_Error_String(result)); 1084 return (CKR_FUNCTION_FAILED); 1085 } 1086 1087 /* load the SRK */ 1088 if ((result = Tspi_Context_LoadKeyByUUID(hContext, 1089 TSS_PS_TYPE_SYSTEM, SRK_UUID, hSRK))) { 1090 stlogit("Tspi_Context_LoadKeyByUUID: 0x%0x - %s", 1091 result, Trspi_Error_String(result)); 1092 goto done; 1093 } 1094 if ((result = Tspi_GetPolicyObject(*hSRK, TSS_POLICY_USAGE, 1095 &hPolicy))) { 1096 stlogit("Tspi_GetPolicyObject: 0x%0x - %s", 1097 result, Trspi_Error_String(result)); 1098 goto done; 1099 } 1100 if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 1101 sizeof (wellKnown), wellKnown))) { 1102 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1103 result, Trspi_Error_String(result)); 1104 goto done; 1105 } 1106 1107 done: 1108 return (result); 1109 } 1110 1111 static TSS_RESULT 1112 tss_find_and_load_key(TSS_HCONTEXT hContext, 1113 char *keyid, TSS_UUID *uuid, TSS_HKEY hParent, 1114 BYTE *hash, TSS_HKEY *hKey) 1115 { 1116 TSS_RESULT result; 1117 1118 if (local_uuid_is_null(uuid) && 1119 find_uuid(keyid, uuid)) { 1120 /* The UUID was not created or saved yet */ 1121 return (1); 1122 } 1123 result = Tspi_Context_GetKeyByUUID(hContext, 1124 TSS_PS_TYPE_USER, *uuid, hKey); 1125 if (result) { 1126 stlogit("Tspi_Context_GetKeyByUUID: 0x%0x - %s", 1127 result, Trspi_Error_String(result)); 1128 return (result); 1129 } 1130 1131 if (hash != NULL) { 1132 result = tss_assign_secret_key_policy(hContext, *hKey, 1133 (CK_BYTE *)hash); 1134 if (result) 1135 return (result); 1136 } 1137 1138 result = Tspi_Key_LoadKey(*hKey, hParent); 1139 if (result) 1140 stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1141 result, Trspi_Error_String(result)); 1142 1143 return (result); 1144 } 1145 1146 static TSS_RESULT 1147 token_load_public_root_key(TSS_HCONTEXT hContext) 1148 { 1149 TSS_RESULT result; 1150 TSS_HKEY hSRK; 1151 1152 if (hPublicRootKey != NULL_HKEY) 1153 return (TSS_SUCCESS); 1154 1155 if ((result = token_load_srk(hContext, &hSRK))) { 1156 return (result); 1157 } 1158 1159 result = tss_find_and_load_key(hContext, 1160 TPMTOK_PUBLIC_ROOT_KEY_ID, 1161 &publicRootKeyUUID, hSRK, NULL, &hPublicRootKey); 1162 if (result) 1163 return (result); 1164 1165 return (result); 1166 } 1167 1168 static TSS_RESULT 1169 tss_generate_key(TSS_HCONTEXT hContext, TSS_FLAG initFlags, BYTE *passHash, 1170 TSS_HKEY hParentKey, TSS_HKEY *phKey) 1171 { 1172 TSS_RESULT result; 1173 TSS_HPOLICY hMigPolicy; 1174 1175 if ((result = Tspi_Context_CreateObject(hContext, 1176 TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) { 1177 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1178 result, Trspi_Error_String(result)); 1179 return (result); 1180 } 1181 result = tss_assign_secret_key_policy(hContext, *phKey, passHash); 1182 1183 if (result) { 1184 Tspi_Context_CloseObject(hContext, *phKey); 1185 return (result); 1186 } 1187 1188 if (TPMTOK_TSS_KEY_MIG_TYPE(initFlags) == TSS_KEY_MIGRATABLE) { 1189 if ((result = Tspi_Context_CreateObject(hContext, 1190 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, 1191 &hMigPolicy))) { 1192 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1193 result, Trspi_Error_String(result)); 1194 Tspi_Context_CloseObject(hContext, *phKey); 1195 return (result); 1196 } 1197 1198 if (passHash == NULL) { 1199 result = Tspi_Policy_SetSecret(hMigPolicy, 1200 TSS_SECRET_MODE_NONE, 0, NULL); 1201 } else { 1202 result = Tspi_Policy_SetSecret(hMigPolicy, 1203 TSS_SECRET_MODE_SHA1, 20, passHash); 1204 } 1205 1206 if (result != TSS_SUCCESS) { 1207 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1208 result, Trspi_Error_String(result)); 1209 Tspi_Context_CloseObject(hContext, *phKey); 1210 Tspi_Context_CloseObject(hContext, hMigPolicy); 1211 return (result); 1212 } 1213 1214 if ((result = Tspi_Policy_AssignToObject(hMigPolicy, *phKey))) { 1215 stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s", 1216 result, Trspi_Error_String(result)); 1217 Tspi_Context_CloseObject(hContext, *phKey); 1218 Tspi_Context_CloseObject(hContext, hMigPolicy); 1219 return (result); 1220 } 1221 } 1222 1223 if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) { 1224 if ((result = Tspi_SetAttribUint32(*phKey, 1225 TSS_TSPATTRIB_KEY_INFO, 1226 TSS_TSPATTRIB_KEYINFO_ENCSCHEME, 1227 TSS_ES_RSAESPKCSV15))) { 1228 stlogit("Tspi_SetAttribUint32: 0x%0x - %s", 1229 result, Trspi_Error_String(result)); 1230 Tspi_Context_CloseObject(hContext, *phKey); 1231 Tspi_Context_CloseObject(hContext, hMigPolicy); 1232 return (result); 1233 } 1234 1235 if ((result = Tspi_SetAttribUint32(*phKey, 1236 TSS_TSPATTRIB_KEY_INFO, 1237 TSS_TSPATTRIB_KEYINFO_SIGSCHEME, 1238 TSS_SS_RSASSAPKCS1V15_DER))) { 1239 stlogit("Tspi_SetAttribUint32: 0x%0x - %s", 1240 result, Trspi_Error_String(result)); 1241 Tspi_Context_CloseObject(hContext, *phKey); 1242 Tspi_Context_CloseObject(hContext, hMigPolicy); 1243 return (result); 1244 } 1245 } 1246 1247 if ((result = Tspi_Key_CreateKey(*phKey, hParentKey, 0))) { 1248 stlogit("Tspi_Key_CreateKey: 0x%0x - %s", 1249 result, Trspi_Error_String(result)); 1250 Tspi_Context_CloseObject(hContext, *phKey); 1251 Tspi_Context_CloseObject(hContext, hMigPolicy); 1252 } 1253 1254 return (result); 1255 } 1256 1257 static TSS_RESULT 1258 tss_change_auth( 1259 TSS_HCONTEXT hContext, 1260 TSS_HKEY hObjectToChange, TSS_HKEY hParentObject, 1261 TSS_UUID objUUID, TSS_UUID parentUUID, 1262 CK_CHAR *passHash) 1263 { 1264 TSS_RESULT result; 1265 TSS_HPOLICY hPolicy; 1266 TSS_HKEY oldkey; 1267 1268 if ((result = Tspi_Context_CreateObject(hContext, 1269 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { 1270 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1271 result, Trspi_Error_String(result)); 1272 return (result); 1273 } 1274 1275 if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 1276 SHA1_DIGEST_LENGTH, passHash))) { 1277 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 1278 result, Trspi_Error_String(result)); 1279 return (result); 1280 } 1281 1282 if ((result = Tspi_ChangeAuth(hObjectToChange, hParentObject, 1283 hPolicy))) { 1284 stlogit("Tspi_ChangeAuth: 0x%0x - %s", 1285 result, Trspi_Error_String(result)); 1286 } 1287 /* 1288 * Update the PS key by unregistering the key UUID and then 1289 * re-registering with the same UUID. This forces the updated 1290 * auth data associated with the key to be stored in PS so 1291 * the new PIN can be used next time. 1292 */ 1293 if ((result = Tspi_Context_UnregisterKey(hContext, 1294 TSS_PS_TYPE_USER, objUUID, &oldkey))) 1295 stlogit("Tspi_Context_UnregisterKey: 0x%0x - %s", 1296 result, Trspi_Error_String(result)); 1297 1298 if ((result = Tspi_Context_RegisterKey(hContext, hObjectToChange, 1299 TSS_PS_TYPE_USER, objUUID, TSS_PS_TYPE_USER, parentUUID))) 1300 stlogit("Tspi_Context_RegisterKey: 0x%0x - %s", 1301 result, Trspi_Error_String(result)); 1302 1303 return (result); 1304 } 1305 1306 static CK_RV 1307 token_generate_leaf_key(TSS_HCONTEXT hContext, 1308 int key_type, CK_CHAR_PTR passHash, TSS_HKEY *phKey) 1309 { 1310 CK_RV rc = CKR_FUNCTION_FAILED; 1311 TSS_RESULT result; 1312 TSS_HKEY hParentKey; 1313 TSS_UUID newuuid, parentUUID; 1314 char *keyid; 1315 TSS_FLAG initFlags = TSS_KEY_MIGRATABLE | 1316 TSS_KEY_TYPE_BIND | TSS_KEY_SIZE_2048 | TSS_KEY_AUTHORIZATION; 1317 1318 switch (key_type) { 1319 case TPMTOK_PUBLIC_LEAF_KEY: 1320 hParentKey = hPublicRootKey; 1321 keyid = TPMTOK_PUBLIC_LEAF_KEY_ID; 1322 local_uuid_copy(&parentUUID, &publicRootKeyUUID); 1323 break; 1324 case TPMTOK_PRIVATE_LEAF_KEY: 1325 hParentKey = hPrivateRootKey; 1326 keyid = TPMTOK_PRIVATE_LEAF_KEY_ID; 1327 local_uuid_copy(&parentUUID, &privateRootKeyUUID); 1328 break; 1329 default: 1330 stlogit("Unknown key type 0x%0x", key_type); 1331 goto done; 1332 break; 1333 } 1334 1335 if (result = tss_generate_key(hContext, initFlags, passHash, 1336 hParentKey, phKey)) { 1337 return (rc); 1338 } 1339 1340 /* 1341 * - generate newUUID 1342 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1343 * USER, newUUID, USER, parentUUID); 1344 * - store newUUID 1345 */ 1346 (void) local_uuid_generate(&newuuid); 1347 1348 result = Tspi_Context_RegisterKey(hContext, *phKey, 1349 TSS_PS_TYPE_USER, newuuid, 1350 TSS_PS_TYPE_USER, parentUUID); 1351 if (result == TSS_SUCCESS) { 1352 int ret; 1353 /* 1354 * Add the UUID to the token UUID index. 1355 */ 1356 ret = add_uuid(keyid, &newuuid); 1357 1358 if (ret) 1359 result = Tspi_Context_UnregisterKey(hContext, 1360 TSS_PS_TYPE_USER, newuuid, phKey); 1361 else 1362 rc = CKR_OK; 1363 } 1364 1365 done: 1366 return (rc); 1367 } 1368 1369 /* 1370 * PINs are verified by attempting to bind/unbind random data using a 1371 * TPM resident key that has the PIN being tested assigned as its "secret". 1372 * If the PIN is incorrect, the unbind operation will fail. 1373 */ 1374 static CK_RV 1375 token_verify_pin(TSS_HCONTEXT hContext, TSS_HKEY hKey) 1376 { 1377 TSS_HENCDATA hEncData; 1378 UINT32 ulUnboundDataLen; 1379 BYTE *rgbUnboundData = NULL; 1380 BYTE rgbData[16]; 1381 TSS_RESULT result; 1382 CK_RV rc = CKR_FUNCTION_FAILED; 1383 1384 if ((result = Tspi_Context_CreateObject(hContext, 1385 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 1386 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1387 result, Trspi_Error_String(result)); 1388 goto done; 1389 } 1390 1391 /* Use some random data */ 1392 rc = token_rng(hContext, rgbData, sizeof (rgbData)); 1393 if (rc) 1394 goto done; 1395 1396 if ((result = Tspi_Data_Bind(hEncData, hKey, 1397 sizeof (rgbData), rgbData))) { 1398 stlogit("Tspi_Data_Bind: 0x%0x - %s", 1399 result, Trspi_Error_String(result)); 1400 goto done; 1401 } 1402 1403 /* unbind the junk data to test the key's auth data */ 1404 result = Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen, 1405 &rgbUnboundData); 1406 if (result == TSS_E_TSP_AUTHFAIL) { 1407 rc = CKR_PIN_INCORRECT; 1408 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 1409 result, Trspi_Error_String(result)); 1410 goto done; 1411 } else if (result != TSS_SUCCESS) { 1412 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 1413 result, Trspi_Error_String(result)); 1414 rc = CKR_FUNCTION_FAILED; 1415 goto done; 1416 } 1417 1418 if (memcmp(rgbUnboundData, rgbData, ulUnboundDataLen)) 1419 rc = CKR_PIN_INCORRECT; 1420 else 1421 rc = CKR_OK; 1422 1423 done: 1424 if (rgbUnboundData != NULL) 1425 Tspi_Context_FreeMemory(hContext, rgbUnboundData); 1426 Tspi_Context_CloseObject(hContext, hEncData); 1427 return (rc); 1428 } 1429 1430 static CK_RV 1431 token_create_private_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash) 1432 { 1433 CK_RV rc; 1434 TSS_RESULT result; 1435 int ret; 1436 TSS_FLAG initFlags = TSS_KEY_SIZE_2048 | 1437 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE; 1438 TSS_UUID SRK_UUID = TSS_UUID_SRK; 1439 TSS_HKEY hSRK; 1440 1441 if (token_load_srk(hContext, &hSRK)) 1442 return (CKR_FUNCTION_FAILED); 1443 1444 /* 1445 * - create UUID privateRootKeyUUID 1446 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1447 * USER, privateRootKeyUUID, system, UUID_SRK); 1448 * - store privateRootKeyUUID in users private token space. 1449 */ 1450 if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK, 1451 &hPrivateRootKey))) { 1452 return (result); 1453 } 1454 if (local_uuid_is_null(&privateRootKeyUUID)) 1455 local_uuid_generate(&privateRootKeyUUID); 1456 1457 result = Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1458 TSS_PS_TYPE_USER, privateRootKeyUUID, 1459 TSS_PS_TYPE_SYSTEM, SRK_UUID); 1460 1461 if (result) { 1462 local_uuid_clear(&privateRootKeyUUID); 1463 return (result); 1464 } 1465 1466 ret = add_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, &privateRootKeyUUID); 1467 if (ret) { 1468 result = Tspi_Context_UnregisterKey(hContext, 1469 TSS_PS_TYPE_USER, privateRootKeyUUID, 1470 &hPrivateRootKey); 1471 return (CKR_FUNCTION_FAILED); 1472 } 1473 1474 if ((result = Tspi_Key_LoadKey(hPrivateRootKey, hSRK))) { 1475 stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1476 result, Trspi_Error_String(result)); 1477 Tspi_Context_CloseObject(hContext, hPrivateRootKey); 1478 1479 (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID); 1480 local_uuid_clear(&privateRootKeyUUID); 1481 1482 hPrivateRootKey = NULL_HKEY; 1483 return (CKR_FUNCTION_FAILED); 1484 } 1485 1486 1487 /* generate the private leaf key */ 1488 if ((rc = token_generate_leaf_key(hContext, 1489 TPMTOK_PRIVATE_LEAF_KEY, 1490 pinHash, &hPrivateLeafKey))) { 1491 return (rc); 1492 } 1493 1494 if ((result = Tspi_Key_LoadKey(hPrivateLeafKey, hPrivateRootKey))) { 1495 stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1496 result, Trspi_Error_String(result)); 1497 1498 (void) Tspi_Context_UnregisterKey(hContext, 1499 TSS_PS_TYPE_USER, privateLeafKeyUUID, 1500 &hPrivateLeafKey); 1501 (void) remove_uuid(TPMTOK_PRIVATE_LEAF_KEY_ID); 1502 local_uuid_clear(&privateLeafKeyUUID); 1503 1504 (void) Tspi_Context_UnregisterKey(hContext, 1505 TSS_PS_TYPE_USER, privateRootKeyUUID, 1506 &hPrivateRootKey); 1507 (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID); 1508 local_uuid_clear(&privateRootKeyUUID); 1509 1510 Tspi_Context_CloseObject(hContext, hPrivateRootKey); 1511 hPrivateRootKey = NULL_HKEY; 1512 1513 Tspi_Context_CloseObject(hContext, hPrivateLeafKey); 1514 hPrivateRootKey = NULL_HKEY; 1515 1516 return (CKR_FUNCTION_FAILED); 1517 } 1518 return (rc); 1519 } 1520 1521 static CK_RV 1522 token_create_public_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash) 1523 { 1524 CK_RV rc; 1525 TSS_RESULT result; 1526 int ret; 1527 TSS_FLAG initFlags = TSS_KEY_SIZE_2048 | 1528 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE; 1529 TSS_UUID srk_uuid = TSS_UUID_SRK; 1530 TSS_HKEY hSRK; 1531 1532 if (token_load_srk(hContext, &hSRK)) 1533 return (CKR_FUNCTION_FAILED); 1534 1535 /* 1536 * - create publicRootKeyUUID 1537 * - Tspi_Context_RegisterKey(hContext, hPublicRootKey, 1538 * USER, publicRootKeyUUID, system, UUID_SRK); 1539 * - store publicRootKeyUUID in users private token space. 1540 */ 1541 if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK, 1542 &hPublicRootKey))) { 1543 return (CKR_FUNCTION_FAILED); 1544 } 1545 if (local_uuid_is_null(&publicRootKeyUUID)) 1546 local_uuid_generate(&publicRootKeyUUID); 1547 1548 result = Tspi_Context_RegisterKey(hContext, hPublicRootKey, 1549 TSS_PS_TYPE_USER, publicRootKeyUUID, 1550 TSS_PS_TYPE_SYSTEM, srk_uuid); 1551 1552 if (result) { 1553 local_uuid_clear(&publicRootKeyUUID); 1554 return (CKR_FUNCTION_FAILED); 1555 } 1556 1557 ret = add_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID); 1558 if (ret) { 1559 result = Tspi_Context_UnregisterKey(hContext, 1560 TSS_PS_TYPE_USER, publicRootKeyUUID, 1561 &hPublicRootKey); 1562 /* does result matter here? */ 1563 return (CKR_FUNCTION_FAILED); 1564 } 1565 1566 /* Load the newly created publicRootKey into the TPM using the SRK */ 1567 if ((result = Tspi_Key_LoadKey(hPublicRootKey, hSRK))) { 1568 stlogit("Tspi_Key_LoadKey: 0x%x - %s", result, 1569 Trspi_Error_String(result)); 1570 Tspi_Context_CloseObject(hContext, hPublicRootKey); 1571 hPublicRootKey = NULL_HKEY; 1572 return (CKR_FUNCTION_FAILED); 1573 } 1574 1575 /* create the SO's leaf key */ 1576 if ((rc = token_generate_leaf_key(hContext, TPMTOK_PUBLIC_LEAF_KEY, 1577 pinHash, &hPublicLeafKey))) { 1578 return (rc); 1579 } 1580 1581 if ((result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey))) { 1582 stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1583 result, Trspi_Error_String(result)); 1584 1585 /* Unregister keys and clear UUIDs */ 1586 (void) Tspi_Context_UnregisterKey(hContext, 1587 TSS_PS_TYPE_USER, publicLeafKeyUUID, 1588 &hPublicLeafKey); 1589 (void) remove_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID); 1590 1591 (void) Tspi_Context_UnregisterKey(hContext, 1592 TSS_PS_TYPE_USER, publicRootKeyUUID, 1593 &hPublicRootKey); 1594 (void) remove_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID); 1595 1596 Tspi_Context_CloseObject(hContext, hPublicRootKey); 1597 hPublicRootKey = NULL_HKEY; 1598 1599 Tspi_Context_CloseObject(hContext, hPublicLeafKey); 1600 hPublicLeafKey = NULL_HKEY; 1601 1602 return (CKR_FUNCTION_FAILED); 1603 } 1604 1605 return (rc); 1606 } 1607 1608 CK_RV 1609 token_specific_login( 1610 TSS_HCONTEXT hContext, 1611 CK_USER_TYPE userType, 1612 CK_CHAR_PTR pPin, 1613 CK_ULONG ulPinLen) 1614 { 1615 CK_RV rc; 1616 CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; 1617 TSS_RESULT result; 1618 TSS_HKEY hSRK; 1619 1620 /* Make sure the SRK is loaded into the TPM */ 1621 if ((result = token_load_srk(hContext, &hSRK))) { 1622 return (CKR_FUNCTION_FAILED); 1623 } 1624 1625 if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { 1626 return (CKR_FUNCTION_FAILED); 1627 } 1628 1629 if (userType == CKU_USER) { 1630 /* 1631 * If the public root key doesn't exist yet, 1632 * the SO hasn't init'd the token. 1633 */ 1634 if ((result = token_load_public_root_key(hContext))) { 1635 if (result == TPM_E_DECRYPT_ERROR) { 1636 return (CKR_USER_PIN_NOT_INITIALIZED); 1637 } 1638 } 1639 1640 /* 1641 * - find privateRootKeyUUID 1642 * - load by UUID (SRK parent) 1643 */ 1644 if (local_uuid_is_null(&privateRootKeyUUID) && 1645 find_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, 1646 &privateRootKeyUUID)) { 1647 if (memcmp(hash_sha, 1648 default_user_pin_sha, 1649 SHA1_DIGEST_LENGTH)) 1650 return (CKR_PIN_INCORRECT); 1651 1652 not_initialized = 1; 1653 return (CKR_OK); 1654 } 1655 1656 if ((rc = verify_user_pin(hContext, hash_sha))) { 1657 return (rc); 1658 } 1659 1660 (void) memcpy(current_user_pin_sha, hash_sha, 1661 SHA1_DIGEST_LENGTH); 1662 1663 rc = load_private_token_objects(hContext); 1664 if (rc == CKR_OK) { 1665 (void) XProcLock(xproclock); 1666 global_shm->priv_loaded = TRUE; 1667 (void) XProcUnLock(xproclock); 1668 } 1669 } else { 1670 /* 1671 * SO login logic: 1672 * 1673 * - find publicRootKey UUID 1674 * - load by UUID wrap with hSRK from above 1675 */ 1676 if (local_uuid_is_null(&publicRootKeyUUID) && 1677 find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, 1678 &publicRootKeyUUID)) { 1679 if (memcmp(hash_sha, 1680 default_so_pin_sha, 1681 SHA1_DIGEST_LENGTH)) 1682 return (CKR_PIN_INCORRECT); 1683 1684 not_initialized = 1; 1685 return (CKR_OK); 1686 1687 } 1688 if (hPublicRootKey == NULL_HKEY) { 1689 result = tss_find_and_load_key( 1690 hContext, 1691 TPMTOK_PUBLIC_ROOT_KEY_ID, 1692 &publicRootKeyUUID, hSRK, NULL, 1693 &hPublicRootKey); 1694 1695 if (result) 1696 return (CKR_FUNCTION_FAILED); 1697 } 1698 1699 /* find, load the public leaf key */ 1700 if (hPublicLeafKey == NULL_HKEY) { 1701 result = tss_find_and_load_key( 1702 hContext, 1703 TPMTOK_PUBLIC_LEAF_KEY_ID, 1704 &publicLeafKeyUUID, hPublicRootKey, hash_sha, 1705 &hPublicLeafKey); 1706 if (result) 1707 return (CKR_FUNCTION_FAILED); 1708 } 1709 1710 if ((rc = token_verify_pin(hContext, hPublicLeafKey))) { 1711 return (rc); 1712 } 1713 1714 (void) memcpy(current_so_pin_sha, hash_sha, SHA1_DIGEST_LENGTH); 1715 } 1716 1717 return (rc); 1718 } 1719 1720 CK_RV 1721 token_specific_logout(TSS_HCONTEXT hContext) 1722 { 1723 if (hPrivateLeafKey != NULL_HKEY) { 1724 Tspi_Key_UnloadKey(hPrivateLeafKey); 1725 hPrivateLeafKey = NULL_HKEY; 1726 } else if (hPublicLeafKey != NULL_HKEY) { 1727 Tspi_Key_UnloadKey(hPublicLeafKey); 1728 hPublicLeafKey = NULL_HKEY; 1729 } 1730 1731 local_uuid_clear(&publicRootKeyUUID); 1732 local_uuid_clear(&publicLeafKeyUUID); 1733 local_uuid_clear(&privateRootKeyUUID); 1734 local_uuid_clear(&privateLeafKeyUUID); 1735 1736 (void) memset(current_so_pin_sha, 0, SHA1_DIGEST_LENGTH); 1737 (void) memset(current_user_pin_sha, 0, SHA1_DIGEST_LENGTH); 1738 1739 (void) object_mgr_purge_private_token_objects(hContext); 1740 1741 return (CKR_OK); 1742 } 1743 1744 /*ARGSUSED*/ 1745 CK_RV 1746 token_specific_init_pin(TSS_HCONTEXT hContext, 1747 CK_CHAR_PTR pPin, CK_ULONG ulPinLen) 1748 { 1749 /* 1750 * Since the SO must log in before calling C_InitPIN, we will 1751 * be able to return (CKR_OK) automatically here. 1752 * This is because the USER key structure is created at the 1753 * time of her first login, not at C_InitPIN time. 1754 */ 1755 return (CKR_OK); 1756 } 1757 1758 static CK_RV 1759 check_pin_properties(CK_USER_TYPE userType, CK_BYTE *pinHash, 1760 CK_ULONG ulPinLen) 1761 { 1762 /* make sure the new PIN is different */ 1763 if (userType == CKU_USER) { 1764 if (!memcmp(pinHash, default_user_pin_sha, 1765 SHA1_DIGEST_LENGTH)) { 1766 LogError1("new PIN must not be the default"); 1767 return (CKR_PIN_INVALID); 1768 } 1769 } else { 1770 if (!memcmp(pinHash, default_so_pin_sha, 1771 SHA1_DIGEST_LENGTH)) { 1772 LogError1("new PIN must not be the default"); 1773 return (CKR_PIN_INVALID); 1774 } 1775 } 1776 1777 if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) { 1778 LogError1("New PIN is out of size range"); 1779 return (CKR_PIN_LEN_RANGE); 1780 } 1781 1782 return (CKR_OK); 1783 } 1784 1785 /* 1786 * This function is called from set_pin only, where a non-logged-in public 1787 * session can provide the user pin which must be verified. This function 1788 * assumes that the pin has already been set once, so there's no migration 1789 * path option or checking of the default user pin. 1790 */ 1791 static CK_RV 1792 verify_user_pin(TSS_HCONTEXT hContext, CK_BYTE *hash_sha) 1793 { 1794 CK_RV rc; 1795 TSS_RESULT result; 1796 TSS_HKEY hSRK; 1797 1798 if (token_load_srk(hContext, &hSRK)) 1799 return (CKR_FUNCTION_FAILED); 1800 1801 /* 1802 * Verify the user by loading the privateLeafKey 1803 * into the TPM (if it's not already) and then 1804 * call the verify_pin operation. 1805 * 1806 * The hashed PIN is assigned to the private leaf key. 1807 * If it is incorrect (not the same as the one originally 1808 * used when the key was created), the verify operation 1809 * will fail. 1810 */ 1811 if (hPrivateRootKey == NULL_HKEY) { 1812 result = tss_find_and_load_key( 1813 hContext, 1814 TPMTOK_PRIVATE_ROOT_KEY_ID, 1815 &privateRootKeyUUID, hSRK, NULL, &hPrivateRootKey); 1816 if (result) 1817 return (CKR_FUNCTION_FAILED); 1818 } 1819 1820 if (hPrivateLeafKey == NULL_HKEY) { 1821 result = tss_find_and_load_key( 1822 hContext, 1823 TPMTOK_PRIVATE_LEAF_KEY_ID, 1824 &privateLeafKeyUUID, hPrivateRootKey, hash_sha, 1825 &hPrivateLeafKey); 1826 1827 if (result) 1828 return (CKR_FUNCTION_FAILED); 1829 } 1830 1831 /* 1832 * Verify that the PIN is correct by attempting to wrap/unwrap some 1833 * random data. 1834 */ 1835 if ((rc = token_verify_pin(hContext, hPrivateLeafKey))) { 1836 return (rc); 1837 } 1838 1839 return (CKR_OK); 1840 } 1841 1842 CK_RV 1843 token_specific_set_pin(ST_SESSION_HANDLE session, 1844 CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen, 1845 CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen) 1846 { 1847 SESSION *sess = session_mgr_find(session.sessionh); 1848 CK_BYTE oldpin_hash[SHA1_DIGEST_LENGTH]; 1849 CK_BYTE newpin_hash[SHA1_DIGEST_LENGTH]; 1850 CK_RV rc; 1851 TSS_HKEY hSRK; 1852 1853 if (!sess) { 1854 return (CKR_SESSION_HANDLE_INVALID); 1855 } 1856 1857 if ((rc = compute_sha(pOldPin, ulOldPinLen, oldpin_hash))) { 1858 return (CKR_FUNCTION_FAILED); 1859 } 1860 if ((rc = compute_sha(pNewPin, ulNewPinLen, newpin_hash))) { 1861 return (CKR_FUNCTION_FAILED); 1862 } 1863 1864 if (token_load_srk(sess->hContext, &hSRK)) { 1865 return (CKR_FUNCTION_FAILED); 1866 } 1867 1868 /* 1869 * From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of 1870 * the user that is currently logged in, or the CKU_USER PIN 1871 * if the session is not logged in." 1872 * A non R/W session fails with CKR_SESSION_READ_ONLY. 1873 */ 1874 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS || 1875 sess->session_info.state == CKS_RW_PUBLIC_SESSION) { 1876 if (not_initialized) { 1877 if (memcmp(oldpin_hash, default_user_pin_sha, 1878 SHA1_DIGEST_LENGTH)) { 1879 return (CKR_PIN_INCORRECT); 1880 } 1881 1882 if ((rc = check_pin_properties(CKU_USER, newpin_hash, 1883 ulNewPinLen))) { 1884 return (rc); 1885 } 1886 1887 if ((rc = token_create_private_tree(sess->hContext, 1888 newpin_hash))) { 1889 return (CKR_FUNCTION_FAILED); 1890 } 1891 1892 nv_token_data->token_info.flags &= 1893 ~(CKF_USER_PIN_TO_BE_CHANGED); 1894 nv_token_data->token_info.flags |= 1895 CKF_USER_PIN_INITIALIZED; 1896 1897 nv_token_data->token_info.flags &= 1898 ~(CKF_USER_PIN_TO_BE_CHANGED); 1899 nv_token_data->token_info.flags |= 1900 CKF_USER_PIN_INITIALIZED; 1901 1902 return (save_token_data(nv_token_data)); 1903 } 1904 1905 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) { 1906 /* if we're already logged in, just verify the hash */ 1907 if (memcmp(current_user_pin_sha, oldpin_hash, 1908 SHA1_DIGEST_LENGTH)) { 1909 return (CKR_PIN_INCORRECT); 1910 } 1911 } else { 1912 if ((rc = verify_user_pin(sess->hContext, 1913 oldpin_hash))) { 1914 return (rc); 1915 } 1916 } 1917 1918 if ((rc = check_pin_properties(CKU_USER, newpin_hash, 1919 ulNewPinLen))) 1920 return (rc); 1921 1922 /* change the auth on the TSS object */ 1923 if (tss_change_auth(sess->hContext, 1924 hPrivateLeafKey, hPrivateRootKey, 1925 privateLeafKeyUUID, privateRootKeyUUID, 1926 newpin_hash)) 1927 return (CKR_FUNCTION_FAILED); 1928 1929 } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { 1930 if (not_initialized) { 1931 if (memcmp(default_so_pin_sha, oldpin_hash, 1932 SHA1_DIGEST_LENGTH)) 1933 return (CKR_PIN_INCORRECT); 1934 1935 if ((rc = check_pin_properties(CKU_SO, 1936 newpin_hash, ulNewPinLen))) 1937 return (rc); 1938 1939 if ((rc = token_create_public_tree(sess->hContext, 1940 newpin_hash))) 1941 return (CKR_FUNCTION_FAILED); 1942 1943 nv_token_data->token_info.flags &= 1944 ~(CKF_SO_PIN_TO_BE_CHANGED); 1945 1946 return (save_token_data(nv_token_data)); 1947 } 1948 1949 if (memcmp(current_so_pin_sha, oldpin_hash, 1950 SHA1_DIGEST_LENGTH)) 1951 return (CKR_PIN_INCORRECT); 1952 1953 if ((rc = check_pin_properties(CKU_SO, newpin_hash, 1954 ulNewPinLen))) 1955 return (rc); 1956 1957 /* change auth on the SO's leaf key */ 1958 if (tss_change_auth(sess->hContext, 1959 hPublicLeafKey, hPublicRootKey, 1960 publicLeafKeyUUID, publicRootKeyUUID, 1961 newpin_hash)) 1962 return (CKR_FUNCTION_FAILED); 1963 1964 } else { 1965 rc = CKR_SESSION_READ_ONLY; 1966 } 1967 1968 return (rc); 1969 } 1970 1971 /* only called at token init time */ 1972 CK_RV 1973 token_specific_verify_so_pin(TSS_HCONTEXT hContext, CK_CHAR_PTR pPin, 1974 CK_ULONG ulPinLen) 1975 { 1976 CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; 1977 CK_RV rc; 1978 TSS_RESULT result; 1979 TSS_HKEY hSRK; 1980 1981 if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { 1982 return (CKR_FUNCTION_FAILED); 1983 } 1984 if ((rc = token_load_srk(hContext, &hSRK))) { 1985 return (CKR_FUNCTION_FAILED); 1986 } 1987 1988 /* 1989 * TRYME INSTEAD: 1990 * - find publicRootKeyUUID 1991 * - Load publicRootKey by UUID (SRK parent) 1992 * - find publicLeafKeyUUID 1993 * - Load publicLeafKey by UUID (publicRootKey parent) 1994 * - set password policy on publicLeafKey 1995 */ 1996 if (local_uuid_is_null(&publicRootKeyUUID) && 1997 find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID)) { 1998 /* 1999 * The SO hasn't set her PIN yet, compare the 2000 * login pin with the hard-coded value. 2001 */ 2002 if (memcmp(default_so_pin_sha, hash_sha, 2003 SHA1_DIGEST_LENGTH)) { 2004 return (CKR_PIN_INCORRECT); 2005 } 2006 return (CKR_OK); 2007 } 2008 2009 result = Tspi_Context_GetKeyByUUID(hContext, 2010 TSS_PS_TYPE_USER, publicRootKeyUUID, &hPublicRootKey); 2011 2012 if (result) 2013 return (CKR_FUNCTION_FAILED); 2014 2015 result = Tspi_Key_LoadKey(hPublicRootKey, hSRK); 2016 if (result) 2017 return (CKR_FUNCTION_FAILED); 2018 2019 if (local_uuid_is_null(&publicLeafKeyUUID) && 2020 find_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID, &publicLeafKeyUUID)) 2021 return (CKR_FUNCTION_FAILED); 2022 2023 result = Tspi_Context_GetKeyByUUID(hContext, 2024 TSS_PS_TYPE_USER, publicLeafKeyUUID, &hPublicLeafKey); 2025 if (result) 2026 return (CKR_FUNCTION_FAILED); 2027 2028 result = tss_assign_secret_key_policy(hContext, hPublicLeafKey, 2029 hash_sha); 2030 if (result) 2031 return (CKR_FUNCTION_FAILED); 2032 2033 result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey); 2034 if (result) 2035 return (CKR_FUNCTION_FAILED); 2036 2037 /* If the hash given is wrong, the verify will fail */ 2038 if ((rc = token_verify_pin(hContext, hPublicLeafKey))) { 2039 return (rc); 2040 } 2041 2042 return (CKR_OK); 2043 } 2044 2045 CK_RV 2046 token_specific_final() 2047 { 2048 return (CKR_OK); 2049 } 2050 2051 /* 2052 * Wrap the 20 bytes of auth data and store in an attribute of the two 2053 * keys. 2054 */ 2055 static CK_RV 2056 token_wrap_auth_data(TSS_HCONTEXT hContext, 2057 CK_BYTE *authData, TEMPLATE *publ_tmpl, 2058 TEMPLATE *priv_tmpl) 2059 { 2060 CK_RV rc; 2061 CK_ATTRIBUTE *new_attr; 2062 2063 TSS_RESULT ret; 2064 TSS_HKEY hParentKey; 2065 TSS_HENCDATA hEncData; 2066 BYTE *blob; 2067 UINT32 blob_size; 2068 2069 if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) { 2070 return (CKR_FUNCTION_FAILED); 2071 } else if (hPublicLeafKey != NULL_HKEY) { 2072 hParentKey = hPublicLeafKey; 2073 } else { 2074 hParentKey = hPrivateLeafKey; 2075 } 2076 2077 /* create the encrypted data object */ 2078 if ((ret = Tspi_Context_CreateObject(hContext, 2079 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2080 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2081 ret, Trspi_Error_String(ret)); 2082 return (CKR_FUNCTION_FAILED); 2083 } 2084 2085 if ((ret = Tspi_Data_Bind(hEncData, hParentKey, SHA1_DIGEST_LENGTH, 2086 authData))) { 2087 stlogit("Tspi_Data_Bind: 0x%0x - %s", 2088 ret, Trspi_Error_String(ret)); 2089 return (CKR_FUNCTION_FAILED); 2090 } 2091 2092 /* pull the encrypted data out of the encrypted data object */ 2093 if ((ret = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB, 2094 TSS_TSPATTRIB_ENCDATABLOB_BLOB, &blob_size, &blob))) { 2095 stlogit("Tspi_SetAttribData: 0x%0x - %s", 2096 ret, Trspi_Error_String(ret)); 2097 return (CKR_FUNCTION_FAILED); 2098 } 2099 2100 if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size, 2101 &new_attr))) { 2102 return (rc); 2103 } 2104 (void) template_update_attribute(publ_tmpl, new_attr); 2105 2106 if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, 2107 blob_size, &new_attr))) { 2108 return (rc); 2109 } 2110 (void) template_update_attribute(priv_tmpl, new_attr); 2111 2112 return (rc); 2113 } 2114 2115 static CK_RV 2116 token_unwrap_auth_data(TSS_HCONTEXT hContext, CK_BYTE *encAuthData, 2117 CK_ULONG encAuthDataLen, TSS_HKEY hKey, 2118 BYTE **authData) 2119 { 2120 TSS_RESULT result; 2121 TSS_HENCDATA hEncData; 2122 BYTE *buf; 2123 UINT32 buf_size; 2124 2125 if ((result = Tspi_Context_CreateObject(hContext, 2126 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2127 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2128 result, Trspi_Error_String(result)); 2129 return (CKR_FUNCTION_FAILED); 2130 } 2131 2132 if ((result = Tspi_SetAttribData(hEncData, 2133 TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2134 encAuthDataLen, encAuthData))) { 2135 stlogit("Tspi_SetAttribData: 0x%0x - %s", 2136 result, Trspi_Error_String(result)); 2137 return (CKR_FUNCTION_FAILED); 2138 } 2139 2140 /* unbind the data, receiving the plaintext back */ 2141 if ((result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf))) { 2142 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 2143 result, Trspi_Error_String(result)); 2144 return (CKR_FUNCTION_FAILED); 2145 } 2146 2147 if (buf_size != SHA1_DIGEST_LENGTH) { 2148 return (CKR_FUNCTION_FAILED); 2149 } 2150 2151 *authData = buf; 2152 2153 return (CKR_OK); 2154 } 2155 2156 CK_RV 2157 token_specific_rsa_generate_keypair( 2158 TSS_HCONTEXT hContext, 2159 TEMPLATE *publ_tmpl, 2160 TEMPLATE *priv_tmpl) 2161 { 2162 CK_ATTRIBUTE *attr = NULL; 2163 CK_ULONG mod_bits = 0; 2164 CK_BBOOL flag; 2165 CK_RV rc; 2166 2167 TSS_FLAG initFlags = 0; 2168 BYTE authHash[SHA1_DIGEST_LENGTH]; 2169 BYTE *authData = NULL; 2170 TSS_HKEY hKey = NULL_HKEY; 2171 TSS_HKEY hParentKey = NULL_HKEY; 2172 TSS_RESULT result; 2173 UINT32 ulBlobLen; 2174 BYTE *rgbBlob; 2175 2176 /* Make sure the public exponent is usable */ 2177 if ((util_check_public_exponent(publ_tmpl))) { 2178 return (CKR_TEMPLATE_INCONSISTENT); 2179 } 2180 2181 flag = template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr); 2182 if (!flag) { 2183 return (CKR_TEMPLATE_INCOMPLETE); 2184 } 2185 mod_bits = *(CK_ULONG *)attr->pValue; 2186 2187 if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) { 2188 return (CKR_KEY_SIZE_RANGE); 2189 } 2190 2191 /* 2192 * If we're not logged in, hPrivateLeafKey and hPublicLeafKey 2193 * should be NULL. 2194 */ 2195 if ((hPrivateLeafKey == NULL_HKEY) && 2196 (hPublicLeafKey == NULL_HKEY)) { 2197 /* public session, wrap key with the PRK */ 2198 initFlags |= TSS_KEY_TYPE_LEGACY | 2199 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2200 2201 if ((result = token_load_public_root_key(hContext))) { 2202 return (CKR_FUNCTION_FAILED); 2203 } 2204 2205 hParentKey = hPublicRootKey; 2206 } else if (hPrivateLeafKey != NULL_HKEY) { 2207 /* logged in USER session */ 2208 initFlags |= TSS_KEY_TYPE_LEGACY | 2209 TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2210 2211 /* get a random SHA1 hash for the auth data */ 2212 if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) { 2213 return (CKR_FUNCTION_FAILED); 2214 } 2215 2216 authData = authHash; 2217 hParentKey = hPrivateRootKey; 2218 } else { 2219 /* logged in SO session */ 2220 initFlags |= TSS_KEY_TYPE_LEGACY | 2221 TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2222 2223 /* get a random SHA1 hash for the auth data */ 2224 if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) { 2225 return (CKR_FUNCTION_FAILED); 2226 } 2227 2228 authData = authHash; 2229 hParentKey = hPublicRootKey; 2230 } 2231 2232 if ((result = tss_generate_key(hContext, initFlags, authData, 2233 hParentKey, &hKey))) { 2234 return (result); 2235 } 2236 2237 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 2238 TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { 2239 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2240 result, Trspi_Error_String(result)); 2241 return (CKR_FUNCTION_FAILED); 2242 } 2243 2244 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, 2245 ulBlobLen, &attr))) { 2246 Tspi_Context_FreeMemory(hContext, rgbBlob); 2247 return (rc); 2248 } 2249 (void) template_update_attribute(priv_tmpl, attr); 2250 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, 2251 ulBlobLen, &attr))) { 2252 Tspi_Context_FreeMemory(hContext, rgbBlob); 2253 return (rc); 2254 } 2255 (void) template_update_attribute(publ_tmpl, attr); 2256 2257 Tspi_Context_FreeMemory(hContext, rgbBlob); 2258 2259 /* grab the public key to put into the public key object */ 2260 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2261 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &ulBlobLen, &rgbBlob))) { 2262 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2263 result, Trspi_Error_String(result)); 2264 return (result); 2265 } 2266 2267 /* add the public key blob to the object template */ 2268 if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { 2269 Tspi_Context_FreeMemory(hContext, rgbBlob); 2270 return (rc); 2271 } 2272 (void) template_update_attribute(publ_tmpl, attr); 2273 2274 /* add the public key blob to the object template */ 2275 if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { 2276 Tspi_Context_FreeMemory(hContext, rgbBlob); 2277 return (rc); 2278 } 2279 (void) template_update_attribute(priv_tmpl, attr); 2280 Tspi_Context_FreeMemory(hContext, rgbBlob); 2281 2282 /* wrap the authdata and put it into an object */ 2283 if (authData != NULL) { 2284 rc = token_wrap_auth_data(hContext, authData, publ_tmpl, 2285 priv_tmpl); 2286 } 2287 2288 return (rc); 2289 } 2290 2291 static CK_RV 2292 token_rsa_load_key( 2293 TSS_HCONTEXT hContext, 2294 OBJECT *key_obj, 2295 TSS_HKEY *phKey) 2296 { 2297 TSS_RESULT result; 2298 TSS_HPOLICY hPolicy = NULL_HPOLICY; 2299 TSS_HKEY hParentKey; 2300 BYTE *authData = NULL; 2301 CK_ATTRIBUTE *attr; 2302 CK_RV rc; 2303 CK_OBJECT_HANDLE handle; 2304 2305 if (hPrivateLeafKey != NULL_HKEY) { 2306 hParentKey = hPrivateRootKey; 2307 } else { 2308 if ((result = token_load_public_root_key(hContext))) 2309 return (CKR_FUNCTION_FAILED); 2310 2311 hParentKey = hPublicRootKey; 2312 } 2313 2314 if ((rc = template_attribute_find(key_obj->template, 2315 CKA_IBM_OPAQUE, &attr)) == FALSE) { 2316 /* if the key blob wasn't found, then try to wrap the key */ 2317 rc = object_mgr_find_in_map2(hContext, key_obj, &handle); 2318 if (rc != CKR_OK) 2319 return (CKR_FUNCTION_FAILED); 2320 2321 if ((rc = token_load_key(hContext, 2322 handle, hParentKey, NULL, phKey))) { 2323 return (rc); 2324 } 2325 /* try again to get the CKA_IBM_OPAQUE attr */ 2326 if ((rc = template_attribute_find(key_obj->template, 2327 CKA_IBM_OPAQUE, &attr)) == FALSE) { 2328 return (rc); 2329 } 2330 } 2331 2332 if ((result = Tspi_Context_LoadKeyByBlob(hContext, 2333 hParentKey, attr->ulValueLen, 2334 attr->pValue, phKey))) { 2335 stlogit("Tspi_Context_LoadKeyByBlob: 0x%0x - %s", 2336 result, Trspi_Error_String(result)); 2337 return (CKR_FUNCTION_FAILED); 2338 } 2339 2340 /* auth data may be required */ 2341 if (template_attribute_find(key_obj->template, CKA_ENC_AUTHDATA, 2342 &attr) == TRUE && attr) { 2343 if ((hPrivateLeafKey == NULL_HKEY) && 2344 (hPublicLeafKey == NULL_HKEY)) { 2345 return (CKR_FUNCTION_FAILED); 2346 } else if (hPublicLeafKey != NULL_HKEY) { 2347 hParentKey = hPublicLeafKey; 2348 } else { 2349 hParentKey = hPrivateLeafKey; 2350 } 2351 2352 if ((result = token_unwrap_auth_data(hContext, 2353 attr->pValue, 2354 attr->ulValueLen, hParentKey, &authData))) { 2355 return (CKR_FUNCTION_FAILED); 2356 } 2357 2358 if ((result = Tspi_GetPolicyObject(*phKey, 2359 TSS_POLICY_USAGE, &hPolicy))) { 2360 stlogit("Tspi_GetPolicyObject: 0x%0x - %s", 2361 result, Trspi_Error_String(result)); 2362 return (CKR_FUNCTION_FAILED); 2363 } 2364 2365 /* 2366 * If the policy handle returned is the same as the 2367 * context's default policy, then a new policy must 2368 * be created and assigned to the key. Otherwise, just set the 2369 * secret in the policy. 2370 */ 2371 if (hPolicy == hDefaultPolicy) { 2372 if ((result = Tspi_Context_CreateObject(hContext, 2373 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, 2374 &hPolicy))) { 2375 stlogit("Tspi_Context_CreateObject: " 2376 "0x%0x - %s", 2377 result, Trspi_Error_String(result)); 2378 return (CKR_FUNCTION_FAILED); 2379 } 2380 2381 if ((result = Tspi_Policy_SetSecret(hPolicy, 2382 TSS_SECRET_MODE_SHA1, 2383 SHA1_DIGEST_LENGTH, authData))) { 2384 stlogit("Tspi_Policy_SetSecret: " 2385 "0x%0x - %s", 2386 result, Trspi_Error_String(result)); 2387 return (CKR_FUNCTION_FAILED); 2388 } 2389 2390 if ((result = Tspi_Policy_AssignToObject(hPolicy, 2391 *phKey))) { 2392 stlogit("Tspi_Policy_AssignToObject: " 2393 "0x%0x - %s", 2394 result, Trspi_Error_String(result)); 2395 return (CKR_FUNCTION_FAILED); 2396 } 2397 } else if ((result = Tspi_Policy_SetSecret(hPolicy, 2398 TSS_SECRET_MODE_SHA1, SHA1_DIGEST_LENGTH, authData))) { 2399 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 2400 result, Trspi_Error_String(result)); 2401 return (CKR_FUNCTION_FAILED); 2402 } 2403 2404 Tspi_Context_FreeMemory(hContext, authData); 2405 } 2406 2407 return (CKR_OK); 2408 } 2409 2410 CK_RV 2411 tpm_decrypt_data( 2412 TSS_HCONTEXT hContext, 2413 TSS_HKEY hKey, 2414 CK_BYTE * in_data, 2415 CK_ULONG in_data_len, 2416 CK_BYTE * out_data, 2417 CK_ULONG * out_data_len) 2418 { 2419 TSS_RESULT result; 2420 TSS_HENCDATA hEncData = NULL_HENCDATA; 2421 UINT32 buf_size = 0, modLen; 2422 BYTE *buf = NULL, *modulus = NULL; 2423 CK_ULONG chunklen, remain, outlen; 2424 2425 /* push the data into the encrypted data object */ 2426 if ((result = Tspi_Context_CreateObject(hContext, 2427 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2428 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2429 result, Trspi_Error_String(result)); 2430 return (CKR_FUNCTION_FAILED); 2431 } 2432 2433 /* 2434 * Figure out the modulus size so we can break the data 2435 * into smaller chunks if necessary. 2436 */ 2437 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2438 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) { 2439 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2440 result, Trspi_Error_String(result)); 2441 return (result); 2442 } 2443 /* we don't need the actual modulus */ 2444 Tspi_Context_FreeMemory(hContext, modulus); 2445 2446 chunklen = (in_data_len > modLen ? modLen : in_data_len); 2447 remain = in_data_len; 2448 outlen = 0; 2449 2450 while (remain > 0) { 2451 if ((result = Tspi_SetAttribData(hEncData, 2452 TSS_TSPATTRIB_ENCDATA_BLOB, 2453 TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2454 chunklen, in_data))) { 2455 stlogit("Tspi_SetAttribData: 0x%0x - %s", 2456 result, Trspi_Error_String(result)); 2457 return (CKR_FUNCTION_FAILED); 2458 } 2459 2460 /* unbind the data, receiving the plaintext back */ 2461 if ((result = Tspi_Data_Unbind(hEncData, hKey, 2462 &buf_size, &buf))) { 2463 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 2464 result, Trspi_Error_String(result)); 2465 return (CKR_FUNCTION_FAILED); 2466 } 2467 2468 if (*out_data_len < buf_size + outlen) { 2469 Tspi_Context_FreeMemory(hContext, buf); 2470 return (CKR_BUFFER_TOO_SMALL); 2471 } 2472 2473 (void) memcpy(out_data + outlen, buf, buf_size); 2474 2475 outlen += buf_size; 2476 in_data += chunklen; 2477 remain -= chunklen; 2478 2479 Tspi_Context_FreeMemory(hContext, buf); 2480 if (chunklen > remain) 2481 chunklen = remain; 2482 } 2483 *out_data_len = outlen; 2484 return (CKR_OK); 2485 } 2486 2487 CK_RV 2488 token_specific_rsa_decrypt( 2489 TSS_HCONTEXT hContext, 2490 CK_BYTE * in_data, 2491 CK_ULONG in_data_len, 2492 CK_BYTE * out_data, 2493 CK_ULONG * out_data_len, 2494 OBJECT * key_obj) 2495 { 2496 CK_RV rc; 2497 TSS_HKEY hKey; 2498 2499 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2500 return (rc); 2501 } 2502 2503 rc = tpm_decrypt_data(hContext, hKey, in_data, in_data_len, 2504 out_data, out_data_len); 2505 2506 return (rc); 2507 } 2508 2509 CK_RV 2510 token_specific_rsa_verify( 2511 TSS_HCONTEXT hContext, 2512 CK_BYTE * in_data, 2513 CK_ULONG in_data_len, 2514 CK_BYTE * sig, 2515 CK_ULONG sig_len, 2516 OBJECT * key_obj) 2517 { 2518 TSS_RESULT result; 2519 TSS_HHASH hHash; 2520 TSS_HKEY hKey; 2521 CK_RV rc; 2522 2523 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2524 return (rc); 2525 } 2526 2527 /* Create the hash object we'll use to sign */ 2528 if ((result = Tspi_Context_CreateObject(hContext, 2529 TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { 2530 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2531 result, Trspi_Error_String(result)); 2532 return (CKR_FUNCTION_FAILED); 2533 } 2534 2535 /* Insert the data into the hash object */ 2536 if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, 2537 in_data))) { 2538 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s", 2539 result, Trspi_Error_String(result)); 2540 return (CKR_FUNCTION_FAILED); 2541 } 2542 2543 /* Verify */ 2544 result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig); 2545 if (result != TSS_SUCCESS && 2546 TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) { 2547 stlogit("Tspi_Hash_VerifySignature: 0x%0x - %s", 2548 result, Trspi_Error_String(result)); 2549 } 2550 2551 if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) { 2552 rc = CKR_SIGNATURE_INVALID; 2553 } else { 2554 rc = CKR_OK; 2555 } 2556 2557 return (rc); 2558 } 2559 2560 CK_RV 2561 token_specific_rsa_sign( 2562 TSS_HCONTEXT hContext, 2563 CK_BYTE * in_data, 2564 CK_ULONG in_data_len, 2565 CK_BYTE * out_data, 2566 CK_ULONG * out_data_len, 2567 OBJECT * key_obj) 2568 { 2569 TSS_RESULT result; 2570 TSS_HHASH hHash; 2571 BYTE *sig; 2572 UINT32 sig_len; 2573 TSS_HKEY hKey; 2574 CK_RV rc; 2575 2576 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2577 return (rc); 2578 } 2579 2580 /* Create the hash object we'll use to sign */ 2581 if ((result = Tspi_Context_CreateObject(hContext, 2582 TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { 2583 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2584 result, Trspi_Error_String(result)); 2585 return (CKR_FUNCTION_FAILED); 2586 } 2587 2588 /* Insert the data into the hash object */ 2589 if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, 2590 in_data))) { 2591 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s", 2592 result, Trspi_Error_String(result)); 2593 return (CKR_FUNCTION_FAILED); 2594 } 2595 2596 /* Sign */ 2597 if ((result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig))) { 2598 stlogit("Tspi_Hash_Sign: 0x%0x - %s", 2599 result, Trspi_Error_String(result)); 2600 return (CKR_FUNCTION_FAILED); 2601 } 2602 2603 if (sig_len > *out_data_len) { 2604 Tspi_Context_FreeMemory(hContext, sig); 2605 return (CKR_BUFFER_TOO_SMALL); 2606 } 2607 2608 (void) memcpy(out_data, sig, sig_len); 2609 *out_data_len = sig_len; 2610 Tspi_Context_FreeMemory(hContext, sig); 2611 2612 return (CKR_OK); 2613 } 2614 2615 CK_RV 2616 tpm_encrypt_data( 2617 TSS_HCONTEXT hContext, 2618 TSS_HKEY hKey, 2619 CK_BYTE *in_data, 2620 CK_ULONG in_data_len, 2621 CK_BYTE *out_data, 2622 CK_ULONG *out_data_len) 2623 { 2624 TSS_RESULT result; 2625 TSS_HENCDATA hEncData; 2626 BYTE *dataBlob, *modulus; 2627 UINT32 dataBlobSize, modLen; 2628 CK_ULONG chunklen, remain; 2629 CK_ULONG outlen; 2630 2631 if ((result = Tspi_Context_CreateObject(hContext, 2632 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2633 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2634 result, Trspi_Error_String(result)); 2635 return (CKR_FUNCTION_FAILED); 2636 } 2637 /* 2638 * Figure out the modulus size so we can break the data 2639 * into smaller chunks if necessary. 2640 */ 2641 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2642 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) { 2643 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2644 result, Trspi_Error_String(result)); 2645 return (result); 2646 } 2647 /* we don't need the actual modulus */ 2648 Tspi_Context_FreeMemory(hContext, modulus); 2649 2650 /* 2651 * According to TSS spec for Tspi_Data_Bind (4.3.4.21.5), 2652 * Max input data size is: modLen - (40 - 2 - 4 - 1) 2653 * (for RSA OAEP SHA1 operations). 2654 */ 2655 modLen -= 47; 2656 2657 chunklen = (in_data_len > modLen ? modLen : in_data_len); 2658 remain = in_data_len; 2659 outlen = 0; 2660 while (remain > 0) { 2661 if ((result = Tspi_Data_Bind(hEncData, hKey, 2662 chunklen, in_data))) { 2663 stlogit("Tspi_Data_Bind: 0x%0x - %s", 2664 result, Trspi_Error_String(result)); 2665 return (CKR_FUNCTION_FAILED); 2666 } 2667 2668 if ((result = Tspi_GetAttribData(hEncData, 2669 TSS_TSPATTRIB_ENCDATA_BLOB, 2670 TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2671 &dataBlobSize, &dataBlob))) { 2672 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2673 result, Trspi_Error_String(result)); 2674 return (CKR_FUNCTION_FAILED); 2675 } 2676 2677 if (outlen + dataBlobSize > *out_data_len) { 2678 Tspi_Context_FreeMemory(hContext, dataBlob); 2679 return (CKR_DATA_LEN_RANGE); 2680 } 2681 2682 (void) memcpy(out_data + outlen, 2683 dataBlob, dataBlobSize); 2684 2685 outlen += dataBlobSize; 2686 in_data += chunklen; 2687 remain -= chunklen; 2688 2689 if (chunklen > remain) 2690 chunklen = remain; 2691 2692 Tspi_Context_FreeMemory(hContext, dataBlob); 2693 } 2694 *out_data_len = outlen; 2695 2696 return (CKR_OK); 2697 } 2698 2699 CK_RV 2700 token_specific_rsa_encrypt( 2701 TSS_HCONTEXT hContext, 2702 CK_BYTE * in_data, 2703 CK_ULONG in_data_len, 2704 CK_BYTE * out_data, 2705 CK_ULONG * out_data_len, 2706 OBJECT * key_obj) 2707 { 2708 TSS_HKEY hKey; 2709 CK_RV rc; 2710 2711 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2712 return (rc); 2713 } 2714 2715 rc = tpm_encrypt_data(hContext, hKey, in_data, in_data_len, 2716 out_data, out_data_len); 2717 2718 return (rc); 2719 } 2720