summaryrefslogtreecommitdiff
path: root/src/tspi/tsp_changeauth.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
commitc3649a2def02c41d837ae1f79dda729ccb91e677 (patch)
treebea46dff212fdef977fe9094a70a939e8cc21885 /src/tspi/tsp_changeauth.c
downloadtrousers-c3649a2def02c41d837ae1f79dda729ccb91e677.tar.gz
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tspi/tsp_changeauth.c')
-rw-r--r--src/tspi/tsp_changeauth.c470
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