blob: 7467bedc2fcfd80d5d20b0c82a73e2dbcd1c011d [file] [log] [blame]
Gaurav Shahce0cc302010-03-24 13:48:55 -07001/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Functions for querying, manipulating and locking rollback indices
6 * stored in the TPM NVRAM.
7 */
8
9#include "rollback_index.h"
10
Gaurav Shahce0cc302010-03-24 13:48:55 -070011#include "tlcl.h"
Gaurav Shah887e3d42010-04-27 16:26:48 -070012#include "tss_constants.h"
Randall Spanglerf3029052010-06-16 13:42:58 -070013#include "utility.h"
Gaurav Shahce0cc302010-03-24 13:48:55 -070014
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -070015static int g_rollback_recovery_mode = 0;
Gaurav Shahce0cc302010-03-24 13:48:55 -070016
vbendeb3ecaf772010-06-24 16:19:53 -070017/* disable MSVC warning on const logical expression (as in } while(0);) */
18__pragma(warning (disable: 4127))
19
Luigi Semenzato4f11c362010-06-10 11:01:04 -070020#define RETURN_ON_FAILURE(tpm_command) do { \
21 uint32_t result; \
22 if ((result = (tpm_command)) != TPM_SUCCESS) { \
Randall Spangler7a786b72010-07-08 13:29:42 -070023 VBDEBUG(("Rollback: %08x returned by " #tpm_command "\n", (int)result)); \
Luigi Semenzato4f11c362010-06-10 11:01:04 -070024 return result; \
25 } \
Luigi Semenzato59204c52010-06-09 13:37:15 -070026 } while (0)
27
Randall Spangler4abede32010-08-12 16:40:32 -070028
Luigi Semenzato416f6812010-07-08 12:12:12 -070029uint32_t TPMClearAndReenable(void) {
Randall Spangler3e1081f2010-07-19 10:04:21 -070030 VBDEBUG(("TPM: Clear and re-enable\n"));
Luigi Semenzato361049c2010-06-22 13:37:53 -070031 RETURN_ON_FAILURE(TlclForceClear());
32 RETURN_ON_FAILURE(TlclSetEnable());
33 RETURN_ON_FAILURE(TlclSetDeactivated(0));
Randall Spanglerada3fa92010-07-20 15:35:49 -070034
Luigi Semenzato361049c2010-06-22 13:37:53 -070035 return TPM_SUCCESS;
36}
37
Randall Spangler4abede32010-08-12 16:40:32 -070038
Luigi Semenzato361049c2010-06-22 13:37:53 -070039/* Like TlclWrite(), but checks for write errors due to hitting the 64-write
40 * limit and clears the TPM when that happens. This can only happen when the
41 * TPM is unowned, so it is OK to clear it (and we really have no choice).
42 * This is not expected to happen frequently, but it could happen.
43 */
Randall Spangler4abede32010-08-12 16:40:32 -070044static uint32_t SafeWrite(uint32_t index, const void* data, uint32_t length) {
Luigi Semenzato361049c2010-06-22 13:37:53 -070045 uint32_t result = TlclWrite(index, data, length);
46 if (result == TPM_E_MAXNVWRITES) {
47 RETURN_ON_FAILURE(TPMClearAndReenable());
48 return TlclWrite(index, data, length);
49 } else {
50 return result;
51 }
52}
53
Randall Spangler4abede32010-08-12 16:40:32 -070054
Luigi Semenzato8510d912010-07-08 15:40:30 -070055/* Similarly to SafeWrite(), this ensures we don't fail a DefineSpace because
56 * we hit the TPM write limit. This is even less likely to happen than with
57 * writes because we only define spaces once at initialization, but we'd rather
58 * be paranoid about this.
59 */
60static uint32_t SafeDefineSpace(uint32_t index, uint32_t perm, uint32_t size) {
61 uint32_t result = TlclDefineSpace(index, perm, size);
62 if (result == TPM_E_MAXNVWRITES) {
63 RETURN_ON_FAILURE(TPMClearAndReenable());
64 return TlclDefineSpace(index, perm, size);
65 } else {
66 return result;
67 }
68}
69
Randall Spangler4abede32010-08-12 16:40:32 -070070
71/* Functions to read and write firmware and kernel spaces. */
72static uint32_t ReadSpaceFirmware(RollbackSpaceFirmware* rsf) {
73 return TlclRead(FIRMWARE_NV_INDEX, rsf, sizeof(RollbackSpaceFirmware));
Luigi Semenzato4f11c362010-06-10 11:01:04 -070074}
75
Randall Spangler4abede32010-08-12 16:40:32 -070076static uint32_t WriteSpaceFirmware(const RollbackSpaceFirmware* rsf) {
77 return SafeWrite(FIRMWARE_NV_INDEX, rsf, sizeof(RollbackSpaceFirmware));
Luigi Semenzato4f11c362010-06-10 11:01:04 -070078}
79
Randall Spanglerbb5d9f12010-08-16 15:36:07 -070080#ifndef DISABLE_ROLLBACK_TPM
Randall Spangler4abede32010-08-12 16:40:32 -070081static uint32_t ReadSpaceKernel(RollbackSpaceKernel* rsk) {
82 return TlclRead(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
83}
Randall Spanglerbb5d9f12010-08-16 15:36:07 -070084#endif
Randall Spangler4abede32010-08-12 16:40:32 -070085
86static uint32_t WriteSpaceKernel(const RollbackSpaceKernel* rsk) {
87 return SafeWrite(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
88}
89
Randall Spangler4abede32010-08-12 16:40:32 -070090/* Creates the NVRAM spaces, and sets their initial values as needed. */
91static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf,
92 RollbackSpaceKernel* rsk) {
93 static const RollbackSpaceFirmware rsf_init = {
94 ROLLBACK_SPACE_FIRMWARE_VERSION, 0, 0, 0};
95 static const RollbackSpaceKernel rsk_init = {
96 ROLLBACK_SPACE_KERNEL_VERSION, ROLLBACK_SPACE_KERNEL_UID, 0, 0};
Randall Spangler3e1081f2010-07-19 10:04:21 -070097 uint8_t nvlocked = 0;
Gaurav Shahce0cc302010-03-24 13:48:55 -070098
Randall Spangler3e1081f2010-07-19 10:04:21 -070099 VBDEBUG(("TPM: Initializing spaces\n"));
Gaurav Shahce0cc302010-03-24 13:48:55 -0700100
Randall Spangler4abede32010-08-12 16:40:32 -0700101 /* The TPM will not enforce the NV authorization restrictions until the
Randall Spangler63dffcb2010-08-05 15:13:14 -0700102 * execution of a TPM_NV_DefineSpace with the handle of TPM_NV_INDEX_LOCK.
103 * Create that space if it doesn't already exist. */
Randall Spangler3e1081f2010-07-19 10:04:21 -0700104 RETURN_ON_FAILURE(TlclGetFlags(NULL, NULL, &nvlocked));
105 VBDEBUG(("TPM: nvlocked=%d\n", nvlocked));
106 if (!nvlocked) {
107 VBDEBUG(("TPM: Enabling NV locking\n"));
108 RETURN_ON_FAILURE(TlclSetNvLocked());
109 }
110
Randall Spangler4abede32010-08-12 16:40:32 -0700111 /* Initialize the firmware and kernel spaces */
112 Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware));
Randall Spangler4abede32010-08-12 16:40:32 -0700113 Memcpy(rsk, &rsk_init, sizeof(RollbackSpaceKernel));
Gaurav Shahce0cc302010-03-24 13:48:55 -0700114
Randall Spangler4abede32010-08-12 16:40:32 -0700115 /* Define and set firmware and kernel spaces */
116 RETURN_ON_FAILURE(SafeDefineSpace(FIRMWARE_NV_INDEX,
117 TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE,
118 sizeof(RollbackSpaceFirmware)));
119 RETURN_ON_FAILURE(WriteSpaceFirmware(rsf));
120 RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_NV_INDEX, TPM_NV_PER_PPWRITE,
121 sizeof(RollbackSpaceKernel)));
122 RETURN_ON_FAILURE(WriteSpaceKernel(rsk));
Luigi Semenzato59204c52010-06-09 13:37:15 -0700123 return TPM_SUCCESS;
Gaurav Shahce0cc302010-03-24 13:48:55 -0700124}
125
Luigi Semenzato2666f102010-06-15 08:12:32 -0700126
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700127/* SetupTPM starts the TPM and establishes the root of trust for the
128 * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a
129 * TPM hardware failure. 3 An unexpected TPM state due to some attack. In
130 * general we cannot easily distinguish the kind of failure, so our strategy is
131 * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM
132 * again, which executes (almost) the same sequence of operations. There is a
133 * good chance that, if recovery mode was entered because of a TPM failure, the
134 * failure will repeat itself. (In general this is impossible to guarantee
135 * because we have no way of creating the exact TPM initial state at the
136 * previous boot.) In recovery mode, we ignore the failure and continue, thus
137 * giving the recovery kernel a chance to fix things (that's why we don't set
138 * bGlobalLock). The choice is between a knowingly insecure device and a
139 * bricked device.
140 *
141 * As a side note, observe that we go through considerable hoops to avoid using
142 * the STCLEAR permissions for the index spaces. We do this to avoid writing
143 * to the TPM flashram at every reboot or wake-up, because of concerns about
144 * the durability of the NVRAM.
145 */
Randall Spangler4abede32010-08-12 16:40:32 -0700146uint32_t SetupTPM(int recovery_mode, int developer_mode,
147 RollbackSpaceFirmware* rsf) {
148
Randall Spangler4abede32010-08-12 16:40:32 -0700149 int rsf_dirty = 0;
150 uint8_t new_flags = 0;
Luigi Semenzato596b6402010-05-27 14:04:52 -0700151 uint8_t disable;
152 uint8_t deactivated;
Luigi Semenzato416f6812010-07-08 12:12:12 -0700153 uint32_t result;
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700154
Randall Spangler3e1081f2010-07-19 10:04:21 -0700155 VBDEBUG(("TPM: SetupTPM(r%d, d%d)\n", recovery_mode, developer_mode));
156
157 /* TODO: TlclLibInit() should be able to return failure */
Luigi Semenzato59204c52010-06-09 13:37:15 -0700158 TlclLibInit();
Randall Spangler3e1081f2010-07-19 10:04:21 -0700159
Luigi Semenzato59204c52010-06-09 13:37:15 -0700160 RETURN_ON_FAILURE(TlclStartup());
Randall Spangler3e1081f2010-07-19 10:04:21 -0700161#ifdef USE_CONTINUE_SELF_TEST
Randall Spangler4abede32010-08-12 16:40:32 -0700162 /* TODO: ContinueSelfTest() should be faster than SelfTestFull, but
163 * may also not work properly in older TPM firmware. For now, do
164 * the full self test. */
Luigi Semenzato59204c52010-06-09 13:37:15 -0700165 RETURN_ON_FAILURE(TlclContinueSelfTest());
Randall Spangler3e1081f2010-07-19 10:04:21 -0700166#else
167 RETURN_ON_FAILURE(TlclSelfTestFull());
168#endif
Luigi Semenzato59204c52010-06-09 13:37:15 -0700169 RETURN_ON_FAILURE(TlclAssertPhysicalPresence());
Randall Spangler4abede32010-08-12 16:40:32 -0700170
171 /* Check that the TPM is enabled and activated. */
Randall Spangler3e1081f2010-07-19 10:04:21 -0700172 RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated, NULL));
Luigi Semenzato596b6402010-05-27 14:04:52 -0700173 if (disable || deactivated) {
Randall Spangler4abede32010-08-12 16:40:32 -0700174 VBDEBUG(("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
175 disable, deactivated));
Luigi Semenzato59204c52010-06-09 13:37:15 -0700176 RETURN_ON_FAILURE(TlclSetEnable());
177 RETURN_ON_FAILURE(TlclSetDeactivated(0));
Randall Spangler3e1081f2010-07-19 10:04:21 -0700178 VBDEBUG(("TPM: Must reboot to re-enable\n"));
Luigi Semenzato2666f102010-06-15 08:12:32 -0700179 return TPM_E_MUST_REBOOT;
Luigi Semenzato596b6402010-05-27 14:04:52 -0700180 }
Randall Spangler4abede32010-08-12 16:40:32 -0700181
182 /* Read the firmware space. */
183 result = ReadSpaceFirmware(rsf);
184 if (TPM_E_BADINDEX == result) {
Randall Spanglerbb5d9f12010-08-16 15:36:07 -0700185 RollbackSpaceKernel rsk;
186
Randall Spangler4abede32010-08-12 16:40:32 -0700187 /* This is the first time we've run, and the TPM has not been
188 * initialized. Initialize it. */
189 VBDEBUG(("TPM: Not initialized yet.\n"));
190 RETURN_ON_FAILURE(InitializeSpaces(rsf, &rsk));
191 } else if (TPM_SUCCESS != result) {
192 VBDEBUG(("TPM: Firmware space in a bad state; giving up.\n"));
193 return TPM_E_CORRUPTED_STATE;
194 }
195 VBDEBUG(("TPM: Firmware space sv%d f%x v%x\n",
196 rsf->struct_version, rsf->flags, rsf->fw_versions));
197
Randall Spangler4abede32010-08-12 16:40:32 -0700198 /* Clear ownership if developer flag has toggled */
199 if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) !=
200 (rsf->flags & FLAG_LAST_BOOT_DEVELOPER)) {
201 VBDEBUG(("TPM: Developer flag changed; clearing owner.\n"));
202 RETURN_ON_FAILURE(TPMClearAndReenable());
Luigi Semenzato2666f102010-06-15 08:12:32 -0700203 }
Randall Spangler4abede32010-08-12 16:40:32 -0700204
205 /* Update flags */
206 if (developer_mode)
207 new_flags |= FLAG_LAST_BOOT_DEVELOPER;
Randall Spanglerbb5d9f12010-08-16 15:36:07 -0700208 if (recovery_mode)
Randall Spangler4abede32010-08-12 16:40:32 -0700209 g_rollback_recovery_mode = 1; /* Global variables are usable in
210 * recovery mode */
Randall Spanglerbb5d9f12010-08-16 15:36:07 -0700211
Randall Spangler4abede32010-08-12 16:40:32 -0700212 if (rsf->flags != new_flags) {
213 rsf->flags = new_flags;
214 rsf_dirty = 1;
215 }
216
217 /* If firmware space is dirty, flush it back to the TPM */
218 if (rsf_dirty) {
219 VBDEBUG(("TPM: Updating firmware space.\n"));
220 RETURN_ON_FAILURE(WriteSpaceFirmware(rsf));
221 }
222
Randall Spangler3e1081f2010-07-19 10:04:21 -0700223 VBDEBUG(("TPM: SetupTPM() succeeded\n"));
Luigi Semenzato59204c52010-06-09 13:37:15 -0700224 return TPM_SUCCESS;
Gaurav Shahce0cc302010-03-24 13:48:55 -0700225}
226
vbendeb3ecaf772010-06-24 16:19:53 -0700227/* disable MSVC warnings on unused arguments */
228__pragma(warning (disable: 4100))
Randall Spangler10788382010-06-23 15:35:31 -0700229
Randall Spangler39f66112010-07-14 09:10:23 -0700230
231#ifdef DISABLE_ROLLBACK_TPM
232
Randall Spanglerada3fa92010-07-20 15:35:49 -0700233/* Dummy implementations which don't support TPM rollback protection */
Randall Spangler39f66112010-07-14 09:10:23 -0700234
Randall Spangler66680282010-08-16 12:33:44 -0700235uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
Randall Spanglerada3fa92010-07-20 15:35:49 -0700236#ifndef CHROMEOS_ENVIRONMENT
237 /* Initialize the TPM, but ignore return codes. In ChromeOS
238 * environment, don't even talk to the TPM. */
239 TlclLibInit();
240 TlclStartup();
Randall Spangler63dffcb2010-08-05 15:13:14 -0700241 TlclSelfTestFull();
Randall Spanglerada3fa92010-07-20 15:35:49 -0700242#endif
Randall Spangler39f66112010-07-14 09:10:23 -0700243
Randall Spangler66680282010-08-16 12:33:44 -0700244 *version = 0;
Randall Spangler39f66112010-07-14 09:10:23 -0700245 return TPM_SUCCESS;
246}
247
Randall Spangler66680282010-08-16 12:33:44 -0700248uint32_t RollbackFirmwareWrite(uint32_t version) {
Randall Spangler39f66112010-07-14 09:10:23 -0700249 return TPM_SUCCESS;
250}
251
252uint32_t RollbackFirmwareLock(void) {
253 return TPM_SUCCESS;
254}
255
256uint32_t RollbackKernelRecovery(int developer_mode) {
Randall Spanglerada3fa92010-07-20 15:35:49 -0700257#ifndef CHROMEOS_ENVIRONMENT
258 /* Initialize the TPM, but ignore return codes. In ChromeOS
259 * environment, don't even talk to the TPM. */
260 TlclLibInit();
261 TlclStartup();
Randall Spangler63dffcb2010-08-05 15:13:14 -0700262 TlclSelfTestFull();
Randall Spanglerada3fa92010-07-20 15:35:49 -0700263#endif
Randall Spangler39f66112010-07-14 09:10:23 -0700264 return TPM_SUCCESS;
265}
266
Randall Spangler66680282010-08-16 12:33:44 -0700267uint32_t RollbackKernelRead(uint32_t* version) {
268 *version = 0;
Randall Spangler39f66112010-07-14 09:10:23 -0700269 return TPM_SUCCESS;
270}
271
Randall Spangler66680282010-08-16 12:33:44 -0700272uint32_t RollbackKernelWrite(uint32_t version) {
Randall Spangler39f66112010-07-14 09:10:23 -0700273 return TPM_SUCCESS;
274}
275
276uint32_t RollbackKernelLock(void) {
277 return TPM_SUCCESS;
278}
279
280#else
281
Randall Spangler66680282010-08-16 12:33:44 -0700282uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
Randall Spangler4abede32010-08-12 16:40:32 -0700283 RollbackSpaceFirmware rsf;
Randall Spangler10788382010-06-23 15:35:31 -0700284
Randall Spangler4abede32010-08-12 16:40:32 -0700285 RETURN_ON_FAILURE(SetupTPM(0, developer_mode, &rsf));
Randall Spangler66680282010-08-16 12:33:44 -0700286 *version = rsf.fw_versions;
Randall Spanglerbb5d9f12010-08-16 15:36:07 -0700287 VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)rsf.fw_versions));
Randall Spangler10788382010-06-23 15:35:31 -0700288 return TPM_SUCCESS;
289}
290
Randall Spangler66680282010-08-16 12:33:44 -0700291uint32_t RollbackFirmwareWrite(uint32_t version) {
Randall Spangler4abede32010-08-12 16:40:32 -0700292 RollbackSpaceFirmware rsf;
Randall Spangler4abede32010-08-12 16:40:32 -0700293
294 RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf));
Randall Spangler66680282010-08-16 12:33:44 -0700295 VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)rsf.fw_versions,
296 (int)version));
297 rsf.fw_versions = version;
Randall Spangler4abede32010-08-12 16:40:32 -0700298 return WriteSpaceFirmware(&rsf);
Randall Spangler10788382010-06-23 15:35:31 -0700299}
300
301uint32_t RollbackFirmwareLock(void) {
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700302 return TlclSetGlobalLock();
Randall Spangler10788382010-06-23 15:35:31 -0700303}
304
305uint32_t RollbackKernelRecovery(int developer_mode) {
Randall Spangler4abede32010-08-12 16:40:32 -0700306 RollbackSpaceFirmware rsf;
307 uint32_t result = SetupTPM(1, developer_mode, &rsf);
Luigi Semenzato5e9c0b92010-07-02 10:36:37 -0700308 /* In recovery mode we ignore TPM malfunctions or corruptions, and leave the
309 * TPM completely unlocked if and only if the dev mode switch is ON. The
310 * recovery kernel will fix the TPM (if needed) and lock it ASAP. We leave
Randall Spangler4abede32010-08-12 16:40:32 -0700311 * Physical Presence on in either case. */
Luigi Semenzato5e9c0b92010-07-02 10:36:37 -0700312 if (!developer_mode) {
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700313 RETURN_ON_FAILURE(TlclSetGlobalLock());
314 }
Luigi Semenzato416f6812010-07-08 12:12:12 -0700315 /* We still return the result of SetupTPM even though we expect the caller to
Randall Spangler4abede32010-08-12 16:40:32 -0700316 * ignore it. It's useful in unit testing. */
Luigi Semenzato416f6812010-07-08 12:12:12 -0700317 return result;
Randall Spangler10788382010-06-23 15:35:31 -0700318}
319
Randall Spangler66680282010-08-16 12:33:44 -0700320uint32_t RollbackKernelRead(uint32_t* version) {
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700321 if (g_rollback_recovery_mode) {
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700322 *version = 0;
323 } else {
Randall Spangler4abede32010-08-12 16:40:32 -0700324 RollbackSpaceKernel rsk;
Randall Spanglerbb5d9f12010-08-16 15:36:07 -0700325 uint32_t perms;
326
327 /* Read the kernel space and verify its permissions. If the kernel
328 * space has the wrong permission, or it doesn't contain the right
329 * identifier, we give up. This will need to be fixed by the
330 * recovery kernel. We have to worry about this because at any time
331 * (even with PP turned off) the TPM owner can remove and redefine a
332 * PP-protected space (but not write to it). */
Randall Spangler4abede32010-08-12 16:40:32 -0700333 RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
Randall Spanglerbb5d9f12010-08-16 15:36:07 -0700334 RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms));
335 if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid)
336 return TPM_E_CORRUPTED_STATE;
337
Randall Spangler66680282010-08-16 12:33:44 -0700338 *version = rsk.kernel_versions;
339 VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions));
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700340 }
Randall Spangler10788382010-06-23 15:35:31 -0700341 return TPM_SUCCESS;
342}
343
Randall Spangler66680282010-08-16 12:33:44 -0700344uint32_t RollbackKernelWrite(uint32_t version) {
Randall Spangler4abede32010-08-12 16:40:32 -0700345 if (g_rollback_recovery_mode) {
346 return TPM_SUCCESS;
347 } else {
348 RollbackSpaceKernel rsk;
Randall Spangler4abede32010-08-12 16:40:32 -0700349 RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
350 VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n", (int)rsk.kernel_versions,
Randall Spangler66680282010-08-16 12:33:44 -0700351 (int)version));
352 rsk.kernel_versions = version;
Randall Spangler4abede32010-08-12 16:40:32 -0700353 return WriteSpaceKernel(&rsk);
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700354 }
Randall Spangler10788382010-06-23 15:35:31 -0700355}
356
357uint32_t RollbackKernelLock(void) {
Randall Spangler4abede32010-08-12 16:40:32 -0700358 if (g_rollback_recovery_mode) {
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700359 return TPM_SUCCESS;
Randall Spangler4abede32010-08-12 16:40:32 -0700360 } else {
361 return TlclLockPhysicalPresence();
Luigi Semenzato2b9ddae2010-06-28 13:34:31 -0700362 }
Randall Spangler10788382010-06-23 15:35:31 -0700363}
Randall Spangler39f66112010-07-14 09:10:23 -0700364
365#endif // DISABLE_ROLLBACK_TPM