diff options
Diffstat (limited to 'src/tspi/tsp_changeauth.c')
-rw-r--r-- | src/tspi/tsp_changeauth.c | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/src/tspi/tsp_changeauth.c b/src/tspi/tsp_changeauth.c new file mode 100644 index 0000000..7b194fc --- /dev/null +++ b/src/tspi/tsp_changeauth.c @@ -0,0 +1,470 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + + +TSS_RESULT +Trspi_UnloadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data) +{ + Trspi_UnloadBlob_TCPA_VERSION(offset, blob, &data->ver); + Trspi_UnloadBlob_UINT32(offset, &data->sealInfoSize, blob); + + if (data->sealInfoSize > 0) { + data->sealInfo = malloc(data->sealInfoSize); + if (data->sealInfo == NULL) { + LogError("malloc of %d bytes failed.", data->sealInfoSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(offset, data->sealInfoSize, blob, data->sealInfo); + } else { + data->sealInfo = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &data->encDataSize, blob); + + if (data->encDataSize > 0) { + data->encData = malloc(data->encDataSize); + if (data->encData == NULL) { + LogError("malloc of %d bytes failed.", data->encDataSize); + free(data->sealInfo); + data->sealInfo = NULL; + return TSPERR(TSS_E_OUTOFMEMORY); + } + + Trspi_UnloadBlob(offset, data->encDataSize, blob, data->encData); + } else { + data->encData = NULL; + } + + return TSS_SUCCESS; +} + +void +Trspi_LoadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data) +{ + Trspi_LoadBlob_TCPA_VERSION(offset, blob, data->ver); + Trspi_LoadBlob_UINT32(offset, data->sealInfoSize, blob); + Trspi_LoadBlob(offset, data->sealInfoSize, blob, data->sealInfo); + Trspi_LoadBlob_UINT32(offset, data->encDataSize, blob); + Trspi_LoadBlob(offset, data->encDataSize, blob, data->encData); +} + +TSS_RESULT +changeauth_owner(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + TSS_RESULT result; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + if ((result = authsess_xsap_init(tspContext, hObjectToChange, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner, + TPM_ET_OWNER, &xsap))) + return result; + + /* calculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_OWNER); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP, + &xsap->encAuthUse, TPM_ET_OWNER, + xsap->pAuth))) + goto error; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + result = authsess_xsap_verify(xsap, &digest); +error: + authsess_free(xsap); + + return result; +} + +TSS_RESULT +changeauth_srk(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + TSS_RESULT result; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + + if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner, + TPM_ET_OWNER, &xsap))) + return result; + + /* calculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_SRK); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP, + &xsap->encAuthUse, TPM_ET_SRK, + xsap->pAuth))) + goto error; + + /* Validate the Auths */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + result = authsess_xsap_verify(xsap, &digest); +error: + authsess_free(xsap); + + return result; +} + +TSS_RESULT +changeauth_encdata(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + TSS_RESULT result; + Trspi_HashCtx hashCtx; + TSS_HPOLICY hPolicy; + TCS_KEY_HANDLE keyHandle; + UINT64 offset; + struct authsess *xsap = NULL; + TPM_STORED_DATA storedData; + UINT32 dataBlobLength, newEncSize; + BYTE *dataBlob, *newEncData; + TPM_AUTH auth2; + + /* get the secret for the parent */ + if ((result = obj_encdata_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy))) + return result; + + /* get the data Object */ + if ((result = obj_encdata_get_data(hObjectToChange, &dataBlobLength, &dataBlob))) + return result; + + offset = 0; + if ((result = Trspi_UnloadBlob_STORED_DATA(&offset, dataBlob, &storedData))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle))) + return result; + + if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth, + TPM_ET_KEYHANDLE, &xsap))) + return result; + + /* caluculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT16(&hashCtx, TPM_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TPM_ET_DATA); + result |= Trspi_Hash_UINT32(&hashCtx, storedData.encDataSize); + result |= Trspi_HashUpdate(&hashCtx, storedData.encDataSize, storedData.encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth, + hPolicy, FALSE, &digest, &auth2))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP, + &xsap->encAuthUse, TPM_ET_DATA, + storedData.encDataSize, storedData.encData, + xsap->pAuth, &auth2, &newEncSize, + &newEncData))) + goto error; + + /* Validate the Auths */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT32(&hashCtx, newEncSize); + result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_verify(xsap, &digest))) + goto error; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2))) + goto error; + + memcpy(storedData.encData, newEncData, newEncSize); + free(newEncData); + storedData.encDataSize = newEncSize; + + offset = 0; + Trspi_LoadBlob_STORED_DATA(&offset, dataBlob, &storedData); + + result = obj_encdata_set_data(hObjectToChange, offset, dataBlob); + +error: + authsess_free(xsap); + free(storedData.sealInfo); + free(storedData.encData); + + return result; + +} + +TSS_RESULT +changeauth_key(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + Trspi_HashCtx hashCtx; + TSS_RESULT result; + TSS_KEY keyToChange; + TCS_KEY_HANDLE keyHandle; + struct authsess *xsap = NULL; + UINT32 objectLength; + TSS_HPOLICY hPolicy; + BYTE *keyBlob; + UINT32 newEncSize; + BYTE *newEncData; + TPM_AUTH auth2; + UINT64 offset; + + + if ((result = obj_rsakey_get_blob(hObjectToChange, &objectLength, &keyBlob))) + return result; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyToChange))) { + LogDebug("UnloadBlob_TSS_KEY failed. " + "result=0x%x", result); + return result; + } + + if ((result = obj_rsakey_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy, NULL))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle))) + return result; + + if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth, + keyHandle == TPM_KEYHND_SRK ? + TPM_ET_SRK : TPM_ET_KEYHANDLE, &xsap))) + return result; + + /* caluculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_KEY); + result |= Trspi_Hash_UINT32(&hashCtx, keyToChange.encSize); + result |= Trspi_HashUpdate(&hashCtx, keyToChange.encSize, + keyToChange.encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth, + hPolicy, FALSE, &digest, &auth2))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP, + &xsap->encAuthUse, TPM_ET_KEY, + keyToChange.encSize, keyToChange.encData, + xsap->pAuth, &auth2, &newEncSize, + &newEncData))) + goto error; + + /* Validate the Auths */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT32(&hashCtx, newEncSize); + result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_verify(xsap, &digest))) + goto error; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2))) + return result; + + memcpy(keyToChange.encData, newEncData, newEncSize); + free(newEncData); + + offset = 0; + LoadBlob_TSS_KEY(&offset, keyBlob, &keyToChange); + objectLength = offset; + + result = obj_rsakey_set_tcpakey(hObjectToChange, objectLength, keyBlob); +error: + authsess_free(xsap); + + return result; +} + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_ChangeAuth(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + UINT32 encDataSize, /* in */ + BYTE * encData, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + TPM_AUTH * entityAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(parentHandle, 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 = parentHandle; + handles = &handle; + + dataLen = sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH) + + sizeof(TCPA_ENTITY_TYPE) + + sizeof(UINT32) + + encDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, protocolID, data); + Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata); + Trspi_LoadBlob_UINT16(&offset, entityType, data); + Trspi_LoadBlob_UINT32(&offset, encDataSize, data); + Trspi_LoadBlob(&offset, encDataSize, data, encData); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuth, dataLen, data, + &pubKeyHash, &handlesLen, &handles, + ownerAuth, entityAuth, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec); + + if ((*outData = malloc(*outDataSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *outDataSize); + *outDataSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_ChangeAuthOwner(TSS_HCONTEXT tspContext, /* in */ + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + UINT64 offset; + BYTE data[sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH) + sizeof(TCPA_ENTITY_TYPE)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, protocolID, data); + Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata); + Trspi_LoadBlob_UINT16(&offset, entityType, data); + + return obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuthOwner, sizeof(data), + data, NULL, &handlesLen, NULL, ownerAuth, NULL, NULL, + NULL); +} +#endif |