xref: /onnv-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/tpm_specific.c (revision 11747:2b967904a95d)
19126SWyllys.Ingersoll@Sun.COM /*
29126SWyllys.Ingersoll@Sun.COM  * The Initial Developer of the Original Code is International
39126SWyllys.Ingersoll@Sun.COM  * Business Machines Corporation. Portions created by IBM
49126SWyllys.Ingersoll@Sun.COM  * Corporation are Copyright (C) 2005 International Business
59126SWyllys.Ingersoll@Sun.COM  * Machines Corporation. All Rights Reserved.
69126SWyllys.Ingersoll@Sun.COM  *
79126SWyllys.Ingersoll@Sun.COM  * This program is free software; you can redistribute it and/or modify
89126SWyllys.Ingersoll@Sun.COM  * it under the terms of the Common Public License as published by
99126SWyllys.Ingersoll@Sun.COM  * IBM Corporation; either version 1 of the License, or (at your option)
109126SWyllys.Ingersoll@Sun.COM  * any later version.
119126SWyllys.Ingersoll@Sun.COM  *
129126SWyllys.Ingersoll@Sun.COM  * This program is distributed in the hope that it will be useful,
139126SWyllys.Ingersoll@Sun.COM  * but WITHOUT ANY WARRANTY; without even the implied warranty of
149126SWyllys.Ingersoll@Sun.COM  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
159126SWyllys.Ingersoll@Sun.COM  * Common Public License for more details.
169126SWyllys.Ingersoll@Sun.COM  *
179126SWyllys.Ingersoll@Sun.COM  * You should have received a copy of the Common Public License
189126SWyllys.Ingersoll@Sun.COM  * along with this program; if not, a copy can be viewed at
199126SWyllys.Ingersoll@Sun.COM  * http://www.opensource.org/licenses/cpl1.0.php.
209126SWyllys.Ingersoll@Sun.COM  */
219126SWyllys.Ingersoll@Sun.COM /*
22*11747Swyllys.ingersoll@sun.com  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
239126SWyllys.Ingersoll@Sun.COM  * Use is subject to license terms.
249126SWyllys.Ingersoll@Sun.COM  */
259126SWyllys.Ingersoll@Sun.COM 
269126SWyllys.Ingersoll@Sun.COM #include <pthread.h>
279126SWyllys.Ingersoll@Sun.COM #include <string.h>
289126SWyllys.Ingersoll@Sun.COM 
299126SWyllys.Ingersoll@Sun.COM #include <sys/types.h>
309126SWyllys.Ingersoll@Sun.COM #include <sys/stat.h>
319126SWyllys.Ingersoll@Sun.COM #include <uuid/uuid.h>
329126SWyllys.Ingersoll@Sun.COM #include <fcntl.h>
339126SWyllys.Ingersoll@Sun.COM #include <errno.h>
349126SWyllys.Ingersoll@Sun.COM #include <pwd.h>
359126SWyllys.Ingersoll@Sun.COM #include <syslog.h>
369126SWyllys.Ingersoll@Sun.COM 
379453SWyllys.Ingersoll@Sun.COM #include <openssl/rsa.h>
389453SWyllys.Ingersoll@Sun.COM 
399126SWyllys.Ingersoll@Sun.COM #include <tss/platform.h>
409126SWyllys.Ingersoll@Sun.COM #include <tss/tss_defines.h>
419126SWyllys.Ingersoll@Sun.COM #include <tss/tss_typedef.h>
429126SWyllys.Ingersoll@Sun.COM #include <tss/tss_structs.h>
439126SWyllys.Ingersoll@Sun.COM #include <tss/tss_error.h>
449126SWyllys.Ingersoll@Sun.COM #include <tss/tcs_error.h>
459126SWyllys.Ingersoll@Sun.COM #include <tss/tspi.h>
469126SWyllys.Ingersoll@Sun.COM #include <trousers/trousers.h>
479126SWyllys.Ingersoll@Sun.COM 
489126SWyllys.Ingersoll@Sun.COM #include "tpmtok_int.h"
499126SWyllys.Ingersoll@Sun.COM #include "tpmtok_defs.h"
509126SWyllys.Ingersoll@Sun.COM 
519453SWyllys.Ingersoll@Sun.COM #define	MAX_RSA_KEYLENGTH 512
529453SWyllys.Ingersoll@Sun.COM 
539126SWyllys.Ingersoll@Sun.COM extern void stlogit(char *fmt, ...);
549126SWyllys.Ingersoll@Sun.COM 
559126SWyllys.Ingersoll@Sun.COM CK_RV token_rng(TSS_HCONTEXT, CK_BYTE *,  CK_ULONG);
569126SWyllys.Ingersoll@Sun.COM int tok_slot2local(CK_SLOT_ID);
579126SWyllys.Ingersoll@Sun.COM CK_RV token_specific_session(CK_SLOT_ID);
589453SWyllys.Ingersoll@Sun.COM CK_RV token_specific_final(TSS_HCONTEXT);
599126SWyllys.Ingersoll@Sun.COM 
609126SWyllys.Ingersoll@Sun.COM CK_RV
619126SWyllys.Ingersoll@Sun.COM token_specific_rsa_decrypt(
629126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT,
639126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
649126SWyllys.Ingersoll@Sun.COM 	CK_ULONG,
659126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
669126SWyllys.Ingersoll@Sun.COM 	CK_ULONG *,
679126SWyllys.Ingersoll@Sun.COM 	OBJECT *);
689126SWyllys.Ingersoll@Sun.COM 
699126SWyllys.Ingersoll@Sun.COM CK_RV
709126SWyllys.Ingersoll@Sun.COM token_specific_rsa_encrypt(
719126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT,
729126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
739126SWyllys.Ingersoll@Sun.COM 	CK_ULONG,
749126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
759126SWyllys.Ingersoll@Sun.COM 	CK_ULONG *,
769126SWyllys.Ingersoll@Sun.COM 	OBJECT *);
779126SWyllys.Ingersoll@Sun.COM 
789126SWyllys.Ingersoll@Sun.COM CK_RV
799126SWyllys.Ingersoll@Sun.COM token_specific_rsa_sign(
809126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT,
819126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
829126SWyllys.Ingersoll@Sun.COM 	CK_ULONG,
839126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
849126SWyllys.Ingersoll@Sun.COM 	CK_ULONG *,
859126SWyllys.Ingersoll@Sun.COM 	OBJECT *);
869126SWyllys.Ingersoll@Sun.COM 
879126SWyllys.Ingersoll@Sun.COM CK_RV
889126SWyllys.Ingersoll@Sun.COM token_specific_rsa_verify(TSS_HCONTEXT, CK_BYTE *,
899126SWyllys.Ingersoll@Sun.COM     CK_ULONG, CK_BYTE *, CK_ULONG, OBJECT *);
909126SWyllys.Ingersoll@Sun.COM 
919126SWyllys.Ingersoll@Sun.COM CK_RV
929126SWyllys.Ingersoll@Sun.COM token_specific_rsa_generate_keypair(TSS_HCONTEXT,
939126SWyllys.Ingersoll@Sun.COM 	TEMPLATE *,
949126SWyllys.Ingersoll@Sun.COM 	TEMPLATE *);
959126SWyllys.Ingersoll@Sun.COM 
969126SWyllys.Ingersoll@Sun.COM CK_RV
979126SWyllys.Ingersoll@Sun.COM token_specific_sha_init(DIGEST_CONTEXT *);
989126SWyllys.Ingersoll@Sun.COM 
999126SWyllys.Ingersoll@Sun.COM CK_RV
1009126SWyllys.Ingersoll@Sun.COM token_specific_sha_update(DIGEST_CONTEXT *,
1019126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
1029126SWyllys.Ingersoll@Sun.COM 	CK_ULONG);
1039126SWyllys.Ingersoll@Sun.COM 
1049126SWyllys.Ingersoll@Sun.COM CK_RV
1059126SWyllys.Ingersoll@Sun.COM token_specific_sha_final(DIGEST_CONTEXT *,
1069126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *,
1079126SWyllys.Ingersoll@Sun.COM 	CK_ULONG *);
1089126SWyllys.Ingersoll@Sun.COM 
1099126SWyllys.Ingersoll@Sun.COM CK_RV token_specific_login(TSS_HCONTEXT, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG);
1109126SWyllys.Ingersoll@Sun.COM CK_RV token_specific_logout(TSS_HCONTEXT);
1119126SWyllys.Ingersoll@Sun.COM CK_RV token_specific_init_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG);
1129126SWyllys.Ingersoll@Sun.COM CK_RV token_specific_set_pin(ST_SESSION_HANDLE, CK_CHAR_PTR,
1139126SWyllys.Ingersoll@Sun.COM 	CK_ULONG, CK_CHAR_PTR, CK_ULONG);
1149126SWyllys.Ingersoll@Sun.COM CK_RV token_specific_verify_so_pin(TSS_HCONTEXT, CK_CHAR_PTR, CK_ULONG);
1159126SWyllys.Ingersoll@Sun.COM 
1169126SWyllys.Ingersoll@Sun.COM static CK_RV
1179126SWyllys.Ingersoll@Sun.COM token_specific_init(char *, CK_SLOT_ID, TSS_HCONTEXT *);
1189126SWyllys.Ingersoll@Sun.COM 
1199126SWyllys.Ingersoll@Sun.COM struct token_specific_struct token_specific = {
1209126SWyllys.Ingersoll@Sun.COM 	"TPM_Debug",
1219126SWyllys.Ingersoll@Sun.COM 	&token_specific_init,
1229126SWyllys.Ingersoll@Sun.COM 	NULL,
1239126SWyllys.Ingersoll@Sun.COM 	&token_rng,
1249126SWyllys.Ingersoll@Sun.COM 	&token_specific_session,
1259126SWyllys.Ingersoll@Sun.COM 	&token_specific_final,
1269126SWyllys.Ingersoll@Sun.COM 	&token_specific_rsa_decrypt,
1279126SWyllys.Ingersoll@Sun.COM 	&token_specific_rsa_encrypt,
1289126SWyllys.Ingersoll@Sun.COM 	&token_specific_rsa_sign,
1299126SWyllys.Ingersoll@Sun.COM 	&token_specific_rsa_verify,
1309126SWyllys.Ingersoll@Sun.COM 	&token_specific_rsa_generate_keypair,
1319126SWyllys.Ingersoll@Sun.COM 	NULL,
1329126SWyllys.Ingersoll@Sun.COM 	NULL,
1339126SWyllys.Ingersoll@Sun.COM 	NULL,
1349126SWyllys.Ingersoll@Sun.COM 	&token_specific_login,
1359126SWyllys.Ingersoll@Sun.COM 	&token_specific_logout,
1369126SWyllys.Ingersoll@Sun.COM 	&token_specific_init_pin,
1379126SWyllys.Ingersoll@Sun.COM 	&token_specific_set_pin,
1389126SWyllys.Ingersoll@Sun.COM 	&token_specific_verify_so_pin
1399126SWyllys.Ingersoll@Sun.COM };
1409126SWyllys.Ingersoll@Sun.COM 
1419126SWyllys.Ingersoll@Sun.COM /* The context we'll use globally to connect to the TSP */
1429126SWyllys.Ingersoll@Sun.COM 
1439126SWyllys.Ingersoll@Sun.COM /* TSP key handles */
1449126SWyllys.Ingersoll@Sun.COM TSS_HKEY hPublicRootKey = NULL_HKEY;
1459126SWyllys.Ingersoll@Sun.COM TSS_HKEY hPublicLeafKey = NULL_HKEY;
1469126SWyllys.Ingersoll@Sun.COM TSS_HKEY hPrivateRootKey = NULL_HKEY;
1479126SWyllys.Ingersoll@Sun.COM TSS_HKEY hPrivateLeafKey = NULL_HKEY;
1489126SWyllys.Ingersoll@Sun.COM 
1499126SWyllys.Ingersoll@Sun.COM TSS_UUID publicRootKeyUUID;
1509126SWyllys.Ingersoll@Sun.COM TSS_UUID publicLeafKeyUUID;
1519126SWyllys.Ingersoll@Sun.COM TSS_UUID privateRootKeyUUID;
1529126SWyllys.Ingersoll@Sun.COM TSS_UUID privateLeafKeyUUID;
1539126SWyllys.Ingersoll@Sun.COM 
1549126SWyllys.Ingersoll@Sun.COM /* TSP policy handles */
1559126SWyllys.Ingersoll@Sun.COM TSS_HPOLICY hDefaultPolicy = NULL_HPOLICY;
1569126SWyllys.Ingersoll@Sun.COM 
1579126SWyllys.Ingersoll@Sun.COM /* PKCS#11 key handles */
1589126SWyllys.Ingersoll@Sun.COM int not_initialized = 0;
1599126SWyllys.Ingersoll@Sun.COM 
1609126SWyllys.Ingersoll@Sun.COM CK_BYTE current_user_pin_sha[SHA1_DIGEST_LENGTH];
1619126SWyllys.Ingersoll@Sun.COM CK_BYTE current_so_pin_sha[SHA1_DIGEST_LENGTH];
1629126SWyllys.Ingersoll@Sun.COM 
1639126SWyllys.Ingersoll@Sun.COM static TPM_CAP_VERSION_INFO tpmvinfo;
1649126SWyllys.Ingersoll@Sun.COM 
1659126SWyllys.Ingersoll@Sun.COM static CK_RV
1669126SWyllys.Ingersoll@Sun.COM verify_user_pin(TSS_HCONTEXT, CK_BYTE *);
1679126SWyllys.Ingersoll@Sun.COM 
1689453SWyllys.Ingersoll@Sun.COM static TSS_RESULT
1699453SWyllys.Ingersoll@Sun.COM tss_assign_secret_key_policy(TSS_HCONTEXT, TSS_FLAG, TSS_HKEY, CK_CHAR *);
1709453SWyllys.Ingersoll@Sun.COM 
1719453SWyllys.Ingersoll@Sun.COM static TSS_RESULT
1729453SWyllys.Ingersoll@Sun.COM set_legacy_key_params(TSS_HKEY);
1739453SWyllys.Ingersoll@Sun.COM 
1749126SWyllys.Ingersoll@Sun.COM static void
local_uuid_clear(TSS_UUID * uuid)1759126SWyllys.Ingersoll@Sun.COM local_uuid_clear(TSS_UUID *uuid)
1769126SWyllys.Ingersoll@Sun.COM {
1779126SWyllys.Ingersoll@Sun.COM 	if (uuid == NULL)
1789126SWyllys.Ingersoll@Sun.COM 		return;
1799126SWyllys.Ingersoll@Sun.COM 	(void) memset(uuid, 0, sizeof (TSS_UUID));
1809126SWyllys.Ingersoll@Sun.COM }
1819126SWyllys.Ingersoll@Sun.COM 
1829126SWyllys.Ingersoll@Sun.COM 
1839126SWyllys.Ingersoll@Sun.COM /* convert from TSS_UUID to uuid_t */
1849126SWyllys.Ingersoll@Sun.COM static void
tss_uuid_convert_from(TSS_UUID * uu,uuid_t ptr)1859126SWyllys.Ingersoll@Sun.COM tss_uuid_convert_from(TSS_UUID *uu, uuid_t ptr)
1869126SWyllys.Ingersoll@Sun.COM {
1879126SWyllys.Ingersoll@Sun.COM 	uint_t		tmp;
1889126SWyllys.Ingersoll@Sun.COM 	uchar_t		*out = ptr;
1899126SWyllys.Ingersoll@Sun.COM 
1909126SWyllys.Ingersoll@Sun.COM 	tmp = ntohl(uu->ulTimeLow);
1919126SWyllys.Ingersoll@Sun.COM 	out[3] = (uchar_t)tmp;
1929126SWyllys.Ingersoll@Sun.COM 	tmp >>= 8;
1939126SWyllys.Ingersoll@Sun.COM 	out[2] = (uchar_t)tmp;
1949126SWyllys.Ingersoll@Sun.COM 	tmp >>= 8;
1959126SWyllys.Ingersoll@Sun.COM 	out[1] = (uchar_t)tmp;
1969126SWyllys.Ingersoll@Sun.COM 	tmp >>= 8;
1979126SWyllys.Ingersoll@Sun.COM 	out[0] = (uchar_t)tmp;
1989126SWyllys.Ingersoll@Sun.COM 
1999126SWyllys.Ingersoll@Sun.COM 	tmp = ntohs(uu->usTimeMid);
2009126SWyllys.Ingersoll@Sun.COM 	out[5] = (uchar_t)tmp;
2019126SWyllys.Ingersoll@Sun.COM 	tmp >>= 8;
2029126SWyllys.Ingersoll@Sun.COM 	out[4] = (uchar_t)tmp;
2039126SWyllys.Ingersoll@Sun.COM 
2049126SWyllys.Ingersoll@Sun.COM 	tmp = ntohs(uu->usTimeHigh);
2059126SWyllys.Ingersoll@Sun.COM 	out[7] = (uchar_t)tmp;
2069126SWyllys.Ingersoll@Sun.COM 	tmp >>= 8;
2079126SWyllys.Ingersoll@Sun.COM 	out[6] = (uchar_t)tmp;
2089126SWyllys.Ingersoll@Sun.COM 
2099126SWyllys.Ingersoll@Sun.COM 	tmp = uu->bClockSeqHigh;
2109126SWyllys.Ingersoll@Sun.COM 	out[8] = (uchar_t)tmp;
2119126SWyllys.Ingersoll@Sun.COM 	tmp = uu->bClockSeqLow;
2129126SWyllys.Ingersoll@Sun.COM 	out[9] = (uchar_t)tmp;
2139126SWyllys.Ingersoll@Sun.COM 
2149126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(out+10, uu->rgbNode, 6);
2159126SWyllys.Ingersoll@Sun.COM }
2169126SWyllys.Ingersoll@Sun.COM 
2179126SWyllys.Ingersoll@Sun.COM /* convert from uuid_t to TSS_UUID */
2189126SWyllys.Ingersoll@Sun.COM static void
tss_uuid_convert_to(TSS_UUID * uuid,uuid_t in)2199126SWyllys.Ingersoll@Sun.COM tss_uuid_convert_to(TSS_UUID *uuid, uuid_t in)
2209126SWyllys.Ingersoll@Sun.COM {
2219126SWyllys.Ingersoll@Sun.COM 	uchar_t		*ptr;
2229126SWyllys.Ingersoll@Sun.COM 	uint32_t	ltmp;
2239126SWyllys.Ingersoll@Sun.COM 	uint16_t	stmp;
2249126SWyllys.Ingersoll@Sun.COM 
2259126SWyllys.Ingersoll@Sun.COM 	ptr = in;
2269126SWyllys.Ingersoll@Sun.COM 
2279126SWyllys.Ingersoll@Sun.COM 	ltmp = *ptr++;
2289126SWyllys.Ingersoll@Sun.COM 	ltmp = (ltmp << 8) | *ptr++;
2299126SWyllys.Ingersoll@Sun.COM 	ltmp = (ltmp << 8) | *ptr++;
2309126SWyllys.Ingersoll@Sun.COM 	ltmp = (ltmp << 8) | *ptr++;
2319126SWyllys.Ingersoll@Sun.COM 	uuid->ulTimeLow = ntohl(ltmp);
2329126SWyllys.Ingersoll@Sun.COM 
2339126SWyllys.Ingersoll@Sun.COM 	stmp = *ptr++;
2349126SWyllys.Ingersoll@Sun.COM 	stmp = (stmp << 8) | *ptr++;
2359126SWyllys.Ingersoll@Sun.COM 	uuid->usTimeMid = ntohs(stmp);
2369126SWyllys.Ingersoll@Sun.COM 
2379126SWyllys.Ingersoll@Sun.COM 	stmp = *ptr++;
2389126SWyllys.Ingersoll@Sun.COM 	stmp = (stmp << 8) | *ptr++;
2399126SWyllys.Ingersoll@Sun.COM 	uuid->usTimeHigh = ntohs(stmp);
2409126SWyllys.Ingersoll@Sun.COM 
2419126SWyllys.Ingersoll@Sun.COM 	uuid->bClockSeqHigh = *ptr++;
2429126SWyllys.Ingersoll@Sun.COM 
2439126SWyllys.Ingersoll@Sun.COM 	uuid->bClockSeqLow = *ptr++;
2449126SWyllys.Ingersoll@Sun.COM 
2459126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(uuid->rgbNode, ptr, 6);
2469126SWyllys.Ingersoll@Sun.COM }
2479126SWyllys.Ingersoll@Sun.COM 
2489126SWyllys.Ingersoll@Sun.COM static void
local_uuid_copy(TSS_UUID * dst,TSS_UUID * src)2499126SWyllys.Ingersoll@Sun.COM local_uuid_copy(TSS_UUID *dst, TSS_UUID *src)
2509126SWyllys.Ingersoll@Sun.COM {
2519126SWyllys.Ingersoll@Sun.COM 	uuid_t udst, usrc;
2529126SWyllys.Ingersoll@Sun.COM 
2539126SWyllys.Ingersoll@Sun.COM 	tss_uuid_convert_from(dst, udst);
2549126SWyllys.Ingersoll@Sun.COM 	tss_uuid_convert_from(src, usrc);
2559126SWyllys.Ingersoll@Sun.COM 
2569126SWyllys.Ingersoll@Sun.COM 	uuid_copy(udst, usrc);
2579126SWyllys.Ingersoll@Sun.COM 
2589126SWyllys.Ingersoll@Sun.COM 	tss_uuid_convert_to(dst, udst);
2599126SWyllys.Ingersoll@Sun.COM }
2609126SWyllys.Ingersoll@Sun.COM 
2619126SWyllys.Ingersoll@Sun.COM static void
local_uuid_generate(TSS_UUID * uu)2629126SWyllys.Ingersoll@Sun.COM local_uuid_generate(TSS_UUID *uu)
2639126SWyllys.Ingersoll@Sun.COM {
2649126SWyllys.Ingersoll@Sun.COM 	uuid_t newuuid;
2659126SWyllys.Ingersoll@Sun.COM 
2669126SWyllys.Ingersoll@Sun.COM 	uuid_generate(newuuid);
2679126SWyllys.Ingersoll@Sun.COM 
2689126SWyllys.Ingersoll@Sun.COM 	tss_uuid_convert_to(uu, newuuid);
2699126SWyllys.Ingersoll@Sun.COM }
2709126SWyllys.Ingersoll@Sun.COM 
2719126SWyllys.Ingersoll@Sun.COM static int
local_copy_file(char * dst,char * src)2729126SWyllys.Ingersoll@Sun.COM local_copy_file(char *dst, char *src)
2739126SWyllys.Ingersoll@Sun.COM {
2749126SWyllys.Ingersoll@Sun.COM 	FILE *fdest, *fsrc;
2759126SWyllys.Ingersoll@Sun.COM 	char line[BUFSIZ];
2769126SWyllys.Ingersoll@Sun.COM 
2779126SWyllys.Ingersoll@Sun.COM 	fdest = fopen(dst, "w");
2789126SWyllys.Ingersoll@Sun.COM 	if (fdest == NULL)
2799126SWyllys.Ingersoll@Sun.COM 		return (-1);
2809126SWyllys.Ingersoll@Sun.COM 
2819126SWyllys.Ingersoll@Sun.COM 	fsrc = fopen(src, "r");
2829126SWyllys.Ingersoll@Sun.COM 	if (fsrc == NULL) {
2839126SWyllys.Ingersoll@Sun.COM 		(void) fclose(fdest);
2849126SWyllys.Ingersoll@Sun.COM 		return (-1);
2859126SWyllys.Ingersoll@Sun.COM 	}
2869126SWyllys.Ingersoll@Sun.COM 
2879126SWyllys.Ingersoll@Sun.COM 	while (fread(line, sizeof (line), 1, fsrc))
2889126SWyllys.Ingersoll@Sun.COM 		(void) fprintf(fdest, "%s\n", line);
2899126SWyllys.Ingersoll@Sun.COM 	(void) fclose(fsrc);
2909126SWyllys.Ingersoll@Sun.COM 	(void) fclose(fdest);
2919126SWyllys.Ingersoll@Sun.COM 	return (0);
2929126SWyllys.Ingersoll@Sun.COM }
2939126SWyllys.Ingersoll@Sun.COM 
2949126SWyllys.Ingersoll@Sun.COM static int
remove_uuid(char * keyname)2959126SWyllys.Ingersoll@Sun.COM remove_uuid(char *keyname)
2969126SWyllys.Ingersoll@Sun.COM {
2979126SWyllys.Ingersoll@Sun.COM 	int ret = 0;
2989126SWyllys.Ingersoll@Sun.COM 	FILE *fp, *newfp;
2999126SWyllys.Ingersoll@Sun.COM 	char fname[MAXPATHLEN];
3009126SWyllys.Ingersoll@Sun.COM 	char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ];
3019126SWyllys.Ingersoll@Sun.COM 	char *tmpfname;
3029126SWyllys.Ingersoll@Sun.COM 	char *p = get_tpm_keystore_path();
3039126SWyllys.Ingersoll@Sun.COM 
3049126SWyllys.Ingersoll@Sun.COM 	if (p == NULL)
3059126SWyllys.Ingersoll@Sun.COM 		return (-1);
3069126SWyllys.Ingersoll@Sun.COM 
3079126SWyllys.Ingersoll@Sun.COM 	(void) snprintf(fname, sizeof (fname),
3089126SWyllys.Ingersoll@Sun.COM 	    "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME);
3099126SWyllys.Ingersoll@Sun.COM 
3109126SWyllys.Ingersoll@Sun.COM 	fp = fopen(fname, "r");
3119126SWyllys.Ingersoll@Sun.COM 	if (fp == NULL) {
3129126SWyllys.Ingersoll@Sun.COM 		return (-1);
3139126SWyllys.Ingersoll@Sun.COM 	}
3149126SWyllys.Ingersoll@Sun.COM 
3159126SWyllys.Ingersoll@Sun.COM 	tmpfname = tempnam("/tmp", "tpmtok");
3169126SWyllys.Ingersoll@Sun.COM 	newfp = fopen(tmpfname, "w+");
3179126SWyllys.Ingersoll@Sun.COM 	if (newfp == NULL) {
3189126SWyllys.Ingersoll@Sun.COM 		free(tmpfname);
3199126SWyllys.Ingersoll@Sun.COM 		(void) fclose(fp);
3209126SWyllys.Ingersoll@Sun.COM 		return (-1);
3219126SWyllys.Ingersoll@Sun.COM 	}
3229126SWyllys.Ingersoll@Sun.COM 
3239126SWyllys.Ingersoll@Sun.COM 	while (!feof(fp)) {
3249126SWyllys.Ingersoll@Sun.COM 		(void) fgets(line, sizeof (line), fp);
3259126SWyllys.Ingersoll@Sun.COM 		if (sscanf(line, "%1024s %1024s", key, idstr) == 2) {
3269126SWyllys.Ingersoll@Sun.COM 			if (strcmp(key, keyname))
3279126SWyllys.Ingersoll@Sun.COM 				(void) fprintf(newfp, "%s\n", line);
3289126SWyllys.Ingersoll@Sun.COM 		}
3299126SWyllys.Ingersoll@Sun.COM 	}
3309126SWyllys.Ingersoll@Sun.COM 
3319126SWyllys.Ingersoll@Sun.COM 	(void) fclose(fp);
3329126SWyllys.Ingersoll@Sun.COM 	(void) fclose(newfp);
3339126SWyllys.Ingersoll@Sun.COM 	if (local_copy_file(fname, tmpfname) == 0)
3349126SWyllys.Ingersoll@Sun.COM 		(void) unlink(tmpfname);
3359126SWyllys.Ingersoll@Sun.COM 
3369126SWyllys.Ingersoll@Sun.COM 	free(tmpfname);
3379126SWyllys.Ingersoll@Sun.COM 
3389126SWyllys.Ingersoll@Sun.COM 	return (ret);
3399126SWyllys.Ingersoll@Sun.COM }
3409126SWyllys.Ingersoll@Sun.COM 
3419126SWyllys.Ingersoll@Sun.COM static int
find_uuid(char * keyname,TSS_UUID * uu)3429126SWyllys.Ingersoll@Sun.COM find_uuid(char *keyname, TSS_UUID *uu)
3439126SWyllys.Ingersoll@Sun.COM {
3449126SWyllys.Ingersoll@Sun.COM 	int ret = 0, found = 0;
3459126SWyllys.Ingersoll@Sun.COM 	FILE *fp = NULL;
3469126SWyllys.Ingersoll@Sun.COM 	char fname[MAXPATHLEN];
3479126SWyllys.Ingersoll@Sun.COM 	char line[BUFSIZ], key[BUFSIZ], idstr[BUFSIZ];
3489126SWyllys.Ingersoll@Sun.COM 	uuid_t uuid;
3499126SWyllys.Ingersoll@Sun.COM 	char *p = get_tpm_keystore_path();
3509126SWyllys.Ingersoll@Sun.COM 
3519126SWyllys.Ingersoll@Sun.COM 	if (p == NULL)
3529126SWyllys.Ingersoll@Sun.COM 		return (-1);
3539126SWyllys.Ingersoll@Sun.COM 
3549126SWyllys.Ingersoll@Sun.COM 	tss_uuid_convert_from(uu, uuid);
3559126SWyllys.Ingersoll@Sun.COM 
3569126SWyllys.Ingersoll@Sun.COM 	(void) snprintf(fname, sizeof (fname),
3579126SWyllys.Ingersoll@Sun.COM 	    "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME);
3589126SWyllys.Ingersoll@Sun.COM 
3599126SWyllys.Ingersoll@Sun.COM 	/* Open UUID Index file */
3609126SWyllys.Ingersoll@Sun.COM 	fp = fopen(fname, "r");
3619126SWyllys.Ingersoll@Sun.COM 	if (fp == NULL) {
3629126SWyllys.Ingersoll@Sun.COM 		if (errno == ENOENT) {
3639126SWyllys.Ingersoll@Sun.COM 			/* initialize the file */
3649126SWyllys.Ingersoll@Sun.COM 			fp = fopen(fname, "w");
3659126SWyllys.Ingersoll@Sun.COM 			if (fp != NULL)
3669126SWyllys.Ingersoll@Sun.COM 				(void) fclose(fp);
3679126SWyllys.Ingersoll@Sun.COM 		}
3689126SWyllys.Ingersoll@Sun.COM 		return (-1);
3699126SWyllys.Ingersoll@Sun.COM 	}
3709126SWyllys.Ingersoll@Sun.COM 
3719126SWyllys.Ingersoll@Sun.COM 	while (!feof(fp)) {
3729126SWyllys.Ingersoll@Sun.COM 		(void) fgets(line, sizeof (line), fp);
3739126SWyllys.Ingersoll@Sun.COM 		if (sscanf(line, "%1024s %1024s", key, idstr) == 2) {
3749126SWyllys.Ingersoll@Sun.COM 			if (strcmp(key, keyname) == 0) {
3759126SWyllys.Ingersoll@Sun.COM 				ret = uuid_parse(idstr, uuid);
3769126SWyllys.Ingersoll@Sun.COM 				if (ret == 0) {
3779126SWyllys.Ingersoll@Sun.COM 					found = 1;
3789126SWyllys.Ingersoll@Sun.COM 					tss_uuid_convert_to(uu,
3799126SWyllys.Ingersoll@Sun.COM 					    uuid);
3809126SWyllys.Ingersoll@Sun.COM 				}
3819126SWyllys.Ingersoll@Sun.COM 				break;
3829126SWyllys.Ingersoll@Sun.COM 			}
3839126SWyllys.Ingersoll@Sun.COM 		}
3849126SWyllys.Ingersoll@Sun.COM 	}
3859126SWyllys.Ingersoll@Sun.COM 	(void) fclose(fp);
3869126SWyllys.Ingersoll@Sun.COM 
3879126SWyllys.Ingersoll@Sun.COM 	if (!found)
3889126SWyllys.Ingersoll@Sun.COM 		ret = -1;
3899126SWyllys.Ingersoll@Sun.COM 	return (ret);
3909126SWyllys.Ingersoll@Sun.COM }
3919126SWyllys.Ingersoll@Sun.COM 
3929126SWyllys.Ingersoll@Sun.COM static int
local_uuid_is_null(TSS_UUID * uu)3939126SWyllys.Ingersoll@Sun.COM local_uuid_is_null(TSS_UUID *uu)
3949126SWyllys.Ingersoll@Sun.COM {
3959126SWyllys.Ingersoll@Sun.COM 	uuid_t uuid;
3969126SWyllys.Ingersoll@Sun.COM 	int nulluuid;
3979126SWyllys.Ingersoll@Sun.COM 
3989126SWyllys.Ingersoll@Sun.COM 	tss_uuid_convert_from(uu, uuid);
3999126SWyllys.Ingersoll@Sun.COM 
4009126SWyllys.Ingersoll@Sun.COM 	nulluuid = uuid_is_null(uuid);
4019126SWyllys.Ingersoll@Sun.COM 	return (nulluuid);
4029126SWyllys.Ingersoll@Sun.COM }
4039126SWyllys.Ingersoll@Sun.COM 
4049126SWyllys.Ingersoll@Sun.COM static int
add_uuid(char * keyname,TSS_UUID * uu)4059126SWyllys.Ingersoll@Sun.COM add_uuid(char *keyname, TSS_UUID *uu)
4069126SWyllys.Ingersoll@Sun.COM {
4079126SWyllys.Ingersoll@Sun.COM 	FILE *fp = NULL;
4089126SWyllys.Ingersoll@Sun.COM 	char fname[MAXPATHLEN];
4099126SWyllys.Ingersoll@Sun.COM 	char idstr[BUFSIZ];
4109126SWyllys.Ingersoll@Sun.COM 	uuid_t uuid;
4119126SWyllys.Ingersoll@Sun.COM 	char *p = get_tpm_keystore_path();
4129126SWyllys.Ingersoll@Sun.COM 
4139126SWyllys.Ingersoll@Sun.COM 	if (p == NULL)
4149126SWyllys.Ingersoll@Sun.COM 		return (-1);
4159126SWyllys.Ingersoll@Sun.COM 
4169126SWyllys.Ingersoll@Sun.COM 	tss_uuid_convert_from(uu, uuid);
4179126SWyllys.Ingersoll@Sun.COM 
4189126SWyllys.Ingersoll@Sun.COM 	if (uuid_is_null(uuid))
4199126SWyllys.Ingersoll@Sun.COM 		return (-1);
4209126SWyllys.Ingersoll@Sun.COM 
4219126SWyllys.Ingersoll@Sun.COM 	uuid_unparse(uuid, idstr);
4229126SWyllys.Ingersoll@Sun.COM 
4239126SWyllys.Ingersoll@Sun.COM 	(void) snprintf(fname, sizeof (fname),
4249126SWyllys.Ingersoll@Sun.COM 	    "%s/%s", p, TPMTOK_UUID_INDEX_FILENAME);
4259126SWyllys.Ingersoll@Sun.COM 
4269126SWyllys.Ingersoll@Sun.COM 	fp = fopen(fname, "a");
4279126SWyllys.Ingersoll@Sun.COM 	if (fp == NULL)
4289126SWyllys.Ingersoll@Sun.COM 		return (-1);
4299126SWyllys.Ingersoll@Sun.COM 
4309126SWyllys.Ingersoll@Sun.COM 	(void) fprintf(fp, "%s %s\n", keyname, idstr);
4319126SWyllys.Ingersoll@Sun.COM 	(void) fclose(fp);
4329126SWyllys.Ingersoll@Sun.COM 
4339126SWyllys.Ingersoll@Sun.COM 	return (0);
4349126SWyllys.Ingersoll@Sun.COM }
4359126SWyllys.Ingersoll@Sun.COM 
4369126SWyllys.Ingersoll@Sun.COM 
4379126SWyllys.Ingersoll@Sun.COM static UINT32
util_get_keysize_flag(CK_ULONG size)4389126SWyllys.Ingersoll@Sun.COM util_get_keysize_flag(CK_ULONG size)
4399126SWyllys.Ingersoll@Sun.COM {
4409126SWyllys.Ingersoll@Sun.COM 	switch (size) {
4419126SWyllys.Ingersoll@Sun.COM 		case 512:
4429126SWyllys.Ingersoll@Sun.COM 			return (TSS_KEY_SIZE_512);
4439126SWyllys.Ingersoll@Sun.COM 			break;
4449126SWyllys.Ingersoll@Sun.COM 		case 1024:
4459126SWyllys.Ingersoll@Sun.COM 			return (TSS_KEY_SIZE_1024);
4469126SWyllys.Ingersoll@Sun.COM 			break;
4479126SWyllys.Ingersoll@Sun.COM 		case 2048:
4489126SWyllys.Ingersoll@Sun.COM 			return (TSS_KEY_SIZE_2048);
4499126SWyllys.Ingersoll@Sun.COM 			break;
4509126SWyllys.Ingersoll@Sun.COM 		default:
4519126SWyllys.Ingersoll@Sun.COM 			break;
4529126SWyllys.Ingersoll@Sun.COM 	}
4539126SWyllys.Ingersoll@Sun.COM 
4549126SWyllys.Ingersoll@Sun.COM 	return (0);
4559126SWyllys.Ingersoll@Sun.COM }
4569126SWyllys.Ingersoll@Sun.COM 
4579126SWyllys.Ingersoll@Sun.COM /* make sure the public exponent attribute is 65537 */
4589126SWyllys.Ingersoll@Sun.COM static CK_ULONG
util_check_public_exponent(TEMPLATE * tmpl)4599126SWyllys.Ingersoll@Sun.COM util_check_public_exponent(TEMPLATE *tmpl)
4609126SWyllys.Ingersoll@Sun.COM {
4619126SWyllys.Ingersoll@Sun.COM 	CK_BBOOL flag;
4629126SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE *publ_exp_attr;
4639126SWyllys.Ingersoll@Sun.COM 	CK_BYTE pubexp_bytes[] = { 1, 0, 1 };
4649126SWyllys.Ingersoll@Sun.COM 	CK_ULONG publ_exp, rc = 1;
4659126SWyllys.Ingersoll@Sun.COM 
4669126SWyllys.Ingersoll@Sun.COM 	flag = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT,
4679126SWyllys.Ingersoll@Sun.COM 	    &publ_exp_attr);
4689126SWyllys.Ingersoll@Sun.COM 	if (!flag) {
4699126SWyllys.Ingersoll@Sun.COM 		LogError1("Couldn't find public exponent attribute");
4709126SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCOMPLETE);
4719126SWyllys.Ingersoll@Sun.COM 	}
4729126SWyllys.Ingersoll@Sun.COM 
4739126SWyllys.Ingersoll@Sun.COM 	switch (publ_exp_attr->ulValueLen) {
4749126SWyllys.Ingersoll@Sun.COM 		case 3:
4759126SWyllys.Ingersoll@Sun.COM 			rc = memcmp(pubexp_bytes, publ_exp_attr->pValue, 3);
4769126SWyllys.Ingersoll@Sun.COM 			break;
4779126SWyllys.Ingersoll@Sun.COM 		case sizeof (CK_ULONG):
4789126SWyllys.Ingersoll@Sun.COM 			publ_exp = *((CK_ULONG *)publ_exp_attr->pValue);
4799126SWyllys.Ingersoll@Sun.COM 			if (publ_exp == 65537)
4809126SWyllys.Ingersoll@Sun.COM 				rc = 0;
4819126SWyllys.Ingersoll@Sun.COM 			break;
4829126SWyllys.Ingersoll@Sun.COM 		default:
4839126SWyllys.Ingersoll@Sun.COM 			break;
4849126SWyllys.Ingersoll@Sun.COM 	}
4859126SWyllys.Ingersoll@Sun.COM 
4869126SWyllys.Ingersoll@Sun.COM 	return (rc);
4879126SWyllys.Ingersoll@Sun.COM }
4889126SWyllys.Ingersoll@Sun.COM 
4899126SWyllys.Ingersoll@Sun.COM TSS_RESULT
set_public_modulus(TSS_HCONTEXT hContext,TSS_HKEY hKey,unsigned long size_n,unsigned char * n)4909126SWyllys.Ingersoll@Sun.COM set_public_modulus(TSS_HCONTEXT hContext, TSS_HKEY hKey,
4919126SWyllys.Ingersoll@Sun.COM 	unsigned long size_n, unsigned char *n)
4929126SWyllys.Ingersoll@Sun.COM {
4939126SWyllys.Ingersoll@Sun.COM 	UINT64 offset;
4949126SWyllys.Ingersoll@Sun.COM 	UINT32 blob_size;
4959126SWyllys.Ingersoll@Sun.COM 	BYTE *blob, pub_blob[1024];
4969126SWyllys.Ingersoll@Sun.COM 	TCPA_PUBKEY pub_key;
4979126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
4989126SWyllys.Ingersoll@Sun.COM 
4999126SWyllys.Ingersoll@Sun.COM 	/* Get the TCPA_PUBKEY blob from the key object. */
5009126SWyllys.Ingersoll@Sun.COM 	result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
5019126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blob_size, &blob);
5029126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
5039126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetAttribData failed: rc=0x%0x - %s\n",
5049126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
5059126SWyllys.Ingersoll@Sun.COM 		return (result);
5069126SWyllys.Ingersoll@Sun.COM 	}
5079126SWyllys.Ingersoll@Sun.COM 
5089126SWyllys.Ingersoll@Sun.COM 	offset = 0;
5099126SWyllys.Ingersoll@Sun.COM 	result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pub_key);
5109126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
5119126SWyllys.Ingersoll@Sun.COM 		stlogit("Trspi_UnloadBlob_PUBKEY failed: rc=0x%0x - %s\n",
5129126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
5139126SWyllys.Ingersoll@Sun.COM 		return (result);
5149126SWyllys.Ingersoll@Sun.COM 	}
5159126SWyllys.Ingersoll@Sun.COM 
5169126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, blob);
5179126SWyllys.Ingersoll@Sun.COM 	/* Free the first dangling reference, putting 'n' in its place */
5189126SWyllys.Ingersoll@Sun.COM 	free(pub_key.pubKey.key);
5199126SWyllys.Ingersoll@Sun.COM 	pub_key.pubKey.keyLength = size_n;
5209126SWyllys.Ingersoll@Sun.COM 	pub_key.pubKey.key = n;
5219126SWyllys.Ingersoll@Sun.COM 
5229126SWyllys.Ingersoll@Sun.COM 	offset = 0;
5239126SWyllys.Ingersoll@Sun.COM 	Trspi_LoadBlob_PUBKEY(&offset, pub_blob, &pub_key);
5249126SWyllys.Ingersoll@Sun.COM 
5259126SWyllys.Ingersoll@Sun.COM 	/* Free the second dangling reference */
5269126SWyllys.Ingersoll@Sun.COM 	free(pub_key.algorithmParms.parms);
5279126SWyllys.Ingersoll@Sun.COM 
5289126SWyllys.Ingersoll@Sun.COM 	/* set the public key data in the TSS object */
5299126SWyllys.Ingersoll@Sun.COM 	result = Tspi_SetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
5309126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, (UINT32)offset, pub_blob);
5319126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
5329126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_SetAttribData failed: rc=0x%0x - %s\n",
5339126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
5349126SWyllys.Ingersoll@Sun.COM 		return (result);
5359126SWyllys.Ingersoll@Sun.COM 	}
5369126SWyllys.Ingersoll@Sun.COM 
5379126SWyllys.Ingersoll@Sun.COM 	return (result);
5389126SWyllys.Ingersoll@Sun.COM }
5399126SWyllys.Ingersoll@Sun.COM 
5409126SWyllys.Ingersoll@Sun.COM /*
5419126SWyllys.Ingersoll@Sun.COM  * Get details about the TPM to put into the token_info structure.
5429126SWyllys.Ingersoll@Sun.COM  */
5439126SWyllys.Ingersoll@Sun.COM CK_RV
token_get_tpm_info(TSS_HCONTEXT hContext,TOKEN_DATA * td)5449126SWyllys.Ingersoll@Sun.COM token_get_tpm_info(TSS_HCONTEXT hContext, TOKEN_DATA *td)
5459126SWyllys.Ingersoll@Sun.COM {
5469126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
5479126SWyllys.Ingersoll@Sun.COM 	TPM_CAPABILITY_AREA capArea = TSS_TPMCAP_VERSION_VAL;
5489126SWyllys.Ingersoll@Sun.COM 	UINT32 datalen;
5499126SWyllys.Ingersoll@Sun.COM 	BYTE *data;
5509126SWyllys.Ingersoll@Sun.COM 	TSS_HTPM hTPM;
5519126SWyllys.Ingersoll@Sun.COM 
5529126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) {
5539126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s",
5549126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
5559126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
5569126SWyllys.Ingersoll@Sun.COM 	}
5579126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_TPM_GetCapability(hTPM,
5589126SWyllys.Ingersoll@Sun.COM 	    capArea, 0, NULL, &datalen, &data)) != 0 || datalen == 0 ||
5599126SWyllys.Ingersoll@Sun.COM 	    data == NULL) {
5609126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_GetCapability: 0x%0x - %s",
5619126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
5629126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
5639126SWyllys.Ingersoll@Sun.COM 	}
5649126SWyllys.Ingersoll@Sun.COM 	if (datalen > sizeof (tpmvinfo)) {
5659126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, data);
5669126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
5679126SWyllys.Ingersoll@Sun.COM 	}
5689126SWyllys.Ingersoll@Sun.COM 
56910134Swyllys.ingersoll@sun.com 	(void) memcpy(&tpmvinfo, (void *)data, datalen);
5709126SWyllys.Ingersoll@Sun.COM 
5719126SWyllys.Ingersoll@Sun.COM 	bzero(td->token_info.manufacturerID,
5729126SWyllys.Ingersoll@Sun.COM 	    sizeof (td->token_info.manufacturerID));
5739126SWyllys.Ingersoll@Sun.COM 
5749126SWyllys.Ingersoll@Sun.COM 	(void) memset(td->token_info.manufacturerID,  ' ',
5759126SWyllys.Ingersoll@Sun.COM 	    sizeof (td->token_info.manufacturerID) - 1);
57610134Swyllys.ingersoll@sun.com 
5779126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(td->token_info.manufacturerID,
5789126SWyllys.Ingersoll@Sun.COM 	    tpmvinfo.tpmVendorID, sizeof (tpmvinfo.tpmVendorID));
5799126SWyllys.Ingersoll@Sun.COM 
5809126SWyllys.Ingersoll@Sun.COM 	(void) memset(td->token_info.label, ' ',
5819126SWyllys.Ingersoll@Sun.COM 	    sizeof (td->token_info.label) - 1);
58210134Swyllys.ingersoll@sun.com 
58310134Swyllys.ingersoll@sun.com 	(void) memcpy(td->token_info.label, "TPM", 3);
5849126SWyllys.Ingersoll@Sun.COM 
5859126SWyllys.Ingersoll@Sun.COM 	td->token_info.hardwareVersion.major = tpmvinfo.version.major;
5869126SWyllys.Ingersoll@Sun.COM 	td->token_info.hardwareVersion.minor = tpmvinfo.version.minor;
5879126SWyllys.Ingersoll@Sun.COM 	td->token_info.firmwareVersion.major = tpmvinfo.version.revMajor;
5889126SWyllys.Ingersoll@Sun.COM 	td->token_info.firmwareVersion.minor = tpmvinfo.version.revMinor;
5899126SWyllys.Ingersoll@Sun.COM 
5909126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, data);
5919126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
5929126SWyllys.Ingersoll@Sun.COM }
5939126SWyllys.Ingersoll@Sun.COM 
5949126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/
5959126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_session(CK_SLOT_ID slotid)5969126SWyllys.Ingersoll@Sun.COM token_specific_session(CK_SLOT_ID  slotid)
5979126SWyllys.Ingersoll@Sun.COM {
5989126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
5999126SWyllys.Ingersoll@Sun.COM }
6009126SWyllys.Ingersoll@Sun.COM 
6019126SWyllys.Ingersoll@Sun.COM CK_RV
token_rng(TSS_HCONTEXT hContext,CK_BYTE * output,CK_ULONG bytes)6029126SWyllys.Ingersoll@Sun.COM token_rng(TSS_HCONTEXT hContext, CK_BYTE *output, CK_ULONG bytes)
6039126SWyllys.Ingersoll@Sun.COM {
6049126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT rc;
6059126SWyllys.Ingersoll@Sun.COM 	TSS_HTPM hTPM;
6069126SWyllys.Ingersoll@Sun.COM 	BYTE *random_bytes = NULL;
6079126SWyllys.Ingersoll@Sun.COM 
6089126SWyllys.Ingersoll@Sun.COM 	if ((rc = Tspi_Context_GetTpmObject(hContext, &hTPM))) {
6099126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s",
6109126SWyllys.Ingersoll@Sun.COM 		    rc, Trspi_Error_String(rc));
6119126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
6129126SWyllys.Ingersoll@Sun.COM 	}
6139126SWyllys.Ingersoll@Sun.COM 
6149126SWyllys.Ingersoll@Sun.COM 	if ((rc = Tspi_TPM_GetRandom(hTPM, bytes, &random_bytes))) {
6159126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_TPM_GetRandom: 0x%0x - %s",
6169126SWyllys.Ingersoll@Sun.COM 		    rc, Trspi_Error_String(rc));
6179126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
6189126SWyllys.Ingersoll@Sun.COM 	}
6199126SWyllys.Ingersoll@Sun.COM 
6209126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(output, random_bytes, bytes);
6219126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, random_bytes);
6229126SWyllys.Ingersoll@Sun.COM 
6239126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
6249126SWyllys.Ingersoll@Sun.COM }
6259126SWyllys.Ingersoll@Sun.COM 
6269126SWyllys.Ingersoll@Sun.COM TSS_RESULT
open_tss_context(TSS_HCONTEXT * pContext)6279126SWyllys.Ingersoll@Sun.COM open_tss_context(TSS_HCONTEXT *pContext)
6289126SWyllys.Ingersoll@Sun.COM {
6299126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
6309126SWyllys.Ingersoll@Sun.COM 
6319126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_Create(pContext))) {
6329126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_Create: 0x%0x - %s",
6339126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
6349126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
6359126SWyllys.Ingersoll@Sun.COM 	}
6369126SWyllys.Ingersoll@Sun.COM 
6379126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_Connect(*pContext, NULL))) {
6389126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_Connect: 0x%0x - %s",
6399126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
640*11747Swyllys.ingersoll@sun.com 		Tspi_Context_Close(*pContext);
641*11747Swyllys.ingersoll@sun.com 		*pContext = 0;
6429126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
6439126SWyllys.Ingersoll@Sun.COM 	}
6449126SWyllys.Ingersoll@Sun.COM 	return (result);
6459126SWyllys.Ingersoll@Sun.COM }
6469126SWyllys.Ingersoll@Sun.COM 
6479126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/
6489126SWyllys.Ingersoll@Sun.COM static CK_RV
token_specific_init(char * Correlator,CK_SLOT_ID SlotNumber,TSS_HCONTEXT * hContext)6499126SWyllys.Ingersoll@Sun.COM token_specific_init(char *Correlator, CK_SLOT_ID SlotNumber,
6509126SWyllys.Ingersoll@Sun.COM     TSS_HCONTEXT *hContext)
6519126SWyllys.Ingersoll@Sun.COM {
6529126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
6539126SWyllys.Ingersoll@Sun.COM 
6549126SWyllys.Ingersoll@Sun.COM 	result = open_tss_context(hContext);
6559126SWyllys.Ingersoll@Sun.COM 	if (result)
6569126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
6579126SWyllys.Ingersoll@Sun.COM 
6589126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_GetDefaultPolicy(*hContext,
6599126SWyllys.Ingersoll@Sun.COM 	    &hDefaultPolicy))) {
6609126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_GetDefaultPolicy: 0x%0x - %s",
6619126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
6629126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
6639126SWyllys.Ingersoll@Sun.COM 	}
6649126SWyllys.Ingersoll@Sun.COM 
6659126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&publicRootKeyUUID);
6669126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&privateRootKeyUUID);
6679126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&publicLeafKeyUUID);
6689126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&privateLeafKeyUUID);
6699126SWyllys.Ingersoll@Sun.COM 
6709126SWyllys.Ingersoll@Sun.COM 	result = token_get_tpm_info(*hContext, nv_token_data);
6719126SWyllys.Ingersoll@Sun.COM 	return (result);
6729126SWyllys.Ingersoll@Sun.COM }
6739126SWyllys.Ingersoll@Sun.COM 
6749126SWyllys.Ingersoll@Sun.COM /*
6759126SWyllys.Ingersoll@Sun.COM  * Given a modulus and prime from an RSA key, create a TSS_HKEY object by
6769126SWyllys.Ingersoll@Sun.COM  * wrapping the RSA key with a key from the TPM (SRK or other previously stored
6779126SWyllys.Ingersoll@Sun.COM  * key).
6789126SWyllys.Ingersoll@Sun.COM  */
6799126SWyllys.Ingersoll@Sun.COM static CK_RV
token_wrap_sw_key(TSS_HCONTEXT hContext,int size_n,unsigned char * n,int size_p,unsigned char * p,TSS_HKEY hParentKey,TSS_FLAG initFlags,TSS_HKEY * phKey)6809126SWyllys.Ingersoll@Sun.COM token_wrap_sw_key(
6819126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
6829126SWyllys.Ingersoll@Sun.COM 	int size_n,
6839126SWyllys.Ingersoll@Sun.COM 	unsigned char *n,
6849126SWyllys.Ingersoll@Sun.COM 	int size_p,
6859126SWyllys.Ingersoll@Sun.COM 	unsigned char *p,
6869126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hParentKey,
6879126SWyllys.Ingersoll@Sun.COM 	TSS_FLAG initFlags,
6889126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY *phKey)
6899126SWyllys.Ingersoll@Sun.COM {
6909126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
6919126SWyllys.Ingersoll@Sun.COM 	UINT32 key_size;
6929126SWyllys.Ingersoll@Sun.COM 
6939126SWyllys.Ingersoll@Sun.COM 	key_size = util_get_keysize_flag(size_n * 8);
6949126SWyllys.Ingersoll@Sun.COM 	if (initFlags == 0) {
6959126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
6969126SWyllys.Ingersoll@Sun.COM 	}
6979126SWyllys.Ingersoll@Sun.COM 
6989126SWyllys.Ingersoll@Sun.COM 	/* create the TSS key object */
6999126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
7009126SWyllys.Ingersoll@Sun.COM 	    TSS_KEY_MIGRATABLE | initFlags | key_size, phKey);
7019126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
7029126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
7039126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
7049126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
7059126SWyllys.Ingersoll@Sun.COM 	}
7069126SWyllys.Ingersoll@Sun.COM 
7079126SWyllys.Ingersoll@Sun.COM 	result = set_public_modulus(hContext, *phKey, size_n, n);
7089126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
7099126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, *phKey);
7109126SWyllys.Ingersoll@Sun.COM 		*phKey = NULL_HKEY;
7119126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
7129126SWyllys.Ingersoll@Sun.COM 	}
7139126SWyllys.Ingersoll@Sun.COM 
7149126SWyllys.Ingersoll@Sun.COM 	/* set the private key data in the TSS object */
7159126SWyllys.Ingersoll@Sun.COM 	result = Tspi_SetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
7169126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, size_p, p);
7179126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
7189126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_SetAttribData: 0x%x - %s",
7199126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
7209126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, *phKey);
7219126SWyllys.Ingersoll@Sun.COM 		*phKey = NULL_HKEY;
7229126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
7239126SWyllys.Ingersoll@Sun.COM 	}
7249126SWyllys.Ingersoll@Sun.COM 
7259453SWyllys.Ingersoll@Sun.COM 	result = tss_assign_secret_key_policy(hContext, TSS_POLICY_MIGRATION,
7269453SWyllys.Ingersoll@Sun.COM 	    *phKey, NULL);
7279126SWyllys.Ingersoll@Sun.COM 
7289126SWyllys.Ingersoll@Sun.COM 	if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
7299126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_SetAttribUint32(*phKey,
7309126SWyllys.Ingersoll@Sun.COM 		    TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
7319126SWyllys.Ingersoll@Sun.COM 		    TSS_ES_RSAESPKCSV15))) {
7329126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n",
7339126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
7349126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
7359126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
7369126SWyllys.Ingersoll@Sun.COM 		}
7379126SWyllys.Ingersoll@Sun.COM 
7389126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_SetAttribUint32(*phKey,
7399126SWyllys.Ingersoll@Sun.COM 		    TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
7409126SWyllys.Ingersoll@Sun.COM 		    TSS_SS_RSASSAPKCS1V15_DER))) {
7419126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_SetAttribUint32: 0x%0x - %s\n",
7429126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
7439126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
7449126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
7459126SWyllys.Ingersoll@Sun.COM 		}
7469126SWyllys.Ingersoll@Sun.COM 	}
7479126SWyllys.Ingersoll@Sun.COM 
7489126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Key_WrapKey(*phKey, hParentKey, NULL_HPCRS);
7499126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
7509126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Key_WrapKey: 0x%0x - %s",
7519126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
7529126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, *phKey);
7539126SWyllys.Ingersoll@Sun.COM 		*phKey = NULL_HKEY;
7549126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
7559126SWyllys.Ingersoll@Sun.COM 	}
7569126SWyllys.Ingersoll@Sun.COM 
7579126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
7589126SWyllys.Ingersoll@Sun.COM }
7599126SWyllys.Ingersoll@Sun.COM 
7609126SWyllys.Ingersoll@Sun.COM /*
7619126SWyllys.Ingersoll@Sun.COM  * Create a TPM key blob for an imported key. This function is only called when
7629126SWyllys.Ingersoll@Sun.COM  * a key is in active use, so any failure should trickle through.
7639126SWyllys.Ingersoll@Sun.COM  */
7649126SWyllys.Ingersoll@Sun.COM static CK_RV
token_wrap_key_object(TSS_HCONTEXT hContext,CK_OBJECT_HANDLE ckObject,TSS_HKEY hParentKey,TSS_HKEY * phKey)7659126SWyllys.Ingersoll@Sun.COM token_wrap_key_object(TSS_HCONTEXT hContext,
7669126SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_HANDLE ckObject,
7679126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hParentKey, TSS_HKEY *phKey)
7689126SWyllys.Ingersoll@Sun.COM {
7699126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc = CKR_OK;
7709126SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE	*attr = NULL, *new_attr, *prime_attr;
7719126SWyllys.Ingersoll@Sun.COM 	CK_ULONG	class, key_type;
7729126SWyllys.Ingersoll@Sun.COM 	OBJECT		*obj;
7739126SWyllys.Ingersoll@Sun.COM 
7749126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
7759126SWyllys.Ingersoll@Sun.COM 	TSS_FLAG	initFlags = 0;
7769126SWyllys.Ingersoll@Sun.COM 	BYTE		*rgbBlob;
7779126SWyllys.Ingersoll@Sun.COM 	UINT32		ulBlobLen;
7789126SWyllys.Ingersoll@Sun.COM 
7799126SWyllys.Ingersoll@Sun.COM 	if ((rc = object_mgr_find_in_map1(hContext, ckObject, &obj))) {
7809126SWyllys.Ingersoll@Sun.COM 		return (rc);
7819126SWyllys.Ingersoll@Sun.COM 	}
7829126SWyllys.Ingersoll@Sun.COM 
7839126SWyllys.Ingersoll@Sun.COM 	/* if the object isn't a key, fail */
7849126SWyllys.Ingersoll@Sun.COM 	if (template_attribute_find(obj->template, CKA_KEY_TYPE,
7859126SWyllys.Ingersoll@Sun.COM 	    &attr) == FALSE) {
7869126SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCOMPLETE);
7879126SWyllys.Ingersoll@Sun.COM 	}
7889126SWyllys.Ingersoll@Sun.COM 
7899126SWyllys.Ingersoll@Sun.COM 	key_type = *((CK_ULONG *)attr->pValue);
7909126SWyllys.Ingersoll@Sun.COM 
7919126SWyllys.Ingersoll@Sun.COM 	if (key_type != CKK_RSA) {
7929126SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCONSISTENT);
7939126SWyllys.Ingersoll@Sun.COM 	}
7949126SWyllys.Ingersoll@Sun.COM 
7959126SWyllys.Ingersoll@Sun.COM 	if (template_attribute_find(obj->template, CKA_CLASS,
7969126SWyllys.Ingersoll@Sun.COM 	    &attr) == FALSE) {
7979126SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCOMPLETE);
7989126SWyllys.Ingersoll@Sun.COM 	}
7999126SWyllys.Ingersoll@Sun.COM 
8009126SWyllys.Ingersoll@Sun.COM 	class = *((CK_ULONG *)attr->pValue);
8019126SWyllys.Ingersoll@Sun.COM 
8029126SWyllys.Ingersoll@Sun.COM 	if (class == CKO_PRIVATE_KEY) {
8039126SWyllys.Ingersoll@Sun.COM 		/*
8049126SWyllys.Ingersoll@Sun.COM 		 * In order to create a full TSS key blob using a PKCS#11
8059126SWyllys.Ingersoll@Sun.COM 		 * private key object, we need one of the two primes, the
8069126SWyllys.Ingersoll@Sun.COM 		 * modulus and the private exponent and we need the public
8079126SWyllys.Ingersoll@Sun.COM 		 * exponent to be correct.
8089126SWyllys.Ingersoll@Sun.COM 		 */
8099126SWyllys.Ingersoll@Sun.COM 
8109126SWyllys.Ingersoll@Sun.COM 		/*
8119126SWyllys.Ingersoll@Sun.COM 		 * Check the least likely attribute to exist first, the
8129126SWyllys.Ingersoll@Sun.COM 		 * primes.
8139126SWyllys.Ingersoll@Sun.COM 		 */
8149126SWyllys.Ingersoll@Sun.COM 		if (template_attribute_find(obj->template, CKA_PRIME_1,
8159126SWyllys.Ingersoll@Sun.COM 		    &prime_attr) == FALSE) {
8169126SWyllys.Ingersoll@Sun.COM 			if (template_attribute_find(obj->template,
8179126SWyllys.Ingersoll@Sun.COM 			    CKA_PRIME_2, &prime_attr) == FALSE) {
8189126SWyllys.Ingersoll@Sun.COM 				return (CKR_TEMPLATE_INCOMPLETE);
8199126SWyllys.Ingersoll@Sun.COM 			}
8209126SWyllys.Ingersoll@Sun.COM 		}
8219126SWyllys.Ingersoll@Sun.COM 
8229126SWyllys.Ingersoll@Sun.COM 		/* Make sure the public exponent is usable */
8239126SWyllys.Ingersoll@Sun.COM 		if ((rc = util_check_public_exponent(obj->template))) {
8249126SWyllys.Ingersoll@Sun.COM 			return (CKR_TEMPLATE_INCONSISTENT);
8259126SWyllys.Ingersoll@Sun.COM 		}
8269126SWyllys.Ingersoll@Sun.COM 
8279126SWyllys.Ingersoll@Sun.COM 		/* get the modulus */
8289126SWyllys.Ingersoll@Sun.COM 		if (template_attribute_find(obj->template, CKA_MODULUS,
8299126SWyllys.Ingersoll@Sun.COM 		    &attr) == FALSE) {
8309126SWyllys.Ingersoll@Sun.COM 			return (CKR_TEMPLATE_INCOMPLETE);
8319126SWyllys.Ingersoll@Sun.COM 		}
8329126SWyllys.Ingersoll@Sun.COM 
8339126SWyllys.Ingersoll@Sun.COM 		/* make sure the key size is usable */
8349126SWyllys.Ingersoll@Sun.COM 		initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
8359126SWyllys.Ingersoll@Sun.COM 		if (initFlags == 0) {
8369126SWyllys.Ingersoll@Sun.COM 			return (CKR_TEMPLATE_INCONSISTENT);
8379126SWyllys.Ingersoll@Sun.COM 		}
8389126SWyllys.Ingersoll@Sun.COM 
8399126SWyllys.Ingersoll@Sun.COM 		/* generate the software based key */
8409126SWyllys.Ingersoll@Sun.COM 		if ((rc = token_wrap_sw_key(hContext,
8419126SWyllys.Ingersoll@Sun.COM 		    (int)attr->ulValueLen, attr->pValue,
8429126SWyllys.Ingersoll@Sun.COM 		    (int)prime_attr->ulValueLen, prime_attr->pValue,
8439126SWyllys.Ingersoll@Sun.COM 		    hParentKey, TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION,
8449126SWyllys.Ingersoll@Sun.COM 		    phKey))) {
8459126SWyllys.Ingersoll@Sun.COM 			return (rc);
8469126SWyllys.Ingersoll@Sun.COM 		}
8479126SWyllys.Ingersoll@Sun.COM 	} else if (class == CKO_PUBLIC_KEY) {
8489126SWyllys.Ingersoll@Sun.COM 		/* Make sure the public exponent is usable */
8499126SWyllys.Ingersoll@Sun.COM 		if ((util_check_public_exponent(obj->template))) {
8509126SWyllys.Ingersoll@Sun.COM 			return (CKR_TEMPLATE_INCONSISTENT);
8519126SWyllys.Ingersoll@Sun.COM 		}
8529126SWyllys.Ingersoll@Sun.COM 
8539126SWyllys.Ingersoll@Sun.COM 		/* grab the modulus to put into the TSS key object */
8549126SWyllys.Ingersoll@Sun.COM 		if (template_attribute_find(obj->template,
8559126SWyllys.Ingersoll@Sun.COM 		    CKA_MODULUS, &attr) == FALSE) {
8569126SWyllys.Ingersoll@Sun.COM 			return (CKR_TEMPLATE_INCONSISTENT);
8579126SWyllys.Ingersoll@Sun.COM 		}
8589126SWyllys.Ingersoll@Sun.COM 
8599126SWyllys.Ingersoll@Sun.COM 		/* make sure the key size is usable */
8609126SWyllys.Ingersoll@Sun.COM 		initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
8619126SWyllys.Ingersoll@Sun.COM 		if (initFlags == 0) {
8629126SWyllys.Ingersoll@Sun.COM 			return (CKR_TEMPLATE_INCONSISTENT);
8639126SWyllys.Ingersoll@Sun.COM 		}
8649126SWyllys.Ingersoll@Sun.COM 
8659453SWyllys.Ingersoll@Sun.COM 		initFlags |= TSS_KEY_MIGRATABLE | TSS_KEY_NO_AUTHORIZATION |
8669453SWyllys.Ingersoll@Sun.COM 		    TSS_KEY_TYPE_LEGACY;
8679126SWyllys.Ingersoll@Sun.COM 
8689126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_Context_CreateObject(hContext,
8699126SWyllys.Ingersoll@Sun.COM 		    TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) {
8709126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
8719126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
8729126SWyllys.Ingersoll@Sun.COM 			return (result);
8739126SWyllys.Ingersoll@Sun.COM 		}
8749126SWyllys.Ingersoll@Sun.COM 
8759126SWyllys.Ingersoll@Sun.COM 		if ((result = set_public_modulus(hContext, *phKey,
8769126SWyllys.Ingersoll@Sun.COM 		    attr->ulValueLen, attr->pValue))) {
8779126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
8789126SWyllys.Ingersoll@Sun.COM 			*phKey = NULL_HKEY;
8799126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
8809126SWyllys.Ingersoll@Sun.COM 		}
8819453SWyllys.Ingersoll@Sun.COM 		result = tss_assign_secret_key_policy(hContext,
8829453SWyllys.Ingersoll@Sun.COM 		    TSS_POLICY_MIGRATION, *phKey, NULL);
8839453SWyllys.Ingersoll@Sun.COM 		if (result) {
8849453SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
8859453SWyllys.Ingersoll@Sun.COM 			*phKey = NULL_HKEY;
8869453SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
8879453SWyllys.Ingersoll@Sun.COM 		}
8889453SWyllys.Ingersoll@Sun.COM 
8899453SWyllys.Ingersoll@Sun.COM 		result = set_legacy_key_params(*phKey);
8909453SWyllys.Ingersoll@Sun.COM 		if (result) {
8919453SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
8929453SWyllys.Ingersoll@Sun.COM 			*phKey = NULL_HKEY;
8939453SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
8949453SWyllys.Ingersoll@Sun.COM 		}
8959126SWyllys.Ingersoll@Sun.COM 	} else {
8969126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
8979126SWyllys.Ingersoll@Sun.COM 	}
8989126SWyllys.Ingersoll@Sun.COM 
8999126SWyllys.Ingersoll@Sun.COM 	/* grab the entire key blob to put into the PKCS#11 object */
9009126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
9019126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) {
9029126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetAttribData: 0x%0x - %s",
9039126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
9049126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
9059126SWyllys.Ingersoll@Sun.COM 	}
9069126SWyllys.Ingersoll@Sun.COM 
9079126SWyllys.Ingersoll@Sun.COM 	/* insert the key blob into the object */
9089126SWyllys.Ingersoll@Sun.COM 	if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen,
9099126SWyllys.Ingersoll@Sun.COM 	    &new_attr))) {
9109126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, rgbBlob);
9119126SWyllys.Ingersoll@Sun.COM 		return (rc);
9129126SWyllys.Ingersoll@Sun.COM 	}
9139126SWyllys.Ingersoll@Sun.COM 	(void) template_update_attribute(obj->template, new_attr);
9149126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, rgbBlob);
9159126SWyllys.Ingersoll@Sun.COM 
9169126SWyllys.Ingersoll@Sun.COM 	/*
9179126SWyllys.Ingersoll@Sun.COM 	 * If this is a token object, save it with the new attribute
9189126SWyllys.Ingersoll@Sun.COM 	 * so that we don't have to go down this path again.
9199126SWyllys.Ingersoll@Sun.COM 	 */
9209126SWyllys.Ingersoll@Sun.COM 	if (!object_is_session_object(obj)) {
9219126SWyllys.Ingersoll@Sun.COM 		rc = save_token_object(hContext, obj);
9229126SWyllys.Ingersoll@Sun.COM 	}
9239126SWyllys.Ingersoll@Sun.COM 
9249126SWyllys.Ingersoll@Sun.COM 	return (rc);
9259126SWyllys.Ingersoll@Sun.COM }
9269126SWyllys.Ingersoll@Sun.COM 
9279126SWyllys.Ingersoll@Sun.COM static TSS_RESULT
tss_assign_secret_key_policy(TSS_HCONTEXT hContext,TSS_FLAG policyType,TSS_HKEY hKey,CK_CHAR * passHash)9289453SWyllys.Ingersoll@Sun.COM tss_assign_secret_key_policy(TSS_HCONTEXT hContext, TSS_FLAG policyType,
9299453SWyllys.Ingersoll@Sun.COM     TSS_HKEY hKey, CK_CHAR *passHash)
9309126SWyllys.Ingersoll@Sun.COM {
9319126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
9329126SWyllys.Ingersoll@Sun.COM 	TSS_HPOLICY hPolicy;
9339126SWyllys.Ingersoll@Sun.COM 
9349126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
9359453SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_POLICY, policyType, &hPolicy))) {
9369126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
9379126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
9389126SWyllys.Ingersoll@Sun.COM 		return (result);
9399126SWyllys.Ingersoll@Sun.COM 	}
9409126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Policy_AssignToObject(hPolicy, hKey))) {
9419126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s",
9429126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
9439126SWyllys.Ingersoll@Sun.COM 		goto done;
9449126SWyllys.Ingersoll@Sun.COM 	}
9459126SWyllys.Ingersoll@Sun.COM 	if (passHash == NULL) {
9469126SWyllys.Ingersoll@Sun.COM 		result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE,
9479126SWyllys.Ingersoll@Sun.COM 		    0, NULL);
9489126SWyllys.Ingersoll@Sun.COM 	} else {
9499126SWyllys.Ingersoll@Sun.COM 		result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
9509126SWyllys.Ingersoll@Sun.COM 		    SHA1_DIGEST_LENGTH, passHash);
9519126SWyllys.Ingersoll@Sun.COM 	}
9529126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS) {
9539126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
9549126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
9559126SWyllys.Ingersoll@Sun.COM 		goto done;
9569126SWyllys.Ingersoll@Sun.COM 	}
9579126SWyllys.Ingersoll@Sun.COM done:
9589126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS)
9599126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPolicy);
9609126SWyllys.Ingersoll@Sun.COM 	return (result);
9619126SWyllys.Ingersoll@Sun.COM }
9629126SWyllys.Ingersoll@Sun.COM 
9639126SWyllys.Ingersoll@Sun.COM /*
9649126SWyllys.Ingersoll@Sun.COM  * Take a key from the TSS store (on-disk) and load it into the TPM, wrapped
9659126SWyllys.Ingersoll@Sun.COM  * by an already TPM-resident key and protected with a PIN (optional).
9669126SWyllys.Ingersoll@Sun.COM  */
9679126SWyllys.Ingersoll@Sun.COM static CK_RV
token_load_key(TSS_HCONTEXT hContext,CK_OBJECT_HANDLE ckKey,TSS_HKEY hParentKey,CK_CHAR_PTR passHash,TSS_HKEY * phKey)9689126SWyllys.Ingersoll@Sun.COM token_load_key(
9699126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
9709126SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_HANDLE ckKey,
9719126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hParentKey,
9729126SWyllys.Ingersoll@Sun.COM 	CK_CHAR_PTR passHash,
9739126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY *phKey)
9749126SWyllys.Ingersoll@Sun.COM {
9759126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
9769126SWyllys.Ingersoll@Sun.COM 	CK_RV rc;
9779126SWyllys.Ingersoll@Sun.COM 
9789453SWyllys.Ingersoll@Sun.COM 	/*
9799453SWyllys.Ingersoll@Sun.COM 	 * The key blob wasn't found, load the parts of the key
9809453SWyllys.Ingersoll@Sun.COM 	 * from the object DB and create a new key object that
9819453SWyllys.Ingersoll@Sun.COM 	 * gets loaded into the TPM, wrapped with the parent key.
9829453SWyllys.Ingersoll@Sun.COM 	 */
9839453SWyllys.Ingersoll@Sun.COM 	if ((rc = token_wrap_key_object(hContext, ckKey,
9849453SWyllys.Ingersoll@Sun.COM 	    hParentKey, phKey))) {
9859453SWyllys.Ingersoll@Sun.COM 		return (rc);
9869126SWyllys.Ingersoll@Sun.COM 	}
9879126SWyllys.Ingersoll@Sun.COM 
9889126SWyllys.Ingersoll@Sun.COM 	/*
9899126SWyllys.Ingersoll@Sun.COM 	 * Assign the PIN hash (optional) to the newly loaded key object,
9909126SWyllys.Ingersoll@Sun.COM 	 * if this PIN is incorrect, the TPM will not be able to decrypt
9919126SWyllys.Ingersoll@Sun.COM 	 * the private key and use it.
9929126SWyllys.Ingersoll@Sun.COM 	 */
9939453SWyllys.Ingersoll@Sun.COM 	result = tss_assign_secret_key_policy(hContext, TSS_POLICY_USAGE,
9949453SWyllys.Ingersoll@Sun.COM 	    *phKey, passHash);
9959453SWyllys.Ingersoll@Sun.COM 
9969126SWyllys.Ingersoll@Sun.COM 	return (result);
9979126SWyllys.Ingersoll@Sun.COM }
9989126SWyllys.Ingersoll@Sun.COM 
9999126SWyllys.Ingersoll@Sun.COM /*
10009126SWyllys.Ingersoll@Sun.COM  * Load the SRK into the TPM by referencing its well-known UUID and using the
10019126SWyllys.Ingersoll@Sun.COM  * default SRK PIN (20 bytes of 0x00).
10029126SWyllys.Ingersoll@Sun.COM  *
10039126SWyllys.Ingersoll@Sun.COM  * NOTE - if the SRK PIN is changed by an administrative tool, this code will
10049126SWyllys.Ingersoll@Sun.COM  * fail because it assumes that the well-known PIN is still being used.
10059126SWyllys.Ingersoll@Sun.COM  */
10069126SWyllys.Ingersoll@Sun.COM static TSS_RESULT
token_load_srk(TSS_HCONTEXT hContext,TSS_HKEY * hSRK)10079126SWyllys.Ingersoll@Sun.COM token_load_srk(TSS_HCONTEXT hContext, TSS_HKEY *hSRK)
10089126SWyllys.Ingersoll@Sun.COM {
10099126SWyllys.Ingersoll@Sun.COM 	TSS_HPOLICY hPolicy;
10109126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
10119126SWyllys.Ingersoll@Sun.COM 	TSS_UUID SRK_UUID = TSS_UUID_SRK;
10129126SWyllys.Ingersoll@Sun.COM 	BYTE wellKnown[] = TSS_WELL_KNOWN_SECRET;
10139126SWyllys.Ingersoll@Sun.COM 	TSS_HTPM hTPM;
10149126SWyllys.Ingersoll@Sun.COM 
10159126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_GetTpmObject(hContext, &hTPM))) {
10169126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_GetTpmObject: 0x%0x - %s",
10179126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
10189126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
10199126SWyllys.Ingersoll@Sun.COM 	}
10209126SWyllys.Ingersoll@Sun.COM 
10219126SWyllys.Ingersoll@Sun.COM 	/* load the SRK */
10229126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_LoadKeyByUUID(hContext,
10239126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_SYSTEM, SRK_UUID, hSRK))) {
10249126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_LoadKeyByUUID: 0x%0x - %s",
10259126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
10269126SWyllys.Ingersoll@Sun.COM 		goto done;
10279126SWyllys.Ingersoll@Sun.COM 	}
10289126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetPolicyObject(*hSRK, TSS_POLICY_USAGE,
10299126SWyllys.Ingersoll@Sun.COM 	    &hPolicy))) {
10309126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetPolicyObject: 0x%0x - %s",
10319126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
10329126SWyllys.Ingersoll@Sun.COM 		goto done;
10339126SWyllys.Ingersoll@Sun.COM 	}
10349126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
10359126SWyllys.Ingersoll@Sun.COM 	    sizeof (wellKnown), wellKnown))) {
10369126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
10379126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
10389126SWyllys.Ingersoll@Sun.COM 		goto done;
10399126SWyllys.Ingersoll@Sun.COM 	}
10409126SWyllys.Ingersoll@Sun.COM 
10419126SWyllys.Ingersoll@Sun.COM done:
10429126SWyllys.Ingersoll@Sun.COM 	return (result);
10439126SWyllys.Ingersoll@Sun.COM }
10449126SWyllys.Ingersoll@Sun.COM 
10459126SWyllys.Ingersoll@Sun.COM static TSS_RESULT
tss_find_and_load_key(TSS_HCONTEXT hContext,char * keyid,TSS_UUID * uuid,TSS_HKEY hParent,BYTE * hash,TSS_HKEY * hKey)10469126SWyllys.Ingersoll@Sun.COM tss_find_and_load_key(TSS_HCONTEXT hContext,
10479126SWyllys.Ingersoll@Sun.COM 	char *keyid, TSS_UUID *uuid, TSS_HKEY hParent,
10489126SWyllys.Ingersoll@Sun.COM 	BYTE *hash, TSS_HKEY *hKey)
10499126SWyllys.Ingersoll@Sun.COM {
10509126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
10519126SWyllys.Ingersoll@Sun.COM 
10529126SWyllys.Ingersoll@Sun.COM 	if (local_uuid_is_null(uuid) &&
10539126SWyllys.Ingersoll@Sun.COM 	    find_uuid(keyid, uuid)) {
10549126SWyllys.Ingersoll@Sun.COM 		/* The UUID was not created or saved yet */
10559126SWyllys.Ingersoll@Sun.COM 		return (1);
10569126SWyllys.Ingersoll@Sun.COM 	}
10579126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Context_GetKeyByUUID(hContext,
10589126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, *uuid, hKey);
10599126SWyllys.Ingersoll@Sun.COM 	if (result) {
10609126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_GetKeyByUUID: 0x%0x - %s",
10619126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
10629126SWyllys.Ingersoll@Sun.COM 		return (result);
10639126SWyllys.Ingersoll@Sun.COM 	}
10649126SWyllys.Ingersoll@Sun.COM 
10659126SWyllys.Ingersoll@Sun.COM 	if (hash != NULL) {
10669453SWyllys.Ingersoll@Sun.COM 		result = tss_assign_secret_key_policy(hContext,
10679453SWyllys.Ingersoll@Sun.COM 		    TSS_POLICY_USAGE, *hKey, (CK_BYTE *)hash);
10689126SWyllys.Ingersoll@Sun.COM 		if (result)
10699126SWyllys.Ingersoll@Sun.COM 			return (result);
10709126SWyllys.Ingersoll@Sun.COM 	}
10719126SWyllys.Ingersoll@Sun.COM 
10729126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Key_LoadKey(*hKey, hParent);
10739126SWyllys.Ingersoll@Sun.COM 	if (result)
10749126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
10759126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
10769126SWyllys.Ingersoll@Sun.COM 
10779126SWyllys.Ingersoll@Sun.COM 	return (result);
10789126SWyllys.Ingersoll@Sun.COM }
10799126SWyllys.Ingersoll@Sun.COM 
10809126SWyllys.Ingersoll@Sun.COM static TSS_RESULT
token_load_public_root_key(TSS_HCONTEXT hContext)10819126SWyllys.Ingersoll@Sun.COM token_load_public_root_key(TSS_HCONTEXT hContext)
10829126SWyllys.Ingersoll@Sun.COM {
10839126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
10849126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hSRK;
10859126SWyllys.Ingersoll@Sun.COM 
10869126SWyllys.Ingersoll@Sun.COM 	if (hPublicRootKey != NULL_HKEY)
10879126SWyllys.Ingersoll@Sun.COM 		return (TSS_SUCCESS);
10889126SWyllys.Ingersoll@Sun.COM 
10899126SWyllys.Ingersoll@Sun.COM 	if ((result = token_load_srk(hContext, &hSRK))) {
10909126SWyllys.Ingersoll@Sun.COM 		return (result);
10919126SWyllys.Ingersoll@Sun.COM 	}
10929126SWyllys.Ingersoll@Sun.COM 
10939126SWyllys.Ingersoll@Sun.COM 	result = tss_find_and_load_key(hContext,
10949126SWyllys.Ingersoll@Sun.COM 	    TPMTOK_PUBLIC_ROOT_KEY_ID,
10959126SWyllys.Ingersoll@Sun.COM 	    &publicRootKeyUUID, hSRK, NULL, &hPublicRootKey);
10969126SWyllys.Ingersoll@Sun.COM 	if (result)
10979126SWyllys.Ingersoll@Sun.COM 		return (result);
10989126SWyllys.Ingersoll@Sun.COM 
10999126SWyllys.Ingersoll@Sun.COM 	return (result);
11009126SWyllys.Ingersoll@Sun.COM }
11019126SWyllys.Ingersoll@Sun.COM 
11029126SWyllys.Ingersoll@Sun.COM static TSS_RESULT
set_legacy_key_params(TSS_HKEY hKey)11039453SWyllys.Ingersoll@Sun.COM set_legacy_key_params(TSS_HKEY hKey)
11049453SWyllys.Ingersoll@Sun.COM {
11059453SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
11069453SWyllys.Ingersoll@Sun.COM 
11079453SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_SetAttribUint32(hKey,
11089453SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEY_INFO,
11099453SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
11109453SWyllys.Ingersoll@Sun.COM 	    TSS_ES_RSAESPKCSV15))) {
11119453SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_SetAttribUint32: 0x%0x - %s",
11129453SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
11139453SWyllys.Ingersoll@Sun.COM 		return (result);
11149453SWyllys.Ingersoll@Sun.COM 	}
11159453SWyllys.Ingersoll@Sun.COM 
11169453SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_SetAttribUint32(hKey,
11179453SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEY_INFO,
11189453SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
11199453SWyllys.Ingersoll@Sun.COM 	    TSS_SS_RSASSAPKCS1V15_DER))) {
11209453SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_SetAttribUint32: 0x%0x - %s",
11219453SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
11229453SWyllys.Ingersoll@Sun.COM 		return (result);
11239453SWyllys.Ingersoll@Sun.COM 	}
11249453SWyllys.Ingersoll@Sun.COM 
11259453SWyllys.Ingersoll@Sun.COM 	return (result);
11269453SWyllys.Ingersoll@Sun.COM }
11279453SWyllys.Ingersoll@Sun.COM 
11289453SWyllys.Ingersoll@Sun.COM static TSS_RESULT
tss_generate_key(TSS_HCONTEXT hContext,TSS_FLAG initFlags,BYTE * passHash,TSS_HKEY hParentKey,TSS_HKEY * phKey)11299126SWyllys.Ingersoll@Sun.COM tss_generate_key(TSS_HCONTEXT hContext, TSS_FLAG initFlags, BYTE *passHash,
11309126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hParentKey, TSS_HKEY *phKey)
11319126SWyllys.Ingersoll@Sun.COM {
11329126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
11339126SWyllys.Ingersoll@Sun.COM 	TSS_HPOLICY	hMigPolicy;
11349126SWyllys.Ingersoll@Sun.COM 
11359126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
11369126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) {
11379126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
11389126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
11399126SWyllys.Ingersoll@Sun.COM 		return (result);
11409126SWyllys.Ingersoll@Sun.COM 	}
11419453SWyllys.Ingersoll@Sun.COM 	result = tss_assign_secret_key_policy(hContext, TSS_POLICY_USAGE,
11429453SWyllys.Ingersoll@Sun.COM 	    *phKey, passHash);
11439126SWyllys.Ingersoll@Sun.COM 
11449126SWyllys.Ingersoll@Sun.COM 	if (result) {
11459126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, *phKey);
11469126SWyllys.Ingersoll@Sun.COM 		return (result);
11479126SWyllys.Ingersoll@Sun.COM 	}
11489126SWyllys.Ingersoll@Sun.COM 
11499126SWyllys.Ingersoll@Sun.COM 	if (TPMTOK_TSS_KEY_MIG_TYPE(initFlags) == TSS_KEY_MIGRATABLE) {
11509126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_Context_CreateObject(hContext,
11519126SWyllys.Ingersoll@Sun.COM 		    TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION,
11529126SWyllys.Ingersoll@Sun.COM 		    &hMigPolicy))) {
11539126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
11549126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
11559126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
11569126SWyllys.Ingersoll@Sun.COM 			return (result);
11579126SWyllys.Ingersoll@Sun.COM 		}
11589126SWyllys.Ingersoll@Sun.COM 
11599126SWyllys.Ingersoll@Sun.COM 		if (passHash == NULL) {
11609126SWyllys.Ingersoll@Sun.COM 			result = Tspi_Policy_SetSecret(hMigPolicy,
11619126SWyllys.Ingersoll@Sun.COM 			    TSS_SECRET_MODE_NONE, 0, NULL);
11629126SWyllys.Ingersoll@Sun.COM 		} else {
11639126SWyllys.Ingersoll@Sun.COM 			result = Tspi_Policy_SetSecret(hMigPolicy,
11649126SWyllys.Ingersoll@Sun.COM 			    TSS_SECRET_MODE_SHA1, 20, passHash);
11659126SWyllys.Ingersoll@Sun.COM 		}
11669126SWyllys.Ingersoll@Sun.COM 
11679126SWyllys.Ingersoll@Sun.COM 		if (result != TSS_SUCCESS) {
11689126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
11699126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
11709126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
11719126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, hMigPolicy);
11729126SWyllys.Ingersoll@Sun.COM 			return (result);
11739126SWyllys.Ingersoll@Sun.COM 		}
11749126SWyllys.Ingersoll@Sun.COM 
11759126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_Policy_AssignToObject(hMigPolicy, *phKey))) {
11769126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_Policy_AssignToObject: 0x%0x - %s",
11779126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
11789126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
11799126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, hMigPolicy);
11809126SWyllys.Ingersoll@Sun.COM 			return (result);
11819126SWyllys.Ingersoll@Sun.COM 		}
11829126SWyllys.Ingersoll@Sun.COM 	}
11839126SWyllys.Ingersoll@Sun.COM 
11849126SWyllys.Ingersoll@Sun.COM 	if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
11859453SWyllys.Ingersoll@Sun.COM 		result = set_legacy_key_params(*phKey);
11869453SWyllys.Ingersoll@Sun.COM 		if (result) {
11879126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, *phKey);
11889126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_CloseObject(hContext, hMigPolicy);
11899126SWyllys.Ingersoll@Sun.COM 			return (result);
11909126SWyllys.Ingersoll@Sun.COM 		}
11919126SWyllys.Ingersoll@Sun.COM 	}
11929126SWyllys.Ingersoll@Sun.COM 
11939126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Key_CreateKey(*phKey, hParentKey, 0))) {
11949126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Key_CreateKey: 0x%0x - %s",
11959126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
11969126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, *phKey);
11979126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hMigPolicy);
11989126SWyllys.Ingersoll@Sun.COM 	}
11999126SWyllys.Ingersoll@Sun.COM 
12009126SWyllys.Ingersoll@Sun.COM 	return (result);
12019126SWyllys.Ingersoll@Sun.COM }
12029126SWyllys.Ingersoll@Sun.COM 
12039126SWyllys.Ingersoll@Sun.COM static TSS_RESULT
tss_change_auth(TSS_HCONTEXT hContext,TSS_HKEY hObjectToChange,TSS_HKEY hParentObject,TSS_UUID objUUID,TSS_UUID parentUUID,CK_CHAR * passHash)12049126SWyllys.Ingersoll@Sun.COM tss_change_auth(
12059126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
12069126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hObjectToChange, TSS_HKEY hParentObject,
12079126SWyllys.Ingersoll@Sun.COM 	TSS_UUID objUUID, TSS_UUID parentUUID,
12089126SWyllys.Ingersoll@Sun.COM 	CK_CHAR *passHash)
12099126SWyllys.Ingersoll@Sun.COM {
12109126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
12119126SWyllys.Ingersoll@Sun.COM 	TSS_HPOLICY hPolicy;
12129126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY oldkey;
12139126SWyllys.Ingersoll@Sun.COM 
12149126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
12159126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) {
12169126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
12179126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
12189126SWyllys.Ingersoll@Sun.COM 		return (result);
12199126SWyllys.Ingersoll@Sun.COM 	}
12209126SWyllys.Ingersoll@Sun.COM 
12219126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
12229126SWyllys.Ingersoll@Sun.COM 	    SHA1_DIGEST_LENGTH, passHash))) {
12239126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
12249126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
12259126SWyllys.Ingersoll@Sun.COM 		return (result);
12269126SWyllys.Ingersoll@Sun.COM 	}
12279126SWyllys.Ingersoll@Sun.COM 
12289126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_ChangeAuth(hObjectToChange, hParentObject,
12299126SWyllys.Ingersoll@Sun.COM 	    hPolicy))) {
12309126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_ChangeAuth: 0x%0x - %s",
12319126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
12329126SWyllys.Ingersoll@Sun.COM 	}
12339126SWyllys.Ingersoll@Sun.COM 	/*
12349126SWyllys.Ingersoll@Sun.COM 	 * Update the PS key by unregistering the key UUID and then
12359126SWyllys.Ingersoll@Sun.COM 	 * re-registering with the same UUID.  This forces the updated
12369126SWyllys.Ingersoll@Sun.COM 	 * auth data associated with the key to be stored in PS so
12379126SWyllys.Ingersoll@Sun.COM 	 * the new PIN can be used next time.
12389126SWyllys.Ingersoll@Sun.COM 	 */
12399126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_UnregisterKey(hContext,
12409126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, objUUID, &oldkey)))
12419126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_UnregisterKey: 0x%0x - %s",
12429126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
12439126SWyllys.Ingersoll@Sun.COM 
12449126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_RegisterKey(hContext, hObjectToChange,
12459126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, objUUID, TSS_PS_TYPE_USER, parentUUID)))
12469126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_RegisterKey: 0x%0x - %s",
12479126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
12489126SWyllys.Ingersoll@Sun.COM 
12499126SWyllys.Ingersoll@Sun.COM 	return (result);
12509126SWyllys.Ingersoll@Sun.COM }
12519126SWyllys.Ingersoll@Sun.COM 
12529126SWyllys.Ingersoll@Sun.COM static CK_RV
token_generate_leaf_key(TSS_HCONTEXT hContext,int key_type,CK_CHAR_PTR passHash,TSS_HKEY * phKey)12539126SWyllys.Ingersoll@Sun.COM token_generate_leaf_key(TSS_HCONTEXT hContext,
12549126SWyllys.Ingersoll@Sun.COM 	int key_type, CK_CHAR_PTR passHash, TSS_HKEY *phKey)
12559126SWyllys.Ingersoll@Sun.COM {
12569126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc = CKR_FUNCTION_FAILED;
12579126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
12589126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hParentKey;
12599126SWyllys.Ingersoll@Sun.COM 	TSS_UUID	newuuid, parentUUID;
12609126SWyllys.Ingersoll@Sun.COM 	char		*keyid;
12619126SWyllys.Ingersoll@Sun.COM 	TSS_FLAG	initFlags = TSS_KEY_MIGRATABLE |
12629126SWyllys.Ingersoll@Sun.COM 	    TSS_KEY_TYPE_BIND | TSS_KEY_SIZE_2048  | TSS_KEY_AUTHORIZATION;
12639126SWyllys.Ingersoll@Sun.COM 
12649126SWyllys.Ingersoll@Sun.COM 	switch (key_type) {
12659126SWyllys.Ingersoll@Sun.COM 		case TPMTOK_PUBLIC_LEAF_KEY:
12669126SWyllys.Ingersoll@Sun.COM 			hParentKey = hPublicRootKey;
12679126SWyllys.Ingersoll@Sun.COM 			keyid = TPMTOK_PUBLIC_LEAF_KEY_ID;
12689126SWyllys.Ingersoll@Sun.COM 			local_uuid_copy(&parentUUID, &publicRootKeyUUID);
12699126SWyllys.Ingersoll@Sun.COM 			break;
12709126SWyllys.Ingersoll@Sun.COM 		case TPMTOK_PRIVATE_LEAF_KEY:
12719126SWyllys.Ingersoll@Sun.COM 			hParentKey = hPrivateRootKey;
12729126SWyllys.Ingersoll@Sun.COM 			keyid = TPMTOK_PRIVATE_LEAF_KEY_ID;
12739126SWyllys.Ingersoll@Sun.COM 			local_uuid_copy(&parentUUID, &privateRootKeyUUID);
12749126SWyllys.Ingersoll@Sun.COM 			break;
12759126SWyllys.Ingersoll@Sun.COM 		default:
12769126SWyllys.Ingersoll@Sun.COM 			stlogit("Unknown key type 0x%0x", key_type);
12779126SWyllys.Ingersoll@Sun.COM 			goto done;
12789126SWyllys.Ingersoll@Sun.COM 			break;
12799126SWyllys.Ingersoll@Sun.COM 	}
12809126SWyllys.Ingersoll@Sun.COM 
12819126SWyllys.Ingersoll@Sun.COM 	if (result = tss_generate_key(hContext, initFlags, passHash,
12829126SWyllys.Ingersoll@Sun.COM 	    hParentKey, phKey)) {
12839126SWyllys.Ingersoll@Sun.COM 		return (rc);
12849126SWyllys.Ingersoll@Sun.COM 	}
12859126SWyllys.Ingersoll@Sun.COM 
12869126SWyllys.Ingersoll@Sun.COM 	/*
12879126SWyllys.Ingersoll@Sun.COM 	 * - generate newUUID
12889126SWyllys.Ingersoll@Sun.COM 	 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey,
12899126SWyllys.Ingersoll@Sun.COM 	 *   USER, newUUID, USER, parentUUID);
12909126SWyllys.Ingersoll@Sun.COM 	 * - store newUUID
12919126SWyllys.Ingersoll@Sun.COM 	 */
12929126SWyllys.Ingersoll@Sun.COM 	(void) local_uuid_generate(&newuuid);
12939126SWyllys.Ingersoll@Sun.COM 
12949126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Context_RegisterKey(hContext, *phKey,
12959126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, newuuid,
12969126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, parentUUID);
12979126SWyllys.Ingersoll@Sun.COM 	if (result == TSS_SUCCESS) {
12989126SWyllys.Ingersoll@Sun.COM 		int ret;
12999126SWyllys.Ingersoll@Sun.COM 		/*
13009126SWyllys.Ingersoll@Sun.COM 		 * Add the UUID to the token UUID index.
13019126SWyllys.Ingersoll@Sun.COM 		 */
13029126SWyllys.Ingersoll@Sun.COM 		ret = add_uuid(keyid, &newuuid);
13039126SWyllys.Ingersoll@Sun.COM 
13049126SWyllys.Ingersoll@Sun.COM 		if (ret)
13059126SWyllys.Ingersoll@Sun.COM 			result = Tspi_Context_UnregisterKey(hContext,
13069126SWyllys.Ingersoll@Sun.COM 			    TSS_PS_TYPE_USER, newuuid, phKey);
13079126SWyllys.Ingersoll@Sun.COM 		else
13089126SWyllys.Ingersoll@Sun.COM 			rc = CKR_OK;
13099126SWyllys.Ingersoll@Sun.COM 	}
13109126SWyllys.Ingersoll@Sun.COM 
13119126SWyllys.Ingersoll@Sun.COM done:
13129126SWyllys.Ingersoll@Sun.COM 	return (rc);
13139126SWyllys.Ingersoll@Sun.COM }
13149126SWyllys.Ingersoll@Sun.COM 
13159126SWyllys.Ingersoll@Sun.COM /*
13169126SWyllys.Ingersoll@Sun.COM  * PINs are verified by attempting to bind/unbind random data using a
13179126SWyllys.Ingersoll@Sun.COM  * TPM resident key that has the PIN being tested assigned as its "secret".
13189126SWyllys.Ingersoll@Sun.COM  * If the PIN is incorrect, the unbind operation will fail.
13199126SWyllys.Ingersoll@Sun.COM  */
13209126SWyllys.Ingersoll@Sun.COM static CK_RV
token_verify_pin(TSS_HCONTEXT hContext,TSS_HKEY hKey)13219126SWyllys.Ingersoll@Sun.COM token_verify_pin(TSS_HCONTEXT hContext, TSS_HKEY hKey)
13229126SWyllys.Ingersoll@Sun.COM {
13239126SWyllys.Ingersoll@Sun.COM 	TSS_HENCDATA hEncData;
13249126SWyllys.Ingersoll@Sun.COM 	UINT32 ulUnboundDataLen;
13259126SWyllys.Ingersoll@Sun.COM 	BYTE *rgbUnboundData = NULL;
13269126SWyllys.Ingersoll@Sun.COM 	BYTE rgbData[16];
13279126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
13289126SWyllys.Ingersoll@Sun.COM 	CK_RV rc = CKR_FUNCTION_FAILED;
13299126SWyllys.Ingersoll@Sun.COM 
13309126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
13319126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
13329126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
13339126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
13349126SWyllys.Ingersoll@Sun.COM 		goto done;
13359126SWyllys.Ingersoll@Sun.COM 	}
13369126SWyllys.Ingersoll@Sun.COM 
13379126SWyllys.Ingersoll@Sun.COM 	/* Use some random data */
13389126SWyllys.Ingersoll@Sun.COM 	rc = token_rng(hContext, rgbData, sizeof (rgbData));
13399126SWyllys.Ingersoll@Sun.COM 	if (rc)
13409126SWyllys.Ingersoll@Sun.COM 		goto done;
13419126SWyllys.Ingersoll@Sun.COM 
13429126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Data_Bind(hEncData, hKey,
13439126SWyllys.Ingersoll@Sun.COM 	    sizeof (rgbData), rgbData))) {
13449126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Data_Bind: 0x%0x - %s",
13459126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
13469126SWyllys.Ingersoll@Sun.COM 		goto done;
13479126SWyllys.Ingersoll@Sun.COM 	}
13489126SWyllys.Ingersoll@Sun.COM 
13499126SWyllys.Ingersoll@Sun.COM 	/* unbind the junk data to test the key's auth data */
13509126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen,
13519126SWyllys.Ingersoll@Sun.COM 	    &rgbUnboundData);
13529453SWyllys.Ingersoll@Sun.COM 	if (result == TPM_E_AUTHFAIL) {
13539126SWyllys.Ingersoll@Sun.COM 		rc = CKR_PIN_INCORRECT;
13549126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Data_Unbind: 0x%0x - %s",
13559126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
13569126SWyllys.Ingersoll@Sun.COM 		goto done;
13579126SWyllys.Ingersoll@Sun.COM 	} else if (result != TSS_SUCCESS) {
13589126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Data_Unbind: 0x%0x - %s",
13599126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
13609126SWyllys.Ingersoll@Sun.COM 		rc = CKR_FUNCTION_FAILED;
13619126SWyllys.Ingersoll@Sun.COM 		goto done;
13629126SWyllys.Ingersoll@Sun.COM 	}
13639126SWyllys.Ingersoll@Sun.COM 
13649126SWyllys.Ingersoll@Sun.COM 	if (memcmp(rgbUnboundData, rgbData, ulUnboundDataLen))
13659126SWyllys.Ingersoll@Sun.COM 		rc = CKR_PIN_INCORRECT;
13669126SWyllys.Ingersoll@Sun.COM 	else
13679126SWyllys.Ingersoll@Sun.COM 		rc = CKR_OK;
13689126SWyllys.Ingersoll@Sun.COM 
13699126SWyllys.Ingersoll@Sun.COM done:
13709126SWyllys.Ingersoll@Sun.COM 	if (rgbUnboundData != NULL)
13719126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, rgbUnboundData);
13729126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_CloseObject(hContext, hEncData);
13739126SWyllys.Ingersoll@Sun.COM 	return (rc);
13749126SWyllys.Ingersoll@Sun.COM }
13759126SWyllys.Ingersoll@Sun.COM 
13769126SWyllys.Ingersoll@Sun.COM static CK_RV
token_create_private_tree(TSS_HCONTEXT hContext,CK_BYTE * pinHash)13779126SWyllys.Ingersoll@Sun.COM token_create_private_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash)
13789126SWyllys.Ingersoll@Sun.COM {
13799126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
13809126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
13819126SWyllys.Ingersoll@Sun.COM 	int		ret;
13829126SWyllys.Ingersoll@Sun.COM 	TSS_FLAG initFlags = TSS_KEY_SIZE_2048 |
13839126SWyllys.Ingersoll@Sun.COM 	    TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE;
13849126SWyllys.Ingersoll@Sun.COM 	TSS_UUID SRK_UUID = TSS_UUID_SRK;
13859126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hSRK;
13869126SWyllys.Ingersoll@Sun.COM 
13879126SWyllys.Ingersoll@Sun.COM 	if (token_load_srk(hContext, &hSRK))
13889126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
13899126SWyllys.Ingersoll@Sun.COM 
13909126SWyllys.Ingersoll@Sun.COM 	/*
13919126SWyllys.Ingersoll@Sun.COM 	 * - create UUID privateRootKeyUUID
13929126SWyllys.Ingersoll@Sun.COM 	 * - Tspi_Context_RegisterKey(hContext, hPrivateRootKey,
13939126SWyllys.Ingersoll@Sun.COM 	 *   USER, privateRootKeyUUID, system, UUID_SRK);
13949126SWyllys.Ingersoll@Sun.COM 	 * - store privateRootKeyUUID in users private token space.
13959126SWyllys.Ingersoll@Sun.COM 	 */
13969126SWyllys.Ingersoll@Sun.COM 	if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK,
13979126SWyllys.Ingersoll@Sun.COM 	    &hPrivateRootKey))) {
13989126SWyllys.Ingersoll@Sun.COM 		return (result);
13999126SWyllys.Ingersoll@Sun.COM 	}
14009126SWyllys.Ingersoll@Sun.COM 	if (local_uuid_is_null(&privateRootKeyUUID))
14019126SWyllys.Ingersoll@Sun.COM 		local_uuid_generate(&privateRootKeyUUID);
14029126SWyllys.Ingersoll@Sun.COM 
14039126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Context_RegisterKey(hContext, hPrivateRootKey,
14049126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, privateRootKeyUUID,
14059126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_SYSTEM, SRK_UUID);
14069126SWyllys.Ingersoll@Sun.COM 
14079126SWyllys.Ingersoll@Sun.COM 	if (result) {
14089126SWyllys.Ingersoll@Sun.COM 		local_uuid_clear(&privateRootKeyUUID);
14099126SWyllys.Ingersoll@Sun.COM 		return (result);
14109126SWyllys.Ingersoll@Sun.COM 	}
14119126SWyllys.Ingersoll@Sun.COM 
14129126SWyllys.Ingersoll@Sun.COM 	ret = add_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID, &privateRootKeyUUID);
14139126SWyllys.Ingersoll@Sun.COM 	if (ret) {
14149126SWyllys.Ingersoll@Sun.COM 		result = Tspi_Context_UnregisterKey(hContext,
14159126SWyllys.Ingersoll@Sun.COM 		    TSS_PS_TYPE_USER, privateRootKeyUUID,
14169126SWyllys.Ingersoll@Sun.COM 		    &hPrivateRootKey);
14179126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
14189126SWyllys.Ingersoll@Sun.COM 	}
14199126SWyllys.Ingersoll@Sun.COM 
14209126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Key_LoadKey(hPrivateRootKey, hSRK))) {
14219126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
14229126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
14239126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPrivateRootKey);
14249126SWyllys.Ingersoll@Sun.COM 
14259126SWyllys.Ingersoll@Sun.COM 		(void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID);
14269126SWyllys.Ingersoll@Sun.COM 		local_uuid_clear(&privateRootKeyUUID);
14279126SWyllys.Ingersoll@Sun.COM 
14289126SWyllys.Ingersoll@Sun.COM 		hPrivateRootKey = NULL_HKEY;
14299126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
14309126SWyllys.Ingersoll@Sun.COM 	}
14319126SWyllys.Ingersoll@Sun.COM 
14329126SWyllys.Ingersoll@Sun.COM 
14339126SWyllys.Ingersoll@Sun.COM 	/* generate the private leaf key */
14349126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_generate_leaf_key(hContext,
14359126SWyllys.Ingersoll@Sun.COM 	    TPMTOK_PRIVATE_LEAF_KEY,
14369126SWyllys.Ingersoll@Sun.COM 	    pinHash, &hPrivateLeafKey))) {
14379126SWyllys.Ingersoll@Sun.COM 		return (rc);
14389126SWyllys.Ingersoll@Sun.COM 	}
14399126SWyllys.Ingersoll@Sun.COM 
14409126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Key_LoadKey(hPrivateLeafKey, hPrivateRootKey))) {
14419126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
14429126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
14439126SWyllys.Ingersoll@Sun.COM 
14449126SWyllys.Ingersoll@Sun.COM 		(void) Tspi_Context_UnregisterKey(hContext,
14459126SWyllys.Ingersoll@Sun.COM 		    TSS_PS_TYPE_USER, privateLeafKeyUUID,
14469126SWyllys.Ingersoll@Sun.COM 		    &hPrivateLeafKey);
14479126SWyllys.Ingersoll@Sun.COM 		(void) remove_uuid(TPMTOK_PRIVATE_LEAF_KEY_ID);
14489126SWyllys.Ingersoll@Sun.COM 		local_uuid_clear(&privateLeafKeyUUID);
14499126SWyllys.Ingersoll@Sun.COM 
14509126SWyllys.Ingersoll@Sun.COM 		(void) Tspi_Context_UnregisterKey(hContext,
14519126SWyllys.Ingersoll@Sun.COM 		    TSS_PS_TYPE_USER, privateRootKeyUUID,
14529126SWyllys.Ingersoll@Sun.COM 		    &hPrivateRootKey);
14539126SWyllys.Ingersoll@Sun.COM 		(void) remove_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID);
14549126SWyllys.Ingersoll@Sun.COM 		local_uuid_clear(&privateRootKeyUUID);
14559126SWyllys.Ingersoll@Sun.COM 
14569126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPrivateRootKey);
14579126SWyllys.Ingersoll@Sun.COM 		hPrivateRootKey = NULL_HKEY;
14589126SWyllys.Ingersoll@Sun.COM 
14599126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPrivateLeafKey);
14609126SWyllys.Ingersoll@Sun.COM 		hPrivateRootKey = NULL_HKEY;
14619126SWyllys.Ingersoll@Sun.COM 
14629126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
14639126SWyllys.Ingersoll@Sun.COM 	}
14649126SWyllys.Ingersoll@Sun.COM 	return (rc);
14659126SWyllys.Ingersoll@Sun.COM }
14669126SWyllys.Ingersoll@Sun.COM 
14679126SWyllys.Ingersoll@Sun.COM static CK_RV
token_create_public_tree(TSS_HCONTEXT hContext,CK_BYTE * pinHash)14689126SWyllys.Ingersoll@Sun.COM token_create_public_tree(TSS_HCONTEXT hContext, CK_BYTE *pinHash)
14699126SWyllys.Ingersoll@Sun.COM {
14709126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
14719126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
14729126SWyllys.Ingersoll@Sun.COM 	int		ret;
14739126SWyllys.Ingersoll@Sun.COM 	TSS_FLAG initFlags = TSS_KEY_SIZE_2048 |
14749126SWyllys.Ingersoll@Sun.COM 	    TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE;
14759126SWyllys.Ingersoll@Sun.COM 	TSS_UUID srk_uuid = TSS_UUID_SRK;
14769126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hSRK;
14779126SWyllys.Ingersoll@Sun.COM 
14789126SWyllys.Ingersoll@Sun.COM 	if (token_load_srk(hContext, &hSRK))
14799126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
14809126SWyllys.Ingersoll@Sun.COM 
14819126SWyllys.Ingersoll@Sun.COM 	/*
14829126SWyllys.Ingersoll@Sun.COM 	 * - create publicRootKeyUUID
14839126SWyllys.Ingersoll@Sun.COM 	 * - Tspi_Context_RegisterKey(hContext, hPublicRootKey,
14849126SWyllys.Ingersoll@Sun.COM 	 *   USER, publicRootKeyUUID, system, UUID_SRK);
14859126SWyllys.Ingersoll@Sun.COM 	 * - store publicRootKeyUUID in users private token space.
14869126SWyllys.Ingersoll@Sun.COM 	 */
14879126SWyllys.Ingersoll@Sun.COM 	if ((result = tss_generate_key(hContext, initFlags, NULL, hSRK,
14889126SWyllys.Ingersoll@Sun.COM 	    &hPublicRootKey))) {
14899126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
14909126SWyllys.Ingersoll@Sun.COM 	}
14919126SWyllys.Ingersoll@Sun.COM 	if (local_uuid_is_null(&publicRootKeyUUID))
14929126SWyllys.Ingersoll@Sun.COM 		local_uuid_generate(&publicRootKeyUUID);
14939126SWyllys.Ingersoll@Sun.COM 
14949126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Context_RegisterKey(hContext, hPublicRootKey,
14959126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, publicRootKeyUUID,
14969126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_SYSTEM, srk_uuid);
14979126SWyllys.Ingersoll@Sun.COM 
14989126SWyllys.Ingersoll@Sun.COM 	if (result) {
14999126SWyllys.Ingersoll@Sun.COM 		local_uuid_clear(&publicRootKeyUUID);
15009126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
15019126SWyllys.Ingersoll@Sun.COM 	}
15029126SWyllys.Ingersoll@Sun.COM 
15039126SWyllys.Ingersoll@Sun.COM 	ret = add_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID);
15049126SWyllys.Ingersoll@Sun.COM 	if (ret) {
15059126SWyllys.Ingersoll@Sun.COM 		result = Tspi_Context_UnregisterKey(hContext,
15069126SWyllys.Ingersoll@Sun.COM 		    TSS_PS_TYPE_USER, publicRootKeyUUID,
15079126SWyllys.Ingersoll@Sun.COM 		    &hPublicRootKey);
15089126SWyllys.Ingersoll@Sun.COM 		/* does result matter here? */
15099126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
15109126SWyllys.Ingersoll@Sun.COM 	}
15119126SWyllys.Ingersoll@Sun.COM 
15129126SWyllys.Ingersoll@Sun.COM 	/* Load the newly created publicRootKey into the TPM using the SRK */
15139126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Key_LoadKey(hPublicRootKey, hSRK))) {
15149126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Key_LoadKey: 0x%x - %s", result,
15159126SWyllys.Ingersoll@Sun.COM 		    Trspi_Error_String(result));
15169126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPublicRootKey);
15179126SWyllys.Ingersoll@Sun.COM 		hPublicRootKey = NULL_HKEY;
15189126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
15199126SWyllys.Ingersoll@Sun.COM 	}
15209126SWyllys.Ingersoll@Sun.COM 
15219126SWyllys.Ingersoll@Sun.COM 	/* create the SO's leaf key */
15229126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_generate_leaf_key(hContext, TPMTOK_PUBLIC_LEAF_KEY,
15239126SWyllys.Ingersoll@Sun.COM 	    pinHash, &hPublicLeafKey))) {
15249126SWyllys.Ingersoll@Sun.COM 		return (rc);
15259126SWyllys.Ingersoll@Sun.COM 	}
15269126SWyllys.Ingersoll@Sun.COM 
15279126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey))) {
15289126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Key_LoadKey: 0x%0x - %s",
15299126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
15309126SWyllys.Ingersoll@Sun.COM 
15319126SWyllys.Ingersoll@Sun.COM 		/* Unregister keys and clear UUIDs */
15329126SWyllys.Ingersoll@Sun.COM 		(void) Tspi_Context_UnregisterKey(hContext,
15339126SWyllys.Ingersoll@Sun.COM 		    TSS_PS_TYPE_USER, publicLeafKeyUUID,
15349126SWyllys.Ingersoll@Sun.COM 		    &hPublicLeafKey);
15359126SWyllys.Ingersoll@Sun.COM 		(void) remove_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID);
15369126SWyllys.Ingersoll@Sun.COM 
15379126SWyllys.Ingersoll@Sun.COM 		(void) Tspi_Context_UnregisterKey(hContext,
15389126SWyllys.Ingersoll@Sun.COM 		    TSS_PS_TYPE_USER, publicRootKeyUUID,
15399126SWyllys.Ingersoll@Sun.COM 		    &hPublicRootKey);
15409126SWyllys.Ingersoll@Sun.COM 		(void) remove_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID);
15419126SWyllys.Ingersoll@Sun.COM 
15429126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPublicRootKey);
15439126SWyllys.Ingersoll@Sun.COM 		hPublicRootKey = NULL_HKEY;
15449126SWyllys.Ingersoll@Sun.COM 
15459126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPublicLeafKey);
15469126SWyllys.Ingersoll@Sun.COM 		hPublicLeafKey = NULL_HKEY;
15479126SWyllys.Ingersoll@Sun.COM 
15489126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
15499126SWyllys.Ingersoll@Sun.COM 	}
15509126SWyllys.Ingersoll@Sun.COM 
15519126SWyllys.Ingersoll@Sun.COM 	return (rc);
15529126SWyllys.Ingersoll@Sun.COM }
15539126SWyllys.Ingersoll@Sun.COM 
15549126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_login(TSS_HCONTEXT hContext,CK_USER_TYPE userType,CK_CHAR_PTR pPin,CK_ULONG ulPinLen)15559126SWyllys.Ingersoll@Sun.COM token_specific_login(
15569126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
15579126SWyllys.Ingersoll@Sun.COM 	CK_USER_TYPE userType,
15589126SWyllys.Ingersoll@Sun.COM 	CK_CHAR_PTR pPin,
15599126SWyllys.Ingersoll@Sun.COM 	CK_ULONG ulPinLen)
15609126SWyllys.Ingersoll@Sun.COM {
15619126SWyllys.Ingersoll@Sun.COM 	CK_RV rc;
15629126SWyllys.Ingersoll@Sun.COM 	CK_BYTE hash_sha[SHA1_DIGEST_LENGTH];
15639126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
15649126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hSRK;
15659126SWyllys.Ingersoll@Sun.COM 
15669126SWyllys.Ingersoll@Sun.COM 	/* Make sure the SRK is loaded into the TPM */
15679126SWyllys.Ingersoll@Sun.COM 	if ((result = token_load_srk(hContext, &hSRK))) {
15689126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
15699126SWyllys.Ingersoll@Sun.COM 	}
15709126SWyllys.Ingersoll@Sun.COM 
15719126SWyllys.Ingersoll@Sun.COM 	if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) {
15729126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
15739126SWyllys.Ingersoll@Sun.COM 	}
15749126SWyllys.Ingersoll@Sun.COM 
15759126SWyllys.Ingersoll@Sun.COM 	if (userType == CKU_USER) {
15769126SWyllys.Ingersoll@Sun.COM 		/*
15779126SWyllys.Ingersoll@Sun.COM 		 * If the public root key doesn't exist yet,
15789126SWyllys.Ingersoll@Sun.COM 		 * the SO hasn't init'd the token.
15799126SWyllys.Ingersoll@Sun.COM 		 */
15809126SWyllys.Ingersoll@Sun.COM 		if ((result = token_load_public_root_key(hContext))) {
15819126SWyllys.Ingersoll@Sun.COM 			if (result == TPM_E_DECRYPT_ERROR) {
15829126SWyllys.Ingersoll@Sun.COM 				return (CKR_USER_PIN_NOT_INITIALIZED);
15839126SWyllys.Ingersoll@Sun.COM 			}
15849126SWyllys.Ingersoll@Sun.COM 		}
15859126SWyllys.Ingersoll@Sun.COM 
15869126SWyllys.Ingersoll@Sun.COM 		/*
15879126SWyllys.Ingersoll@Sun.COM 		 * - find privateRootKeyUUID
15889126SWyllys.Ingersoll@Sun.COM 		 * - load by UUID (SRK parent)
15899126SWyllys.Ingersoll@Sun.COM 		 */
15909126SWyllys.Ingersoll@Sun.COM 		if (local_uuid_is_null(&privateRootKeyUUID) &&
15919126SWyllys.Ingersoll@Sun.COM 		    find_uuid(TPMTOK_PRIVATE_ROOT_KEY_ID,
15929126SWyllys.Ingersoll@Sun.COM 		    &privateRootKeyUUID)) {
15939126SWyllys.Ingersoll@Sun.COM 				if (memcmp(hash_sha,
15949126SWyllys.Ingersoll@Sun.COM 				    default_user_pin_sha,
15959126SWyllys.Ingersoll@Sun.COM 				    SHA1_DIGEST_LENGTH))
15969126SWyllys.Ingersoll@Sun.COM 					return (CKR_PIN_INCORRECT);
15979126SWyllys.Ingersoll@Sun.COM 
15989126SWyllys.Ingersoll@Sun.COM 				not_initialized = 1;
15999126SWyllys.Ingersoll@Sun.COM 				return (CKR_OK);
16009126SWyllys.Ingersoll@Sun.COM 		}
16019126SWyllys.Ingersoll@Sun.COM 
16029126SWyllys.Ingersoll@Sun.COM 		if ((rc = verify_user_pin(hContext, hash_sha))) {
16039126SWyllys.Ingersoll@Sun.COM 			return (rc);
16049126SWyllys.Ingersoll@Sun.COM 		}
16059126SWyllys.Ingersoll@Sun.COM 
16069126SWyllys.Ingersoll@Sun.COM 		(void) memcpy(current_user_pin_sha, hash_sha,
16079126SWyllys.Ingersoll@Sun.COM 		    SHA1_DIGEST_LENGTH);
16089126SWyllys.Ingersoll@Sun.COM 
16099126SWyllys.Ingersoll@Sun.COM 		rc = load_private_token_objects(hContext);
16109126SWyllys.Ingersoll@Sun.COM 		if (rc == CKR_OK) {
16119126SWyllys.Ingersoll@Sun.COM 			(void) XProcLock(xproclock);
16129126SWyllys.Ingersoll@Sun.COM 			global_shm->priv_loaded = TRUE;
16139126SWyllys.Ingersoll@Sun.COM 			(void) XProcUnLock(xproclock);
16149126SWyllys.Ingersoll@Sun.COM 		}
16159126SWyllys.Ingersoll@Sun.COM 	} else {
16169126SWyllys.Ingersoll@Sun.COM 		/*
16179126SWyllys.Ingersoll@Sun.COM 		 * SO login logic:
16189126SWyllys.Ingersoll@Sun.COM 		 *
16199126SWyllys.Ingersoll@Sun.COM 		 * - find publicRootKey UUID
16209126SWyllys.Ingersoll@Sun.COM 		 * - load by UUID wrap with hSRK from above
16219126SWyllys.Ingersoll@Sun.COM 		 */
16229126SWyllys.Ingersoll@Sun.COM 		if (local_uuid_is_null(&publicRootKeyUUID) &&
16239126SWyllys.Ingersoll@Sun.COM 		    find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID,
16249126SWyllys.Ingersoll@Sun.COM 		    &publicRootKeyUUID)) {
16259126SWyllys.Ingersoll@Sun.COM 				if (memcmp(hash_sha,
16269126SWyllys.Ingersoll@Sun.COM 				    default_so_pin_sha,
16279126SWyllys.Ingersoll@Sun.COM 				    SHA1_DIGEST_LENGTH))
16289126SWyllys.Ingersoll@Sun.COM 					return (CKR_PIN_INCORRECT);
16299126SWyllys.Ingersoll@Sun.COM 
16309126SWyllys.Ingersoll@Sun.COM 				not_initialized = 1;
16319126SWyllys.Ingersoll@Sun.COM 				return (CKR_OK);
16329126SWyllys.Ingersoll@Sun.COM 
16339126SWyllys.Ingersoll@Sun.COM 		}
16349126SWyllys.Ingersoll@Sun.COM 		if (hPublicRootKey == NULL_HKEY) {
16359126SWyllys.Ingersoll@Sun.COM 			result = tss_find_and_load_key(
16369126SWyllys.Ingersoll@Sun.COM 			    hContext,
16379126SWyllys.Ingersoll@Sun.COM 			    TPMTOK_PUBLIC_ROOT_KEY_ID,
16389126SWyllys.Ingersoll@Sun.COM 			    &publicRootKeyUUID, hSRK, NULL,
16399126SWyllys.Ingersoll@Sun.COM 			    &hPublicRootKey);
16409126SWyllys.Ingersoll@Sun.COM 
16419126SWyllys.Ingersoll@Sun.COM 			if (result)
16429126SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
16439126SWyllys.Ingersoll@Sun.COM 		}
16449126SWyllys.Ingersoll@Sun.COM 
16459126SWyllys.Ingersoll@Sun.COM 		/* find, load the public leaf key */
16469126SWyllys.Ingersoll@Sun.COM 		if (hPublicLeafKey == NULL_HKEY) {
16479126SWyllys.Ingersoll@Sun.COM 			result = tss_find_and_load_key(
16489126SWyllys.Ingersoll@Sun.COM 			    hContext,
16499126SWyllys.Ingersoll@Sun.COM 			    TPMTOK_PUBLIC_LEAF_KEY_ID,
16509126SWyllys.Ingersoll@Sun.COM 			    &publicLeafKeyUUID, hPublicRootKey, hash_sha,
16519126SWyllys.Ingersoll@Sun.COM 			    &hPublicLeafKey);
16529126SWyllys.Ingersoll@Sun.COM 			if (result)
16539126SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
16549126SWyllys.Ingersoll@Sun.COM 		}
16559126SWyllys.Ingersoll@Sun.COM 
16569126SWyllys.Ingersoll@Sun.COM 		if ((rc = token_verify_pin(hContext, hPublicLeafKey))) {
16579126SWyllys.Ingersoll@Sun.COM 			return (rc);
16589126SWyllys.Ingersoll@Sun.COM 		}
16599126SWyllys.Ingersoll@Sun.COM 
16609126SWyllys.Ingersoll@Sun.COM 		(void) memcpy(current_so_pin_sha, hash_sha, SHA1_DIGEST_LENGTH);
16619126SWyllys.Ingersoll@Sun.COM 	}
16629126SWyllys.Ingersoll@Sun.COM 
16639126SWyllys.Ingersoll@Sun.COM 	return (rc);
16649126SWyllys.Ingersoll@Sun.COM }
16659126SWyllys.Ingersoll@Sun.COM 
16669126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_logout(TSS_HCONTEXT hContext)16679126SWyllys.Ingersoll@Sun.COM token_specific_logout(TSS_HCONTEXT hContext)
16689126SWyllys.Ingersoll@Sun.COM {
16699126SWyllys.Ingersoll@Sun.COM 	if (hPrivateLeafKey != NULL_HKEY) {
16709126SWyllys.Ingersoll@Sun.COM 		Tspi_Key_UnloadKey(hPrivateLeafKey);
16719126SWyllys.Ingersoll@Sun.COM 		hPrivateLeafKey = NULL_HKEY;
16729126SWyllys.Ingersoll@Sun.COM 	} else if (hPublicLeafKey != NULL_HKEY) {
16739126SWyllys.Ingersoll@Sun.COM 		Tspi_Key_UnloadKey(hPublicLeafKey);
16749126SWyllys.Ingersoll@Sun.COM 		hPublicLeafKey = NULL_HKEY;
16759126SWyllys.Ingersoll@Sun.COM 	}
16769126SWyllys.Ingersoll@Sun.COM 
16779126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&publicRootKeyUUID);
16789126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&publicLeafKeyUUID);
16799126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&privateRootKeyUUID);
16809126SWyllys.Ingersoll@Sun.COM 	local_uuid_clear(&privateLeafKeyUUID);
16819126SWyllys.Ingersoll@Sun.COM 
16829126SWyllys.Ingersoll@Sun.COM 	(void) memset(current_so_pin_sha, 0, SHA1_DIGEST_LENGTH);
16839126SWyllys.Ingersoll@Sun.COM 	(void) memset(current_user_pin_sha, 0, SHA1_DIGEST_LENGTH);
16849126SWyllys.Ingersoll@Sun.COM 
16859126SWyllys.Ingersoll@Sun.COM 	(void) object_mgr_purge_private_token_objects(hContext);
16869126SWyllys.Ingersoll@Sun.COM 
16879126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
16889126SWyllys.Ingersoll@Sun.COM }
16899126SWyllys.Ingersoll@Sun.COM 
16909126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/
16919126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_init_pin(TSS_HCONTEXT hContext,CK_CHAR_PTR pPin,CK_ULONG ulPinLen)16929126SWyllys.Ingersoll@Sun.COM token_specific_init_pin(TSS_HCONTEXT hContext,
16939126SWyllys.Ingersoll@Sun.COM 	CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
16949126SWyllys.Ingersoll@Sun.COM {
16959126SWyllys.Ingersoll@Sun.COM 	/*
16969126SWyllys.Ingersoll@Sun.COM 	 * Since the SO must log in before calling C_InitPIN, we will
16979126SWyllys.Ingersoll@Sun.COM 	 * be able to return (CKR_OK) automatically here.
16989126SWyllys.Ingersoll@Sun.COM 	 * This is because the USER key structure is created at the
16999126SWyllys.Ingersoll@Sun.COM 	 * time of her first login, not at C_InitPIN time.
17009126SWyllys.Ingersoll@Sun.COM 	 */
17019126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
17029126SWyllys.Ingersoll@Sun.COM }
17039126SWyllys.Ingersoll@Sun.COM 
17049126SWyllys.Ingersoll@Sun.COM static CK_RV
check_pin_properties(CK_USER_TYPE userType,CK_BYTE * pinHash,CK_ULONG ulPinLen)17059126SWyllys.Ingersoll@Sun.COM check_pin_properties(CK_USER_TYPE userType, CK_BYTE *pinHash,
17069126SWyllys.Ingersoll@Sun.COM 	CK_ULONG ulPinLen)
17079126SWyllys.Ingersoll@Sun.COM {
17089126SWyllys.Ingersoll@Sun.COM 	/* make sure the new PIN is different */
17099126SWyllys.Ingersoll@Sun.COM 	if (userType == CKU_USER) {
17109126SWyllys.Ingersoll@Sun.COM 		if (!memcmp(pinHash, default_user_pin_sha,
17119126SWyllys.Ingersoll@Sun.COM 		    SHA1_DIGEST_LENGTH)) {
17129126SWyllys.Ingersoll@Sun.COM 			LogError1("new PIN must not be the default");
17139126SWyllys.Ingersoll@Sun.COM 			return (CKR_PIN_INVALID);
17149126SWyllys.Ingersoll@Sun.COM 		}
17159126SWyllys.Ingersoll@Sun.COM 	} else {
17169126SWyllys.Ingersoll@Sun.COM 		if (!memcmp(pinHash, default_so_pin_sha,
17179126SWyllys.Ingersoll@Sun.COM 		    SHA1_DIGEST_LENGTH)) {
17189126SWyllys.Ingersoll@Sun.COM 			LogError1("new PIN must not be the default");
17199126SWyllys.Ingersoll@Sun.COM 			return (CKR_PIN_INVALID);
17209126SWyllys.Ingersoll@Sun.COM 		}
17219126SWyllys.Ingersoll@Sun.COM 	}
17229126SWyllys.Ingersoll@Sun.COM 
17239126SWyllys.Ingersoll@Sun.COM 	if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) {
17249126SWyllys.Ingersoll@Sun.COM 		LogError1("New PIN is out of size range");
17259126SWyllys.Ingersoll@Sun.COM 		return (CKR_PIN_LEN_RANGE);
17269126SWyllys.Ingersoll@Sun.COM 	}
17279126SWyllys.Ingersoll@Sun.COM 
17289126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
17299126SWyllys.Ingersoll@Sun.COM }
17309126SWyllys.Ingersoll@Sun.COM 
17319126SWyllys.Ingersoll@Sun.COM /*
17329126SWyllys.Ingersoll@Sun.COM  * This function is called from set_pin only, where a non-logged-in public
17339126SWyllys.Ingersoll@Sun.COM  * session can provide the user pin which must be verified. This function
17349126SWyllys.Ingersoll@Sun.COM  * assumes that the pin has already been set once, so there's no migration
17359126SWyllys.Ingersoll@Sun.COM  * path option or checking of the default user pin.
17369126SWyllys.Ingersoll@Sun.COM  */
17379126SWyllys.Ingersoll@Sun.COM static CK_RV
verify_user_pin(TSS_HCONTEXT hContext,CK_BYTE * hash_sha)17389126SWyllys.Ingersoll@Sun.COM verify_user_pin(TSS_HCONTEXT hContext, CK_BYTE *hash_sha)
17399126SWyllys.Ingersoll@Sun.COM {
17409126SWyllys.Ingersoll@Sun.COM 	CK_RV rc;
17419126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
17429126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hSRK;
17439126SWyllys.Ingersoll@Sun.COM 
17449126SWyllys.Ingersoll@Sun.COM 	if (token_load_srk(hContext, &hSRK))
17459126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
17469126SWyllys.Ingersoll@Sun.COM 
17479126SWyllys.Ingersoll@Sun.COM 	/*
17489126SWyllys.Ingersoll@Sun.COM 	 * Verify the user by loading the privateLeafKey
17499126SWyllys.Ingersoll@Sun.COM 	 * into the TPM (if it's not already) and then
17509126SWyllys.Ingersoll@Sun.COM 	 * call the verify_pin operation.
17519126SWyllys.Ingersoll@Sun.COM 	 *
17529126SWyllys.Ingersoll@Sun.COM 	 * The hashed PIN is assigned to the private leaf key.
17539126SWyllys.Ingersoll@Sun.COM 	 * If it is incorrect (not the same as the one originally
17549126SWyllys.Ingersoll@Sun.COM 	 * used when the key was created), the verify operation
17559126SWyllys.Ingersoll@Sun.COM 	 * will fail.
17569126SWyllys.Ingersoll@Sun.COM 	 */
17579126SWyllys.Ingersoll@Sun.COM 	if (hPrivateRootKey == NULL_HKEY) {
17589126SWyllys.Ingersoll@Sun.COM 		result = tss_find_and_load_key(
17599126SWyllys.Ingersoll@Sun.COM 		    hContext,
17609126SWyllys.Ingersoll@Sun.COM 		    TPMTOK_PRIVATE_ROOT_KEY_ID,
17619126SWyllys.Ingersoll@Sun.COM 		    &privateRootKeyUUID, hSRK, NULL, &hPrivateRootKey);
17629126SWyllys.Ingersoll@Sun.COM 		if (result)
17639126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
17649126SWyllys.Ingersoll@Sun.COM 	}
17659126SWyllys.Ingersoll@Sun.COM 
17669126SWyllys.Ingersoll@Sun.COM 	if (hPrivateLeafKey == NULL_HKEY) {
17679126SWyllys.Ingersoll@Sun.COM 		result = tss_find_and_load_key(
17689126SWyllys.Ingersoll@Sun.COM 		    hContext,
17699126SWyllys.Ingersoll@Sun.COM 		    TPMTOK_PRIVATE_LEAF_KEY_ID,
17709126SWyllys.Ingersoll@Sun.COM 		    &privateLeafKeyUUID, hPrivateRootKey, hash_sha,
17719126SWyllys.Ingersoll@Sun.COM 		    &hPrivateLeafKey);
17729126SWyllys.Ingersoll@Sun.COM 
17739126SWyllys.Ingersoll@Sun.COM 		if (result)
17749126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
17759126SWyllys.Ingersoll@Sun.COM 	}
17769126SWyllys.Ingersoll@Sun.COM 
17779126SWyllys.Ingersoll@Sun.COM 	/*
17789126SWyllys.Ingersoll@Sun.COM 	 * Verify that the PIN is correct by attempting to wrap/unwrap some
17799126SWyllys.Ingersoll@Sun.COM 	 * random data.
17809126SWyllys.Ingersoll@Sun.COM 	 */
17819126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_verify_pin(hContext, hPrivateLeafKey))) {
17829126SWyllys.Ingersoll@Sun.COM 		return (rc);
17839126SWyllys.Ingersoll@Sun.COM 	}
17849126SWyllys.Ingersoll@Sun.COM 
17859126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
17869126SWyllys.Ingersoll@Sun.COM }
17879126SWyllys.Ingersoll@Sun.COM 
17889126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_set_pin(ST_SESSION_HANDLE session,CK_CHAR_PTR pOldPin,CK_ULONG ulOldPinLen,CK_CHAR_PTR pNewPin,CK_ULONG ulNewPinLen)17899126SWyllys.Ingersoll@Sun.COM token_specific_set_pin(ST_SESSION_HANDLE session,
17909126SWyllys.Ingersoll@Sun.COM 	CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
17919126SWyllys.Ingersoll@Sun.COM 	CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
17929126SWyllys.Ingersoll@Sun.COM {
17939126SWyllys.Ingersoll@Sun.COM 	SESSION		*sess = session_mgr_find(session.sessionh);
17949126SWyllys.Ingersoll@Sun.COM 	CK_BYTE		oldpin_hash[SHA1_DIGEST_LENGTH];
17959126SWyllys.Ingersoll@Sun.COM 	CK_BYTE		newpin_hash[SHA1_DIGEST_LENGTH];
17969126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
17979126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hSRK;
17989126SWyllys.Ingersoll@Sun.COM 
17999126SWyllys.Ingersoll@Sun.COM 	if (!sess) {
18009126SWyllys.Ingersoll@Sun.COM 		return (CKR_SESSION_HANDLE_INVALID);
18019126SWyllys.Ingersoll@Sun.COM 	}
18029126SWyllys.Ingersoll@Sun.COM 
18039126SWyllys.Ingersoll@Sun.COM 	if ((rc = compute_sha(pOldPin, ulOldPinLen, oldpin_hash))) {
18049126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
18059126SWyllys.Ingersoll@Sun.COM 	}
18069126SWyllys.Ingersoll@Sun.COM 	if ((rc = compute_sha(pNewPin, ulNewPinLen, newpin_hash))) {
18079126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
18089126SWyllys.Ingersoll@Sun.COM 	}
18099126SWyllys.Ingersoll@Sun.COM 
18109126SWyllys.Ingersoll@Sun.COM 	if (token_load_srk(sess->hContext, &hSRK)) {
18119126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
18129126SWyllys.Ingersoll@Sun.COM 	}
18139126SWyllys.Ingersoll@Sun.COM 
18149126SWyllys.Ingersoll@Sun.COM 	/*
18159126SWyllys.Ingersoll@Sun.COM 	 * From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of
18169126SWyllys.Ingersoll@Sun.COM 	 * the user that is currently logged in, or the CKU_USER PIN
18179126SWyllys.Ingersoll@Sun.COM 	 * if the session is not logged in."
18189126SWyllys.Ingersoll@Sun.COM 	 * A non R/W session fails with CKR_SESSION_READ_ONLY.
18199126SWyllys.Ingersoll@Sun.COM 	 */
18209126SWyllys.Ingersoll@Sun.COM 	if (sess->session_info.state == CKS_RW_USER_FUNCTIONS ||
18219126SWyllys.Ingersoll@Sun.COM 	    sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
18229126SWyllys.Ingersoll@Sun.COM 		if (not_initialized) {
18239126SWyllys.Ingersoll@Sun.COM 			if (memcmp(oldpin_hash, default_user_pin_sha,
18249126SWyllys.Ingersoll@Sun.COM 			    SHA1_DIGEST_LENGTH)) {
18259126SWyllys.Ingersoll@Sun.COM 				return (CKR_PIN_INCORRECT);
18269126SWyllys.Ingersoll@Sun.COM 			}
18279126SWyllys.Ingersoll@Sun.COM 
18289126SWyllys.Ingersoll@Sun.COM 			if ((rc = check_pin_properties(CKU_USER, newpin_hash,
18299126SWyllys.Ingersoll@Sun.COM 			    ulNewPinLen))) {
18309126SWyllys.Ingersoll@Sun.COM 				return (rc);
18319126SWyllys.Ingersoll@Sun.COM 			}
18329126SWyllys.Ingersoll@Sun.COM 
18339126SWyllys.Ingersoll@Sun.COM 			if ((rc = token_create_private_tree(sess->hContext,
18349126SWyllys.Ingersoll@Sun.COM 			    newpin_hash))) {
18359126SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
18369126SWyllys.Ingersoll@Sun.COM 			}
18379126SWyllys.Ingersoll@Sun.COM 
18389126SWyllys.Ingersoll@Sun.COM 			nv_token_data->token_info.flags &=
18399126SWyllys.Ingersoll@Sun.COM 			    ~(CKF_USER_PIN_TO_BE_CHANGED);
18409126SWyllys.Ingersoll@Sun.COM 			nv_token_data->token_info.flags |=
18419126SWyllys.Ingersoll@Sun.COM 			    CKF_USER_PIN_INITIALIZED;
18429126SWyllys.Ingersoll@Sun.COM 
18439126SWyllys.Ingersoll@Sun.COM 			nv_token_data->token_info.flags &=
18449126SWyllys.Ingersoll@Sun.COM 			    ~(CKF_USER_PIN_TO_BE_CHANGED);
18459126SWyllys.Ingersoll@Sun.COM 			nv_token_data->token_info.flags |=
18469126SWyllys.Ingersoll@Sun.COM 			    CKF_USER_PIN_INITIALIZED;
18479126SWyllys.Ingersoll@Sun.COM 
18489126SWyllys.Ingersoll@Sun.COM 			return (save_token_data(nv_token_data));
18499126SWyllys.Ingersoll@Sun.COM 		}
18509126SWyllys.Ingersoll@Sun.COM 
18519126SWyllys.Ingersoll@Sun.COM 		if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) {
18529126SWyllys.Ingersoll@Sun.COM 			/* if we're already logged in, just verify the hash */
18539126SWyllys.Ingersoll@Sun.COM 			if (memcmp(current_user_pin_sha, oldpin_hash,
18549126SWyllys.Ingersoll@Sun.COM 			    SHA1_DIGEST_LENGTH)) {
18559126SWyllys.Ingersoll@Sun.COM 				return (CKR_PIN_INCORRECT);
18569126SWyllys.Ingersoll@Sun.COM 			}
18579126SWyllys.Ingersoll@Sun.COM 		} else {
18589126SWyllys.Ingersoll@Sun.COM 			if ((rc = verify_user_pin(sess->hContext,
18599126SWyllys.Ingersoll@Sun.COM 			    oldpin_hash))) {
18609126SWyllys.Ingersoll@Sun.COM 				return (rc);
18619126SWyllys.Ingersoll@Sun.COM 			}
18629126SWyllys.Ingersoll@Sun.COM 		}
18639126SWyllys.Ingersoll@Sun.COM 
18649126SWyllys.Ingersoll@Sun.COM 		if ((rc = check_pin_properties(CKU_USER, newpin_hash,
18659126SWyllys.Ingersoll@Sun.COM 		    ulNewPinLen)))
18669126SWyllys.Ingersoll@Sun.COM 			return (rc);
18679126SWyllys.Ingersoll@Sun.COM 
18689126SWyllys.Ingersoll@Sun.COM 		/* change the auth on the TSS object */
18699126SWyllys.Ingersoll@Sun.COM 		if (tss_change_auth(sess->hContext,
18709126SWyllys.Ingersoll@Sun.COM 		    hPrivateLeafKey, hPrivateRootKey,
18719126SWyllys.Ingersoll@Sun.COM 		    privateLeafKeyUUID, privateRootKeyUUID,
18729126SWyllys.Ingersoll@Sun.COM 		    newpin_hash))
18739126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
18749126SWyllys.Ingersoll@Sun.COM 
18759126SWyllys.Ingersoll@Sun.COM 	} else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
18769126SWyllys.Ingersoll@Sun.COM 		if (not_initialized) {
18779126SWyllys.Ingersoll@Sun.COM 			if (memcmp(default_so_pin_sha, oldpin_hash,
18789126SWyllys.Ingersoll@Sun.COM 			    SHA1_DIGEST_LENGTH))
18799126SWyllys.Ingersoll@Sun.COM 				return (CKR_PIN_INCORRECT);
18809126SWyllys.Ingersoll@Sun.COM 
18819126SWyllys.Ingersoll@Sun.COM 			if ((rc = check_pin_properties(CKU_SO,
18829126SWyllys.Ingersoll@Sun.COM 			    newpin_hash, ulNewPinLen)))
18839126SWyllys.Ingersoll@Sun.COM 				return (rc);
18849126SWyllys.Ingersoll@Sun.COM 
18859126SWyllys.Ingersoll@Sun.COM 			if ((rc = token_create_public_tree(sess->hContext,
18869126SWyllys.Ingersoll@Sun.COM 			    newpin_hash)))
18879126SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
18889126SWyllys.Ingersoll@Sun.COM 
18899126SWyllys.Ingersoll@Sun.COM 			nv_token_data->token_info.flags &=
18909126SWyllys.Ingersoll@Sun.COM 			    ~(CKF_SO_PIN_TO_BE_CHANGED);
18919126SWyllys.Ingersoll@Sun.COM 
18929126SWyllys.Ingersoll@Sun.COM 			return (save_token_data(nv_token_data));
18939126SWyllys.Ingersoll@Sun.COM 		}
18949126SWyllys.Ingersoll@Sun.COM 
18959126SWyllys.Ingersoll@Sun.COM 		if (memcmp(current_so_pin_sha, oldpin_hash,
18969126SWyllys.Ingersoll@Sun.COM 		    SHA1_DIGEST_LENGTH))
18979126SWyllys.Ingersoll@Sun.COM 			return (CKR_PIN_INCORRECT);
18989126SWyllys.Ingersoll@Sun.COM 
18999126SWyllys.Ingersoll@Sun.COM 		if ((rc = check_pin_properties(CKU_SO, newpin_hash,
19009126SWyllys.Ingersoll@Sun.COM 		    ulNewPinLen)))
19019126SWyllys.Ingersoll@Sun.COM 			return (rc);
19029126SWyllys.Ingersoll@Sun.COM 
19039126SWyllys.Ingersoll@Sun.COM 		/* change auth on the SO's leaf key */
19049126SWyllys.Ingersoll@Sun.COM 		if (tss_change_auth(sess->hContext,
19059126SWyllys.Ingersoll@Sun.COM 		    hPublicLeafKey, hPublicRootKey,
19069126SWyllys.Ingersoll@Sun.COM 		    publicLeafKeyUUID, publicRootKeyUUID,
19079126SWyllys.Ingersoll@Sun.COM 		    newpin_hash))
19089126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
19099126SWyllys.Ingersoll@Sun.COM 
19109126SWyllys.Ingersoll@Sun.COM 	} else {
19119126SWyllys.Ingersoll@Sun.COM 		rc = CKR_SESSION_READ_ONLY;
19129126SWyllys.Ingersoll@Sun.COM 	}
19139126SWyllys.Ingersoll@Sun.COM 
19149126SWyllys.Ingersoll@Sun.COM 	return (rc);
19159126SWyllys.Ingersoll@Sun.COM }
19169126SWyllys.Ingersoll@Sun.COM 
19179126SWyllys.Ingersoll@Sun.COM /* only called at token init time */
19189126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_verify_so_pin(TSS_HCONTEXT hContext,CK_CHAR_PTR pPin,CK_ULONG ulPinLen)19199126SWyllys.Ingersoll@Sun.COM token_specific_verify_so_pin(TSS_HCONTEXT hContext, CK_CHAR_PTR pPin,
19209126SWyllys.Ingersoll@Sun.COM     CK_ULONG ulPinLen)
19219126SWyllys.Ingersoll@Sun.COM {
19229126SWyllys.Ingersoll@Sun.COM 	CK_BYTE hash_sha[SHA1_DIGEST_LENGTH];
19239126SWyllys.Ingersoll@Sun.COM 	CK_RV rc;
19249126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
19259126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hSRK;
19269126SWyllys.Ingersoll@Sun.COM 
19279126SWyllys.Ingersoll@Sun.COM 	if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) {
19289126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19299126SWyllys.Ingersoll@Sun.COM 	}
19309126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_load_srk(hContext, &hSRK))) {
19319126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19329126SWyllys.Ingersoll@Sun.COM 	}
19339126SWyllys.Ingersoll@Sun.COM 
19349126SWyllys.Ingersoll@Sun.COM 	/*
19359126SWyllys.Ingersoll@Sun.COM 	 * TRYME INSTEAD:
19369126SWyllys.Ingersoll@Sun.COM 	 * - find publicRootKeyUUID
19379126SWyllys.Ingersoll@Sun.COM 	 * - Load publicRootKey by UUID (SRK parent)
19389126SWyllys.Ingersoll@Sun.COM 	 * - find publicLeafKeyUUID
19399126SWyllys.Ingersoll@Sun.COM 	 * - Load publicLeafKey by UUID (publicRootKey parent)
19409126SWyllys.Ingersoll@Sun.COM 	 * - set password policy on publicLeafKey
19419126SWyllys.Ingersoll@Sun.COM 	 */
19429126SWyllys.Ingersoll@Sun.COM 	if (local_uuid_is_null(&publicRootKeyUUID) &&
19439126SWyllys.Ingersoll@Sun.COM 	    find_uuid(TPMTOK_PUBLIC_ROOT_KEY_ID, &publicRootKeyUUID)) {
19449126SWyllys.Ingersoll@Sun.COM 		/*
19459126SWyllys.Ingersoll@Sun.COM 		 * The SO hasn't set her PIN yet, compare the
19469126SWyllys.Ingersoll@Sun.COM 		 * login pin with the hard-coded value.
19479126SWyllys.Ingersoll@Sun.COM 		 */
19489126SWyllys.Ingersoll@Sun.COM 		if (memcmp(default_so_pin_sha, hash_sha,
19499126SWyllys.Ingersoll@Sun.COM 		    SHA1_DIGEST_LENGTH)) {
19509126SWyllys.Ingersoll@Sun.COM 			return (CKR_PIN_INCORRECT);
19519126SWyllys.Ingersoll@Sun.COM 		}
19529126SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
19539126SWyllys.Ingersoll@Sun.COM 	}
19549126SWyllys.Ingersoll@Sun.COM 
19559126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Context_GetKeyByUUID(hContext,
19569126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, publicRootKeyUUID, &hPublicRootKey);
19579126SWyllys.Ingersoll@Sun.COM 
19589126SWyllys.Ingersoll@Sun.COM 	if (result)
19599126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19609126SWyllys.Ingersoll@Sun.COM 
19619126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Key_LoadKey(hPublicRootKey, hSRK);
19629126SWyllys.Ingersoll@Sun.COM 	if (result)
19639126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19649126SWyllys.Ingersoll@Sun.COM 
19659126SWyllys.Ingersoll@Sun.COM 	if (local_uuid_is_null(&publicLeafKeyUUID) &&
19669126SWyllys.Ingersoll@Sun.COM 	    find_uuid(TPMTOK_PUBLIC_LEAF_KEY_ID, &publicLeafKeyUUID))
19679126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19689126SWyllys.Ingersoll@Sun.COM 
19699126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Context_GetKeyByUUID(hContext,
19709126SWyllys.Ingersoll@Sun.COM 	    TSS_PS_TYPE_USER, publicLeafKeyUUID, &hPublicLeafKey);
19719126SWyllys.Ingersoll@Sun.COM 	if (result)
19729126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19739126SWyllys.Ingersoll@Sun.COM 
19749453SWyllys.Ingersoll@Sun.COM 	result = tss_assign_secret_key_policy(hContext, TSS_POLICY_USAGE,
19759453SWyllys.Ingersoll@Sun.COM 	    hPublicLeafKey, hash_sha);
19769126SWyllys.Ingersoll@Sun.COM 	if (result)
19779126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19789126SWyllys.Ingersoll@Sun.COM 
19799126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey);
19809126SWyllys.Ingersoll@Sun.COM 	if (result)
19819126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
19829126SWyllys.Ingersoll@Sun.COM 
19839126SWyllys.Ingersoll@Sun.COM 	/* If the hash given is wrong, the verify will fail */
19849126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_verify_pin(hContext, hPublicLeafKey))) {
19859126SWyllys.Ingersoll@Sun.COM 		return (rc);
19869126SWyllys.Ingersoll@Sun.COM 	}
19879126SWyllys.Ingersoll@Sun.COM 
19889126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
19899126SWyllys.Ingersoll@Sun.COM }
19909126SWyllys.Ingersoll@Sun.COM 
19919126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_final(TSS_HCONTEXT hContext)19929453SWyllys.Ingersoll@Sun.COM token_specific_final(TSS_HCONTEXT hContext)
19939126SWyllys.Ingersoll@Sun.COM {
19949453SWyllys.Ingersoll@Sun.COM 	if (hPublicRootKey != NULL_HKEY) {
19959453SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPublicRootKey);
19969453SWyllys.Ingersoll@Sun.COM 		hPublicRootKey = NULL_HKEY;
19979453SWyllys.Ingersoll@Sun.COM 	}
19989453SWyllys.Ingersoll@Sun.COM 	if (hPublicLeafKey != NULL_HKEY) {
19999453SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPublicLeafKey);
20009453SWyllys.Ingersoll@Sun.COM 		hPublicLeafKey = NULL_HKEY;
20019453SWyllys.Ingersoll@Sun.COM 	}
20029453SWyllys.Ingersoll@Sun.COM 	if (hPrivateRootKey != NULL_HKEY) {
20039453SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPrivateRootKey);
20049453SWyllys.Ingersoll@Sun.COM 		hPrivateRootKey = NULL_HKEY;
20059453SWyllys.Ingersoll@Sun.COM 	}
20069453SWyllys.Ingersoll@Sun.COM 	if (hPrivateLeafKey != NULL_HKEY) {
20079453SWyllys.Ingersoll@Sun.COM 		Tspi_Context_CloseObject(hContext, hPrivateLeafKey);
20089453SWyllys.Ingersoll@Sun.COM 		hPrivateLeafKey = NULL_HKEY;
20099453SWyllys.Ingersoll@Sun.COM 	}
20109126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
20119126SWyllys.Ingersoll@Sun.COM }
20129126SWyllys.Ingersoll@Sun.COM 
20139126SWyllys.Ingersoll@Sun.COM /*
20149126SWyllys.Ingersoll@Sun.COM  * Wrap the 20 bytes of auth data and store in an attribute of the two
20159126SWyllys.Ingersoll@Sun.COM  * keys.
20169126SWyllys.Ingersoll@Sun.COM  */
20179126SWyllys.Ingersoll@Sun.COM static CK_RV
token_wrap_auth_data(TSS_HCONTEXT hContext,CK_BYTE * authData,TEMPLATE * publ_tmpl,TEMPLATE * priv_tmpl)20189126SWyllys.Ingersoll@Sun.COM token_wrap_auth_data(TSS_HCONTEXT hContext,
20199126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *authData, TEMPLATE *publ_tmpl,
20209126SWyllys.Ingersoll@Sun.COM 	TEMPLATE *priv_tmpl)
20219126SWyllys.Ingersoll@Sun.COM {
20229126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
20239126SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE	*new_attr;
20249126SWyllys.Ingersoll@Sun.COM 
20259126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	ret;
20269126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hParentKey;
20279126SWyllys.Ingersoll@Sun.COM 	TSS_HENCDATA	hEncData;
20289126SWyllys.Ingersoll@Sun.COM 	BYTE		*blob;
20299126SWyllys.Ingersoll@Sun.COM 	UINT32		blob_size;
20309126SWyllys.Ingersoll@Sun.COM 
20319126SWyllys.Ingersoll@Sun.COM 	if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) {
20329126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
20339126SWyllys.Ingersoll@Sun.COM 	} else if (hPublicLeafKey != NULL_HKEY) {
20349126SWyllys.Ingersoll@Sun.COM 		hParentKey = hPublicLeafKey;
20359126SWyllys.Ingersoll@Sun.COM 	} else {
20369126SWyllys.Ingersoll@Sun.COM 		hParentKey = hPrivateLeafKey;
20379126SWyllys.Ingersoll@Sun.COM 	}
20389126SWyllys.Ingersoll@Sun.COM 
20399126SWyllys.Ingersoll@Sun.COM 	/* create the encrypted data object */
20409126SWyllys.Ingersoll@Sun.COM 	if ((ret = Tspi_Context_CreateObject(hContext,
20419126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
20429126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
20439126SWyllys.Ingersoll@Sun.COM 		    ret, Trspi_Error_String(ret));
20449126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
20459126SWyllys.Ingersoll@Sun.COM 	}
20469126SWyllys.Ingersoll@Sun.COM 
20479126SWyllys.Ingersoll@Sun.COM 	if ((ret = Tspi_Data_Bind(hEncData, hParentKey, SHA1_DIGEST_LENGTH,
20489126SWyllys.Ingersoll@Sun.COM 	    authData))) {
20499126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Data_Bind: 0x%0x - %s",
20509126SWyllys.Ingersoll@Sun.COM 		    ret, Trspi_Error_String(ret));
20519126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
20529126SWyllys.Ingersoll@Sun.COM 	}
20539126SWyllys.Ingersoll@Sun.COM 
20549126SWyllys.Ingersoll@Sun.COM 	/* pull the encrypted data out of the encrypted data object */
20559126SWyllys.Ingersoll@Sun.COM 	if ((ret = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
20569126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_ENCDATABLOB_BLOB, &blob_size, &blob))) {
20579126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_SetAttribData: 0x%0x - %s",
20589126SWyllys.Ingersoll@Sun.COM 		    ret, Trspi_Error_String(ret));
20599126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
20609126SWyllys.Ingersoll@Sun.COM 	}
20619126SWyllys.Ingersoll@Sun.COM 
20629126SWyllys.Ingersoll@Sun.COM 	if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size,
20639126SWyllys.Ingersoll@Sun.COM 	    &new_attr))) {
20649126SWyllys.Ingersoll@Sun.COM 		return (rc);
20659126SWyllys.Ingersoll@Sun.COM 	}
20669126SWyllys.Ingersoll@Sun.COM 	(void) template_update_attribute(publ_tmpl, new_attr);
20679126SWyllys.Ingersoll@Sun.COM 
20689126SWyllys.Ingersoll@Sun.COM 	if ((rc = build_attribute(CKA_ENC_AUTHDATA, blob,
20699126SWyllys.Ingersoll@Sun.COM 	    blob_size, &new_attr))) {
20709126SWyllys.Ingersoll@Sun.COM 		return (rc);
20719126SWyllys.Ingersoll@Sun.COM 	}
20729126SWyllys.Ingersoll@Sun.COM 	(void) template_update_attribute(priv_tmpl, new_attr);
20739126SWyllys.Ingersoll@Sun.COM 
20749126SWyllys.Ingersoll@Sun.COM 	return (rc);
20759126SWyllys.Ingersoll@Sun.COM }
20769126SWyllys.Ingersoll@Sun.COM 
20779126SWyllys.Ingersoll@Sun.COM static CK_RV
token_unwrap_auth_data(TSS_HCONTEXT hContext,CK_BYTE * encAuthData,CK_ULONG encAuthDataLen,TSS_HKEY hKey,BYTE ** authData)20789126SWyllys.Ingersoll@Sun.COM token_unwrap_auth_data(TSS_HCONTEXT hContext, CK_BYTE *encAuthData,
20799126SWyllys.Ingersoll@Sun.COM 	CK_ULONG encAuthDataLen, TSS_HKEY hKey,
20809126SWyllys.Ingersoll@Sun.COM 	BYTE **authData)
20819126SWyllys.Ingersoll@Sun.COM {
20829126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
20839126SWyllys.Ingersoll@Sun.COM 	TSS_HENCDATA	hEncData;
20849126SWyllys.Ingersoll@Sun.COM 	BYTE		*buf;
20859126SWyllys.Ingersoll@Sun.COM 	UINT32		buf_size;
20869126SWyllys.Ingersoll@Sun.COM 
20879126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
20889126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
20899126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
20909126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
20919126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
20929126SWyllys.Ingersoll@Sun.COM 	}
20939126SWyllys.Ingersoll@Sun.COM 
20949126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_SetAttribData(hEncData,
20959126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB,
20969126SWyllys.Ingersoll@Sun.COM 	    encAuthDataLen, encAuthData))) {
20979126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_SetAttribData: 0x%0x - %s",
20989126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
20999126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
21009126SWyllys.Ingersoll@Sun.COM 	}
21019126SWyllys.Ingersoll@Sun.COM 
21029126SWyllys.Ingersoll@Sun.COM 	/* unbind the data, receiving the plaintext back */
21039126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf))) {
21049126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Data_Unbind: 0x%0x - %s",
21059126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
21069126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
21079126SWyllys.Ingersoll@Sun.COM 	}
21089126SWyllys.Ingersoll@Sun.COM 
21099126SWyllys.Ingersoll@Sun.COM 	if (buf_size != SHA1_DIGEST_LENGTH) {
21109126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
21119126SWyllys.Ingersoll@Sun.COM 	}
21129126SWyllys.Ingersoll@Sun.COM 
21139126SWyllys.Ingersoll@Sun.COM 	*authData = buf;
21149126SWyllys.Ingersoll@Sun.COM 
21159126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
21169126SWyllys.Ingersoll@Sun.COM }
21179126SWyllys.Ingersoll@Sun.COM 
21189126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_rsa_generate_keypair(TSS_HCONTEXT hContext,TEMPLATE * publ_tmpl,TEMPLATE * priv_tmpl)21199126SWyllys.Ingersoll@Sun.COM token_specific_rsa_generate_keypair(
21209126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
21219126SWyllys.Ingersoll@Sun.COM 	TEMPLATE  *publ_tmpl,
21229126SWyllys.Ingersoll@Sun.COM 	TEMPLATE  *priv_tmpl)
21239126SWyllys.Ingersoll@Sun.COM {
21249126SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE	*attr = NULL;
21259126SWyllys.Ingersoll@Sun.COM 	CK_ULONG	mod_bits = 0;
21269126SWyllys.Ingersoll@Sun.COM 	CK_BBOOL	flag;
21279126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
21289126SWyllys.Ingersoll@Sun.COM 
21299126SWyllys.Ingersoll@Sun.COM 	TSS_FLAG	initFlags = 0;
21309126SWyllys.Ingersoll@Sun.COM 	BYTE		authHash[SHA1_DIGEST_LENGTH];
21319126SWyllys.Ingersoll@Sun.COM 	BYTE		*authData = NULL;
21329126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hKey = NULL_HKEY;
21339126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hParentKey = NULL_HKEY;
21349126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
21359126SWyllys.Ingersoll@Sun.COM 	UINT32		ulBlobLen;
21369126SWyllys.Ingersoll@Sun.COM 	BYTE		*rgbBlob;
21379126SWyllys.Ingersoll@Sun.COM 
21389126SWyllys.Ingersoll@Sun.COM 	/* Make sure the public exponent is usable */
21399126SWyllys.Ingersoll@Sun.COM 	if ((util_check_public_exponent(publ_tmpl))) {
21409126SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCONSISTENT);
21419126SWyllys.Ingersoll@Sun.COM 	}
21429126SWyllys.Ingersoll@Sun.COM 
21439126SWyllys.Ingersoll@Sun.COM 	flag = template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr);
21449126SWyllys.Ingersoll@Sun.COM 	if (!flag) {
21459126SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCOMPLETE);
21469126SWyllys.Ingersoll@Sun.COM 	}
21479126SWyllys.Ingersoll@Sun.COM 	mod_bits = *(CK_ULONG *)attr->pValue;
21489126SWyllys.Ingersoll@Sun.COM 
21499126SWyllys.Ingersoll@Sun.COM 	if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) {
21509126SWyllys.Ingersoll@Sun.COM 		return (CKR_KEY_SIZE_RANGE);
21519126SWyllys.Ingersoll@Sun.COM 	}
21529126SWyllys.Ingersoll@Sun.COM 
21539126SWyllys.Ingersoll@Sun.COM 	/*
21549126SWyllys.Ingersoll@Sun.COM 	 * If we're not logged in, hPrivateLeafKey and hPublicLeafKey
21559126SWyllys.Ingersoll@Sun.COM 	 * should be NULL.
21569126SWyllys.Ingersoll@Sun.COM 	 */
21579126SWyllys.Ingersoll@Sun.COM 	if ((hPrivateLeafKey == NULL_HKEY) &&
21589126SWyllys.Ingersoll@Sun.COM 	    (hPublicLeafKey == NULL_HKEY)) {
21599126SWyllys.Ingersoll@Sun.COM 		/* public session, wrap key with the PRK */
21609126SWyllys.Ingersoll@Sun.COM 		initFlags |= TSS_KEY_TYPE_LEGACY |
21619126SWyllys.Ingersoll@Sun.COM 		    TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE;
21629126SWyllys.Ingersoll@Sun.COM 
21639126SWyllys.Ingersoll@Sun.COM 		if ((result = token_load_public_root_key(hContext))) {
21649126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
21659126SWyllys.Ingersoll@Sun.COM 		}
21669126SWyllys.Ingersoll@Sun.COM 
21679126SWyllys.Ingersoll@Sun.COM 		hParentKey = hPublicRootKey;
21689126SWyllys.Ingersoll@Sun.COM 	} else if (hPrivateLeafKey != NULL_HKEY) {
21699126SWyllys.Ingersoll@Sun.COM 		/* logged in USER session */
21709126SWyllys.Ingersoll@Sun.COM 		initFlags |= TSS_KEY_TYPE_LEGACY |
21719126SWyllys.Ingersoll@Sun.COM 		    TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
21729126SWyllys.Ingersoll@Sun.COM 
21739126SWyllys.Ingersoll@Sun.COM 		/* get a random SHA1 hash for the auth data */
21749126SWyllys.Ingersoll@Sun.COM 		if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) {
21759126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
21769126SWyllys.Ingersoll@Sun.COM 		}
21779126SWyllys.Ingersoll@Sun.COM 
21789126SWyllys.Ingersoll@Sun.COM 		authData = authHash;
21799126SWyllys.Ingersoll@Sun.COM 		hParentKey = hPrivateRootKey;
21809126SWyllys.Ingersoll@Sun.COM 	} else {
21819126SWyllys.Ingersoll@Sun.COM 		/* logged in SO session */
21829126SWyllys.Ingersoll@Sun.COM 		initFlags |= TSS_KEY_TYPE_LEGACY |
21839126SWyllys.Ingersoll@Sun.COM 		    TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
21849126SWyllys.Ingersoll@Sun.COM 
21859126SWyllys.Ingersoll@Sun.COM 		/* get a random SHA1 hash for the auth data */
21869126SWyllys.Ingersoll@Sun.COM 		if ((rc = token_rng(hContext, authHash, SHA1_DIGEST_LENGTH))) {
21879126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
21889126SWyllys.Ingersoll@Sun.COM 		}
21899126SWyllys.Ingersoll@Sun.COM 
21909126SWyllys.Ingersoll@Sun.COM 		authData = authHash;
21919126SWyllys.Ingersoll@Sun.COM 		hParentKey = hPublicRootKey;
21929126SWyllys.Ingersoll@Sun.COM 	}
21939126SWyllys.Ingersoll@Sun.COM 
21949126SWyllys.Ingersoll@Sun.COM 	if ((result = tss_generate_key(hContext, initFlags, authData,
21959126SWyllys.Ingersoll@Sun.COM 	    hParentKey, &hKey))) {
21969126SWyllys.Ingersoll@Sun.COM 		return (result);
21979126SWyllys.Ingersoll@Sun.COM 	}
21989126SWyllys.Ingersoll@Sun.COM 
21999126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
22009126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) {
22019126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetAttribData: 0x%0x - %s",
22029126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
22039126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
22049126SWyllys.Ingersoll@Sun.COM 	}
22059126SWyllys.Ingersoll@Sun.COM 
22069126SWyllys.Ingersoll@Sun.COM 	if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob,
22079126SWyllys.Ingersoll@Sun.COM 	    ulBlobLen, &attr))) {
22089126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, rgbBlob);
22099126SWyllys.Ingersoll@Sun.COM 		return (rc);
22109126SWyllys.Ingersoll@Sun.COM 	}
22119126SWyllys.Ingersoll@Sun.COM 	(void) template_update_attribute(priv_tmpl, attr);
22129126SWyllys.Ingersoll@Sun.COM 	if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob,
22139126SWyllys.Ingersoll@Sun.COM 	    ulBlobLen, &attr))) {
22149126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, rgbBlob);
22159126SWyllys.Ingersoll@Sun.COM 		return (rc);
22169126SWyllys.Ingersoll@Sun.COM 	}
22179126SWyllys.Ingersoll@Sun.COM 	(void) template_update_attribute(publ_tmpl, attr);
22189126SWyllys.Ingersoll@Sun.COM 
22199126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, rgbBlob);
22209126SWyllys.Ingersoll@Sun.COM 
22219126SWyllys.Ingersoll@Sun.COM 	/* grab the public key to put into the public key object */
22229126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
22239126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &ulBlobLen, &rgbBlob))) {
22249126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetAttribData: 0x%0x - %s",
22259126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
22269126SWyllys.Ingersoll@Sun.COM 		return (result);
22279126SWyllys.Ingersoll@Sun.COM 	}
22289126SWyllys.Ingersoll@Sun.COM 
22299126SWyllys.Ingersoll@Sun.COM 	/* add the public key blob to the object template */
22309126SWyllys.Ingersoll@Sun.COM 	if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) {
22319126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, rgbBlob);
22329126SWyllys.Ingersoll@Sun.COM 		return (rc);
22339126SWyllys.Ingersoll@Sun.COM 	}
22349126SWyllys.Ingersoll@Sun.COM 	(void) template_update_attribute(publ_tmpl, attr);
22359126SWyllys.Ingersoll@Sun.COM 
22369126SWyllys.Ingersoll@Sun.COM 	/* add the public key blob to the object template */
22379126SWyllys.Ingersoll@Sun.COM 	if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) {
22389126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, rgbBlob);
22399126SWyllys.Ingersoll@Sun.COM 		return (rc);
22409126SWyllys.Ingersoll@Sun.COM 	}
22419126SWyllys.Ingersoll@Sun.COM 	(void) template_update_attribute(priv_tmpl, attr);
22429126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, rgbBlob);
22439126SWyllys.Ingersoll@Sun.COM 
22449126SWyllys.Ingersoll@Sun.COM 	/* wrap the authdata and put it into an object */
22459126SWyllys.Ingersoll@Sun.COM 	if (authData != NULL) {
22469126SWyllys.Ingersoll@Sun.COM 		rc = token_wrap_auth_data(hContext, authData, publ_tmpl,
22479126SWyllys.Ingersoll@Sun.COM 		    priv_tmpl);
22489126SWyllys.Ingersoll@Sun.COM 	}
22499126SWyllys.Ingersoll@Sun.COM 
22509126SWyllys.Ingersoll@Sun.COM 	return (rc);
22519126SWyllys.Ingersoll@Sun.COM }
22529126SWyllys.Ingersoll@Sun.COM 
22539126SWyllys.Ingersoll@Sun.COM static CK_RV
token_rsa_load_key(TSS_HCONTEXT hContext,OBJECT * key_obj,TSS_HKEY * phKey)22549126SWyllys.Ingersoll@Sun.COM token_rsa_load_key(
22559126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
22569126SWyllys.Ingersoll@Sun.COM 	OBJECT *key_obj,
22579126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY *phKey)
22589126SWyllys.Ingersoll@Sun.COM {
22599126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
22609126SWyllys.Ingersoll@Sun.COM 	TSS_HPOLICY hPolicy = NULL_HPOLICY;
22619126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hParentKey;
22629126SWyllys.Ingersoll@Sun.COM 	BYTE		*authData = NULL;
22639126SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE	*attr;
22649126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
22659126SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_HANDLE handle;
22669453SWyllys.Ingersoll@Sun.COM 	CK_ULONG	class;
22679126SWyllys.Ingersoll@Sun.COM 
22689126SWyllys.Ingersoll@Sun.COM 	if (hPrivateLeafKey != NULL_HKEY) {
22699126SWyllys.Ingersoll@Sun.COM 		hParentKey = hPrivateRootKey;
22709126SWyllys.Ingersoll@Sun.COM 	} else {
22719126SWyllys.Ingersoll@Sun.COM 		if ((result = token_load_public_root_key(hContext)))
22729126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
22739126SWyllys.Ingersoll@Sun.COM 
22749126SWyllys.Ingersoll@Sun.COM 		hParentKey = hPublicRootKey;
22759126SWyllys.Ingersoll@Sun.COM 	}
22769126SWyllys.Ingersoll@Sun.COM 
22779453SWyllys.Ingersoll@Sun.COM 	*phKey = NULL;
22789453SWyllys.Ingersoll@Sun.COM 	if (template_attribute_find(key_obj->template, CKA_CLASS,
22799453SWyllys.Ingersoll@Sun.COM 	    &attr) == FALSE) {
22809453SWyllys.Ingersoll@Sun.COM 		return (CKR_TEMPLATE_INCOMPLETE);
22819453SWyllys.Ingersoll@Sun.COM 	}
22829453SWyllys.Ingersoll@Sun.COM 	class = *((CK_ULONG *)attr->pValue);
22839453SWyllys.Ingersoll@Sun.COM 
22849453SWyllys.Ingersoll@Sun.COM 	rc = template_attribute_find(key_obj->template,
22859453SWyllys.Ingersoll@Sun.COM 	    CKA_IBM_OPAQUE, &attr);
22869453SWyllys.Ingersoll@Sun.COM 	/*
22879453SWyllys.Ingersoll@Sun.COM 	 * A public key cannot use the OPAQUE data attribute so they
22889453SWyllys.Ingersoll@Sun.COM 	 * must be created in software.  A private key may not yet
22899453SWyllys.Ingersoll@Sun.COM 	 * have its "opaque" data defined and needs to be created
22909453SWyllys.Ingersoll@Sun.COM 	 * and loaded so it can be used inside the TPM.
22919453SWyllys.Ingersoll@Sun.COM 	 */
22929453SWyllys.Ingersoll@Sun.COM 	if (class == CKO_PUBLIC_KEY || rc == FALSE) {
22939126SWyllys.Ingersoll@Sun.COM 		rc = object_mgr_find_in_map2(hContext, key_obj, &handle);
22949126SWyllys.Ingersoll@Sun.COM 		if (rc != CKR_OK)
22959126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
22969126SWyllys.Ingersoll@Sun.COM 
22979126SWyllys.Ingersoll@Sun.COM 		if ((rc = token_load_key(hContext,
22989126SWyllys.Ingersoll@Sun.COM 		    handle, hParentKey, NULL, phKey))) {
22999126SWyllys.Ingersoll@Sun.COM 			return (rc);
23009126SWyllys.Ingersoll@Sun.COM 		}
23019453SWyllys.Ingersoll@Sun.COM 	}
23029453SWyllys.Ingersoll@Sun.COM 	/*
23039453SWyllys.Ingersoll@Sun.COM 	 * If this is a private key, get the blob and load it in the TPM.
23049453SWyllys.Ingersoll@Sun.COM 	 * If it is public, the key is already loaded in software.
23059453SWyllys.Ingersoll@Sun.COM 	 */
23069453SWyllys.Ingersoll@Sun.COM 	if (class == CKO_PRIVATE_KEY) {
23079453SWyllys.Ingersoll@Sun.COM 		/* If we already have a handle, just load it */
23089453SWyllys.Ingersoll@Sun.COM 		if (*phKey != NULL) {
23099453SWyllys.Ingersoll@Sun.COM 			result = Tspi_Key_LoadKey(*phKey, hParentKey);
23109453SWyllys.Ingersoll@Sun.COM 			if (result) {
23119453SWyllys.Ingersoll@Sun.COM 				stlogit("Tspi_Context_LoadKeyByBlob: "
23129453SWyllys.Ingersoll@Sun.COM 				    "0x%0x - %s",
23139453SWyllys.Ingersoll@Sun.COM 				    result, Trspi_Error_String(result));
23149453SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
23159453SWyllys.Ingersoll@Sun.COM 			}
23169453SWyllys.Ingersoll@Sun.COM 		} else {
23179453SWyllys.Ingersoll@Sun.COM 			/* try again to get the CKA_IBM_OPAQUE attr */
23189453SWyllys.Ingersoll@Sun.COM 			if ((rc = template_attribute_find(key_obj->template,
23199453SWyllys.Ingersoll@Sun.COM 			    CKA_IBM_OPAQUE, &attr)) == FALSE) {
23209453SWyllys.Ingersoll@Sun.COM 				return (rc);
23219453SWyllys.Ingersoll@Sun.COM 			}
23229453SWyllys.Ingersoll@Sun.COM 			if ((result = Tspi_Context_LoadKeyByBlob(hContext,
23239453SWyllys.Ingersoll@Sun.COM 			    hParentKey, attr->ulValueLen, attr->pValue,
23249453SWyllys.Ingersoll@Sun.COM 			    phKey))) {
23259453SWyllys.Ingersoll@Sun.COM 				stlogit("Tspi_Context_LoadKeyByBlob: "
23269453SWyllys.Ingersoll@Sun.COM 				    "0x%0x - %s",
23279453SWyllys.Ingersoll@Sun.COM 				    result, Trspi_Error_String(result));
23289453SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
23299453SWyllys.Ingersoll@Sun.COM 			}
23309126SWyllys.Ingersoll@Sun.COM 		}
23319126SWyllys.Ingersoll@Sun.COM 	}
23329126SWyllys.Ingersoll@Sun.COM 
23339126SWyllys.Ingersoll@Sun.COM 	/* auth data may be required */
23349126SWyllys.Ingersoll@Sun.COM 	if (template_attribute_find(key_obj->template, CKA_ENC_AUTHDATA,
23359126SWyllys.Ingersoll@Sun.COM 	    &attr) == TRUE && attr) {
23369126SWyllys.Ingersoll@Sun.COM 		if ((hPrivateLeafKey == NULL_HKEY) &&
23379126SWyllys.Ingersoll@Sun.COM 		    (hPublicLeafKey == NULL_HKEY)) {
23389126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
23399126SWyllys.Ingersoll@Sun.COM 		} else if (hPublicLeafKey != NULL_HKEY) {
23409126SWyllys.Ingersoll@Sun.COM 			hParentKey = hPublicLeafKey;
23419126SWyllys.Ingersoll@Sun.COM 		} else {
23429126SWyllys.Ingersoll@Sun.COM 			hParentKey = hPrivateLeafKey;
23439126SWyllys.Ingersoll@Sun.COM 		}
23449126SWyllys.Ingersoll@Sun.COM 
23459126SWyllys.Ingersoll@Sun.COM 		if ((result = token_unwrap_auth_data(hContext,
23469453SWyllys.Ingersoll@Sun.COM 		    attr->pValue, attr->ulValueLen,
23479453SWyllys.Ingersoll@Sun.COM 		    hParentKey, &authData))) {
23489126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
23499126SWyllys.Ingersoll@Sun.COM 		}
23509126SWyllys.Ingersoll@Sun.COM 
23519126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_GetPolicyObject(*phKey,
23529126SWyllys.Ingersoll@Sun.COM 		    TSS_POLICY_USAGE, &hPolicy))) {
23539126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_GetPolicyObject: 0x%0x - %s",
23549126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
23559126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
23569126SWyllys.Ingersoll@Sun.COM 		}
23579126SWyllys.Ingersoll@Sun.COM 
23589126SWyllys.Ingersoll@Sun.COM 		/*
23599126SWyllys.Ingersoll@Sun.COM 		 * If the policy handle returned is the same as the
23609126SWyllys.Ingersoll@Sun.COM 		 * context's default policy, then a new policy must
23619126SWyllys.Ingersoll@Sun.COM 		 * be created and assigned to the key. Otherwise, just set the
23629126SWyllys.Ingersoll@Sun.COM 		 * secret in the policy.
23639126SWyllys.Ingersoll@Sun.COM 		 */
23649126SWyllys.Ingersoll@Sun.COM 		if (hPolicy == hDefaultPolicy) {
23659126SWyllys.Ingersoll@Sun.COM 			if ((result = Tspi_Context_CreateObject(hContext,
23669126SWyllys.Ingersoll@Sun.COM 			    TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE,
23679126SWyllys.Ingersoll@Sun.COM 			    &hPolicy))) {
23689126SWyllys.Ingersoll@Sun.COM 				stlogit("Tspi_Context_CreateObject: "
23699126SWyllys.Ingersoll@Sun.COM 				    "0x%0x - %s",
23709126SWyllys.Ingersoll@Sun.COM 				    result, Trspi_Error_String(result));
23719126SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
23729126SWyllys.Ingersoll@Sun.COM 			}
23739126SWyllys.Ingersoll@Sun.COM 
23749126SWyllys.Ingersoll@Sun.COM 			if ((result = Tspi_Policy_SetSecret(hPolicy,
23759126SWyllys.Ingersoll@Sun.COM 			    TSS_SECRET_MODE_SHA1,
23769126SWyllys.Ingersoll@Sun.COM 			    SHA1_DIGEST_LENGTH, authData))) {
23779126SWyllys.Ingersoll@Sun.COM 				stlogit("Tspi_Policy_SetSecret: "
23789126SWyllys.Ingersoll@Sun.COM 				    "0x%0x - %s",
23799126SWyllys.Ingersoll@Sun.COM 				    result, Trspi_Error_String(result));
23809126SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
23819126SWyllys.Ingersoll@Sun.COM 			}
23829126SWyllys.Ingersoll@Sun.COM 
23839126SWyllys.Ingersoll@Sun.COM 			if ((result = Tspi_Policy_AssignToObject(hPolicy,
23849126SWyllys.Ingersoll@Sun.COM 			    *phKey))) {
23859126SWyllys.Ingersoll@Sun.COM 				stlogit("Tspi_Policy_AssignToObject: "
23869126SWyllys.Ingersoll@Sun.COM 				    "0x%0x - %s",
23879126SWyllys.Ingersoll@Sun.COM 				    result, Trspi_Error_String(result));
23889126SWyllys.Ingersoll@Sun.COM 				return (CKR_FUNCTION_FAILED);
23899126SWyllys.Ingersoll@Sun.COM 			}
23909126SWyllys.Ingersoll@Sun.COM 		} else if ((result = Tspi_Policy_SetSecret(hPolicy,
23919126SWyllys.Ingersoll@Sun.COM 		    TSS_SECRET_MODE_SHA1, SHA1_DIGEST_LENGTH, authData))) {
23929126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_Policy_SetSecret: 0x%0x - %s",
23939126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
23949126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
23959126SWyllys.Ingersoll@Sun.COM 		}
23969126SWyllys.Ingersoll@Sun.COM 
23979126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, authData);
23989126SWyllys.Ingersoll@Sun.COM 	}
23999126SWyllys.Ingersoll@Sun.COM 
24009126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
24019126SWyllys.Ingersoll@Sun.COM }
24029126SWyllys.Ingersoll@Sun.COM 
24039126SWyllys.Ingersoll@Sun.COM CK_RV
tpm_decrypt_data(TSS_HCONTEXT hContext,TSS_HKEY hKey,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)24049126SWyllys.Ingersoll@Sun.COM tpm_decrypt_data(
24059126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
24069126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY    hKey,
24079126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * in_data,
24089126SWyllys.Ingersoll@Sun.COM 	CK_ULONG    in_data_len,
24099126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * out_data,
24109126SWyllys.Ingersoll@Sun.COM 	CK_ULONG  * out_data_len)
24119126SWyllys.Ingersoll@Sun.COM {
24129126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT result;
24139126SWyllys.Ingersoll@Sun.COM 	TSS_HENCDATA	hEncData = NULL_HENCDATA;
24149126SWyllys.Ingersoll@Sun.COM 	UINT32		buf_size = 0, modLen;
24159126SWyllys.Ingersoll@Sun.COM 	BYTE		*buf = NULL, *modulus = NULL;
24169126SWyllys.Ingersoll@Sun.COM 	CK_ULONG	chunklen, remain, outlen;
24179126SWyllys.Ingersoll@Sun.COM 
24189126SWyllys.Ingersoll@Sun.COM 	/* push the data into the encrypted data object */
24199126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
24209126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
24219126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
24229126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
24239126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
24249126SWyllys.Ingersoll@Sun.COM 	}
24259126SWyllys.Ingersoll@Sun.COM 
24269126SWyllys.Ingersoll@Sun.COM 	/*
24279126SWyllys.Ingersoll@Sun.COM 	 * Figure out the modulus size so we can break the data
24289126SWyllys.Ingersoll@Sun.COM 	 * into smaller chunks if necessary.
24299126SWyllys.Ingersoll@Sun.COM 	 */
24309126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
24319126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
24329126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetAttribData: 0x%0x - %s",
24339126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
24349126SWyllys.Ingersoll@Sun.COM 		return (result);
24359126SWyllys.Ingersoll@Sun.COM 	}
24369126SWyllys.Ingersoll@Sun.COM 	/* we don't need the actual modulus */
24379126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, modulus);
24389126SWyllys.Ingersoll@Sun.COM 
24399126SWyllys.Ingersoll@Sun.COM 	chunklen = (in_data_len > modLen ? modLen : in_data_len);
24409126SWyllys.Ingersoll@Sun.COM 	remain = in_data_len;
24419126SWyllys.Ingersoll@Sun.COM 	outlen = 0;
24429126SWyllys.Ingersoll@Sun.COM 
24439126SWyllys.Ingersoll@Sun.COM 	while (remain > 0) {
24449126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_SetAttribData(hEncData,
24459126SWyllys.Ingersoll@Sun.COM 		    TSS_TSPATTRIB_ENCDATA_BLOB,
24469126SWyllys.Ingersoll@Sun.COM 		    TSS_TSPATTRIB_ENCDATABLOB_BLOB,
24479126SWyllys.Ingersoll@Sun.COM 		    chunklen, in_data))) {
24489126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_SetAttribData: 0x%0x - %s",
24499126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
24509126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
24519126SWyllys.Ingersoll@Sun.COM 		}
24529126SWyllys.Ingersoll@Sun.COM 
24539126SWyllys.Ingersoll@Sun.COM 		/* unbind the data, receiving the plaintext back */
24549126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_Data_Unbind(hEncData, hKey,
24559126SWyllys.Ingersoll@Sun.COM 		    &buf_size, &buf))) {
24569126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_Data_Unbind: 0x%0x - %s",
24579126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
24589126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
24599126SWyllys.Ingersoll@Sun.COM 		}
24609126SWyllys.Ingersoll@Sun.COM 
24619126SWyllys.Ingersoll@Sun.COM 		if (*out_data_len < buf_size + outlen) {
24629126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_FreeMemory(hContext, buf);
24639126SWyllys.Ingersoll@Sun.COM 			return (CKR_BUFFER_TOO_SMALL);
24649126SWyllys.Ingersoll@Sun.COM 		}
24659126SWyllys.Ingersoll@Sun.COM 
24669126SWyllys.Ingersoll@Sun.COM 		(void) memcpy(out_data + outlen, buf, buf_size);
24679126SWyllys.Ingersoll@Sun.COM 
24689126SWyllys.Ingersoll@Sun.COM 		outlen += buf_size;
24699126SWyllys.Ingersoll@Sun.COM 		in_data += chunklen;
24709126SWyllys.Ingersoll@Sun.COM 		remain -= chunklen;
24719126SWyllys.Ingersoll@Sun.COM 
24729126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, buf);
24739126SWyllys.Ingersoll@Sun.COM 		if (chunklen > remain)
24749126SWyllys.Ingersoll@Sun.COM 			chunklen = remain;
24759126SWyllys.Ingersoll@Sun.COM 	}
24769126SWyllys.Ingersoll@Sun.COM 	*out_data_len = outlen;
24779126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
24789126SWyllys.Ingersoll@Sun.COM }
24799126SWyllys.Ingersoll@Sun.COM 
24809126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_rsa_decrypt(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)24819126SWyllys.Ingersoll@Sun.COM token_specific_rsa_decrypt(
24829126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
24839126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * in_data,
24849126SWyllys.Ingersoll@Sun.COM 	CK_ULONG    in_data_len,
24859126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * out_data,
24869126SWyllys.Ingersoll@Sun.COM 	CK_ULONG  * out_data_len,
24879126SWyllys.Ingersoll@Sun.COM 	OBJECT	  * key_obj)
24889126SWyllys.Ingersoll@Sun.COM {
24899126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
24909126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hKey;
24919126SWyllys.Ingersoll@Sun.COM 
24929126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
24939126SWyllys.Ingersoll@Sun.COM 		return (rc);
24949126SWyllys.Ingersoll@Sun.COM 	}
24959126SWyllys.Ingersoll@Sun.COM 
24969126SWyllys.Ingersoll@Sun.COM 	rc = tpm_decrypt_data(hContext, hKey, in_data, in_data_len,
24979126SWyllys.Ingersoll@Sun.COM 	    out_data, out_data_len);
24989126SWyllys.Ingersoll@Sun.COM 
24999126SWyllys.Ingersoll@Sun.COM 	return (rc);
25009126SWyllys.Ingersoll@Sun.COM }
25019126SWyllys.Ingersoll@Sun.COM 
25029126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_rsa_verify(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * sig,CK_ULONG sig_len,OBJECT * key_obj)25039126SWyllys.Ingersoll@Sun.COM token_specific_rsa_verify(
25049126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
25059126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * in_data,
25069126SWyllys.Ingersoll@Sun.COM 	CK_ULONG    in_data_len,
25079126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * sig,
25089126SWyllys.Ingersoll@Sun.COM 	CK_ULONG    sig_len,
25099126SWyllys.Ingersoll@Sun.COM 	OBJECT	  * key_obj)
25109126SWyllys.Ingersoll@Sun.COM {
25119126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
25129126SWyllys.Ingersoll@Sun.COM 	TSS_HHASH	hHash;
25139126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hKey;
25149126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
25159126SWyllys.Ingersoll@Sun.COM 
25169126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
25179126SWyllys.Ingersoll@Sun.COM 		return (rc);
25189126SWyllys.Ingersoll@Sun.COM 	}
25199126SWyllys.Ingersoll@Sun.COM 
25209126SWyllys.Ingersoll@Sun.COM 	/* Create the hash object we'll use to sign */
25219126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
25229126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) {
25239126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
25249126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
25259126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
25269126SWyllys.Ingersoll@Sun.COM 	}
25279126SWyllys.Ingersoll@Sun.COM 
25289126SWyllys.Ingersoll@Sun.COM 	/* Insert the data into the hash object */
25299126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len,
25309126SWyllys.Ingersoll@Sun.COM 	    in_data))) {
25319126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s",
25329126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
25339126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
25349126SWyllys.Ingersoll@Sun.COM 	}
25359126SWyllys.Ingersoll@Sun.COM 
25369126SWyllys.Ingersoll@Sun.COM 	/* Verify */
25379126SWyllys.Ingersoll@Sun.COM 	result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig);
25389126SWyllys.Ingersoll@Sun.COM 	if (result != TSS_SUCCESS &&
25399126SWyllys.Ingersoll@Sun.COM 	    TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) {
25409126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Hash_VerifySignature: 0x%0x - %s",
25419126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
25429126SWyllys.Ingersoll@Sun.COM 	}
25439126SWyllys.Ingersoll@Sun.COM 
25449126SWyllys.Ingersoll@Sun.COM 	if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) {
25459126SWyllys.Ingersoll@Sun.COM 		rc = CKR_SIGNATURE_INVALID;
25469126SWyllys.Ingersoll@Sun.COM 	} else {
25479126SWyllys.Ingersoll@Sun.COM 		rc = CKR_OK;
25489126SWyllys.Ingersoll@Sun.COM 	}
25499126SWyllys.Ingersoll@Sun.COM 
25509126SWyllys.Ingersoll@Sun.COM 	return (rc);
25519126SWyllys.Ingersoll@Sun.COM }
25529126SWyllys.Ingersoll@Sun.COM 
25539126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_rsa_sign(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)25549126SWyllys.Ingersoll@Sun.COM token_specific_rsa_sign(
25559126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
25569126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * in_data,
25579126SWyllys.Ingersoll@Sun.COM 	CK_ULONG    in_data_len,
25589126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * out_data,
25599126SWyllys.Ingersoll@Sun.COM 	CK_ULONG  * out_data_len,
25609126SWyllys.Ingersoll@Sun.COM 	OBJECT	  * key_obj)
25619126SWyllys.Ingersoll@Sun.COM {
25629126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
25639126SWyllys.Ingersoll@Sun.COM 	TSS_HHASH	hHash;
25649126SWyllys.Ingersoll@Sun.COM 	BYTE		*sig;
25659126SWyllys.Ingersoll@Sun.COM 	UINT32		sig_len;
25669126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hKey;
25679126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
25689126SWyllys.Ingersoll@Sun.COM 
25699126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
25709126SWyllys.Ingersoll@Sun.COM 		return (rc);
25719126SWyllys.Ingersoll@Sun.COM 	}
25729126SWyllys.Ingersoll@Sun.COM 
25739126SWyllys.Ingersoll@Sun.COM 	/* Create the hash object we'll use to sign */
25749126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
25759126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) {
25769126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
25779126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
25789126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
25799126SWyllys.Ingersoll@Sun.COM 	}
25809126SWyllys.Ingersoll@Sun.COM 
25819126SWyllys.Ingersoll@Sun.COM 	/* Insert the data into the hash object */
25829126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len,
25839126SWyllys.Ingersoll@Sun.COM 	    in_data))) {
25849126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Hash_SetHashValue: 0x%0x - %s",
25859126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
25869126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
25879126SWyllys.Ingersoll@Sun.COM 	}
25889126SWyllys.Ingersoll@Sun.COM 
25899126SWyllys.Ingersoll@Sun.COM 	/* Sign */
25909126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig))) {
25919126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Hash_Sign: 0x%0x - %s",
25929126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
25939453SWyllys.Ingersoll@Sun.COM 		return (CKR_DATA_LEN_RANGE);
25949126SWyllys.Ingersoll@Sun.COM 	}
25959126SWyllys.Ingersoll@Sun.COM 
25969126SWyllys.Ingersoll@Sun.COM 	if (sig_len > *out_data_len) {
25979126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, sig);
25989126SWyllys.Ingersoll@Sun.COM 		return (CKR_BUFFER_TOO_SMALL);
25999126SWyllys.Ingersoll@Sun.COM 	}
26009126SWyllys.Ingersoll@Sun.COM 
26019126SWyllys.Ingersoll@Sun.COM 	(void) memcpy(out_data, sig, sig_len);
26029126SWyllys.Ingersoll@Sun.COM 	*out_data_len = sig_len;
26039126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, sig);
26049126SWyllys.Ingersoll@Sun.COM 
26059126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
26069126SWyllys.Ingersoll@Sun.COM }
26079126SWyllys.Ingersoll@Sun.COM 
26089126SWyllys.Ingersoll@Sun.COM CK_RV
tpm_encrypt_data(TSS_HCONTEXT hContext,TSS_HKEY hKey,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)26099126SWyllys.Ingersoll@Sun.COM tpm_encrypt_data(
26109126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
26119126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY hKey,
26129126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *in_data,
26139126SWyllys.Ingersoll@Sun.COM 	CK_ULONG in_data_len,
26149126SWyllys.Ingersoll@Sun.COM 	CK_BYTE *out_data,
26159126SWyllys.Ingersoll@Sun.COM 	CK_ULONG *out_data_len)
26169126SWyllys.Ingersoll@Sun.COM {
26179126SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
26189126SWyllys.Ingersoll@Sun.COM 	TSS_HENCDATA	hEncData;
26199126SWyllys.Ingersoll@Sun.COM 	BYTE		*dataBlob, *modulus;
26209126SWyllys.Ingersoll@Sun.COM 	UINT32		dataBlobSize, modLen;
26219126SWyllys.Ingersoll@Sun.COM 	CK_ULONG	chunklen, remain;
26229126SWyllys.Ingersoll@Sun.COM 	CK_ULONG	outlen;
26239453SWyllys.Ingersoll@Sun.COM 	UINT32		keyusage, scheme, maxsize;
26249126SWyllys.Ingersoll@Sun.COM 
26259126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_Context_CreateObject(hContext,
26269126SWyllys.Ingersoll@Sun.COM 	    TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) {
26279126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_Context_CreateObject: 0x%0x - %s",
26289126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
26299126SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
26309126SWyllys.Ingersoll@Sun.COM 	}
26319126SWyllys.Ingersoll@Sun.COM 	/*
26329126SWyllys.Ingersoll@Sun.COM 	 * Figure out the modulus size so we can break the data
26339126SWyllys.Ingersoll@Sun.COM 	 * into smaller chunks if necessary.
26349126SWyllys.Ingersoll@Sun.COM 	 */
26359126SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
26369126SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
26379126SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetAttribData: 0x%0x - %s",
26389126SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
26399126SWyllys.Ingersoll@Sun.COM 		return (result);
26409126SWyllys.Ingersoll@Sun.COM 	}
26419126SWyllys.Ingersoll@Sun.COM 	/* we don't need the actual modulus */
26429126SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, modulus);
26439126SWyllys.Ingersoll@Sun.COM 
26449126SWyllys.Ingersoll@Sun.COM 	/*
26459126SWyllys.Ingersoll@Sun.COM 	 * According to TSS spec for Tspi_Data_Bind (4.3.4.21.5),
26469453SWyllys.Ingersoll@Sun.COM 	 * Max input data size varies depending on the key type and
26479453SWyllys.Ingersoll@Sun.COM 	 * encryption scheme.
26489126SWyllys.Ingersoll@Sun.COM 	 */
26499453SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
26509453SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_USAGE, &keyusage))) {
26519453SWyllys.Ingersoll@Sun.COM 		stlogit("Cannot find USAGE: %s\n",
26529453SWyllys.Ingersoll@Sun.COM 		    Trspi_Error_String(result));
26539453SWyllys.Ingersoll@Sun.COM 		return (result);
26549453SWyllys.Ingersoll@Sun.COM 	}
26559453SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
26569453SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_ENCSCHEME, &scheme))) {
26579453SWyllys.Ingersoll@Sun.COM 		stlogit("Cannot find ENCSCHEME: %s\n",
26589453SWyllys.Ingersoll@Sun.COM 		    Trspi_Error_String(result));
26599453SWyllys.Ingersoll@Sun.COM 		return (result);
26609453SWyllys.Ingersoll@Sun.COM 	}
26619453SWyllys.Ingersoll@Sun.COM 	switch (scheme) {
26629453SWyllys.Ingersoll@Sun.COM 		case TSS_ES_RSAESPKCSV15:
26639453SWyllys.Ingersoll@Sun.COM 			if (keyusage == TSS_KEYUSAGE_BIND)
26649453SWyllys.Ingersoll@Sun.COM 				maxsize = 16;
26659453SWyllys.Ingersoll@Sun.COM 			else /* legacy */
26669453SWyllys.Ingersoll@Sun.COM 				maxsize = 11;
26679453SWyllys.Ingersoll@Sun.COM 			break;
26689453SWyllys.Ingersoll@Sun.COM 		case TSS_ES_RSAESOAEP_SHA1_MGF1:
26699453SWyllys.Ingersoll@Sun.COM 			maxsize = 47;
26709453SWyllys.Ingersoll@Sun.COM 			break;
26719453SWyllys.Ingersoll@Sun.COM 		default:
26729453SWyllys.Ingersoll@Sun.COM 			maxsize = 0;
26739453SWyllys.Ingersoll@Sun.COM 	}
26749453SWyllys.Ingersoll@Sun.COM 
26759453SWyllys.Ingersoll@Sun.COM 	modLen -= maxsize;
26769126SWyllys.Ingersoll@Sun.COM 
26779126SWyllys.Ingersoll@Sun.COM 	chunklen = (in_data_len > modLen ? modLen : in_data_len);
26789126SWyllys.Ingersoll@Sun.COM 	remain = in_data_len;
26799126SWyllys.Ingersoll@Sun.COM 	outlen = 0;
26809126SWyllys.Ingersoll@Sun.COM 	while (remain > 0) {
26819126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_Data_Bind(hEncData, hKey,
26829126SWyllys.Ingersoll@Sun.COM 		    chunklen, in_data))) {
26839126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_Data_Bind: 0x%0x - %s",
26849126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
26859126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
26869126SWyllys.Ingersoll@Sun.COM 		}
26879126SWyllys.Ingersoll@Sun.COM 
26889126SWyllys.Ingersoll@Sun.COM 		if ((result = Tspi_GetAttribData(hEncData,
26899126SWyllys.Ingersoll@Sun.COM 		    TSS_TSPATTRIB_ENCDATA_BLOB,
26909126SWyllys.Ingersoll@Sun.COM 		    TSS_TSPATTRIB_ENCDATABLOB_BLOB,
26919126SWyllys.Ingersoll@Sun.COM 		    &dataBlobSize, &dataBlob))) {
26929126SWyllys.Ingersoll@Sun.COM 			stlogit("Tspi_GetAttribData: 0x%0x - %s",
26939126SWyllys.Ingersoll@Sun.COM 			    result, Trspi_Error_String(result));
26949126SWyllys.Ingersoll@Sun.COM 			return (CKR_FUNCTION_FAILED);
26959126SWyllys.Ingersoll@Sun.COM 		}
26969126SWyllys.Ingersoll@Sun.COM 
26979126SWyllys.Ingersoll@Sun.COM 		if (outlen + dataBlobSize > *out_data_len) {
26989126SWyllys.Ingersoll@Sun.COM 			Tspi_Context_FreeMemory(hContext, dataBlob);
26999126SWyllys.Ingersoll@Sun.COM 			return (CKR_DATA_LEN_RANGE);
27009126SWyllys.Ingersoll@Sun.COM 		}
27019126SWyllys.Ingersoll@Sun.COM 
27029126SWyllys.Ingersoll@Sun.COM 		(void) memcpy(out_data + outlen,
27039126SWyllys.Ingersoll@Sun.COM 		    dataBlob, dataBlobSize);
27049126SWyllys.Ingersoll@Sun.COM 
27059126SWyllys.Ingersoll@Sun.COM 		outlen += dataBlobSize;
27069126SWyllys.Ingersoll@Sun.COM 		in_data += chunklen;
27079126SWyllys.Ingersoll@Sun.COM 		remain -= chunklen;
27089126SWyllys.Ingersoll@Sun.COM 
27099126SWyllys.Ingersoll@Sun.COM 		if (chunklen > remain)
27109126SWyllys.Ingersoll@Sun.COM 			chunklen = remain;
27119126SWyllys.Ingersoll@Sun.COM 
27129126SWyllys.Ingersoll@Sun.COM 		Tspi_Context_FreeMemory(hContext, dataBlob);
27139126SWyllys.Ingersoll@Sun.COM 	}
27149126SWyllys.Ingersoll@Sun.COM 	*out_data_len = outlen;
27159126SWyllys.Ingersoll@Sun.COM 
27169126SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
27179126SWyllys.Ingersoll@Sun.COM }
27189126SWyllys.Ingersoll@Sun.COM 
27199126SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_rsa_encrypt(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)27209126SWyllys.Ingersoll@Sun.COM token_specific_rsa_encrypt(
27219126SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT hContext,
27229126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * in_data,
27239126SWyllys.Ingersoll@Sun.COM 	CK_ULONG    in_data_len,
27249126SWyllys.Ingersoll@Sun.COM 	CK_BYTE   * out_data,
27259126SWyllys.Ingersoll@Sun.COM 	CK_ULONG  * out_data_len,
27269126SWyllys.Ingersoll@Sun.COM 	OBJECT	  * key_obj)
27279126SWyllys.Ingersoll@Sun.COM {
27289126SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hKey;
27299126SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
27309126SWyllys.Ingersoll@Sun.COM 
27319126SWyllys.Ingersoll@Sun.COM 	if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
27329126SWyllys.Ingersoll@Sun.COM 		return (rc);
27339126SWyllys.Ingersoll@Sun.COM 	}
27349126SWyllys.Ingersoll@Sun.COM 
27359126SWyllys.Ingersoll@Sun.COM 	rc  = tpm_encrypt_data(hContext, hKey, in_data, in_data_len,
27369126SWyllys.Ingersoll@Sun.COM 	    out_data, out_data_len);
27379126SWyllys.Ingersoll@Sun.COM 
27389126SWyllys.Ingersoll@Sun.COM 	return (rc);
27399126SWyllys.Ingersoll@Sun.COM }
27409453SWyllys.Ingersoll@Sun.COM 
27419453SWyllys.Ingersoll@Sun.COM /*
27429453SWyllys.Ingersoll@Sun.COM  * RSA Verify Recover
27439453SWyllys.Ingersoll@Sun.COM  *
27449453SWyllys.Ingersoll@Sun.COM  * Public key crypto is done in software, not by the TPM.
27459453SWyllys.Ingersoll@Sun.COM  * We bypass the TSPI library here in favor of calls directly
27469453SWyllys.Ingersoll@Sun.COM  * to OpenSSL because we don't want to add any padding, the in_data (signature)
27479453SWyllys.Ingersoll@Sun.COM  * already contains the data stream to be decrypted and is already
27489453SWyllys.Ingersoll@Sun.COM  * padded and formatted correctly.
27499453SWyllys.Ingersoll@Sun.COM  */
27509453SWyllys.Ingersoll@Sun.COM CK_RV
token_specific_rsa_verify_recover(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)27519453SWyllys.Ingersoll@Sun.COM token_specific_rsa_verify_recover(
27529453SWyllys.Ingersoll@Sun.COM 	TSS_HCONTEXT	hContext,
27539453SWyllys.Ingersoll@Sun.COM 	CK_BYTE		*in_data,	/* signature */
27549453SWyllys.Ingersoll@Sun.COM 	CK_ULONG	in_data_len,
27559453SWyllys.Ingersoll@Sun.COM 	CK_BYTE		*out_data,	/* decrypted */
27569453SWyllys.Ingersoll@Sun.COM 	CK_ULONG	*out_data_len,
27579453SWyllys.Ingersoll@Sun.COM 	OBJECT		*key_obj)
27589453SWyllys.Ingersoll@Sun.COM {
27599453SWyllys.Ingersoll@Sun.COM 	TSS_HKEY	hKey;
27609453SWyllys.Ingersoll@Sun.COM 	TSS_RESULT	result;
27619453SWyllys.Ingersoll@Sun.COM 	CK_RV		rc;
27629453SWyllys.Ingersoll@Sun.COM 	BYTE		*modulus;
27639453SWyllys.Ingersoll@Sun.COM 	UINT32		modLen;
27649453SWyllys.Ingersoll@Sun.COM 	RSA		*rsa = NULL;
27659453SWyllys.Ingersoll@Sun.COM 	uchar_t		exp[] = { 0x01, 0x00, 0x01 };
27669453SWyllys.Ingersoll@Sun.COM 	int		sslrv, num;
27679453SWyllys.Ingersoll@Sun.COM 	BYTE		temp[MAX_RSA_KEYLENGTH];
276810134Swyllys.ingersoll@sun.com 	BYTE		outdata[MAX_RSA_KEYLENGTH];
27699453SWyllys.Ingersoll@Sun.COM 	int		i;
27709453SWyllys.Ingersoll@Sun.COM 
27719453SWyllys.Ingersoll@Sun.COM 	if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
27729453SWyllys.Ingersoll@Sun.COM 		return (rc);
27739453SWyllys.Ingersoll@Sun.COM 	}
27749453SWyllys.Ingersoll@Sun.COM 
27759453SWyllys.Ingersoll@Sun.COM 	if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
27769453SWyllys.Ingersoll@Sun.COM 	    TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
27779453SWyllys.Ingersoll@Sun.COM 		stlogit("Tspi_GetAttribData: 0x%0x - %s",
27789453SWyllys.Ingersoll@Sun.COM 		    result, Trspi_Error_String(result));
27799453SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
27809453SWyllys.Ingersoll@Sun.COM 	}
27819453SWyllys.Ingersoll@Sun.COM 
27829453SWyllys.Ingersoll@Sun.COM 	if (in_data_len != modLen) {
27839453SWyllys.Ingersoll@Sun.COM 		rc = CKR_SIGNATURE_LEN_RANGE;
27849453SWyllys.Ingersoll@Sun.COM 		goto end;
27859453SWyllys.Ingersoll@Sun.COM 	}
27869453SWyllys.Ingersoll@Sun.COM 
27879453SWyllys.Ingersoll@Sun.COM 	rsa = RSA_new();
27889453SWyllys.Ingersoll@Sun.COM 	if (rsa == NULL) {
27899453SWyllys.Ingersoll@Sun.COM 		rc = CKR_HOST_MEMORY;
27909453SWyllys.Ingersoll@Sun.COM 		goto end;
27919453SWyllys.Ingersoll@Sun.COM 	}
27929453SWyllys.Ingersoll@Sun.COM 
27939453SWyllys.Ingersoll@Sun.COM 	rsa->n = BN_bin2bn(modulus, modLen, rsa->n);
27949453SWyllys.Ingersoll@Sun.COM 	rsa->e = BN_bin2bn(exp, sizeof (exp), rsa->e);
27959453SWyllys.Ingersoll@Sun.COM 	if (rsa->n == NULL || rsa->e == NULL) {
27969453SWyllys.Ingersoll@Sun.COM 		rc = CKR_HOST_MEMORY;
27979453SWyllys.Ingersoll@Sun.COM 		goto end;
27989453SWyllys.Ingersoll@Sun.COM 	}
27999453SWyllys.Ingersoll@Sun.COM 
280010134Swyllys.ingersoll@sun.com 	rsa->flags |= RSA_FLAG_SIGN_VER;
280110134Swyllys.ingersoll@sun.com 
28029453SWyllys.Ingersoll@Sun.COM 	/* use RSA_NO_PADDING because the data is already padded (PKCS1) */
280310134Swyllys.ingersoll@sun.com 	sslrv = RSA_public_encrypt(in_data_len, in_data, outdata,
28049453SWyllys.Ingersoll@Sun.COM 	    rsa, RSA_NO_PADDING);
28059453SWyllys.Ingersoll@Sun.COM 	if (sslrv == -1) {
28069453SWyllys.Ingersoll@Sun.COM 		rc = CKR_FUNCTION_FAILED;
28079453SWyllys.Ingersoll@Sun.COM 		goto end;
28089453SWyllys.Ingersoll@Sun.COM 	}
28099453SWyllys.Ingersoll@Sun.COM 
28109453SWyllys.Ingersoll@Sun.COM 	/* Strip leading 0's before stripping the padding */
28119453SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < sslrv; i++)
281210134Swyllys.ingersoll@sun.com 		if (outdata[i] != 0)
28139453SWyllys.Ingersoll@Sun.COM 			break;
28149453SWyllys.Ingersoll@Sun.COM 
28159453SWyllys.Ingersoll@Sun.COM 	num = BN_num_bytes(rsa->n);
28169453SWyllys.Ingersoll@Sun.COM 
28179453SWyllys.Ingersoll@Sun.COM 	/* Use OpenSSL function for stripping PKCS#1 padding */
28189453SWyllys.Ingersoll@Sun.COM 	sslrv = RSA_padding_check_PKCS1_type_1(temp, sizeof (temp),
281910134Swyllys.ingersoll@sun.com 	    &outdata[i], sslrv - i, num);
28209453SWyllys.Ingersoll@Sun.COM 
28219453SWyllys.Ingersoll@Sun.COM 	if (sslrv < 0) {
28229453SWyllys.Ingersoll@Sun.COM 		rc = CKR_FUNCTION_FAILED;
28239453SWyllys.Ingersoll@Sun.COM 		goto end;
28249453SWyllys.Ingersoll@Sun.COM 	}
28259453SWyllys.Ingersoll@Sun.COM 
28269453SWyllys.Ingersoll@Sun.COM 	if (*out_data_len < sslrv) {
28279453SWyllys.Ingersoll@Sun.COM 		rc = CKR_BUFFER_TOO_SMALL;
28289453SWyllys.Ingersoll@Sun.COM 		*out_data_len = 0;
28299453SWyllys.Ingersoll@Sun.COM 		goto end;
28309453SWyllys.Ingersoll@Sun.COM 	}
28319453SWyllys.Ingersoll@Sun.COM 
28329453SWyllys.Ingersoll@Sun.COM 	/* The return code indicates the number of bytes remaining */
28339453SWyllys.Ingersoll@Sun.COM 	(void) memcpy(out_data, temp, sslrv);
28349453SWyllys.Ingersoll@Sun.COM 	*out_data_len = sslrv;
28359453SWyllys.Ingersoll@Sun.COM end:
28369453SWyllys.Ingersoll@Sun.COM 	Tspi_Context_FreeMemory(hContext, modulus);
28379453SWyllys.Ingersoll@Sun.COM 	if (rsa)
28389453SWyllys.Ingersoll@Sun.COM 		RSA_free(rsa);
28399453SWyllys.Ingersoll@Sun.COM 
28409453SWyllys.Ingersoll@Sun.COM 	return (rc);
28419453SWyllys.Ingersoll@Sun.COM }
2842