obj_rsakey.c revision 1.1.1.2
1
2/*
3 * Licensed Materials - Property of IBM
4 *
5 * trousers - An open source TCG Software Stack
6 *
7 * (C) Copyright International Business Machines Corp. 2005, 2007
8 *
9 */
10
11
12#include <stdlib.h>
13#include <stdio.h>
14#include <errno.h>
15#include <string.h>
16#include <inttypes.h>
17
18#include "trousers/tss.h"
19#include "trousers/trousers.h"
20#include "trousers_types.h"
21#include "spi_utils.h"
22#include "capabilities.h"
23#include "tsplog.h"
24#include "obj.h"
25
26TSS_RESULT
27obj_rsakey_add(TSS_HCONTEXT tspContext, TSS_FLAG initFlags, TSS_HOBJECT *phObject)
28{
29	UINT64 offset;
30	TSS_RESULT result;
31	TCPA_RSA_KEY_PARMS rsaKeyParms;
32	TSS_FLAG flags = 0;
33	struct tr_rsakey_obj *rsakey = calloc(1, sizeof(struct tr_rsakey_obj));
34	TPM_STRUCT_VER ver = { 1, 1, 0, 0 };  // Must be 1.1.0.0 for 1.2 TPMs
35	UINT32 ctx_ver;
36
37	if (rsakey == NULL) {
38		LogError("malloc of %zd bytes failed.", sizeof(struct tr_rsakey_obj));
39		return TSPERR(TSS_E_OUTOFMEMORY);
40	}
41
42	if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, &rsakey->usagePolicy))) {
43		free(rsakey);
44		return result;
45	}
46
47	if ((initFlags & TSS_KEY_STRUCT_BITMASK) == TSS_KEY_STRUCT_DEFAULT) {
48		/* Its not set, go with the context's default */
49		if ((result = obj_context_get_connection_version(tspContext, &ctx_ver))) {
50			free(rsakey);
51			return result;
52		}
53
54		switch (ctx_ver) {
55			case TSS_TSPATTRIB_CONTEXT_VERSION_V1_2:
56				initFlags |= TSS_KEY_STRUCT_KEY12;
57				break;
58			case TSS_TSPATTRIB_CONTEXT_VERSION_V1_1:
59				/* fall through */
60			default:
61				initFlags |= TSS_KEY_STRUCT_KEY;
62				break;
63		}
64	}
65
66	offset = 0;
67	switch (initFlags & TSS_KEY_STRUCT_BITMASK) {
68		case TSS_KEY_STRUCT_KEY:
69			rsakey->key.hdr.key11.ver = ver;
70			rsakey->type = TSS_KEY_STRUCT_KEY;
71			rsakey->pcrInfoType = TSS_PCRS_STRUCT_INFO;
72			rsakey->key.keyFlags = 0;
73			break;
74		case TSS_KEY_STRUCT_KEY12:
75			rsakey->key.hdr.key12.tag = TPM_TAG_KEY12;
76			rsakey->key.hdr.key12.fill = 0;
77			rsakey->type = TSS_KEY_STRUCT_KEY12;
78			rsakey->pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG;
79			rsakey->key.keyFlags = TPM_PCRIGNOREDONREAD;
80			break;
81		default:
82			free(rsakey);
83			return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG);
84			break;
85	}
86
87	if (initFlags == TSS_KEY_EMPTY_KEY)
88		goto add_key;
89
90	__tspi_memset(&rsaKeyParms, 0, sizeof(TCPA_RSA_KEY_PARMS));
91
92	rsakey->key.algorithmParms.algorithmID = TCPA_ALG_RSA;
93	rsakey->key.algorithmParms.parmSize = sizeof(TCPA_RSA_KEY_PARMS);
94
95	rsakey->key.algorithmParms.parms = calloc(1, sizeof(TCPA_RSA_KEY_PARMS));
96	if (rsakey->key.algorithmParms.parms == NULL) {
97		LogError("calloc of %u bytes failed.", rsakey->key.algorithmParms.parmSize);
98		free(rsakey);
99		return TSPERR(TSS_E_OUTOFMEMORY);
100	}
101	rsaKeyParms.exponentSize = 0;
102	rsaKeyParms.numPrimes = 2;
103
104	rsakey->key.pubKey.keyLength = 0;
105	rsakey->key.encSize = 0;
106	rsakey->key.PCRInfoSize = 0;
107
108	/* End of all the default stuff */
109
110	if (initFlags & TSS_KEY_VOLATILE)
111		rsakey->key.keyFlags |= TPM_VOLATILE;
112	if (initFlags & TSS_KEY_MIGRATABLE)
113		rsakey->key.keyFlags |= TPM_MIGRATABLE;
114	if (initFlags & TSS_KEY_AUTHORIZATION) {
115		rsakey->key.authDataUsage = TPM_AUTH_ALWAYS;
116		flags |= TSS_OBJ_FLAG_USAGEAUTH;
117	}
118
119#ifdef TSS_BUILD_CMK
120	if (initFlags & TSS_KEY_CERTIFIED_MIGRATABLE) {
121		if (rsakey->type == TSS_KEY_STRUCT_KEY) {
122			free(rsakey);
123			return TSPERR(TSS_E_BAD_PARAMETER);
124		}
125		rsakey->key.keyFlags |= TPM_MIGRATEAUTHORITY;
126	}
127#endif
128
129	/* set the key length */
130	if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_512) {
131		rsaKeyParms.keyLength = 512;
132	} else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_1024) {
133		rsaKeyParms.keyLength = 1024;
134	} else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_2048) {
135		rsaKeyParms.keyLength = 2048;
136	} else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_4096) {
137		rsaKeyParms.keyLength = 4096;
138	} else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_8192) {
139		rsaKeyParms.keyLength = 8192;
140	} else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_16384) {
141		rsaKeyParms.keyLength = 16384;
142	}
143
144	/* assign encryption and signature schemes */
145	if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_SIGNING) {
146		rsakey->key.keyUsage = TPM_KEY_SIGNING;
147		rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE;
148		rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
149	} else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_BIND) {
150		rsakey->key.keyUsage = TPM_KEY_BIND;
151		rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
152		rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
153	} else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_LEGACY) {
154		rsakey->key.keyUsage = TPM_KEY_LEGACY;
155		rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
156		rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
157	} else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_STORAGE) {
158		rsakey->key.keyUsage = TPM_KEY_STORAGE;
159		rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
160		rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
161	} else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_IDENTITY) {
162		rsakey->key.keyUsage = TPM_KEY_IDENTITY;
163		rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE;
164		rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
165	} else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_AUTHCHANGE) {
166		rsakey->key.keyUsage = TPM_KEY_AUTHCHANGE;
167		rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
168		rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
169	}
170
171	/* Load the RSA key parms into the blob in the TCPA_KEY_PARMS pointer.
172	 * If the exponent is left NULL, the parmSize variable will change
173	 * here */
174	offset = 0;
175	Trspi_LoadBlob_RSA_KEY_PARMS(&offset, rsakey->key.algorithmParms.parms, &rsaKeyParms);
176	rsakey->key.algorithmParms.parmSize = offset;
177
178add_key:
179	if ((result = obj_list_add(&rsakey_list, tspContext, flags, rsakey, phObject))) {
180		free(rsakey->key.algorithmParms.parms);
181		free(rsakey);
182		return result;
183	}
184
185	return TSS_SUCCESS;
186}
187
188/* Add a new rsakey to the list when its pulled from user PS */
189TSS_RESULT
190obj_rsakey_add_by_key(TSS_HCONTEXT tspContext, TSS_UUID *uuid, BYTE *key, TSS_FLAG flags,
191		      TSS_HKEY *phKey)
192{
193	TSS_RESULT result;
194	UINT64 offset;
195	struct tr_rsakey_obj *rsakey = calloc(1, sizeof(struct tr_rsakey_obj));
196
197	if (rsakey == NULL) {
198		LogError("malloc of %zd bytes failed.", sizeof(struct tr_rsakey_obj));
199		return TSPERR(TSS_E_OUTOFMEMORY);
200	}
201
202	memcpy(&rsakey->uuid, uuid, sizeof(TSS_UUID));
203
204	offset = 0;
205	if ((result = UnloadBlob_TSS_KEY(&offset, key, &rsakey->key))) {
206		free(rsakey);
207		return result;
208	}
209	if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12)
210		rsakey->type = TSS_KEY_STRUCT_KEY12;
211	else
212		rsakey->type = TSS_KEY_STRUCT_KEY;
213
214	flags |= TSS_OBJ_FLAG_KEY_SET;
215	if (rsakey->key.authDataUsage)
216		flags |= TSS_OBJ_FLAG_USAGEAUTH;
217
218	if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, &rsakey->usagePolicy))) {
219		free(rsakey);
220		return result;
221	}
222
223	if ((result = obj_list_add(&rsakey_list, tspContext, flags, rsakey, phKey))) {
224		free_key_refs(&rsakey->key);
225		free(rsakey);
226		return result;
227	}
228
229	return TSS_SUCCESS;
230}
231
232TSS_BOOL
233obj_is_rsakey(TSS_HOBJECT hObject)
234{
235	TSS_BOOL answer = FALSE;
236
237	if ((obj_list_get_obj(&rsakey_list, hObject))) {
238		answer = TRUE;
239		obj_list_put(&rsakey_list);
240	}
241
242	return answer;
243}
244
245TSS_RESULT
246obj_rsakey_set_flags(TSS_HKEY hKey, UINT32 flags)
247{
248	struct tsp_object *obj;
249	struct tr_rsakey_obj *rsakey;
250	TSS_RESULT result = TSS_SUCCESS;
251
252	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
253		return TSPERR(TSS_E_INVALID_HANDLE);
254
255	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
256		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
257		goto done;
258	}
259
260	rsakey = (struct tr_rsakey_obj *)obj->data;
261	rsakey->key.keyFlags = flags;
262done:
263	obj_list_put(&rsakey_list);
264
265	return result;
266}
267
268TSS_RESULT
269obj_rsakey_set_size(TSS_HKEY hKey, UINT32 len)
270{
271	struct tsp_object *obj;
272	struct tr_rsakey_obj *rsakey;
273	TSS_RESULT result = TSS_SUCCESS;
274
275	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
276		return TSPERR(TSS_E_INVALID_HANDLE);
277
278	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
279		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
280		goto done;
281	}
282
283	rsakey = (struct tr_rsakey_obj *)obj->data;
284	rsakey->key.pubKey.keyLength = len/8;
285done:
286	obj_list_put(&rsakey_list);
287
288	return result;
289}
290
291TSS_RESULT
292obj_rsakey_set_key_parms(TSS_HKEY hKey, TCPA_KEY_PARMS *parms)
293{
294	struct tsp_object *obj;
295	struct tr_rsakey_obj *rsakey;
296	TSS_RESULT result = TSS_SUCCESS;
297
298	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
299		return TSPERR(TSS_E_INVALID_HANDLE);
300
301	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
302		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
303		goto done;
304	}
305
306	rsakey = (struct tr_rsakey_obj *)obj->data;
307
308	free(rsakey->key.algorithmParms.parms);
309
310	memcpy(&rsakey->key.algorithmParms, parms, sizeof(TCPA_KEY_PARMS));
311
312	if (parms->parmSize > 0) {
313		if ((rsakey->key.algorithmParms.parms =
314					malloc(parms->parmSize)) == NULL) {
315			LogError("calloc of %d bytes failed.", parms->parmSize);
316			result = TSPERR(TSS_E_OUTOFMEMORY);
317			goto done;
318		}
319
320		memcpy(rsakey->key.algorithmParms.parms, parms->parms,
321		       parms->parmSize);
322	} else {
323		rsakey->key.algorithmParms.parms = NULL;
324	}
325
326done:
327	obj_list_put(&rsakey_list);
328
329	return result;
330}
331
332TSS_RESULT
333obj_rsakey_set_policy(TSS_HKEY hKey, TSS_HPOLICY hPolicy)
334{
335	struct tsp_object *obj;
336	struct tr_rsakey_obj *rsakey;
337	UINT32 policyType;
338	TSS_RESULT result = TSS_SUCCESS;
339
340	if ((result = obj_policy_get_type(hPolicy, &policyType)))
341		return result;
342
343	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
344		return TSPERR(TSS_E_INVALID_HANDLE);
345
346	rsakey = (struct tr_rsakey_obj *)obj->data;
347
348	switch (policyType) {
349		case TSS_POLICY_USAGE:
350			rsakey->usagePolicy = hPolicy;
351			break;
352		case TSS_POLICY_MIGRATION:
353			rsakey->migPolicy = hPolicy;
354			break;
355		default:
356			result = TSPERR(TSS_E_BAD_PARAMETER);
357	}
358
359	obj_list_put(&rsakey_list);
360
361	return result;
362}
363
364TSS_RESULT
365obj_rsakey_set_pstype(TSS_HKEY hKey, UINT32 type)
366{
367	struct tsp_object *obj;
368
369	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
370		return TSPERR(TSS_E_INVALID_HANDLE);
371
372	switch (type) {
373		case TSS_PS_TYPE_USER:
374			obj->flags |= TSS_OBJ_FLAG_USER_PS;
375			obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
376			break;
377		case TSS_PS_TYPE_SYSTEM:
378			obj->flags |= TSS_OBJ_FLAG_SYSTEM_PS;
379			obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
380			break;
381		case TSS_PS_TYPE_NO:
382		default:
383			obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
384			obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
385			break;
386	}
387
388	obj_list_put(&rsakey_list);
389
390	return TSS_SUCCESS;
391}
392
393/* WARN: Nobody should call this function directly except for the
394 * Get/Set Attrib functions. The TCPA_KEY structure wants values
395 * for keyUsage to be TPM_KEY_* values, and this function translates
396 * to TSS_KEYUSAGE_* values for passing to an app. */
397TSS_RESULT
398obj_rsakey_get_usage(TSS_HKEY hKey, UINT32 *usage)
399{
400	TSS_RESULT result = TSS_SUCCESS;
401	struct tsp_object *obj;
402	struct tr_rsakey_obj *rsakey;
403
404	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
405		return TSPERR(TSS_E_INVALID_HANDLE);
406
407	rsakey = (struct tr_rsakey_obj *)obj->data;
408
409	switch (rsakey->key.keyUsage) {
410		case TPM_KEY_SIGNING:
411			*usage = TSS_KEYUSAGE_SIGN;
412			break;
413		case TPM_KEY_BIND:
414			*usage = TSS_KEYUSAGE_BIND;
415			break;
416		case TPM_KEY_LEGACY:
417			*usage = TSS_KEYUSAGE_LEGACY;
418			break;
419		case TPM_KEY_AUTHCHANGE:
420			*usage = TSS_KEYUSAGE_AUTHCHANGE;
421			break;
422		case TPM_KEY_IDENTITY:
423			*usage = TSS_KEYUSAGE_IDENTITY;
424			break;
425		case TPM_KEY_STORAGE:
426			*usage = TSS_KEYUSAGE_STORAGE;
427			break;
428		default:
429			result = TSPERR(TSS_E_INVALID_ATTRIB_DATA);
430			break;
431	}
432
433	obj_list_put(&rsakey_list);
434
435	return result;
436}
437
438/* WARN: Nobody should call this function directly except for the
439 * Get/Set Attrib functions. The TCPA_KEY structure wants values
440 * for keyUsage to be TPM_KEY_* values, and this function translates
441 * to TSS_KEYUSAGE_* values for passing to an app. */
442TSS_RESULT
443obj_rsakey_set_usage(TSS_HKEY hKey, UINT32 usage)
444{
445	TSS_RESULT result = TSS_SUCCESS;
446	struct tsp_object *obj;
447	struct tr_rsakey_obj *rsakey;
448
449	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
450		return TSPERR(TSS_E_INVALID_HANDLE);
451
452	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
453		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
454		goto done;
455	}
456
457	rsakey = (struct tr_rsakey_obj *)obj->data;
458
459	switch (usage) {
460		case TSS_KEYUSAGE_SIGN:
461			rsakey->key.keyUsage = TPM_KEY_SIGNING;
462			break;
463		case TSS_KEYUSAGE_BIND:
464			rsakey->key.keyUsage = TPM_KEY_BIND;
465			break;
466		case TSS_KEYUSAGE_LEGACY:
467			rsakey->key.keyUsage = TPM_KEY_LEGACY;
468			break;
469		case TSS_KEYUSAGE_AUTHCHANGE:
470			rsakey->key.keyUsage = TPM_KEY_AUTHCHANGE;
471			break;
472		case TSS_KEYUSAGE_IDENTITY:
473			rsakey->key.keyUsage = TPM_KEY_IDENTITY;
474			break;
475		case TSS_KEYUSAGE_STORAGE:
476			rsakey->key.keyUsage = TPM_KEY_STORAGE;
477			break;
478		default:
479			result = TSPERR(TSS_E_INVALID_ATTRIB_DATA);
480			break;
481	}
482done:
483	obj_list_put(&rsakey_list);
484
485	return result;
486}
487
488TSS_RESULT
489obj_rsakey_set_migratable(TSS_HKEY hKey, UINT32 mig)
490{
491	struct tsp_object *obj;
492	struct tr_rsakey_obj *rsakey;
493	TSS_RESULT result = TSS_SUCCESS;
494
495	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
496		return TSPERR(TSS_E_INVALID_HANDLE);
497
498	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
499		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
500		goto done;
501	}
502
503	rsakey = (struct tr_rsakey_obj *)obj->data;
504	if (mig)
505		rsakey->key.keyFlags |= TPM_MIGRATABLE;
506	else
507		rsakey->key.keyFlags &= (~TPM_MIGRATABLE);
508done:
509	obj_list_put(&rsakey_list);
510
511	return result;
512}
513
514TSS_RESULT
515obj_rsakey_set_redirected(TSS_HKEY hKey, UINT32 redir)
516{
517	struct tsp_object *obj;
518	struct tr_rsakey_obj *rsakey;
519	TSS_RESULT result = TSS_SUCCESS;
520
521	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
522		return TSPERR(TSS_E_INVALID_HANDLE);
523
524	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
525		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
526		goto done;
527	}
528
529	rsakey = (struct tr_rsakey_obj *)obj->data;
530	if (redir)
531		rsakey->key.keyFlags |= TPM_REDIRECTION;
532	else
533		rsakey->key.keyFlags &= (~TPM_REDIRECTION);
534done:
535	obj_list_put(&rsakey_list);
536
537	return result;
538}
539
540TSS_RESULT
541obj_rsakey_set_volatile(TSS_HKEY hKey, UINT32 vol)
542{
543	struct tsp_object *obj;
544	struct tr_rsakey_obj *rsakey;
545	TSS_RESULT result = TSS_SUCCESS;
546
547	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
548		return TSPERR(TSS_E_INVALID_HANDLE);
549
550	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
551		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
552		goto done;
553	}
554
555	rsakey = (struct tr_rsakey_obj *)obj->data;
556	if (vol)
557		rsakey->key.keyFlags |= TPM_VOLATILE;
558	else
559		rsakey->key.keyFlags &= (~TPM_VOLATILE);
560done:
561	obj_list_put(&rsakey_list);
562
563	return result;
564}
565
566TSS_RESULT
567obj_rsakey_get_authdata_usage(TSS_HKEY hKey, UINT32 *usage)
568{
569	struct tsp_object *obj;
570	struct tr_rsakey_obj *rsakey;
571
572	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
573		return TSPERR(TSS_E_INVALID_HANDLE);
574
575	rsakey = (struct tr_rsakey_obj *)obj->data;
576	*usage = (UINT32)rsakey->key.authDataUsage ? TRUE : FALSE;
577
578	obj_list_put(&rsakey_list);
579
580	return TSS_SUCCESS;
581}
582
583TSS_RESULT
584obj_rsakey_set_authdata_usage(TSS_HKEY hKey, UINT32 usage)
585{
586	struct tsp_object *obj;
587	struct tr_rsakey_obj *rsakey;
588	TSS_RESULT result = TSS_SUCCESS;
589
590	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
591		return TSPERR(TSS_E_INVALID_HANDLE);
592
593	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
594		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
595		goto done;
596	}
597
598	rsakey = (struct tr_rsakey_obj *)obj->data;
599
600	rsakey->key.authDataUsage = (BYTE)usage;
601	if (usage)
602		obj->flags |= TSS_OBJ_FLAG_USAGEAUTH;
603	else
604		obj->flags &= ~TSS_OBJ_FLAG_USAGEAUTH;
605done:
606	obj_list_put(&rsakey_list);
607
608	return result;
609}
610
611TSS_RESULT
612obj_rsakey_get_alg(TSS_HKEY hKey, UINT32 *alg)
613{
614	struct tsp_object *obj;
615	struct tr_rsakey_obj *rsakey;
616
617	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
618		return TSPERR(TSS_E_INVALID_HANDLE);
619
620	rsakey = (struct tr_rsakey_obj *)obj->data;
621
622	switch (rsakey->key.algorithmParms.algorithmID) {
623		case TCPA_ALG_RSA:
624			*alg = TSS_ALG_RSA;
625			break;
626		default:
627			*alg = rsakey->key.algorithmParms.algorithmID;
628			break;
629	}
630
631	obj_list_put(&rsakey_list);
632
633	return TSS_SUCCESS;
634}
635
636TSS_RESULT
637obj_rsakey_set_alg(TSS_HKEY hKey, UINT32 alg)
638{
639	struct tsp_object *obj;
640	struct tr_rsakey_obj *rsakey;
641	TSS_RESULT result = TSS_SUCCESS;
642
643	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
644		return TSPERR(TSS_E_INVALID_HANDLE);
645
646	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
647		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
648		goto done;
649	}
650
651	rsakey = (struct tr_rsakey_obj *)obj->data;
652	switch (alg) {
653		case TSS_ALG_RSA:
654			rsakey->key.algorithmParms.algorithmID = TCPA_ALG_RSA;
655			break;
656		default:
657			rsakey->key.algorithmParms.algorithmID = alg;
658			break;
659	}
660done:
661	obj_list_put(&rsakey_list);
662
663	return result;
664}
665
666TSS_RESULT
667obj_rsakey_get_es(TSS_HKEY hKey, UINT32 *es)
668{
669	struct tsp_object *obj;
670	struct tr_rsakey_obj *rsakey;
671
672	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
673		return TSPERR(TSS_E_INVALID_HANDLE);
674
675	rsakey = (struct tr_rsakey_obj *)obj->data;
676
677	/* translate TPM numbers to TSS numbers */
678	switch (rsakey->key.algorithmParms.encScheme) {
679		case TCPA_ES_NONE:
680			*es = TSS_ES_NONE;
681			break;
682		case TCPA_ES_RSAESPKCSv15:
683			*es = TSS_ES_RSAESPKCSV15;
684			break;
685		case TCPA_ES_RSAESOAEP_SHA1_MGF1:
686			*es = TSS_ES_RSAESOAEP_SHA1_MGF1;
687			break;
688		default:
689			*es = rsakey->key.algorithmParms.encScheme;
690			break;
691	}
692
693	obj_list_put(&rsakey_list);
694
695	return TSS_SUCCESS;
696}
697
698TSS_RESULT
699obj_rsakey_set_es(TSS_HKEY hKey, UINT32 es)
700{
701	struct tsp_object *obj;
702	struct tr_rsakey_obj *rsakey;
703	TSS_RESULT result = TSS_SUCCESS;
704
705	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
706		return TSPERR(TSS_E_INVALID_HANDLE);
707
708	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
709		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
710		goto done;
711	}
712
713	rsakey = (struct tr_rsakey_obj *)obj->data;
714
715	/* translate TSS numbers to TPM numbers */
716	switch (es) {
717		case TSS_ES_NONE:
718			rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE;
719			break;
720		case TSS_ES_RSAESPKCSV15:
721			rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESPKCSv15;
722			break;
723		case TSS_ES_RSAESOAEP_SHA1_MGF1:
724			rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1;
725			break;
726		default:
727			rsakey->key.algorithmParms.encScheme = es;
728			break;
729	}
730done:
731	obj_list_put(&rsakey_list);
732
733	return result;
734}
735
736TSS_RESULT
737obj_rsakey_get_ss(TSS_HKEY hKey, UINT32 *ss)
738{
739	struct tsp_object *obj;
740	struct tr_rsakey_obj *rsakey;
741
742	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
743		return TSPERR(TSS_E_INVALID_HANDLE);
744
745	rsakey = (struct tr_rsakey_obj *)obj->data;
746
747	/* translate TPM numbers to TSS numbers */
748	switch (rsakey->key.algorithmParms.sigScheme) {
749		case TCPA_SS_NONE:
750			*ss = TSS_SS_NONE;
751			break;
752		case TCPA_SS_RSASSAPKCS1v15_SHA1:
753			*ss = TSS_SS_RSASSAPKCS1V15_SHA1;
754			break;
755		case TCPA_SS_RSASSAPKCS1v15_DER:
756			*ss = TSS_SS_RSASSAPKCS1V15_DER;
757			break;
758		case TCPA_SS_RSASSAPKCS1v15_INFO:
759			*ss = TSS_SS_RSASSAPKCS1V15_INFO;
760			break;
761		default:
762			*ss = rsakey->key.algorithmParms.sigScheme;
763			break;
764	}
765
766
767	obj_list_put(&rsakey_list);
768
769	return TSS_SUCCESS;
770}
771
772TSS_RESULT
773obj_rsakey_set_ss(TSS_HKEY hKey, UINT32 ss)
774{
775	struct tsp_object *obj;
776	struct tr_rsakey_obj *rsakey;
777	TSS_RESULT result = TSS_SUCCESS;
778
779	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
780		return TSPERR(TSS_E_INVALID_HANDLE);
781
782	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
783		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
784		goto done;
785	}
786
787	rsakey = (struct tr_rsakey_obj *)obj->data;
788
789	/* translate TSS numbers to TPM numbers */
790	switch (ss) {
791		case TSS_SS_NONE:
792			rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE;
793			break;
794		case TSS_SS_RSASSAPKCS1V15_SHA1:
795			rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1;
796			break;
797		case TSS_SS_RSASSAPKCS1V15_DER:
798			rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_DER;
799			break;
800		case TSS_SS_RSASSAPKCS1V15_INFO:
801			rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_INFO;
802			break;
803		default:
804			rsakey->key.algorithmParms.sigScheme = ss;
805			break;
806	}
807done:
808	obj_list_put(&rsakey_list);
809
810	return result;
811}
812
813TSS_RESULT
814obj_rsakey_set_num_primes(TSS_HKEY hKey, UINT32 num)
815{
816	struct tsp_object *obj;
817	struct tr_rsakey_obj *rsakey;
818	TSS_RESULT result = TSS_SUCCESS;
819
820	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
821		return TSPERR(TSS_E_INVALID_HANDLE);
822
823	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
824		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
825		goto done;
826	}
827
828	rsakey = (struct tr_rsakey_obj *)obj->data;
829	UINT32ToArray(num, &rsakey->key.algorithmParms.parms[4]);
830done:
831	obj_list_put(&rsakey_list);
832
833	return result;
834}
835
836TSS_RESULT
837obj_rsakey_get_num_primes(TSS_HKEY hKey, UINT32 *num)
838{
839	struct tsp_object *obj;
840	struct tr_rsakey_obj *rsakey;
841	TCPA_RSA_KEY_PARMS *parms;
842
843	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
844		return TSPERR(TSS_E_INVALID_HANDLE);
845
846	rsakey = (struct tr_rsakey_obj *)obj->data;
847	parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms;
848	*num = endian32(parms->numPrimes);
849
850	obj_list_put(&rsakey_list);
851
852	return TSS_SUCCESS;
853}
854
855TSS_RESULT
856obj_rsakey_get_flags(TSS_HKEY hKey, UINT32 *flags)
857{
858	struct tsp_object *obj;
859	struct tr_rsakey_obj *rsakey;
860
861	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
862		return TSPERR(TSS_E_INVALID_HANDLE);
863
864	rsakey = (struct tr_rsakey_obj *)obj->data;
865	*flags = rsakey->key.keyFlags;
866
867	obj_list_put(&rsakey_list);
868
869	return TSS_SUCCESS;
870}
871
872TSS_RESULT
873obj_rsakey_get_size(TSS_HKEY hKey, UINT32 *len)
874{
875	struct tsp_object *obj;
876	struct tr_rsakey_obj *rsakey;
877
878	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
879		return TSPERR(TSS_E_INVALID_HANDLE);
880
881	rsakey = (struct tr_rsakey_obj *)obj->data;
882
883	switch (rsakey->key.pubKey.keyLength) {
884		case 512/8:
885			*len = TSS_KEY_SIZEVAL_512BIT;
886			break;
887		case 1024/8:
888			*len = TSS_KEY_SIZEVAL_1024BIT;
889			break;
890		case 2048/8:
891			*len = TSS_KEY_SIZEVAL_2048BIT;
892			break;
893		default:
894			*len = rsakey->key.pubKey.keyLength * 8;
895			break;
896	}
897
898	obj_list_put(&rsakey_list);
899
900	return TSS_SUCCESS;
901}
902
903TSS_RESULT
904obj_rsakey_get_pstype(TSS_HKEY hKey, UINT32 *type)
905{
906	struct tsp_object *obj;
907
908	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
909		return TSPERR(TSS_E_INVALID_HANDLE);
910
911	if (obj->flags & TSS_OBJ_FLAG_SYSTEM_PS)
912		*type = TSS_PS_TYPE_SYSTEM;
913	else if (obj->flags & TSS_OBJ_FLAG_USER_PS)
914		*type = TSS_PS_TYPE_USER;
915	else
916		*type = TSS_PS_TYPE_NO;
917
918	obj_list_put(&rsakey_list);
919
920	return TSS_SUCCESS;
921}
922
923TSS_BOOL
924obj_rsakey_is_migratable(TSS_HKEY hKey)
925{
926	struct tsp_object *obj;
927	struct tr_rsakey_obj *rsakey;
928	TSS_BOOL answer = FALSE;
929
930	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
931		return answer;
932
933	rsakey = (struct tr_rsakey_obj *)obj->data;
934	if (rsakey->key.keyFlags & TPM_MIGRATABLE)
935		answer = TRUE;
936
937	obj_list_put(&rsakey_list);
938
939	return answer;
940}
941
942TSS_BOOL
943obj_rsakey_is_redirected(TSS_HKEY hKey)
944{
945	struct tsp_object *obj;
946	struct tr_rsakey_obj *rsakey;
947	TSS_BOOL answer = FALSE;
948
949	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
950		return answer;
951
952	rsakey = (struct tr_rsakey_obj *)obj->data;
953	if (rsakey->key.keyFlags & TPM_REDIRECTION)
954		answer = TRUE;
955
956	obj_list_put(&rsakey_list);
957
958	return answer;
959}
960
961TSS_BOOL
962obj_rsakey_is_volatile(TSS_HKEY hKey)
963{
964	struct tsp_object *obj;
965	struct tr_rsakey_obj *rsakey;
966	TSS_BOOL answer = FALSE;
967
968	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
969		return answer;
970
971	rsakey = (struct tr_rsakey_obj *)obj->data;
972	if (rsakey->key.keyFlags & TPM_VOLATILE)
973		answer = TRUE;
974
975	obj_list_put(&rsakey_list);
976
977	return answer;
978}
979
980TSS_RESULT
981obj_rsakey_get_tsp_context(TSS_HKEY hKey, TSS_HCONTEXT *tspContext)
982{
983	struct tsp_object *obj;
984
985	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
986		return TSPERR(TSS_E_INVALID_HANDLE);
987
988	*tspContext = obj->tspContext;
989
990	obj_list_put(&rsakey_list);
991
992	return TSS_SUCCESS;
993}
994
995TSS_RESULT
996obj_rsakey_get_policies(TSS_HKEY hKey, TSS_HPOLICY *usage, TSS_HPOLICY *mig, TSS_BOOL *auth)
997{
998	struct tsp_object *obj;
999	struct tr_rsakey_obj *rsakey;
1000
1001	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1002		return TSPERR(TSS_E_INVALID_HANDLE);
1003
1004	rsakey = (struct tr_rsakey_obj *)obj->data;
1005
1006	*mig = rsakey->migPolicy;
1007	*usage = rsakey->usagePolicy;
1008	*auth = rsakey->key.authDataUsage ? TRUE : FALSE;
1009
1010	obj_list_put(&rsakey_list);
1011
1012	return TSS_SUCCESS;
1013}
1014
1015TSS_RESULT
1016obj_rsakey_get_policy(TSS_HKEY hKey, UINT32 policyType,
1017		      TSS_HPOLICY *phPolicy, TSS_BOOL *auth)
1018{
1019	struct tsp_object *obj;
1020	struct tr_rsakey_obj *rsakey;
1021	TSS_RESULT result = TSS_SUCCESS;
1022
1023	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1024		return TSPERR(TSS_E_INVALID_HANDLE);
1025
1026	rsakey = (struct tr_rsakey_obj *)obj->data;
1027
1028	switch (policyType) {
1029		case TSS_POLICY_USAGE:
1030			*phPolicy = rsakey->usagePolicy;
1031			if (auth != NULL) {
1032				if (obj->flags & TSS_OBJ_FLAG_USAGEAUTH)
1033					*auth = TRUE;
1034				else
1035					*auth = FALSE;
1036			}
1037			break;
1038		case TSS_POLICY_MIGRATION:
1039			if (!rsakey->migPolicy) {
1040				result = TSPERR(TSS_E_KEY_NO_MIGRATION_POLICY);
1041				break;
1042			}
1043
1044			*phPolicy = rsakey->migPolicy;
1045			if (auth != NULL) {
1046				if (obj->flags & TSS_OBJ_FLAG_MIGAUTH)
1047					*auth = TRUE;
1048				else
1049					*auth = FALSE;
1050			}
1051			break;
1052		default:
1053			result = TSPERR(TSS_E_BAD_PARAMETER);
1054	}
1055
1056	obj_list_put(&rsakey_list);
1057
1058	return result;
1059}
1060
1061TSS_RESULT
1062obj_rsakey_get_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data)
1063{
1064	struct tsp_object *obj;
1065	struct tr_rsakey_obj *rsakey;
1066	TSS_RESULT result = TSS_SUCCESS;
1067	UINT64 offset;
1068
1069	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1070		return TSPERR(TSS_E_INVALID_HANDLE);
1071
1072	rsakey = (struct tr_rsakey_obj *)obj->data;
1073
1074	offset = 0;
1075	LoadBlob_TSS_KEY(&offset, NULL, &rsakey->key);
1076
1077	*data = calloc_tspi(obj->tspContext, offset);
1078	if (*data == NULL) {
1079		LogError("malloc of %" PRIu64 " bytes failed.", offset);
1080		result = TSPERR(TSS_E_OUTOFMEMORY);
1081		goto done;
1082	}
1083
1084	offset = 0;
1085	LoadBlob_TSS_KEY(&offset, *data, &rsakey->key);
1086	*size = offset;
1087
1088done:
1089	obj_list_put(&rsakey_list);
1090
1091	return result;
1092}
1093
1094TSS_RESULT
1095obj_rsakey_get_priv_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data)
1096{
1097	struct tsp_object *obj;
1098	struct tr_rsakey_obj *rsakey;
1099	TSS_RESULT result = TSS_SUCCESS;
1100
1101	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1102		return TSPERR(TSS_E_INVALID_HANDLE);
1103
1104	rsakey = (struct tr_rsakey_obj *)obj->data;
1105
1106	*data = calloc_tspi(obj->tspContext, rsakey->key.encSize);
1107	if (*data == NULL) {
1108		LogError("malloc of %u bytes failed.", rsakey->key.encSize);
1109		result = TSPERR(TSS_E_OUTOFMEMORY);
1110		goto done;
1111	}
1112	*size = rsakey->key.encSize;
1113	memcpy(*data, rsakey->key.encData, rsakey->key.encSize);
1114
1115done:
1116	obj_list_put(&rsakey_list);
1117
1118	return result;
1119}
1120
1121TSS_RESULT
1122obj_rsakey_get_modulus(TSS_HKEY hKey, UINT32 *size, BYTE **data)
1123{
1124	struct tsp_object *obj;
1125	struct tr_rsakey_obj *rsakey;
1126	TSS_RESULT result = TSS_SUCCESS;
1127
1128	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1129		return TSPERR(TSS_E_INVALID_HANDLE);
1130
1131	rsakey = (struct tr_rsakey_obj *)obj->data;
1132
1133	/* if this key object represents the SRK and the public key
1134	 * data here is all 0's, then we shouldn't return it, we
1135	 * should return TSS_E_BAD_PARAMETER. This is part of protecting
1136	 * the SRK public key. */
1137	if (rsakey->tcsHandle == TPM_KEYHND_SRK) {
1138		BYTE zeroBlob[2048] = { 0, };
1139
1140		if (!memcmp(rsakey->key.pubKey.key, zeroBlob, rsakey->key.pubKey.keyLength)) {
1141			result = TSPERR(TSS_E_BAD_PARAMETER);
1142			goto done;
1143		}
1144	}
1145
1146	*data = calloc_tspi(obj->tspContext, rsakey->key.pubKey.keyLength);
1147	if (*data == NULL) {
1148		LogError("malloc of %u bytes failed.", rsakey->key.pubKey.keyLength);
1149		result = TSPERR(TSS_E_OUTOFMEMORY);
1150		goto done;
1151	}
1152	*size = rsakey->key.pubKey.keyLength;
1153	memcpy(*data, rsakey->key.pubKey.key, rsakey->key.pubKey.keyLength);
1154
1155done:
1156	obj_list_put(&rsakey_list);
1157
1158	return result;
1159}
1160
1161TSS_RESULT
1162obj_rsakey_set_modulus(TSS_HKEY hKey, UINT32 size, BYTE *data)
1163{
1164	struct tsp_object *obj;
1165	struct tr_rsakey_obj *rsakey;
1166	TSS_RESULT result = TSS_SUCCESS;
1167	BYTE *free_ptr;
1168
1169	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1170		return TSPERR(TSS_E_INVALID_HANDLE);
1171
1172	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
1173		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1174		goto done;
1175	}
1176
1177	rsakey = (struct tr_rsakey_obj *)obj->data;
1178
1179	free_ptr = rsakey->key.pubKey.key;
1180
1181	rsakey->key.pubKey.key = malloc(size);
1182	if (rsakey->key.pubKey.key == NULL) {
1183		rsakey->key.pubKey.key = free_ptr; // restore
1184		LogError("malloc of %u bytes failed.", size);
1185		result = TSPERR(TSS_E_OUTOFMEMORY);
1186		goto done;
1187	}
1188	rsakey->key.pubKey.keyLength = size;
1189	memcpy(rsakey->key.pubKey.key, data, size);
1190
1191done:
1192	obj_list_put(&rsakey_list);
1193
1194	return result;
1195}
1196
1197TSS_RESULT
1198obj_rsakey_get_pub_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data)
1199{
1200	struct tsp_object *obj;
1201	struct tr_rsakey_obj *rsakey;
1202	TSS_RESULT result = TSS_SUCCESS;
1203	UINT64 offset;
1204
1205	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1206		return TSPERR(TSS_E_INVALID_HANDLE);
1207
1208	rsakey = (struct tr_rsakey_obj *)obj->data;
1209
1210	/* if this key object represents the SRK and the public key
1211	 * data here is all 0's, then we shouldn't return it, we
1212	 * should return TSS_E_BAD_PARAMETER. This is part of protecting
1213	 * the SRK public key. */
1214	if (rsakey->tcsHandle == TPM_KEYHND_SRK) {
1215		BYTE zeroBlob[2048] = { 0, };
1216
1217		if (!memcmp(rsakey->key.pubKey.key, zeroBlob, rsakey->key.pubKey.keyLength)) {
1218			result = TSPERR(TSS_E_BAD_PARAMETER);
1219			goto done;
1220		}
1221	}
1222
1223	offset = 0;
1224	Trspi_LoadBlob_KEY_PARMS(&offset, NULL, &rsakey->key.algorithmParms);
1225	Trspi_LoadBlob_STORE_PUBKEY(&offset, NULL, &rsakey->key.pubKey);
1226
1227	*data = calloc_tspi(obj->tspContext, offset);
1228	if (*data == NULL) {
1229		LogError("malloc of %" PRIu64 " bytes failed.", offset);
1230		result = TSPERR(TSS_E_OUTOFMEMORY);
1231		goto done;
1232	}
1233
1234	offset = 0;
1235	Trspi_LoadBlob_KEY_PARMS(&offset, *data, &rsakey->key.algorithmParms);
1236	Trspi_LoadBlob_STORE_PUBKEY(&offset, *data, &rsakey->key.pubKey);
1237	*size = offset;
1238
1239done:
1240	obj_list_put(&rsakey_list);
1241
1242	return result;
1243}
1244
1245TSS_RESULT
1246obj_rsakey_get_version(TSS_HKEY hKey, UINT32 *size, BYTE **data)
1247{
1248	struct tsp_object *obj;
1249	struct tr_rsakey_obj *rsakey;
1250	TSS_RESULT result = TSS_SUCCESS;
1251	UINT64 offset;
1252	TPM_STRUCT_VER ver = {1, 2, 0, 0}, *pVer;
1253
1254	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1255		return TSPERR(TSS_E_INVALID_HANDLE);
1256
1257	rsakey = (struct tr_rsakey_obj *)obj->data;
1258
1259	if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12)
1260		pVer = &ver;
1261	else
1262		pVer = &rsakey->key.hdr.key11.ver;
1263
1264	offset = 0;
1265	Trspi_LoadBlob_TCPA_VERSION(&offset, NULL, *pVer);
1266
1267	*data = calloc_tspi(obj->tspContext, offset);
1268	if (*data == NULL) {
1269		LogError("malloc of %" PRIu64 " bytes failed.", offset);
1270		result = TSPERR(TSS_E_OUTOFMEMORY);
1271		goto done;
1272	}
1273
1274	offset = 0;
1275	Trspi_LoadBlob_TCPA_VERSION(&offset, *data, *pVer);
1276	*size = offset;
1277
1278done:
1279	obj_list_put(&rsakey_list);
1280
1281	return result;
1282}
1283
1284TSS_RESULT
1285obj_rsakey_get_exponent(TSS_HKEY hKey, UINT32 *size, BYTE **data)
1286{
1287	struct tsp_object *obj;
1288	struct tr_rsakey_obj *rsakey;
1289	TSS_RESULT result = TSS_SUCCESS;
1290	TCPA_RSA_KEY_PARMS *parms;
1291	BYTE default_exp[3] = { 0x1, 0x0, 0x1 };
1292	UINT32 offset;
1293
1294	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1295		return TSPERR(TSS_E_INVALID_HANDLE);
1296
1297	rsakey = (struct tr_rsakey_obj *)obj->data;
1298	parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms;
1299	offset = parms->exponentSize;
1300
1301	/* see TPM 1.1b spec pg. 51. If exponentSize is 0, we're using the
1302	 * default exponent of 2^16 + 1. */
1303	if (offset == 0) {
1304		offset = 3;
1305		*data = calloc_tspi(obj->tspContext, offset);
1306		if (*data == NULL) {
1307			LogError("malloc of %u bytes failed.", offset);
1308			result = TSPERR(TSS_E_OUTOFMEMORY);
1309			goto done;
1310		}
1311		*size = offset;
1312		memcpy(*data, default_exp, offset);
1313	} else {
1314		*data = calloc_tspi(obj->tspContext, offset);
1315		if (*data == NULL) {
1316			LogError("malloc of %u bytes failed.", offset);
1317			result = TSPERR(TSS_E_OUTOFMEMORY);
1318			goto done;
1319		}
1320		*size = offset;
1321		memcpy(*data, parms->exponent, offset);
1322	}
1323
1324done:
1325	obj_list_put(&rsakey_list);
1326
1327	return result;
1328}
1329
1330TSS_RESULT
1331obj_rsakey_set_exponent(TSS_HKEY hKey, UINT32 size, BYTE *data)
1332{
1333	struct tsp_object *obj;
1334	struct tr_rsakey_obj *rsakey;
1335	TSS_RESULT result = TSS_SUCCESS;
1336	TCPA_RSA_KEY_PARMS *parms;
1337	BYTE *free_ptr;
1338
1339	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1340		return TSPERR(TSS_E_INVALID_HANDLE);
1341
1342	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
1343		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1344		goto done;
1345	}
1346
1347	rsakey = (struct tr_rsakey_obj *)obj->data;
1348	parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms;
1349
1350	free_ptr = parms->exponent;
1351
1352	parms->exponent = malloc(size);
1353	if (parms->exponent == NULL) {
1354		parms->exponent = free_ptr; // restore
1355		LogError("malloc of %u bytes failed.", size);
1356		result = TSPERR(TSS_E_OUTOFMEMORY);
1357		goto done;
1358	}
1359	parms->exponentSize = size;
1360	memcpy(parms->exponent, data, size);
1361done:
1362	obj_list_put(&rsakey_list);
1363
1364	return result;
1365}
1366
1367TSS_RESULT
1368obj_rsakey_get_uuid(TSS_HKEY hKey, UINT32 *size, BYTE **data)
1369{
1370	struct tsp_object *obj;
1371	struct tr_rsakey_obj *rsakey;
1372	TSS_RESULT result = TSS_SUCCESS;
1373	UINT64 offset;
1374
1375	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1376		return TSPERR(TSS_E_INVALID_HANDLE);
1377
1378	rsakey = (struct tr_rsakey_obj *)obj->data;
1379
1380	offset = 0;
1381	Trspi_LoadBlob_UUID(&offset, NULL, rsakey->uuid);
1382
1383	*data = calloc_tspi(obj->tspContext, offset);
1384	if (*data == NULL) {
1385		LogError("malloc of %" PRIu64 " bytes failed.", offset);
1386		result = TSPERR(TSS_E_OUTOFMEMORY);
1387		goto done;
1388	}
1389
1390	offset = 0;
1391	Trspi_LoadBlob_UUID(&offset, *data, rsakey->uuid);
1392	*size = offset;
1393
1394done:
1395	obj_list_put(&rsakey_list);
1396
1397	return result;
1398}
1399
1400TSS_RESULT
1401obj_rsakey_set_uuid(TSS_HKEY hKey, TSS_FLAG ps_type, TSS_UUID *uuid)
1402{
1403	struct tsp_object *obj;
1404	struct tr_rsakey_obj *rsakey;
1405
1406	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1407		return TSPERR(TSS_E_INVALID_HANDLE);
1408
1409	rsakey = (struct tr_rsakey_obj *)obj->data;
1410	memcpy(&rsakey->uuid, uuid, sizeof(TSS_UUID));
1411
1412	switch (ps_type) {
1413		case TSS_PS_TYPE_SYSTEM:
1414			obj->flags |= TSS_OBJ_FLAG_SYSTEM_PS;
1415			obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
1416			break;
1417		case TSS_PS_TYPE_USER:
1418			obj->flags |= TSS_OBJ_FLAG_USER_PS;
1419			obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
1420			break;
1421		case TSS_PS_TYPE_NO:
1422		default:
1423			obj->flags &= ~TSS_OBJ_FLAG_USER_PS;
1424			obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS;
1425			break;
1426	}
1427
1428	obj_list_put(&rsakey_list);
1429
1430	return TSS_SUCCESS;
1431}
1432
1433TSS_RESULT
1434obj_rsakey_set_tcs_handle(TSS_HKEY hKey, TCS_KEY_HANDLE tcsHandle)
1435{
1436	struct tsp_object *obj;
1437	struct tr_rsakey_obj *rsakey;
1438
1439	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1440		return TSPERR(TSS_E_INVALID_HANDLE);
1441
1442	rsakey = (struct tr_rsakey_obj *)obj->data;
1443	rsakey->tcsHandle = tcsHandle;
1444
1445	obj_list_put(&rsakey_list);
1446
1447	return TSS_SUCCESS;
1448}
1449
1450TSS_RESULT
1451obj_rsakey_get_tcs_handle(TSS_HKEY hKey, TCS_KEY_HANDLE *tcsHandle)
1452{
1453	struct tsp_object *obj;
1454	struct tr_rsakey_obj *rsakey;
1455	TSS_RESULT result = TSS_SUCCESS;
1456
1457	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1458		return TSPERR(TSS_E_INVALID_HANDLE);
1459
1460	rsakey = (struct tr_rsakey_obj *)obj->data;
1461	if (rsakey->tcsHandle)
1462		*tcsHandle = rsakey->tcsHandle;
1463	else
1464		result = TSPERR(TSS_E_KEY_NOT_LOADED);
1465
1466	obj_list_put(&rsakey_list);
1467
1468	return result;
1469}
1470
1471TSS_RESULT
1472obj_rsakey_set_tcpakey(TSS_HKEY hKey, UINT32 size, BYTE *data)
1473{
1474	struct tsp_object *obj;
1475	struct tr_rsakey_obj *rsakey;
1476	UINT64 offset;
1477	TSS_RESULT result = TSS_SUCCESS;
1478
1479	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1480		return TSPERR(TSS_E_INVALID_HANDLE);
1481
1482	rsakey = (struct tr_rsakey_obj *)obj->data;
1483
1484	free_key_refs(&rsakey->key);
1485
1486	offset = 0;
1487	if ((result = UnloadBlob_TSS_KEY(&offset, data, &rsakey->key)))
1488		goto done;
1489	if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12)
1490		rsakey->type = TSS_KEY_STRUCT_KEY12;
1491	else
1492		rsakey->type = TSS_KEY_STRUCT_KEY;
1493
1494	if (rsakey->key.authDataUsage)
1495		obj->flags |= TSS_OBJ_FLAG_USAGEAUTH;
1496	else
1497		obj->flags &= ~TSS_OBJ_FLAG_USAGEAUTH;
1498
1499	if (rsakey->key.PCRInfoSize && rsakey->key.PCRInfo) {
1500		offset = 0;
1501		if (rsakey->type == TSS_KEY_STRUCT_KEY12) {
1502			if ((result = Trspi_UnloadBlob_PCR_INFO_LONG(&offset, rsakey->key.PCRInfo,
1503								     &rsakey->pcrInfo.infolong)))
1504				goto done;
1505		} else {
1506			if ((result = Trspi_UnloadBlob_PCR_INFO(&offset, rsakey->key.PCRInfo,
1507								&rsakey->pcrInfo.info11)))
1508				goto done;
1509		}
1510	}
1511
1512	obj->flags |= TSS_OBJ_FLAG_KEY_SET;
1513done:
1514	obj_list_put(&rsakey_list);
1515
1516	return result;
1517}
1518
1519TSS_RESULT
1520obj_rsakey_get_pcr_digest(TSS_HKEY hKey,
1521                          TSS_FLAG pcrInfoType,
1522                          TSS_FLAG dir,
1523                          UINT32 *size,
1524                          BYTE **data)
1525{
1526	struct tsp_object *obj;
1527	struct tr_rsakey_obj *rsakey;
1528	TSS_RESULT result = TSS_SUCCESS;
1529	TPM_DIGEST *digest = NULL;
1530	UINT64 offset;
1531
1532	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1533		return TSPERR(TSS_E_INVALID_HANDLE);
1534
1535	rsakey = (struct tr_rsakey_obj *)obj->data;
1536
1537	if (pcrInfoType != rsakey->pcrInfoType) {
1538		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1539		goto done;
1540	}
1541
1542	switch (pcrInfoType) {
1543		case TSS_PCRS_STRUCT_INFO:
1544			if (dir == TSS_TSPATTRIB_KEYPCR_DIGEST_ATCREATION)
1545				digest = &rsakey->pcrInfo.info11.digestAtCreation;
1546			else if (dir == TSS_TSPATTRIB_KEYPCR_DIGEST_ATRELEASE)
1547				digest = &rsakey->pcrInfo.info11.digestAtRelease;
1548			else {
1549				result = TSPERR(TSS_E_BAD_PARAMETER);
1550				goto done;
1551			}
1552			break;
1553		case TSS_PCRS_STRUCT_INFO_LONG:
1554			if (dir == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATCREATION)
1555				digest = &rsakey->pcrInfo.infolong.digestAtCreation;
1556			else if (dir == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATRELEASE)
1557				digest = &rsakey->pcrInfo.infolong.digestAtRelease;
1558			else {
1559				result = TSPERR(TSS_E_BAD_PARAMETER);
1560				goto done;
1561			}
1562			break;
1563		default:
1564			result = TSPERR(TSS_E_INTERNAL_ERROR);
1565			goto done;
1566	}
1567
1568	*size = sizeof(TPM_DIGEST);
1569
1570	if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) {
1571		LogError("malloc of %u bytes failed.", *size);
1572		*size = 0;
1573		result = TSPERR(TSS_E_OUTOFMEMORY);
1574		goto done;
1575	}
1576
1577	offset = 0;
1578	Trspi_LoadBlob_DIGEST(&offset, *data, digest);
1579done:
1580	obj_list_put(&rsakey_list);
1581
1582	return result;
1583}
1584
1585
1586TSS_RESULT
1587obj_rsakey_get_pcr_locality(TSS_HKEY hKey, TSS_FLAG dir, UINT32 *locality)
1588{
1589	struct tsp_object *obj;
1590	struct tr_rsakey_obj *rsakey;
1591	TSS_RESULT result = TSS_SUCCESS;
1592
1593	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1594		return TSPERR(TSS_E_INVALID_HANDLE);
1595
1596	rsakey = (struct tr_rsakey_obj *)obj->data;
1597
1598	if (rsakey->pcrInfoType == TSS_PCRS_STRUCT_INFO_LONG) {
1599		if (dir == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATCREATION)
1600			*locality = rsakey->pcrInfo.infolong.localityAtCreation;
1601		else if (dir == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATRELEASE)
1602			*locality = rsakey->pcrInfo.infolong.localityAtRelease;
1603		else
1604			result = TSPERR(TSS_E_BAD_PARAMETER);
1605	} else
1606		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1607
1608	obj_list_put(&rsakey_list);
1609
1610	return result;
1611}
1612
1613TSS_RESULT
1614obj_rsakey_get_pcr_selection(TSS_HKEY hKey,
1615			     UINT32 pcrInfoType,
1616			     TSS_FLAG dir,
1617			     UINT32 *size,
1618			     BYTE **data)
1619{
1620	struct tsp_object *obj;
1621	struct tr_rsakey_obj *rsakey;
1622	TSS_RESULT result = TSS_SUCCESS;
1623	UINT64 offset;
1624	TPM_PCR_SELECTION *selection = NULL;
1625
1626	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1627		return TSPERR(TSS_E_INVALID_HANDLE);
1628
1629	rsakey = (struct tr_rsakey_obj *)obj->data;
1630
1631        if (pcrInfoType != rsakey->pcrInfoType) {
1632                result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1633                goto done;
1634        }
1635
1636        switch (pcrInfoType) {
1637                case TSS_PCRS_STRUCT_INFO:
1638                        if (dir == TSS_TSPATTRIB_KEYPCR_SELECTION)
1639                                selection = &rsakey->pcrInfo.info11.pcrSelection;
1640                        else {
1641                                result = TSPERR(TSS_E_BAD_PARAMETER);
1642                                goto done;
1643                        }
1644                        break;
1645                case TSS_PCRS_STRUCT_INFO_LONG:
1646                        if (dir == TSS_TSPATTRIB_KEYPCRLONG_CREATION_SELECTION)
1647                                selection = &rsakey->pcrInfo.infolong.creationPCRSelection;
1648                        else if (dir == TSS_TSPATTRIB_KEYPCRLONG_RELEASE_SELECTION)
1649                                selection = &rsakey->pcrInfo.infolong.releasePCRSelection;
1650                        else {
1651                                result = TSPERR(TSS_E_BAD_PARAMETER);
1652                                goto done;
1653                        }
1654                        break;
1655                default:
1656                        result = TSPERR(TSS_E_INTERNAL_ERROR);
1657                        goto done;
1658        }
1659
1660        *size = sizeof(UINT16) + selection->sizeOfSelect;
1661
1662        if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) {
1663                LogError("malloc of %u bytes failed.", *size);
1664                *size = 0;
1665                result = TSPERR(TSS_E_OUTOFMEMORY);
1666                goto done;
1667        }
1668
1669        offset = 0;
1670        Trspi_LoadBlob_PCR_SELECTION(&offset, *data, selection);
1671
1672done:
1673	obj_list_put(&rsakey_list);
1674
1675	return result;
1676}
1677
1678TSS_RESULT
1679rsakey_set_pubkey(struct tr_rsakey_obj *rsakey, BYTE *pubkey)
1680{
1681	TSS_RESULT result;
1682	UINT64 offset = 0;
1683	TPM_PUBKEY pub;
1684
1685	if ((result = Trspi_UnloadBlob_PUBKEY(&offset, pubkey, &pub)))
1686		return result;
1687
1688	free(rsakey->key.pubKey.key);
1689	free(rsakey->key.algorithmParms.parms);
1690
1691	memcpy(&rsakey->key.pubKey, &pub.pubKey, sizeof(TPM_STORE_PUBKEY));
1692	memcpy(&rsakey->key.algorithmParms, &pub.algorithmParms, sizeof(TPM_KEY_PARMS));
1693
1694	return TSS_SUCCESS;
1695}
1696
1697/* Expect a TPM_PUBKEY as is explained in the portable data section of the spec */
1698TSS_RESULT
1699obj_rsakey_set_pubkey(TSS_HKEY hKey, UINT32 force, BYTE *data)
1700{
1701	struct tsp_object *obj;
1702	struct tr_rsakey_obj *rsakey;
1703	TSS_RESULT result;
1704
1705	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1706		return TSPERR(TSS_E_INVALID_HANDLE);
1707
1708	rsakey = (struct tr_rsakey_obj *)obj->data;
1709
1710	if (!force && (obj->flags & TSS_OBJ_FLAG_KEY_SET)) {
1711		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1712		goto done;
1713	}
1714
1715	result = rsakey_set_pubkey(rsakey, data);
1716done:
1717	obj_list_put(&rsakey_list);
1718
1719	return result;
1720}
1721
1722TSS_RESULT
1723obj_rsakey_set_srk_pubkey(BYTE *pubkey)
1724{
1725	struct tsp_object *obj;
1726	struct obj_list *list = &rsakey_list;
1727	struct tr_rsakey_obj *rsakey;
1728	TSS_RESULT result;
1729
1730	MUTEX_LOCK(list->lock);
1731
1732	for (obj = list->head; obj; obj = obj->next) {
1733		rsakey = (struct tr_rsakey_obj *)obj->data;
1734
1735		/* we found the SRK, set this data as its public key */
1736		if (rsakey->tcsHandle == TPM_KEYHND_SRK) {
1737			result = rsakey_set_pubkey(rsakey, pubkey);
1738			MUTEX_UNLOCK(list->lock);
1739			return result;
1740		}
1741	}
1742
1743	MUTEX_UNLOCK(list->lock);
1744
1745	return TSPERR(TSS_E_INVALID_HANDLE);
1746}
1747
1748TSS_RESULT
1749obj_rsakey_set_privkey(TSS_HKEY hKey, UINT32 force, UINT32 size, BYTE *data)
1750{
1751	struct tsp_object *obj;
1752	struct tr_rsakey_obj *rsakey;
1753	TSS_RESULT result = TSS_SUCCESS;
1754	void *to_free;
1755
1756	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1757		return TSPERR(TSS_E_INVALID_HANDLE);
1758
1759	if (!force && (obj->flags & TSS_OBJ_FLAG_KEY_SET)) {
1760		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1761		goto done;
1762	}
1763
1764	rsakey = (struct tr_rsakey_obj *)obj->data;
1765
1766	to_free = rsakey->key.encData;
1767
1768	rsakey->key.encData = calloc(1, size);
1769	if (rsakey->key.encData == NULL) {
1770		rsakey->key.encData = to_free; // restore
1771		LogError("malloc of %u bytes failed.", size);
1772		result = TSPERR(TSS_E_OUTOFMEMORY);
1773		goto done;
1774	}
1775
1776	free(to_free);
1777	rsakey->key.encSize = size;
1778	memcpy(rsakey->key.encData, data, size);
1779done:
1780	obj_list_put(&rsakey_list);
1781
1782	return result;
1783}
1784
1785TSS_RESULT
1786obj_rsakey_set_pcr_data(TSS_HKEY hKey, TSS_HPCRS hPcrComposite)
1787{
1788	struct tsp_object *obj;
1789	struct tr_rsakey_obj *rsakey;
1790	TSS_RESULT result = TSS_SUCCESS;
1791	UINT32 pcrType, pcrSize;
1792	BYTE *pcrInfo;
1793
1794	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1795		return TSPERR(TSS_E_INVALID_HANDLE);
1796
1797	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
1798		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1799		goto done;
1800	}
1801
1802	rsakey = (struct tr_rsakey_obj *)obj->data;
1803
1804	/* passing in a pcrType of TSS_PCRS_STRUCT_DEFAULT will tell the pcr routine to create
1805	 * a structure matching the type of the hPcrComposite object */
1806	pcrType = TSS_PCRS_STRUCT_DEFAULT;
1807	if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrType, &pcrSize, &pcrInfo)))
1808		goto done;
1809
1810	rsakey->key.PCRInfo = pcrInfo;
1811	rsakey->key.PCRInfoSize = pcrSize;
1812done:
1813	obj_list_put(&rsakey_list);
1814
1815	return result;
1816}
1817
1818void
1819__tspi_rsakey_free(void *data)
1820{
1821	struct tr_rsakey_obj *rsakey = (struct tr_rsakey_obj *)data;
1822
1823	free(rsakey->key.algorithmParms.parms);
1824	free(rsakey->key.encData);
1825	free(rsakey->key.PCRInfo);
1826	free(rsakey->key.pubKey.key);
1827	free(rsakey);
1828}
1829
1830/* Remove an individual rsakey object from the rsakey list with handle
1831 * equal to hObject. Clean up the TSP's key handle table. */
1832TSS_RESULT
1833obj_rsakey_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
1834{
1835	TSS_RESULT result;
1836
1837	if ((result = obj_list_remove(&rsakey_list, &__tspi_rsakey_free, hObject, tspContext)))
1838		return result;
1839
1840	return TSS_SUCCESS;
1841}
1842
1843TSS_RESULT
1844obj_rsakey_get_by_pub(UINT32 pub_size, BYTE *pub, TSS_HKEY *hKey)
1845{
1846	struct obj_list *list = &rsakey_list;
1847	struct tsp_object *obj;
1848	struct tr_rsakey_obj *rsakey;
1849	TSS_RESULT result = TSS_SUCCESS;
1850
1851	MUTEX_LOCK(list->lock);
1852
1853	for (obj = list->head; obj; obj = obj->next) {
1854		rsakey = (struct tr_rsakey_obj *)obj->data;
1855
1856		if (rsakey->key.pubKey.keyLength == pub_size &&
1857		    !memcmp(&rsakey->key.pubKey.key, pub, pub_size)) {
1858			*hKey = obj->handle;
1859			goto done;
1860		}
1861	}
1862
1863	*hKey = 0;
1864done:
1865	MUTEX_UNLOCK(list->lock);
1866
1867	return result;
1868}
1869
1870TSS_RESULT
1871obj_rsakey_get_by_uuid(TSS_UUID *uuid, TSS_HKEY *hKey)
1872{
1873	struct obj_list *list = &rsakey_list;
1874	struct tsp_object *obj;
1875	struct tr_rsakey_obj *rsakey;
1876	TSS_RESULT result = TSS_SUCCESS;
1877
1878	MUTEX_LOCK(list->lock);
1879
1880	for (obj = list->head; obj; obj = obj->next) {
1881		rsakey = (struct tr_rsakey_obj *)obj->data;
1882
1883		if (!memcmp(&rsakey->uuid, uuid, sizeof(TSS_UUID))) {
1884			*hKey = obj->handle;
1885			goto done;
1886		}
1887	}
1888
1889	result = TSPERR(TSS_E_PS_KEY_NOTFOUND);
1890done:
1891	MUTEX_UNLOCK(list->lock);
1892
1893	return result;
1894}
1895
1896void
1897obj_rsakey_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext)
1898{
1899	struct tsp_object *obj;
1900	struct obj_list *list = &rsakey_list;
1901	struct tr_rsakey_obj *rsakey;
1902
1903	MUTEX_LOCK(list->lock);
1904
1905	for (obj = list->head; obj; obj = obj->next) {
1906		if (obj->tspContext != tspContext)
1907			continue;
1908
1909		rsakey = (struct tr_rsakey_obj *)obj->data;
1910		if (rsakey->usagePolicy == hPolicy)
1911			rsakey->usagePolicy = NULL_HPOLICY;
1912
1913		if (rsakey->migPolicy == hPolicy)
1914			rsakey->migPolicy = NULL_HPOLICY;
1915	}
1916
1917	MUTEX_UNLOCK(list->lock);
1918}
1919
1920#if 0
1921TSS_RESULT
1922obj_rsakey_get_transport_attribs(TSS_HKEY hKey, TCS_KEY_HANDLE *hTCSKey, TPM_DIGEST *pubDigest)
1923{
1924	struct tsp_object *obj;
1925	struct tr_rsakey_obj *rsakey;
1926	TSS_RESULT result;
1927	Trspi_HashCtx hashCtx;
1928
1929	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1930		return TSPERR(TSS_E_INVALID_HANDLE);
1931
1932	rsakey = (struct tr_rsakey_obj *)obj->data;
1933	*hTCSKey = rsakey->tcsHandle;
1934
1935	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1936	result |= Trspi_Hash_STORE_PUBKEY(&hashCtx, &rsakey->key.pubKey);
1937	result |= Trspi_HashFinal(&hashCtx, pubDigest->digest);
1938
1939	obj_list_put(&rsakey_list);
1940
1941	return result;
1942}
1943#endif
1944
1945#ifdef TSS_BUILD_CMK
1946TSS_BOOL
1947obj_rsakey_is_cmk(TSS_HKEY hKey)
1948{
1949	struct tsp_object *obj;
1950	struct tr_rsakey_obj *rsakey;
1951	TSS_BOOL answer = FALSE;
1952
1953	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1954		return answer;
1955
1956	rsakey = (struct tr_rsakey_obj *)obj->data;
1957	if (rsakey->type != TSS_KEY_STRUCT_KEY) {
1958		if (rsakey->key.keyFlags & TPM_MIGRATEAUTHORITY)
1959			answer = TRUE;
1960	}
1961
1962	obj_list_put(&rsakey_list);
1963
1964	return answer;
1965}
1966
1967TSS_RESULT
1968obj_rsakey_set_cmk(TSS_HKEY hKey, UINT32 cmk)
1969{
1970	struct tsp_object *obj;
1971	struct tr_rsakey_obj *rsakey;
1972	TSS_RESULT result = TSS_SUCCESS;
1973
1974	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
1975		return TSPERR(TSS_E_INVALID_HANDLE);
1976
1977	if (obj->flags & TSS_OBJ_FLAG_KEY_SET) {
1978		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1979		goto done;
1980	}
1981
1982	rsakey = (struct tr_rsakey_obj *)obj->data;
1983	if (rsakey->type == TSS_KEY_STRUCT_KEY) {
1984		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1985		goto done;
1986	}
1987
1988	if (cmk)
1989		rsakey->key.keyFlags |= TPM_MIGRATEAUTHORITY;
1990	else
1991		rsakey->key.keyFlags &= (~TPM_MIGRATEAUTHORITY);
1992
1993done:
1994	obj_list_put(&rsakey_list);
1995
1996	return result;
1997}
1998
1999TSS_RESULT
2000obj_rsakey_set_msa_approval(TSS_HKEY hKey, UINT32 blobSize, BYTE *blob)
2001{
2002	struct tsp_object *obj;
2003	struct tr_rsakey_obj *rsakey;
2004	TSS_RESULT result = TSS_SUCCESS;
2005
2006	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
2007		return TSPERR(TSS_E_INVALID_HANDLE);
2008
2009	rsakey = (struct tr_rsakey_obj *)obj->data;
2010
2011	if (blobSize != sizeof(rsakey->msaApproval.digest)) {
2012		result = TSPERR(TSS_E_BAD_PARAMETER);
2013		goto done;
2014	}
2015	memcpy(rsakey->msaApproval.digest, blob, sizeof(rsakey->msaApproval.digest));
2016
2017done:
2018	obj_list_put(&rsakey_list);
2019
2020	return result;
2021}
2022
2023TSS_RESULT
2024obj_rsakey_get_msa_approval(TSS_HKEY hKey, UINT32 *blobSize, BYTE **blob)
2025{
2026	struct tsp_object *obj;
2027	struct tr_rsakey_obj *rsakey;
2028	TSS_RESULT result = TSS_SUCCESS;
2029
2030	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
2031		return TSPERR(TSS_E_INVALID_HANDLE);
2032
2033	rsakey = (struct tr_rsakey_obj *)obj->data;
2034
2035	if ((*blob = calloc_tspi(obj->tspContext, sizeof(rsakey->msaApproval.digest))) == NULL) {
2036		LogError("malloc of %zd bytes failed.", sizeof(rsakey->msaApproval.digest));
2037		result = TSPERR(TSS_E_OUTOFMEMORY);
2038		goto done;
2039	}
2040	memcpy(*blob, rsakey->msaApproval.digest, sizeof(rsakey->msaApproval.digest));
2041	*blobSize = sizeof(rsakey->msaApproval.digest);
2042
2043done:
2044	obj_list_put(&rsakey_list);
2045
2046	return result;
2047}
2048
2049TSS_RESULT
2050obj_rsakey_set_msa_digest(TSS_HKEY hKey, UINT32 blobSize, BYTE *blob)
2051{
2052	struct tsp_object *obj;
2053	struct tr_rsakey_obj *rsakey;
2054	TSS_RESULT result = TSS_SUCCESS;
2055
2056	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
2057		return TSPERR(TSS_E_INVALID_HANDLE);
2058
2059	rsakey = (struct tr_rsakey_obj *)obj->data;
2060
2061	if (blobSize != sizeof(rsakey->msaDigest.digest)) {
2062		result = TSPERR(TSS_E_BAD_PARAMETER);
2063		goto done;
2064	}
2065	memcpy(rsakey->msaDigest.digest, blob, sizeof(rsakey->msaDigest.digest));
2066
2067done:
2068	obj_list_put(&rsakey_list);
2069
2070	return result;
2071}
2072
2073TSS_RESULT
2074obj_rsakey_get_msa_digest(TSS_HKEY hKey, UINT32 *blobSize, BYTE **blob)
2075{
2076	struct tsp_object *obj;
2077	struct tr_rsakey_obj *rsakey;
2078	TSS_RESULT result = TSS_SUCCESS;
2079
2080	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
2081		return TSPERR(TSS_E_INVALID_HANDLE);
2082
2083	rsakey = (struct tr_rsakey_obj *)obj->data;
2084
2085	if ((*blob = calloc_tspi(obj->tspContext, sizeof(rsakey->msaDigest.digest))) == NULL) {
2086		LogError("malloc of %zd bytes failed.", sizeof(rsakey->msaDigest.digest));
2087		result = TSPERR(TSS_E_OUTOFMEMORY);
2088		goto done;
2089	}
2090	memcpy(*blob, rsakey->msaDigest.digest, sizeof(rsakey->msaDigest.digest));
2091	*blobSize = sizeof(rsakey->msaDigest.digest);
2092
2093done:
2094	obj_list_put(&rsakey_list);
2095
2096	return result;
2097}
2098#endif
2099
2100TSS_RESULT
2101obj_rsakey_get_ownerevict(TSS_HKEY hKey, UINT32 *value)
2102{
2103	struct tsp_object *obj;
2104	struct tr_rsakey_obj *rsakey;
2105
2106	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
2107		return TSPERR(TSS_E_INVALID_HANDLE);
2108
2109	rsakey = (struct tr_rsakey_obj *)obj->data;
2110	*value = rsakey->flags & TSS_RSAKEY_FLAG_OWNEREVICT;
2111
2112	obj_list_put(&rsakey_list);
2113
2114	return TSS_SUCCESS;
2115}
2116
2117TSS_RESULT
2118obj_rsakey_set_ownerevict(TSS_HKEY hKey, TSS_BOOL value)
2119{
2120	struct tsp_object *obj;
2121	struct tr_rsakey_obj *rsakey;
2122
2123	if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL)
2124		return TSPERR(TSS_E_INVALID_HANDLE);
2125
2126	rsakey = (struct tr_rsakey_obj *)obj->data;
2127
2128	if (value)
2129		rsakey->flags |= TSS_RSAKEY_FLAG_OWNEREVICT;
2130	else
2131		rsakey->flags &= ~TSS_RSAKEY_FLAG_OWNEREVICT;
2132
2133	obj_list_put(&rsakey_list);
2134
2135	return TSS_SUCCESS;
2136}
2137