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 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2012 Milan Jurik. All rights reserved. 25 */ 26 27 #include <pthread.h> 28 #include <string.h> 29 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <uuid/uuid.h> 33 #include <fcntl.h> 34 #include <errno.h> 35 #include <pwd.h> 36 #include <syslog.h> 37 38 #include <openssl/rsa.h> 39 40 #include <tss/platform.h> 41 #include <tss/tss_defines.h> 42 #include <tss/tss_typedef.h> 43 #include <tss/tss_structs.h> 44 #include <tss/tss_error.h> 45 #include <tss/tcs_error.h> 46 #include <tss/tspi.h> 47 #include <trousers/trousers.h> 48 49 #include "tpmtok_int.h" 50 #include "tpmtok_defs.h" 51 52 #define MAX_RSA_KEYLENGTH 512 53 54 extern void stlogit(char *fmt, ...); 55 56 CK_RV token_rng(TSS_HCONTEXT, CK_BYTE *, CK_ULONG); 57 int tok_slot2local(CK_SLOT_ID); 58 CK_RV token_specific_session(CK_SLOT_ID); 59 CK_RV token_specific_final(TSS_HCONTEXT); 60 61 CK_RV 62 token_specific_rsa_decrypt( 63 TSS_HCONTEXT, 64 CK_BYTE *, 65 CK_ULONG, 66 CK_BYTE *, 67 CK_ULONG *, 68 OBJECT *); 69 70 CK_RV 71 token_specific_rsa_encrypt( 72 TSS_HCONTEXT, 73 CK_BYTE *, 74 CK_ULONG, 75 CK_BYTE *, 76 CK_ULONG *, 77 OBJECT *); 78 79 CK_RV 80 token_specific_rsa_sign( 81 TSS_HCONTEXT, 82 CK_BYTE *, 83 CK_ULONG, 84 CK_BYTE *, 85 CK_ULONG *, 86 OBJECT *); 87 88 CK_RV 89 token_specific_rsa_verify(TSS_HCONTEXT, CK_BYTE *, 90 CK_ULONG, CK_BYTE *, CK_ULONG, OBJECT *); 91 92 CK_RV 93 token_specific_rsa_generate_keypair(TSS_HCONTEXT, 94 TEMPLATE *, 95 TEMPLATE *); 96 97 CK_RV 98 token_specific_sha_init(DIGEST_CONTEXT *); 99 100 CK_RV 101 token_specific_sha_update(DIGEST_CONTEXT *, 102 CK_BYTE *, 103 CK_ULONG); 104 105 CK_RV 106 token_specific_sha_final(DIGEST_CONTEXT *, 107 CK_BYTE *, 108 CK_ULONG *); 109 110 CK_RV token_specific_login(TSS_HCONTEXT, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG); 111 CK_RV token_specific_logout(TSS_HCONTEXT); 112 CK_RV token_specific_init_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG); 113 CK_RV token_specific_set_pin(ST_SESSION_HANDLE, CK_CHAR_PTR, 114 CK_ULONG, CK_CHAR_PTR, CK_ULONG); 115 CK_RV token_specific_verify_so_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG); 116 117 static CK_RV 118 token_specific_init(char *, CK_SLOT_ID, TSS_HCONTEXT *); 119 120 struct token_specific_struct token_specific = { 121 "TPM_Debug", 122 &token_specific_init, 123 NULL, 124 &token_rng, 125 &token_specific_session, 126 &token_specific_final, 127 &token_specific_rsa_decrypt, 128 &token_specific_rsa_encrypt, 129 &token_specific_rsa_sign, 130 &token_specific_rsa_verify, 131 &token_specific_rsa_generate_keypair, 132 NULL, 133 NULL, 134 NULL, 135 &token_specific_login, 136 &token_specific_logout, 137 &token_specific_init_pin, 138 &token_specific_set_pin, 139 &token_specific_verify_so_pin 140 }; 141 142 /* The context we'll use globally to connect to the TSP */ 143 144 /* TSP key handles */ 145 TSS_HKEY hPublicRootKey = NULL_HKEY; 146 TSS_HKEY hPublicLeafKey = NULL_HKEY; 147 TSS_HKEY hPrivateRootKey = NULL_HKEY; 148 TSS_HKEY hPrivateLeafKey = NULL_HKEY; 149 150 TSS_UUID publicRootKeyUUID; 151 TSS_UUID publicLeafKeyUUID; 152 TSS_UUID privateRootKeyUUID; 153 TSS_UUID privateLeafKeyUUID; 154 155 /* TSP policy handles */ 156 TSS_HPOLICY hDefaultPolicy = NULL_HPOLICY; 157 158 /* PKCS#11 key handles */ 159 int not_initialized = 0; 160 161 CK_BYTE current_user_pin_sha[SHA1_DIGEST_LENGTH]; 162 CK_BYTE current_so_pin_sha[SHA1_DIGEST_LENGTH]; 163 164 static TPM_CAP_VERSION_INFO tpmvinfo; 165 166 static CK_RV 167 verify_user_pin(TSS_HCONTEXT, CK_BYTE *); 168 169 static TSS_RESULT 170 tss_assign_secret_key_policy(TSS_HCONTEXT, TSS_FLAG, TSS_HKEY, CK_CHAR *); 171 172 static TSS_RESULT 173 set_legacy_key_params(TSS_HKEY); 174 175 static void 176 local_uuid_clear(TSS_UUID *uuid) 177 { 178 if (uuid == NULL) 179 return; 180 (void) memset(uuid, 0, sizeof (TSS_UUID)); 181 } 182 183 184 /* convert from TSS_UUID to uuid_t */ 185 static void 186 tss_uuid_convert_from(TSS_UUID *uu, uuid_t ptr) 187 { 188 uint_t tmp; 189 uchar_t *out = ptr; 190 191 tmp = ntohl(uu->ulTimeLow); 192 out[3] = (uchar_t)tmp; 193 tmp >>= 8; 194 out[2] = (uchar_t)tmp; 195 tmp >>= 8; 196 out[1] = (uchar_t)tmp; 197 tmp >>= 8; 198 out[0] = (uchar_t)tmp; 199 200 tmp = ntohs(uu->usTimeMid); 201 out[5] = (uchar_t)tmp; 202 tmp >>= 8; 203 out[4] = (uchar_t)tmp; 204 205 tmp = ntohs(uu->usTimeHigh); 206 out[7] = (uchar_t)tmp; 207 tmp >>= 8; 208 out[6] = (uchar_t)tmp; 209 210 tmp = uu->bClockSeqHigh; 211 out[8] = (uchar_t)tmp; 212 tmp = uu->bClockSeqLow; 213 out[9] = (uchar_t)tmp; 214 215 (void) memcpy(out+10, uu->rgbNode, 6); 216 } 217 218 /* convert from uuid_t to TSS_UUID */ 219 static void 220 tss_uuid_convert_to(TSS_UUID *uuid, uuid_t in) 221 { 222 uchar_t *ptr; 223 uint32_t ltmp; 224 uint16_t stmp; 225 226 ptr = in; 227 228 ltmp = *ptr++; 229 ltmp = (ltmp << 8) | *ptr++; 230 ltmp = (ltmp << 8) | *ptr++; 231 ltmp = (ltmp << 8) | *ptr++; 232 uuid->ulTimeLow = ntohl(ltmp); 233 234 stmp = *ptr++; 235 stmp = (stmp << 8) | *ptr++; 236 uuid->usTimeMid = ntohs(stmp); 237 238 stmp = *ptr++; 239 stmp = (stmp << 8) | *ptr++; 240 uuid->usTimeHigh = ntohs(stmp); 241 242 uuid->bClockSeqHigh = *ptr++; 243 244 uuid->bClockSeqLow = *ptr++; 245 246 (void) memcpy(uuid->rgbNode, ptr, 6); 247 } 248 249 static void 250 local_uuid_copy(TSS_UUID *dst, TSS_UUID *src) 251 { 252 uuid_t udst, usrc; 253 254 tss_uuid_convert_from(dst, udst); 255 tss_uuid_convert_from(src, usrc); 256 257 uuid_copy(udst, usrc); 258 259 tss_uuid_convert_to(dst, udst); 260 } 261 262 static void 263 local_uuid_generate(TSS_UUID *uu) 264 { 265 uuid_t newuuid; 266 267 uuid_generate(newuuid); 268 269 tss_uuid_convert_to(uu, newuuid); 270 } 271 272 static int 273 local_copy_file(char *dst, char *src) 274 { 275 FILE *fdest, *fsrc; 276 char line[BUFSIZ]; 277 278 fdest = fopen(dst, "w"); 279 if (fdest == NULL) 280 return (-1); 281 282 fsrc = fopen(src, "r"); 283 if (fsrc == NULL) { 284 (void) fclose(fdest); 285 return (-1); 286 } 287 288 while (fread(line, sizeof (line), 1, fsrc)) 289 (void) fprintf(fdest, "%s\n", line); 290 (void) fclose(fsrc); 291 (void) fclose(fdest); 292 return (0); 293 } 294 295 static int 296 remove_uuid(char *keyname) 297 { 298 int ret = 0; 299 FILE *fp, *newfp; 300 char fname[MAXPATHLEN]; 301 char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ]; 302 char *tmpfname; 303 char *p = get_tpm_keystore_path(); 304 305 if (p == NULL) 306 return (-1); 307 308 (void) snprintf(fname, sizeof (fname), 309 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 310 311 fp = fopen(fname, "r"); 312 if (fp == NULL) { 313 return (-1); 314 } 315 316 tmpfname = tempnam("/tmp", "tpmtok"); 317 newfp = fopen(tmpfname, "w+"); 318 if (newfp == NULL) { 319 free(tmpfname); 320 (void) fclose(fp); 321 return (-1); 322 } 323 324 while (!feof(fp)) { 325 (void) fgets(line, sizeof (line), fp); 326 if (sscanf(line, "%1024s %1024s", key, idstr) == 2) { 327 if (strcmp(key, keyname)) 328 (void) fprintf(newfp, "%s\n", line); 329 } 330 } 331 332 (void) fclose(fp); 333 (void) fclose(newfp); 334 if (local_copy_file(fname, tmpfname) == 0) 335 (void) unlink(tmpfname); 336 337 free(tmpfname); 338 339 return (ret); 340 } 341 342 static int 343 find_uuid(char *keyname, TSS_UUID *uu) 344 { 345 int ret = 0, found = 0; 346 FILE *fp = NULL; 347 char fname[MAXPATHLEN]; 348 char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ]; 349 uuid_t uuid; 350 char *p = get_tpm_keystore_path(); 351 352 if (p == NULL) 353 return (-1); 354 355 tss_uuid_convert_from(uu, uuid); 356 357 (void) snprintf(fname, sizeof (fname), 358 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 359 360 /* Open UUID Index file */ 361 fp = fopen(fname, "r"); 362 if (fp == NULL) { 363 if (errno == ENOENT) { 364 /* initialize the file */ 365 fp = fopen(fname, "w"); 366 if (fp != NULL) 367 (void) fclose(fp); 368 } 369 return (-1); 370 } 371 372 while (!feof(fp)) { 373 (void) fgets(line, sizeof (line), fp); 374 if (sscanf(line, "%1024s %1024s", key, idstr) == 2) { 375 if (strcmp(key, keyname) == 0) { 376 ret = uuid_parse(idstr, uuid); 377 if (ret == 0) { 378 found = 1; 379 tss_uuid_convert_to(uu, 380 uuid); 381 } 382 break; 383 } 384 } 385 } 386 (void) fclose(fp); 387 388 if (!found) 389 ret = -1; 390 return (ret); 391 } 392 393 static int 394 local_uuid_is_null(TSS_UUID *uu) 395 { 396 uuid_t uuid; 397 int nulluuid; 398 399 tss_uuid_convert_from(uu, uuid); 400 401 nulluuid = uuid_is_null(uuid); 402 return (nulluuid); 403 } 404 405 static int 406 add_uuid(char *keyname, TSS_UUID *uu) 407 { 408 FILE *fp = NULL; 409 char fname[MAXPATHLEN]; 410 char idstr[BUFSIZ]; 411 uuid_t uuid; 412 char *p = get_tpm_keystore_path(); 413 414 if (p == NULL) 415 return (-1); 416 417 tss_uuid_convert_from(uu, uuid); 418 419 if (uuid_is_null(uuid)) 420 return (-1); 421 422 uuid_unparse(uuid, idstr); 423 424 (void) snprintf(fname, sizeof (fname), 425 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME); 426 427 fp = fopen(fname, "a"); 428 if (fp == NULL) 429 return (-1); 430 431 (void) fprintf(fp, "%s %s\n", keyname, idstr); 432 (void) fclose(fp); 433 434 return (0); 435 } 436 437 438 static UINT32 439 util_get_keysize_flag(CK_ULONG size) 440 { 441 switch (size) { 442 case 512: 443 return (TSS_KEY_SIZE_512); 444 case 1024: 445 return (TSS_KEY_SIZE_1024); 446 case 2048: 447 return (TSS_KEY_SIZE_2048); 448 default: 449 break; 450 } 451 452 return (0); 453 } 454 455 /* make sure the public exponent attribute is 65537 */ 456 static CK_ULONG 457 util_check_public_exponent(TEMPLATE *tmpl) 458 { 459 CK_BBOOL flag; 460 CK_ATTRIBUTE *publ_exp_attr; 461 CK_BYTE pubexp_bytes[] = { 1, 0, 1 }; 462 CK_ULONG publ_exp, rc = 1; 463 464 flag = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, 465 &publ_exp_attr); 466 if (!flag) { 467 LogError1("Couldn't find public exponent attribute"); 468 return (CKR_TEMPLATE_INCOMPLETE); 469 } 470 471 switch (publ_exp_attr->ulValueLen) { 472 case 3: 473 rc = memcmp(pubexp_bytes, publ_exp_attr->pValue, 3); 474 break; 475 case sizeof (CK_ULONG): 476 publ_exp = *((CK_ULONG *)publ_exp_attr->pValue); 477 if (publ_exp == 65537) 478 rc = 0; 479 break; 480 default: 481 break; 482 } 483 484 return (rc); 485 } 486 487 TSS_RESULT 488 set_public_modulus(TSS_HCONTEXT hContext, TSS_HKEY hKey, 489 unsigned long size_n, unsigned char *n) 490 { 491 UINT64 offset; 492 UINT32 blob_size; 493 BYTE *blob, pub_blob[1024]; 494 TCPA_PUBKEY pub_key; 495 TSS_RESULT result; 496 497 /* Get the TCPA_PUBKEY blob from the key object. */ 498 result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 499 TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blob_size, &blob); 500 if (result != TSS_SUCCESS) { 501 stlogit("Tspi_GetAttribData failed: rc=0x%0x - %s\n", 502 result, Trspi_Error_String(result)); 503 return (result); 504 } 505 506 offset = 0; 507 result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pub_key); 508 if (result != TSS_SUCCESS) { 509 stlogit("Trspi_UnloadBlob_PUBKEY failed: rc=0x%0x - %s\n", 510 result, Trspi_Error_String(result)); 511 return (result); 512 } 513 514 Tspi_Context_FreeMemory(hContext, blob); 515 /* Free the first dangling reference, putting 'n' in its place */ 516 free(pub_key.pubKey.key); 517 pub_key.pubKey.keyLength = size_n; 518 pub_key.pubKey.key = n; 519 520 offset = 0; 521 Trspi_LoadBlob_PUBKEY(&offset, pub_blob, &pub_key); 522 523 /* Free the second dangling reference */ 524 free(pub_key.algorithmParms.parms); 525 526 /* set the public key data in the TSS object */ 527 result = Tspi_SetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 528 TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, (UINT32)offset, pub_blob); 529 if (result != TSS_SUCCESS) { 530 stlogit("Tspi_SetAttribData failed: rc=0x%0x - %s\n", 531 result, Trspi_Error_String(result)); 532 return (result); 533 } 534 535 return (result); 536 } 537 538 /* 539 * Get details about the TPM to put into the token_info structure. 540 */ 541 CK_RV 542 token_get_tpm_info(TSS_HCONTEXT hContext, TOKEN_DATA *td) 543 { 544 TSS_RESULT result; 545 TPM_CAPABILITY_AREA capArea = TSS_TPMCAP_VERSION_VAL; 546 UINT32 datalen; 547 BYTE *data; 548 TSS_HTPM hTPM; 549 550 if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) { 551 stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s", 552 result, Trspi_Error_String(result)); 553 return (CKR_FUNCTION_FAILED); 554 } 555 if ((result = Tspi_TPM_GetCapability(hTPM, 556 capArea, 0, NULL, &datalen, &data)) != 0 || datalen == 0 || 557 data == NULL) { 558 stlogit("Tspi_Context_GetCapability: 0x%0x - %s", 559 result, Trspi_Error_String(result)); 560 return (CKR_FUNCTION_FAILED); 561 } 562 if (datalen > sizeof (tpmvinfo)) { 563 Tspi_Context_FreeMemory(hContext, data); 564 return (CKR_FUNCTION_FAILED); 565 } 566 567 (void) memcpy(&tpmvinfo, (void *)data, datalen); 568 569 bzero(td->token_info.manufacturerID, 570 sizeof (td->token_info.manufacturerID)); 571 572 (void) memset(td->token_info.manufacturerID, ' ', 573 sizeof (td->token_info.manufacturerID) - 1); 574 575 (void) memcpy(td->token_info.manufacturerID, 576 tpmvinfo.tpmVendorID, sizeof (tpmvinfo.tpmVendorID)); 577 578 (void) memset(td->token_info.label, ' ', 579 sizeof (td->token_info.label) - 1); 580 581 (void) memcpy(td->token_info.label, "TPM", 3); 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 Tspi_Context_Close(*pContext); 639 *pContext = 0; 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 } 1277 1278 if (result = tss_generate_key(hContext, initFlags, passHash, 1279 hParentKey, phKey)) { 1280 return (rc); 1281 } 1282 1283 /* 1284 * - generate newUUID 1285 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1286 * USER, newUUID, USER, parentUUID); 1287 * - store newUUID 1288 */ 1289 (void) local_uuid_generate(&newuuid); 1290 1291 result = Tspi_Context_RegisterKey(hContext, *phKey, 1292 TSS_PS_TYPE_USER, newuuid, 1293 TSS_PS_TYPE_USER, parentUUID); 1294 if (result == TSS_SUCCESS) { 1295 int ret; 1296 /* 1297 * Add the UUID to the token UUID index. 1298 */ 1299 ret = add_uuid(keyid, &newuuid); 1300 1301 if (ret) 1302 result = Tspi_Context_UnregisterKey(hContext, 1303 TSS_PS_TYPE_USER, newuuid, phKey); 1304 else 1305 rc = CKR_OK; 1306 } 1307 1308 done: 1309 return (rc); 1310 } 1311 1312 /* 1313 * PINs are verified by attempting to bind/unbind random data using a 1314 * TPM resident key that has the PIN being tested assigned as its "secret". 1315 * If the PIN is incorrect, the unbind operation will fail. 1316 */ 1317 static CK_RV 1318 token_verify_pin(TSS_HCONTEXT hContext, TSS_HKEY hKey) 1319 { 1320 TSS_HENCDATA hEncData; 1321 UINT32 ulUnboundDataLen; 1322 BYTE *rgbUnboundData = NULL; 1323 BYTE rgbData[16]; 1324 TSS_RESULT result; 1325 CK_RV rc = CKR_FUNCTION_FAILED; 1326 1327 if ((result = Tspi_Context_CreateObject(hContext, 1328 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 1329 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 1330 result, Trspi_Error_String(result)); 1331 goto done; 1332 } 1333 1334 /* Use some random data */ 1335 rc = token_rng(hContext, rgbData, sizeof (rgbData)); 1336 if (rc) 1337 goto done; 1338 1339 if ((result = Tspi_Data_Bind(hEncData, hKey, 1340 sizeof (rgbData), rgbData))) { 1341 stlogit("Tspi_Data_Bind: 0x%0x - %s", 1342 result, Trspi_Error_String(result)); 1343 goto done; 1344 } 1345 1346 /* unbind the junk data to test the key's auth data */ 1347 result = Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen, 1348 &rgbUnboundData); 1349 if (result == TPM_E_AUTHFAIL) { 1350 rc = CKR_PIN_INCORRECT; 1351 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 1352 result, Trspi_Error_String(result)); 1353 goto done; 1354 } else if (result != TSS_SUCCESS) { 1355 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 1356 result, Trspi_Error_String(result)); 1357 rc = CKR_FUNCTION_FAILED; 1358 goto done; 1359 } 1360 1361 if (memcmp(rgbUnboundData, rgbData, ulUnboundDataLen)) 1362 rc = CKR_PIN_INCORRECT; 1363 else 1364 rc = CKR_OK; 1365 1366 done: 1367 if (rgbUnboundData != NULL) 1368 Tspi_Context_FreeMemory(hContext, rgbUnboundData); 1369 Tspi_Context_CloseObject(hContext, hEncData); 1370 return (rc); 1371 } 1372 1373 static CK_RV 1374 token_create_private_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash) 1375 { 1376 CK_RV rc; 1377 TSS_RESULT result; 1378 int ret; 1379 TSS_FLAG initFlags = TSS_KEY_SIZE_2048 | 1380 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE; 1381 TSS_UUID SRK_UUID = TSS_UUID_SRK; 1382 TSS_HKEY hSRK; 1383 1384 if (token_load_srk(hContext, &hSRK)) 1385 return (CKR_FUNCTION_FAILED); 1386 1387 /* 1388 * - create UUID privateRootKeyUUID 1389 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1390 * USER, privateRootKeyUUID, system, UUID_SRK); 1391 * - store privateRootKeyUUID in users private token space. 1392 */ 1393 if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK, 1394 &hPrivateRootKey))) { 1395 return (result); 1396 } 1397 if (local_uuid_is_null(&privateRootKeyUUID)) 1398 local_uuid_generate(&privateRootKeyUUID); 1399 1400 result = Tspi_Context_RegisterKey(hContext, hPrivateRootKey, 1401 TSS_PS_TYPE_USER, privateRootKeyUUID, 1402 TSS_PS_TYPE_SYSTEM, SRK_UUID); 1403 1404 if (result) { 1405 local_uuid_clear(&privateRootKeyUUID); 1406 return (result); 1407 } 1408 1409 ret = add_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, &privateRootKeyUUID); 1410 if (ret) { 1411 result = Tspi_Context_UnregisterKey(hContext, 1412 TSS_PS_TYPE_USER, privateRootKeyUUID, 1413 &hPrivateRootKey); 1414 return (CKR_FUNCTION_FAILED); 1415 } 1416 1417 if ((result = Tspi_Key_LoadKey(hPrivateRootKey, hSRK))) { 1418 stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1419 result, Trspi_Error_String(result)); 1420 Tspi_Context_CloseObject(hContext, hPrivateRootKey); 1421 1422 (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID); 1423 local_uuid_clear(&privateRootKeyUUID); 1424 1425 hPrivateRootKey = NULL_HKEY; 1426 return (CKR_FUNCTION_FAILED); 1427 } 1428 1429 1430 /* generate the private leaf key */ 1431 if ((rc = token_generate_leaf_key(hContext, 1432 TPMTOK_PRIVATE_LEAF_KEY, 1433 pinHash, &hPrivateLeafKey))) { 1434 return (rc); 1435 } 1436 1437 if ((result = Tspi_Key_LoadKey(hPrivateLeafKey, hPrivateRootKey))) { 1438 stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1439 result, Trspi_Error_String(result)); 1440 1441 (void) Tspi_Context_UnregisterKey(hContext, 1442 TSS_PS_TYPE_USER, privateLeafKeyUUID, 1443 &hPrivateLeafKey); 1444 (void) remove_uuid(TPMTOK_PRIVATE_LEAF_KEY_ID); 1445 local_uuid_clear(&privateLeafKeyUUID); 1446 1447 (void) Tspi_Context_UnregisterKey(hContext, 1448 TSS_PS_TYPE_USER, privateRootKeyUUID, 1449 &hPrivateRootKey); 1450 (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID); 1451 local_uuid_clear(&privateRootKeyUUID); 1452 1453 Tspi_Context_CloseObject(hContext, hPrivateRootKey); 1454 hPrivateRootKey = NULL_HKEY; 1455 1456 Tspi_Context_CloseObject(hContext, hPrivateLeafKey); 1457 hPrivateRootKey = NULL_HKEY; 1458 1459 return (CKR_FUNCTION_FAILED); 1460 } 1461 return (rc); 1462 } 1463 1464 static CK_RV 1465 token_create_public_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash) 1466 { 1467 CK_RV rc; 1468 TSS_RESULT result; 1469 int ret; 1470 TSS_FLAG initFlags = TSS_KEY_SIZE_2048 | 1471 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE; 1472 TSS_UUID srk_uuid = TSS_UUID_SRK; 1473 TSS_HKEY hSRK; 1474 1475 if (token_load_srk(hContext, &hSRK)) 1476 return (CKR_FUNCTION_FAILED); 1477 1478 /* 1479 * - create publicRootKeyUUID 1480 * - Tspi_Context_RegisterKey(hContext, hPublicRootKey, 1481 * USER, publicRootKeyUUID, system, UUID_SRK); 1482 * - store publicRootKeyUUID in users private token space. 1483 */ 1484 if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK, 1485 &hPublicRootKey))) { 1486 return (CKR_FUNCTION_FAILED); 1487 } 1488 if (local_uuid_is_null(&publicRootKeyUUID)) 1489 local_uuid_generate(&publicRootKeyUUID); 1490 1491 result = Tspi_Context_RegisterKey(hContext, hPublicRootKey, 1492 TSS_PS_TYPE_USER, publicRootKeyUUID, 1493 TSS_PS_TYPE_SYSTEM, srk_uuid); 1494 1495 if (result) { 1496 local_uuid_clear(&publicRootKeyUUID); 1497 return (CKR_FUNCTION_FAILED); 1498 } 1499 1500 ret = add_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID); 1501 if (ret) { 1502 result = Tspi_Context_UnregisterKey(hContext, 1503 TSS_PS_TYPE_USER, publicRootKeyUUID, 1504 &hPublicRootKey); 1505 /* does result matter here? */ 1506 return (CKR_FUNCTION_FAILED); 1507 } 1508 1509 /* Load the newly created publicRootKey into the TPM using the SRK */ 1510 if ((result = Tspi_Key_LoadKey(hPublicRootKey, hSRK))) { 1511 stlogit("Tspi_Key_LoadKey: 0x%x - %s", result, 1512 Trspi_Error_String(result)); 1513 Tspi_Context_CloseObject(hContext, hPublicRootKey); 1514 hPublicRootKey = NULL_HKEY; 1515 return (CKR_FUNCTION_FAILED); 1516 } 1517 1518 /* create the SO's leaf key */ 1519 if ((rc = token_generate_leaf_key(hContext, TPMTOK_PUBLIC_LEAF_KEY, 1520 pinHash, &hPublicLeafKey))) { 1521 return (rc); 1522 } 1523 1524 if ((result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey))) { 1525 stlogit("Tspi_Key_LoadKey: 0x%0x - %s", 1526 result, Trspi_Error_String(result)); 1527 1528 /* Unregister keys and clear UUIDs */ 1529 (void) Tspi_Context_UnregisterKey(hContext, 1530 TSS_PS_TYPE_USER, publicLeafKeyUUID, 1531 &hPublicLeafKey); 1532 (void) remove_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID); 1533 1534 (void) Tspi_Context_UnregisterKey(hContext, 1535 TSS_PS_TYPE_USER, publicRootKeyUUID, 1536 &hPublicRootKey); 1537 (void) remove_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID); 1538 1539 Tspi_Context_CloseObject(hContext, hPublicRootKey); 1540 hPublicRootKey = NULL_HKEY; 1541 1542 Tspi_Context_CloseObject(hContext, hPublicLeafKey); 1543 hPublicLeafKey = NULL_HKEY; 1544 1545 return (CKR_FUNCTION_FAILED); 1546 } 1547 1548 return (rc); 1549 } 1550 1551 CK_RV 1552 token_specific_login( 1553 TSS_HCONTEXT hContext, 1554 CK_USER_TYPE userType, 1555 CK_CHAR_PTR pPin, 1556 CK_ULONG ulPinLen) 1557 { 1558 CK_RV rc; 1559 CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; 1560 TSS_RESULT result; 1561 TSS_HKEY hSRK; 1562 1563 /* Make sure the SRK is loaded into the TPM */ 1564 if ((result = token_load_srk(hContext, &hSRK))) { 1565 return (CKR_FUNCTION_FAILED); 1566 } 1567 1568 if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { 1569 return (CKR_FUNCTION_FAILED); 1570 } 1571 1572 if (userType == CKU_USER) { 1573 /* 1574 * If the public root key doesn't exist yet, 1575 * the SO hasn't init'd the token. 1576 */ 1577 if ((result = token_load_public_root_key(hContext))) { 1578 if (result == TPM_E_DECRYPT_ERROR) { 1579 return (CKR_USER_PIN_NOT_INITIALIZED); 1580 } 1581 } 1582 1583 /* 1584 * - find privateRootKeyUUID 1585 * - load by UUID (SRK parent) 1586 */ 1587 if (local_uuid_is_null(&privateRootKeyUUID) && 1588 find_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, 1589 &privateRootKeyUUID)) { 1590 if (memcmp(hash_sha, 1591 default_user_pin_sha, 1592 SHA1_DIGEST_LENGTH)) 1593 return (CKR_PIN_INCORRECT); 1594 1595 not_initialized = 1; 1596 return (CKR_OK); 1597 } 1598 1599 if ((rc = verify_user_pin(hContext, hash_sha))) { 1600 return (rc); 1601 } 1602 1603 (void) memcpy(current_user_pin_sha, hash_sha, 1604 SHA1_DIGEST_LENGTH); 1605 1606 rc = load_private_token_objects(hContext); 1607 if (rc == CKR_OK) { 1608 (void) XProcLock(xproclock); 1609 global_shm->priv_loaded = TRUE; 1610 (void) XProcUnLock(xproclock); 1611 } 1612 } else { 1613 /* 1614 * SO login logic: 1615 * 1616 * - find publicRootKey UUID 1617 * - load by UUID wrap with hSRK from above 1618 */ 1619 if (local_uuid_is_null(&publicRootKeyUUID) && 1620 find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, 1621 &publicRootKeyUUID)) { 1622 if (memcmp(hash_sha, 1623 default_so_pin_sha, 1624 SHA1_DIGEST_LENGTH)) 1625 return (CKR_PIN_INCORRECT); 1626 1627 not_initialized = 1; 1628 return (CKR_OK); 1629 1630 } 1631 if (hPublicRootKey == NULL_HKEY) { 1632 result = tss_find_and_load_key( 1633 hContext, 1634 TPMTOK_PUBLIC_ROOT_KEY_ID, 1635 &publicRootKeyUUID, hSRK, NULL, 1636 &hPublicRootKey); 1637 1638 if (result) 1639 return (CKR_FUNCTION_FAILED); 1640 } 1641 1642 /* find, load the public leaf key */ 1643 if (hPublicLeafKey == NULL_HKEY) { 1644 result = tss_find_and_load_key( 1645 hContext, 1646 TPMTOK_PUBLIC_LEAF_KEY_ID, 1647 &publicLeafKeyUUID, hPublicRootKey, hash_sha, 1648 &hPublicLeafKey); 1649 if (result) 1650 return (CKR_FUNCTION_FAILED); 1651 } 1652 1653 if ((rc = token_verify_pin(hContext, hPublicLeafKey))) { 1654 return (rc); 1655 } 1656 1657 (void) memcpy(current_so_pin_sha, hash_sha, SHA1_DIGEST_LENGTH); 1658 } 1659 1660 return (rc); 1661 } 1662 1663 CK_RV 1664 token_specific_logout(TSS_HCONTEXT hContext) 1665 { 1666 if (hPrivateLeafKey != NULL_HKEY) { 1667 Tspi_Key_UnloadKey(hPrivateLeafKey); 1668 hPrivateLeafKey = NULL_HKEY; 1669 } else if (hPublicLeafKey != NULL_HKEY) { 1670 Tspi_Key_UnloadKey(hPublicLeafKey); 1671 hPublicLeafKey = NULL_HKEY; 1672 } 1673 1674 local_uuid_clear(&publicRootKeyUUID); 1675 local_uuid_clear(&publicLeafKeyUUID); 1676 local_uuid_clear(&privateRootKeyUUID); 1677 local_uuid_clear(&privateLeafKeyUUID); 1678 1679 (void) memset(current_so_pin_sha, 0, SHA1_DIGEST_LENGTH); 1680 (void) memset(current_user_pin_sha, 0, SHA1_DIGEST_LENGTH); 1681 1682 (void) object_mgr_purge_private_token_objects(hContext); 1683 1684 return (CKR_OK); 1685 } 1686 1687 /*ARGSUSED*/ 1688 CK_RV 1689 token_specific_init_pin(TSS_HCONTEXT hContext, 1690 CK_CHAR_PTR pPin, CK_ULONG ulPinLen) 1691 { 1692 /* 1693 * Since the SO must log in before calling C_InitPIN, we will 1694 * be able to return (CKR_OK) automatically here. 1695 * This is because the USER key structure is created at the 1696 * time of her first login, not at C_InitPIN time. 1697 */ 1698 return (CKR_OK); 1699 } 1700 1701 static CK_RV 1702 check_pin_properties(CK_USER_TYPE userType, CK_BYTE *pinHash, 1703 CK_ULONG ulPinLen) 1704 { 1705 /* make sure the new PIN is different */ 1706 if (userType == CKU_USER) { 1707 if (!memcmp(pinHash, default_user_pin_sha, 1708 SHA1_DIGEST_LENGTH)) { 1709 LogError1("new PIN must not be the default"); 1710 return (CKR_PIN_INVALID); 1711 } 1712 } else { 1713 if (!memcmp(pinHash, default_so_pin_sha, 1714 SHA1_DIGEST_LENGTH)) { 1715 LogError1("new PIN must not be the default"); 1716 return (CKR_PIN_INVALID); 1717 } 1718 } 1719 1720 if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) { 1721 LogError1("New PIN is out of size range"); 1722 return (CKR_PIN_LEN_RANGE); 1723 } 1724 1725 return (CKR_OK); 1726 } 1727 1728 /* 1729 * This function is called from set_pin only, where a non-logged-in public 1730 * session can provide the user pin which must be verified. This function 1731 * assumes that the pin has already been set once, so there's no migration 1732 * path option or checking of the default user pin. 1733 */ 1734 static CK_RV 1735 verify_user_pin(TSS_HCONTEXT hContext, CK_BYTE *hash_sha) 1736 { 1737 CK_RV rc; 1738 TSS_RESULT result; 1739 TSS_HKEY hSRK; 1740 1741 if (token_load_srk(hContext, &hSRK)) 1742 return (CKR_FUNCTION_FAILED); 1743 1744 /* 1745 * Verify the user by loading the privateLeafKey 1746 * into the TPM (if it's not already) and then 1747 * call the verify_pin operation. 1748 * 1749 * The hashed PIN is assigned to the private leaf key. 1750 * If it is incorrect (not the same as the one originally 1751 * used when the key was created), the verify operation 1752 * will fail. 1753 */ 1754 if (hPrivateRootKey == NULL_HKEY) { 1755 result = tss_find_and_load_key( 1756 hContext, 1757 TPMTOK_PRIVATE_ROOT_KEY_ID, 1758 &privateRootKeyUUID, hSRK, NULL, &hPrivateRootKey); 1759 if (result) 1760 return (CKR_FUNCTION_FAILED); 1761 } 1762 1763 if (hPrivateLeafKey == NULL_HKEY) { 1764 result = tss_find_and_load_key( 1765 hContext, 1766 TPMTOK_PRIVATE_LEAF_KEY_ID, 1767 &privateLeafKeyUUID, hPrivateRootKey, hash_sha, 1768 &hPrivateLeafKey); 1769 1770 if (result) 1771 return (CKR_FUNCTION_FAILED); 1772 } 1773 1774 /* 1775 * Verify that the PIN is correct by attempting to wrap/unwrap some 1776 * random data. 1777 */ 1778 if ((rc = token_verify_pin(hContext, hPrivateLeafKey))) { 1779 return (rc); 1780 } 1781 1782 return (CKR_OK); 1783 } 1784 1785 CK_RV 1786 token_specific_set_pin(ST_SESSION_HANDLE session, 1787 CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen, 1788 CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen) 1789 { 1790 SESSION *sess = session_mgr_find(session.sessionh); 1791 CK_BYTE oldpin_hash[SHA1_DIGEST_LENGTH]; 1792 CK_BYTE newpin_hash[SHA1_DIGEST_LENGTH]; 1793 CK_RV rc; 1794 TSS_HKEY hSRK; 1795 1796 if (!sess) { 1797 return (CKR_SESSION_HANDLE_INVALID); 1798 } 1799 1800 if ((rc = compute_sha(pOldPin, ulOldPinLen, oldpin_hash))) { 1801 return (CKR_FUNCTION_FAILED); 1802 } 1803 if ((rc = compute_sha(pNewPin, ulNewPinLen, newpin_hash))) { 1804 return (CKR_FUNCTION_FAILED); 1805 } 1806 1807 if (token_load_srk(sess->hContext, &hSRK)) { 1808 return (CKR_FUNCTION_FAILED); 1809 } 1810 1811 /* 1812 * From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of 1813 * the user that is currently logged in, or the CKU_USER PIN 1814 * if the session is not logged in." 1815 * A non R/W session fails with CKR_SESSION_READ_ONLY. 1816 */ 1817 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS || 1818 sess->session_info.state == CKS_RW_PUBLIC_SESSION) { 1819 if (not_initialized) { 1820 if (memcmp(oldpin_hash, default_user_pin_sha, 1821 SHA1_DIGEST_LENGTH)) { 1822 return (CKR_PIN_INCORRECT); 1823 } 1824 1825 if ((rc = check_pin_properties(CKU_USER, newpin_hash, 1826 ulNewPinLen))) { 1827 return (rc); 1828 } 1829 1830 if ((rc = token_create_private_tree(sess->hContext, 1831 newpin_hash))) { 1832 return (CKR_FUNCTION_FAILED); 1833 } 1834 1835 nv_token_data->token_info.flags &= 1836 ~(CKF_USER_PIN_TO_BE_CHANGED); 1837 nv_token_data->token_info.flags |= 1838 CKF_USER_PIN_INITIALIZED; 1839 1840 nv_token_data->token_info.flags &= 1841 ~(CKF_USER_PIN_TO_BE_CHANGED); 1842 nv_token_data->token_info.flags |= 1843 CKF_USER_PIN_INITIALIZED; 1844 1845 return (save_token_data(nv_token_data)); 1846 } 1847 1848 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) { 1849 /* if we're already logged in, just verify the hash */ 1850 if (memcmp(current_user_pin_sha, oldpin_hash, 1851 SHA1_DIGEST_LENGTH)) { 1852 return (CKR_PIN_INCORRECT); 1853 } 1854 } else { 1855 if ((rc = verify_user_pin(sess->hContext, 1856 oldpin_hash))) { 1857 return (rc); 1858 } 1859 } 1860 1861 if ((rc = check_pin_properties(CKU_USER, newpin_hash, 1862 ulNewPinLen))) 1863 return (rc); 1864 1865 /* change the auth on the TSS object */ 1866 if (tss_change_auth(sess->hContext, 1867 hPrivateLeafKey, hPrivateRootKey, 1868 privateLeafKeyUUID, privateRootKeyUUID, 1869 newpin_hash)) 1870 return (CKR_FUNCTION_FAILED); 1871 1872 } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { 1873 if (not_initialized) { 1874 if (memcmp(default_so_pin_sha, oldpin_hash, 1875 SHA1_DIGEST_LENGTH)) 1876 return (CKR_PIN_INCORRECT); 1877 1878 if ((rc = check_pin_properties(CKU_SO, 1879 newpin_hash, ulNewPinLen))) 1880 return (rc); 1881 1882 if ((rc = token_create_public_tree(sess->hContext, 1883 newpin_hash))) 1884 return (CKR_FUNCTION_FAILED); 1885 1886 nv_token_data->token_info.flags &= 1887 ~(CKF_SO_PIN_TO_BE_CHANGED); 1888 1889 return (save_token_data(nv_token_data)); 1890 } 1891 1892 if (memcmp(current_so_pin_sha, oldpin_hash, 1893 SHA1_DIGEST_LENGTH)) 1894 return (CKR_PIN_INCORRECT); 1895 1896 if ((rc = check_pin_properties(CKU_SO, newpin_hash, 1897 ulNewPinLen))) 1898 return (rc); 1899 1900 /* change auth on the SO's leaf key */ 1901 if (tss_change_auth(sess->hContext, 1902 hPublicLeafKey, hPublicRootKey, 1903 publicLeafKeyUUID, publicRootKeyUUID, 1904 newpin_hash)) 1905 return (CKR_FUNCTION_FAILED); 1906 1907 } else { 1908 rc = CKR_SESSION_READ_ONLY; 1909 } 1910 1911 return (rc); 1912 } 1913 1914 /* only called at token init time */ 1915 CK_RV 1916 token_specific_verify_so_pin(TSS_HCONTEXT hContext, CK_CHAR_PTR pPin, 1917 CK_ULONG ulPinLen) 1918 { 1919 CK_BYTE hash_sha[SHA1_DIGEST_LENGTH]; 1920 CK_RV rc; 1921 TSS_RESULT result; 1922 TSS_HKEY hSRK; 1923 1924 if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { 1925 return (CKR_FUNCTION_FAILED); 1926 } 1927 if ((rc = token_load_srk(hContext, &hSRK))) { 1928 return (CKR_FUNCTION_FAILED); 1929 } 1930 1931 /* 1932 * TRYME INSTEAD: 1933 * - find publicRootKeyUUID 1934 * - Load publicRootKey by UUID (SRK parent) 1935 * - find publicLeafKeyUUID 1936 * - Load publicLeafKey by UUID (publicRootKey parent) 1937 * - set password policy on publicLeafKey 1938 */ 1939 if (local_uuid_is_null(&publicRootKeyUUID) && 1940 find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID)) { 1941 /* 1942 * The SO hasn't set her PIN yet, compare the 1943 * login pin with the hard-coded value. 1944 */ 1945 if (memcmp(default_so_pin_sha, hash_sha, 1946 SHA1_DIGEST_LENGTH)) { 1947 return (CKR_PIN_INCORRECT); 1948 } 1949 return (CKR_OK); 1950 } 1951 1952 result = Tspi_Context_GetKeyByUUID(hContext, 1953 TSS_PS_TYPE_USER, publicRootKeyUUID, &hPublicRootKey); 1954 1955 if (result) 1956 return (CKR_FUNCTION_FAILED); 1957 1958 result = Tspi_Key_LoadKey(hPublicRootKey, hSRK); 1959 if (result) 1960 return (CKR_FUNCTION_FAILED); 1961 1962 if (local_uuid_is_null(&publicLeafKeyUUID) && 1963 find_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID, &publicLeafKeyUUID)) 1964 return (CKR_FUNCTION_FAILED); 1965 1966 result = Tspi_Context_GetKeyByUUID(hContext, 1967 TSS_PS_TYPE_USER, publicLeafKeyUUID, &hPublicLeafKey); 1968 if (result) 1969 return (CKR_FUNCTION_FAILED); 1970 1971 result = tss_assign_secret_key_policy(hContext, TSS_POLICY_USAGE, 1972 hPublicLeafKey, hash_sha); 1973 if (result) 1974 return (CKR_FUNCTION_FAILED); 1975 1976 result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey); 1977 if (result) 1978 return (CKR_FUNCTION_FAILED); 1979 1980 /* If the hash given is wrong, the verify will fail */ 1981 if ((rc = token_verify_pin(hContext, hPublicLeafKey))) { 1982 return (rc); 1983 } 1984 1985 return (CKR_OK); 1986 } 1987 1988 CK_RV 1989 token_specific_final(TSS_HCONTEXT hContext) 1990 { 1991 if (hPublicRootKey != NULL_HKEY) { 1992 Tspi_Context_CloseObject(hContext, hPublicRootKey); 1993 hPublicRootKey = NULL_HKEY; 1994 } 1995 if (hPublicLeafKey != NULL_HKEY) { 1996 Tspi_Context_CloseObject(hContext, hPublicLeafKey); 1997 hPublicLeafKey = NULL_HKEY; 1998 } 1999 if (hPrivateRootKey != NULL_HKEY) { 2000 Tspi_Context_CloseObject(hContext, hPrivateRootKey); 2001 hPrivateRootKey = NULL_HKEY; 2002 } 2003 if (hPrivateLeafKey != NULL_HKEY) { 2004 Tspi_Context_CloseObject(hContext, hPrivateLeafKey); 2005 hPrivateLeafKey = NULL_HKEY; 2006 } 2007 return (CKR_OK); 2008 } 2009 2010 /* 2011 * Wrap the 20 bytes of auth data and store in an attribute of the two 2012 * keys. 2013 */ 2014 static CK_RV 2015 token_wrap_auth_data(TSS_HCONTEXT hContext, 2016 CK_BYTE *authData, TEMPLATE *publ_tmpl, 2017 TEMPLATE *priv_tmpl) 2018 { 2019 CK_RV rc; 2020 CK_ATTRIBUTE *new_attr; 2021 2022 TSS_RESULT ret; 2023 TSS_HKEY hParentKey; 2024 TSS_HENCDATA hEncData; 2025 BYTE *blob; 2026 UINT32 blob_size; 2027 2028 if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) { 2029 return (CKR_FUNCTION_FAILED); 2030 } else if (hPublicLeafKey != NULL_HKEY) { 2031 hParentKey = hPublicLeafKey; 2032 } else { 2033 hParentKey = hPrivateLeafKey; 2034 } 2035 2036 /* create the encrypted data object */ 2037 if ((ret = Tspi_Context_CreateObject(hContext, 2038 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2039 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2040 ret, Trspi_Error_String(ret)); 2041 return (CKR_FUNCTION_FAILED); 2042 } 2043 2044 if ((ret = Tspi_Data_Bind(hEncData, hParentKey, SHA1_DIGEST_LENGTH, 2045 authData))) { 2046 stlogit("Tspi_Data_Bind: 0x%0x - %s", 2047 ret, Trspi_Error_String(ret)); 2048 return (CKR_FUNCTION_FAILED); 2049 } 2050 2051 /* pull the encrypted data out of the encrypted data object */ 2052 if ((ret = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB, 2053 TSS_TSPATTRIB_ENCDATABLOB_BLOB, &blob_size, &blob))) { 2054 stlogit("Tspi_SetAttribData: 0x%0x - %s", 2055 ret, Trspi_Error_String(ret)); 2056 return (CKR_FUNCTION_FAILED); 2057 } 2058 2059 if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size, 2060 &new_attr))) { 2061 return (rc); 2062 } 2063 (void) template_update_attribute(publ_tmpl, new_attr); 2064 2065 if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, 2066 blob_size, &new_attr))) { 2067 return (rc); 2068 } 2069 (void) template_update_attribute(priv_tmpl, new_attr); 2070 2071 return (rc); 2072 } 2073 2074 static CK_RV 2075 token_unwrap_auth_data(TSS_HCONTEXT hContext, CK_BYTE *encAuthData, 2076 CK_ULONG encAuthDataLen, TSS_HKEY hKey, 2077 BYTE **authData) 2078 { 2079 TSS_RESULT result; 2080 TSS_HENCDATA hEncData; 2081 BYTE *buf; 2082 UINT32 buf_size; 2083 2084 if ((result = Tspi_Context_CreateObject(hContext, 2085 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2086 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2087 result, Trspi_Error_String(result)); 2088 return (CKR_FUNCTION_FAILED); 2089 } 2090 2091 if ((result = Tspi_SetAttribData(hEncData, 2092 TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2093 encAuthDataLen, encAuthData))) { 2094 stlogit("Tspi_SetAttribData: 0x%0x - %s", 2095 result, Trspi_Error_String(result)); 2096 return (CKR_FUNCTION_FAILED); 2097 } 2098 2099 /* unbind the data, receiving the plaintext back */ 2100 if ((result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf))) { 2101 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 2102 result, Trspi_Error_String(result)); 2103 return (CKR_FUNCTION_FAILED); 2104 } 2105 2106 if (buf_size != SHA1_DIGEST_LENGTH) { 2107 return (CKR_FUNCTION_FAILED); 2108 } 2109 2110 *authData = buf; 2111 2112 return (CKR_OK); 2113 } 2114 2115 CK_RV 2116 token_specific_rsa_generate_keypair( 2117 TSS_HCONTEXT hContext, 2118 TEMPLATE *publ_tmpl, 2119 TEMPLATE *priv_tmpl) 2120 { 2121 CK_ATTRIBUTE *attr = NULL; 2122 CK_ULONG mod_bits = 0; 2123 CK_BBOOL flag; 2124 CK_RV rc; 2125 2126 TSS_FLAG initFlags = 0; 2127 BYTE authHash[SHA1_DIGEST_LENGTH]; 2128 BYTE *authData = NULL; 2129 TSS_HKEY hKey = NULL_HKEY; 2130 TSS_HKEY hParentKey = NULL_HKEY; 2131 TSS_RESULT result; 2132 UINT32 ulBlobLen; 2133 BYTE *rgbBlob; 2134 2135 /* Make sure the public exponent is usable */ 2136 if ((util_check_public_exponent(publ_tmpl))) { 2137 return (CKR_TEMPLATE_INCONSISTENT); 2138 } 2139 2140 flag = template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr); 2141 if (!flag) { 2142 return (CKR_TEMPLATE_INCOMPLETE); 2143 } 2144 mod_bits = *(CK_ULONG *)attr->pValue; 2145 2146 if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) { 2147 return (CKR_KEY_SIZE_RANGE); 2148 } 2149 2150 /* 2151 * If we're not logged in, hPrivateLeafKey and hPublicLeafKey 2152 * should be NULL. 2153 */ 2154 if ((hPrivateLeafKey == NULL_HKEY) && 2155 (hPublicLeafKey == NULL_HKEY)) { 2156 /* public session, wrap key with the PRK */ 2157 initFlags |= TSS_KEY_TYPE_LEGACY | 2158 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2159 2160 if ((result = token_load_public_root_key(hContext))) { 2161 return (CKR_FUNCTION_FAILED); 2162 } 2163 2164 hParentKey = hPublicRootKey; 2165 } else if (hPrivateLeafKey != NULL_HKEY) { 2166 /* logged in USER session */ 2167 initFlags |= TSS_KEY_TYPE_LEGACY | 2168 TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2169 2170 /* get a random SHA1 hash for the auth data */ 2171 if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) { 2172 return (CKR_FUNCTION_FAILED); 2173 } 2174 2175 authData = authHash; 2176 hParentKey = hPrivateRootKey; 2177 } else { 2178 /* logged in SO session */ 2179 initFlags |= TSS_KEY_TYPE_LEGACY | 2180 TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; 2181 2182 /* get a random SHA1 hash for the auth data */ 2183 if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) { 2184 return (CKR_FUNCTION_FAILED); 2185 } 2186 2187 authData = authHash; 2188 hParentKey = hPublicRootKey; 2189 } 2190 2191 if ((result = tss_generate_key(hContext, initFlags, authData, 2192 hParentKey, &hKey))) { 2193 return (result); 2194 } 2195 2196 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 2197 TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { 2198 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2199 result, Trspi_Error_String(result)); 2200 return (CKR_FUNCTION_FAILED); 2201 } 2202 2203 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, 2204 ulBlobLen, &attr))) { 2205 Tspi_Context_FreeMemory(hContext, rgbBlob); 2206 return (rc); 2207 } 2208 (void) template_update_attribute(priv_tmpl, attr); 2209 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, 2210 ulBlobLen, &attr))) { 2211 Tspi_Context_FreeMemory(hContext, rgbBlob); 2212 return (rc); 2213 } 2214 (void) template_update_attribute(publ_tmpl, attr); 2215 2216 Tspi_Context_FreeMemory(hContext, rgbBlob); 2217 2218 /* grab the public key to put into the public key object */ 2219 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2220 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &ulBlobLen, &rgbBlob))) { 2221 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2222 result, Trspi_Error_String(result)); 2223 return (result); 2224 } 2225 2226 /* add the public key blob to the object template */ 2227 if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { 2228 Tspi_Context_FreeMemory(hContext, rgbBlob); 2229 return (rc); 2230 } 2231 (void) template_update_attribute(publ_tmpl, attr); 2232 2233 /* add the public key blob to the object template */ 2234 if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { 2235 Tspi_Context_FreeMemory(hContext, rgbBlob); 2236 return (rc); 2237 } 2238 (void) template_update_attribute(priv_tmpl, attr); 2239 Tspi_Context_FreeMemory(hContext, rgbBlob); 2240 2241 /* wrap the authdata and put it into an object */ 2242 if (authData != NULL) { 2243 rc = token_wrap_auth_data(hContext, authData, publ_tmpl, 2244 priv_tmpl); 2245 } 2246 2247 return (rc); 2248 } 2249 2250 static CK_RV 2251 token_rsa_load_key( 2252 TSS_HCONTEXT hContext, 2253 OBJECT *key_obj, 2254 TSS_HKEY *phKey) 2255 { 2256 TSS_RESULT result; 2257 TSS_HPOLICY hPolicy = NULL_HPOLICY; 2258 TSS_HKEY hParentKey; 2259 BYTE *authData = NULL; 2260 CK_ATTRIBUTE *attr; 2261 CK_RV rc; 2262 CK_OBJECT_HANDLE handle; 2263 CK_ULONG class; 2264 2265 if (hPrivateLeafKey != NULL_HKEY) { 2266 hParentKey = hPrivateRootKey; 2267 } else { 2268 if ((result = token_load_public_root_key(hContext))) 2269 return (CKR_FUNCTION_FAILED); 2270 2271 hParentKey = hPublicRootKey; 2272 } 2273 2274 *phKey = NULL; 2275 if (template_attribute_find(key_obj->template, CKA_CLASS, 2276 &attr) == FALSE) { 2277 return (CKR_TEMPLATE_INCOMPLETE); 2278 } 2279 class = *((CK_ULONG *)attr->pValue); 2280 2281 rc = template_attribute_find(key_obj->template, 2282 CKA_IBM_OPAQUE, &attr); 2283 /* 2284 * A public key cannot use the OPAQUE data attribute so they 2285 * must be created in software. A private key may not yet 2286 * have its "opaque" data defined and needs to be created 2287 * and loaded so it can be used inside the TPM. 2288 */ 2289 if (class == CKO_PUBLIC_KEY || rc == FALSE) { 2290 rc = object_mgr_find_in_map2(hContext, key_obj, &handle); 2291 if (rc != CKR_OK) 2292 return (CKR_FUNCTION_FAILED); 2293 2294 if ((rc = token_load_key(hContext, 2295 handle, hParentKey, NULL, phKey))) { 2296 return (rc); 2297 } 2298 } 2299 /* 2300 * If this is a private key, get the blob and load it in the TPM. 2301 * If it is public, the key is already loaded in software. 2302 */ 2303 if (class == CKO_PRIVATE_KEY) { 2304 /* If we already have a handle, just load it */ 2305 if (*phKey != NULL) { 2306 result = Tspi_Key_LoadKey(*phKey, hParentKey); 2307 if (result) { 2308 stlogit("Tspi_Context_LoadKeyByBlob: " 2309 "0x%0x - %s", 2310 result, Trspi_Error_String(result)); 2311 return (CKR_FUNCTION_FAILED); 2312 } 2313 } else { 2314 /* try again to get the CKA_IBM_OPAQUE attr */ 2315 if ((rc = template_attribute_find(key_obj->template, 2316 CKA_IBM_OPAQUE, &attr)) == FALSE) { 2317 return (rc); 2318 } 2319 if ((result = Tspi_Context_LoadKeyByBlob(hContext, 2320 hParentKey, attr->ulValueLen, attr->pValue, 2321 phKey))) { 2322 stlogit("Tspi_Context_LoadKeyByBlob: " 2323 "0x%0x - %s", 2324 result, Trspi_Error_String(result)); 2325 return (CKR_FUNCTION_FAILED); 2326 } 2327 } 2328 } 2329 2330 /* auth data may be required */ 2331 if (template_attribute_find(key_obj->template, CKA_ENC_AUTHDATA, 2332 &attr) == TRUE && attr) { 2333 if ((hPrivateLeafKey == NULL_HKEY) && 2334 (hPublicLeafKey == NULL_HKEY)) { 2335 return (CKR_FUNCTION_FAILED); 2336 } else if (hPublicLeafKey != NULL_HKEY) { 2337 hParentKey = hPublicLeafKey; 2338 } else { 2339 hParentKey = hPrivateLeafKey; 2340 } 2341 2342 if ((result = token_unwrap_auth_data(hContext, 2343 attr->pValue, attr->ulValueLen, 2344 hParentKey, &authData))) { 2345 return (CKR_FUNCTION_FAILED); 2346 } 2347 2348 if ((result = Tspi_GetPolicyObject(*phKey, 2349 TSS_POLICY_USAGE, &hPolicy))) { 2350 stlogit("Tspi_GetPolicyObject: 0x%0x - %s", 2351 result, Trspi_Error_String(result)); 2352 return (CKR_FUNCTION_FAILED); 2353 } 2354 2355 /* 2356 * If the policy handle returned is the same as the 2357 * context's default policy, then a new policy must 2358 * be created and assigned to the key. Otherwise, just set the 2359 * secret in the policy. 2360 */ 2361 if (hPolicy == hDefaultPolicy) { 2362 if ((result = Tspi_Context_CreateObject(hContext, 2363 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, 2364 &hPolicy))) { 2365 stlogit("Tspi_Context_CreateObject: " 2366 "0x%0x - %s", 2367 result, Trspi_Error_String(result)); 2368 return (CKR_FUNCTION_FAILED); 2369 } 2370 2371 if ((result = Tspi_Policy_SetSecret(hPolicy, 2372 TSS_SECRET_MODE_SHA1, 2373 SHA1_DIGEST_LENGTH, authData))) { 2374 stlogit("Tspi_Policy_SetSecret: " 2375 "0x%0x - %s", 2376 result, Trspi_Error_String(result)); 2377 return (CKR_FUNCTION_FAILED); 2378 } 2379 2380 if ((result = Tspi_Policy_AssignToObject(hPolicy, 2381 *phKey))) { 2382 stlogit("Tspi_Policy_AssignToObject: " 2383 "0x%0x - %s", 2384 result, Trspi_Error_String(result)); 2385 return (CKR_FUNCTION_FAILED); 2386 } 2387 } else if ((result = Tspi_Policy_SetSecret(hPolicy, 2388 TSS_SECRET_MODE_SHA1, SHA1_DIGEST_LENGTH, authData))) { 2389 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s", 2390 result, Trspi_Error_String(result)); 2391 return (CKR_FUNCTION_FAILED); 2392 } 2393 2394 Tspi_Context_FreeMemory(hContext, authData); 2395 } 2396 2397 return (CKR_OK); 2398 } 2399 2400 CK_RV 2401 tpm_decrypt_data( 2402 TSS_HCONTEXT hContext, 2403 TSS_HKEY hKey, 2404 CK_BYTE * in_data, 2405 CK_ULONG in_data_len, 2406 CK_BYTE * out_data, 2407 CK_ULONG * out_data_len) 2408 { 2409 TSS_RESULT result; 2410 TSS_HENCDATA hEncData = NULL_HENCDATA; 2411 UINT32 buf_size = 0, modLen; 2412 BYTE *buf = NULL, *modulus = NULL; 2413 CK_ULONG chunklen, remain, outlen; 2414 2415 /* push the data into the encrypted data object */ 2416 if ((result = Tspi_Context_CreateObject(hContext, 2417 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2418 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2419 result, Trspi_Error_String(result)); 2420 return (CKR_FUNCTION_FAILED); 2421 } 2422 2423 /* 2424 * Figure out the modulus size so we can break the data 2425 * into smaller chunks if necessary. 2426 */ 2427 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2428 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) { 2429 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2430 result, Trspi_Error_String(result)); 2431 return (result); 2432 } 2433 /* we don't need the actual modulus */ 2434 Tspi_Context_FreeMemory(hContext, modulus); 2435 2436 chunklen = (in_data_len > modLen ? modLen : in_data_len); 2437 remain = in_data_len; 2438 outlen = 0; 2439 2440 while (remain > 0) { 2441 if ((result = Tspi_SetAttribData(hEncData, 2442 TSS_TSPATTRIB_ENCDATA_BLOB, 2443 TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2444 chunklen, in_data))) { 2445 stlogit("Tspi_SetAttribData: 0x%0x - %s", 2446 result, Trspi_Error_String(result)); 2447 return (CKR_FUNCTION_FAILED); 2448 } 2449 2450 /* unbind the data, receiving the plaintext back */ 2451 if ((result = Tspi_Data_Unbind(hEncData, hKey, 2452 &buf_size, &buf))) { 2453 stlogit("Tspi_Data_Unbind: 0x%0x - %s", 2454 result, Trspi_Error_String(result)); 2455 return (CKR_FUNCTION_FAILED); 2456 } 2457 2458 if (*out_data_len < buf_size + outlen) { 2459 Tspi_Context_FreeMemory(hContext, buf); 2460 return (CKR_BUFFER_TOO_SMALL); 2461 } 2462 2463 (void) memcpy(out_data + outlen, buf, buf_size); 2464 2465 outlen += buf_size; 2466 in_data += chunklen; 2467 remain -= chunklen; 2468 2469 Tspi_Context_FreeMemory(hContext, buf); 2470 if (chunklen > remain) 2471 chunklen = remain; 2472 } 2473 *out_data_len = outlen; 2474 return (CKR_OK); 2475 } 2476 2477 CK_RV 2478 token_specific_rsa_decrypt( 2479 TSS_HCONTEXT hContext, 2480 CK_BYTE * in_data, 2481 CK_ULONG in_data_len, 2482 CK_BYTE * out_data, 2483 CK_ULONG * out_data_len, 2484 OBJECT * key_obj) 2485 { 2486 CK_RV rc; 2487 TSS_HKEY hKey; 2488 2489 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2490 return (rc); 2491 } 2492 2493 rc = tpm_decrypt_data(hContext, hKey, in_data, in_data_len, 2494 out_data, out_data_len); 2495 2496 return (rc); 2497 } 2498 2499 CK_RV 2500 token_specific_rsa_verify( 2501 TSS_HCONTEXT hContext, 2502 CK_BYTE * in_data, 2503 CK_ULONG in_data_len, 2504 CK_BYTE * sig, 2505 CK_ULONG sig_len, 2506 OBJECT * key_obj) 2507 { 2508 TSS_RESULT result; 2509 TSS_HHASH hHash; 2510 TSS_HKEY hKey; 2511 CK_RV rc; 2512 2513 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2514 return (rc); 2515 } 2516 2517 /* Create the hash object we'll use to sign */ 2518 if ((result = Tspi_Context_CreateObject(hContext, 2519 TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { 2520 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2521 result, Trspi_Error_String(result)); 2522 return (CKR_FUNCTION_FAILED); 2523 } 2524 2525 /* Insert the data into the hash object */ 2526 if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, 2527 in_data))) { 2528 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s", 2529 result, Trspi_Error_String(result)); 2530 return (CKR_FUNCTION_FAILED); 2531 } 2532 2533 /* Verify */ 2534 result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig); 2535 if (result != TSS_SUCCESS && 2536 TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) { 2537 stlogit("Tspi_Hash_VerifySignature: 0x%0x - %s", 2538 result, Trspi_Error_String(result)); 2539 } 2540 2541 if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) { 2542 rc = CKR_SIGNATURE_INVALID; 2543 } else { 2544 rc = CKR_OK; 2545 } 2546 2547 return (rc); 2548 } 2549 2550 CK_RV 2551 token_specific_rsa_sign( 2552 TSS_HCONTEXT hContext, 2553 CK_BYTE * in_data, 2554 CK_ULONG in_data_len, 2555 CK_BYTE * out_data, 2556 CK_ULONG * out_data_len, 2557 OBJECT * key_obj) 2558 { 2559 TSS_RESULT result; 2560 TSS_HHASH hHash; 2561 BYTE *sig; 2562 UINT32 sig_len; 2563 TSS_HKEY hKey; 2564 CK_RV rc; 2565 2566 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2567 return (rc); 2568 } 2569 2570 /* Create the hash object we'll use to sign */ 2571 if ((result = Tspi_Context_CreateObject(hContext, 2572 TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { 2573 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2574 result, Trspi_Error_String(result)); 2575 return (CKR_FUNCTION_FAILED); 2576 } 2577 2578 /* Insert the data into the hash object */ 2579 if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, 2580 in_data))) { 2581 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s", 2582 result, Trspi_Error_String(result)); 2583 return (CKR_FUNCTION_FAILED); 2584 } 2585 2586 /* Sign */ 2587 if ((result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig))) { 2588 stlogit("Tspi_Hash_Sign: 0x%0x - %s", 2589 result, Trspi_Error_String(result)); 2590 return (CKR_DATA_LEN_RANGE); 2591 } 2592 2593 if (sig_len > *out_data_len) { 2594 Tspi_Context_FreeMemory(hContext, sig); 2595 return (CKR_BUFFER_TOO_SMALL); 2596 } 2597 2598 (void) memcpy(out_data, sig, sig_len); 2599 *out_data_len = sig_len; 2600 Tspi_Context_FreeMemory(hContext, sig); 2601 2602 return (CKR_OK); 2603 } 2604 2605 CK_RV 2606 tpm_encrypt_data( 2607 TSS_HCONTEXT hContext, 2608 TSS_HKEY hKey, 2609 CK_BYTE *in_data, 2610 CK_ULONG in_data_len, 2611 CK_BYTE *out_data, 2612 CK_ULONG *out_data_len) 2613 { 2614 TSS_RESULT result; 2615 TSS_HENCDATA hEncData; 2616 BYTE *dataBlob, *modulus; 2617 UINT32 dataBlobSize, modLen; 2618 CK_ULONG chunklen, remain; 2619 CK_ULONG outlen; 2620 UINT32 keyusage, scheme, maxsize; 2621 2622 if ((result = Tspi_Context_CreateObject(hContext, 2623 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { 2624 stlogit("Tspi_Context_CreateObject: 0x%0x - %s", 2625 result, Trspi_Error_String(result)); 2626 return (CKR_FUNCTION_FAILED); 2627 } 2628 /* 2629 * Figure out the modulus size so we can break the data 2630 * into smaller chunks if necessary. 2631 */ 2632 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2633 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) { 2634 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2635 result, Trspi_Error_String(result)); 2636 return (result); 2637 } 2638 /* we don't need the actual modulus */ 2639 Tspi_Context_FreeMemory(hContext, modulus); 2640 2641 /* 2642 * According to TSS spec for Tspi_Data_Bind (4.3.4.21.5), 2643 * Max input data size varies depending on the key type and 2644 * encryption scheme. 2645 */ 2646 if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 2647 TSS_TSPATTRIB_KEYINFO_USAGE, &keyusage))) { 2648 stlogit("Cannot find USAGE: %s\n", 2649 Trspi_Error_String(result)); 2650 return (result); 2651 } 2652 if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 2653 TSS_TSPATTRIB_KEYINFO_ENCSCHEME, &scheme))) { 2654 stlogit("Cannot find ENCSCHEME: %s\n", 2655 Trspi_Error_String(result)); 2656 return (result); 2657 } 2658 switch (scheme) { 2659 case TSS_ES_RSAESPKCSV15: 2660 if (keyusage == TSS_KEYUSAGE_BIND) 2661 maxsize = 16; 2662 else /* legacy */ 2663 maxsize = 11; 2664 break; 2665 case TSS_ES_RSAESOAEP_SHA1_MGF1: 2666 maxsize = 47; 2667 break; 2668 default: 2669 maxsize = 0; 2670 } 2671 2672 modLen -= maxsize; 2673 2674 chunklen = (in_data_len > modLen ? modLen : in_data_len); 2675 remain = in_data_len; 2676 outlen = 0; 2677 while (remain > 0) { 2678 if ((result = Tspi_Data_Bind(hEncData, hKey, 2679 chunklen, in_data))) { 2680 stlogit("Tspi_Data_Bind: 0x%0x - %s", 2681 result, Trspi_Error_String(result)); 2682 return (CKR_FUNCTION_FAILED); 2683 } 2684 2685 if ((result = Tspi_GetAttribData(hEncData, 2686 TSS_TSPATTRIB_ENCDATA_BLOB, 2687 TSS_TSPATTRIB_ENCDATABLOB_BLOB, 2688 &dataBlobSize, &dataBlob))) { 2689 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2690 result, Trspi_Error_String(result)); 2691 return (CKR_FUNCTION_FAILED); 2692 } 2693 2694 if (outlen + dataBlobSize > *out_data_len) { 2695 Tspi_Context_FreeMemory(hContext, dataBlob); 2696 return (CKR_DATA_LEN_RANGE); 2697 } 2698 2699 (void) memcpy(out_data + outlen, 2700 dataBlob, dataBlobSize); 2701 2702 outlen += dataBlobSize; 2703 in_data += chunklen; 2704 remain -= chunklen; 2705 2706 if (chunklen > remain) 2707 chunklen = remain; 2708 2709 Tspi_Context_FreeMemory(hContext, dataBlob); 2710 } 2711 *out_data_len = outlen; 2712 2713 return (CKR_OK); 2714 } 2715 2716 CK_RV 2717 token_specific_rsa_encrypt( 2718 TSS_HCONTEXT hContext, 2719 CK_BYTE * in_data, 2720 CK_ULONG in_data_len, 2721 CK_BYTE * out_data, 2722 CK_ULONG * out_data_len, 2723 OBJECT * key_obj) 2724 { 2725 TSS_HKEY hKey; 2726 CK_RV rc; 2727 2728 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2729 return (rc); 2730 } 2731 2732 rc = tpm_encrypt_data(hContext, hKey, in_data, in_data_len, 2733 out_data, out_data_len); 2734 2735 return (rc); 2736 } 2737 2738 /* 2739 * RSA Verify Recover 2740 * 2741 * Public key crypto is done in software, not by the TPM. 2742 * We bypass the TSPI library here in favor of calls directly 2743 * to OpenSSL because we don't want to add any padding, the in_data (signature) 2744 * already contains the data stream to be decrypted and is already 2745 * padded and formatted correctly. 2746 */ 2747 CK_RV 2748 token_specific_rsa_verify_recover( 2749 TSS_HCONTEXT hContext, 2750 CK_BYTE *in_data, /* signature */ 2751 CK_ULONG in_data_len, 2752 CK_BYTE *out_data, /* decrypted */ 2753 CK_ULONG *out_data_len, 2754 OBJECT *key_obj) 2755 { 2756 TSS_HKEY hKey; 2757 TSS_RESULT result; 2758 CK_RV rc; 2759 BYTE *modulus; 2760 UINT32 modLen; 2761 RSA *rsa = NULL; 2762 uchar_t exp[] = { 0x01, 0x00, 0x01 }; 2763 int sslrv, num; 2764 BYTE temp[MAX_RSA_KEYLENGTH]; 2765 BYTE outdata[MAX_RSA_KEYLENGTH]; 2766 int i; 2767 2768 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) { 2769 return (rc); 2770 } 2771 2772 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, 2773 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) { 2774 stlogit("Tspi_GetAttribData: 0x%0x - %s", 2775 result, Trspi_Error_String(result)); 2776 return (CKR_FUNCTION_FAILED); 2777 } 2778 2779 if (in_data_len != modLen) { 2780 rc = CKR_SIGNATURE_LEN_RANGE; 2781 goto end; 2782 } 2783 2784 rsa = RSA_new(); 2785 if (rsa == NULL) { 2786 rc = CKR_HOST_MEMORY; 2787 goto end; 2788 } 2789 2790 rsa->n = BN_bin2bn(modulus, modLen, rsa->n); 2791 rsa->e = BN_bin2bn(exp, sizeof (exp), rsa->e); 2792 if (rsa->n == NULL || rsa->e == NULL) { 2793 rc = CKR_HOST_MEMORY; 2794 goto end; 2795 } 2796 2797 rsa->flags |= RSA_FLAG_SIGN_VER; 2798 2799 /* use RSA_NO_PADDING because the data is already padded (PKCS1) */ 2800 sslrv = RSA_public_encrypt(in_data_len, in_data, outdata, 2801 rsa, RSA_NO_PADDING); 2802 if (sslrv == -1) { 2803 rc = CKR_FUNCTION_FAILED; 2804 goto end; 2805 } 2806 2807 /* Strip leading 0's before stripping the padding */ 2808 for (i = 0; i < sslrv; i++) 2809 if (outdata[i] != 0) 2810 break; 2811 2812 num = BN_num_bytes(rsa->n); 2813 2814 /* Use OpenSSL function for stripping PKCS#1 padding */ 2815 sslrv = RSA_padding_check_PKCS1_type_1(temp, sizeof (temp), 2816 &outdata[i], sslrv - i, num); 2817 2818 if (sslrv < 0) { 2819 rc = CKR_FUNCTION_FAILED; 2820 goto end; 2821 } 2822 2823 if (*out_data_len < sslrv) { 2824 rc = CKR_BUFFER_TOO_SMALL; 2825 *out_data_len = 0; 2826 goto end; 2827 } 2828 2829 /* The return code indicates the number of bytes remaining */ 2830 (void) memcpy(out_data, temp, sslrv); 2831 *out_data_len = sslrv; 2832 end: 2833 Tspi_Context_FreeMemory(hContext, modulus); 2834 if (rsa) 2835 RSA_free(rsa); 2836 2837 return (rc); 2838 } 2839