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
17#include "trousers/tss.h"
18#include "trousers/trousers.h"
19#include "trousers_types.h"
20#include "spi_utils.h"
21#include "capabilities.h"
22#include "tsplog.h"
23#include "obj.h"
24#include "tsp_delegate.h"
25#include "authsess.h"
26
27
28TSS_RESULT
29obj_policy_add(TSS_HCONTEXT tsp_context, UINT32 type, TSS_HOBJECT *phObject)
30{
31	struct tr_policy_obj *policy;
32	TSS_RESULT result;
33
34	if ((policy = calloc(1, sizeof(struct tr_policy_obj))) == NULL) {
35		LogError("malloc of %zd bytes failed", sizeof(struct tr_policy_obj));
36		return TSPERR(TSS_E_OUTOFMEMORY);
37	}
38
39	policy->type = type;
40#ifndef TSS_SPEC_COMPLIANCE
41	policy->SecretMode = TSS_SECRET_MODE_NONE;
42#else
43	policy->SecretMode = TSS_SECRET_MODE_POPUP;
44#endif
45	/* The policy object will inherit this attribute from the context */
46	if ((result = obj_context_get_hash_mode(tsp_context, &policy->hashMode))) {
47		free(policy);
48		return result;
49	}
50	policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS;
51#ifdef TSS_BUILD_DELEGATION
52	policy->delegationType = TSS_DELEGATIONTYPE_NONE;
53#endif
54
55	if ((result = obj_list_add(&policy_list, tsp_context, 0, policy, phObject))) {
56		free(policy);
57		return result;
58	}
59
60	return TSS_SUCCESS;
61}
62
63void
64__tspi_policy_free(void *data)
65{
66	struct tr_policy_obj *policy = (struct tr_policy_obj *)data;
67
68	free(policy->popupString);
69#ifdef TSS_BUILD_DELEGATION
70	free(policy->delegationBlob);
71#endif
72	free(policy);
73}
74
75TSS_RESULT
76obj_policy_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
77{
78	TSS_RESULT result;
79
80	if ((result = obj_list_remove(&policy_list, &__tspi_policy_free, hObject, tspContext)))
81		return result;
82
83	obj_lists_remove_policy_refs(hObject, tspContext);
84
85	return TSS_SUCCESS;
86}
87
88TSS_BOOL
89obj_is_policy(TSS_HOBJECT hObject)
90{
91	TSS_BOOL answer = FALSE;
92
93	if ((obj_list_get_obj(&policy_list, hObject))) {
94		answer = TRUE;
95		obj_list_put(&policy_list);
96	}
97
98	return answer;
99}
100
101TSS_RESULT
102obj_policy_get_type(TSS_HPOLICY hPolicy, UINT32 *type)
103{
104	struct tsp_object *obj;
105	struct tr_policy_obj *policy;
106
107	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
108		return TSPERR(TSS_E_INVALID_HANDLE);
109
110	policy = (struct tr_policy_obj *)obj->data;
111	*type = policy->type;
112
113	obj_list_put(&policy_list);
114
115	return TSS_SUCCESS;
116}
117
118TSS_RESULT
119obj_policy_set_type(TSS_HPOLICY hPolicy, UINT32 type)
120{
121	struct tsp_object *obj;
122	struct tr_policy_obj *policy;
123
124	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
125		return TSPERR(TSS_E_INVALID_HANDLE);
126
127	policy = (struct tr_policy_obj *)obj->data;
128	policy->type = type;
129
130	obj_list_put(&policy_list);
131
132	return TSS_SUCCESS;
133}
134
135TSS_RESULT
136obj_policy_get_tsp_context(TSS_HPOLICY hPolicy, TSS_HCONTEXT *tspContext)
137{
138	struct tsp_object *obj;
139
140	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
141		return TSPERR(TSS_E_INVALID_HANDLE);
142
143	*tspContext = obj->tspContext;
144
145	obj_list_put(&policy_list);
146
147	return TSS_SUCCESS;
148}
149
150TSS_RESULT
151obj_policy_do_hmac(TSS_HPOLICY hPolicy, TSS_HOBJECT hAuthorizedObject,
152		   TSS_BOOL returnOrVerify, UINT32 ulPendingFunction,
153		   TSS_BOOL continueUse, UINT32 ulSizeNonces,
154		   BYTE *rgbNonceEven, BYTE *rgbNonceOdd,
155		   BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP,
156		   UINT32 ulSizeDigestHmac, BYTE *rgbParamDigest,
157		   BYTE *rgbHmacData)
158{
159	struct tsp_object *obj;
160	struct tr_policy_obj *policy;
161	TSS_RESULT result = TSS_SUCCESS;
162
163	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
164		return TSPERR(TSS_E_INVALID_HANDLE);
165
166	policy = (struct tr_policy_obj *)obj->data;
167
168	result = policy->Tspicb_CallbackHMACAuth(
169			policy->hmacAppData, hAuthorizedObject,
170			returnOrVerify,
171			ulPendingFunction,
172			continueUse,
173			ulSizeNonces,
174			rgbNonceEven,
175			rgbNonceOdd,
176			rgbNonceEvenOSAP, rgbNonceOddOSAP, ulSizeDigestHmac,
177			rgbParamDigest,
178			rgbHmacData);
179
180	obj_list_put(&policy_list);
181
182	return result;
183}
184
185TSS_RESULT
186obj_policy_get_secret(TSS_HPOLICY hPolicy, TSS_BOOL ctx, TCPA_SECRET *secret)
187{
188	struct tsp_object *obj;
189	struct tr_policy_obj *policy;
190	TSS_RESULT result = TSS_SUCCESS;
191	TCPA_SECRET null_secret;
192
193	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
194		return TSPERR(TSS_E_INVALID_HANDLE);
195
196	policy = (struct tr_policy_obj *)obj->data;
197
198	memset(&null_secret, 0, sizeof(TCPA_SECRET));
199
200	switch (policy->SecretMode) {
201		case TSS_SECRET_MODE_POPUP:
202			/* if the secret is still NULL, grab it using the GUI */
203			if (policy->SecretSet == FALSE) {
204				if ((result = popup_GetSecret(ctx,
205							      policy->hashMode,
206							      policy->popupString,
207							      policy->Secret)))
208					break;
209			}
210			policy->SecretSet = TRUE;
211			/* fall through */
212		case TSS_SECRET_MODE_PLAIN:
213		case TSS_SECRET_MODE_SHA1:
214			if (policy->SecretSet == FALSE) {
215				result = TSPERR(TSS_E_POLICY_NO_SECRET);
216				break;
217			}
218
219			memcpy(secret, policy->Secret, sizeof(TCPA_SECRET));
220			break;
221		case TSS_SECRET_MODE_NONE:
222			memcpy(secret, &null_secret, sizeof(TCPA_SECRET));
223			break;
224		default:
225			result = TSPERR(TSS_E_POLICY_NO_SECRET);
226			break;
227	}
228#ifdef TSS_DEBUG
229	if (!result) {
230		LogDebug("Got a secret:");
231		LogDebugData(20, (BYTE *)secret);
232	}
233#endif
234	obj_list_put(&policy_list);
235
236	return result;
237}
238
239TSS_RESULT
240obj_policy_flush_secret(TSS_HPOLICY hPolicy)
241{
242	struct tsp_object *obj;
243	struct tr_policy_obj *policy;
244
245	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
246		return TSPERR(TSS_E_INVALID_HANDLE);
247
248	policy = (struct tr_policy_obj *)obj->data;
249
250	memset(&policy->Secret, 0, policy->SecretSize);
251	policy->SecretSet = FALSE;
252
253	obj_list_put(&policy_list);
254
255	return TSS_SUCCESS;
256}
257
258TSS_RESULT
259obj_policy_set_secret_object(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size,
260			     TCPA_DIGEST *digest, TSS_BOOL set)
261{
262	struct tsp_object *obj;
263	struct tr_policy_obj *policy;
264	TSS_RESULT result = TSS_SUCCESS;
265
266	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
267		return TSPERR(TSS_E_INVALID_HANDLE);
268
269	policy = (struct tr_policy_obj *)obj->data;
270
271	/* if this is going to be a callback policy, the
272	 * callbacks need to already be set. (See TSS 1.1b
273	 * spec pg. 62). */
274	if (mode == TSS_SECRET_MODE_CALLBACK) {
275		if (policy->Tspicb_CallbackHMACAuth == NULL) {
276			result = TSPERR(TSS_E_FAIL);
277			goto done;
278		}
279	}
280
281	if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) {
282		policy->SecretCounter = policy->SecretTimeStamp;
283	} else if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
284		time_t t = time(NULL);
285		if (t == ((time_t)-1)) {
286			LogError("time failed: %s", strerror(errno));
287			result = TSPERR(TSS_E_INTERNAL_ERROR);
288			goto done;
289		}
290
291		policy->SecretTimeStamp = t;
292	}
293
294	memcpy(policy->Secret, digest, size);
295	policy->SecretMode = mode;
296	policy->SecretSize = size;
297	policy->SecretSet = set;
298done:
299	obj_list_put(&policy_list);
300
301	return result;
302}
303
304TSS_RESULT
305obj_policy_is_secret_set(TSS_HPOLICY hPolicy, TSS_BOOL *secretSet)
306{
307	struct tsp_object *obj;
308	struct tr_policy_obj *policy;
309	TSS_RESULT result = TSS_SUCCESS;
310
311	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
312		return TSPERR(TSS_E_INVALID_HANDLE);
313
314	policy = (struct tr_policy_obj *)obj->data;
315
316	*secretSet = policy->SecretSet;
317	obj_list_put(&policy_list);
318
319	return result;
320}
321
322
323TSS_RESULT
324obj_policy_set_secret(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size, BYTE *data)
325{
326	TCPA_DIGEST digest;
327	UINT32 secret_size = 0;
328	TSS_BOOL secret_set = TRUE;
329	TSS_RESULT result;
330
331	memset(&digest.digest, 0, sizeof(TCPA_DIGEST));
332
333	switch (mode) {
334		case TSS_SECRET_MODE_PLAIN:
335			if ((result = Trspi_Hash(TSS_HASH_SHA1, size, data,
336						 (BYTE *)&digest.digest)))
337				return result;
338			secret_size = TCPA_SHA1_160_HASH_LEN;
339			break;
340		case TSS_SECRET_MODE_SHA1:
341			if (size != TCPA_SHA1_160_HASH_LEN)
342				return TSPERR(TSS_E_BAD_PARAMETER);
343
344			memcpy(&digest.digest, data, size);
345			secret_size = TCPA_SHA1_160_HASH_LEN;
346			break;
347		case TSS_SECRET_MODE_POPUP:
348		case TSS_SECRET_MODE_NONE:
349			secret_set = FALSE;
350		case TSS_SECRET_MODE_CALLBACK:
351			break;
352		default:
353			return TSPERR(TSS_E_BAD_PARAMETER);
354	}
355
356	return obj_policy_set_secret_object(hPolicy, mode, secret_size,
357					    &digest, secret_set);
358}
359
360TSS_RESULT
361obj_policy_get_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, UINT32 *cb)
362{
363#ifndef __LP64__
364	struct tsp_object *obj;
365	struct tr_policy_obj *policy;
366	TSS_RESULT result = TSS_SUCCESS;
367
368	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
369		return TSPERR(TSS_E_INVALID_HANDLE);
370
371	policy = (struct tr_policy_obj *)obj->data;
372
373	switch (type) {
374		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
375			*cb = (UINT32)policy->Tspicb_CallbackHMACAuth;
376			break;
377		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
378			*cb = (UINT32)policy->Tspicb_CallbackXorEnc;
379			break;
380		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
381			*cb = (UINT32)policy->Tspicb_CallbackTakeOwnership;
382			break;
383		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
384			*cb = (UINT32)policy->Tspicb_CallbackChangeAuthAsym;
385			break;
386		default:
387			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
388			break;
389	}
390
391	obj_list_put(&policy_list);
392
393	return result;
394#else
395	return TSPERR(TSS_E_FAIL);
396#endif
397}
398
399TSS_RESULT
400obj_policy_set_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, TSS_FLAG app_data, UINT32 cb)
401{
402#ifndef __LP64__
403	struct tsp_object *obj;
404	struct tr_policy_obj *policy;
405	TSS_RESULT result = TSS_SUCCESS;
406
407	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
408		return TSPERR(TSS_E_INVALID_HANDLE);
409
410	policy = (struct tr_policy_obj *)obj->data;
411
412	switch (type) {
413		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
414			policy->Tspicb_CallbackHMACAuth = (PVOID)cb;
415			policy->hmacAppData = (PVOID)app_data;
416			break;
417		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
418			policy->Tspicb_CallbackXorEnc = (PVOID)cb;
419			policy->xorAppData = (PVOID)app_data;
420			break;
421		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
422			policy->Tspicb_CallbackTakeOwnership = (PVOID)cb;
423			policy->takeownerAppData = (PVOID)app_data;
424			break;
425		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
426			policy->Tspicb_CallbackChangeAuthAsym = (PVOID)cb;
427			policy->changeauthAppData = (PVOID)app_data;
428			break;
429		default:
430			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
431			break;
432	}
433
434	obj_list_put(&policy_list);
435
436	return result;
437#else
438	return TSPERR(TSS_E_FAIL);
439#endif
440}
441
442TSS_RESULT
443obj_policy_set_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, BYTE *in)
444{
445	struct tsp_object *obj;
446	struct tr_policy_obj *policy;
447	TSS_RESULT result = TSS_SUCCESS;
448	TSS_CALLBACK *cb = (TSS_CALLBACK *)in;
449
450	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
451		return TSPERR(TSS_E_INVALID_HANDLE);
452
453	policy = (struct tr_policy_obj *)obj->data;
454
455	switch (flag) {
456		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
457			if (!cb) {
458				policy->Tspicb_CallbackHMACAuth = NULL;
459				break;
460			}
461
462			policy->Tspicb_CallbackHMACAuth =
463				(TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL,
464				UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *,
465				BYTE *, BYTE *, UINT32, BYTE *, BYTE *))
466				cb->callback;
467			policy->hmacAppData = cb->appData;
468			policy->hmacAlg = cb->alg;
469			break;
470		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
471			if (!cb) {
472				policy->Tspicb_CallbackXorEnc = NULL;
473				break;
474			}
475
476			policy->Tspicb_CallbackXorEnc =
477				(TSS_RESULT (*)(PVOID, TSS_HOBJECT,
478				TSS_HOBJECT, TSS_FLAG, UINT32, BYTE *, BYTE *,
479				BYTE *, BYTE *, UINT32, BYTE *, BYTE *))
480				cb->callback;
481			policy->xorAppData = cb->appData;
482			policy->xorAlg = cb->alg;
483			break;
484		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
485			if (!cb) {
486				policy->Tspicb_CallbackTakeOwnership = NULL;
487				break;
488			}
489
490			policy->Tspicb_CallbackTakeOwnership =
491				(TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY,
492				UINT32, BYTE *))cb->callback;
493			policy->takeownerAppData = cb->appData;
494			policy->takeownerAlg = cb->alg;
495			break;
496		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
497			if (!cb) {
498				policy->Tspicb_CallbackChangeAuthAsym = NULL;
499				break;
500			}
501
502			policy->Tspicb_CallbackChangeAuthAsym =
503				(TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY,
504				UINT32, UINT32, BYTE *, BYTE *))cb->callback;
505			policy->changeauthAppData = cb->appData;
506			policy->changeauthAlg = cb->alg;
507			break;
508#ifdef TSS_BUILD_SEALX
509		case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
510			if (!cb) {
511				policy->Tspicb_CallbackSealxMask = NULL;
512				policy->sealxAppData = NULL;
513				policy->sealxAlg = 0;
514				break;
515			}
516
517			policy->Tspicb_CallbackSealxMask =
518				(TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA,
519				TSS_ALGORITHM_ID, UINT32, BYTE *, BYTE *, BYTE *, BYTE *,
520				UINT32, BYTE *, BYTE *))cb->callback;
521			policy->sealxAppData = cb->appData;
522			policy->sealxAlg = cb->alg;
523			break;
524#endif
525		default:
526			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
527			break;
528	}
529
530	obj_list_put(&policy_list);
531
532	return result;
533}
534
535TSS_RESULT
536obj_policy_get_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, UINT32 *size, BYTE **out)
537{
538	struct tsp_object *obj;
539	struct tr_policy_obj *policy;
540	TSS_RESULT result = TSS_SUCCESS;
541	TSS_CALLBACK *cb;
542
543	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
544		return TSPERR(TSS_E_INVALID_HANDLE);
545
546	policy = (struct tr_policy_obj *)obj->data;
547
548	if ((cb = calloc_tspi(obj->tspContext, sizeof(TSS_CALLBACK))) == NULL) {
549		LogError("malloc of %zd bytes failed.", sizeof(TSS_CALLBACK));
550		result = TSPERR(TSS_E_OUTOFMEMORY);
551		goto done;
552	}
553
554	switch (flag) {
555		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
556			cb->callback = policy->Tspicb_CallbackHMACAuth;
557			cb->appData = policy->hmacAppData;
558			cb->alg = policy->hmacAlg;
559			*size = sizeof(TSS_CALLBACK);
560			*out = (BYTE *)cb;
561			break;
562		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
563			cb->callback = policy->Tspicb_CallbackXorEnc;
564			cb->appData = policy->xorAppData;
565			cb->alg = policy->xorAlg;
566			*size = sizeof(TSS_CALLBACK);
567			*out = (BYTE *)cb;
568			break;
569		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
570			cb->callback = policy->Tspicb_CallbackTakeOwnership;
571			cb->appData = policy->takeownerAppData;
572			cb->alg = policy->takeownerAlg;
573			*size = sizeof(TSS_CALLBACK);
574			*out = (BYTE *)cb;
575			break;
576		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
577			cb->callback = policy->Tspicb_CallbackChangeAuthAsym;
578			cb->appData = policy->changeauthAppData;
579			cb->alg = policy->changeauthAlg;
580			*size = sizeof(TSS_CALLBACK);
581			*out = (BYTE *)cb;
582			break;
583#ifdef TSS_BUILD_SEALX
584		case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
585			cb->callback = policy->Tspicb_CallbackSealxMask;
586			cb->appData = policy->sealxAppData;
587			cb->alg = policy->sealxAlg;
588			*size = sizeof(TSS_CALLBACK);
589			*out = (BYTE *)cb;
590			break;
591#endif
592		default:
593			free_tspi(obj->tspContext, cb);
594			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
595			break;
596	}
597done:
598	obj_list_put(&policy_list);
599
600	return result;
601}
602
603TSS_RESULT
604obj_policy_get_lifetime(TSS_HPOLICY hPolicy, UINT32 *lifetime)
605{
606	struct tsp_object *obj;
607	struct tr_policy_obj *policy;
608
609	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
610		return TSPERR(TSS_E_INVALID_HANDLE);
611
612	policy = (struct tr_policy_obj *)obj->data;
613	*lifetime = policy->SecretLifetime;
614
615	obj_list_put(&policy_list);
616
617	return TSS_SUCCESS;
618}
619
620TSS_RESULT
621obj_policy_set_lifetime(TSS_HPOLICY hPolicy, UINT32 type, UINT32 value)
622{
623	struct tsp_object *obj;
624	struct tr_policy_obj *policy;
625	TSS_RESULT result = TSS_SUCCESS;
626	time_t t;
627
628	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
629		return TSPERR(TSS_E_INVALID_HANDLE);
630
631	policy = (struct tr_policy_obj *)obj->data;
632
633	switch (type) {
634		case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS:
635			policy->SecretCounter = 0;
636			policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS;
637			policy->SecretTimeStamp = 0;
638			break;
639		case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER:
640			/* Both SecretCounter and SecretTimeStamp will receive value. Every time the
641			 * policy is used, SecretCounter will be decremented. Each time SetSecret is
642			 * called, SecretCounter will get the value stored in SecretTimeStamp */
643			policy->SecretCounter = value;
644			policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER;
645			policy->SecretTimeStamp = value;
646			break;
647		case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER:
648			t = time(NULL);
649			if (t == ((time_t)-1)) {
650				LogError("time failed: %s", strerror(errno));
651				result = TSPERR(TSS_E_INTERNAL_ERROR);
652				break;
653			}
654
655			/* For mode time, we'll use the SecretCounter variable to hold the number
656			 * of seconds we're valid and the SecretTimeStamp var to record the current
657			 * timestamp. This should protect against overflows. */
658			policy->SecretCounter = value;
659			policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER;
660			policy->SecretTimeStamp = t;
661			break;
662		default:
663			result = TSPERR(TSS_E_BAD_PARAMETER);
664			break;
665	}
666
667	obj_list_put(&policy_list);
668
669	return result;
670}
671
672TSS_RESULT
673obj_policy_get_mode(TSS_HPOLICY hPolicy, UINT32 *mode)
674{
675	struct tsp_object *obj;
676	struct tr_policy_obj *policy;
677
678	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
679		return TSPERR(TSS_E_INVALID_HANDLE);
680
681	policy = (struct tr_policy_obj *)obj->data;
682	*mode = policy->SecretMode;
683
684	obj_list_put(&policy_list);
685
686	return TSS_SUCCESS;
687}
688
689TSS_RESULT
690obj_policy_get_counter(TSS_HPOLICY hPolicy, UINT32 *counter)
691{
692	struct tsp_object *obj;
693	struct tr_policy_obj *policy;
694	TSS_RESULT result = TSS_SUCCESS;
695
696	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
697		return TSPERR(TSS_E_INVALID_HANDLE);
698
699	policy = (struct tr_policy_obj *)obj->data;
700
701	if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER)
702		*counter = policy->SecretCounter;
703	else
704		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
705
706	obj_list_put(&policy_list);
707
708	return result;
709}
710
711TSS_RESULT
712obj_policy_dec_counter(TSS_HPOLICY hPolicy)
713{
714	struct tsp_object *obj;
715	struct tr_policy_obj *policy;
716
717	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
718		return TSPERR(TSS_E_INVALID_HANDLE);
719
720	policy = (struct tr_policy_obj *)obj->data;
721
722	/* Only decrement if SecretCounter > 0, otherwise it could loop and become valid again */
723	if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER &&
724	    policy->SecretCounter > 0) {
725		policy->SecretCounter--;
726	}
727
728	obj_list_put(&policy_list);
729
730	return TSS_SUCCESS;
731}
732
733/* return a unicode string to the Tspi_GetAttribData function */
734TSS_RESULT
735obj_policy_get_string(TSS_HPOLICY hPolicy, UINT32 *size, BYTE **data)
736{
737	TSS_RESULT result = TSS_SUCCESS;
738	BYTE *utf_string;
739	UINT32 utf_size;
740	struct tsp_object *obj;
741	struct tr_policy_obj *policy;
742
743	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
744		return TSPERR(TSS_E_INVALID_HANDLE);
745
746	policy = (struct tr_policy_obj *)obj->data;
747
748	*size = policy->popupStringLength;
749	if (policy->popupStringLength == 0) {
750		*data = NULL;
751	} else {
752		utf_size = policy->popupStringLength;
753		utf_string = Trspi_Native_To_UNICODE(policy->popupString,
754						     &utf_size);
755		if (utf_string == NULL) {
756			result = TSPERR(TSS_E_INTERNAL_ERROR);
757			goto done;
758		}
759
760		*data = calloc_tspi(obj->tspContext, utf_size);
761		if (*data == NULL) {
762			free(utf_string);
763			LogError("malloc of %d bytes failed.", utf_size);
764			result = TSPERR(TSS_E_OUTOFMEMORY);
765			goto done;
766		}
767
768		*size = utf_size;
769		memcpy(*data, utf_string, utf_size);
770		free(utf_string);
771	}
772
773done:
774	obj_list_put(&policy_list);
775
776	return result;
777}
778
779TSS_RESULT
780obj_policy_set_string(TSS_HPOLICY hPolicy, UINT32 size, BYTE *data)
781{
782	struct tsp_object *obj;
783	struct tr_policy_obj *policy;
784
785	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
786		return TSPERR(TSS_E_INVALID_HANDLE);
787
788	policy = (struct tr_policy_obj *)obj->data;
789
790	free(policy->popupString);
791	policy->popupString = data;
792	policy->popupStringLength = size;
793
794	obj_list_put(&policy_list);
795
796	return TSS_SUCCESS;
797}
798
799TSS_RESULT
800obj_policy_get_secs_until_expired(TSS_HPOLICY hPolicy, UINT32 *secs)
801{
802	TSS_RESULT result = TSS_SUCCESS;
803	struct tsp_object *obj;
804	struct tr_policy_obj *policy;
805	int seconds_elapsed;
806	time_t t;
807
808	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
809		return TSPERR(TSS_E_INVALID_HANDLE);
810
811	policy = (struct tr_policy_obj *)obj->data;
812
813	if (policy->SecretLifetime != TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
814		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
815		goto done;
816	}
817
818	if ((t = time(NULL)) == ((time_t)-1)) {
819		LogError("time failed: %s", strerror(errno));
820		result = TSPERR(TSS_E_INTERNAL_ERROR);
821		goto done;
822	}
823	/* curtime - SecretTimeStamp is the number of seconds elapsed since we started the timer.
824	 * SecretCounter is the number of seconds the secret is valid.  If
825	 * seconds_elspased > SecretCounter, we've expired. */
826	seconds_elapsed = t - policy->SecretTimeStamp;
827	if ((UINT32)seconds_elapsed >= policy->SecretCounter) {
828		*secs = 0;
829	} else {
830		*secs = policy->SecretCounter - seconds_elapsed;
831	}
832
833done:
834	obj_list_put(&policy_list);
835
836	return result;
837}
838
839TSS_RESULT
840policy_has_expired(struct tr_policy_obj *policy, TSS_BOOL *answer)
841{
842	switch (policy->SecretLifetime) {
843	case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS:
844		*answer = FALSE;
845		break;
846	case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER:
847		*answer = (policy->SecretCounter == 0 ? TRUE : FALSE);
848		break;
849	case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER:
850	{
851		int seconds_elapsed;
852		time_t t = time(NULL);
853
854		if (t == ((time_t)-1)) {
855			LogError("time failed: %s", strerror(errno));
856			return TSPERR(TSS_E_INTERNAL_ERROR);
857		}
858		/* curtime - SecretTimer is the number of seconds elapsed since we
859		 * started the timer. SecretCounter is the number of seconds the
860		 * secret is valid.  If seconds_elspased > SecretCounter, we've
861		 * expired.
862		 */
863		seconds_elapsed = t - policy->SecretTimeStamp;
864		*answer = ((UINT32)seconds_elapsed >= policy->SecretCounter ? TRUE : FALSE);
865		break;
866	}
867	default:
868		LogError("policy has an undefined secret lifetime!");
869		return TSPERR(TSS_E_INVALID_OBJ_ACCESS);
870	}
871
872	return TSS_SUCCESS;
873}
874
875TSS_RESULT
876obj_policy_has_expired(TSS_HPOLICY hPolicy, TSS_BOOL *answer)
877{
878	struct tsp_object *obj;
879	struct tr_policy_obj *policy;
880	TSS_RESULT result;
881
882	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
883		return TSPERR(TSS_E_INVALID_HANDLE);
884
885	policy = (struct tr_policy_obj *)obj->data;
886
887	result = policy_has_expired(policy, answer);
888
889	obj_list_put(&policy_list);
890
891	return result;
892}
893
894TSS_RESULT
895obj_policy_get_xsap_params(TSS_HPOLICY hPolicy,
896			   TPM_COMMAND_CODE command,
897			   TPM_ENTITY_TYPE *et,
898			   UINT32 *entity_value_size,
899			   BYTE **entity_value,
900			   BYTE *secret,
901			   TSS_CALLBACK *cb_xor,
902			   TSS_CALLBACK *cb_hmac,
903			   TSS_CALLBACK *cb_sealx,
904			   UINT32 *mode,
905			   TSS_BOOL new_secret)
906{
907	struct tsp_object *obj;
908	struct tr_policy_obj *policy;
909	TSS_RESULT result;
910	TSS_BOOL answer = FALSE;
911
912	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
913		return TSPERR(TSS_E_INVALID_HANDLE);
914
915	policy = (struct tr_policy_obj *)obj->data;
916
917	if ((result = policy_has_expired(policy, &answer)))
918		goto done;
919
920	if (answer) {
921		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
922		goto done;
923	}
924#ifdef TSS_BUILD_DELEGATION
925	/* if the delegation index or blob is set, check to see if the command is delegated, if so,
926	 * return the blob or index as the secret data */
927	if (command && (policy->delegationType != TSS_DELEGATIONTYPE_NONE)) {
928		if (policy->delegationBlob) {
929			if ((*entity_value = malloc(policy->delegationBlobLength)) == NULL) {
930				LogError("malloc of %u bytes failed.",
931					 policy->delegationBlobLength);
932				result = TSPERR(TSS_E_OUTOFMEMORY);
933				goto done;
934			}
935
936			memcpy(*entity_value, policy->delegationBlob, policy->delegationBlobLength);
937			*entity_value_size = policy->delegationBlobLength;
938			if (policy->delegationType == TSS_DELEGATIONTYPE_OWNER)
939				*et = TPM_ET_DEL_OWNER_BLOB;
940			else
941				*et = TPM_ET_DEL_KEY_BLOB;
942		} else {
943			if ((*entity_value = malloc(sizeof(UINT32))) == NULL) {
944				LogError("malloc of %zd bytes failed.", sizeof(UINT32));
945				result = TSPERR(TSS_E_OUTOFMEMORY);
946				goto done;
947			}
948
949			*(UINT32 *)entity_value = policy->delegationIndex;
950			*entity_value_size = sizeof(UINT32);
951			*et = TPM_ET_DEL_ROW;
952		}
953	}
954#endif
955	/* Either this is a policy set to mode callback, in which case both xor and hmac addresses
956	 * must be set, or this is an encrypted data object's policy, where its mode is independent
957	 * of whether a sealx callback is set */
958	if (policy->SecretMode == TSS_SECRET_MODE_CALLBACK && cb_xor && cb_hmac) {
959		if ((policy->Tspicb_CallbackXorEnc && !policy->Tspicb_CallbackHMACAuth) ||
960		    (!policy->Tspicb_CallbackXorEnc && policy->Tspicb_CallbackHMACAuth)) {
961			result = TSPERR(TSS_E_INTERNAL_ERROR);
962			goto done;
963		}
964
965		cb_xor->callback = policy->Tspicb_CallbackXorEnc;
966		cb_xor->appData = policy->xorAppData;
967		cb_xor->alg = policy->xorAlg;
968
969		cb_hmac->callback = policy->Tspicb_CallbackHMACAuth;
970		cb_hmac->appData = policy->hmacAppData;
971		cb_hmac->alg = policy->hmacAlg;
972#ifdef TSS_BUILD_SEALX
973	} else if (cb_sealx && policy->Tspicb_CallbackSealxMask) {
974		cb_sealx->callback = policy->Tspicb_CallbackSealxMask;
975		cb_sealx->appData = policy->sealxAppData;
976		cb_sealx->alg = policy->sealxAlg;
977#endif
978	}
979
980	if ((policy->SecretMode == TSS_SECRET_MODE_POPUP) &&
981	    (policy->SecretSet == FALSE)) {
982		if ((result = popup_GetSecret(new_secret,
983					      policy->hashMode,
984					      policy->popupString,
985					      policy->Secret)))
986			goto done;
987			policy->SecretSet = TRUE;
988	}
989	memcpy(secret, policy->Secret, TPM_SHA1_160_HASH_LEN);
990	*mode = policy->SecretMode;
991done:
992	obj_list_put(&policy_list);
993
994	return result;
995}
996
997TSS_RESULT
998obj_policy_do_xor(TSS_HPOLICY hPolicy,
999		  TSS_HOBJECT hOSAPObject, TSS_HOBJECT hObject,
1000		  TSS_FLAG PurposeSecret, UINT32 ulSizeNonces,
1001		  BYTE *rgbNonceEven, BYTE *rgbNonceOdd,
1002		  BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP,
1003		  UINT32 ulSizeEncAuth, BYTE *rgbEncAuthUsage,
1004		  BYTE *rgbEncAuthMigration)
1005{
1006	TSS_RESULT result;
1007	struct tsp_object *obj;
1008	struct tr_policy_obj *policy;
1009
1010	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1011		return TSPERR(TSS_E_INVALID_HANDLE);
1012
1013	policy = (struct tr_policy_obj *)obj->data;
1014
1015	result = policy->Tspicb_CallbackXorEnc(policy->xorAppData,
1016			hOSAPObject, hObject,
1017			PurposeSecret, ulSizeNonces,
1018			rgbNonceEven, rgbNonceOdd,
1019			rgbNonceEvenOSAP, rgbNonceOddOSAP,
1020			ulSizeEncAuth,
1021			rgbEncAuthUsage, rgbEncAuthMigration);
1022
1023	obj_list_put(&policy_list);
1024
1025	return result;
1026}
1027
1028TSS_RESULT
1029obj_policy_do_takeowner(TSS_HPOLICY hPolicy,
1030			TSS_HOBJECT hObject, TSS_HKEY hObjectPubKey,
1031			UINT32 ulSizeEncAuth, BYTE *rgbEncAuth)
1032{
1033	TSS_RESULT result;
1034	struct tsp_object *obj;
1035	struct tr_policy_obj *policy;
1036
1037	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1038		return TSPERR(TSS_E_INVALID_HANDLE);
1039
1040	policy = (struct tr_policy_obj *)obj->data;
1041
1042	result = policy->Tspicb_CallbackTakeOwnership(
1043			policy->takeownerAppData,
1044			hObject, hObjectPubKey, ulSizeEncAuth,
1045			rgbEncAuth);
1046
1047	obj_list_put(&policy_list);
1048
1049	return result;
1050}
1051
1052TSS_RESULT
1053obj_policy_get_hash_mode(TSS_HPOLICY hPolicy, UINT32 *mode)
1054{
1055	struct tsp_object *obj;
1056	struct tr_policy_obj *policy;
1057
1058	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1059		return TSPERR(TSS_E_INVALID_HANDLE);
1060
1061	policy = (struct tr_policy_obj *)obj->data;
1062	*mode = policy->hashMode;
1063
1064	obj_list_put(&policy_list);
1065
1066	return TSS_SUCCESS;
1067}
1068
1069TSS_RESULT
1070obj_policy_set_hash_mode(TSS_HPOLICY hPolicy, UINT32 mode)
1071{
1072	struct tsp_object *obj;
1073	struct tr_policy_obj *policy;
1074
1075	switch (mode) {
1076		case TSS_TSPATTRIB_HASH_MODE_NULL:
1077		case TSS_TSPATTRIB_HASH_MODE_NOT_NULL:
1078			break;
1079		default:
1080			return TSPERR(TSS_E_INVALID_ATTRIB_DATA);
1081	}
1082
1083	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1084		return TSPERR(TSS_E_INVALID_HANDLE);
1085
1086	policy = (struct tr_policy_obj *)obj->data;
1087	policy->hashMode = mode;
1088
1089	obj_list_put(&policy_list);
1090
1091	return TSS_SUCCESS;
1092}
1093
1094#ifdef TSS_BUILD_DELEGATION
1095TSS_RESULT
1096obj_policy_set_delegation_type(TSS_HPOLICY hPolicy, UINT32 type)
1097{
1098	struct tsp_object *obj;
1099	struct tr_policy_obj *policy;
1100	TSS_RESULT result = TSS_SUCCESS;
1101
1102	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1103		return TSPERR(TSS_E_INVALID_HANDLE);
1104
1105	policy = (struct tr_policy_obj *)obj->data;
1106
1107	switch (type) {
1108	case TSS_DELEGATIONTYPE_NONE:
1109		obj_policy_clear_delegation(policy);
1110		break;
1111	case TSS_DELEGATIONTYPE_OWNER:
1112	case TSS_DELEGATIONTYPE_KEY:
1113		if (policy->delegationIndexSet || policy->delegationBlob) {
1114			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1115			goto done;
1116		}
1117		break;
1118	}
1119
1120	policy->delegationType = type;
1121
1122done:
1123	obj_list_put(&policy_list);
1124
1125	return result;
1126}
1127
1128
1129TSS_RESULT
1130obj_policy_get_delegation_type(TSS_HPOLICY hPolicy, UINT32 *type)
1131{
1132	struct tsp_object *obj;
1133	struct tr_policy_obj *policy;
1134
1135	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1136		return TSPERR(TSS_E_INVALID_HANDLE);
1137
1138	policy = (struct tr_policy_obj *)obj->data;
1139
1140	*type = policy->delegationType;
1141
1142	obj_list_put(&policy_list);
1143
1144	return TSS_SUCCESS;
1145}
1146
1147TSS_RESULT
1148obj_policy_set_delegation_index(TSS_HPOLICY hPolicy, UINT32 index)
1149{
1150	struct tsp_object *obj;
1151	struct tr_policy_obj *policy;
1152	TPM_DELEGATE_PUBLIC public;
1153	TSS_RESULT result;
1154
1155	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1156		return TSPERR(TSS_E_INVALID_HANDLE);
1157
1158	policy = (struct tr_policy_obj *)obj->data;
1159
1160	if ((result = get_delegate_index(obj->tspContext, index, &public)))
1161		goto done;
1162
1163	free(public.pcrInfo.pcrSelection.pcrSelect);
1164
1165	obj_policy_clear_delegation(policy);
1166	switch (public.permissions.delegateType) {
1167	case TPM_DEL_OWNER_BITS:
1168		policy->delegationType = TSS_DELEGATIONTYPE_OWNER;
1169		break;
1170	case TPM_DEL_KEY_BITS:
1171		policy->delegationType = TSS_DELEGATIONTYPE_KEY;
1172		break;
1173	default:
1174		result = TSPERR(TSS_E_BAD_PARAMETER);
1175		goto done;
1176	}
1177	policy->delegationIndex = index;
1178	policy->delegationIndexSet = TRUE;
1179
1180done:
1181	obj_list_put(&policy_list);
1182
1183	return result;
1184}
1185
1186TSS_RESULT
1187obj_policy_get_delegation_index(TSS_HPOLICY hPolicy, UINT32 *index)
1188{
1189	struct tsp_object *obj;
1190	struct tr_policy_obj *policy;
1191	TSS_RESULT result = TSS_SUCCESS;
1192
1193	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1194		return TSPERR(TSS_E_INVALID_HANDLE);
1195
1196	policy = (struct tr_policy_obj *)obj->data;
1197
1198	if (!policy->delegationIndexSet) {
1199		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1200		goto done;
1201	}
1202
1203	*index = policy->delegationIndex;
1204
1205done:
1206	obj_list_put(&policy_list);
1207
1208	return result;
1209}
1210
1211TSS_RESULT obj_policy_set_delegation_per1(TSS_HPOLICY hPolicy, UINT32 per1)
1212{
1213	struct tsp_object *obj;
1214	struct tr_policy_obj *policy;
1215	TSS_RESULT result = TSS_SUCCESS;
1216
1217	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1218		return TSPERR(TSS_E_INVALID_HANDLE);
1219
1220	policy = (struct tr_policy_obj *)obj->data;
1221
1222	if (policy->delegationIndexSet || policy->delegationBlob) {
1223		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1224		goto done;
1225	}
1226
1227	policy->delegationPer1 = per1;
1228
1229done:
1230	obj_list_put(&policy_list);
1231
1232	return result;
1233}
1234
1235TSS_RESULT obj_policy_get_delegation_per1(TSS_HPOLICY hPolicy, UINT32 *per1)
1236{
1237	struct tsp_object *obj;
1238	struct tr_policy_obj *policy;
1239	TPM_DELEGATE_PUBLIC public;
1240	TSS_RESULT result = TSS_SUCCESS;
1241
1242	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1243		return TSPERR(TSS_E_INVALID_HANDLE);
1244
1245	policy = (struct tr_policy_obj *)obj->data;
1246
1247	if (policy->delegationIndexSet || policy->delegationBlob) {
1248		if ((result = obj_policy_get_delegate_public(obj, &public)))
1249			goto done;
1250		*per1 = public.permissions.per1;
1251		free(public.pcrInfo.pcrSelection.pcrSelect);
1252	} else
1253		*per1 = policy->delegationPer1;
1254
1255done:
1256	obj_list_put(&policy_list);
1257
1258	return result;
1259}
1260
1261TSS_RESULT obj_policy_set_delegation_per2(TSS_HPOLICY hPolicy, UINT32 per2)
1262{
1263	struct tsp_object *obj;
1264	struct tr_policy_obj *policy;
1265	TSS_RESULT result = TSS_SUCCESS;
1266
1267	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1268		return TSPERR(TSS_E_INVALID_HANDLE);
1269
1270	policy = (struct tr_policy_obj *)obj->data;
1271
1272	if (policy->delegationIndexSet || policy->delegationBlob) {
1273		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1274		goto done;
1275	}
1276
1277	policy->delegationPer2 = per2;
1278
1279done:
1280	obj_list_put(&policy_list);
1281
1282	return result;
1283}
1284
1285TSS_RESULT obj_policy_get_delegation_per2(TSS_HPOLICY hPolicy, UINT32 *per2)
1286{
1287	struct tsp_object *obj;
1288	struct tr_policy_obj *policy;
1289	TPM_DELEGATE_PUBLIC public;
1290	TSS_RESULT result = TSS_SUCCESS;
1291
1292	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1293		return TSPERR(TSS_E_INVALID_HANDLE);
1294
1295	policy = (struct tr_policy_obj *)obj->data;
1296
1297	if (policy->delegationIndexSet || policy->delegationBlob) {
1298		if ((result = obj_policy_get_delegate_public(obj, &public)))
1299			goto done;
1300		*per2 = public.permissions.per2;
1301		free(public.pcrInfo.pcrSelection.pcrSelect);
1302	} else
1303		*per2 = policy->delegationPer2;
1304
1305done:
1306	obj_list_put(&policy_list);
1307
1308	return result;
1309}
1310
1311TSS_RESULT
1312obj_policy_set_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 blobLength, BYTE *blob)
1313{
1314	struct tsp_object *obj;
1315	struct tr_policy_obj *policy;
1316	UINT16 tag;
1317	UINT64 offset;
1318	TSS_RESULT result = TSS_SUCCESS;
1319
1320	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1321		return TSPERR(TSS_E_INVALID_HANDLE);
1322
1323	policy = (struct tr_policy_obj *)obj->data;
1324
1325	obj_policy_clear_delegation(policy);
1326
1327	if (blobLength == 0) {
1328		result = TSPERR(TSS_E_BAD_PARAMETER);
1329		goto done;
1330	}
1331
1332	offset = 0;
1333	Trspi_UnloadBlob_UINT16(&offset, &tag, blob);
1334	switch (tag) {
1335	case TPM_TAG_DELEGATE_OWNER_BLOB:
1336		if (type && (type != TSS_DELEGATIONTYPE_OWNER)) {
1337			result = TSPERR(TSS_E_BAD_PARAMETER);
1338			goto done;
1339		}
1340		policy->delegationType = TSS_DELEGATIONTYPE_OWNER;
1341		break;
1342	case TPM_TAG_DELG_KEY_BLOB:
1343		if (type && (type != TSS_DELEGATIONTYPE_KEY)) {
1344			result = TSPERR(TSS_E_BAD_PARAMETER);
1345			goto done;
1346		}
1347		policy->delegationType = TSS_DELEGATIONTYPE_KEY;
1348		break;
1349	default:
1350		result = TSPERR(TSS_E_BAD_PARAMETER);
1351		goto done;
1352	}
1353
1354	if ((policy->delegationBlob = malloc(blobLength)) == NULL) {
1355		LogError("malloc of %u bytes failed.", blobLength);
1356		result = TSPERR(TSS_E_OUTOFMEMORY);
1357		goto done;
1358	}
1359
1360	policy->delegationBlobLength = blobLength;
1361	memcpy(policy->delegationBlob, blob, blobLength);
1362
1363done:
1364	obj_list_put(&policy_list);
1365
1366	return result;
1367}
1368
1369TSS_RESULT
1370obj_policy_get_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 *blobLength, BYTE **blob)
1371{
1372	struct tsp_object *obj;
1373	struct tr_policy_obj *policy;
1374	TSS_RESULT result = TSS_SUCCESS;
1375
1376	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1377		return TSPERR(TSS_E_INVALID_HANDLE);
1378
1379	policy = (struct tr_policy_obj *)obj->data;
1380
1381	if (policy->delegationBlobLength == 0) {
1382		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1383		goto done;
1384	}
1385
1386	if (type && (type != policy->delegationType)) {
1387		result = TSPERR(TSS_E_BAD_PARAMETER);
1388		goto done;
1389	}
1390
1391	if ((*blob = calloc_tspi(obj->tspContext, policy->delegationBlobLength)) == NULL) {
1392		LogError("malloc of %u bytes failed.", policy->delegationBlobLength);
1393		result = TSPERR(TSS_E_OUTOFMEMORY);
1394		goto done;
1395	}
1396
1397	memcpy(*blob, policy->delegationBlob, policy->delegationBlobLength);
1398	*blobLength = policy->delegationBlobLength;
1399
1400done:
1401	obj_list_put(&policy_list);
1402
1403	return result;
1404}
1405
1406TSS_RESULT
1407obj_policy_get_delegation_label(TSS_HPOLICY hPolicy, BYTE *label)
1408{
1409	struct tsp_object *obj;
1410	struct tr_policy_obj *policy;
1411	TPM_DELEGATE_PUBLIC public;
1412	TSS_RESULT result = TSS_SUCCESS;
1413
1414	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1415		return TSPERR(TSS_E_INVALID_HANDLE);
1416
1417	policy = (struct tr_policy_obj *)obj->data;
1418
1419	if (policy->delegationIndexSet || policy->delegationBlob) {
1420		if ((result = obj_policy_get_delegate_public(obj, &public)))
1421			goto done;
1422		*label = public.label.label;
1423		free(public.pcrInfo.pcrSelection.pcrSelect);
1424	} else
1425		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1426
1427done:
1428	obj_list_put(&policy_list);
1429
1430	return result;
1431}
1432
1433TSS_RESULT
1434obj_policy_get_delegation_familyid(TSS_HPOLICY hPolicy, UINT32 *familyID)
1435{
1436	struct tsp_object *obj;
1437	struct tr_policy_obj *policy;
1438	TPM_DELEGATE_PUBLIC public;
1439	TSS_RESULT result = TSS_SUCCESS;
1440
1441	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1442		return TSPERR(TSS_E_INVALID_HANDLE);
1443
1444	policy = (struct tr_policy_obj *)obj->data;
1445
1446	if (policy->delegationIndexSet || policy->delegationBlob) {
1447		if ((result = obj_policy_get_delegate_public(obj, &public)))
1448			goto done;
1449		*familyID = public.familyID;
1450		free(public.pcrInfo.pcrSelection.pcrSelect);
1451	} else
1452		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1453
1454done:
1455	obj_list_put(&policy_list);
1456
1457	return result;
1458}
1459
1460TSS_RESULT
1461obj_policy_get_delegation_vercount(TSS_HPOLICY hPolicy, UINT32 *verCount)
1462{
1463	struct tsp_object *obj;
1464	struct tr_policy_obj *policy;
1465	TPM_DELEGATE_PUBLIC public;
1466	TSS_RESULT result = TSS_SUCCESS;
1467
1468	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1469		return TSPERR(TSS_E_INVALID_HANDLE);
1470
1471	policy = (struct tr_policy_obj *)obj->data;
1472
1473	if (policy->delegationIndexSet || policy->delegationBlob) {
1474		if ((result = obj_policy_get_delegate_public(obj, &public)))
1475			goto done;
1476		*verCount = public.verificationCount;
1477		free(public.pcrInfo.pcrSelection.pcrSelect);
1478	} else
1479		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1480
1481done:
1482	obj_list_put(&policy_list);
1483
1484	return result;
1485}
1486
1487TSS_RESULT
1488obj_policy_get_delegation_pcr_locality(TSS_HPOLICY hPolicy, UINT32 *locality)
1489{
1490	struct tsp_object *obj;
1491	struct tr_policy_obj *policy;
1492	TPM_DELEGATE_PUBLIC public;
1493	TSS_RESULT result = TSS_SUCCESS;
1494
1495	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1496		return TSPERR(TSS_E_INVALID_HANDLE);
1497
1498	policy = (struct tr_policy_obj *)obj->data;
1499
1500	if (policy->delegationIndexSet || policy->delegationBlob) {
1501		if ((result = obj_policy_get_delegate_public(obj, &public)))
1502			goto done;
1503		*locality = public.pcrInfo.localityAtRelease;
1504		free(public.pcrInfo.pcrSelection.pcrSelect);
1505	} else
1506		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1507
1508done:
1509	obj_list_put(&policy_list);
1510
1511	return result;
1512}
1513
1514TSS_RESULT
1515obj_policy_get_delegation_pcr_digest(TSS_HPOLICY hPolicy, UINT32 *digestLength, BYTE **digest)
1516{
1517	struct tsp_object *obj;
1518	struct tr_policy_obj *policy;
1519	TPM_DELEGATE_PUBLIC public;
1520	TSS_RESULT result = TSS_SUCCESS;
1521
1522	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1523		return TSPERR(TSS_E_INVALID_HANDLE);
1524
1525	policy = (struct tr_policy_obj *)obj->data;
1526
1527	if (policy->delegationIndexSet || policy->delegationBlob) {
1528		if ((result = obj_policy_get_delegate_public(obj, &public)))
1529			goto done;
1530		*digest = calloc_tspi(obj->tspContext, TPM_SHA1_160_HASH_LEN);
1531		if (*digest == NULL) {
1532			LogError("malloc of %u bytes failed.", TPM_SHA1_160_HASH_LEN);
1533			result = TSPERR(TSS_E_OUTOFMEMORY);
1534			goto done;
1535		}
1536		memcpy(*digest, &public.pcrInfo.digestAtRelease.digest, TPM_SHA1_160_HASH_LEN);
1537		*digestLength = TPM_SHA1_160_HASH_LEN;
1538		free(public.pcrInfo.pcrSelection.pcrSelect);
1539	} else
1540		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1541
1542done:
1543	obj_list_put(&policy_list);
1544
1545	return result;
1546}
1547
1548TSS_RESULT
1549obj_policy_get_delegation_pcr_selection(TSS_HPOLICY hPolicy, UINT32 *selectionLength,
1550					BYTE **selection)
1551{
1552	struct tsp_object *obj;
1553	struct tr_policy_obj *policy;
1554	TPM_DELEGATE_PUBLIC public;
1555	UINT64 offset;
1556	TSS_RESULT result = TSS_SUCCESS;
1557
1558	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1559		return TSPERR(TSS_E_INVALID_HANDLE);
1560
1561	policy = (struct tr_policy_obj *)obj->data;
1562
1563	if (policy->delegationIndexSet || policy->delegationBlob) {
1564		if ((result = obj_policy_get_delegate_public(obj, &public)))
1565			goto done;
1566		offset = 0;
1567		Trspi_LoadBlob_PCR_SELECTION(&offset, NULL, &public.pcrInfo.pcrSelection);
1568		*selection = calloc_tspi(obj->tspContext, offset);
1569		if (*selection == NULL) {
1570			LogError("malloc of %u bytes failed.", (UINT32)offset);
1571			result = TSPERR(TSS_E_OUTOFMEMORY);
1572			goto done;
1573		}
1574		offset = 0;
1575		Trspi_LoadBlob_PCR_SELECTION(&offset, *selection, &public.pcrInfo.pcrSelection);
1576		*selectionLength = offset;
1577		free(public.pcrInfo.pcrSelection.pcrSelect);
1578	} else
1579		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1580
1581done:
1582	obj_list_put(&policy_list);
1583
1584	return result;
1585}
1586
1587TSS_RESULT
1588obj_policy_is_delegation_index_set(TSS_HPOLICY hPolicy, TSS_BOOL *indexSet)
1589{
1590	struct tsp_object *obj;
1591	struct tr_policy_obj *policy;
1592
1593	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1594		return TSPERR(TSS_E_INVALID_HANDLE);
1595
1596	policy = (struct tr_policy_obj *)obj->data;
1597
1598	*indexSet = policy->delegationIndexSet;
1599
1600	obj_list_put(&policy_list);
1601
1602	return TSS_SUCCESS;
1603}
1604
1605void
1606obj_policy_clear_delegation(struct tr_policy_obj *policy)
1607{
1608	free(policy->delegationBlob);
1609	policy->delegationType = TSS_DELEGATIONTYPE_NONE;
1610	policy->delegationPer1 = 0;
1611	policy->delegationPer2 = 0;
1612	policy->delegationIndexSet = FALSE;
1613	policy->delegationIndex = 0;
1614	policy->delegationBlobLength = 0;
1615	policy->delegationBlob = NULL;
1616}
1617
1618TSS_RESULT
1619obj_policy_get_delegate_public(struct tsp_object *obj, TPM_DELEGATE_PUBLIC *public)
1620{
1621	struct tr_policy_obj *policy;
1622	UINT16 tag;
1623	TPM_DELEGATE_OWNER_BLOB ownerBlob;
1624	TPM_DELEGATE_KEY_BLOB keyBlob;
1625	UINT64 offset;
1626	TSS_RESULT result;
1627
1628	policy = (struct tr_policy_obj *)obj->data;
1629
1630	if (policy->delegationIndexSet) {
1631		if ((result = get_delegate_index(obj->tspContext, policy->delegationIndex,
1632				public)))
1633			return result;
1634	} else if (policy->delegationBlob) {
1635		offset = 0;
1636		Trspi_UnloadBlob_UINT16(&offset, &tag, policy->delegationBlob);
1637
1638		offset = 0;
1639		switch (tag) {
1640		case TPM_TAG_DELEGATE_OWNER_BLOB:
1641			if ((result = Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB(&offset,
1642									policy->delegationBlob,
1643									&ownerBlob)))
1644				return result;
1645			*public = ownerBlob.pub;
1646			free(ownerBlob.additionalArea);
1647			free(ownerBlob.sensitiveArea);
1648			break;
1649		case TPM_TAG_DELG_KEY_BLOB:
1650			if ((result = Trspi_UnloadBlob_TPM_DELEGATE_KEY_BLOB(&offset,
1651									     policy->delegationBlob,
1652									     &keyBlob)))
1653				return result;
1654			*public = keyBlob.pub;
1655			free(keyBlob.additionalArea);
1656			free(keyBlob.sensitiveArea);
1657			break;
1658		default:
1659			return TSPERR(TSS_E_INTERNAL_ERROR);
1660		}
1661	} else
1662		return TSPERR(TSS_E_INTERNAL_ERROR);
1663
1664	return TSS_SUCCESS;
1665}
1666#endif
1667
1668