xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tspi_admin.c (revision 1023804e3833a0bd94414f2545512128f6502c74)
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