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