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 
28 TSS_RESULT
obj_policy_add(TSS_HCONTEXT tsp_context,UINT32 type,TSS_HOBJECT * phObject)29 obj_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 
63 void
__tspi_policy_free(void * data)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 
75 TSS_RESULT
obj_policy_remove(TSS_HOBJECT hObject,TSS_HCONTEXT tspContext)76 obj_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 
88 TSS_BOOL
obj_is_policy(TSS_HOBJECT hObject)89 obj_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 
101 TSS_RESULT
obj_policy_get_type(TSS_HPOLICY hPolicy,UINT32 * type)102 obj_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 
118 TSS_RESULT
obj_policy_set_type(TSS_HPOLICY hPolicy,UINT32 type)119 obj_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 
135 TSS_RESULT
obj_policy_get_tsp_context(TSS_HPOLICY hPolicy,TSS_HCONTEXT * tspContext)136 obj_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 
150 TSS_RESULT
obj_policy_do_hmac(TSS_HPOLICY hPolicy,TSS_HOBJECT hAuthorizedObject,TSS_BOOL returnOrVerify,UINT32 ulPendingFunction,TSS_BOOL continueUse,UINT32 ulSizeNonces,BYTE * rgbNonceEven,BYTE * rgbNonceOdd,BYTE * rgbNonceEvenOSAP,BYTE * rgbNonceOddOSAP,UINT32 ulSizeDigestHmac,BYTE * rgbParamDigest,BYTE * rgbHmacData)151 obj_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 
185 TSS_RESULT
obj_policy_get_secret(TSS_HPOLICY hPolicy,TSS_BOOL ctx,TCPA_SECRET * secret)186 obj_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 	__tspi_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 
239 TSS_RESULT
obj_policy_flush_secret(TSS_HPOLICY hPolicy)240 obj_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 	__tspi_memset(&policy->Secret, 0, policy->SecretSize);
251 	policy->SecretSet = FALSE;
252 
253 	obj_list_put(&policy_list);
254 
255 	return TSS_SUCCESS;
256 }
257 
258 TSS_RESULT
obj_policy_set_secret_object(TSS_HPOLICY hPolicy,TSS_FLAG mode,UINT32 size,TCPA_DIGEST * digest,TSS_BOOL set)259 obj_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;
298 done:
299 	obj_list_put(&policy_list);
300 
301 	return result;
302 }
303 
304 TSS_RESULT
obj_policy_is_secret_set(TSS_HPOLICY hPolicy,TSS_BOOL * secretSet)305 obj_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 
323 TSS_RESULT
obj_policy_set_secret(TSS_HPOLICY hPolicy,TSS_FLAG mode,UINT32 size,BYTE * data)324 obj_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 	__tspi_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 
360 TSS_RESULT
obj_policy_get_cb11(TSS_HPOLICY hPolicy,TSS_FLAG type,UINT32 * cb)361 obj_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 
399 TSS_RESULT
obj_policy_set_cb11(TSS_HPOLICY hPolicy,TSS_FLAG type,TSS_FLAG app_data,UINT32 cb)400 obj_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 
442 TSS_RESULT
obj_policy_set_cb12(TSS_HPOLICY hPolicy,TSS_FLAG flag,BYTE * in)443 obj_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 
535 TSS_RESULT
obj_policy_get_cb12(TSS_HPOLICY hPolicy,TSS_FLAG flag,UINT32 * size,BYTE ** out)536 obj_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 	}
597 done:
598 	obj_list_put(&policy_list);
599 
600 	return result;
601 }
602 
603 TSS_RESULT
obj_policy_get_lifetime(TSS_HPOLICY hPolicy,UINT32 * lifetime)604 obj_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 
620 TSS_RESULT
obj_policy_set_lifetime(TSS_HPOLICY hPolicy,UINT32 type,UINT32 value)621 obj_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 
672 TSS_RESULT
obj_policy_get_mode(TSS_HPOLICY hPolicy,UINT32 * mode)673 obj_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 
689 TSS_RESULT
obj_policy_get_counter(TSS_HPOLICY hPolicy,UINT32 * counter)690 obj_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 
711 TSS_RESULT
obj_policy_dec_counter(TSS_HPOLICY hPolicy)712 obj_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 */
734 TSS_RESULT
obj_policy_get_string(TSS_HPOLICY hPolicy,UINT32 * size,BYTE ** data)735 obj_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 
773 done:
774 	obj_list_put(&policy_list);
775 
776 	return result;
777 }
778 
779 TSS_RESULT
obj_policy_set_string(TSS_HPOLICY hPolicy,UINT32 size,BYTE * data)780 obj_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 
799 TSS_RESULT
obj_policy_get_secs_until_expired(TSS_HPOLICY hPolicy,UINT32 * secs)800 obj_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 
833 done:
834 	obj_list_put(&policy_list);
835 
836 	return result;
837 }
838 
839 TSS_RESULT
policy_has_expired(struct tr_policy_obj * policy,TSS_BOOL * answer)840 policy_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 
875 TSS_RESULT
obj_policy_has_expired(TSS_HPOLICY hPolicy,TSS_BOOL * answer)876 obj_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 
894 TSS_RESULT
obj_policy_get_xsap_params(TSS_HPOLICY hPolicy,TPM_COMMAND_CODE command,TPM_ENTITY_TYPE * et,UINT32 * entity_value_size,BYTE ** entity_value,BYTE * secret,TSS_CALLBACK * cb_xor,TSS_CALLBACK * cb_hmac,TSS_CALLBACK * cb_sealx,UINT32 * mode,TSS_BOOL new_secret)895 obj_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;
991 done:
992 	obj_list_put(&policy_list);
993 
994 	return result;
995 }
996 
997 TSS_RESULT
obj_policy_do_xor(TSS_HPOLICY hPolicy,TSS_HOBJECT hOSAPObject,TSS_HOBJECT hObject,TSS_FLAG PurposeSecret,UINT32 ulSizeNonces,BYTE * rgbNonceEven,BYTE * rgbNonceOdd,BYTE * rgbNonceEvenOSAP,BYTE * rgbNonceOddOSAP,UINT32 ulSizeEncAuth,BYTE * rgbEncAuthUsage,BYTE * rgbEncAuthMigration)998 obj_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 
1028 TSS_RESULT
obj_policy_do_takeowner(TSS_HPOLICY hPolicy,TSS_HOBJECT hObject,TSS_HKEY hObjectPubKey,UINT32 ulSizeEncAuth,BYTE * rgbEncAuth)1029 obj_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 
1052 TSS_RESULT
obj_policy_get_hash_mode(TSS_HPOLICY hPolicy,UINT32 * mode)1053 obj_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 
1069 TSS_RESULT
obj_policy_set_hash_mode(TSS_HPOLICY hPolicy,UINT32 mode)1070 obj_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
1095 TSS_RESULT
obj_policy_set_delegation_type(TSS_HPOLICY hPolicy,UINT32 type)1096 obj_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 
1122 done:
1123 	obj_list_put(&policy_list);
1124 
1125 	return result;
1126 }
1127 
1128 
1129 TSS_RESULT
obj_policy_get_delegation_type(TSS_HPOLICY hPolicy,UINT32 * type)1130 obj_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 
1147 TSS_RESULT
obj_policy_set_delegation_index(TSS_HPOLICY hPolicy,UINT32 index)1148 obj_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 
1180 done:
1181 	obj_list_put(&policy_list);
1182 
1183 	return result;
1184 }
1185 
1186 TSS_RESULT
obj_policy_get_delegation_index(TSS_HPOLICY hPolicy,UINT32 * index)1187 obj_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 
1205 done:
1206 	obj_list_put(&policy_list);
1207 
1208 	return result;
1209 }
1210 
obj_policy_set_delegation_per1(TSS_HPOLICY hPolicy,UINT32 per1)1211 TSS_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 
1229 done:
1230 	obj_list_put(&policy_list);
1231 
1232 	return result;
1233 }
1234 
obj_policy_get_delegation_per1(TSS_HPOLICY hPolicy,UINT32 * per1)1235 TSS_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 
1255 done:
1256 	obj_list_put(&policy_list);
1257 
1258 	return result;
1259 }
1260 
obj_policy_set_delegation_per2(TSS_HPOLICY hPolicy,UINT32 per2)1261 TSS_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 
1279 done:
1280 	obj_list_put(&policy_list);
1281 
1282 	return result;
1283 }
1284 
obj_policy_get_delegation_per2(TSS_HPOLICY hPolicy,UINT32 * per2)1285 TSS_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 
1305 done:
1306 	obj_list_put(&policy_list);
1307 
1308 	return result;
1309 }
1310 
1311 TSS_RESULT
obj_policy_set_delegation_blob(TSS_HPOLICY hPolicy,UINT32 type,UINT32 blobLength,BYTE * blob)1312 obj_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 
1363 done:
1364 	obj_list_put(&policy_list);
1365 
1366 	return result;
1367 }
1368 
1369 TSS_RESULT
obj_policy_get_delegation_blob(TSS_HPOLICY hPolicy,UINT32 type,UINT32 * blobLength,BYTE ** blob)1370 obj_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 
1400 done:
1401 	obj_list_put(&policy_list);
1402 
1403 	return result;
1404 }
1405 
1406 TSS_RESULT
obj_policy_get_delegation_label(TSS_HPOLICY hPolicy,BYTE * label)1407 obj_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 
1427 done:
1428 	obj_list_put(&policy_list);
1429 
1430 	return result;
1431 }
1432 
1433 TSS_RESULT
obj_policy_get_delegation_familyid(TSS_HPOLICY hPolicy,UINT32 * familyID)1434 obj_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 
1454 done:
1455 	obj_list_put(&policy_list);
1456 
1457 	return result;
1458 }
1459 
1460 TSS_RESULT
obj_policy_get_delegation_vercount(TSS_HPOLICY hPolicy,UINT32 * verCount)1461 obj_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 
1481 done:
1482 	obj_list_put(&policy_list);
1483 
1484 	return result;
1485 }
1486 
1487 TSS_RESULT
obj_policy_get_delegation_pcr_locality(TSS_HPOLICY hPolicy,UINT32 * locality)1488 obj_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 
1508 done:
1509 	obj_list_put(&policy_list);
1510 
1511 	return result;
1512 }
1513 
1514 TSS_RESULT
obj_policy_get_delegation_pcr_digest(TSS_HPOLICY hPolicy,UINT32 * digestLength,BYTE ** digest)1515 obj_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 
1542 done:
1543 	obj_list_put(&policy_list);
1544 
1545 	return result;
1546 }
1547 
1548 TSS_RESULT
obj_policy_get_delegation_pcr_selection(TSS_HPOLICY hPolicy,UINT32 * selectionLength,BYTE ** selection)1549 obj_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 
1581 done:
1582 	obj_list_put(&policy_list);
1583 
1584 	return result;
1585 }
1586 
1587 TSS_RESULT
obj_policy_is_delegation_index_set(TSS_HPOLICY hPolicy,TSS_BOOL * indexSet)1588 obj_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 
1605 void
obj_policy_clear_delegation(struct tr_policy_obj * policy)1606 obj_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 
1618 TSS_RESULT
obj_policy_get_delegate_public(struct tsp_object * obj,TPM_DELEGATE_PUBLIC * public)1619 obj_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