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