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-2007
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_SetStatus(TSS_HTPM hTPM,TSS_FLAG statusFlag,TSS_BOOL fTpmState)26 Tspi_TPM_SetStatus(TSS_HTPM hTPM, /* in */
27 TSS_FLAG statusFlag, /* in */
28 TSS_BOOL fTpmState) /* in */
29 {
30 TPM_AUTH auth, *pAuth;
31 TSS_RESULT result;
32 TCPA_DIGEST hashDigest;
33 TSS_HCONTEXT tspContext;
34 TSS_HPOLICY hPolicy;
35 TSS_HPOLICY hOperatorPolicy;
36 Trspi_HashCtx hashCtx;
37 UINT32 tpmVersion;
38
39 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
40 return result;
41
42 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
43 return result;
44
45 switch (statusFlag) {
46 case TSS_TPMSTATUS_DISABLEOWNERCLEAR:
47 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
48 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisableOwnerClear);
49 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
50 return result;
51
52 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DisableOwnerClear, hPolicy,
53 FALSE, &hashDigest, &auth)))
54 return result;
55
56 if ((result = TCS_API(tspContext)->DisableOwnerClear(tspContext, &auth)))
57 return result;
58
59 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
60 result |= Trspi_Hash_UINT32(&hashCtx, result);
61 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisableOwnerClear);
62 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
63 return result;
64
65 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
66 return result;
67 break;
68 case TSS_TPMSTATUS_DISABLEFORCECLEAR:
69 result = TCS_API(tspContext)->DisableForceClear(tspContext);
70 break;
71 case TSS_TPMSTATUS_DISABLED:
72 case TSS_TPMSTATUS_OWNERSETDISABLE:
73 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
74 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerSetDisable);
75 result |= Trspi_Hash_BOOL(&hashCtx, fTpmState);
76 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
77 return result;
78
79 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerSetDisable, hPolicy,
80 FALSE, &hashDigest, &auth)))
81 return result;
82
83 if ((result = TCS_API(tspContext)->OwnerSetDisable(tspContext, fTpmState, &auth)))
84 return result;
85
86 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
87 result |= Trspi_Hash_UINT32(&hashCtx, result);
88 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerSetDisable);
89 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
90 return result;
91
92 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
93 return result;
94 break;
95 case TSS_TPMSTATUS_PHYSICALDISABLE:
96 if (fTpmState)
97 result = TCS_API(tspContext)->PhysicalDisable(tspContext);
98 else
99 result = TCS_API(tspContext)->PhysicalEnable(tspContext);
100 break;
101 case TSS_TPMSTATUS_DEACTIVATED:
102 case TSS_TPMSTATUS_PHYSICALSETDEACTIVATED:
103 result = TCS_API(tspContext)->PhysicalSetDeactivated(tspContext, fTpmState);
104 break;
105 case TSS_TPMSTATUS_SETTEMPDEACTIVATED:
106 if ((result = obj_context_get_tpm_version(tspContext, &tpmVersion)))
107 return result;
108
109 /* XXX Change 0,1,2 to #defines */
110 switch (tpmVersion) {
111 case 0:
112 case 1:
113 result = TCS_API(tspContext)->SetTempDeactivated(tspContext);
114 break;
115 case 2:
116 if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_OPERATOR, &hOperatorPolicy)))
117 return result;
118
119 if (hOperatorPolicy != NULL_HPOLICY) {
120 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
121 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetTempDeactivated);
122 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
123 return result;
124
125 pAuth = &auth;
126 if ((result = secret_PerformAuth_OIAP(hTPM,
127 TPM_ORD_SetTempDeactivated,
128 hOperatorPolicy, FALSE,
129 &hashDigest, pAuth)))
130 return result;
131 }
132 else
133 pAuth = NULL;
134
135 if ((result = TCS_API(tspContext)->SetTempDeactivated2(tspContext, pAuth)))
136 return result;
137
138 if (pAuth) {
139 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
140 result |= Trspi_Hash_UINT32(&hashCtx, result);
141 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetTempDeactivated);
142 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
143 return result;
144
145 if ((result = obj_policy_validate_auth_oiap(hOperatorPolicy,
146 &hashDigest,
147 pAuth)))
148 return result;
149 }
150 break;
151 default:
152 return TSPERR(TSS_E_INTERNAL_ERROR);
153 }
154 break;
155 case TSS_TPMSTATUS_SETOWNERINSTALL:
156 result = TCS_API(tspContext)->SetOwnerInstall(tspContext, fTpmState);
157 break;
158 case TSS_TPMSTATUS_DISABLEPUBEKREAD:
159 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
160 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisablePubekRead);
161 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
162 return result;
163
164 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DisablePubekRead, hPolicy,
165 FALSE, &hashDigest, &auth)))
166 return result;
167
168 if ((result = TCS_API(tspContext)->DisablePubekRead(tspContext, &auth)))
169 return result;
170
171 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
172 result |= Trspi_Hash_UINT32(&hashCtx, result);
173 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisablePubekRead);
174 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
175 return result;
176
177 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
178 return result;
179 break;
180 case TSS_TPMSTATUS_ALLOWMAINTENANCE:
181 /* Allow maintenance cannot be set to TRUE in the TPM */
182 if (fTpmState)
183 return TSPERR(TSS_E_BAD_PARAMETER);
184
185 /* The path to setting allow maintenance to FALSE is through
186 * KillMaintenanceFeature */
187 return Tspi_TPM_KillMaintenanceFeature(hTPM);
188 break;
189 #ifdef TSS_BUILD_TSS12
190 case TSS_TPMSTATUS_DISABLEPUBSRKREAD:
191 /* The logic of setting a 'disable' flag is reversed in the TPM, where setting this
192 * flag to TRUE will enable the SRK read, while FALSE disables it. So we need to
193 * flip the bool here. Sigh... */
194 fTpmState = fTpmState ? FALSE : TRUE;
195
196 result = TSP_SetCapability(tspContext, hTPM, hPolicy, TPM_SET_PERM_FLAGS,
197 TPM_PF_READSRKPUB, fTpmState);
198 break;
199 case TSS_TPMSTATUS_RESETLOCK:
200 /* ignoring the bool here */
201 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
202 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ResetLockValue);
203 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
204 return result;
205
206 if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_ResetLockValue, hPolicy,
207 FALSE, &hashDigest, &auth)))
208 return result;
209
210 if ((result = TCS_API(tspContext)->ResetLockValue(tspContext, &auth)))
211 return result;
212
213 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
214 result |= Trspi_Hash_UINT32(&hashCtx, result);
215 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ResetLockValue);
216 if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
217 return result;
218
219 if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
220 return result;
221 break;
222 #endif
223 #ifndef TSS_SPEC_COMPLIANCE
224 case TSS_TPMSTATUS_PHYSPRES_LIFETIMELOCK:
225 /* set the lifetime lock bit */
226 result = TCS_API(tspContext)->PhysicalPresence(tspContext,
227 TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK);
228 break;
229 case TSS_TPMSTATUS_PHYSPRES_HWENABLE:
230 /* HWENABLE, TRUE -> set the TPM_PHYSICAL_PRESENCE_HW_ENABLE bit
231 * HWENABLE, FALSE -> set the TPM_PHYSICAL_PRESENCE_HW_DISABLE bit */
232 if (fTpmState)
233 result = TCS_API(tspContext)->PhysicalPresence(tspContext,
234 TPM_PHYSICAL_PRESENCE_HW_ENABLE);
235 else
236 result = TCS_API(tspContext)->PhysicalPresence(tspContext,
237 TPM_PHYSICAL_PRESENCE_HW_DISABLE);
238 break;
239 case TSS_TPMSTATUS_PHYSPRES_CMDENABLE:
240 /* CMDENABLE, TRUE -> set the TPM_PHYSICAL_PRESENCE_CMD_ENABLE bit
241 * CMDENABLE, FALSE -> set the TPM_PHYSICAL_PRESENCE_CMD_DISABLE bit */
242 if (fTpmState)
243 result = TCS_API(tspContext)->PhysicalPresence(tspContext,
244 TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
245 else
246 result = TCS_API(tspContext)->PhysicalPresence(tspContext,
247 TPM_PHYSICAL_PRESENCE_CMD_DISABLE);
248 break;
249 case TSS_TPMSTATUS_PHYSPRES_LOCK:
250 /* set the physical presence lock bit */
251 result = TCS_API(tspContext)->PhysicalPresence(tspContext,
252 TPM_PHYSICAL_PRESENCE_LOCK);
253 break;
254 case TSS_TPMSTATUS_PHYSPRESENCE:
255 /* set the physical presence state */
256 result = TCS_API(tspContext)->PhysicalPresence(tspContext, (fTpmState ?
257 TPM_PHYSICAL_PRESENCE_PRESENT :
258 TPM_PHYSICAL_PRESENCE_NOTPRESENT));
259 break;
260 #endif
261 default:
262 return TSPERR(TSS_E_BAD_PARAMETER);
263 break;
264 }
265
266 return result;
267 }
268
269 TSS_RESULT
Tspi_TPM_GetStatus(TSS_HTPM hTPM,TSS_FLAG statusFlag,TSS_BOOL * pfTpmState)270 Tspi_TPM_GetStatus(TSS_HTPM hTPM, /* in */
271 TSS_FLAG statusFlag, /* in */
272 TSS_BOOL * pfTpmState) /* out */
273 {
274 TSS_HCONTEXT tspContext;
275 TSS_RESULT result;
276 UINT32 nonVolFlags;
277 UINT32 volFlags;
278
279 if (pfTpmState == NULL)
280 return TSPERR(TSS_E_BAD_PARAMETER);
281
282 if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
283 return result;
284
285 if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags)))
286 return result;
287
288 switch (statusFlag) {
289 case TSS_TPMSTATUS_DISABLEOWNERCLEAR:
290 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLEOWNERCLEAR_BIT);
291 break;
292 case TSS_TPMSTATUS_DISABLEFORCECLEAR:
293 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_DISABLEFORCECLEAR_BIT);
294 break;
295 case TSS_TPMSTATUS_DISABLED:
296 case TSS_TPMSTATUS_OWNERSETDISABLE:
297 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLE_BIT);
298 break;
299 case TSS_TPMSTATUS_DEACTIVATED:
300 case TSS_TPMSTATUS_PHYSICALSETDEACTIVATED:
301 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DEACTIVATED_BIT);
302 break;
303 case TSS_TPMSTATUS_SETTEMPDEACTIVATED:
304 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_DEACTIVATED_BIT);
305 break;
306 case TSS_TPMSTATUS_SETOWNERINSTALL:
307 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OWNERSHIP_BIT);
308 break;
309 case TSS_TPMSTATUS_DISABLEPUBEKREAD:
310 *pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READPUBEK_BIT);
311 break;
312 case TSS_TPMSTATUS_ALLOWMAINTENANCE:
313 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ALLOWMAINTENANCE_BIT);
314 break;
315 case TSS_TPMSTATUS_MAINTENANCEUSED:
316 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_MAINTENANCEDONE_BIT);
317 break;
318 case TSS_TPMSTATUS_PHYSPRES_LIFETIMELOCK:
319 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCELIFETIMELOCK_BIT);
320 break;
321 case TSS_TPMSTATUS_PHYSPRES_HWENABLE:
322 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCEHWENABLE_BIT);
323 break;
324 case TSS_TPMSTATUS_PHYSPRES_CMDENABLE:
325 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCECMDENABLE_BIT);
326 break;
327 case TSS_TPMSTATUS_CEKP_USED:
328 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_CEKPUSED_BIT);
329 break;
330 case TSS_TPMSTATUS_PHYSPRESENCE:
331 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCE_BIT);
332 break;
333 case TSS_TPMSTATUS_PHYSPRES_LOCK:
334 *pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCELOCK_BIT);
335 break;
336 case TSS_TPMSTATUS_TPMPOST:
337 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOST_BIT);
338 break;
339 case TSS_TPMSTATUS_TPMPOSTLOCK:
340 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOSTLOCK_BIT);
341 break;
342 case TSS_TPMSTATUS_FIPS:
343 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_FIPS_BIT);
344 break;
345 case TSS_TPMSTATUS_ENABLE_REVOKEEK:
346 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ENABLEREVOKEEK_BIT);
347 break;
348 case TSS_TPMSTATUS_TPM_ESTABLISHED:
349 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_RESETESTABLISHMENTBIT_BIT);
350 break;
351 case TSS_TPMSTATUS_NV_LOCK:
352 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_NV_LOCKED_BIT);
353 break;
354 case TSS_TPMSTATUS_POSTINITIALISE:
355 /* There is no way to query the TPM for this flag. */
356 result = TSPERR(TSS_E_NOTIMPL);
357 break;
358 #ifdef TSS_BUILD_TSS12
359 case TSS_TPMSTATUS_DISABLEPUBSRKREAD:
360 *pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READSRKPUB_BIT);
361 break;
362 case TSS_TPMSTATUS_OPERATORINSTALLED:
363 *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OPERATOR_BIT);
364 break;
365 #endif
366 default:
367 return TSPERR(TSS_E_BAD_PARAMETER);
368 break;
369 }
370
371 return TSS_SUCCESS;
372 }
373