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