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
Tspi_TPM_GetAuditDigest(TSS_HTPM hTpm,TSS_HKEY hKey,TSS_BOOL closeAudit,UINT32 * pulAuditDigestSize,BYTE ** prgbAuditDigest,TPM_COUNTER_VALUE * pCounterValue,TSS_VALIDATION * pValidationData,UINT32 * ordSize,UINT32 ** ordList)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 __tspi_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