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
25TSS_RESULT
26Tspi_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		/* set the HW enable bit */
231		result = TCS_API(tspContext)->PhysicalPresence(tspContext,
232							       TPM_PHYSICAL_PRESENCE_HW_ENABLE);
233		break;
234	case TSS_TPMSTATUS_PHYSPRES_CMDENABLE:
235		/* set the command enable bit */
236		result = TCS_API(tspContext)->PhysicalPresence(tspContext,
237							       TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
238		break;
239	case TSS_TPMSTATUS_PHYSPRES_LOCK:
240		/* set the physical presence lock bit */
241		result = TCS_API(tspContext)->PhysicalPresence(tspContext,
242							       TPM_PHYSICAL_PRESENCE_LOCK);
243		break;
244	case TSS_TPMSTATUS_PHYSPRESENCE:
245		/* set the physical presence state */
246		result = TCS_API(tspContext)->PhysicalPresence(tspContext, (fTpmState ?
247							       TPM_PHYSICAL_PRESENCE_PRESENT :
248							       TPM_PHYSICAL_PRESENCE_NOTPRESENT));
249		break;
250#endif
251	default:
252		return TSPERR(TSS_E_BAD_PARAMETER);
253		break;
254	}
255
256	return result;
257}
258
259TSS_RESULT
260Tspi_TPM_GetStatus(TSS_HTPM hTPM,		/* in */
261		   TSS_FLAG statusFlag,		/* in */
262		   TSS_BOOL * pfTpmState)	/* out */
263{
264	TSS_HCONTEXT tspContext;
265	TSS_RESULT result;
266	UINT32 nonVolFlags;
267	UINT32 volFlags;
268
269	if (pfTpmState == NULL)
270		return TSPERR(TSS_E_BAD_PARAMETER);
271
272	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
273		return result;
274
275	if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags)))
276		return result;
277
278	switch (statusFlag) {
279	case TSS_TPMSTATUS_DISABLEOWNERCLEAR:
280		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLEOWNERCLEAR_BIT);
281		break;
282	case TSS_TPMSTATUS_DISABLEFORCECLEAR:
283		*pfTpmState = BOOL(volFlags & TSS_TPM_SF_DISABLEFORCECLEAR_BIT);
284		break;
285	case TSS_TPMSTATUS_DISABLED:
286	case TSS_TPMSTATUS_OWNERSETDISABLE:
287		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLE_BIT);
288		break;
289	case TSS_TPMSTATUS_DEACTIVATED:
290	case TSS_TPMSTATUS_PHYSICALSETDEACTIVATED:
291		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DEACTIVATED_BIT);
292		break;
293	case TSS_TPMSTATUS_SETTEMPDEACTIVATED:
294		*pfTpmState = BOOL(volFlags & TSS_TPM_SF_DEACTIVATED_BIT);
295		break;
296	case TSS_TPMSTATUS_SETOWNERINSTALL:
297		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OWNERSHIP_BIT);
298		break;
299	case TSS_TPMSTATUS_DISABLEPUBEKREAD:
300		*pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READPUBEK_BIT);
301		break;
302	case TSS_TPMSTATUS_ALLOWMAINTENANCE:
303		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ALLOWMAINTENANCE_BIT);
304		break;
305	case TSS_TPMSTATUS_MAINTENANCEUSED:
306		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_MAINTENANCEDONE_BIT);
307		break;
308	case TSS_TPMSTATUS_PHYSPRES_LIFETIMELOCK:
309		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCELIFETIMELOCK_BIT);
310		break;
311	case TSS_TPMSTATUS_PHYSPRES_HWENABLE:
312		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCEHWENABLE_BIT);
313		break;
314	case TSS_TPMSTATUS_PHYSPRES_CMDENABLE:
315		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCECMDENABLE_BIT);
316		break;
317	case TSS_TPMSTATUS_CEKP_USED:
318		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_CEKPUSED_BIT);
319		break;
320	case TSS_TPMSTATUS_PHYSPRESENCE:
321		*pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCE_BIT);
322		break;
323	case TSS_TPMSTATUS_PHYSPRES_LOCK:
324		*pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCELOCK_BIT);
325		break;
326	case TSS_TPMSTATUS_TPMPOST:
327		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOST_BIT);
328		break;
329	case TSS_TPMSTATUS_TPMPOSTLOCK:
330		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOSTLOCK_BIT);
331		break;
332	case TSS_TPMSTATUS_FIPS:
333		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_FIPS_BIT);
334		break;
335	case TSS_TPMSTATUS_ENABLE_REVOKEEK:
336		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ENABLEREVOKEEK_BIT);
337		break;
338	case TSS_TPMSTATUS_TPM_ESTABLISHED:
339		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_RESETESTABLISHMENTBIT_BIT);
340		break;
341	case TSS_TPMSTATUS_NV_LOCK:
342		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_NV_LOCKED_BIT);
343		break;
344	case TSS_TPMSTATUS_POSTINITIALISE:
345		/* There is no way to query the TPM for this flag. */
346		result = TSPERR(TSS_E_NOTIMPL);
347		break;
348#ifdef TSS_BUILD_TSS12
349	case TSS_TPMSTATUS_DISABLEPUBSRKREAD:
350		*pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READSRKPUB_BIT);
351		break;
352	case TSS_TPMSTATUS_OPERATORINSTALLED:
353		*pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OPERATOR_BIT);
354		break;
355#endif
356	default:
357		return TSPERR(TSS_E_BAD_PARAMETER);
358		break;
359	}
360
361	return TSS_SUCCESS;
362}
363