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/tspi_cmk.c | |
download | trousers-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.c | 475 |
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; +} + |