Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: firmware/lib/rollback_index.c

Issue 2804038: Never set bGlobalLock in recovery/dev mode. Don't try to fix bad kernel space. (Closed) Base URL: ssh://git@chromiumos-git/vboot_reference.git
Patch Set: . Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « firmware/lib/include/tss_constants.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* 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 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 * 4 *
5 * Functions for querying, manipulating and locking rollback indices 5 * Functions for querying, manipulating and locking rollback indices
6 * stored in the TPM NVRAM. 6 * stored in the TPM NVRAM.
7 */ 7 */
8 8
9 #include "rollback_index.h" 9 #include "rollback_index.h"
10 10
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 } 129 }
130 return TPM_SUCCESS; 130 return TPM_SUCCESS;
131 } 131 }
132 132
133 /* Checks if the kernel version space has been mucked with. If it has, 133 /* Checks if the kernel version space has been mucked with. If it has,
134 * reconstructs it using the backup value. 134 * reconstructs it using the backup value.
135 */ 135 */
136 uint32_t RecoverKernelSpace(void) { 136 uint32_t RecoverKernelSpace(void) {
137 uint32_t perms = 0; 137 uint32_t perms = 0;
138 uint8_t buffer[KERNEL_SPACE_SIZE]; 138 uint8_t buffer[KERNEL_SPACE_SIZE];
139 int read_OK = 0;
140 int perms_OK = 0;
141 uint32_t backup_combined_versions; 139 uint32_t backup_combined_versions;
142 uint32_t must_use_backup; 140 uint32_t must_use_backup;
141 uint32_t zero = 0;
143 142
144 RETURN_ON_FAILURE(TlclRead(KERNEL_MUST_USE_BACKUP_NV_INDEX, 143 RETURN_ON_FAILURE(TlclRead(KERNEL_MUST_USE_BACKUP_NV_INDEX,
145 (uint8_t*) &must_use_backup, sizeof(uint32_t))); 144 (uint8_t*) &must_use_backup, sizeof(uint32_t)));
146 /* must_use_backup is true if the previous boot entered recovery mode. */ 145 /* must_use_backup is true if the previous boot entered recovery mode. */
147 146
148 read_OK = TlclRead(KERNEL_VERSIONS_NV_INDEX, (uint8_t*) &buffer, 147 /* If we can't read the kernel space, or it has the wrong permission, or it
149 KERNEL_SPACE_SIZE) == TPM_SUCCESS; 148 * doesn't contain the right identifier, we give up. This will need to be
150 if (read_OK) { 149 * fixed by the recovery kernel. We have to worry about this because at any
151 RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_VERSIONS_NV_INDEX, &perms)); 150 * time (even with PP turned off) the TPM owner can remove and redefine a
152 perms_OK = perms == TPM_NV_PER_PPWRITE; 151 * PP-protected space (but not write to it).
153 } 152 */
154 if (!must_use_backup && read_OK && perms_OK && 153 RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX, (uint8_t*) &buffer,
154 KERNEL_SPACE_SIZE));
155 RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_VERSIONS_NV_INDEX, &perms));
156 if (perms != TPM_NV_PER_PPWRITE ||
155 !Memcmp(buffer + sizeof(uint32_t), KERNEL_SPACE_UID, 157 !Memcmp(buffer + sizeof(uint32_t), KERNEL_SPACE_UID,
156 KERNEL_SPACE_UID_SIZE)) { 158 KERNEL_SPACE_UID_SIZE)) {
157 /* Everything is fine. This is the normal, frequent path. */ 159 return TPM_E_CORRUPTED_STATE;
158 return TPM_SUCCESS;
159 } 160 }
160 161
161 /* Either we detected that something went wrong, or we cannot trust the
162 * PP-protected kernel space. Attempts to fix. It is not always necessary
163 * to redefine the space, but we might as well, since this path should be
164 * taken quite seldom (after recovery mode and after an attack).
165 */
166 RETURN_ON_FAILURE(InitializeKernelVersionsSpaces());
167 RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_BACKUP_NV_INDEX,
168 (uint8_t*) &backup_combined_versions,
169 sizeof(uint32_t)));
170 RETURN_ON_FAILURE(SafeWrite(KERNEL_VERSIONS_NV_INDEX,
171 (uint8_t*) &backup_combined_versions,
172 sizeof(uint32_t)));
173 if (must_use_backup) { 162 if (must_use_backup) {
174 uint32_t zero = 0; 163 /* We must use the backup space because in the preceding boot cycle the
164 * primary space was left unlocked and cannot be trusted.
165 */
166 RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_BACKUP_NV_INDEX,
167 (uint8_t*) &backup_combined_versions,
168 sizeof(uint32_t)));
169 RETURN_ON_FAILURE(SafeWrite(KERNEL_VERSIONS_NV_INDEX,
170 (uint8_t*) &backup_combined_versions,
171 sizeof(uint32_t)));
175 RETURN_ON_FAILURE(SafeWrite(KERNEL_MUST_USE_BACKUP_NV_INDEX, 172 RETURN_ON_FAILURE(SafeWrite(KERNEL_MUST_USE_BACKUP_NV_INDEX,
176 (uint8_t*) &zero, 0)); 173 (uint8_t*) &zero, 0));
177 } 174 }
178 return TPM_SUCCESS; 175 return TPM_SUCCESS;
179 } 176 }
180 177
181 static uint32_t BackupKernelSpace(void) { 178 static uint32_t BackupKernelSpace(void) {
182 uint32_t kernel_versions; 179 uint32_t kernel_versions;
183 uint32_t backup_versions; 180 uint32_t backup_versions;
184 RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX, 181 RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX,
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 return SafeWrite(FIRMWARE_VERSIONS_NV_INDEX, 292 return SafeWrite(FIRMWARE_VERSIONS_NV_INDEX,
296 (uint8_t*) &combined_version, 293 (uint8_t*) &combined_version,
297 sizeof(uint32_t)); 294 sizeof(uint32_t));
298 } 295 }
299 296
300 uint32_t RollbackFirmwareLock(void) { 297 uint32_t RollbackFirmwareLock(void) {
301 return TlclSetGlobalLock(); 298 return TlclSetGlobalLock();
302 } 299 }
303 300
304 uint32_t RollbackKernelRecovery(int developer_mode) { 301 uint32_t RollbackKernelRecovery(int developer_mode) {
305 uint32_t result = SetupTPM(1, developer_mode); 302 (void) SetupTPM(1, developer_mode);
306 if (result == TPM_SUCCESS) { 303 /* In recovery mode we ignore TPM malfunctions or corruptions, and leave the
304 * TPM completely unlocked if and only if the dev mode switch is ON. The
305 * recovery kernel will fix the TPM (if needed) and lock it ASAP. We leave
306 * Physical Presence on in either case.
307 */
308 if (!developer_mode) {
307 RETURN_ON_FAILURE(TlclSetGlobalLock()); 309 RETURN_ON_FAILURE(TlclSetGlobalLock());
308 } 310 }
309 return TPM_SUCCESS; 311 return TPM_SUCCESS;
310 } 312 }
311 313
312 uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) { 314 uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) {
313 uint32_t kernel_versions; 315 uint32_t kernel_versions;
314 if (g_rollback_recovery_mode) { 316 if (g_rollback_recovery_mode) {
315 *key_version = 0; 317 *key_version = 0;
316 *version = 0; 318 *version = 0;
(...skipping 18 matching lines...) Expand all
335 return TPM_SUCCESS; 337 return TPM_SUCCESS;
336 } 338 }
337 339
338 uint32_t RollbackKernelLock(void) { 340 uint32_t RollbackKernelLock(void) {
339 if (!g_rollback_recovery_mode) { 341 if (!g_rollback_recovery_mode) {
340 return TlclLockPhysicalPresence(); 342 return TlclLockPhysicalPresence();
341 } else { 343 } else {
342 return TPM_SUCCESS; 344 return TPM_SUCCESS;
343 } 345 }
344 } 346 }
OLDNEW
« no previous file with comments | « firmware/lib/include/tss_constants.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698