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