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)
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.
31 #include <sys/types.h>
33 #include <uuid/uuid.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>
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
);
63 token_specific_rsa_decrypt(
72 token_specific_rsa_encrypt(
81 token_specific_rsa_sign(
90 token_specific_rsa_verify(TSS_HCONTEXT
, CK_BYTE
*,
91 CK_ULONG
, CK_BYTE
*, CK_ULONG
, OBJECT
*);
94 token_specific_rsa_generate_keypair(TSS_HCONTEXT
,
99 token_specific_sha_init(DIGEST_CONTEXT
*);
102 token_specific_sha_update(DIGEST_CONTEXT
*,
107 token_specific_sha_final(DIGEST_CONTEXT
*,
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
);
119 token_specific_init(char *, CK_SLOT_ID
, TSS_HCONTEXT
*);
121 struct token_specific_struct token_specific
= {
123 &token_specific_init
,
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
,
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
;
168 verify_user_pin(TSS_HCONTEXT
, CK_BYTE
*);
171 tss_assign_secret_key_policy(TSS_HCONTEXT
, TSS_FLAG
, TSS_HKEY
, CK_CHAR
*);
174 set_legacy_key_params(TSS_HKEY
);
177 local_uuid_clear(TSS_UUID
*uuid
)
181 (void) memset(uuid
, 0, sizeof (TSS_UUID
));
185 /* convert from TSS_UUID to uuid_t */
187 tss_uuid_convert_from(TSS_UUID
*uu
, uuid_t ptr
)
192 tmp
= ntohl(uu
->ulTimeLow
);
193 out
[3] = (uchar_t
)tmp
;
195 out
[2] = (uchar_t
)tmp
;
197 out
[1] = (uchar_t
)tmp
;
199 out
[0] = (uchar_t
)tmp
;
201 tmp
= ntohs(uu
->usTimeMid
);
202 out
[5] = (uchar_t
)tmp
;
204 out
[4] = (uchar_t
)tmp
;
206 tmp
= ntohs(uu
->usTimeHigh
);
207 out
[7] = (uchar_t
)tmp
;
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 */
221 tss_uuid_convert_to(TSS_UUID
*uuid
, uuid_t in
)
230 ltmp
= (ltmp
<< 8) | *ptr
++;
231 ltmp
= (ltmp
<< 8) | *ptr
++;
232 ltmp
= (ltmp
<< 8) | *ptr
++;
233 uuid
->ulTimeLow
= ntohl(ltmp
);
236 stmp
= (stmp
<< 8) | *ptr
++;
237 uuid
->usTimeMid
= ntohs(stmp
);
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);
251 local_uuid_copy(TSS_UUID
*dst
, TSS_UUID
*src
)
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
);
264 local_uuid_generate(TSS_UUID
*uu
)
268 uuid_generate(newuuid
);
270 tss_uuid_convert_to(uu
, newuuid
);
274 local_copy_file(char *dst
, char *src
)
279 fdest
= fopen(dst
, "w");
283 fsrc
= fopen(src
, "r");
285 (void) fclose(fdest
);
289 while (fread(line
, sizeof (line
), 1, fsrc
))
290 (void) fprintf(fdest
, "%s\n", line
);
292 (void) fclose(fdest
);
297 remove_uuid(char *keyname
)
301 char fname
[MAXPATHLEN
];
302 char line
[BUFSIZ
], key
[BUFSIZ
], idstr
[BUFSIZ
];
304 char *p
= get_tpm_keystore_path();
309 (void) snprintf(fname
, sizeof (fname
),
310 "%s/%s", p
, TPMTOK_UUID_INDEX_FILENAME
);
312 fp
= fopen(fname
, "r");
317 tmpfname
= tempnam("/tmp", "tpmtok");
318 newfp
= fopen(tmpfname
, "w+");
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
);
334 (void) fclose(newfp
);
335 if (local_copy_file(fname
, tmpfname
) == 0)
336 (void) unlink(tmpfname
);
344 find_uuid(char *keyname
, TSS_UUID
*uu
)
346 int ret
= 0, found
= 0;
348 char fname
[MAXPATHLEN
];
349 char line
[BUFSIZ
], key
[BUFSIZ
], idstr
[BUFSIZ
];
351 char *p
= get_tpm_keystore_path();
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");
364 if (errno
== ENOENT
) {
365 /* initialize the file */
366 fp
= fopen(fname
, "w");
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
);
380 tss_uuid_convert_to(uu
,
395 local_uuid_is_null(TSS_UUID
*uu
)
400 tss_uuid_convert_from(uu
, uuid
);
402 nulluuid
= uuid_is_null(uuid
);
407 add_uuid(char *keyname
, TSS_UUID
*uu
)
410 char fname
[MAXPATHLEN
];
413 char *p
= get_tpm_keystore_path();
418 tss_uuid_convert_from(uu
, uuid
);
420 if (uuid_is_null(uuid
))
423 uuid_unparse(uuid
, idstr
);
425 (void) snprintf(fname
, sizeof (fname
),
426 "%s/%s", p
, TPMTOK_UUID_INDEX_FILENAME
);
428 fp
= fopen(fname
, "a");
432 (void) fprintf(fp
, "%s %s\n", keyname
, idstr
);
440 util_get_keysize_flag(CK_ULONG size
)
444 return (TSS_KEY_SIZE_512
);
446 return (TSS_KEY_SIZE_1024
);
448 return (TSS_KEY_SIZE_2048
);
456 /* make sure the public exponent attribute is 65537 */
458 util_check_public_exponent(TEMPLATE
*tmpl
)
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
,
468 LogError1("Couldn't find public exponent attribute");
469 return (CKR_TEMPLATE_INCOMPLETE
);
472 switch (publ_exp_attr
->ulValueLen
) {
474 rc
= memcmp(pubexp_bytes
, publ_exp_attr
->pValue
, 3);
476 case sizeof (CK_ULONG
):
477 publ_exp
= *((CK_ULONG
*)publ_exp_attr
->pValue
);
478 if (publ_exp
== 65537)
489 set_public_modulus(TSS_HCONTEXT hContext
, TSS_HKEY hKey
,
490 unsigned long size_n
, unsigned char *n
)
494 BYTE
*blob
, pub_blob
[1024];
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
));
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
));
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
;
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
));
540 * Get details about the TPM to put into the token_info structure.
543 token_get_tpm_info(TSS_HCONTEXT hContext
, TOKEN_DATA
*td
)
546 TPM_CAPABILITY_AREA capArea
= TSS_TPMCAP_VERSION_VAL
;
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 ||
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
);
595 token_specific_session(CK_SLOT_ID slotid
)
601 token_rng(TSS_HCONTEXT hContext
, CK_BYTE
*output
, CK_ULONG bytes
)
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
);
626 open_tss_context(TSS_HCONTEXT
*pContext
)
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
);
641 return (CKR_FUNCTION_FAILED
);
648 token_specific_init(char *Correlator
, CK_SLOT_ID SlotNumber
,
649 TSS_HCONTEXT
*hContext
)
653 result
= open_tss_context(hContext
);
655 return (CKR_FUNCTION_FAILED
);
657 if ((result
= Tspi_Context_GetDefaultPolicy(*hContext
,
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
);
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
680 TSS_HCONTEXT hContext
,
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
);
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
);
721 return (CKR_FUNCTION_FAILED
);
724 result
= tss_assign_secret_key_policy(hContext
, TSS_POLICY_MIGRATION
,
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
);
753 return (CKR_FUNCTION_FAILED
);
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.
764 token_wrap_key_object(TSS_HCONTEXT hContext
,
765 CK_OBJECT_HANDLE ckObject
,
766 TSS_HKEY hParentKey
, TSS_HKEY
*phKey
)
769 CK_ATTRIBUTE
*attr
= NULL
, *new_attr
, *prime_attr
;
770 CK_ULONG
class, key_type
;
774 TSS_FLAG initFlags
= 0;
778 if ((rc
= object_mgr_find_in_map1(hContext
, ckObject
, &obj
))) {
782 /* if the object isn't a key, fail */
783 if (template_attribute_find(obj
->template, CKA_KEY_TYPE
,
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
,
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
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
,
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
,
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
|
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
));
874 if ((result
= set_public_modulus(hContext
, *phKey
,
875 attr
->ulValueLen
, attr
->pValue
))) {
876 Tspi_Context_CloseObject(hContext
, *phKey
);
878 return (CKR_FUNCTION_FAILED
);
880 result
= tss_assign_secret_key_policy(hContext
,
881 TSS_POLICY_MIGRATION
, *phKey
, NULL
);
883 Tspi_Context_CloseObject(hContext
, *phKey
);
885 return (CKR_FUNCTION_FAILED
);
888 result
= set_legacy_key_params(*phKey
);
890 Tspi_Context_CloseObject(hContext
, *phKey
);
892 return (CKR_FUNCTION_FAILED
);
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
,
909 Tspi_Context_FreeMemory(hContext
, rgbBlob
);
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
);
927 tss_assign_secret_key_policy(TSS_HCONTEXT hContext
, TSS_FLAG policyType
,
928 TSS_HKEY hKey
, CK_CHAR
*passHash
)
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
));
939 if ((result
= Tspi_Policy_AssignToObject(hPolicy
, hKey
))) {
940 stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s",
941 result
, Trspi_Error_String(result
));
944 if (passHash
== NULL
) {
945 result
= Tspi_Policy_SetSecret(hPolicy
, TSS_SECRET_MODE_NONE
,
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
));
957 if (result
!= TSS_SUCCESS
)
958 Tspi_Context_CloseObject(hContext
, hPolicy
);
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).
968 TSS_HCONTEXT hContext
,
969 CK_OBJECT_HANDLE ckKey
,
971 CK_CHAR_PTR passHash
,
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
))) {
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
,
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.
1006 token_load_srk(TSS_HCONTEXT hContext
, TSS_HKEY
*hSRK
)
1008 TSS_HPOLICY hPolicy
;
1010 TSS_UUID SRK_UUID
= TSS_UUID_SRK
;
1011 BYTE wellKnown
[] = TSS_WELL_KNOWN_SECRET
;
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
);
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
));
1027 if ((result
= Tspi_GetPolicyObject(*hSRK
, TSS_POLICY_USAGE
,
1029 stlogit("Tspi_GetPolicyObject: 0x%0x - %s",
1030 result
, Trspi_Error_String(result
));
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
));
1045 tss_find_and_load_key(TSS_HCONTEXT hContext
,
1046 char *keyid
, TSS_UUID
*uuid
, TSS_HKEY hParent
,
1047 BYTE
*hash
, TSS_HKEY
*hKey
)
1051 if (local_uuid_is_null(uuid
) &&
1052 find_uuid(keyid
, uuid
)) {
1053 /* The UUID was not created or saved yet */
1056 result
= Tspi_Context_GetKeyByUUID(hContext
,
1057 TSS_PS_TYPE_USER
, *uuid
, hKey
);
1059 stlogit("Tspi_Context_GetKeyByUUID: 0x%0x - %s",
1060 result
, Trspi_Error_String(result
));
1065 result
= tss_assign_secret_key_policy(hContext
,
1066 TSS_POLICY_USAGE
, *hKey
, (CK_BYTE
*)hash
);
1071 result
= Tspi_Key_LoadKey(*hKey
, hParent
);
1073 stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
1074 result
, Trspi_Error_String(result
));
1080 token_load_public_root_key(TSS_HCONTEXT hContext
)
1085 if (hPublicRootKey
!= NULL_HKEY
)
1086 return (TSS_SUCCESS
);
1088 if ((result
= token_load_srk(hContext
, &hSRK
))) {
1092 result
= tss_find_and_load_key(hContext
,
1093 TPMTOK_PUBLIC_ROOT_KEY_ID
,
1094 &publicRootKeyUUID
, hSRK
, NULL
, &hPublicRootKey
);
1102 set_legacy_key_params(TSS_HKEY hKey
)
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
));
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
));
1128 tss_generate_key(TSS_HCONTEXT hContext
, TSS_FLAG initFlags
, BYTE
*passHash
,
1129 TSS_HKEY hParentKey
, TSS_HKEY
*phKey
)
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
));
1140 result
= tss_assign_secret_key_policy(hContext
, TSS_POLICY_USAGE
,
1144 Tspi_Context_CloseObject(hContext
, *phKey
);
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
,
1152 stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
1153 result
, Trspi_Error_String(result
));
1154 Tspi_Context_CloseObject(hContext
, *phKey
);
1158 if (passHash
== NULL
) {
1159 result
= Tspi_Policy_SetSecret(hMigPolicy
,
1160 TSS_SECRET_MODE_NONE
, 0, NULL
);
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
);
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
);
1183 if (TPMTOK_TSS_KEY_TYPE(initFlags
) == TSS_KEY_TYPE_LEGACY
) {
1184 result
= set_legacy_key_params(*phKey
);
1186 Tspi_Context_CloseObject(hContext
, *phKey
);
1187 Tspi_Context_CloseObject(hContext
, hMigPolicy
);
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
);
1204 TSS_HCONTEXT hContext
,
1205 TSS_HKEY hObjectToChange
, TSS_HKEY hParentObject
,
1206 TSS_UUID objUUID
, TSS_UUID parentUUID
,
1210 TSS_HPOLICY hPolicy
;
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
));
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
));
1227 if ((result
= Tspi_ChangeAuth(hObjectToChange
, hParentObject
,
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
));
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
;
1257 TSS_HKEY hParentKey
;
1258 TSS_UUID newuuid
, parentUUID
;
1260 TSS_FLAG initFlags
= TSS_KEY_MIGRATABLE
|
1261 TSS_KEY_TYPE_BIND
| TSS_KEY_SIZE_2048
| TSS_KEY_AUTHORIZATION
;
1264 case TPMTOK_PUBLIC_LEAF_KEY
:
1265 hParentKey
= hPublicRootKey
;
1266 keyid
= TPMTOK_PUBLIC_LEAF_KEY_ID
;
1267 local_uuid_copy(&parentUUID
, &publicRootKeyUUID
);
1269 case TPMTOK_PRIVATE_LEAF_KEY
:
1270 hParentKey
= hPrivateRootKey
;
1271 keyid
= TPMTOK_PRIVATE_LEAF_KEY_ID
;
1272 local_uuid_copy(&parentUUID
, &privateRootKeyUUID
);
1275 stlogit("Unknown key type 0x%0x", key_type
);
1279 if (result
= tss_generate_key(hContext
, initFlags
, passHash
,
1280 hParentKey
, phKey
)) {
1285 * - generate newUUID
1286 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey,
1287 * USER, newUUID, USER, parentUUID);
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
) {
1298 * Add the UUID to the token UUID index.
1300 ret
= add_uuid(keyid
, &newuuid
);
1303 result
= Tspi_Context_UnregisterKey(hContext
,
1304 TSS_PS_TYPE_USER
, newuuid
, phKey
);
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.
1319 token_verify_pin(TSS_HCONTEXT hContext
, TSS_HKEY hKey
)
1321 TSS_HENCDATA hEncData
;
1322 UINT32 ulUnboundDataLen
;
1323 BYTE
*rgbUnboundData
= NULL
;
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
));
1335 /* Use some random data */
1336 rc
= token_rng(hContext
, rgbData
, sizeof (rgbData
));
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
));
1347 /* unbind the junk data to test the key's auth data */
1348 result
= Tspi_Data_Unbind(hEncData
, hKey
, &ulUnboundDataLen
,
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
));
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
;
1362 if (memcmp(rgbUnboundData
, rgbData
, ulUnboundDataLen
))
1363 rc
= CKR_PIN_INCORRECT
;
1368 if (rgbUnboundData
!= NULL
)
1369 Tspi_Context_FreeMemory(hContext
, rgbUnboundData
);
1370 Tspi_Context_CloseObject(hContext
, hEncData
);
1375 token_create_private_tree(TSS_HCONTEXT hContext
, CK_BYTE
*pinHash
)
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
;
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
))) {
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
);
1406 local_uuid_clear(&privateRootKeyUUID
);
1410 ret
= add_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID
, &privateRootKeyUUID
);
1412 result
= Tspi_Context_UnregisterKey(hContext
,
1413 TSS_PS_TYPE_USER
, privateRootKeyUUID
,
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
))) {
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
,
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
,
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
);
1466 token_create_public_tree(TSS_HCONTEXT hContext
, CK_BYTE
*pinHash
)
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
;
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
);
1497 local_uuid_clear(&publicRootKeyUUID
);
1498 return (CKR_FUNCTION_FAILED
);
1501 ret
= add_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID
, &publicRootKeyUUID
);
1503 result
= Tspi_Context_UnregisterKey(hContext
,
1504 TSS_PS_TYPE_USER
, publicRootKeyUUID
,
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
))) {
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
,
1533 (void) remove_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID
);
1535 (void) Tspi_Context_UnregisterKey(hContext
,
1536 TSS_PS_TYPE_USER
, publicRootKeyUUID
,
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
);
1553 token_specific_login(
1554 TSS_HCONTEXT hContext
,
1555 CK_USER_TYPE userType
,
1560 CK_BYTE hash_sha
[SHA1_DIGEST_LENGTH
];
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;
1600 if ((rc
= verify_user_pin(hContext
, hash_sha
))) {
1604 (void) memcpy(current_user_pin_sha
, hash_sha
,
1605 SHA1_DIGEST_LENGTH
);
1607 rc
= load_private_token_objects(hContext
);
1609 (void) XProcLock(xproclock
);
1610 global_shm
->priv_loaded
= TRUE
;
1611 (void) XProcUnLock(xproclock
);
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
,
1625 SHA1_DIGEST_LENGTH
))
1626 return (CKR_PIN_INCORRECT
);
1628 not_initialized
= 1;
1632 if (hPublicRootKey
== NULL_HKEY
) {
1633 result
= tss_find_and_load_key(
1635 TPMTOK_PUBLIC_ROOT_KEY_ID
,
1636 &publicRootKeyUUID
, hSRK
, NULL
,
1640 return (CKR_FUNCTION_FAILED
);
1643 /* find, load the public leaf key */
1644 if (hPublicLeafKey
== NULL_HKEY
) {
1645 result
= tss_find_and_load_key(
1647 TPMTOK_PUBLIC_LEAF_KEY_ID
,
1648 &publicLeafKeyUUID
, hPublicRootKey
, hash_sha
,
1651 return (CKR_FUNCTION_FAILED
);
1654 if ((rc
= token_verify_pin(hContext
, hPublicLeafKey
))) {
1658 (void) memcpy(current_so_pin_sha
, hash_sha
, SHA1_DIGEST_LENGTH
);
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
);
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.
1703 check_pin_properties(CK_USER_TYPE userType
, CK_BYTE
*pinHash
,
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
);
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
);
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.
1736 verify_user_pin(TSS_HCONTEXT hContext
, CK_BYTE
*hash_sha
)
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
1755 if (hPrivateRootKey
== NULL_HKEY
) {
1756 result
= tss_find_and_load_key(
1758 TPMTOK_PRIVATE_ROOT_KEY_ID
,
1759 &privateRootKeyUUID
, hSRK
, NULL
, &hPrivateRootKey
);
1761 return (CKR_FUNCTION_FAILED
);
1764 if (hPrivateLeafKey
== NULL_HKEY
) {
1765 result
= tss_find_and_load_key(
1767 TPMTOK_PRIVATE_LEAF_KEY_ID
,
1768 &privateLeafKeyUUID
, hPrivateRootKey
, hash_sha
,
1772 return (CKR_FUNCTION_FAILED
);
1776 * Verify that the PIN is correct by attempting to wrap/unwrap some
1779 if ((rc
= token_verify_pin(hContext
, hPrivateLeafKey
))) {
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
];
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
,
1831 if ((rc
= token_create_private_tree(sess
->hContext
,
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
);
1856 if ((rc
= verify_user_pin(sess
->hContext
,
1862 if ((rc
= check_pin_properties(CKU_USER
, newpin_hash
,
1866 /* change the auth on the TSS object */
1867 if (tss_change_auth(sess
->hContext
,
1868 hPrivateLeafKey
, hPrivateRootKey
,
1869 privateLeafKeyUUID
, privateRootKeyUUID
,
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
)))
1883 if ((rc
= token_create_public_tree(sess
->hContext
,
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
,
1901 /* change auth on the SO's leaf key */
1902 if (tss_change_auth(sess
->hContext
,
1903 hPublicLeafKey
, hPublicRootKey
,
1904 publicLeafKeyUUID
, publicRootKeyUUID
,
1906 return (CKR_FUNCTION_FAILED
);
1909 rc
= CKR_SESSION_READ_ONLY
;
1915 /* only called at token init time */
1917 token_specific_verify_so_pin(TSS_HCONTEXT hContext
, CK_CHAR_PTR pPin
,
1920 CK_BYTE hash_sha
[SHA1_DIGEST_LENGTH
];
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
);
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
);
1953 result
= Tspi_Context_GetKeyByUUID(hContext
,
1954 TSS_PS_TYPE_USER
, publicRootKeyUUID
, &hPublicRootKey
);
1957 return (CKR_FUNCTION_FAILED
);
1959 result
= Tspi_Key_LoadKey(hPublicRootKey
, hSRK
);
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
);
1970 return (CKR_FUNCTION_FAILED
);
1972 result
= tss_assign_secret_key_policy(hContext
, TSS_POLICY_USAGE
,
1973 hPublicLeafKey
, hash_sha
);
1975 return (CKR_FUNCTION_FAILED
);
1977 result
= Tspi_Key_LoadKey(hPublicLeafKey
, hPublicRootKey
);
1979 return (CKR_FUNCTION_FAILED
);
1981 /* If the hash given is wrong, the verify will fail */
1982 if ((rc
= token_verify_pin(hContext
, hPublicLeafKey
))) {
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
;
2012 * Wrap the 20 bytes of auth data and store in an attribute of the two
2016 token_wrap_auth_data(TSS_HCONTEXT hContext
,
2017 CK_BYTE
*authData
, TEMPLATE
*publ_tmpl
,
2018 TEMPLATE
*priv_tmpl
)
2021 CK_ATTRIBUTE
*new_attr
;
2024 TSS_HKEY hParentKey
;
2025 TSS_HENCDATA hEncData
;
2029 if ((hPrivateLeafKey
== NULL_HKEY
) && (hPublicLeafKey
== NULL_HKEY
)) {
2030 return (CKR_FUNCTION_FAILED
);
2031 } else if (hPublicLeafKey
!= NULL_HKEY
) {
2032 hParentKey
= hPublicLeafKey
;
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
,
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
,
2064 (void) template_update_attribute(publ_tmpl
, new_attr
);
2066 if ((rc
= build_attribute(CKA_ENC_AUTHDATA
, blob
,
2067 blob_size
, &new_attr
))) {
2070 (void) template_update_attribute(priv_tmpl
, new_attr
);
2076 token_unwrap_auth_data(TSS_HCONTEXT hContext
, CK_BYTE
*encAuthData
,
2077 CK_ULONG encAuthDataLen
, TSS_HKEY hKey
,
2081 TSS_HENCDATA hEncData
;
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
);
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;
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
;
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
);
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
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
;
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
))) {
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
);
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
);
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
));
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
);
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
);
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
,
2253 TSS_HCONTEXT hContext
,
2258 TSS_HPOLICY hPolicy
= NULL_HPOLICY
;
2259 TSS_HKEY hParentKey
;
2260 BYTE
*authData
= NULL
;
2263 CK_OBJECT_HANDLE handle
;
2266 if (hPrivateLeafKey
!= NULL_HKEY
) {
2267 hParentKey
= hPrivateRootKey
;
2269 if ((result
= token_load_public_root_key(hContext
)))
2270 return (CKR_FUNCTION_FAILED
);
2272 hParentKey
= hPublicRootKey
;
2276 if (template_attribute_find(key_obj
->template, CKA_CLASS
,
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
);
2293 return (CKR_FUNCTION_FAILED
);
2295 if ((rc
= token_load_key(hContext
,
2296 handle
, hParentKey
, NULL
, phKey
))) {
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
);
2309 stlogit("Tspi_Context_LoadKeyByBlob: "
2311 result
, Trspi_Error_String(result
));
2312 return (CKR_FUNCTION_FAILED
);
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
) {
2320 if ((result
= Tspi_Context_LoadKeyByBlob(hContext
,
2321 hParentKey
, attr
->ulValueLen
, attr
->pValue
,
2323 stlogit("Tspi_Context_LoadKeyByBlob: "
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
;
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
,
2366 stlogit("Tspi_Context_CreateObject: "
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: "
2377 result
, Trspi_Error_String(result
));
2378 return (CKR_FUNCTION_FAILED
);
2381 if ((result
= Tspi_Policy_AssignToObject(hPolicy
,
2383 stlogit("Tspi_Policy_AssignToObject: "
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
);
2403 TSS_HCONTEXT hContext
,
2406 CK_ULONG in_data_len
,
2408 CK_ULONG
* out_data_len
)
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
));
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
;
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
);
2467 in_data
+= chunklen
;
2470 Tspi_Context_FreeMemory(hContext
, buf
);
2471 if (chunklen
> remain
)
2474 *out_data_len
= outlen
;
2479 token_specific_rsa_decrypt(
2480 TSS_HCONTEXT hContext
,
2482 CK_ULONG in_data_len
,
2484 CK_ULONG
* out_data_len
,
2490 if ((rc
= token_rsa_load_key(hContext
, key_obj
, &hKey
))) {
2494 rc
= tpm_decrypt_data(hContext
, hKey
, in_data
, in_data_len
,
2495 out_data
, out_data_len
);
2501 token_specific_rsa_verify(
2502 TSS_HCONTEXT hContext
,
2504 CK_ULONG in_data_len
,
2514 if ((rc
= token_rsa_load_key(hContext
, key_obj
, &hKey
))) {
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
,
2529 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s",
2530 result
, Trspi_Error_String(result
));
2531 return (CKR_FUNCTION_FAILED
);
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
;
2552 token_specific_rsa_sign(
2553 TSS_HCONTEXT hContext
,
2555 CK_ULONG in_data_len
,
2557 CK_ULONG
* out_data_len
,
2567 if ((rc
= token_rsa_load_key(hContext
, key_obj
, &hKey
))) {
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
,
2582 stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s",
2583 result
, Trspi_Error_String(result
));
2584 return (CKR_FUNCTION_FAILED
);
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
);
2608 TSS_HCONTEXT hContext
,
2611 CK_ULONG in_data_len
,
2613 CK_ULONG
*out_data_len
)
2616 TSS_HENCDATA hEncData
;
2617 BYTE
*dataBlob
, *modulus
;
2618 UINT32 dataBlobSize
, modLen
;
2619 CK_ULONG chunklen
, remain
;
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
));
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
));
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
));
2660 case TSS_ES_RSAESPKCSV15
:
2661 if (keyusage
== TSS_KEYUSAGE_BIND
)
2666 case TSS_ES_RSAESOAEP_SHA1_MGF1
:
2675 chunklen
= (in_data_len
> modLen
? modLen
: in_data_len
);
2676 remain
= in_data_len
;
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
;
2707 if (chunklen
> remain
)
2710 Tspi_Context_FreeMemory(hContext
, dataBlob
);
2712 *out_data_len
= outlen
;
2718 token_specific_rsa_encrypt(
2719 TSS_HCONTEXT hContext
,
2721 CK_ULONG in_data_len
,
2723 CK_ULONG
* out_data_len
,
2729 if ((rc
= token_rsa_load_key(hContext
, key_obj
, &hKey
))) {
2733 rc
= tpm_encrypt_data(hContext
, hKey
, in_data
, in_data_len
,
2734 out_data
, out_data_len
);
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.
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
,
2763 uchar_t exp
[] = { 0x01, 0x00, 0x01 };
2765 BYTE temp
[MAX_RSA_KEYLENGTH
];
2766 BYTE outdata
[MAX_RSA_KEYLENGTH
];
2769 if ((rc
= token_rsa_load_key(hContext
, key_obj
, &hKey
))) {
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
;
2787 rc
= CKR_HOST_MEMORY
;
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
;
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
);
2804 rc
= CKR_FUNCTION_FAILED
;
2808 /* Strip leading 0's before stripping the padding */
2809 for (i
= 0; i
< sslrv
; i
++)
2810 if (outdata
[i
] != 0)
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
);
2820 rc
= CKR_FUNCTION_FAILED
;
2824 if (*out_data_len
< sslrv
) {
2825 rc
= CKR_BUFFER_TOO_SMALL
;
2830 /* The return code indicates the number of bytes remaining */
2831 (void) memcpy(out_data
, temp
, sslrv
);
2832 *out_data_len
= sslrv
;
2834 Tspi_Context_FreeMemory(hContext
, modulus
);