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