xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tsp_delegate.c (revision 1580a27b92f58fcdcb23fdfbc04a7c2b54a0b7c8)
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. 2007
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "trousers_types.h"
19 #include "spi_utils.h"
20 #include "obj.h"
21 #include "tsplog.h"
22 #include "tsp_delegate.h"
23 #include "authsess.h"
24 
25 
26 TSS_RESULT
27 do_delegate_manage(TSS_HTPM hTpm, UINT32 familyID, UINT32 opFlag,
28 		   UINT32 opDataSize, BYTE *opData, UINT32 *outDataSize, BYTE **outData)
29 {
30 	TSS_HCONTEXT hContext;
31 	TSS_HPOLICY hPolicy;
32 	UINT32 secretMode = TSS_SECRET_MODE_NONE;
33 	Trspi_HashCtx hashCtx;
34 	TCPA_DIGEST digest;
35 	TPM_AUTH ownerAuth, *pAuth;
36 	UINT32 retDataSize;
37 	BYTE *retData = NULL;
38 	TSS_RESULT result;
39 
40 	if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
41 		return result;
42 
43 	if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
44 		return result;
45 
46 	if (hPolicy != NULL_HPOLICY) {
47 		if ((result = obj_policy_get_mode(hPolicy, &secretMode)))
48 			return result;
49 	}
50 
51 	if (secretMode != TSS_SECRET_MODE_NONE) {
52 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
53 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage);
54 		result |= Trspi_Hash_UINT32(&hashCtx, familyID);
55 		result |= Trspi_Hash_UINT32(&hashCtx, opFlag);
56 		result |= Trspi_Hash_UINT32(&hashCtx, opDataSize);
57 		result |= Trspi_HashUpdate(&hashCtx, opDataSize, opData);
58 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
59 			return result;
60 
61 		pAuth = &ownerAuth;
62 		if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_Manage, hPolicy, FALSE,
63 						      &digest, pAuth)))
64 			return result;
65 	} else
66 		pAuth = NULL;
67 
68 	/* Perform the delegation operation */
69 	if ((result = TCS_API(hContext)->Delegate_Manage(hContext, familyID, opFlag, opDataSize,
70 							 opData, pAuth, &retDataSize, &retData)))
71 		return result;
72 
73 	if (pAuth) {
74 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
75 		result |= Trspi_Hash_UINT32(&hashCtx, result);
76 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage);
77 		result |= Trspi_Hash_UINT32(&hashCtx, retDataSize);
78 		result |= Trspi_HashUpdate(&hashCtx, retDataSize, retData);
79 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
80 			free(retData);
81 			goto done;
82 		}
83 
84 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) {
85 			free(retData);
86 			goto done;
87 		}
88 	}
89 
90 	*outDataSize = retDataSize;
91 	*outData = retData;
92 
93 done:
94 	return result;
95 }
96 
97 TSS_RESULT
98 create_owner_delegation(TSS_HTPM       hTpm,
99 			BYTE           bLabel,
100 			UINT32         ulFlags,
101 			TSS_HPCRS      hPcrs,
102 			TSS_HDELFAMILY hFamily,
103 			TSS_HPOLICY    hDelegation)
104 {
105 	TSS_HCONTEXT hContext;
106 	TSS_BOOL incrementCount = FALSE;
107 	UINT32 type;
108 	UINT32 publicInfoSize;
109 	BYTE *publicInfo = NULL;
110 	Trspi_HashCtx hashCtx;
111 	TCPA_DIGEST digest;
112 	UINT32 blobSize;
113 	BYTE *blob = NULL;
114 	TSS_RESULT result;
115 	struct authsess *xsap = NULL;
116 
117 	if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
118 		return result;
119 
120 	if ((ulFlags & ~TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT) > 0)
121 		return TSPERR(TSS_E_BAD_PARAMETER);
122 
123 	if (ulFlags & TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT)
124 		incrementCount = TRUE;
125 
126 	if ((result = obj_policy_get_delegation_type(hDelegation, &type)))
127 		return result;
128 
129 	if (type != TSS_DELEGATIONTYPE_OWNER)
130 		return TSPERR(TSS_E_BAD_PARAMETER);
131 
132 	if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation,
133 			&publicInfoSize, &publicInfo)))
134 		return result;
135 
136 	if ((result = authsess_xsap_init(hContext, hTpm, hDelegation, TSS_AUTH_POLICY_NOT_REQUIRED,
137 					 TPM_ORD_Delegate_CreateOwnerDelegation, TPM_ET_OWNER,
138 					 &xsap)))
139 		return result;
140 
141 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
142 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation);
143 	result |= Trspi_Hash_BOOL(&hashCtx, incrementCount);
144 	result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo);
145 	result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata);
146 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
147 		goto done;
148 
149 	if ((result = authsess_xsap_hmac(xsap, &digest)))
150 		goto done;
151 
152 	/* Create the delegation */
153 	if ((result = TCS_API(hContext)->Delegate_CreateOwnerDelegation(hContext, incrementCount,
154 									publicInfoSize, publicInfo,
155 									&xsap->encAuthUse,
156 									xsap->pAuth, &blobSize,
157 									&blob)))
158 		goto done;
159 
160 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
161 	result |= Trspi_Hash_UINT32(&hashCtx, result);
162 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation);
163 	result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
164 	result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
165 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
166 		goto done;
167 
168 	if (authsess_xsap_verify(xsap, &digest)) {
169 		result = TSPERR(TSS_E_TSP_AUTHFAIL);
170 		goto done;
171 	}
172 
173 	result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_OWNER,
174 			blobSize, blob);
175 
176 done:
177 	authsess_free(xsap);
178 	free(publicInfo);
179 	free(blob);
180 
181 	return result;
182 }
183 
184 TSS_RESULT
185 create_key_delegation(TSS_HKEY       hKey,
186 		      BYTE           bLabel,
187 		      UINT32         ulFlags,
188 		      TSS_HPCRS      hPcrs,
189 		      TSS_HDELFAMILY hFamily,
190 		      TSS_HPOLICY    hDelegation)
191 {
192 	TSS_HCONTEXT hContext;
193 	UINT32 type;
194 	TCS_KEY_HANDLE tcsKeyHandle;
195 	UINT32 publicInfoSize;
196 	BYTE *publicInfo = NULL;
197 	Trspi_HashCtx hashCtx;
198 	TCPA_DIGEST digest;
199 	UINT32 blobSize;
200 	BYTE *blob = NULL;
201 	TSS_RESULT result;
202 	struct authsess *xsap = NULL;
203 
204 	if ((result = obj_rsakey_get_tsp_context(hKey, &hContext)))
205 		return result;
206 
207 	if (ulFlags != 0)
208 		return TSPERR(TSS_E_BAD_PARAMETER);
209 
210 	if ((result = obj_policy_get_delegation_type(hDelegation, &type)))
211 		return result;
212 
213 	if (type != TSS_DELEGATIONTYPE_KEY)
214 		return TSPERR(TSS_E_BAD_PARAMETER);
215 
216 	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
217 		return result;
218 
219 	if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation,
220 			&publicInfoSize, &publicInfo)))
221 		return result;
222 
223 	if ((result = authsess_xsap_init(hContext, hKey, hDelegation, TSS_AUTH_POLICY_REQUIRED,
224 					 TPM_ORD_Delegate_CreateKeyDelegation, TPM_ET_KEYHANDLE,
225 					 &xsap)))
226 		return result;
227 
228 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
229 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation);
230 	result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo);
231 	result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
232 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
233 		goto done;
234 
235 	if ((result = authsess_xsap_hmac(xsap, &digest)))
236 		goto done;
237 
238 	/* Create the delegation */
239 	if ((result = TCS_API(hContext)->Delegate_CreateKeyDelegation(hContext, tcsKeyHandle,
240 								      publicInfoSize, publicInfo,
241 								      &xsap->encAuthUse,
242 								      xsap->pAuth, &blobSize,
243 								      &blob)))
244 		goto done;
245 
246 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
247 	result |= Trspi_Hash_UINT32(&hashCtx, result);
248 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation);
249 	result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
250 	result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
251 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
252 		goto done;
253 
254 	if (authsess_xsap_verify(xsap, &digest)) {
255 		result = TSPERR(TSS_E_TSP_AUTHFAIL);
256 		goto done;
257 	}
258 
259 	result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_KEY, blobSize,
260 						blob);
261 
262 done:
263 	free(blob);
264 	authsess_free(xsap);
265 	free(publicInfo);
266 
267 	return result;
268 }
269 
270 TSS_RESULT
271 update_delfamily_object(TSS_HTPM hTpm, UINT32 familyID)
272 {
273 	TSS_HCONTEXT hContext;
274 	UINT32 familyTableSize, delegateTableSize;
275 	BYTE *familyTable = NULL, *delegateTable = NULL;
276 	UINT64 offset;
277 	TPM_FAMILY_TABLE_ENTRY familyTableEntry;
278 	TSS_BOOL familyState;
279 	TSS_HDELFAMILY hFamily;
280 	TSS_RESULT result;
281 
282 	if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
283 		return result;
284 
285 	if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize,
286 							    &familyTable, &delegateTableSize,
287 							    &delegateTable)))
288 		return result;
289 
290 	for (offset = 0; offset < familyTableSize;) {
291 		Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&offset, familyTable, &familyTableEntry);
292 		if (familyTableEntry.familyID == familyID) {
293 			obj_delfamily_find_by_familyid(hContext, familyID, &hFamily);
294 			if (hFamily == NULL_HDELFAMILY) {
295 				if ((result = obj_delfamily_add(hContext, &hFamily)))
296 					goto done;
297 				if ((result = obj_delfamily_set_familyid(hFamily,
298 									 familyTableEntry.familyID)))
299 					goto done;
300 				if ((result = obj_delfamily_set_label(hFamily,
301 								      familyTableEntry.label.label)))
302 					goto done;
303 			}
304 
305 			/* Set/Update the family attributes */
306 			familyState = (familyTableEntry.flags & TPM_FAMFLAG_DELEGATE_ADMIN_LOCK) ?
307 				      TRUE : FALSE;
308 			if ((result = obj_delfamily_set_locked(hFamily, familyState, FALSE)))
309 				goto done;
310 			familyState = (familyTableEntry.flags & TPM_FAMFLAG_ENABLE) ? TRUE : FALSE;
311 			if ((result = obj_delfamily_set_enabled(hFamily, familyState, FALSE)))
312 				goto done;
313 			if ((result = obj_delfamily_set_vercount(hFamily,
314 								 familyTableEntry.verificationCount)))
315 				goto done;
316 
317 			break;
318 		}
319 	}
320 
321 done:
322 	free(familyTable);
323 	free(delegateTable);
324 
325 	return result;
326 }
327 
328 TSS_RESULT
329 get_delegate_index(TSS_HCONTEXT hContext, UINT32 index, TPM_DELEGATE_PUBLIC *public)
330 {
331 	UINT32 familyTableSize, delegateTableSize;
332 	BYTE *familyTable = NULL, *delegateTable = NULL;
333 	UINT64 offset;
334 	UINT32 tpmIndex;
335 	TPM_DELEGATE_PUBLIC tempPublic;
336 	TSS_RESULT result;
337 
338 	if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize,
339 							    &familyTable, &delegateTableSize,
340 							    &delegateTable)))
341 		goto done;
342 
343 	for (offset = 0; offset < delegateTableSize;) {
344 		Trspi_UnloadBlob_UINT32(&offset, &tpmIndex, delegateTable);
345 		if (tpmIndex == index) {
346 			result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, public);
347 			goto done;
348 		} else {
349 			if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, &tempPublic)))
350 				goto done;
351 		}
352 
353 		free(tempPublic.pcrInfo.pcrSelection.pcrSelect);
354 	}
355 
356 	/* Didn't find a matching index */
357 	result = TSPERR(TSS_E_BAD_PARAMETER);
358 
359 done:
360 	free(familyTable);
361 	free(delegateTable);
362 
363 	return result;
364 }
365 
366 TSS_RESULT
367 __tspi_build_delegate_public_info(BYTE           bLabel,
368 			   TSS_HPCRS      hPcrs,
369 			   TSS_HDELFAMILY hFamily,
370 			   TSS_HPOLICY    hDelegation,
371 			   UINT32        *publicInfoSize,
372 			   BYTE         **publicInfo)
373 {
374 	TPM_DELEGATE_PUBLIC public;
375 	UINT32 delegateType;
376 	UINT32 pcrInfoSize;
377 	BYTE *pcrInfo = NULL;
378 	UINT64 offset;
379 	TSS_RESULT result = TSS_SUCCESS;
380 
381 	if (hDelegation == NULL_HPOLICY)
382 		return TSPERR(TSS_E_BAD_PARAMETER);
383 
384 	if ((result = obj_policy_get_delegation_type(hDelegation, &delegateType)))
385 		return result;
386 
387 	/* This call will create a "null" PCR_INFO_SHORT if hPcrs is null */
388 	if ((result = obj_pcrs_create_info_short(hPcrs, &pcrInfoSize, &pcrInfo)))
389 		return result;
390 
391 	memset(&public, 0, sizeof(public));
392 	public.tag = TPM_TAG_DELEGATE_PUBLIC;
393 	public.label.label = bLabel;
394 	offset = 0;
395 	if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, pcrInfo, &public.pcrInfo)))
396 		goto done;
397 	public.permissions.tag = TPM_TAG_DELEGATIONS;
398 	public.permissions.delegateType =
399 		(delegateType == TSS_DELEGATIONTYPE_OWNER) ? TPM_DEL_OWNER_BITS : TPM_DEL_KEY_BITS;
400 	if ((result = obj_policy_get_delegation_per1(hDelegation, &public.permissions.per1)))
401 		goto done;
402 	if ((result = obj_policy_get_delegation_per2(hDelegation, &public.permissions.per2)))
403 		goto done;
404 	if ((result = obj_delfamily_get_familyid(hFamily, &public.familyID)))
405 		goto done;
406 	if ((result = obj_delfamily_get_vercount(hFamily, &public.verificationCount)))
407 		goto done;
408 
409 	offset = 0;
410 	Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, NULL, &public);
411 	*publicInfoSize = offset;
412 	*publicInfo = malloc(*publicInfoSize);
413 	if (*publicInfo == NULL) {
414 		LogError("malloc of %u bytes failed.", *publicInfoSize);
415 		result = TSPERR(TSS_E_OUTOFMEMORY);
416 		goto done;
417 	}
418 	offset = 0;
419 	Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, *publicInfo, &public);
420 
421 done:
422 	free(pcrInfo);
423 	free(public.pcrInfo.pcrSelection.pcrSelect);
424 
425 	return result;
426 }
427 
428 #ifdef TSS_BUILD_TRANSPORT
429 TSS_RESULT
430 Transport_Delegate_Manage(TSS_HCONTEXT tspContext,              /* in */
431 			  TPM_FAMILY_ID familyID,             /* in */
432 			  TPM_FAMILY_OPERATION opFlag,        /* in */
433 			  UINT32 opDataSize,                  /* in */
434 			  BYTE *opData,                       /* in */
435 			  TPM_AUTH *ownerAuth,                /* in, out */
436 			  UINT32 *retDataSize,                /* out */
437 			  BYTE **retData)                     /* out */
438 {
439 	TSS_RESULT result;
440 	UINT32 handlesLen = 0, decLen, dataLen;
441 	UINT64 offset;
442 	BYTE *data, *dec = NULL;
443 
444 
445 	if ((result = obj_context_transport_init(tspContext)))
446 		return result;
447 
448 	LogDebugFn("Executing in a transport session");
449 
450 	dataLen = sizeof(TPM_FAMILY_ID)
451 		  + sizeof(TPM_FAMILY_OPERATION)
452 		  + sizeof(UINT32)
453 		  + opDataSize;
454 	if ((data = malloc(dataLen)) == NULL) {
455 		LogError("malloc of %u bytes failed", dataLen);
456 		return TSPERR(TSS_E_OUTOFMEMORY);
457 	}
458 
459 	offset = 0;
460 	Trspi_LoadBlob_UINT32(&offset, familyID, data);
461 	Trspi_LoadBlob_UINT32(&offset, opFlag, data);
462 	Trspi_LoadBlob_UINT32(&offset, opDataSize, data);
463 	Trspi_LoadBlob(&offset, opDataSize, data, opData);
464 
465 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_Manage, dataLen,
466 						    data, NULL, &handlesLen, NULL, ownerAuth,
467 						    NULL, &decLen, &dec))) {
468 		free(data);
469 		return result;
470 	}
471 	free(data);
472 
473 	offset = 0;
474 	Trspi_UnloadBlob_UINT32(&offset, retDataSize, dec);
475 
476 	if ((*retData = malloc(*retDataSize)) == NULL) {
477 		free(dec);
478 		LogError("malloc of %u bytes failed", *retDataSize);
479 		*retDataSize = 0;
480 		return TSPERR(TSS_E_OUTOFMEMORY);
481 	}
482 	Trspi_UnloadBlob(&offset, *retDataSize, dec, *retData);
483 
484 	free(dec);
485 
486 	return result;
487 }
488 
489 TSS_RESULT
490 Transport_Delegate_CreateKeyDelegation(TSS_HCONTEXT tspContext,         /* in */
491 				       TCS_KEY_HANDLE hKey,           /* in */
492 				       UINT32 publicInfoSize,         /* in */
493 				       BYTE *publicInfo,              /* in */
494 				       TPM_ENCAUTH *encDelAuth,        /* in */
495 				       TPM_AUTH *keyAuth,             /* in, out */
496 				       UINT32 *blobSize,              /* out */
497 				       BYTE **blob)                   /* out */
498 {
499 	TSS_RESULT result;
500 	UINT32 handlesLen, decLen, dataLen;
501 	TCS_HANDLE *handles, handle;
502 	TPM_DIGEST pubKeyHash;
503 	Trspi_HashCtx hashCtx;
504 	UINT64 offset;
505 	BYTE *data, *dec = NULL;
506 
507 	if ((result = obj_context_transport_init(tspContext)))
508 		return result;
509 
510 	LogDebugFn("Executing in a transport session");
511 
512 	if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
513 		return result;
514 
515 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
516 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
517 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
518 		return result;
519 
520 	handlesLen = 1;
521 	handle = hKey;
522 	handles = &handle;
523 
524 	dataLen = publicInfoSize + sizeof(TPM_ENCAUTH);
525 	if ((data = malloc(dataLen)) == NULL) {
526 		LogError("malloc of %u bytes failed", dataLen);
527 		return TSPERR(TSS_E_OUTOFMEMORY);
528 	}
529 
530 	offset = 0;
531 	Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo);
532 	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata);
533 
534 	if ((result = obj_context_transport_execute(tspContext,
535 						    TPM_ORD_Delegate_CreateKeyDelegation, dataLen,
536 						    data, &pubKeyHash, &handlesLen, &handles,
537 						    keyAuth, NULL, &decLen, &dec))) {
538 		free(data);
539 		return result;
540 	}
541 	free(data);
542 
543 	offset = 0;
544 	Trspi_UnloadBlob_UINT32(&offset, blobSize, dec);
545 
546 	if ((*blob = malloc(*blobSize)) == NULL) {
547 		free(dec);
548 		LogError("malloc of %u bytes failed", *blobSize);
549 		*blobSize = 0;
550 		return TSPERR(TSS_E_OUTOFMEMORY);
551 	}
552 	Trspi_UnloadBlob(&offset, *blobSize, dec, *blob);
553 
554 	free(dec);
555 
556 	return result;
557 }
558 
559 TSS_RESULT
560 Transport_Delegate_CreateOwnerDelegation(TSS_HCONTEXT tspContext,       /* in */
561 					 TSS_BOOL increment,          /* in */
562 					 UINT32 publicInfoSize,       /* in */
563 					 BYTE *publicInfo,            /* in */
564 					 TPM_ENCAUTH *encDelAuth,      /* in */
565 					 TPM_AUTH *ownerAuth,         /* in, out */
566 					 UINT32 *blobSize,            /* out */
567 					 BYTE **blob)                 /* out */
568 {
569 	TSS_RESULT result;
570 	UINT32 handlesLen = 0, decLen, dataLen;
571 	UINT64 offset;
572 	BYTE *data, *dec = NULL;
573 
574 	if ((result = obj_context_transport_init(tspContext)))
575 		return result;
576 
577 	LogDebugFn("Executing in a transport session");
578 
579 	dataLen = sizeof(TSS_BOOL) + publicInfoSize + sizeof(TPM_ENCAUTH);
580 	if ((data = malloc(dataLen)) == NULL) {
581 		LogError("malloc of %u bytes failed", dataLen);
582 		return TSPERR(TSS_E_OUTOFMEMORY);
583 	}
584 
585 	offset = 0;
586 	Trspi_LoadBlob_BOOL(&offset, increment, data);
587 	Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo);
588 	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata);
589 
590 	if ((result = obj_context_transport_execute(tspContext,
591 						    TPM_ORD_Delegate_CreateOwnerDelegation, dataLen,
592 						    data, NULL, &handlesLen, NULL, ownerAuth,
593 						    NULL, &decLen, &dec))) {
594 		free(data);
595 		return result;
596 	}
597 	free(data);
598 
599 	offset = 0;
600 	Trspi_UnloadBlob_UINT32(&offset, blobSize, dec);
601 
602 	if ((*blob = malloc(*blobSize)) == NULL) {
603 		free(dec);
604 		LogError("malloc of %u bytes failed", *blobSize);
605 		*blobSize = 0;
606 		return TSPERR(TSS_E_OUTOFMEMORY);
607 	}
608 	Trspi_UnloadBlob(&offset, *blobSize, dec, *blob);
609 
610 	free(dec);
611 
612 	return result;
613 }
614 
615 TSS_RESULT
616 Transport_Delegate_LoadOwnerDelegation(TSS_HCONTEXT tspContext, /* in */
617 				       TPM_DELEGATE_INDEX index,      /* in */
618 				       UINT32 blobSize,               /* in */
619 				       BYTE *blob,                    /* in */
620 				       TPM_AUTH *ownerAuth)           /* in, out */
621 {
622 	TSS_RESULT result;
623 	UINT32 handlesLen = 0, dataLen, decLen;
624 	UINT64 offset;
625 	BYTE *data, *dec = NULL;
626 
627 	if ((result = obj_context_transport_init(tspContext)))
628 		return result;
629 
630 	LogDebugFn("Executing in a transport session");
631 
632 	dataLen = sizeof(TPM_DELEGATE_INDEX) + sizeof(UINT32) + blobSize;
633 	if ((data = malloc(dataLen)) == NULL) {
634 		LogError("malloc of %u bytes failed", dataLen);
635 		return TSPERR(TSS_E_OUTOFMEMORY);
636 	}
637 
638 	offset = 0;
639 	Trspi_LoadBlob_UINT32(&offset, index, data);
640 	Trspi_LoadBlob_UINT32(&offset, blobSize, data);
641 	Trspi_LoadBlob(&offset, blobSize, data, blob);
642 
643 	if ((result = obj_context_transport_execute(tspContext,
644 						    TPM_ORD_Delegate_LoadOwnerDelegation, dataLen,
645 						    data, NULL, &handlesLen, NULL, ownerAuth,
646 						    NULL, &decLen, &dec))) {
647 		free(data);
648 		return result;
649 	}
650 	free(data);
651 	free(dec);
652 
653 	return result;
654 }
655 
656 TSS_RESULT
657 Transport_Delegate_ReadTable(TSS_HCONTEXT tspContext,           /* in */
658 			     UINT32 *familyTableSize,         /* out */
659 			     BYTE **familyTable,              /* out */
660 			     UINT32 *delegateTableSize,       /* out */
661 			     BYTE **delegateTable)            /* out */
662 {
663 	TSS_RESULT result;
664 	UINT32 handlesLen = 0, decLen;
665 	UINT64 offset;
666 	BYTE *dec = NULL;
667 
668 	if ((result = obj_context_transport_init(tspContext)))
669 		return result;
670 
671 	LogDebugFn("Executing in a transport session");
672 
673 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_ReadTable, 0, NULL,
674 						    NULL, &handlesLen, NULL, NULL, NULL, &decLen,
675 						    &dec)))
676 		return result;
677 
678 	offset = 0;
679 	Trspi_UnloadBlob_UINT32(&offset, familyTableSize, dec);
680 
681 	if ((*familyTable = malloc(*familyTableSize)) == NULL) {
682 		free(dec);
683 		LogError("malloc of %u bytes failed", *familyTableSize);
684 		*familyTableSize = 0;
685 		return TSPERR(TSS_E_OUTOFMEMORY);
686 	}
687 	Trspi_UnloadBlob(&offset, *familyTableSize, dec, *familyTable);
688 
689 	Trspi_UnloadBlob_UINT32(&offset, delegateTableSize, dec);
690 
691 	if ((*delegateTable = malloc(*delegateTableSize)) == NULL) {
692 		free(dec);
693 		free(*familyTable);
694 		*familyTable = NULL;
695 		*familyTableSize = 0;
696 		LogError("malloc of %u bytes failed", *delegateTableSize);
697 		*delegateTableSize = 0;
698 		return TSPERR(TSS_E_OUTOFMEMORY);
699 	}
700 	Trspi_UnloadBlob(&offset, *delegateTableSize, dec, *delegateTable);
701 
702 	free(dec);
703 
704 	return result;
705 }
706 
707 TSS_RESULT
708 Transport_Delegate_UpdateVerificationCount(TSS_HCONTEXT tspContext,     /* in */
709 					   UINT32 inputSize,          /* in */
710 					   BYTE *input,               /* in */
711 					   TPM_AUTH *ownerAuth,       /* in, out */
712 					   UINT32 *outputSize,        /* out */
713 					   BYTE **output)             /* out */
714 {
715 	TSS_RESULT result;
716 	UINT32 handlesLen = 0, decLen, dataLen;
717 	UINT64 offset;
718 	BYTE *data, *dec = NULL;
719 
720 
721 	if ((result = obj_context_transport_init(tspContext)))
722 		return result;
723 
724 	LogDebugFn("Executing in a transport session");
725 
726 	dataLen = sizeof(UINT32) + inputSize;
727 	if ((data = malloc(dataLen)) == NULL) {
728 		LogError("malloc of %u bytes failed", dataLen);
729 		return TSPERR(TSS_E_OUTOFMEMORY);
730 	}
731 
732 	offset = 0;
733 	Trspi_LoadBlob_UINT32(&offset, inputSize, data);
734 	Trspi_LoadBlob(&offset, inputSize, data, input);
735 
736 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_UpdateVerification,
737 						    dataLen, data, NULL, &handlesLen, NULL,
738 						    ownerAuth, NULL, &decLen, &dec))) {
739 		free(data);
740 		return result;
741 	}
742 	free(data);
743 
744 	offset = 0;
745 	Trspi_UnloadBlob_UINT32(&offset, outputSize, dec);
746 
747 	if ((*output = malloc(*outputSize)) == NULL) {
748 		free(dec);
749 		LogError("malloc of %u bytes failed", *outputSize);
750 		*outputSize = 0;
751 		return TSPERR(TSS_E_OUTOFMEMORY);
752 	}
753 	Trspi_UnloadBlob(&offset, *outputSize, dec, *output);
754 
755 	free(dec);
756 
757 	return result;
758 }
759 
760 TSS_RESULT
761 Transport_Delegate_VerifyDelegation(TSS_HCONTEXT tspContext,    /* in */
762 				    UINT32 delegateSize,      /* in */
763 				    BYTE *delegate)           /* in */
764 {
765 	TSS_RESULT result;
766 	UINT32 handlesLen = 0, dataLen, decLen;
767 	UINT64 offset;
768 	BYTE *data, *dec = NULL;
769 
770 
771 	if ((result = obj_context_transport_init(tspContext)))
772 		return result;
773 
774 	LogDebugFn("Executing in a transport session");
775 
776 	dataLen = + sizeof(UINT32) + delegateSize;
777 	if ((data = malloc(dataLen)) == NULL) {
778 		LogError("malloc of %u bytes failed", dataLen);
779 		return TSPERR(TSS_E_OUTOFMEMORY);
780 	}
781 
782 	offset = 0;
783 	Trspi_LoadBlob_UINT32(&offset, delegateSize, data);
784 	Trspi_LoadBlob(&offset, delegateSize, data, delegate);
785 
786 	result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_VerifyDelegation,
787 					       dataLen, data, NULL, &handlesLen, NULL, NULL, NULL,
788 					       &decLen, &dec);
789 	free(data);
790 	free(dec);
791 
792 	return result;
793 }
794 
795 TSS_RESULT
796 Transport_DSAP(TSS_HCONTEXT tspContext,		/* in */
797 	       TPM_ENTITY_TYPE entityType,	/* in */
798 	       TCS_KEY_HANDLE keyHandle,	/* in */
799 	       TPM_NONCE *nonceOddDSAP,		/* in */
800 	       UINT32 entityValueSize,		/* in */
801 	       BYTE * entityValue,		/* in */
802 	       TCS_AUTHHANDLE *authHandle,	/* out */
803 	       TPM_NONCE *nonceEven,		/* out */
804 	       TPM_NONCE *nonceEvenDSAP)	/* out */
805 {
806 	TSS_RESULT result;
807 	UINT32 handlesLen, dataLen, decLen;
808 	TCS_HANDLE *handles, handle;
809 	TPM_DIGEST pubKeyHash;
810 	Trspi_HashCtx hashCtx;
811 	UINT64 offset;
812 	BYTE *data, *dec = NULL;
813 
814 	if ((result = obj_context_transport_init(tspContext)))
815 		return result;
816 
817 	LogDebugFn("Executing in a transport session");
818 
819 	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
820 		return result;
821 
822 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
823 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
824 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
825 		return result;
826 
827 	dataLen = sizeof(TPM_ENTITY_TYPE) + sizeof(TPM_KEY_HANDLE)
828 					  + sizeof(TPM_NONCE)
829 					  + sizeof(UINT32)
830 					  + entityValueSize;
831 	if ((data = malloc(dataLen)) == NULL) {
832 		LogError("malloc of %u bytes failed", dataLen);
833 		return TSPERR(TSS_E_OUTOFMEMORY);
834 	}
835 
836 	handlesLen = 1;
837 	handle = keyHandle;
838 	handles = &handle;
839 
840 	offset = 0;
841 	Trspi_LoadBlob_UINT32(&offset, entityType, data);
842 	Trspi_LoadBlob_UINT32(&offset, keyHandle, data);
843 	Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), data, nonceEvenDSAP->nonce);
844 	Trspi_LoadBlob_UINT32(&offset, entityValueSize, data);
845 	Trspi_LoadBlob(&offset, entityValueSize, data, entityValue);
846 
847 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_DSAP, dataLen, data,
848 						    &pubKeyHash, &handlesLen, &handles, NULL, NULL,
849 						    &decLen, &dec))) {
850 		free(data);
851 		return result;
852 	}
853 	free(data);
854 
855 	offset = 0;
856 	Trspi_UnloadBlob_UINT32(&offset, authHandle, dec);
857 
858 	Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEven->nonce);
859 	Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEvenDSAP->nonce);
860 
861 	free(dec);
862 
863 	return result;
864 }
865 #endif
866