summaryrefslogtreecommitdiff
path: root/src/tspi/tspi_cmk.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/tspi_cmk.c
downloadtrousers-upstream.tar.gz
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tspi/tspi_cmk.c')
-rw-r--r--src/tspi/tspi_cmk.c475
1 files changed, 475 insertions, 0 deletions
diff --git a/src/tspi/tspi_cmk.c b/src/tspi/tspi_cmk.c
new file mode 100644
index 0000000..6ced203
--- /dev/null
+++ b/src/tspi/tspi_cmk.c
@@ -0,0 +1,475 @@
+
+/*
+ * 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 <inttypes.h>
+
+#include "trousers/tss.h"
+#include "trousers/trousers.h"
+#include "trousers_types.h"
+#include "spi_utils.h"
+#include "obj.h"
+#include "tsplog.h"
+
+
+TSS_RESULT
+Tspi_TPM_CMKSetRestrictions(TSS_HTPM hTpm, /* in */
+ TSS_CMK_DELEGATE CmkDelegate) /* in */
+{
+ TSS_HCONTEXT hContext;
+ TSS_HPOLICY hPolicy;
+ Trspi_HashCtx hashCtx;
+ TPM_DIGEST digest;
+ TPM_AUTH ownerAuth;
+ 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;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions);
+ result |= Trspi_Hash_UINT32(&hashCtx, CmkDelegate);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ return result;
+
+ if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_SetRestrictions,
+ hPolicy, FALSE, &digest, &ownerAuth)))
+ return result;
+
+ if ((result = RPC_CMK_SetRestrictions(hContext, CmkDelegate, &ownerAuth)))
+ return result;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, result);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ return result;
+
+ if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
+ return result;
+
+ return result;
+}
+
+TSS_RESULT
+Tspi_TPM_CMKApproveMA(TSS_HTPM hTpm, /* in */
+ TSS_HMIGDATA hMaAuthData) /* in */
+{
+ TSS_HCONTEXT hContext;
+ TSS_HPOLICY hPolicy;
+ UINT32 blobSize;
+ BYTE *blob;
+ TPM_DIGEST msaDigest;
+ TPM_HMAC msaHmac;
+ Trspi_HashCtx hashCtx;
+ TPM_DIGEST digest;
+ TPM_AUTH ownerAuth;
+ 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 ((result = obj_migdata_get_msa_digest(hMaAuthData, &blobSize, &blob)))
+ return result;
+ memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest));
+ free_tspi(hContext, blob);
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA);
+ result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ return result;
+
+ if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_ApproveMA,
+ hPolicy, FALSE, &digest, &ownerAuth)))
+ return result;
+
+ if ((result = RPC_CMK_ApproveMA(hContext, msaDigest, &ownerAuth, &msaHmac)))
+ return result;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, result);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA);
+ result |= Trspi_Hash_HMAC(&hashCtx, msaHmac.digest);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ return result;
+
+ if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
+ return result;
+
+ if ((result = obj_migdata_set_msa_hmac(hMaAuthData, sizeof(msaHmac.digest), msaHmac.digest)))
+ return result;
+
+ return result;
+}
+
+TSS_RESULT
+Tspi_TPM_CMKCreateTicket(TSS_HTPM hTpm, /* in */
+ TSS_HKEY hVerifyKey, /* in */
+ TSS_HMIGDATA hSigData) /* in */
+{
+ TSS_HCONTEXT hContext;
+ TSS_HPOLICY hPolicy;
+ UINT32 pubKeySize;
+ BYTE *pubKey = NULL;
+ UINT32 blobSize;
+ BYTE *blob;
+ TPM_DIGEST sigData;
+ UINT32 sigSize;
+ BYTE *sig = NULL;
+ TPM_HMAC sigTicket;
+ Trspi_HashCtx hashCtx;
+ TPM_DIGEST digest;
+ TPM_AUTH ownerAuth;
+ 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 ((result = obj_rsakey_get_pub_blob(hVerifyKey, &pubKeySize, &pubKey)))
+ return result;
+
+ if ((result = obj_migdata_get_sig_data(hSigData, &blobSize, &blob)))
+ goto done;
+ memcpy(sigData.digest, blob, sizeof(sigData.digest));
+ free_tspi(hContext, blob);
+
+ if ((result = obj_migdata_get_sig_value(hSigData, &sigSize, &sig)))
+ goto done;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket);
+ result |= Trspi_HashUpdate(&hashCtx, pubKeySize, pubKey);
+ result |= Trspi_Hash_DIGEST(&hashCtx, sigData.digest);
+ result |= Trspi_Hash_UINT32(&hashCtx, sigSize);
+ result |= Trspi_HashUpdate(&hashCtx, sigSize, sig);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ goto done;
+
+ if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_CreateTicket,
+ hPolicy, FALSE, &digest, &ownerAuth)))
+ goto done;
+
+ if ((result = RPC_CMK_CreateTicket(hContext, pubKeySize, pubKey, sigData, sigSize, sig,
+ &ownerAuth, &sigTicket)))
+ goto done;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, result);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket);
+ result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ goto done;
+
+ if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth)))
+ goto done;
+
+ if ((result = obj_migdata_set_sig_ticket(hSigData, sizeof(sigTicket.digest), sigTicket.digest)))
+ goto done;
+
+done:
+ free_tspi(hContext, pubKey);
+ free_tspi(hContext, sig);
+
+ return result;
+}
+
+TSS_RESULT
+Tspi_Key_CMKCreateBlob(TSS_HKEY hKeyToMigrate, /* in */
+ TSS_HKEY hParentKey, /* in */
+ TSS_HMIGDATA hMigrationData, /* in */
+ UINT32* pulRandomLength, /* out */
+ BYTE** prgbRandom) /* out */
+{
+ TSS_HCONTEXT hContext;
+ TSS_HPOLICY hPolicy;
+ TSS_BOOL usageAuth;
+ TCS_KEY_HANDLE tcsKeyHandle;
+ TSS_MIGRATE_SCHEME migScheme;
+ UINT32 migTicketSize;
+ BYTE *migTicket = NULL;
+ TPM_MIGRATIONKEYAUTH tpmMigKeyAuth;
+ UINT32 msaListSize, restrictTicketSize, sigTicketSize, blobSize;
+ BYTE *msaList = NULL, *restrictTicket = NULL, *blob = NULL;
+ BYTE *sigTicket = NULL;
+ UINT32 pubBlobSize;
+ BYTE *pubBlob = NULL;
+ TPM_DIGEST srcPubKeyDigest;
+ TSS_KEY tssKey;
+ UINT32 randomDataSize, outDataSize, newBlobSize;
+ BYTE *randomData = NULL, *outData = NULL, *newBlob = NULL;
+ Trspi_HashCtx hashCtx;
+ TPM_DIGEST digest;
+ TPM_AUTH parentAuth, *pAuth;
+ UINT64 offset;
+ TSS_RESULT result;
+
+ memset(&tssKey, 0, sizeof(tssKey));
+
+ if (!pulRandomLength || !prgbRandom)
+ return TSPERR(TSS_E_BAD_PARAMETER);
+
+ if (!obj_rsakey_is_cmk(hKeyToMigrate))
+ return TSPERR(TSS_E_BAD_PARAMETER);
+
+ if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext)))
+ return result;
+
+ if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth)))
+ return result;
+
+ if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle)))
+ return result;
+
+ if ((result = obj_migdata_get_ticket_blob(hMigrationData, &migTicketSize, &migTicket)))
+ return result;
+
+ /* Just to get the migration scheme... */
+ offset = 0;
+ if ((result = Trspi_UnloadBlob_MIGRATIONKEYAUTH(&offset, migTicket, &tpmMigKeyAuth)))
+ goto done;
+ /* ... so free everything now */
+ free(tpmMigKeyAuth.migrationKey.algorithmParms.parms);
+ free(tpmMigKeyAuth.migrationKey.pubKey.key);
+ migScheme = tpmMigKeyAuth.migrationScheme;
+
+ if ((result = obj_rsakey_get_pub_blob(hKeyToMigrate, &pubBlobSize, &pubBlob)))
+ goto done;
+ if ((result = obj_migdata_calc_pubkey_digest(pubBlobSize, pubBlob, &srcPubKeyDigest)))
+ goto done;
+
+ if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList)))
+ goto done;
+
+ if (tpmMigKeyAuth.migrationScheme == TPM_MS_RESTRICT_APPROVE_DOUBLE) {
+ if ((result = obj_migdata_get_cmk_auth_blob(hMigrationData, &restrictTicketSize,
+ &restrictTicket)))
+ goto done;
+ if ((result = obj_migdata_get_sig_ticket(hMigrationData, &sigTicketSize,
+ &sigTicket)))
+ goto done;
+ } else {
+ restrictTicketSize = 0;
+ sigTicketSize = 0;
+ }
+
+ if ((result = obj_rsakey_get_blob(hKeyToMigrate, &blobSize, &blob)))
+ goto done;
+
+ offset = 0;
+ if ((result = UnloadBlob_TSS_KEY(&offset, blob, &tssKey)))
+ goto done;
+
+ if (usageAuth) {
+ pAuth = &parentAuth;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob);
+ result |= Trspi_Hash_UINT16(&hashCtx, migScheme);
+ result |= Trspi_HashUpdate(&hashCtx, migTicketSize, migTicket);
+ result |= Trspi_Hash_DIGEST(&hashCtx, srcPubKeyDigest.digest);
+ result |= Trspi_Hash_UINT32(&hashCtx, msaListSize);
+ result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList);
+ result |= Trspi_Hash_UINT32(&hashCtx, restrictTicketSize);
+ result |= Trspi_HashUpdate(&hashCtx, restrictTicketSize, restrictTicket);
+ result |= Trspi_Hash_UINT32(&hashCtx, sigTicketSize);
+ result |= Trspi_HashUpdate(&hashCtx, sigTicketSize, sigTicket);
+ result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize);
+ result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ goto done;
+
+ if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_CreateBlob,
+ hPolicy, FALSE, &digest, pAuth)))
+ goto done;
+ } else
+ pAuth = NULL;
+
+ if ((result = RPC_CMK_CreateBlob(hContext, tcsKeyHandle, migScheme,
+ migTicketSize, migTicket, srcPubKeyDigest, msaListSize, msaList,
+ restrictTicketSize, restrictTicket, sigTicketSize, sigTicket,
+ tssKey.encSize, tssKey.encData, pAuth, &randomDataSize, &randomData,
+ &outDataSize, &outData)))
+ goto done;
+
+ if (pAuth) {
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, result);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob);
+ result |= Trspi_Hash_UINT32(&hashCtx, randomDataSize);
+ result |= Trspi_HashUpdate(&hashCtx, randomDataSize, randomData);
+ result |= Trspi_Hash_UINT32(&hashCtx, outDataSize);
+ result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ goto done;
+ }
+
+ if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
+ goto done;
+
+ /* Create the migdata key blob */
+ free(tssKey.encData);
+ tssKey.encSize = outDataSize;
+ tssKey.encData = outData;
+ /* Set outData to null since it will now be freed during key ref freeing */
+ outData = NULL;
+
+ offset = 0;
+ LoadBlob_TSS_KEY(&offset, NULL, &tssKey);
+
+ newBlobSize = offset;
+ if ((newBlob = malloc(newBlobSize)) == NULL) {
+ LogError("malloc of %u bytes failed.", newBlobSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ offset = 0;
+ LoadBlob_TSS_KEY(&offset, newBlob, &tssKey);
+
+ if ((result = obj_migdata_set_blob(hMigrationData, newBlobSize, newBlob)))
+ goto done;
+
+ if ((*prgbRandom = calloc_tspi(hContext, randomDataSize)) == NULL) {
+ LogError("malloc of %u bytes failed.", randomDataSize);
+ result = TSPERR(TSS_E_OUTOFMEMORY);
+ goto done;
+ }
+ memcpy(*prgbRandom, randomData, randomDataSize);
+ *pulRandomLength = randomDataSize;
+
+done:
+ free_tspi(hContext, migTicket);
+ free_tspi(hContext, pubBlob);
+ free_tspi(hContext, msaList);
+ free_tspi(hContext, restrictTicket);
+ free_tspi(hContext, sigTicket);
+ free_tspi(hContext, blob);
+ free(randomData);
+ free(outData);
+ free(newBlob);
+ free_key_refs(&tssKey);
+
+ return result;
+}
+
+TSS_RESULT
+Tspi_Key_CMKConvertMigration(TSS_HKEY hKeyToMigrate, /* in */
+ TSS_HKEY hParentKey, /* in */
+ TSS_HMIGDATA hMigrationData, /* in */
+ UINT32 ulRandomLength, /* in */
+ BYTE* rgbRandom) /* in */
+{
+ TSS_HCONTEXT hContext;
+ TSS_HPOLICY hPolicy;
+ TSS_BOOL usageAuth;
+ TCS_KEY_HANDLE tcsKeyHandle;
+ TPM_CMK_AUTH restrictTicket;
+ UINT32 blobSize;
+ BYTE *blob;
+ TPM_HMAC sigTicket;
+ UINT32 migDataSize, msaListSize;
+ BYTE *migData = NULL, *msaList = NULL;
+ UINT32 outDataSize;
+ BYTE *outData = NULL;
+ Trspi_HashCtx hashCtx;
+ TPM_DIGEST digest;
+ TPM_AUTH parentAuth, *pAuth;
+ TSS_RESULT result;
+
+ if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext)))
+ return result;
+
+ if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth)))
+ return result;
+
+ if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle)))
+ return result;
+
+ if ((result = obj_migdata_get_cmk_auth(hMigrationData, &restrictTicket)))
+ return result;
+
+ if ((result = obj_migdata_get_sig_ticket(hMigrationData, &blobSize, &blob)))
+ return result;
+ memcpy(sigTicket.digest, blob, sizeof(sigTicket.digest));
+ free_tspi(hContext, blob);
+
+ if ((result = obj_migdata_get_blob(hMigrationData, &migDataSize, &migData)))
+ goto done;
+
+ if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList)))
+ goto done;
+
+ if (usageAuth) {
+ pAuth = &parentAuth;
+
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration);
+ result |= Trspi_HashUpdate(&hashCtx, sizeof(restrictTicket),
+ (BYTE *)&restrictTicket);
+ result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest);
+ result |= Trspi_HashUpdate(&hashCtx, migDataSize, migData);
+ result |= Trspi_Hash_UINT32(&hashCtx, msaListSize);
+ result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList);
+ result |= Trspi_Hash_UINT32(&hashCtx, ulRandomLength);
+ result |= Trspi_HashUpdate(&hashCtx, ulRandomLength, rgbRandom);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ goto done;
+
+ if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_ConvertMigration,
+ hPolicy, FALSE, &digest, pAuth)))
+ goto done;
+ } else
+ pAuth = NULL;
+
+ if ((result = RPC_CMK_ConvertMigration(hContext, tcsKeyHandle, restrictTicket, sigTicket,
+ migDataSize, migData, msaListSize, msaList, ulRandomLength, rgbRandom,
+ pAuth, &outDataSize, &outData)))
+ goto done;
+
+ if (pAuth) {
+ result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
+ result |= Trspi_Hash_UINT32(&hashCtx, result);
+ result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration);
+ result |= Trspi_Hash_UINT32(&hashCtx, outDataSize);
+ result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData);
+ if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
+ goto done;
+ }
+
+ if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
+ goto done;
+
+ /* Set the key object to the now migrated key */
+ if ((result = obj_rsakey_set_tcpakey(hKeyToMigrate, migDataSize, migData)))
+ goto done;
+ if ((result = obj_rsakey_set_privkey(hKeyToMigrate, TRUE, outDataSize, outData)))
+ goto done;
+ result = obj_rsakey_set_tcs_handle(hKeyToMigrate, 0);
+
+done:
+ free_tspi(hContext, migData);
+ free_tspi(hContext, msaList);
+ free(outData);
+
+ return result;
+}
+