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. 2007 8 * 9 */ 10 11 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 16 #include "trousers/tss.h" 17 #include "trousers/trousers.h" 18 #include "trousers_types.h" 19 #include "spi_utils.h" 20 #include "obj.h" 21 #include "tsplog.h" 22 23 24 /* XXX Split into two functions */ 25 TSS_RESULT 26 Tspi_TPM_GetAuditDigest(TSS_HTPM hTpm, /* in */ 27 TSS_HKEY hKey, /* in */ 28 TSS_BOOL closeAudit, /* in */ 29 UINT32* pulAuditDigestSize, /* out */ 30 BYTE** prgbAuditDigest, /* out */ 31 TPM_COUNTER_VALUE* pCounterValue, /* out */ 32 TSS_VALIDATION* pValidationData, /* out */ 33 UINT32* ordSize, /* out */ 34 UINT32** ordList) /* out */ 35 { 36 TSS_HCONTEXT tspContext; 37 UINT32 counterValueSize; 38 BYTE *counterValue = NULL; 39 TPM_DIGEST auditDigest; 40 TSS_RESULT result = TSS_SUCCESS; 41 UINT64 offset; 42 43 if ((pulAuditDigestSize == NULL) || (prgbAuditDigest == NULL) || (pCounterValue == NULL)) 44 return TSPERR(TSS_E_BAD_PARAMETER); 45 46 if (hKey == NULL_HKEY) 47 if ((ordSize == NULL) || (ordList == NULL)) 48 return TSPERR(TSS_E_BAD_PARAMETER); 49 50 if ((result = obj_tpm_get_tsp_context(hTpm, &tspContext))) 51 return result; 52 53 if (hKey == NULL_HKEY) { 54 UINT32 startOrdinal = 0; 55 TSS_BOOL more; 56 UINT32 tcsOrdSize; 57 UINT32 *tcsOrdList = NULL; 58 UINT32 *pulTemp; 59 60 *prgbAuditDigest = NULL; 61 *pulAuditDigestSize = 0; 62 *ordList = NULL; 63 *ordSize = 0; 64 do { 65 if ((result = TCS_API(tspContext)->GetAuditDigest(tspContext, startOrdinal, 66 &auditDigest, 67 &counterValueSize, 68 &counterValue, &more, 69 &tcsOrdSize, 70 &tcsOrdList))) 71 goto done1; 72 73 if ((pulTemp = 74 calloc_tspi(tspContext, 75 (*ordSize + tcsOrdSize) * sizeof(UINT32))) == NULL) { 76 LogError("malloc of %u bytes failed.", *ordSize + tcsOrdSize); 77 result = TSPERR(TSS_E_OUTOFMEMORY); 78 goto done1; 79 } 80 81 if (*ordList) 82 memcpy(pulTemp, *ordList, *ordSize * sizeof(UINT32)); 83 memcpy(pulTemp + *ordSize, tcsOrdList, tcsOrdSize * sizeof(UINT32)); 84 85 free(tcsOrdList); 86 tcsOrdList = NULL; 87 88 if (*ordList) 89 free_tspi(tspContext, *ordList); 90 *ordList = pulTemp; 91 *ordSize += tcsOrdSize; 92 93 if (more == TRUE) { 94 offset = 0; 95 Trspi_UnloadBlob_UINT32(&offset, &startOrdinal, 96 (BYTE *)(*ordList + (*ordSize - 1))); 97 startOrdinal++; 98 free(counterValue); 99 counterValue = NULL; 100 } 101 } while (more == TRUE); 102 103 *pulAuditDigestSize = sizeof(auditDigest.digest); 104 if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) { 105 LogError("malloc of %u bytes failed.", *pulAuditDigestSize); 106 result = TSPERR(TSS_E_OUTOFMEMORY); 107 goto done1; 108 } 109 offset = 0; 110 Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest); 111 112 offset = 0; 113 Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue); 114 115 result = TSS_SUCCESS; 116 117 done1: 118 if (result != TSS_SUCCESS) { 119 if (*prgbAuditDigest) 120 free_tspi(tspContext, *prgbAuditDigest); 121 if (*ordList) 122 free_tspi(tspContext, *ordList); 123 *prgbAuditDigest = NULL; 124 *pulAuditDigestSize = 0; 125 *ordList = NULL; 126 *ordSize = 0; 127 } 128 free(counterValue); 129 free(tcsOrdList); 130 131 return result; 132 } 133 else { 134 TSS_HPOLICY hPolicy; 135 TSS_BOOL usesAuth; 136 TCS_KEY_HANDLE tcsKeyHandle; 137 TPM_AUTH keyAuth, *pAuth; 138 Trspi_HashCtx hashCtx; 139 TCPA_DIGEST digest; 140 TPM_NONCE antiReplay; 141 TPM_DIGEST auditDigest; 142 TPM_DIGEST ordinalDigest; 143 UINT32 sigSize; 144 BYTE *sig = NULL; 145 TPM_SIGN_INFO signInfo; 146 UINT32 signInfoBlobSize; 147 BYTE *signInfoBlob = NULL; 148 149 if (pValidationData == NULL) { 150 LogDebug("Internal Verify"); 151 if ((result = get_local_random(tspContext, FALSE, TPM_NONCE_SIZE, 152 (BYTE **)antiReplay.nonce))) 153 return result; 154 } else { 155 LogDebug("External Verify"); 156 if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) 157 return TSPERR(TSS_E_BAD_PARAMETER); 158 159 if (pValidationData->rgbExternalData == NULL) 160 return TSPERR(TSS_E_BAD_PARAMETER); 161 162 memcpy(antiReplay.nonce, pValidationData->rgbExternalData, 163 sizeof(antiReplay.nonce)); 164 165 pValidationData->ulDataLength = 0; 166 pValidationData->rgbData = NULL; 167 pValidationData->ulValidationDataLength = 0; 168 pValidationData->rgbValidationData = NULL; 169 } 170 171 if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) 172 return result; 173 174 if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) 175 return result; 176 177 if (usesAuth) { 178 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 179 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned); 180 result |= Trspi_Hash_BOOL(&hashCtx, closeAudit); 181 result |= Trspi_Hash_NONCE(&hashCtx, antiReplay.nonce); 182 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 183 return result; 184 185 pAuth = &keyAuth; 186 if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetAuditDigestSigned, 187 hPolicy, FALSE, &digest, pAuth))) 188 return result; 189 } 190 else 191 pAuth = NULL; 192 193 if ((result = TCS_API(tspContext)->GetAuditDigestSigned(tspContext, tcsKeyHandle, 194 closeAudit, &antiReplay, 195 pAuth, &counterValueSize, 196 &counterValue, &auditDigest, 197 &ordinalDigest, &sigSize, 198 &sig))) 199 return result; 200 201 memset(&signInfo, 0, sizeof(signInfo)); 202 signInfo.tag = TPM_TAG_SIGNINFO; 203 memcpy(signInfo.fixed, "ADIG", strlen("ADIG")); 204 signInfo.replay = antiReplay; 205 signInfo.dataLen = sizeof(auditDigest.digest) + counterValueSize + 206 sizeof(ordinalDigest.digest); 207 if ((signInfo.data = malloc(signInfo.dataLen)) == NULL) { 208 LogError("malloc of %u bytes failed.", signInfo.dataLen); 209 result = TSPERR(TSS_E_OUTOFMEMORY); 210 goto done2; 211 } 212 offset = 0; 213 Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &auditDigest); 214 Trspi_LoadBlob(&offset, counterValueSize, signInfo.data, counterValue); 215 Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &ordinalDigest); 216 217 if (usesAuth) { 218 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 219 result |= Trspi_Hash_UINT32(&hashCtx, result); 220 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned); 221 result |= Trspi_HashUpdate(&hashCtx, counterValueSize, counterValue); 222 result |= Trspi_Hash_DIGEST(&hashCtx, auditDigest.digest); 223 result |= Trspi_Hash_DIGEST(&hashCtx, ordinalDigest.digest); 224 result |= Trspi_Hash_UINT32(&hashCtx, sigSize); 225 result |= Trspi_HashUpdate(&hashCtx, sigSize, sig); 226 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) 227 goto done2; 228 229 if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) 230 goto done2; 231 } 232 233 offset = 0; 234 Trspi_LoadBlob_SIGN_INFO(&offset, NULL, &signInfo); 235 signInfoBlobSize = offset; 236 signInfoBlob = malloc(signInfoBlobSize); 237 if (signInfoBlob == NULL) { 238 LogError("malloc of %u bytes failed.", signInfoBlobSize); 239 result = TSPERR(TSS_E_OUTOFMEMORY); 240 goto done2; 241 } 242 offset = 0; 243 Trspi_LoadBlob_SIGN_INFO(&offset, signInfoBlob, &signInfo); 244 245 if (pValidationData == NULL) { 246 if ((result = Trspi_Hash(TSS_HASH_SHA1, signInfoBlobSize, signInfoBlob, 247 digest.digest))) 248 goto done2; 249 250 if ((result = __tspi_rsa_verify(hKey, TSS_HASH_SHA1, sizeof(digest.digest), 251 digest.digest, sigSize, sig))) { 252 result = TSPERR(TSS_E_VERIFICATION_FAILED); 253 goto done2; 254 } 255 } else { 256 pValidationData->ulDataLength = signInfoBlobSize; 257 pValidationData->rgbData = calloc_tspi(tspContext, signInfoBlobSize); 258 if (pValidationData->rgbData == NULL) { 259 LogError("malloc of %u bytes failed.", signInfoBlobSize); 260 result = TSPERR(TSS_E_OUTOFMEMORY); 261 goto done2; 262 } 263 memcpy(pValidationData->rgbData, signInfoBlob, signInfoBlobSize); 264 265 pValidationData->ulValidationDataLength = sigSize; 266 pValidationData->rgbValidationData = calloc_tspi(tspContext, sigSize); 267 if (pValidationData->rgbValidationData == NULL) { 268 LogError("malloc of %u bytes failed.", sigSize); 269 result = TSPERR(TSS_E_OUTOFMEMORY); 270 goto done2; 271 } 272 memcpy(pValidationData->rgbValidationData, sig, sigSize); 273 } 274 275 *pulAuditDigestSize = sizeof(auditDigest.digest); 276 if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) { 277 LogError("malloc of %u bytes failed.", *pulAuditDigestSize); 278 result = TSPERR(TSS_E_OUTOFMEMORY); 279 goto done2; 280 } 281 offset = 0; 282 Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest); 283 284 offset = 0; 285 Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue); 286 287 result = TSS_SUCCESS; 288 289 done2: 290 if (result != TSS_SUCCESS) { 291 if (*prgbAuditDigest) 292 free_tspi(tspContext, *prgbAuditDigest); 293 *prgbAuditDigest = NULL; 294 *pulAuditDigestSize = 0; 295 if (pValidationData != NULL) { 296 if (pValidationData->rgbData) 297 free_tspi(tspContext, pValidationData->rgbData); 298 if (pValidationData->rgbValidationData) 299 free_tspi(tspContext, pValidationData->rgbValidationData); 300 pValidationData->ulDataLength = 0; 301 pValidationData->rgbData = NULL; 302 pValidationData->ulValidationDataLength = 0; 303 pValidationData->rgbValidationData = NULL; 304 } 305 } 306 free(counterValue); 307 free(sig); 308 free(signInfo.data); 309 free(signInfoBlob); 310 311 return result; 312 } 313 } 314