1 2/* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2004-2006 8 * 9 */ 10 11#include <stdlib.h> 12#include <stdio.h> 13#include <string.h> 14#include <inttypes.h> 15 16#include "trousers/tss.h" 17#include "trousers/trousers.h" 18#include "trousers_types.h" 19#include "spi_utils.h" 20#include "capabilities.h" 21#include "tsplog.h" 22#include "obj.h" 23 24 25TSS_RESULT 26Tspi_TPM_TakeOwnership(TSS_HTPM hTPM, /* in */ 27 TSS_HKEY hKeySRK, /* in */ 28 TSS_HKEY hEndorsementPubKey) /* in */ 29{ 30 TPM_AUTH privAuth; 31 BYTE encOwnerAuth[256]; 32 UINT32 encOwnerAuthLength; 33 BYTE encSRKAuth[256]; 34 UINT32 encSRKAuthLength; 35 TCPA_DIGEST digest; 36 TSS_RESULT result; 37 TSS_HCONTEXT tspContext; 38 UINT32 srkKeyBlobLength; 39 BYTE *srkKeyBlob; 40 TSS_HPOLICY hOwnerPolicy; 41 UINT32 newSrkBlobSize; 42 BYTE *newSrkBlob = NULL; 43 BYTE oldAuthDataUsage; 44 TSS_HKEY hPubEK; 45 Trspi_HashCtx hashCtx; 46 47 48 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 49 return result; 50 51 if (hEndorsementPubKey == NULL_HKEY) { 52 if ((result = Tspi_TPM_GetPubEndorsementKey(hTPM, FALSE, NULL, &hPubEK))) { 53 return result; 54 } 55 } else { 56 hPubEK = hEndorsementPubKey; 57 } 58 59 /* Get the srkKeyData */ 60 if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob))) 61 return result; 62 63 /* Need to check for Atmel bug where authDataUsage is changed */ 64 oldAuthDataUsage = srkKeyBlob[10]; 65 LogDebug("oldAuthDataUsage is %.2X. Wait to see if it changes", oldAuthDataUsage); 66 67 /* Now call the module that will encrypt the secrets. This 68 * will either get the secrets from the policy objects or 69 * use the callback function to encrypt the secrets */ 70 71 if ((result = secret_TakeOwnership(hPubEK, hTPM, hKeySRK, &privAuth, &encOwnerAuthLength, 72 encOwnerAuth, &encSRKAuthLength, encSRKAuth))) 73 return result; 74 75 /* Now, take ownership is ready to call. The auth structure should be complete 76 * and the encrypted data structures should be ready */ 77 if ((result = RPC_TakeOwnership(tspContext, TPM_PID_OWNER, encOwnerAuthLength, encOwnerAuth, 78 encSRKAuthLength, encSRKAuth, srkKeyBlobLength, srkKeyBlob, 79 &privAuth, &newSrkBlobSize, &newSrkBlob))) 80 return result; 81 82 /* The final step is to validate the return Auth */ 83 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 84 result |= Trspi_Hash_UINT32(&hashCtx, result); 85 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership); 86 result |= Trspi_HashUpdate(&hashCtx, newSrkBlobSize, newSrkBlob); 87 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 88 return result; 89 90 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) { 91 free(newSrkBlob); 92 return result; 93 } 94 if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &privAuth))) { 95 free(newSrkBlob); 96 return result; 97 } 98 99 /* Now that it's all happy, stuff the keyBlob into the object 100 * If atmel, need to adjust the authDataUsage if it changed */ 101 if (oldAuthDataUsage != newSrkBlob[10]) { /* hardcoded blob stuff */ 102 LogDebug("auth data usage changed. Atmel bug. Fixing in key object"); 103 newSrkBlob[10] = oldAuthDataUsage; /* this will fix it */ 104 } 105 106 result = obj_rsakey_set_tcpakey(hKeySRK, newSrkBlobSize, newSrkBlob); 107 free(newSrkBlob); 108 109 if (result) 110 return result; 111 112 /* The SRK is loaded at this point, so insert it into the key handle list */ 113 return obj_rsakey_set_tcs_handle(hKeySRK, TPM_KEYHND_SRK); 114} 115 116TSS_RESULT 117Tspi_TPM_ClearOwner(TSS_HTPM hTPM, /* in */ 118 TSS_BOOL fForcedClear) /* in */ 119{ 120 TCPA_RESULT result; 121 TPM_AUTH auth; 122 TSS_HCONTEXT tspContext; 123 TCPA_DIGEST hashDigest; 124 TSS_HPOLICY hPolicy; 125 Trspi_HashCtx hashCtx; 126 127 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 128 return result; 129 130 if (!fForcedClear) { /* TPM_OwnerClear */ 131 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) 132 return result; 133 134 /* Now do some Hash'ing */ 135 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 136 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear); 137 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 138 return result; 139 140 /* hashDigest now has the hash result */ 141 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerClear, hPolicy, FALSE, 142 &hashDigest, &auth))) 143 return result; 144 145 if ((result = TCS_API(tspContext)->OwnerClear(tspContext, &auth))) 146 return result; 147 148 /* validate auth */ 149 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 150 result |= Trspi_Hash_UINT32(&hashCtx, result); 151 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear); 152 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) 153 return result; 154 155 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) 156 return result; 157 } else { 158 if ((result = TCS_API(tspContext)->ForceClear(tspContext))) 159 return result; 160 } 161 162 return TSS_SUCCESS; 163} 164