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