3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004-2007
16
#include "trousers/tss.h"
17
#include "trousers/trousers.h"
18
#include "trousers_types.h"
19
#include "spi_utils.h"
20
#include "capabilities.h"
25
Tspi_TPM_Quote2(TSS_HTPM hTPM, // in
26
TSS_HKEY hIdentKey, // in
27
TSS_BOOL fAddVersion, // in
28
TSS_HPCRS hPcrComposite, // in
29
TSS_VALIDATION* pValidationData, // in, out
30
UINT32* versionInfoSize, // out
31
BYTE** versionInfo) // out
34
TSS_HCONTEXT tspContext;
36
TPM_AUTH *pPrivAuth = &privAuth;
40
TCS_KEY_HANDLE tcsKeyHandle;
47
UINT32 pcrDataOutSize;
50
Trspi_HashCtx hashCtx;
52
LogDebug("Tspi_TPM_Quote2 Start:");
54
/* Takes the context that this TPM handle is on */
55
if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
58
/* Test if the hPcrComposite is valid */
59
if ((hPcrComposite) && !obj_is_pcrs(hPcrComposite))
60
return TSPERR(TSS_E_INVALID_HANDLE);
62
/* get the identKey Policy */
63
if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
66
/* get the Identity TCS keyHandle */
67
if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKeyHandle)))
70
/* Sets the validation data - if NULL, TSS provides it's own random value. If
71
* not NULL, takes the validation external data and sets the antiReplay data
73
if (pValidationData == NULL) {
74
LogDebug("Internal Verify:");
75
if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE),
76
(BYTE **)antiReplay.nonce)))
79
LogDebug("External Verify:");
80
if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce))
81
return TSPERR(TSS_E_BAD_PARAMETER);
83
memcpy(antiReplay.nonce, pValidationData->rgbExternalData,
84
sizeof(antiReplay.nonce));
87
/* Create the TPM_PCR_COMPOSITE object */
90
/* Load the PCR Selection Object into the pcrData */
91
if ((result = obj_pcrs_get_selection(hPcrComposite, &pcrDataSize, pcrData)))
96
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
97
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote2);
98
result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, antiReplay.nonce);
99
result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData);
100
result |= Trspi_Hash_BOOL(&hashCtx,fAddVersion);
101
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
103
if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_Quote2, hPolicy, FALSE,
104
&digest, &privAuth))) {
107
pPrivAuth = &privAuth;
113
if ((result = TCS_API(tspContext)->Quote2(tspContext, tcsKeyHandle, &antiReplay,
114
pcrDataSize, pcrData, fAddVersion, pPrivAuth,
115
&pcrDataOutSize, &pcrDataOut, versionInfoSize,
116
versionInfo, &sigSize, &sig)))
120
LogDebug("Got TCS Response:");
121
LogDebug(" pcrDataOutSize: %u",pcrDataOutSize);
122
LogDebug(" pcrDataOut:");
123
LogDebugData(pcrDataOutSize,pcrDataOut);
124
LogDebug(" versionInfoSize: %u",*versionInfoSize);
125
LogDebug(" versionInfo:");
126
if (*versionInfoSize >0)
127
LogDebugData(*versionInfoSize,*versionInfo);
128
LogDebug(" sigSize: %u",sigSize);
130
LogDebugData(sigSize,sig);
134
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
135
result |= Trspi_Hash_UINT32(&hashCtx, result);
136
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote2);
137
result |= Trspi_HashUpdate(&hashCtx, pcrDataOutSize, pcrDataOut);
138
result |= Trspi_Hash_UINT32(&hashCtx,*versionInfoSize);
139
if (*versionInfoSize > 0)
140
result |= Trspi_HashUpdate(&hashCtx, *versionInfoSize,*versionInfo);
141
result |= Trspi_Hash_UINT32(&hashCtx, sigSize);
142
result |= Trspi_HashUpdate(&hashCtx, sigSize, sig);
143
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
145
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth))) {
147
if (*versionInfoSize > 0)
154
/* Set the pcrDataOut back to the TSS */
156
TPM_PCR_INFO_SHORT pcrInfo;
159
if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, pcrDataOut, &pcrInfo))) {
161
if (*versionInfoSize > 0)
167
/* Set both digestAtRelease and localityAtRelease */
168
if ((result = obj_pcrs_set_locality(hPcrComposite, pcrInfo.localityAtRelease))) {
170
if (*versionInfoSize > 0)
176
if ((result = obj_pcrs_set_digest_at_release(hPcrComposite,
177
pcrInfo.digestAtRelease))) {
179
if (*versionInfoSize > 0)
186
/* generate TPM_QUOTE_INFO2 struct */
187
memset("einfo, 0, sizeof(quoteinfo));
189
/* 1. Add Structure TAG */
190
quoteinfo[offset++] = 0x00;
191
quoteinfo[offset++] = (BYTE) TPM_TAG_QUOTE_INFO2;
194
quoteinfo[offset++]='Q';
195
quoteinfo[offset++]='U';
196
quoteinfo[offset++]='T';
197
quoteinfo[offset++]='2';
199
/* 3. AntiReplay Nonce - add the external data*/
200
Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, quoteinfo,
202
/* 4. add the infoshort TPM_PCR_INFO_SHORT data */
203
Trspi_LoadBlob(&offset,pcrDataOutSize,quoteinfo,pcrDataOut);
206
Trspi_LoadBlob(&offset,*versionInfoSize,quoteinfo,*versionInfo);
208
/* versionInfo was not allocated and versionInfoSize has invalid value */
209
*versionInfoSize = 0;
213
LogDebug("TPM_QUOTE_INFO2 data: ");
214
LogDebugData(offset,quoteinfo);
216
if (pValidationData == NULL) {
217
if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, quoteinfo, digest.digest)))
219
if ((result = rsa_verify(hIdentKey,TSS_HASH_SHA1,sizeof(digest.digest),
220
digest.digest, sigSize, sig))) {
222
if (*versionInfoSize > 0)
224
return TSPERR(TSS_E_VERIFICATION_FAILED);
227
pValidationData->rgbValidationData = calloc_tspi(tspContext, sigSize);
228
if (pValidationData->rgbValidationData == NULL) {
229
LogError("malloc of %u bytes failed.", sigSize);
230
if (*versionInfoSize > 0)
232
return TSPERR(TSS_E_OUTOFMEMORY);
234
pValidationData->ulValidationDataLength = sigSize;
235
memcpy(pValidationData->rgbValidationData, sig, sigSize);
238
pValidationData->rgbData = calloc_tspi(tspContext, offset);
239
if (pValidationData->rgbData == NULL) {
240
LogError("malloc of %" PRIu64 " bytes failed.", offset);
241
free_tspi(tspContext, pValidationData->rgbValidationData);
242
pValidationData->rgbValidationData = NULL;
243
pValidationData->ulValidationDataLength = 0;
244
if (*versionInfoSize > 0)
246
return TSPERR(TSS_E_OUTOFMEMORY);
248
pValidationData->ulDataLength = (UINT32)offset;
249
memcpy(pValidationData->rgbData, quoteinfo, offset);
252
LogDebug("Tspi_TPM_Quote2 End");