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