7812 Remove gender specific language
[unleashed.git] / usr / src / lib / pkcs11 / pkcs11_tpm / common / tpm_specific.c
blob2564a2aafddadf94f670b489b01607783232efe4
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.
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.
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.
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.
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.
28 #include <pthread.h>
29 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <uuid/uuid.h>
34 #include <fcntl.h>
35 #include <errno.h>
36 #include <pwd.h>
37 #include <syslog.h>
39 #include <openssl/rsa.h>
41 #include <tss/platform.h>
42 #include <tss/tss_defines.h>
43 #include <tss/tss_typedef.h>
44 #include <tss/tss_structs.h>
45 #include <tss/tss_error.h>
46 #include <tss/tcs_error.h>
47 #include <tss/tspi.h>
48 #include <trousers/trousers.h>
50 #include "tpmtok_int.h"
51 #include "tpmtok_defs.h"
53 #define MAX_RSA_KEYLENGTH 512
55 extern void stlogit(char *fmt, ...);
57 CK_RV token_rng(TSS_HCONTEXT, CK_BYTE *, CK_ULONG);
58 int tok_slot2local(CK_SLOT_ID);
59 CK_RV token_specific_session(CK_SLOT_ID);
60 CK_RV token_specific_final(TSS_HCONTEXT);
62 CK_RV
63 token_specific_rsa_decrypt(
64 TSS_HCONTEXT,
65 CK_BYTE *,
66 CK_ULONG,
67 CK_BYTE *,
68 CK_ULONG *,
69 OBJECT *);
71 CK_RV
72 token_specific_rsa_encrypt(
73 TSS_HCONTEXT,
74 CK_BYTE *,
75 CK_ULONG,
76 CK_BYTE *,
77 CK_ULONG *,
78 OBJECT *);
80 CK_RV
81 token_specific_rsa_sign(
82 TSS_HCONTEXT,
83 CK_BYTE *,
84 CK_ULONG,
85 CK_BYTE *,
86 CK_ULONG *,
87 OBJECT *);
89 CK_RV
90 token_specific_rsa_verify(TSS_HCONTEXT, CK_BYTE *,
91 CK_ULONG, CK_BYTE *, CK_ULONG, OBJECT *);
93 CK_RV
94 token_specific_rsa_generate_keypair(TSS_HCONTEXT,
95 TEMPLATE *,
96 TEMPLATE *);
98 CK_RV
99 token_specific_sha_init(DIGEST_CONTEXT *);
101 CK_RV
102 token_specific_sha_update(DIGEST_CONTEXT *,
103 CK_BYTE *,
104 CK_ULONG);
106 CK_RV
107 token_specific_sha_final(DIGEST_CONTEXT *,
108 CK_BYTE *,
109 CK_ULONG *);
111 CK_RV token_specific_login(TSS_HCONTEXT, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG);
112 CK_RV token_specific_logout(TSS_HCONTEXT);
113 CK_RV token_specific_init_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG);
114 CK_RV token_specific_set_pin(ST_SESSION_HANDLE, CK_CHAR_PTR,
115 CK_ULONG, CK_CHAR_PTR, CK_ULONG);
116 CK_RV token_specific_verify_so_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG);
118 static CK_RV
119 token_specific_init(char *, CK_SLOT_ID, TSS_HCONTEXT *);
121 struct token_specific_struct token_specific = {
122 "TPM_Debug",
123 &token_specific_init,
124 NULL,
125 &token_rng,
126 &token_specific_session,
127 &token_specific_final,
128 &token_specific_rsa_decrypt,
129 &token_specific_rsa_encrypt,
130 &token_specific_rsa_sign,
131 &token_specific_rsa_verify,
132 &token_specific_rsa_generate_keypair,
133 NULL,
134 NULL,
135 NULL,
136 &token_specific_login,
137 &token_specific_logout,
138 &token_specific_init_pin,
139 &token_specific_set_pin,
140 &token_specific_verify_so_pin
143 /* The context we'll use globally to connect to the TSP */
145 /* TSP key handles */
146 TSS_HKEY hPublicRootKey = NULL_HKEY;
147 TSS_HKEY hPublicLeafKey = NULL_HKEY;
148 TSS_HKEY hPrivateRootKey = NULL_HKEY;
149 TSS_HKEY hPrivateLeafKey = NULL_HKEY;
151 TSS_UUID publicRootKeyUUID;
152 TSS_UUID publicLeafKeyUUID;
153 TSS_UUID privateRootKeyUUID;
154 TSS_UUID privateLeafKeyUUID;
156 /* TSP policy handles */
157 TSS_HPOLICY hDefaultPolicy = NULL_HPOLICY;
159 /* PKCS#11 key handles */
160 int not_initialized = 0;
162 CK_BYTE current_user_pin_sha[SHA1_DIGEST_LENGTH];
163 CK_BYTE current_so_pin_sha[SHA1_DIGEST_LENGTH];
165 static TPM_CAP_VERSION_INFO tpmvinfo;
167 static CK_RV
168 verify_user_pin(TSS_HCONTEXT, CK_BYTE *);
170 static TSS_RESULT
171 tss_assign_secret_key_policy(TSS_HCONTEXT, TSS_FLAG, TSS_HKEY, CK_CHAR *);
173 static TSS_RESULT
174 set_legacy_key_params(TSS_HKEY);
176 static void
177 local_uuid_clear(TSS_UUID *uuid)
179 if (uuid == NULL)
180 return;
181 (void) memset(uuid, 0, sizeof (TSS_UUID));
185 /* convert from TSS_UUID to uuid_t */
186 static void
187 tss_uuid_convert_from(TSS_UUID *uu, uuid_t ptr)
189 uint_t tmp;
190 uchar_t *out = ptr;
192 tmp = ntohl(uu->ulTimeLow);
193 out[3] = (uchar_t)tmp;
194 tmp >>= 8;
195 out[2] = (uchar_t)tmp;
196 tmp >>= 8;
197 out[1] = (uchar_t)tmp;
198 tmp >>= 8;
199 out[0] = (uchar_t)tmp;
201 tmp = ntohs(uu->usTimeMid);
202 out[5] = (uchar_t)tmp;
203 tmp >>= 8;
204 out[4] = (uchar_t)tmp;
206 tmp = ntohs(uu->usTimeHigh);
207 out[7] = (uchar_t)tmp;
208 tmp >>= 8;
209 out[6] = (uchar_t)tmp;
211 tmp = uu->bClockSeqHigh;
212 out[8] = (uchar_t)tmp;
213 tmp = uu->bClockSeqLow;
214 out[9] = (uchar_t)tmp;
216 (void) memcpy(out+10, uu->rgbNode, 6);
219 /* convert from uuid_t to TSS_UUID */
220 static void
221 tss_uuid_convert_to(TSS_UUID *uuid, uuid_t in)
223 uchar_t *ptr;
224 uint32_t ltmp;
225 uint16_t stmp;
227 ptr = in;
229 ltmp = *ptr++;
230 ltmp = (ltmp << 8) | *ptr++;
231 ltmp = (ltmp << 8) | *ptr++;
232 ltmp = (ltmp << 8) | *ptr++;
233 uuid->ulTimeLow = ntohl(ltmp);
235 stmp = *ptr++;
236 stmp = (stmp << 8) | *ptr++;
237 uuid->usTimeMid = ntohs(stmp);
239 stmp = *ptr++;
240 stmp = (stmp << 8) | *ptr++;
241 uuid->usTimeHigh = ntohs(stmp);
243 uuid->bClockSeqHigh = *ptr++;
245 uuid->bClockSeqLow = *ptr++;
247 (void) memcpy(uuid->rgbNode, ptr, 6);
250 static void
251 local_uuid_copy(TSS_UUID *dst, TSS_UUID *src)
253 uuid_t udst, usrc;
255 tss_uuid_convert_from(dst, udst);
256 tss_uuid_convert_from(src, usrc);
258 uuid_copy(udst, usrc);
260 tss_uuid_convert_to(dst, udst);
263 static void
264 local_uuid_generate(TSS_UUID *uu)
266 uuid_t newuuid;
268 uuid_generate(newuuid);
270 tss_uuid_convert_to(uu, newuuid);
273 static int
274 local_copy_file(char *dst, char *src)
276 FILE *fdest, *fsrc;
277 char line[BUFSIZ];
279 fdest = fopen(dst, "w");
280 if (fdest == NULL)
281 return (-1);
283 fsrc = fopen(src, "r");
284 if (fsrc == NULL) {
285 (void) fclose(fdest);
286 return (-1);
289 while (fread(line, sizeof (line), 1, fsrc))
290 (void) fprintf(fdest, "%s\n", line);
291 (void) fclose(fsrc);
292 (void) fclose(fdest);
293 return (0);
296 static int
297 remove_uuid(char *keyname)
299 int ret = 0;
300 FILE *fp, *newfp;
301 char fname[MAXPATHLEN];
302 char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ];
303 char *tmpfname;
304 char *p = get_tpm_keystore_path();
306 if (p == NULL)
307 return (-1);
309 (void) snprintf(fname, sizeof (fname),
310 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME);
312 fp = fopen(fname, "r");
313 if (fp == NULL) {
314 return (-1);
317 tmpfname = tempnam("/tmp", "tpmtok");
318 newfp = fopen(tmpfname, "w+");
319 if (newfp == NULL) {
320 free(tmpfname);
321 (void) fclose(fp);
322 return (-1);
325 while (!feof(fp)) {
326 (void) fgets(line, sizeof (line), fp);
327 if (sscanf(line, "%1024s %1024s", key, idstr) == 2) {
328 if (strcmp(key, keyname))
329 (void) fprintf(newfp, "%s\n", line);
333 (void) fclose(fp);
334 (void) fclose(newfp);
335 if (local_copy_file(fname, tmpfname) == 0)
336 (void) unlink(tmpfname);
338 free(tmpfname);
340 return (ret);
343 static int
344 find_uuid(char *keyname, TSS_UUID *uu)
346 int ret = 0, found = 0;
347 FILE *fp = NULL;
348 char fname[MAXPATHLEN];
349 char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ];
350 uuid_t uuid;
351 char *p = get_tpm_keystore_path();
353 if (p == NULL)
354 return (-1);
356 tss_uuid_convert_from(uu, uuid);
358 (void) snprintf(fname, sizeof (fname),
359 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME);
361 /* Open UUID Index file */
362 fp = fopen(fname, "r");
363 if (fp == NULL) {
364 if (errno == ENOENT) {
365 /* initialize the file */
366 fp = fopen(fname, "w");
367 if (fp != NULL)
368 (void) fclose(fp);
370 return (-1);
373 while (!feof(fp)) {
374 (void) fgets(line, sizeof (line), fp);
375 if (sscanf(line, "%1024s %1024s", key, idstr) == 2) {
376 if (strcmp(key, keyname) == 0) {
377 ret = uuid_parse(idstr, uuid);
378 if (ret == 0) {
379 found = 1;
380 tss_uuid_convert_to(uu,
381 uuid);
383 break;
387 (void) fclose(fp);
389 if (!found)
390 ret = -1;
391 return (ret);
394 static int
395 local_uuid_is_null(TSS_UUID *uu)
397 uuid_t uuid;
398 int nulluuid;
400 tss_uuid_convert_from(uu, uuid);
402 nulluuid = uuid_is_null(uuid);
403 return (nulluuid);
406 static int
407 add_uuid(char *keyname, TSS_UUID *uu)
409 FILE *fp = NULL;
410 char fname[MAXPATHLEN];
411 char idstr[BUFSIZ];
412 uuid_t uuid;
413 char *p = get_tpm_keystore_path();
415 if (p == NULL)
416 return (-1);
418 tss_uuid_convert_from(uu, uuid);
420 if (uuid_is_null(uuid))
421 return (-1);
423 uuid_unparse(uuid, idstr);
425 (void) snprintf(fname, sizeof (fname),
426 "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME);
428 fp = fopen(fname, "a");
429 if (fp == NULL)
430 return (-1);
432 (void) fprintf(fp, "%s %s\n", keyname, idstr);
433 (void) fclose(fp);
435 return (0);
439 static UINT32
440 util_get_keysize_flag(CK_ULONG size)
442 switch (size) {
443 case 512:
444 return (TSS_KEY_SIZE_512);
445 case 1024:
446 return (TSS_KEY_SIZE_1024);
447 case 2048:
448 return (TSS_KEY_SIZE_2048);
449 default:
450 break;
453 return (0);
456 /* make sure the public exponent attribute is 65537 */
457 static CK_ULONG
458 util_check_public_exponent(TEMPLATE *tmpl)
460 CK_BBOOL flag;
461 CK_ATTRIBUTE *publ_exp_attr;
462 CK_BYTE pubexp_bytes[] = { 1, 0, 1 };
463 CK_ULONG publ_exp, rc = 1;
465 flag = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT,
466 &publ_exp_attr);
467 if (!flag) {
468 LogError1("Couldn't find public exponent attribute");
469 return (CKR_TEMPLATE_INCOMPLETE);
472 switch (publ_exp_attr->ulValueLen) {
473 case 3:
474 rc = memcmp(pubexp_bytes, publ_exp_attr->pValue, 3);
475 break;
476 case sizeof (CK_ULONG):
477 publ_exp = *((CK_ULONG *)publ_exp_attr->pValue);
478 if (publ_exp == 65537)
479 rc = 0;
480 break;
481 default:
482 break;
485 return (rc);
488 TSS_RESULT
489 set_public_modulus(TSS_HCONTEXT hContext, TSS_HKEY hKey,
490 unsigned long size_n, unsigned char *n)
492 UINT64 offset;
493 UINT32 blob_size;
494 BYTE *blob, pub_blob[1024];
495 TCPA_PUBKEY pub_key;
496 TSS_RESULT result;
498 /* Get the TCPA_PUBKEY blob from the key object. */
499 result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
500 TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blob_size, &blob);
501 if (result != TSS_SUCCESS) {
502 stlogit("Tspi_GetAttribData failed: rc=0x%0x - %s\n",
503 result, Trspi_Error_String(result));
504 return (result);
507 offset = 0;
508 result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pub_key);
509 if (result != TSS_SUCCESS) {
510 stlogit("Trspi_UnloadBlob_PUBKEY failed: rc=0x%0x - %s\n",
511 result, Trspi_Error_String(result));
512 return (result);
515 Tspi_Context_FreeMemory(hContext, blob);
516 /* Free the first dangling reference, putting 'n' in its place */
517 free(pub_key.pubKey.key);
518 pub_key.pubKey.keyLength = size_n;
519 pub_key.pubKey.key = n;
521 offset = 0;
522 Trspi_LoadBlob_PUBKEY(&offset, pub_blob, &pub_key);
524 /* Free the second dangling reference */
525 free(pub_key.algorithmParms.parms);
527 /* set the public key data in the TSS object */
528 result = Tspi_SetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
529 TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, (UINT32)offset, pub_blob);
530 if (result != TSS_SUCCESS) {
531 stlogit("Tspi_SetAttribData failed: rc=0x%0x - %s\n",
532 result, Trspi_Error_String(result));
533 return (result);
536 return (result);
540 * Get details about the TPM to put into the token_info structure.
542 CK_RV
543 token_get_tpm_info(TSS_HCONTEXT hContext, TOKEN_DATA *td)
545 TSS_RESULT result;
546 TPM_CAPABILITY_AREA capArea = TSS_TPMCAP_VERSION_VAL;
547 UINT32 datalen;
548 BYTE *data;
549 TSS_HTPM hTPM;
551 if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) {
552 stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s",
553 result, Trspi_Error_String(result));
554 return (CKR_FUNCTION_FAILED);
556 if ((result = Tspi_TPM_GetCapability(hTPM,
557 capArea, 0, NULL, &datalen, &data)) != 0 || datalen == 0 ||
558 data == NULL) {
559 stlogit("Tspi_Context_GetCapability: 0x%0x - %s",
560 result, Trspi_Error_String(result));
561 return (CKR_FUNCTION_FAILED);
563 if (datalen > sizeof (tpmvinfo)) {
564 Tspi_Context_FreeMemory(hContext, data);
565 return (CKR_FUNCTION_FAILED);
568 (void) memcpy(&tpmvinfo, (void *)data, datalen);
570 bzero(td->token_info.manufacturerID,
571 sizeof (td->token_info.manufacturerID));
573 (void) memset(td->token_info.manufacturerID, ' ',
574 sizeof (td->token_info.manufacturerID) - 1);
576 (void) memcpy(td->token_info.manufacturerID,
577 tpmvinfo.tpmVendorID, sizeof (tpmvinfo.tpmVendorID));
579 (void) memset(td->token_info.label, ' ',
580 sizeof (td->token_info.label) - 1);
582 (void) memcpy(td->token_info.label, "TPM", 3);
584 td->token_info.hardwareVersion.major = tpmvinfo.version.major;
585 td->token_info.hardwareVersion.minor = tpmvinfo.version.minor;
586 td->token_info.firmwareVersion.major = tpmvinfo.version.revMajor;
587 td->token_info.firmwareVersion.minor = tpmvinfo.version.revMinor;
589 Tspi_Context_FreeMemory(hContext, data);
590 return (CKR_OK);
593 /*ARGSUSED*/
594 CK_RV
595 token_specific_session(CK_SLOT_ID slotid)
597 return (CKR_OK);
600 CK_RV
601 token_rng(TSS_HCONTEXT hContext, CK_BYTE *output, CK_ULONG bytes)
603 TSS_RESULT rc;
604 TSS_HTPM hTPM;
605 BYTE *random_bytes = NULL;
607 if ((rc = Tspi_Context_GetTpmObject(hContext, &hTPM))) {
608 stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s",
609 rc, Trspi_Error_String(rc));
610 return (CKR_FUNCTION_FAILED);
613 if ((rc = Tspi_TPM_GetRandom(hTPM, bytes, &random_bytes))) {
614 stlogit("Tspi_TPM_GetRandom: 0x%0x - %s",
615 rc, Trspi_Error_String(rc));
616 return (CKR_FUNCTION_FAILED);
619 (void) memcpy(output, random_bytes, bytes);
620 Tspi_Context_FreeMemory(hContext, random_bytes);
622 return (CKR_OK);
625 TSS_RESULT
626 open_tss_context(TSS_HCONTEXT *pContext)
628 TSS_RESULT result;
630 if ((result = Tspi_Context_Create(pContext))) {
631 stlogit("Tspi_Context_Create: 0x%0x - %s",
632 result, Trspi_Error_String(result));
633 return (CKR_FUNCTION_FAILED);
636 if ((result = Tspi_Context_Connect(*pContext, NULL))) {
637 stlogit("Tspi_Context_Connect: 0x%0x - %s",
638 result, Trspi_Error_String(result));
639 Tspi_Context_Close(*pContext);
640 *pContext = 0;
641 return (CKR_FUNCTION_FAILED);
643 return (result);
646 /*ARGSUSED*/
647 static CK_RV
648 token_specific_init(char *Correlator, CK_SLOT_ID SlotNumber,
649 TSS_HCONTEXT *hContext)
651 TSS_RESULT result;
653 result = open_tss_context(hContext);
654 if (result)
655 return (CKR_FUNCTION_FAILED);
657 if ((result = Tspi_Context_GetDefaultPolicy(*hContext,
658 &hDefaultPolicy))) {
659 stlogit("Tspi_Context_GetDefaultPolicy: 0x%0x - %s",
660 result, Trspi_Error_String(result));
661 return (CKR_FUNCTION_FAILED);
664 local_uuid_clear(&publicRootKeyUUID);
665 local_uuid_clear(&privateRootKeyUUID);
666 local_uuid_clear(&publicLeafKeyUUID);
667 local_uuid_clear(&privateLeafKeyUUID);
669 result = token_get_tpm_info(*hContext, nv_token_data);
670 return (result);
674 * Given a modulus and prime from an RSA key, create a TSS_HKEY object by
675 * wrapping the RSA key with a key from the TPM (SRK or other previously stored
676 * key).
678 static CK_RV
679 token_wrap_sw_key(
680 TSS_HCONTEXT hContext,
681 int size_n,
682 unsigned char *n,
683 int size_p,
684 unsigned char *p,
685 TSS_HKEY hParentKey,
686 TSS_FLAG initFlags,
687 TSS_HKEY *phKey)
689 TSS_RESULT result;
690 UINT32 key_size;
692 key_size = util_get_keysize_flag(size_n * 8);
693 if (initFlags == 0) {
694 return (CKR_FUNCTION_FAILED);
697 /* create the TSS key object */
698 result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
699 TSS_KEY_MIGRATABLE | initFlags | key_size, phKey);
700 if (result != TSS_SUCCESS) {
701 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
702 result, Trspi_Error_String(result));
703 return (CKR_FUNCTION_FAILED);
706 result = set_public_modulus(hContext, *phKey, size_n, n);
707 if (result != TSS_SUCCESS) {
708 Tspi_Context_CloseObject(hContext, *phKey);
709 *phKey = NULL_HKEY;
710 return (CKR_FUNCTION_FAILED);
713 /* set the private key data in the TSS object */
714 result = Tspi_SetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
715 TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, size_p, p);
716 if (result != TSS_SUCCESS) {
717 stlogit("Tspi_SetAttribData: 0x%x - %s",
718 result, Trspi_Error_String(result));
719 Tspi_Context_CloseObject(hContext, *phKey);
720 *phKey = NULL_HKEY;
721 return (CKR_FUNCTION_FAILED);
724 result = tss_assign_secret_key_policy(hContext, TSS_POLICY_MIGRATION,
725 *phKey, NULL);
727 if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
728 if ((result = Tspi_SetAttribUint32(*phKey,
729 TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
730 TSS_ES_RSAESPKCSV15))) {
731 stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n",
732 result, Trspi_Error_String(result));
733 Tspi_Context_CloseObject(hContext, *phKey);
734 return (CKR_FUNCTION_FAILED);
737 if ((result = Tspi_SetAttribUint32(*phKey,
738 TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
739 TSS_SS_RSASSAPKCS1V15_DER))) {
740 stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n",
741 result, Trspi_Error_String(result));
742 Tspi_Context_CloseObject(hContext, *phKey);
743 return (CKR_FUNCTION_FAILED);
747 result = Tspi_Key_WrapKey(*phKey, hParentKey, NULL_HPCRS);
748 if (result != TSS_SUCCESS) {
749 stlogit("Tspi_Key_WrapKey: 0x%0x - %s",
750 result, Trspi_Error_String(result));
751 Tspi_Context_CloseObject(hContext, *phKey);
752 *phKey = NULL_HKEY;
753 return (CKR_FUNCTION_FAILED);
756 return (CKR_OK);
760 * Create a TPM key blob for an imported key. This function is only called when
761 * a key is in active use, so any failure should trickle through.
763 static CK_RV
764 token_wrap_key_object(TSS_HCONTEXT hContext,
765 CK_OBJECT_HANDLE ckObject,
766 TSS_HKEY hParentKey, TSS_HKEY *phKey)
768 CK_RV rc = CKR_OK;
769 CK_ATTRIBUTE *attr = NULL, *new_attr, *prime_attr;
770 CK_ULONG class, key_type;
771 OBJECT *obj;
773 TSS_RESULT result;
774 TSS_FLAG initFlags = 0;
775 BYTE *rgbBlob;
776 UINT32 ulBlobLen;
778 if ((rc = object_mgr_find_in_map1(hContext, ckObject, &obj))) {
779 return (rc);
782 /* if the object isn't a key, fail */
783 if (template_attribute_find(obj->template, CKA_KEY_TYPE,
784 &attr) == FALSE) {
785 return (CKR_TEMPLATE_INCOMPLETE);
788 key_type = *((CK_ULONG *)attr->pValue);
790 if (key_type != CKK_RSA) {
791 return (CKR_TEMPLATE_INCONSISTENT);
794 if (template_attribute_find(obj->template, CKA_CLASS,
795 &attr) == FALSE) {
796 return (CKR_TEMPLATE_INCOMPLETE);
799 class = *((CK_ULONG *)attr->pValue);
801 if (class == CKO_PRIVATE_KEY) {
803 * In order to create a full TSS key blob using a PKCS#11
804 * private key object, we need one of the two primes, the
805 * modulus and the private exponent and we need the public
806 * exponent to be correct.
810 * Check the least likely attribute to exist first, the
811 * primes.
813 if (template_attribute_find(obj->template, CKA_PRIME_1,
814 &prime_attr) == FALSE) {
815 if (template_attribute_find(obj->template,
816 CKA_PRIME_2, &prime_attr) == FALSE) {
817 return (CKR_TEMPLATE_INCOMPLETE);
821 /* Make sure the public exponent is usable */
822 if ((rc = util_check_public_exponent(obj->template))) {
823 return (CKR_TEMPLATE_INCONSISTENT);
826 /* get the modulus */
827 if (template_attribute_find(obj->template, CKA_MODULUS,
828 &attr) == FALSE) {
829 return (CKR_TEMPLATE_INCOMPLETE);
832 /* make sure the key size is usable */
833 initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
834 if (initFlags == 0) {
835 return (CKR_TEMPLATE_INCONSISTENT);
838 /* generate the software based key */
839 if ((rc = token_wrap_sw_key(hContext,
840 (int)attr->ulValueLen, attr->pValue,
841 (int)prime_attr->ulValueLen, prime_attr->pValue,
842 hParentKey, TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION,
843 phKey))) {
844 return (rc);
846 } else if (class == CKO_PUBLIC_KEY) {
847 /* Make sure the public exponent is usable */
848 if ((util_check_public_exponent(obj->template))) {
849 return (CKR_TEMPLATE_INCONSISTENT);
852 /* grab the modulus to put into the TSS key object */
853 if (template_attribute_find(obj->template,
854 CKA_MODULUS, &attr) == FALSE) {
855 return (CKR_TEMPLATE_INCONSISTENT);
858 /* make sure the key size is usable */
859 initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
860 if (initFlags == 0) {
861 return (CKR_TEMPLATE_INCONSISTENT);
864 initFlags |= TSS_KEY_MIGRATABLE | TSS_KEY_NO_AUTHORIZATION |
865 TSS_KEY_TYPE_LEGACY;
867 if ((result = Tspi_Context_CreateObject(hContext,
868 TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) {
869 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
870 result, Trspi_Error_String(result));
871 return (result);
874 if ((result = set_public_modulus(hContext, *phKey,
875 attr->ulValueLen, attr->pValue))) {
876 Tspi_Context_CloseObject(hContext, *phKey);
877 *phKey = NULL_HKEY;
878 return (CKR_FUNCTION_FAILED);
880 result = tss_assign_secret_key_policy(hContext,
881 TSS_POLICY_MIGRATION, *phKey, NULL);
882 if (result) {
883 Tspi_Context_CloseObject(hContext, *phKey);
884 *phKey = NULL_HKEY;
885 return (CKR_FUNCTION_FAILED);
888 result = set_legacy_key_params(*phKey);
889 if (result) {
890 Tspi_Context_CloseObject(hContext, *phKey);
891 *phKey = NULL_HKEY;
892 return (CKR_FUNCTION_FAILED);
894 } else {
895 return (CKR_FUNCTION_FAILED);
898 /* grab the entire key blob to put into the PKCS#11 object */
899 if ((result = Tspi_GetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
900 TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) {
901 stlogit("Tspi_GetAttribData: 0x%0x - %s",
902 result, Trspi_Error_String(result));
903 return (CKR_FUNCTION_FAILED);
906 /* insert the key blob into the object */
907 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen,
908 &new_attr))) {
909 Tspi_Context_FreeMemory(hContext, rgbBlob);
910 return (rc);
912 (void) template_update_attribute(obj->template, new_attr);
913 Tspi_Context_FreeMemory(hContext, rgbBlob);
916 * If this is a token object, save it with the new attribute
917 * so that we don't have to go down this path again.
919 if (!object_is_session_object(obj)) {
920 rc = save_token_object(hContext, obj);
923 return (rc);
926 static TSS_RESULT
927 tss_assign_secret_key_policy(TSS_HCONTEXT hContext, TSS_FLAG policyType,
928 TSS_HKEY hKey, CK_CHAR *passHash)
930 TSS_RESULT result;
931 TSS_HPOLICY hPolicy;
933 if ((result = Tspi_Context_CreateObject(hContext,
934 TSS_OBJECT_TYPE_POLICY, policyType, &hPolicy))) {
935 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
936 result, Trspi_Error_String(result));
937 return (result);
939 if ((result = Tspi_Policy_AssignToObject(hPolicy, hKey))) {
940 stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s",
941 result, Trspi_Error_String(result));
942 goto done;
944 if (passHash == NULL) {
945 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE,
946 0, NULL);
947 } else {
948 result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
949 SHA1_DIGEST_LENGTH, passHash);
951 if (result != TSS_SUCCESS) {
952 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
953 result, Trspi_Error_String(result));
954 goto done;
956 done:
957 if (result != TSS_SUCCESS)
958 Tspi_Context_CloseObject(hContext, hPolicy);
959 return (result);
963 * Take a key from the TSS store (on-disk) and load it into the TPM, wrapped
964 * by an already TPM-resident key and protected with a PIN (optional).
966 static CK_RV
967 token_load_key(
968 TSS_HCONTEXT hContext,
969 CK_OBJECT_HANDLE ckKey,
970 TSS_HKEY hParentKey,
971 CK_CHAR_PTR passHash,
972 TSS_HKEY *phKey)
974 TSS_RESULT result;
975 CK_RV rc;
978 * The key blob wasn't found, load the parts of the key
979 * from the object DB and create a new key object that
980 * gets loaded into the TPM, wrapped with the parent key.
982 if ((rc = token_wrap_key_object(hContext, ckKey,
983 hParentKey, phKey))) {
984 return (rc);
988 * Assign the PIN hash (optional) to the newly loaded key object,
989 * if this PIN is incorrect, the TPM will not be able to decrypt
990 * the private key and use it.
992 result = tss_assign_secret_key_policy(hContext, TSS_POLICY_USAGE,
993 *phKey, passHash);
995 return (result);
999 * Load the SRK into the TPM by referencing its well-known UUID and using the
1000 * default SRK PIN (20 bytes of 0x00).
1002 * NOTE - if the SRK PIN is changed by an administrative tool, this code will
1003 * fail because it assumes that the well-known PIN is still being used.
1005 static TSS_RESULT
1006 token_load_srk(TSS_HCONTEXT hContext, TSS_HKEY *hSRK)
1008 TSS_HPOLICY hPolicy;
1009 TSS_RESULT result;
1010 TSS_UUID SRK_UUID = TSS_UUID_SRK;
1011 BYTE wellKnown[] = TSS_WELL_KNOWN_SECRET;
1012 TSS_HTPM hTPM;
1014 if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) {
1015 stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s",
1016 result, Trspi_Error_String(result));
1017 return (CKR_FUNCTION_FAILED);
1020 /* load the SRK */
1021 if ((result = Tspi_Context_LoadKeyByUUID(hContext,
1022 TSS_PS_TYPE_SYSTEM, SRK_UUID, hSRK))) {
1023 stlogit("Tspi_Context_LoadKeyByUUID: 0x%0x - %s",
1024 result, Trspi_Error_String(result));
1025 goto done;
1027 if ((result = Tspi_GetPolicyObject(*hSRK, TSS_POLICY_USAGE,
1028 &hPolicy))) {
1029 stlogit("Tspi_GetPolicyObject: 0x%0x - %s",
1030 result, Trspi_Error_String(result));
1031 goto done;
1033 if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
1034 sizeof (wellKnown), wellKnown))) {
1035 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
1036 result, Trspi_Error_String(result));
1037 goto done;
1040 done:
1041 return (result);
1044 static TSS_RESULT
1045 tss_find_and_load_key(TSS_HCONTEXT hContext,
1046 char *keyid, TSS_UUID *uuid, TSS_HKEY hParent,
1047 BYTE *hash, TSS_HKEY *hKey)
1049 TSS_RESULT result;
1051 if (local_uuid_is_null(uuid) &&
1052 find_uuid(keyid, uuid)) {
1053 /* The UUID was not created or saved yet */
1054 return (1);
1056 result = Tspi_Context_GetKeyByUUID(hContext,
1057 TSS_PS_TYPE_USER, *uuid, hKey);
1058 if (result) {
1059 stlogit("Tspi_Context_GetKeyByUUID: 0x%0x - %s",
1060 result, Trspi_Error_String(result));
1061 return (result);
1064 if (hash != NULL) {
1065 result = tss_assign_secret_key_policy(hContext,
1066 TSS_POLICY_USAGE, *hKey, (CK_BYTE *)hash);
1067 if (result)
1068 return (result);
1071 result = Tspi_Key_LoadKey(*hKey, hParent);
1072 if (result)
1073 stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
1074 result, Trspi_Error_String(result));
1076 return (result);
1079 static TSS_RESULT
1080 token_load_public_root_key(TSS_HCONTEXT hContext)
1082 TSS_RESULT result;
1083 TSS_HKEY hSRK;
1085 if (hPublicRootKey != NULL_HKEY)
1086 return (TSS_SUCCESS);
1088 if ((result = token_load_srk(hContext, &hSRK))) {
1089 return (result);
1092 result = tss_find_and_load_key(hContext,
1093 TPMTOK_PUBLIC_ROOT_KEY_ID,
1094 &publicRootKeyUUID, hSRK, NULL, &hPublicRootKey);
1095 if (result)
1096 return (result);
1098 return (result);
1101 static TSS_RESULT
1102 set_legacy_key_params(TSS_HKEY hKey)
1104 TSS_RESULT result;
1106 if ((result = Tspi_SetAttribUint32(hKey,
1107 TSS_TSPATTRIB_KEY_INFO,
1108 TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
1109 TSS_ES_RSAESPKCSV15))) {
1110 stlogit("Tspi_SetAttribUint32: 0x%0x - %s",
1111 result, Trspi_Error_String(result));
1112 return (result);
1115 if ((result = Tspi_SetAttribUint32(hKey,
1116 TSS_TSPATTRIB_KEY_INFO,
1117 TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
1118 TSS_SS_RSASSAPKCS1V15_DER))) {
1119 stlogit("Tspi_SetAttribUint32: 0x%0x - %s",
1120 result, Trspi_Error_String(result));
1121 return (result);
1124 return (result);
1127 static TSS_RESULT
1128 tss_generate_key(TSS_HCONTEXT hContext, TSS_FLAG initFlags, BYTE *passHash,
1129 TSS_HKEY hParentKey, TSS_HKEY *phKey)
1131 TSS_RESULT result;
1132 TSS_HPOLICY hMigPolicy;
1134 if ((result = Tspi_Context_CreateObject(hContext,
1135 TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) {
1136 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
1137 result, Trspi_Error_String(result));
1138 return (result);
1140 result = tss_assign_secret_key_policy(hContext, TSS_POLICY_USAGE,
1141 *phKey, passHash);
1143 if (result) {
1144 Tspi_Context_CloseObject(hContext, *phKey);
1145 return (result);
1148 if (TPMTOK_TSS_KEY_MIG_TYPE(initFlags) == TSS_KEY_MIGRATABLE) {
1149 if ((result = Tspi_Context_CreateObject(hContext,
1150 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION,
1151 &hMigPolicy))) {
1152 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
1153 result, Trspi_Error_String(result));
1154 Tspi_Context_CloseObject(hContext, *phKey);
1155 return (result);
1158 if (passHash == NULL) {
1159 result = Tspi_Policy_SetSecret(hMigPolicy,
1160 TSS_SECRET_MODE_NONE, 0, NULL);
1161 } else {
1162 result = Tspi_Policy_SetSecret(hMigPolicy,
1163 TSS_SECRET_MODE_SHA1, 20, passHash);
1166 if (result != TSS_SUCCESS) {
1167 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
1168 result, Trspi_Error_String(result));
1169 Tspi_Context_CloseObject(hContext, *phKey);
1170 Tspi_Context_CloseObject(hContext, hMigPolicy);
1171 return (result);
1174 if ((result = Tspi_Policy_AssignToObject(hMigPolicy, *phKey))) {
1175 stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s",
1176 result, Trspi_Error_String(result));
1177 Tspi_Context_CloseObject(hContext, *phKey);
1178 Tspi_Context_CloseObject(hContext, hMigPolicy);
1179 return (result);
1183 if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
1184 result = set_legacy_key_params(*phKey);
1185 if (result) {
1186 Tspi_Context_CloseObject(hContext, *phKey);
1187 Tspi_Context_CloseObject(hContext, hMigPolicy);
1188 return (result);
1192 if ((result = Tspi_Key_CreateKey(*phKey, hParentKey, 0))) {
1193 stlogit("Tspi_Key_CreateKey: 0x%0x - %s",
1194 result, Trspi_Error_String(result));
1195 Tspi_Context_CloseObject(hContext, *phKey);
1196 Tspi_Context_CloseObject(hContext, hMigPolicy);
1199 return (result);
1202 static TSS_RESULT
1203 tss_change_auth(
1204 TSS_HCONTEXT hContext,
1205 TSS_HKEY hObjectToChange, TSS_HKEY hParentObject,
1206 TSS_UUID objUUID, TSS_UUID parentUUID,
1207 CK_CHAR *passHash)
1209 TSS_RESULT result;
1210 TSS_HPOLICY hPolicy;
1211 TSS_HKEY oldkey;
1213 if ((result = Tspi_Context_CreateObject(hContext,
1214 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) {
1215 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
1216 result, Trspi_Error_String(result));
1217 return (result);
1220 if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
1221 SHA1_DIGEST_LENGTH, passHash))) {
1222 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
1223 result, Trspi_Error_String(result));
1224 return (result);
1227 if ((result = Tspi_ChangeAuth(hObjectToChange, hParentObject,
1228 hPolicy))) {
1229 stlogit("Tspi_ChangeAuth: 0x%0x - %s",
1230 result, Trspi_Error_String(result));
1233 * Update the PS key by unregistering the key UUID and then
1234 * re-registering with the same UUID. This forces the updated
1235 * auth data associated with the key to be stored in PS so
1236 * the new PIN can be used next time.
1238 if ((result = Tspi_Context_UnregisterKey(hContext,
1239 TSS_PS_TYPE_USER, objUUID, &oldkey)))
1240 stlogit("Tspi_Context_UnregisterKey: 0x%0x - %s",
1241 result, Trspi_Error_String(result));
1243 if ((result = Tspi_Context_RegisterKey(hContext, hObjectToChange,
1244 TSS_PS_TYPE_USER, objUUID, TSS_PS_TYPE_USER, parentUUID)))
1245 stlogit("Tspi_Context_RegisterKey: 0x%0x - %s",
1246 result, Trspi_Error_String(result));
1248 return (result);
1251 static CK_RV
1252 token_generate_leaf_key(TSS_HCONTEXT hContext,
1253 int key_type, CK_CHAR_PTR passHash, TSS_HKEY *phKey)
1255 CK_RV rc = CKR_FUNCTION_FAILED;
1256 TSS_RESULT result;
1257 TSS_HKEY hParentKey;
1258 TSS_UUID newuuid, parentUUID;
1259 char *keyid;
1260 TSS_FLAG initFlags = TSS_KEY_MIGRATABLE |
1261 TSS_KEY_TYPE_BIND | TSS_KEY_SIZE_2048 | TSS_KEY_AUTHORIZATION;
1263 switch (key_type) {
1264 case TPMTOK_PUBLIC_LEAF_KEY:
1265 hParentKey = hPublicRootKey;
1266 keyid = TPMTOK_PUBLIC_LEAF_KEY_ID;
1267 local_uuid_copy(&parentUUID, &publicRootKeyUUID);
1268 break;
1269 case TPMTOK_PRIVATE_LEAF_KEY:
1270 hParentKey = hPrivateRootKey;
1271 keyid = TPMTOK_PRIVATE_LEAF_KEY_ID;
1272 local_uuid_copy(&parentUUID, &privateRootKeyUUID);
1273 break;
1274 default:
1275 stlogit("Unknown key type 0x%0x", key_type);
1276 goto done;
1279 if (result = tss_generate_key(hContext, initFlags, passHash,
1280 hParentKey, phKey)) {
1281 return (rc);
1285 * - generate newUUID
1286 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey,
1287 * USER, newUUID, USER, parentUUID);
1288 * - store newUUID
1290 (void) local_uuid_generate(&newuuid);
1292 result = Tspi_Context_RegisterKey(hContext, *phKey,
1293 TSS_PS_TYPE_USER, newuuid,
1294 TSS_PS_TYPE_USER, parentUUID);
1295 if (result == TSS_SUCCESS) {
1296 int ret;
1298 * Add the UUID to the token UUID index.
1300 ret = add_uuid(keyid, &newuuid);
1302 if (ret)
1303 result = Tspi_Context_UnregisterKey(hContext,
1304 TSS_PS_TYPE_USER, newuuid, phKey);
1305 else
1306 rc = CKR_OK;
1309 done:
1310 return (rc);
1314 * PINs are verified by attempting to bind/unbind random data using a
1315 * TPM resident key that has the PIN being tested assigned as its "secret".
1316 * If the PIN is incorrect, the unbind operation will fail.
1318 static CK_RV
1319 token_verify_pin(TSS_HCONTEXT hContext, TSS_HKEY hKey)
1321 TSS_HENCDATA hEncData;
1322 UINT32 ulUnboundDataLen;
1323 BYTE *rgbUnboundData = NULL;
1324 BYTE rgbData[16];
1325 TSS_RESULT result;
1326 CK_RV rc = CKR_FUNCTION_FAILED;
1328 if ((result = Tspi_Context_CreateObject(hContext,
1329 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
1330 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
1331 result, Trspi_Error_String(result));
1332 goto done;
1335 /* Use some random data */
1336 rc = token_rng(hContext, rgbData, sizeof (rgbData));
1337 if (rc)
1338 goto done;
1340 if ((result = Tspi_Data_Bind(hEncData, hKey,
1341 sizeof (rgbData), rgbData))) {
1342 stlogit("Tspi_Data_Bind: 0x%0x - %s",
1343 result, Trspi_Error_String(result));
1344 goto done;
1347 /* unbind the junk data to test the key's auth data */
1348 result = Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen,
1349 &rgbUnboundData);
1350 if (result == TPM_E_AUTHFAIL) {
1351 rc = CKR_PIN_INCORRECT;
1352 stlogit("Tspi_Data_Unbind: 0x%0x - %s",
1353 result, Trspi_Error_String(result));
1354 goto done;
1355 } else if (result != TSS_SUCCESS) {
1356 stlogit("Tspi_Data_Unbind: 0x%0x - %s",
1357 result, Trspi_Error_String(result));
1358 rc = CKR_FUNCTION_FAILED;
1359 goto done;
1362 if (memcmp(rgbUnboundData, rgbData, ulUnboundDataLen))
1363 rc = CKR_PIN_INCORRECT;
1364 else
1365 rc = CKR_OK;
1367 done:
1368 if (rgbUnboundData != NULL)
1369 Tspi_Context_FreeMemory(hContext, rgbUnboundData);
1370 Tspi_Context_CloseObject(hContext, hEncData);
1371 return (rc);
1374 static CK_RV
1375 token_create_private_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash)
1377 CK_RV rc;
1378 TSS_RESULT result;
1379 int ret;
1380 TSS_FLAG initFlags = TSS_KEY_SIZE_2048 |
1381 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE;
1382 TSS_UUID SRK_UUID = TSS_UUID_SRK;
1383 TSS_HKEY hSRK;
1385 if (token_load_srk(hContext, &hSRK))
1386 return (CKR_FUNCTION_FAILED);
1389 * - create UUID privateRootKeyUUID
1390 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey,
1391 * USER, privateRootKeyUUID, system, UUID_SRK);
1392 * - store privateRootKeyUUID in users private token space.
1394 if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK,
1395 &hPrivateRootKey))) {
1396 return (result);
1398 if (local_uuid_is_null(&privateRootKeyUUID))
1399 local_uuid_generate(&privateRootKeyUUID);
1401 result = Tspi_Context_RegisterKey(hContext, hPrivateRootKey,
1402 TSS_PS_TYPE_USER, privateRootKeyUUID,
1403 TSS_PS_TYPE_SYSTEM, SRK_UUID);
1405 if (result) {
1406 local_uuid_clear(&privateRootKeyUUID);
1407 return (result);
1410 ret = add_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, &privateRootKeyUUID);
1411 if (ret) {
1412 result = Tspi_Context_UnregisterKey(hContext,
1413 TSS_PS_TYPE_USER, privateRootKeyUUID,
1414 &hPrivateRootKey);
1415 return (CKR_FUNCTION_FAILED);
1418 if ((result = Tspi_Key_LoadKey(hPrivateRootKey, hSRK))) {
1419 stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
1420 result, Trspi_Error_String(result));
1421 Tspi_Context_CloseObject(hContext, hPrivateRootKey);
1423 (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID);
1424 local_uuid_clear(&privateRootKeyUUID);
1426 hPrivateRootKey = NULL_HKEY;
1427 return (CKR_FUNCTION_FAILED);
1431 /* generate the private leaf key */
1432 if ((rc = token_generate_leaf_key(hContext,
1433 TPMTOK_PRIVATE_LEAF_KEY,
1434 pinHash, &hPrivateLeafKey))) {
1435 return (rc);
1438 if ((result = Tspi_Key_LoadKey(hPrivateLeafKey, hPrivateRootKey))) {
1439 stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
1440 result, Trspi_Error_String(result));
1442 (void) Tspi_Context_UnregisterKey(hContext,
1443 TSS_PS_TYPE_USER, privateLeafKeyUUID,
1444 &hPrivateLeafKey);
1445 (void) remove_uuid(TPMTOK_PRIVATE_LEAF_KEY_ID);
1446 local_uuid_clear(&privateLeafKeyUUID);
1448 (void) Tspi_Context_UnregisterKey(hContext,
1449 TSS_PS_TYPE_USER, privateRootKeyUUID,
1450 &hPrivateRootKey);
1451 (void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID);
1452 local_uuid_clear(&privateRootKeyUUID);
1454 Tspi_Context_CloseObject(hContext, hPrivateRootKey);
1455 hPrivateRootKey = NULL_HKEY;
1457 Tspi_Context_CloseObject(hContext, hPrivateLeafKey);
1458 hPrivateRootKey = NULL_HKEY;
1460 return (CKR_FUNCTION_FAILED);
1462 return (rc);
1465 static CK_RV
1466 token_create_public_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash)
1468 CK_RV rc;
1469 TSS_RESULT result;
1470 int ret;
1471 TSS_FLAG initFlags = TSS_KEY_SIZE_2048 |
1472 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE;
1473 TSS_UUID srk_uuid = TSS_UUID_SRK;
1474 TSS_HKEY hSRK;
1476 if (token_load_srk(hContext, &hSRK))
1477 return (CKR_FUNCTION_FAILED);
1480 * - create publicRootKeyUUID
1481 * - Tspi_Context_RegisterKey(hContext, hPublicRootKey,
1482 * USER, publicRootKeyUUID, system, UUID_SRK);
1483 * - store publicRootKeyUUID in users private token space.
1485 if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK,
1486 &hPublicRootKey))) {
1487 return (CKR_FUNCTION_FAILED);
1489 if (local_uuid_is_null(&publicRootKeyUUID))
1490 local_uuid_generate(&publicRootKeyUUID);
1492 result = Tspi_Context_RegisterKey(hContext, hPublicRootKey,
1493 TSS_PS_TYPE_USER, publicRootKeyUUID,
1494 TSS_PS_TYPE_SYSTEM, srk_uuid);
1496 if (result) {
1497 local_uuid_clear(&publicRootKeyUUID);
1498 return (CKR_FUNCTION_FAILED);
1501 ret = add_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID);
1502 if (ret) {
1503 result = Tspi_Context_UnregisterKey(hContext,
1504 TSS_PS_TYPE_USER, publicRootKeyUUID,
1505 &hPublicRootKey);
1506 /* does result matter here? */
1507 return (CKR_FUNCTION_FAILED);
1510 /* Load the newly created publicRootKey into the TPM using the SRK */
1511 if ((result = Tspi_Key_LoadKey(hPublicRootKey, hSRK))) {
1512 stlogit("Tspi_Key_LoadKey: 0x%x - %s", result,
1513 Trspi_Error_String(result));
1514 Tspi_Context_CloseObject(hContext, hPublicRootKey);
1515 hPublicRootKey = NULL_HKEY;
1516 return (CKR_FUNCTION_FAILED);
1519 /* create the SO's leaf key */
1520 if ((rc = token_generate_leaf_key(hContext, TPMTOK_PUBLIC_LEAF_KEY,
1521 pinHash, &hPublicLeafKey))) {
1522 return (rc);
1525 if ((result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey))) {
1526 stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
1527 result, Trspi_Error_String(result));
1529 /* Unregister keys and clear UUIDs */
1530 (void) Tspi_Context_UnregisterKey(hContext,
1531 TSS_PS_TYPE_USER, publicLeafKeyUUID,
1532 &hPublicLeafKey);
1533 (void) remove_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID);
1535 (void) Tspi_Context_UnregisterKey(hContext,
1536 TSS_PS_TYPE_USER, publicRootKeyUUID,
1537 &hPublicRootKey);
1538 (void) remove_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID);
1540 Tspi_Context_CloseObject(hContext, hPublicRootKey);
1541 hPublicRootKey = NULL_HKEY;
1543 Tspi_Context_CloseObject(hContext, hPublicLeafKey);
1544 hPublicLeafKey = NULL_HKEY;
1546 return (CKR_FUNCTION_FAILED);
1549 return (rc);
1552 CK_RV
1553 token_specific_login(
1554 TSS_HCONTEXT hContext,
1555 CK_USER_TYPE userType,
1556 CK_CHAR_PTR pPin,
1557 CK_ULONG ulPinLen)
1559 CK_RV rc;
1560 CK_BYTE hash_sha[SHA1_DIGEST_LENGTH];
1561 TSS_RESULT result;
1562 TSS_HKEY hSRK;
1564 /* Make sure the SRK is loaded into the TPM */
1565 if ((result = token_load_srk(hContext, &hSRK))) {
1566 return (CKR_FUNCTION_FAILED);
1569 if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) {
1570 return (CKR_FUNCTION_FAILED);
1573 if (userType == CKU_USER) {
1575 * If the public root key doesn't exist yet,
1576 * the SO hasn't init'd the token.
1578 if ((result = token_load_public_root_key(hContext))) {
1579 if (result == TPM_E_DECRYPT_ERROR) {
1580 return (CKR_USER_PIN_NOT_INITIALIZED);
1585 * - find privateRootKeyUUID
1586 * - load by UUID (SRK parent)
1588 if (local_uuid_is_null(&privateRootKeyUUID) &&
1589 find_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID,
1590 &privateRootKeyUUID)) {
1591 if (memcmp(hash_sha,
1592 default_user_pin_sha,
1593 SHA1_DIGEST_LENGTH))
1594 return (CKR_PIN_INCORRECT);
1596 not_initialized = 1;
1597 return (CKR_OK);
1600 if ((rc = verify_user_pin(hContext, hash_sha))) {
1601 return (rc);
1604 (void) memcpy(current_user_pin_sha, hash_sha,
1605 SHA1_DIGEST_LENGTH);
1607 rc = load_private_token_objects(hContext);
1608 if (rc == CKR_OK) {
1609 (void) XProcLock(xproclock);
1610 global_shm->priv_loaded = TRUE;
1611 (void) XProcUnLock(xproclock);
1613 } else {
1615 * SO login logic:
1617 * - find publicRootKey UUID
1618 * - load by UUID wrap with hSRK from above
1620 if (local_uuid_is_null(&publicRootKeyUUID) &&
1621 find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID,
1622 &publicRootKeyUUID)) {
1623 if (memcmp(hash_sha,
1624 default_so_pin_sha,
1625 SHA1_DIGEST_LENGTH))
1626 return (CKR_PIN_INCORRECT);
1628 not_initialized = 1;
1629 return (CKR_OK);
1632 if (hPublicRootKey == NULL_HKEY) {
1633 result = tss_find_and_load_key(
1634 hContext,
1635 TPMTOK_PUBLIC_ROOT_KEY_ID,
1636 &publicRootKeyUUID, hSRK, NULL,
1637 &hPublicRootKey);
1639 if (result)
1640 return (CKR_FUNCTION_FAILED);
1643 /* find, load the public leaf key */
1644 if (hPublicLeafKey == NULL_HKEY) {
1645 result = tss_find_and_load_key(
1646 hContext,
1647 TPMTOK_PUBLIC_LEAF_KEY_ID,
1648 &publicLeafKeyUUID, hPublicRootKey, hash_sha,
1649 &hPublicLeafKey);
1650 if (result)
1651 return (CKR_FUNCTION_FAILED);
1654 if ((rc = token_verify_pin(hContext, hPublicLeafKey))) {
1655 return (rc);
1658 (void) memcpy(current_so_pin_sha, hash_sha, SHA1_DIGEST_LENGTH);
1661 return (rc);
1664 CK_RV
1665 token_specific_logout(TSS_HCONTEXT hContext)
1667 if (hPrivateLeafKey != NULL_HKEY) {
1668 Tspi_Key_UnloadKey(hPrivateLeafKey);
1669 hPrivateLeafKey = NULL_HKEY;
1670 } else if (hPublicLeafKey != NULL_HKEY) {
1671 Tspi_Key_UnloadKey(hPublicLeafKey);
1672 hPublicLeafKey = NULL_HKEY;
1675 local_uuid_clear(&publicRootKeyUUID);
1676 local_uuid_clear(&publicLeafKeyUUID);
1677 local_uuid_clear(&privateRootKeyUUID);
1678 local_uuid_clear(&privateLeafKeyUUID);
1680 (void) memset(current_so_pin_sha, 0, SHA1_DIGEST_LENGTH);
1681 (void) memset(current_user_pin_sha, 0, SHA1_DIGEST_LENGTH);
1683 (void) object_mgr_purge_private_token_objects(hContext);
1685 return (CKR_OK);
1688 /*ARGSUSED*/
1689 CK_RV
1690 token_specific_init_pin(TSS_HCONTEXT hContext,
1691 CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
1694 * Since the SO must log in before calling C_InitPIN, we will
1695 * be able to return (CKR_OK) automatically here.
1696 * This is because the USER key structure is created at the
1697 * time of their first login, not at C_InitPIN time.
1699 return (CKR_OK);
1702 static CK_RV
1703 check_pin_properties(CK_USER_TYPE userType, CK_BYTE *pinHash,
1704 CK_ULONG ulPinLen)
1706 /* make sure the new PIN is different */
1707 if (userType == CKU_USER) {
1708 if (!memcmp(pinHash, default_user_pin_sha,
1709 SHA1_DIGEST_LENGTH)) {
1710 LogError1("new PIN must not be the default");
1711 return (CKR_PIN_INVALID);
1713 } else {
1714 if (!memcmp(pinHash, default_so_pin_sha,
1715 SHA1_DIGEST_LENGTH)) {
1716 LogError1("new PIN must not be the default");
1717 return (CKR_PIN_INVALID);
1721 if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) {
1722 LogError1("New PIN is out of size range");
1723 return (CKR_PIN_LEN_RANGE);
1726 return (CKR_OK);
1730 * This function is called from set_pin only, where a non-logged-in public
1731 * session can provide the user pin which must be verified. This function
1732 * assumes that the pin has already been set once, so there's no migration
1733 * path option or checking of the default user pin.
1735 static CK_RV
1736 verify_user_pin(TSS_HCONTEXT hContext, CK_BYTE *hash_sha)
1738 CK_RV rc;
1739 TSS_RESULT result;
1740 TSS_HKEY hSRK;
1742 if (token_load_srk(hContext, &hSRK))
1743 return (CKR_FUNCTION_FAILED);
1746 * Verify the user by loading the privateLeafKey
1747 * into the TPM (if it's not already) and then
1748 * call the verify_pin operation.
1750 * The hashed PIN is assigned to the private leaf key.
1751 * If it is incorrect (not the same as the one originally
1752 * used when the key was created), the verify operation
1753 * will fail.
1755 if (hPrivateRootKey == NULL_HKEY) {
1756 result = tss_find_and_load_key(
1757 hContext,
1758 TPMTOK_PRIVATE_ROOT_KEY_ID,
1759 &privateRootKeyUUID, hSRK, NULL, &hPrivateRootKey);
1760 if (result)
1761 return (CKR_FUNCTION_FAILED);
1764 if (hPrivateLeafKey == NULL_HKEY) {
1765 result = tss_find_and_load_key(
1766 hContext,
1767 TPMTOK_PRIVATE_LEAF_KEY_ID,
1768 &privateLeafKeyUUID, hPrivateRootKey, hash_sha,
1769 &hPrivateLeafKey);
1771 if (result)
1772 return (CKR_FUNCTION_FAILED);
1776 * Verify that the PIN is correct by attempting to wrap/unwrap some
1777 * random data.
1779 if ((rc = token_verify_pin(hContext, hPrivateLeafKey))) {
1780 return (rc);
1783 return (CKR_OK);
1786 CK_RV
1787 token_specific_set_pin(ST_SESSION_HANDLE session,
1788 CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
1789 CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
1791 SESSION *sess = session_mgr_find(session.sessionh);
1792 CK_BYTE oldpin_hash[SHA1_DIGEST_LENGTH];
1793 CK_BYTE newpin_hash[SHA1_DIGEST_LENGTH];
1794 CK_RV rc;
1795 TSS_HKEY hSRK;
1797 if (!sess) {
1798 return (CKR_SESSION_HANDLE_INVALID);
1801 if ((rc = compute_sha(pOldPin, ulOldPinLen, oldpin_hash))) {
1802 return (CKR_FUNCTION_FAILED);
1804 if ((rc = compute_sha(pNewPin, ulNewPinLen, newpin_hash))) {
1805 return (CKR_FUNCTION_FAILED);
1808 if (token_load_srk(sess->hContext, &hSRK)) {
1809 return (CKR_FUNCTION_FAILED);
1813 * From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of
1814 * the user that is currently logged in, or the CKU_USER PIN
1815 * if the session is not logged in."
1816 * A non R/W session fails with CKR_SESSION_READ_ONLY.
1818 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS ||
1819 sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
1820 if (not_initialized) {
1821 if (memcmp(oldpin_hash, default_user_pin_sha,
1822 SHA1_DIGEST_LENGTH)) {
1823 return (CKR_PIN_INCORRECT);
1826 if ((rc = check_pin_properties(CKU_USER, newpin_hash,
1827 ulNewPinLen))) {
1828 return (rc);
1831 if ((rc = token_create_private_tree(sess->hContext,
1832 newpin_hash))) {
1833 return (CKR_FUNCTION_FAILED);
1836 nv_token_data->token_info.flags &=
1837 ~(CKF_USER_PIN_TO_BE_CHANGED);
1838 nv_token_data->token_info.flags |=
1839 CKF_USER_PIN_INITIALIZED;
1841 nv_token_data->token_info.flags &=
1842 ~(CKF_USER_PIN_TO_BE_CHANGED);
1843 nv_token_data->token_info.flags |=
1844 CKF_USER_PIN_INITIALIZED;
1846 return (save_token_data(nv_token_data));
1849 if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) {
1850 /* if we're already logged in, just verify the hash */
1851 if (memcmp(current_user_pin_sha, oldpin_hash,
1852 SHA1_DIGEST_LENGTH)) {
1853 return (CKR_PIN_INCORRECT);
1855 } else {
1856 if ((rc = verify_user_pin(sess->hContext,
1857 oldpin_hash))) {
1858 return (rc);
1862 if ((rc = check_pin_properties(CKU_USER, newpin_hash,
1863 ulNewPinLen)))
1864 return (rc);
1866 /* change the auth on the TSS object */
1867 if (tss_change_auth(sess->hContext,
1868 hPrivateLeafKey, hPrivateRootKey,
1869 privateLeafKeyUUID, privateRootKeyUUID,
1870 newpin_hash))
1871 return (CKR_FUNCTION_FAILED);
1873 } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
1874 if (not_initialized) {
1875 if (memcmp(default_so_pin_sha, oldpin_hash,
1876 SHA1_DIGEST_LENGTH))
1877 return (CKR_PIN_INCORRECT);
1879 if ((rc = check_pin_properties(CKU_SO,
1880 newpin_hash, ulNewPinLen)))
1881 return (rc);
1883 if ((rc = token_create_public_tree(sess->hContext,
1884 newpin_hash)))
1885 return (CKR_FUNCTION_FAILED);
1887 nv_token_data->token_info.flags &=
1888 ~(CKF_SO_PIN_TO_BE_CHANGED);
1890 return (save_token_data(nv_token_data));
1893 if (memcmp(current_so_pin_sha, oldpin_hash,
1894 SHA1_DIGEST_LENGTH))
1895 return (CKR_PIN_INCORRECT);
1897 if ((rc = check_pin_properties(CKU_SO, newpin_hash,
1898 ulNewPinLen)))
1899 return (rc);
1901 /* change auth on the SO's leaf key */
1902 if (tss_change_auth(sess->hContext,
1903 hPublicLeafKey, hPublicRootKey,
1904 publicLeafKeyUUID, publicRootKeyUUID,
1905 newpin_hash))
1906 return (CKR_FUNCTION_FAILED);
1908 } else {
1909 rc = CKR_SESSION_READ_ONLY;
1912 return (rc);
1915 /* only called at token init time */
1916 CK_RV
1917 token_specific_verify_so_pin(TSS_HCONTEXT hContext, CK_CHAR_PTR pPin,
1918 CK_ULONG ulPinLen)
1920 CK_BYTE hash_sha[SHA1_DIGEST_LENGTH];
1921 CK_RV rc;
1922 TSS_RESULT result;
1923 TSS_HKEY hSRK;
1925 if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) {
1926 return (CKR_FUNCTION_FAILED);
1928 if ((rc = token_load_srk(hContext, &hSRK))) {
1929 return (CKR_FUNCTION_FAILED);
1933 * TRYME INSTEAD:
1934 * - find publicRootKeyUUID
1935 * - Load publicRootKey by UUID (SRK parent)
1936 * - find publicLeafKeyUUID
1937 * - Load publicLeafKey by UUID (publicRootKey parent)
1938 * - set password policy on publicLeafKey
1940 if (local_uuid_is_null(&publicRootKeyUUID) &&
1941 find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID)) {
1943 * The SO hasn't set their PIN yet, compare the
1944 * login pin with the hard-coded value.
1946 if (memcmp(default_so_pin_sha, hash_sha,
1947 SHA1_DIGEST_LENGTH)) {
1948 return (CKR_PIN_INCORRECT);
1950 return (CKR_OK);
1953 result = Tspi_Context_GetKeyByUUID(hContext,
1954 TSS_PS_TYPE_USER, publicRootKeyUUID, &hPublicRootKey);
1956 if (result)
1957 return (CKR_FUNCTION_FAILED);
1959 result = Tspi_Key_LoadKey(hPublicRootKey, hSRK);
1960 if (result)
1961 return (CKR_FUNCTION_FAILED);
1963 if (local_uuid_is_null(&publicLeafKeyUUID) &&
1964 find_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID, &publicLeafKeyUUID))
1965 return (CKR_FUNCTION_FAILED);
1967 result = Tspi_Context_GetKeyByUUID(hContext,
1968 TSS_PS_TYPE_USER, publicLeafKeyUUID, &hPublicLeafKey);
1969 if (result)
1970 return (CKR_FUNCTION_FAILED);
1972 result = tss_assign_secret_key_policy(hContext, TSS_POLICY_USAGE,
1973 hPublicLeafKey, hash_sha);
1974 if (result)
1975 return (CKR_FUNCTION_FAILED);
1977 result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey);
1978 if (result)
1979 return (CKR_FUNCTION_FAILED);
1981 /* If the hash given is wrong, the verify will fail */
1982 if ((rc = token_verify_pin(hContext, hPublicLeafKey))) {
1983 return (rc);
1986 return (CKR_OK);
1989 CK_RV
1990 token_specific_final(TSS_HCONTEXT hContext)
1992 if (hPublicRootKey != NULL_HKEY) {
1993 Tspi_Context_CloseObject(hContext, hPublicRootKey);
1994 hPublicRootKey = NULL_HKEY;
1996 if (hPublicLeafKey != NULL_HKEY) {
1997 Tspi_Context_CloseObject(hContext, hPublicLeafKey);
1998 hPublicLeafKey = NULL_HKEY;
2000 if (hPrivateRootKey != NULL_HKEY) {
2001 Tspi_Context_CloseObject(hContext, hPrivateRootKey);
2002 hPrivateRootKey = NULL_HKEY;
2004 if (hPrivateLeafKey != NULL_HKEY) {
2005 Tspi_Context_CloseObject(hContext, hPrivateLeafKey);
2006 hPrivateLeafKey = NULL_HKEY;
2008 return (CKR_OK);
2012 * Wrap the 20 bytes of auth data and store in an attribute of the two
2013 * keys.
2015 static CK_RV
2016 token_wrap_auth_data(TSS_HCONTEXT hContext,
2017 CK_BYTE *authData, TEMPLATE *publ_tmpl,
2018 TEMPLATE *priv_tmpl)
2020 CK_RV rc;
2021 CK_ATTRIBUTE *new_attr;
2023 TSS_RESULT ret;
2024 TSS_HKEY hParentKey;
2025 TSS_HENCDATA hEncData;
2026 BYTE *blob;
2027 UINT32 blob_size;
2029 if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) {
2030 return (CKR_FUNCTION_FAILED);
2031 } else if (hPublicLeafKey != NULL_HKEY) {
2032 hParentKey = hPublicLeafKey;
2033 } else {
2034 hParentKey = hPrivateLeafKey;
2037 /* create the encrypted data object */
2038 if ((ret = Tspi_Context_CreateObject(hContext,
2039 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
2040 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
2041 ret, Trspi_Error_String(ret));
2042 return (CKR_FUNCTION_FAILED);
2045 if ((ret = Tspi_Data_Bind(hEncData, hParentKey, SHA1_DIGEST_LENGTH,
2046 authData))) {
2047 stlogit("Tspi_Data_Bind: 0x%0x - %s",
2048 ret, Trspi_Error_String(ret));
2049 return (CKR_FUNCTION_FAILED);
2052 /* pull the encrypted data out of the encrypted data object */
2053 if ((ret = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
2054 TSS_TSPATTRIB_ENCDATABLOB_BLOB, &blob_size, &blob))) {
2055 stlogit("Tspi_SetAttribData: 0x%0x - %s",
2056 ret, Trspi_Error_String(ret));
2057 return (CKR_FUNCTION_FAILED);
2060 if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size,
2061 &new_attr))) {
2062 return (rc);
2064 (void) template_update_attribute(publ_tmpl, new_attr);
2066 if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob,
2067 blob_size, &new_attr))) {
2068 return (rc);
2070 (void) template_update_attribute(priv_tmpl, new_attr);
2072 return (rc);
2075 static CK_RV
2076 token_unwrap_auth_data(TSS_HCONTEXT hContext, CK_BYTE *encAuthData,
2077 CK_ULONG encAuthDataLen, TSS_HKEY hKey,
2078 BYTE **authData)
2080 TSS_RESULT result;
2081 TSS_HENCDATA hEncData;
2082 BYTE *buf;
2083 UINT32 buf_size;
2085 if ((result = Tspi_Context_CreateObject(hContext,
2086 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
2087 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
2088 result, Trspi_Error_String(result));
2089 return (CKR_FUNCTION_FAILED);
2092 if ((result = Tspi_SetAttribData(hEncData,
2093 TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB,
2094 encAuthDataLen, encAuthData))) {
2095 stlogit("Tspi_SetAttribData: 0x%0x - %s",
2096 result, Trspi_Error_String(result));
2097 return (CKR_FUNCTION_FAILED);
2100 /* unbind the data, receiving the plaintext back */
2101 if ((result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf))) {
2102 stlogit("Tspi_Data_Unbind: 0x%0x - %s",
2103 result, Trspi_Error_String(result));
2104 return (CKR_FUNCTION_FAILED);
2107 if (buf_size != SHA1_DIGEST_LENGTH) {
2108 return (CKR_FUNCTION_FAILED);
2111 *authData = buf;
2113 return (CKR_OK);
2116 CK_RV
2117 token_specific_rsa_generate_keypair(
2118 TSS_HCONTEXT hContext,
2119 TEMPLATE *publ_tmpl,
2120 TEMPLATE *priv_tmpl)
2122 CK_ATTRIBUTE *attr = NULL;
2123 CK_ULONG mod_bits = 0;
2124 CK_BBOOL flag;
2125 CK_RV rc;
2127 TSS_FLAG initFlags = 0;
2128 BYTE authHash[SHA1_DIGEST_LENGTH];
2129 BYTE *authData = NULL;
2130 TSS_HKEY hKey = NULL_HKEY;
2131 TSS_HKEY hParentKey = NULL_HKEY;
2132 TSS_RESULT result;
2133 UINT32 ulBlobLen;
2134 BYTE *rgbBlob;
2136 /* Make sure the public exponent is usable */
2137 if ((util_check_public_exponent(publ_tmpl))) {
2138 return (CKR_TEMPLATE_INCONSISTENT);
2141 flag = template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr);
2142 if (!flag) {
2143 return (CKR_TEMPLATE_INCOMPLETE);
2145 mod_bits = *(CK_ULONG *)attr->pValue;
2147 if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) {
2148 return (CKR_KEY_SIZE_RANGE);
2152 * If we're not logged in, hPrivateLeafKey and hPublicLeafKey
2153 * should be NULL.
2155 if ((hPrivateLeafKey == NULL_HKEY) &&
2156 (hPublicLeafKey == NULL_HKEY)) {
2157 /* public session, wrap key with the PRK */
2158 initFlags |= TSS_KEY_TYPE_LEGACY |
2159 TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE;
2161 if ((result = token_load_public_root_key(hContext))) {
2162 return (CKR_FUNCTION_FAILED);
2165 hParentKey = hPublicRootKey;
2166 } else if (hPrivateLeafKey != NULL_HKEY) {
2167 /* logged in USER session */
2168 initFlags |= TSS_KEY_TYPE_LEGACY |
2169 TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
2171 /* get a random SHA1 hash for the auth data */
2172 if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) {
2173 return (CKR_FUNCTION_FAILED);
2176 authData = authHash;
2177 hParentKey = hPrivateRootKey;
2178 } else {
2179 /* logged in SO session */
2180 initFlags |= TSS_KEY_TYPE_LEGACY |
2181 TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
2183 /* get a random SHA1 hash for the auth data */
2184 if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) {
2185 return (CKR_FUNCTION_FAILED);
2188 authData = authHash;
2189 hParentKey = hPublicRootKey;
2192 if ((result = tss_generate_key(hContext, initFlags, authData,
2193 hParentKey, &hKey))) {
2194 return (result);
2197 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
2198 TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) {
2199 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2200 result, Trspi_Error_String(result));
2201 return (CKR_FUNCTION_FAILED);
2204 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob,
2205 ulBlobLen, &attr))) {
2206 Tspi_Context_FreeMemory(hContext, rgbBlob);
2207 return (rc);
2209 (void) template_update_attribute(priv_tmpl, attr);
2210 if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob,
2211 ulBlobLen, &attr))) {
2212 Tspi_Context_FreeMemory(hContext, rgbBlob);
2213 return (rc);
2215 (void) template_update_attribute(publ_tmpl, attr);
2217 Tspi_Context_FreeMemory(hContext, rgbBlob);
2219 /* grab the public key to put into the public key object */
2220 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
2221 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &ulBlobLen, &rgbBlob))) {
2222 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2223 result, Trspi_Error_String(result));
2224 return (result);
2227 /* add the public key blob to the object template */
2228 if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) {
2229 Tspi_Context_FreeMemory(hContext, rgbBlob);
2230 return (rc);
2232 (void) template_update_attribute(publ_tmpl, attr);
2234 /* add the public key blob to the object template */
2235 if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) {
2236 Tspi_Context_FreeMemory(hContext, rgbBlob);
2237 return (rc);
2239 (void) template_update_attribute(priv_tmpl, attr);
2240 Tspi_Context_FreeMemory(hContext, rgbBlob);
2242 /* wrap the authdata and put it into an object */
2243 if (authData != NULL) {
2244 rc = token_wrap_auth_data(hContext, authData, publ_tmpl,
2245 priv_tmpl);
2248 return (rc);
2251 static CK_RV
2252 token_rsa_load_key(
2253 TSS_HCONTEXT hContext,
2254 OBJECT *key_obj,
2255 TSS_HKEY *phKey)
2257 TSS_RESULT result;
2258 TSS_HPOLICY hPolicy = NULL_HPOLICY;
2259 TSS_HKEY hParentKey;
2260 BYTE *authData = NULL;
2261 CK_ATTRIBUTE *attr;
2262 CK_RV rc;
2263 CK_OBJECT_HANDLE handle;
2264 CK_ULONG class;
2266 if (hPrivateLeafKey != NULL_HKEY) {
2267 hParentKey = hPrivateRootKey;
2268 } else {
2269 if ((result = token_load_public_root_key(hContext)))
2270 return (CKR_FUNCTION_FAILED);
2272 hParentKey = hPublicRootKey;
2275 *phKey = NULL;
2276 if (template_attribute_find(key_obj->template, CKA_CLASS,
2277 &attr) == FALSE) {
2278 return (CKR_TEMPLATE_INCOMPLETE);
2280 class = *((CK_ULONG *)attr->pValue);
2282 rc = template_attribute_find(key_obj->template,
2283 CKA_IBM_OPAQUE, &attr);
2285 * A public key cannot use the OPAQUE data attribute so they
2286 * must be created in software. A private key may not yet
2287 * have its "opaque" data defined and needs to be created
2288 * and loaded so it can be used inside the TPM.
2290 if (class == CKO_PUBLIC_KEY || rc == FALSE) {
2291 rc = object_mgr_find_in_map2(hContext, key_obj, &handle);
2292 if (rc != CKR_OK)
2293 return (CKR_FUNCTION_FAILED);
2295 if ((rc = token_load_key(hContext,
2296 handle, hParentKey, NULL, phKey))) {
2297 return (rc);
2301 * If this is a private key, get the blob and load it in the TPM.
2302 * If it is public, the key is already loaded in software.
2304 if (class == CKO_PRIVATE_KEY) {
2305 /* If we already have a handle, just load it */
2306 if (*phKey != NULL) {
2307 result = Tspi_Key_LoadKey(*phKey, hParentKey);
2308 if (result) {
2309 stlogit("Tspi_Context_LoadKeyByBlob: "
2310 "0x%0x - %s",
2311 result, Trspi_Error_String(result));
2312 return (CKR_FUNCTION_FAILED);
2314 } else {
2315 /* try again to get the CKA_IBM_OPAQUE attr */
2316 if ((rc = template_attribute_find(key_obj->template,
2317 CKA_IBM_OPAQUE, &attr)) == FALSE) {
2318 return (rc);
2320 if ((result = Tspi_Context_LoadKeyByBlob(hContext,
2321 hParentKey, attr->ulValueLen, attr->pValue,
2322 phKey))) {
2323 stlogit("Tspi_Context_LoadKeyByBlob: "
2324 "0x%0x - %s",
2325 result, Trspi_Error_String(result));
2326 return (CKR_FUNCTION_FAILED);
2331 /* auth data may be required */
2332 if (template_attribute_find(key_obj->template, CKA_ENC_AUTHDATA,
2333 &attr) == TRUE && attr) {
2334 if ((hPrivateLeafKey == NULL_HKEY) &&
2335 (hPublicLeafKey == NULL_HKEY)) {
2336 return (CKR_FUNCTION_FAILED);
2337 } else if (hPublicLeafKey != NULL_HKEY) {
2338 hParentKey = hPublicLeafKey;
2339 } else {
2340 hParentKey = hPrivateLeafKey;
2343 if ((result = token_unwrap_auth_data(hContext,
2344 attr->pValue, attr->ulValueLen,
2345 hParentKey, &authData))) {
2346 return (CKR_FUNCTION_FAILED);
2349 if ((result = Tspi_GetPolicyObject(*phKey,
2350 TSS_POLICY_USAGE, &hPolicy))) {
2351 stlogit("Tspi_GetPolicyObject: 0x%0x - %s",
2352 result, Trspi_Error_String(result));
2353 return (CKR_FUNCTION_FAILED);
2357 * If the policy handle returned is the same as the
2358 * context's default policy, then a new policy must
2359 * be created and assigned to the key. Otherwise, just set the
2360 * secret in the policy.
2362 if (hPolicy == hDefaultPolicy) {
2363 if ((result = Tspi_Context_CreateObject(hContext,
2364 TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE,
2365 &hPolicy))) {
2366 stlogit("Tspi_Context_CreateObject: "
2367 "0x%0x - %s",
2368 result, Trspi_Error_String(result));
2369 return (CKR_FUNCTION_FAILED);
2372 if ((result = Tspi_Policy_SetSecret(hPolicy,
2373 TSS_SECRET_MODE_SHA1,
2374 SHA1_DIGEST_LENGTH, authData))) {
2375 stlogit("Tspi_Policy_SetSecret: "
2376 "0x%0x - %s",
2377 result, Trspi_Error_String(result));
2378 return (CKR_FUNCTION_FAILED);
2381 if ((result = Tspi_Policy_AssignToObject(hPolicy,
2382 *phKey))) {
2383 stlogit("Tspi_Policy_AssignToObject: "
2384 "0x%0x - %s",
2385 result, Trspi_Error_String(result));
2386 return (CKR_FUNCTION_FAILED);
2388 } else if ((result = Tspi_Policy_SetSecret(hPolicy,
2389 TSS_SECRET_MODE_SHA1, SHA1_DIGEST_LENGTH, authData))) {
2390 stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
2391 result, Trspi_Error_String(result));
2392 return (CKR_FUNCTION_FAILED);
2395 Tspi_Context_FreeMemory(hContext, authData);
2398 return (CKR_OK);
2401 CK_RV
2402 tpm_decrypt_data(
2403 TSS_HCONTEXT hContext,
2404 TSS_HKEY hKey,
2405 CK_BYTE * in_data,
2406 CK_ULONG in_data_len,
2407 CK_BYTE * out_data,
2408 CK_ULONG * out_data_len)
2410 TSS_RESULT result;
2411 TSS_HENCDATA hEncData = NULL_HENCDATA;
2412 UINT32 buf_size = 0, modLen;
2413 BYTE *buf = NULL, *modulus = NULL;
2414 CK_ULONG chunklen, remain, outlen;
2416 /* push the data into the encrypted data object */
2417 if ((result = Tspi_Context_CreateObject(hContext,
2418 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
2419 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
2420 result, Trspi_Error_String(result));
2421 return (CKR_FUNCTION_FAILED);
2425 * Figure out the modulus size so we can break the data
2426 * into smaller chunks if necessary.
2428 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
2429 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
2430 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2431 result, Trspi_Error_String(result));
2432 return (result);
2434 /* we don't need the actual modulus */
2435 Tspi_Context_FreeMemory(hContext, modulus);
2437 chunklen = (in_data_len > modLen ? modLen : in_data_len);
2438 remain = in_data_len;
2439 outlen = 0;
2441 while (remain > 0) {
2442 if ((result = Tspi_SetAttribData(hEncData,
2443 TSS_TSPATTRIB_ENCDATA_BLOB,
2444 TSS_TSPATTRIB_ENCDATABLOB_BLOB,
2445 chunklen, in_data))) {
2446 stlogit("Tspi_SetAttribData: 0x%0x - %s",
2447 result, Trspi_Error_String(result));
2448 return (CKR_FUNCTION_FAILED);
2451 /* unbind the data, receiving the plaintext back */
2452 if ((result = Tspi_Data_Unbind(hEncData, hKey,
2453 &buf_size, &buf))) {
2454 stlogit("Tspi_Data_Unbind: 0x%0x - %s",
2455 result, Trspi_Error_String(result));
2456 return (CKR_FUNCTION_FAILED);
2459 if (*out_data_len < buf_size + outlen) {
2460 Tspi_Context_FreeMemory(hContext, buf);
2461 return (CKR_BUFFER_TOO_SMALL);
2464 (void) memcpy(out_data + outlen, buf, buf_size);
2466 outlen += buf_size;
2467 in_data += chunklen;
2468 remain -= chunklen;
2470 Tspi_Context_FreeMemory(hContext, buf);
2471 if (chunklen > remain)
2472 chunklen = remain;
2474 *out_data_len = outlen;
2475 return (CKR_OK);
2478 CK_RV
2479 token_specific_rsa_decrypt(
2480 TSS_HCONTEXT hContext,
2481 CK_BYTE * in_data,
2482 CK_ULONG in_data_len,
2483 CK_BYTE * out_data,
2484 CK_ULONG * out_data_len,
2485 OBJECT * key_obj)
2487 CK_RV rc;
2488 TSS_HKEY hKey;
2490 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2491 return (rc);
2494 rc = tpm_decrypt_data(hContext, hKey, in_data, in_data_len,
2495 out_data, out_data_len);
2497 return (rc);
2500 CK_RV
2501 token_specific_rsa_verify(
2502 TSS_HCONTEXT hContext,
2503 CK_BYTE * in_data,
2504 CK_ULONG in_data_len,
2505 CK_BYTE * sig,
2506 CK_ULONG sig_len,
2507 OBJECT * key_obj)
2509 TSS_RESULT result;
2510 TSS_HHASH hHash;
2511 TSS_HKEY hKey;
2512 CK_RV rc;
2514 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2515 return (rc);
2518 /* Create the hash object we'll use to sign */
2519 if ((result = Tspi_Context_CreateObject(hContext,
2520 TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) {
2521 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
2522 result, Trspi_Error_String(result));
2523 return (CKR_FUNCTION_FAILED);
2526 /* Insert the data into the hash object */
2527 if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len,
2528 in_data))) {
2529 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s",
2530 result, Trspi_Error_String(result));
2531 return (CKR_FUNCTION_FAILED);
2534 /* Verify */
2535 result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig);
2536 if (result != TSS_SUCCESS &&
2537 TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) {
2538 stlogit("Tspi_Hash_VerifySignature: 0x%0x - %s",
2539 result, Trspi_Error_String(result));
2542 if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) {
2543 rc = CKR_SIGNATURE_INVALID;
2544 } else {
2545 rc = CKR_OK;
2548 return (rc);
2551 CK_RV
2552 token_specific_rsa_sign(
2553 TSS_HCONTEXT hContext,
2554 CK_BYTE * in_data,
2555 CK_ULONG in_data_len,
2556 CK_BYTE * out_data,
2557 CK_ULONG * out_data_len,
2558 OBJECT * key_obj)
2560 TSS_RESULT result;
2561 TSS_HHASH hHash;
2562 BYTE *sig;
2563 UINT32 sig_len;
2564 TSS_HKEY hKey;
2565 CK_RV rc;
2567 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2568 return (rc);
2571 /* Create the hash object we'll use to sign */
2572 if ((result = Tspi_Context_CreateObject(hContext,
2573 TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) {
2574 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
2575 result, Trspi_Error_String(result));
2576 return (CKR_FUNCTION_FAILED);
2579 /* Insert the data into the hash object */
2580 if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len,
2581 in_data))) {
2582 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s",
2583 result, Trspi_Error_String(result));
2584 return (CKR_FUNCTION_FAILED);
2587 /* Sign */
2588 if ((result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig))) {
2589 stlogit("Tspi_Hash_Sign: 0x%0x - %s",
2590 result, Trspi_Error_String(result));
2591 return (CKR_DATA_LEN_RANGE);
2594 if (sig_len > *out_data_len) {
2595 Tspi_Context_FreeMemory(hContext, sig);
2596 return (CKR_BUFFER_TOO_SMALL);
2599 (void) memcpy(out_data, sig, sig_len);
2600 *out_data_len = sig_len;
2601 Tspi_Context_FreeMemory(hContext, sig);
2603 return (CKR_OK);
2606 CK_RV
2607 tpm_encrypt_data(
2608 TSS_HCONTEXT hContext,
2609 TSS_HKEY hKey,
2610 CK_BYTE *in_data,
2611 CK_ULONG in_data_len,
2612 CK_BYTE *out_data,
2613 CK_ULONG *out_data_len)
2615 TSS_RESULT result;
2616 TSS_HENCDATA hEncData;
2617 BYTE *dataBlob, *modulus;
2618 UINT32 dataBlobSize, modLen;
2619 CK_ULONG chunklen, remain;
2620 CK_ULONG outlen;
2621 UINT32 keyusage, scheme, maxsize;
2623 if ((result = Tspi_Context_CreateObject(hContext,
2624 TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
2625 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
2626 result, Trspi_Error_String(result));
2627 return (CKR_FUNCTION_FAILED);
2630 * Figure out the modulus size so we can break the data
2631 * into smaller chunks if necessary.
2633 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
2634 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
2635 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2636 result, Trspi_Error_String(result));
2637 return (result);
2639 /* we don't need the actual modulus */
2640 Tspi_Context_FreeMemory(hContext, modulus);
2643 * According to TSS spec for Tspi_Data_Bind (4.3.4.21.5),
2644 * Max input data size varies depending on the key type and
2645 * encryption scheme.
2647 if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
2648 TSS_TSPATTRIB_KEYINFO_USAGE, &keyusage))) {
2649 stlogit("Cannot find USAGE: %s\n",
2650 Trspi_Error_String(result));
2651 return (result);
2653 if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
2654 TSS_TSPATTRIB_KEYINFO_ENCSCHEME, &scheme))) {
2655 stlogit("Cannot find ENCSCHEME: %s\n",
2656 Trspi_Error_String(result));
2657 return (result);
2659 switch (scheme) {
2660 case TSS_ES_RSAESPKCSV15:
2661 if (keyusage == TSS_KEYUSAGE_BIND)
2662 maxsize = 16;
2663 else /* legacy */
2664 maxsize = 11;
2665 break;
2666 case TSS_ES_RSAESOAEP_SHA1_MGF1:
2667 maxsize = 47;
2668 break;
2669 default:
2670 maxsize = 0;
2673 modLen -= maxsize;
2675 chunklen = (in_data_len > modLen ? modLen : in_data_len);
2676 remain = in_data_len;
2677 outlen = 0;
2678 while (remain > 0) {
2679 if ((result = Tspi_Data_Bind(hEncData, hKey,
2680 chunklen, in_data))) {
2681 stlogit("Tspi_Data_Bind: 0x%0x - %s",
2682 result, Trspi_Error_String(result));
2683 return (CKR_FUNCTION_FAILED);
2686 if ((result = Tspi_GetAttribData(hEncData,
2687 TSS_TSPATTRIB_ENCDATA_BLOB,
2688 TSS_TSPATTRIB_ENCDATABLOB_BLOB,
2689 &dataBlobSize, &dataBlob))) {
2690 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2691 result, Trspi_Error_String(result));
2692 return (CKR_FUNCTION_FAILED);
2695 if (outlen + dataBlobSize > *out_data_len) {
2696 Tspi_Context_FreeMemory(hContext, dataBlob);
2697 return (CKR_DATA_LEN_RANGE);
2700 (void) memcpy(out_data + outlen,
2701 dataBlob, dataBlobSize);
2703 outlen += dataBlobSize;
2704 in_data += chunklen;
2705 remain -= chunklen;
2707 if (chunklen > remain)
2708 chunklen = remain;
2710 Tspi_Context_FreeMemory(hContext, dataBlob);
2712 *out_data_len = outlen;
2714 return (CKR_OK);
2717 CK_RV
2718 token_specific_rsa_encrypt(
2719 TSS_HCONTEXT hContext,
2720 CK_BYTE * in_data,
2721 CK_ULONG in_data_len,
2722 CK_BYTE * out_data,
2723 CK_ULONG * out_data_len,
2724 OBJECT * key_obj)
2726 TSS_HKEY hKey;
2727 CK_RV rc;
2729 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2730 return (rc);
2733 rc = tpm_encrypt_data(hContext, hKey, in_data, in_data_len,
2734 out_data, out_data_len);
2736 return (rc);
2740 * RSA Verify Recover
2742 * Public key crypto is done in software, not by the TPM.
2743 * We bypass the TSPI library here in favor of calls directly
2744 * to OpenSSL because we don't want to add any padding, the in_data (signature)
2745 * already contains the data stream to be decrypted and is already
2746 * padded and formatted correctly.
2748 CK_RV
2749 token_specific_rsa_verify_recover(
2750 TSS_HCONTEXT hContext,
2751 CK_BYTE *in_data, /* signature */
2752 CK_ULONG in_data_len,
2753 CK_BYTE *out_data, /* decrypted */
2754 CK_ULONG *out_data_len,
2755 OBJECT *key_obj)
2757 TSS_HKEY hKey;
2758 TSS_RESULT result;
2759 CK_RV rc;
2760 BYTE *modulus;
2761 UINT32 modLen;
2762 RSA *rsa = NULL;
2763 uchar_t exp[] = { 0x01, 0x00, 0x01 };
2764 int sslrv, num;
2765 BYTE temp[MAX_RSA_KEYLENGTH];
2766 BYTE outdata[MAX_RSA_KEYLENGTH];
2767 int i;
2769 if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2770 return (rc);
2773 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
2774 TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
2775 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2776 result, Trspi_Error_String(result));
2777 return (CKR_FUNCTION_FAILED);
2780 if (in_data_len != modLen) {
2781 rc = CKR_SIGNATURE_LEN_RANGE;
2782 goto end;
2785 rsa = RSA_new();
2786 if (rsa == NULL) {
2787 rc = CKR_HOST_MEMORY;
2788 goto end;
2791 rsa->n = BN_bin2bn(modulus, modLen, rsa->n);
2792 rsa->e = BN_bin2bn(exp, sizeof (exp), rsa->e);
2793 if (rsa->n == NULL || rsa->e == NULL) {
2794 rc = CKR_HOST_MEMORY;
2795 goto end;
2798 rsa->flags |= RSA_FLAG_SIGN_VER;
2800 /* use RSA_NO_PADDING because the data is already padded (PKCS1) */
2801 sslrv = RSA_public_encrypt(in_data_len, in_data, outdata,
2802 rsa, RSA_NO_PADDING);
2803 if (sslrv == -1) {
2804 rc = CKR_FUNCTION_FAILED;
2805 goto end;
2808 /* Strip leading 0's before stripping the padding */
2809 for (i = 0; i < sslrv; i++)
2810 if (outdata[i] != 0)
2811 break;
2813 num = BN_num_bytes(rsa->n);
2815 /* Use OpenSSL function for stripping PKCS#1 padding */
2816 sslrv = RSA_padding_check_PKCS1_type_1(temp, sizeof (temp),
2817 &outdata[i], sslrv - i, num);
2819 if (sslrv < 0) {
2820 rc = CKR_FUNCTION_FAILED;
2821 goto end;
2824 if (*out_data_len < sslrv) {
2825 rc = CKR_BUFFER_TOO_SMALL;
2826 *out_data_len = 0;
2827 goto end;
2830 /* The return code indicates the number of bytes remaining */
2831 (void) memcpy(out_data, temp, sslrv);
2832 *out_data_len = sslrv;
2833 end:
2834 Tspi_Context_FreeMemory(hContext, modulus);
2835 if (rsa)
2836 RSA_free(rsa);
2838 return (rc);