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