Home | History | Annotate | Line # | Download | only in tspi
      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 		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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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