xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tspi_admin.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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
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 		/* 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 
259 TSS_RESULT
260 Tspi_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