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
Tspi_TPM_CreateMaintenanceArchive(TSS_HTPM hTPM,TSS_BOOL fGenerateRndNumber,UINT32 * pulRndNumberLength,BYTE ** prgbRndNumber,UINT32 * pulArchiveDataLength,BYTE ** prgbArchiveData)26 Tspi_TPM_CreateMaintenanceArchive(TSS_HTPM hTPM, /* in */
27 TSS_BOOL fGenerateRndNumber, /* in */
28 UINT32 * pulRndNumberLength, /* out */
29 BYTE ** prgbRndNumber, /* out */
30 UINT32 * pulArchiveDataLength, /* out */
31 BYTE ** prgbArchiveData) /* out */
32 {
33 TSS_RESULT result;
34 TSS_HCONTEXT tspContext;
35 TSS_HPOLICY hOwnerPolicy;
36 TPM_AUTH ownerAuth;
37 TCPA_DIGEST digest;
38 Trspi_HashCtx hashCtx;
39
40 if (pulArchiveDataLength == NULL || prgbArchiveData == NULL)
41 return TSPERR(TSS_E_BAD_PARAMETER);
42
43 if (fGenerateRndNumber &&
44 (pulRndNumberLength == NULL || prgbRndNumber == NULL))
45 return TSPERR(TSS_E_BAD_PARAMETER);
46
47 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
48 return result;
49
50 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
51 return result;
52
53 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
54 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMaintenanceArchive);
55 result |= Trspi_Hash_BYTE(&hashCtx, fGenerateRndNumber);
56 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
57 return result;
58
59 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_CreateMaintenanceArchive, hOwnerPolicy,
60 FALSE, &digest, &ownerAuth)))
61 return result;
62
63 if ((result = TCS_API(tspContext)->CreateMaintenanceArchive(tspContext, fGenerateRndNumber,
64 &ownerAuth, pulRndNumberLength,
65 prgbRndNumber,
66 pulArchiveDataLength,
67 prgbArchiveData)))
68 return result;
69
70 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
71 result |= Trspi_Hash_UINT32(&hashCtx, result);
72 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMaintenanceArchive);
73 result |= Trspi_Hash_UINT32(&hashCtx, *pulRndNumberLength);
74 result |= Trspi_HashUpdate(&hashCtx, *pulRndNumberLength, *prgbRndNumber);
75 result |= Trspi_Hash_UINT32(&hashCtx, *pulArchiveDataLength);
76 result |= Trspi_HashUpdate(&hashCtx, *pulArchiveDataLength, *prgbArchiveData);
77 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
78 goto error1;
79
80 if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth)))
81 goto error1;
82
83 if ((result = __tspi_add_mem_entry(tspContext, *prgbRndNumber)))
84 goto error1;
85
86 if ((result = __tspi_add_mem_entry(tspContext, *prgbArchiveData))) {
87 free_tspi(tspContext, *prgbRndNumber);
88 goto error2;
89 }
90
91 return TSS_SUCCESS;
92 error1:
93 free(*prgbRndNumber);
94 error2:
95 free(*prgbArchiveData);
96 return result;
97 }
98
99 TSS_RESULT
Tspi_TPM_KillMaintenanceFeature(TSS_HTPM hTPM)100 Tspi_TPM_KillMaintenanceFeature(TSS_HTPM hTPM) /* in */
101 {
102 TSS_RESULT result;
103 TSS_HCONTEXT tspContext;
104 TSS_HPOLICY hOwnerPolicy;
105 TPM_AUTH ownerAuth;
106 TCPA_DIGEST digest;
107 Trspi_HashCtx hashCtx;
108
109 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
110 return result;
111
112 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
113 return result;
114
115 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
116 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KillMaintenanceFeature);
117 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
118 return result;
119
120 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_KillMaintenanceFeature, hOwnerPolicy,
121 FALSE, &digest, &ownerAuth)))
122 return result;
123
124 if ((result = TCS_API(tspContext)->KillMaintenanceFeature(tspContext, &ownerAuth)))
125 return result;
126
127 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
128 result |= Trspi_Hash_UINT32(&hashCtx, result);
129 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KillMaintenanceFeature);
130 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
131 return result;
132
133 if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth)))
134 return result;
135
136 return TSS_SUCCESS;
137 }
138
139 TSS_RESULT
Tspi_TPM_LoadMaintenancePubKey(TSS_HTPM hTPM,TSS_HKEY hMaintenanceKey,TSS_VALIDATION * pValidationData)140 Tspi_TPM_LoadMaintenancePubKey(TSS_HTPM hTPM, /* in */
141 TSS_HKEY hMaintenanceKey, /* in */
142 TSS_VALIDATION * pValidationData) /* in, out */
143 {
144 TSS_RESULT result;
145 TSS_HCONTEXT tspContext;
146 TCPA_DIGEST checkSum, digest;
147 TCPA_NONCE nonce;
148 UINT64 offset;
149 UINT32 pubBlobSize;
150 BYTE hashBlob[512], *pubBlob;
151
152 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
153 return result;
154
155 if (pValidationData == NULL) {
156 if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE),
157 (BYTE **)nonce.nonce)))
158 return result;
159 } else {
160 if (pValidationData->ulExternalDataLength < sizeof(nonce.nonce))
161 return TSPERR(TSS_E_BAD_PARAMETER);
162
163 memcpy(&nonce.nonce, pValidationData->rgbExternalData, sizeof(nonce.nonce));
164 }
165
166 if ((result = obj_rsakey_get_pub_blob(hMaintenanceKey, &pubBlobSize, &pubBlob)))
167 return result;
168
169 if ((result = TCS_API(tspContext)->LoadManuMaintPub(tspContext, nonce, pubBlobSize, pubBlob,
170 &checkSum)))
171 return result;
172
173 offset = 0;
174 Trspi_LoadBlob(&offset, pubBlobSize, hashBlob, pubBlob);
175 Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, hashBlob, (BYTE *)&nonce.nonce);
176
177 if (pValidationData == NULL) {
178 if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, digest.digest)))
179 return result;
180
181 if (memcmp(&digest.digest, &checkSum.digest, TCPA_SHA1_160_HASH_LEN))
182 result = TSPERR(TSS_E_FAIL);
183 } else {
184 if ((pValidationData->rgbData = calloc_tspi(tspContext, offset)) == NULL)
185 return TSPERR(TSS_E_OUTOFMEMORY);
186
187 pValidationData->ulDataLength = offset;
188 memcpy(pValidationData->rgbData, hashBlob, offset);
189
190 if ((pValidationData->rgbValidationData = calloc_tspi(tspContext,
191 TPM_SHA1_160_HASH_LEN))
192 == NULL) {
193 free_tspi(tspContext, pValidationData->rgbData);
194 pValidationData->rgbData = NULL;
195 pValidationData->ulDataLength = 0;
196 return TSPERR(TSS_E_OUTOFMEMORY);
197 }
198 pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN;
199
200 memcpy(pValidationData->rgbValidationData, checkSum.digest, TCPA_SHA1_160_HASH_LEN);
201 }
202
203 return result;
204 }
205
206 TSS_RESULT
Tspi_TPM_CheckMaintenancePubKey(TSS_HTPM hTPM,TSS_HKEY hMaintenanceKey,TSS_VALIDATION * pValidationData)207 Tspi_TPM_CheckMaintenancePubKey(TSS_HTPM hTPM, /* in */
208 TSS_HKEY hMaintenanceKey, /* in */
209 TSS_VALIDATION * pValidationData) /* in, out */
210 {
211 TSS_RESULT result;
212 TSS_HCONTEXT tspContext;
213 TCPA_DIGEST checkSum, digest;
214 TCPA_NONCE nonce;
215 UINT32 pubBlobSize;
216 BYTE *pubBlob;
217 Trspi_HashCtx hashCtx;
218
219 if ((pValidationData && hMaintenanceKey) || (!pValidationData && !hMaintenanceKey))
220 return TSPERR(TSS_E_BAD_PARAMETER);
221
222 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
223 return result;
224
225 if (pValidationData == NULL) {
226 if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE),
227 (BYTE **)nonce.nonce)))
228 return result;
229 } else {
230 if (pValidationData->ulExternalDataLength < sizeof(nonce.nonce))
231 return TSPERR(TSS_E_BAD_PARAMETER);
232
233 memcpy(&nonce.nonce, pValidationData->rgbExternalData, sizeof(nonce.nonce));
234 }
235
236 if ((result = TCS_API(tspContext)->ReadManuMaintPub(tspContext, nonce, &checkSum)))
237 return result;
238
239 if (pValidationData == NULL) {
240 if ((result = obj_rsakey_get_pub_blob(hMaintenanceKey, &pubBlobSize, &pubBlob)))
241 return result;
242
243 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
244 result |= Trspi_HashUpdate(&hashCtx, pubBlobSize, pubBlob);
245 result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, (BYTE *)&nonce.nonce);
246 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
247 return result;
248
249 if (memcmp(&digest.digest, &checkSum.digest, TCPA_SHA1_160_HASH_LEN))
250 result = TSPERR(TSS_E_FAIL);
251
252 free_tspi(tspContext, pubBlob);
253 } else {
254 /* Ignore Data and DataLength, the application must already have this data.
255 * Do, however, copy out the checksum so that the application can verify */
256 if ((pValidationData->rgbValidationData = calloc_tspi(tspContext,
257 TCPA_SHA1_160_HASH_LEN))
258 == NULL) {
259 return TSPERR(TSS_E_OUTOFMEMORY);
260 }
261
262 pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN;
263 memcpy(pValidationData->rgbValidationData, checkSum.digest, TCPA_SHA1_160_HASH_LEN);
264 }
265
266 return result;
267 }
268
269