/*
* Licensed Materials - Property of IBM
*
* trousers - An open source TCG Software Stack
*
* (C) Copyright International Business Machines Corp. 2007
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "obj.h"
#include "tsplog.h"
#include "tsp_delegate.h"
#include "authsess.h"
TSS_RESULT
do_delegate_manage(TSS_HTPM hTpm, UINT32 familyID, UINT32 opFlag,
UINT32 opDataSize, BYTE *opData, UINT32 *outDataSize, BYTE **outData)
{
TSS_HCONTEXT hContext;
TSS_HPOLICY hPolicy;
UINT32 secretMode = TSS_SECRET_MODE_NONE;
Trspi_HashCtx hashCtx;
TCPA_DIGEST digest;
TPM_AUTH ownerAuth, *pAuth;
UINT32 retDataSize;
BYTE *retData = NULL;
TSS_RESULT result;
if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
return result;
if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy)))
return result;
if (hPolicy != NULL_HPOLICY) {
if ((result = obj_policy_get_mode(hPolicy, &secretMode)))
return result;
}
if (secretMode != TSS_SECRET_MODE_NONE) {
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage);
result |= Trspi_Hash_UINT32(&hashCtx, familyID);
result |= Trspi_Hash_UINT32(&hashCtx, opFlag);
result |= Trspi_Hash_UINT32(&hashCtx, opDataSize);
result |= Trspi_HashUpdate(&hashCtx, opDataSize, opData);
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
return result;
pAuth = &ownerAuth;
if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_Manage, hPolicy, FALSE,
&digest, pAuth)))
return result;
} else
pAuth = NULL;
/* Perform the delegation operation */
if ((result = TCS_API(hContext)->Delegate_Manage(hContext, familyID, opFlag, opDataSize,
opData, pAuth, &retDataSize, &retData)))
return result;
if (pAuth) {
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_UINT32(&hashCtx, result);
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage);
result |= Trspi_Hash_UINT32(&hashCtx, retDataSize);
result |= Trspi_HashUpdate(&hashCtx, retDataSize, retData);
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
free(retData);
goto done;
}
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) {
free(retData);
goto done;
}
}
*outDataSize = retDataSize;
*outData = retData;
done:
return result;
}
TSS_RESULT
create_owner_delegation(TSS_HTPM hTpm,
BYTE bLabel,
UINT32 ulFlags,
TSS_HPCRS hPcrs,
TSS_HDELFAMILY hFamily,
TSS_HPOLICY hDelegation)
{
TSS_HCONTEXT hContext;
TSS_BOOL incrementCount = FALSE;
UINT32 type;
UINT32 publicInfoSize;
BYTE *publicInfo = NULL;
Trspi_HashCtx hashCtx;
TCPA_DIGEST digest;
UINT32 blobSize;
BYTE *blob = NULL;
TSS_RESULT result;
struct authsess *xsap = NULL;
if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
return result;
if ((ulFlags & ~TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT) > 0)
return TSPERR(TSS_E_BAD_PARAMETER);
if (ulFlags & TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT)
incrementCount = TRUE;
if ((result = obj_policy_get_delegation_type(hDelegation, &type)))
return result;
if (type != TSS_DELEGATIONTYPE_OWNER)
return TSPERR(TSS_E_BAD_PARAMETER);
if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation,
&publicInfoSize, &publicInfo)))
return result;
if ((result = authsess_xsap_init(hContext, hTpm, hDelegation, TSS_AUTH_POLICY_NOT_REQUIRED,
TPM_ORD_Delegate_CreateOwnerDelegation, TPM_ET_OWNER,
&xsap))) {
free(publicInfo);
return result;
}
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation);
result |= Trspi_Hash_BOOL(&hashCtx, incrementCount);
result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo);
result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata);
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
goto done;
if ((result = authsess_xsap_hmac(xsap, &digest)))
goto done;
/* Create the delegation */
if ((result = TCS_API(hContext)->Delegate_CreateOwnerDelegation(hContext, incrementCount,
publicInfoSize, publicInfo,
&xsap->encAuthUse,
xsap->pAuth, &blobSize,
&blob)))
goto done;
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_UINT32(&hashCtx, result);
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation);
result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
goto done;
if (authsess_xsap_verify(xsap, &digest)) {
result = TSPERR(TSS_E_TSP_AUTHFAIL);
goto done;
}
result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_OWNER,
blobSize, blob);
done:
authsess_free(xsap);
free(publicInfo);
free(blob);
return result;
}
TSS_RESULT
create_key_delegation(TSS_HKEY hKey,
BYTE bLabel,
UINT32 ulFlags,
TSS_HPCRS hPcrs,
TSS_HDELFAMILY hFamily,
TSS_HPOLICY hDelegation)
{
TSS_HCONTEXT hContext;
UINT32 type;
TCS_KEY_HANDLE tcsKeyHandle;
UINT32 publicInfoSize;
BYTE *publicInfo = NULL;
Trspi_HashCtx hashCtx;
TCPA_DIGEST digest;
UINT32 blobSize;
BYTE *blob = NULL;
TSS_RESULT result;
struct authsess *xsap = NULL;
if ((result = obj_rsakey_get_tsp_context(hKey, &hContext)))
return result;
if (ulFlags != 0)
return TSPERR(TSS_E_BAD_PARAMETER);
if ((result = obj_policy_get_delegation_type(hDelegation, &type)))
return result;
if (type != TSS_DELEGATIONTYPE_KEY)
return TSPERR(TSS_E_BAD_PARAMETER);
if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
return result;
if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation,
&publicInfoSize, &publicInfo)))
return result;
if ((result = authsess_xsap_init(hContext, hKey, hDelegation, TSS_AUTH_POLICY_REQUIRED,
TPM_ORD_Delegate_CreateKeyDelegation, TPM_ET_KEYHANDLE,
&xsap))) {
free(publicInfo);
return result;
}
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation);
result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo);
result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
goto done;
if ((result = authsess_xsap_hmac(xsap, &digest)))
goto done;
/* Create the delegation */
if ((result = TCS_API(hContext)->Delegate_CreateKeyDelegation(hContext, tcsKeyHandle,
publicInfoSize, publicInfo,
&xsap->encAuthUse,
xsap->pAuth, &blobSize,
&blob)))
goto done;
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_UINT32(&hashCtx, result);
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation);
result |= Trspi_Hash_UINT32(&hashCtx, blobSize);
result |= Trspi_HashUpdate(&hashCtx, blobSize, blob);
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
goto done;
if (authsess_xsap_verify(xsap, &digest)) {
result = TSPERR(TSS_E_TSP_AUTHFAIL);
goto done;
}
result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_KEY, blobSize,
blob);
done:
free(blob);
authsess_free(xsap);
free(publicInfo);
return result;
}
TSS_RESULT
update_delfamily_object(TSS_HTPM hTpm, UINT32 familyID)
{
TSS_HCONTEXT hContext;
UINT32 familyTableSize, delegateTableSize;
BYTE *familyTable = NULL, *delegateTable = NULL;
UINT64 offset;
TPM_FAMILY_TABLE_ENTRY familyTableEntry;
TSS_BOOL familyState;
TSS_HDELFAMILY hFamily;
TSS_RESULT result;
if ((result = obj_tpm_get_tsp_context(hTpm, &hContext)))
return result;
if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize,
&familyTable, &delegateTableSize,
&delegateTable)))
return result;
for (offset = 0; offset < familyTableSize;) {
Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&offset, familyTable, &familyTableEntry);
if (familyTableEntry.familyID == familyID) {
obj_delfamily_find_by_familyid(hContext, familyID, &hFamily);
if (hFamily == NULL_HDELFAMILY) {
if ((result = obj_delfamily_add(hContext, &hFamily)))
goto done;
if ((result = obj_delfamily_set_familyid(hFamily,
familyTableEntry.familyID)))
goto done;
if ((result = obj_delfamily_set_label(hFamily,
familyTableEntry.label.label)))
goto done;
}
/* Set/Update the family attributes */
familyState = (familyTableEntry.flags & TPM_FAMFLAG_DELEGATE_ADMIN_LOCK) ?
TRUE : FALSE;
if ((result = obj_delfamily_set_locked(hFamily, familyState, FALSE)))
goto done;
familyState = (familyTableEntry.flags & TPM_FAMFLAG_ENABLE) ? TRUE : FALSE;
if ((result = obj_delfamily_set_enabled(hFamily, familyState, FALSE)))
goto done;
if ((result = obj_delfamily_set_vercount(hFamily,
familyTableEntry.verificationCount)))
goto done;
break;
}
}
done:
free(familyTable);
free(delegateTable);
return result;
}
TSS_RESULT
get_delegate_index(TSS_HCONTEXT hContext, UINT32 index, TPM_DELEGATE_PUBLIC *public)
{
UINT32 familyTableSize, delegateTableSize;
BYTE *familyTable = NULL, *delegateTable = NULL;
UINT64 offset;
UINT32 tpmIndex;
TPM_DELEGATE_PUBLIC tempPublic;
TSS_RESULT result;
if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize,
&familyTable, &delegateTableSize,
&delegateTable)))
goto done;
for (offset = 0; offset < delegateTableSize;) {
Trspi_UnloadBlob_UINT32(&offset, &tpmIndex, delegateTable);
if (tpmIndex == index) {
result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, public);
goto done;
} else {
if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, &tempPublic)))
goto done;
}
free(tempPublic.pcrInfo.pcrSelection.pcrSelect);
}
/* Didn't find a matching index */
result = TSPERR(TSS_E_BAD_PARAMETER);
done:
free(familyTable);
free(delegateTable);
return result;
}
TSS_RESULT
__tspi_build_delegate_public_info(BYTE bLabel,
TSS_HPCRS hPcrs,
TSS_HDELFAMILY hFamily,
TSS_HPOLICY hDelegation,
UINT32 *publicInfoSize,
BYTE **publicInfo)
{
TPM_DELEGATE_PUBLIC public;
UINT32 delegateType;
UINT32 pcrInfoSize;
BYTE *pcrInfo = NULL;
UINT64 offset;
TSS_RESULT result = TSS_SUCCESS;
if (hDelegation == NULL_HPOLICY)
return TSPERR(TSS_E_BAD_PARAMETER);
if ((result = obj_policy_get_delegation_type(hDelegation, &delegateType)))
return result;
/* This call will create a "null" PCR_INFO_SHORT if hPcrs is null */
if ((result = obj_pcrs_create_info_short(hPcrs, &pcrInfoSize, &pcrInfo)))
return result;
__tspi_memset(&public, 0, sizeof(public));
public.tag = TPM_TAG_DELEGATE_PUBLIC;
public.label.label = bLabel;
offset = 0;
if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, pcrInfo, &public.pcrInfo)))
goto done;
public.permissions.tag = TPM_TAG_DELEGATIONS;
public.permissions.delegateType =
(delegateType == TSS_DELEGATIONTYPE_OWNER) ? TPM_DEL_OWNER_BITS : TPM_DEL_KEY_BITS;
if ((result = obj_policy_get_delegation_per1(hDelegation, &public.permissions.per1)))
goto done;
if ((result = obj_policy_get_delegation_per2(hDelegation, &public.permissions.per2)))
goto done;
if ((result = obj_delfamily_get_familyid(hFamily, &public.familyID)))
goto done;
if ((result = obj_delfamily_get_vercount(hFamily, &public.verificationCount)))
goto done;
offset = 0;
Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, NULL, &public);
*publicInfoSize = offset;
*publicInfo = malloc(*publicInfoSize);
if (*publicInfo == NULL) {
LogError("malloc of %u bytes failed.", *publicInfoSize);
result = TSPERR(TSS_E_OUTOFMEMORY);
goto done;
}
offset = 0;
Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, *publicInfo, &public);
done:
free(pcrInfo);
free(public.pcrInfo.pcrSelection.pcrSelect);
return result;
}
#ifdef TSS_BUILD_TRANSPORT
TSS_RESULT
Transport_Delegate_Manage(TSS_HCONTEXT tspContext, /* in */
TPM_FAMILY_ID familyID, /* in */
TPM_FAMILY_OPERATION opFlag, /* in */
UINT32 opDataSize, /* in */
BYTE *opData, /* in */
TPM_AUTH *ownerAuth, /* in, out */
UINT32 *retDataSize, /* out */
BYTE **retData) /* out */
{
TSS_RESULT result;
UINT32 handlesLen = 0, decLen, dataLen;
UINT64 offset;
BYTE *data, *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
dataLen = sizeof(TPM_FAMILY_ID)
+ sizeof(TPM_FAMILY_OPERATION)
+ sizeof(UINT32)
+ opDataSize;
if ((data = malloc(dataLen)) == NULL) {
LogError("malloc of %u bytes failed", dataLen);
return TSPERR(TSS_E_OUTOFMEMORY);
}
offset = 0;
Trspi_LoadBlob_UINT32(&offset, familyID, data);
Trspi_LoadBlob_UINT32(&offset, opFlag, data);
Trspi_LoadBlob_UINT32(&offset, opDataSize, data);
Trspi_LoadBlob(&offset, opDataSize, data, opData);
if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_Manage, dataLen,
data, NULL, &handlesLen, NULL, ownerAuth,
NULL, &decLen, &dec))) {
free(data);
return result;
}
free(data);
offset = 0;
Trspi_UnloadBlob_UINT32(&offset, retDataSize, dec);
if ((*retData = malloc(*retDataSize)) == NULL) {
free(dec);
LogError("malloc of %u bytes failed", *retDataSize);
*retDataSize = 0;
return TSPERR(TSS_E_OUTOFMEMORY);
}
Trspi_UnloadBlob(&offset, *retDataSize, dec, *retData);
free(dec);
return result;
}
TSS_RESULT
Transport_Delegate_CreateKeyDelegation(TSS_HCONTEXT tspContext, /* in */
TCS_KEY_HANDLE hKey, /* in */
UINT32 publicInfoSize, /* in */
BYTE *publicInfo, /* in */
TPM_ENCAUTH *encDelAuth, /* in */
TPM_AUTH *keyAuth, /* in, out */
UINT32 *blobSize, /* out */
BYTE **blob) /* out */
{
TSS_RESULT result;
UINT32 handlesLen, decLen, dataLen;
TCS_HANDLE *handles, handle;
TPM_DIGEST pubKeyHash;
Trspi_HashCtx hashCtx;
UINT64 offset;
BYTE *data, *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
return result;
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
return result;
handlesLen = 1;
handle = hKey;
handles = &handle;
dataLen = publicInfoSize + sizeof(TPM_ENCAUTH);
if ((data = malloc(dataLen)) == NULL) {
LogError("malloc of %u bytes failed", dataLen);
return TSPERR(TSS_E_OUTOFMEMORY);
}
offset = 0;
Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo);
Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata);
if ((result = obj_context_transport_execute(tspContext,
TPM_ORD_Delegate_CreateKeyDelegation, dataLen,
data, &pubKeyHash, &handlesLen, &handles,
keyAuth, NULL, &decLen, &dec))) {
free(data);
return result;
}
free(data);
offset = 0;
Trspi_UnloadBlob_UINT32(&offset, blobSize, dec);
if ((*blob = malloc(*blobSize)) == NULL) {
free(dec);
LogError("malloc of %u bytes failed", *blobSize);
*blobSize = 0;
return TSPERR(TSS_E_OUTOFMEMORY);
}
Trspi_UnloadBlob(&offset, *blobSize, dec, *blob);
free(dec);
return result;
}
TSS_RESULT
Transport_Delegate_CreateOwnerDelegation(TSS_HCONTEXT tspContext, /* in */
TSS_BOOL increment, /* in */
UINT32 publicInfoSize, /* in */
BYTE *publicInfo, /* in */
TPM_ENCAUTH *encDelAuth, /* in */
TPM_AUTH *ownerAuth, /* in, out */
UINT32 *blobSize, /* out */
BYTE **blob) /* out */
{
TSS_RESULT result;
UINT32 handlesLen = 0, decLen, dataLen;
UINT64 offset;
BYTE *data, *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
dataLen = sizeof(TSS_BOOL) + publicInfoSize + sizeof(TPM_ENCAUTH);
if ((data = malloc(dataLen)) == NULL) {
LogError("malloc of %u bytes failed", dataLen);
return TSPERR(TSS_E_OUTOFMEMORY);
}
offset = 0;
Trspi_LoadBlob_BOOL(&offset, increment, data);
Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo);
Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata);
if ((result = obj_context_transport_execute(tspContext,
TPM_ORD_Delegate_CreateOwnerDelegation, dataLen,
data, NULL, &handlesLen, NULL, ownerAuth,
NULL, &decLen, &dec))) {
free(data);
return result;
}
free(data);
offset = 0;
Trspi_UnloadBlob_UINT32(&offset, blobSize, dec);
if ((*blob = malloc(*blobSize)) == NULL) {
free(dec);
LogError("malloc of %u bytes failed", *blobSize);
*blobSize = 0;
return TSPERR(TSS_E_OUTOFMEMORY);
}
Trspi_UnloadBlob(&offset, *blobSize, dec, *blob);
free(dec);
return result;
}
TSS_RESULT
Transport_Delegate_LoadOwnerDelegation(TSS_HCONTEXT tspContext, /* in */
TPM_DELEGATE_INDEX index, /* in */
UINT32 blobSize, /* in */
BYTE *blob, /* in */
TPM_AUTH *ownerAuth) /* in, out */
{
TSS_RESULT result;
UINT32 handlesLen = 0, dataLen, decLen;
UINT64 offset;
BYTE *data, *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
dataLen = sizeof(TPM_DELEGATE_INDEX) + sizeof(UINT32) + blobSize;
if ((data = malloc(dataLen)) == NULL) {
LogError("malloc of %u bytes failed", dataLen);
return TSPERR(TSS_E_OUTOFMEMORY);
}
offset = 0;
Trspi_LoadBlob_UINT32(&offset, index, data);
Trspi_LoadBlob_UINT32(&offset, blobSize, data);
Trspi_LoadBlob(&offset, blobSize, data, blob);
if ((result = obj_context_transport_execute(tspContext,
TPM_ORD_Delegate_LoadOwnerDelegation, dataLen,
data, NULL, &handlesLen, NULL, ownerAuth,
NULL, &decLen, &dec))) {
free(data);
return result;
}
free(data);
free(dec);
return result;
}
TSS_RESULT
Transport_Delegate_ReadTable(TSS_HCONTEXT tspContext, /* in */
UINT32 *familyTableSize, /* out */
BYTE **familyTable, /* out */
UINT32 *delegateTableSize, /* out */
BYTE **delegateTable) /* out */
{
TSS_RESULT result;
UINT32 handlesLen = 0, decLen;
UINT64 offset;
BYTE *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_ReadTable, 0, NULL,
NULL, &handlesLen, NULL, NULL, NULL, &decLen,
&dec)))
return result;
offset = 0;
Trspi_UnloadBlob_UINT32(&offset, familyTableSize, dec);
if ((*familyTable = malloc(*familyTableSize)) == NULL) {
free(dec);
LogError("malloc of %u bytes failed", *familyTableSize);
*familyTableSize = 0;
return TSPERR(TSS_E_OUTOFMEMORY);
}
Trspi_UnloadBlob(&offset, *familyTableSize, dec, *familyTable);
Trspi_UnloadBlob_UINT32(&offset, delegateTableSize, dec);
if ((*delegateTable = malloc(*delegateTableSize)) == NULL) {
free(dec);
free(*familyTable);
*familyTable = NULL;
*familyTableSize = 0;
LogError("malloc of %u bytes failed", *delegateTableSize);
*delegateTableSize = 0;
return TSPERR(TSS_E_OUTOFMEMORY);
}
Trspi_UnloadBlob(&offset, *delegateTableSize, dec, *delegateTable);
free(dec);
return result;
}
TSS_RESULT
Transport_Delegate_UpdateVerificationCount(TSS_HCONTEXT tspContext, /* in */
UINT32 inputSize, /* in */
BYTE *input, /* in */
TPM_AUTH *ownerAuth, /* in, out */
UINT32 *outputSize, /* out */
BYTE **output) /* out */
{
TSS_RESULT result;
UINT32 handlesLen = 0, decLen, dataLen;
UINT64 offset;
BYTE *data, *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
dataLen = sizeof(UINT32) + inputSize;
if ((data = malloc(dataLen)) == NULL) {
LogError("malloc of %u bytes failed", dataLen);
return TSPERR(TSS_E_OUTOFMEMORY);
}
offset = 0;
Trspi_LoadBlob_UINT32(&offset, inputSize, data);
Trspi_LoadBlob(&offset, inputSize, data, input);
if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_UpdateVerification,
dataLen, data, NULL, &handlesLen, NULL,
ownerAuth, NULL, &decLen, &dec))) {
free(data);
return result;
}
free(data);
offset = 0;
Trspi_UnloadBlob_UINT32(&offset, outputSize, dec);
if ((*output = malloc(*outputSize)) == NULL) {
free(dec);
LogError("malloc of %u bytes failed", *outputSize);
*outputSize = 0;
return TSPERR(TSS_E_OUTOFMEMORY);
}
Trspi_UnloadBlob(&offset, *outputSize, dec, *output);
free(dec);
return result;
}
TSS_RESULT
Transport_Delegate_VerifyDelegation(TSS_HCONTEXT tspContext, /* in */
UINT32 delegateSize, /* in */
BYTE *delegate) /* in */
{
TSS_RESULT result;
UINT32 handlesLen = 0, dataLen, decLen;
UINT64 offset;
BYTE *data, *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
dataLen = + sizeof(UINT32) + delegateSize;
if ((data = malloc(dataLen)) == NULL) {
LogError("malloc of %u bytes failed", dataLen);
return TSPERR(TSS_E_OUTOFMEMORY);
}
offset = 0;
Trspi_LoadBlob_UINT32(&offset, delegateSize, data);
Trspi_LoadBlob(&offset, delegateSize, data, delegate);
result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_VerifyDelegation,
dataLen, data, NULL, &handlesLen, NULL, NULL, NULL,
&decLen, &dec);
free(data);
free(dec);
return result;
}
TSS_RESULT
Transport_DSAP(TSS_HCONTEXT tspContext, /* in */
TPM_ENTITY_TYPE entityType, /* in */
TCS_KEY_HANDLE keyHandle, /* in */
TPM_NONCE *nonceOddDSAP, /* in */
UINT32 entityValueSize, /* in */
BYTE * entityValue, /* in */
TCS_AUTHHANDLE *authHandle, /* out */
TPM_NONCE *nonceEven, /* out */
TPM_NONCE *nonceEvenDSAP) /* out */
{
TSS_RESULT result;
UINT32 handlesLen, dataLen, decLen;
TCS_HANDLE *handles, handle;
TPM_DIGEST pubKeyHash;
Trspi_HashCtx hashCtx;
UINT64 offset;
BYTE *data, *dec = NULL;
if ((result = obj_context_transport_init(tspContext)))
return result;
LogDebugFn("Executing in a transport session");
if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
return result;
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
return result;
dataLen = sizeof(TPM_ENTITY_TYPE) + sizeof(TPM_KEY_HANDLE)
+ sizeof(TPM_NONCE)
+ sizeof(UINT32)
+ entityValueSize;
if ((data = malloc(dataLen)) == NULL) {
LogError("malloc of %u bytes failed", dataLen);
return TSPERR(TSS_E_OUTOFMEMORY);
}
handlesLen = 1;
handle = keyHandle;
handles = &handle;
offset = 0;
Trspi_LoadBlob_UINT32(&offset, entityType, data);
Trspi_LoadBlob_UINT32(&offset, keyHandle, data);
Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), data, nonceEvenDSAP->nonce);
Trspi_LoadBlob_UINT32(&offset, entityValueSize, data);
Trspi_LoadBlob(&offset, entityValueSize, data, entityValue);
if ((result = obj_context_transport_execute(tspContext, TPM_ORD_DSAP, dataLen, data,
&pubKeyHash, &handlesLen, &handles, NULL, NULL,
&decLen, &dec))) {
free(data);
return result;
}
free(data);
offset = 0;
Trspi_UnloadBlob_UINT32(&offset, authHandle, dec);
Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEven->nonce);
Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEvenDSAP->nonce);
free(dec);
return result;
}
#endif