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