diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-11-25 14:36:20 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-11-25 14:36:20 +0000 |
commit | c3649a2def02c41d837ae1f79dda729ccb91e677 (patch) | |
tree | bea46dff212fdef977fe9094a70a939e8cc21885 /src/tspi/tsp_delegate.c | |
download | trousers-c3649a2def02c41d837ae1f79dda729ccb91e677.tar.gz |
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tspi/tsp_delegate.c')
-rw-r--r-- | src/tspi/tsp_delegate.c | 865 |
1 files changed, 865 insertions, 0 deletions
diff --git a/src/tspi/tsp_delegate.c b/src/tspi/tsp_delegate.c new file mode 100644 index 0000000..0319e58 --- /dev/null +++ b/src/tspi/tsp_delegate.c @@ -0,0 +1,865 @@ + +/* + * 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))) + 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))) + 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; + + 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 |