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