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 25 TSS_RESULT 26 Tspi_TPM_SelfTestFull(TSS_HTPM hTPM) /* in */ 27 { 28 TSS_RESULT result; 29 TSS_HCONTEXT tspContext; 30 31 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 32 return result; 33 34 return TCS_API(tspContext)->SelfTestFull(tspContext); 35 } 36 37 TSS_RESULT 38 Tspi_TPM_CertifySelfTest(TSS_HTPM hTPM, /* in */ 39 TSS_HKEY hKey, /* in */ 40 TSS_VALIDATION *pValidationData) /* in, out */ 41 { 42 TCPA_RESULT result; 43 TPM_AUTH keyAuth; 44 UINT64 offset = 0; 45 TCPA_DIGEST digest; 46 TCPA_NONCE antiReplay; 47 UINT32 outDataSize; 48 BYTE *outData; 49 TSS_HPOLICY hPolicy; 50 TCS_KEY_HANDLE keyTCSKeyHandle; 51 BYTE *keyData = NULL; 52 UINT32 keyDataSize; 53 TSS_KEY keyContainer; 54 TPM_AUTH *pKeyAuth; 55 TSS_BOOL useAuth; 56 TSS_HCONTEXT tspContext; 57 Trspi_HashCtx hashCtx; 58 59 60 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 61 return result; 62 63 if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, 64 &hPolicy, &useAuth))) 65 return result; 66 67 if ((result = obj_rsakey_get_tcs_handle(hKey, &keyTCSKeyHandle))) 68 return result; 69 70 if (pValidationData == NULL) { 71 if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), 72 (BYTE **)antiReplay.nonce))) { 73 LogError("Failed creating random nonce"); 74 return TSPERR(TSS_E_INTERNAL_ERROR); 75 } 76 } else { 77 if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) 78 return TSPERR(TSS_E_BAD_PARAMETER); 79 80 memcpy(antiReplay.nonce, pValidationData->rgbExternalData, 81 sizeof(antiReplay.nonce)); 82 } 83 84 if (useAuth) { 85 LogDebug("Uses Auth"); 86 87 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 88 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest); 89 result |= Trspi_HashUpdate(&hashCtx, sizeof(TCPA_NONCE), antiReplay.nonce); 90 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 91 return result; 92 93 if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_CertifySelfTest, hPolicy, FALSE, 94 &digest, &keyAuth))) 95 return result; 96 pKeyAuth = &keyAuth; 97 } else { 98 LogDebug("No Auth"); 99 pKeyAuth = NULL; 100 } 101 102 if ((result = TCS_API(tspContext)->CertifySelfTest(tspContext, keyTCSKeyHandle, antiReplay, 103 pKeyAuth, &outDataSize, &outData))) 104 return result; 105 106 /* validate auth */ 107 if (useAuth) { 108 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 109 result |= Trspi_Hash_UINT32(&hashCtx, result); 110 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest); 111 result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); 112 result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); 113 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 114 return result; 115 116 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &keyAuth))) 117 return result; 118 } 119 120 if (pValidationData == NULL) { 121 if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 122 TSS_TSPATTRIB_KEYBLOB_BLOB, &keyDataSize, &keyData))) { 123 LogError("Failed call to GetAttribData to get key blob"); 124 return TSPERR(TSS_E_INTERNAL_ERROR); 125 } 126 127 offset = 0; 128 memset(&keyContainer, 0, sizeof(TSS_KEY)); 129 if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer))) 130 return result; 131 132 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 133 result |= Trspi_HashUpdate(&hashCtx, strlen("Test Passed"), (BYTE *)"Test Passed"); 134 result |= Trspi_HashUpdate(&hashCtx, sizeof(TCPA_NONCE), antiReplay.nonce); 135 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest); 136 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 137 return result; 138 139 if ((result = Trspi_Verify(TSS_HASH_SHA1, digest.digest, 20, 140 keyContainer.pubKey.key, keyContainer.pubKey.keyLength, 141 outData, outDataSize))) { 142 free(outData); 143 free_key_refs(&keyContainer); 144 return TSPERR(TSS_E_VERIFICATION_FAILED); 145 } 146 147 } else { 148 pValidationData->ulDataLength = sizeof(TCPA_NONCE) + sizeof(UINT32) + 149 strlen("Test Passed"); 150 pValidationData->rgbData = calloc_tspi(tspContext, pValidationData->ulDataLength); 151 if (pValidationData->rgbData == NULL) { 152 LogError("malloc of %u bytes failed.", pValidationData->ulDataLength); 153 pValidationData->ulDataLength = 0; 154 return TSPERR(TSS_E_OUTOFMEMORY); 155 } 156 offset = 0; 157 Trspi_LoadBlob(&offset, strlen("Test Passed"), pValidationData->rgbData, 158 (BYTE *)"Test Passed"); 159 Trspi_LoadBlob(&offset, sizeof(TCPA_NONCE), pValidationData->rgbData, 160 antiReplay.nonce); 161 Trspi_LoadBlob_UINT32(&offset, TPM_ORD_CertifySelfTest, pValidationData->rgbData); 162 pValidationData->ulValidationDataLength = outDataSize; 163 pValidationData->rgbValidationData = calloc_tspi(tspContext, outDataSize); 164 if (pValidationData->rgbValidationData == NULL) { 165 free_tspi(tspContext, pValidationData->rgbData); 166 pValidationData->rgbData = NULL; 167 pValidationData->ulDataLength = 0; 168 LogError("malloc of %u bytes failed.", 169 pValidationData->ulValidationDataLength); 170 pValidationData->ulValidationDataLength = 0; 171 return TSPERR(TSS_E_OUTOFMEMORY); 172 } 173 memcpy(pValidationData->rgbValidationData, outData, outDataSize); 174 free(outData); 175 } 176 177 return TSS_SUCCESS; 178 } 179 180 TSS_RESULT 181 Tspi_TPM_GetTestResult(TSS_HTPM hTPM, /* in */ 182 UINT32 * pulTestResultLength, /* out */ 183 BYTE ** prgbTestResult) /* out */ 184 { 185 TSS_HCONTEXT tspContext; 186 TSS_RESULT result; 187 188 if (pulTestResultLength == NULL || prgbTestResult == NULL) 189 return TSPERR(TSS_E_BAD_PARAMETER); 190 191 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) 192 return result; 193 194 if ((result = TCS_API(tspContext)->GetTestResult(tspContext, pulTestResultLength, 195 prgbTestResult))) 196 return result; 197 198 if ((result = __tspi_add_mem_entry(tspContext, *prgbTestResult))) { 199 free(*prgbTestResult); 200 *prgbTestResult = NULL; 201 *pulTestResultLength = 0; 202 } 203 204 return TSS_SUCCESS; 205 } 206 207