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

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

Issue 6719005: Cherry-pick vboot_reference files from TOT to support crossystem (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@0.11.257.B
Patch Set: Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « firmware/lib/include/tpm_bootmode.h ('k') | firmware/lib/tpm_bootmode.c » ('j') | 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-2011 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010-2011 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
11 #include "tlcl.h" 11 #include "tlcl.h"
12 #include "tpm_bootmode.h"
12 #include "tss_constants.h" 13 #include "tss_constants.h"
13 #include "utility.h" 14 #include "utility.h"
14 15
15 /* TPM PCR to use for storing dev mode measurements */
16 #define DEV_REC_MODE_PCR 0
17 /* Input digests for PCR extend */
18 #define DEV_OFF_REC_OFF_SHA1_DIGEST ((uint8_t*) "\x14\x89\xf9\x23\xc4\xdc\xa7" \
19 "\x29\x17\x8b\x3e\x32\x33\x45\x85\x50" \
20 "\xd8\xdd\xdf\x29") /* SHA1("\x00\x00") */
21
22 #define DEV_OFF_REC_ON_SHA1_DIGEST ((uint8_t*) "\x3f\x29\x54\x64\x53\x67\x8b" \
23 "\x85\x59\x31\xc1\x74\xa9\x7d\x6c\x08" \
24 "\x94\xb8\xf5\x46") /* SHA1("\x00\x01") */
25
26 #define DEV_ON_REC_OFF_SHA1_DIGEST ((uint8_t*) "\x0e\x35\x6b\xa5\x05\x63\x1f" \
27 "\xbf\x71\x57\x58\xbe\xd2\x7d\x50\x3f" \
28 "\x8b\x26\x0e\x3a") /* SHA1("\x01\x00") */
29
30 #define DEV_ON_REC_ON_SHA1_DIGEST ((uint8_t*) "\x91\x59\xcb\x8b\xce\xe7\xfc" \
31 "\xb9\x55\x82\xf1\x40\x96\x0c\xda\xe7" \
32 "\x27\x88\xd3\x26") /* SHA1("\x01\x01") */
33
34 static int g_rollback_recovery_mode = 0; 16 static int g_rollback_recovery_mode = 0;
35 17
36 /* disable MSVC warning on const logical expression (as in } while(0);) */ 18 /* disable MSVC warning on const logical expression (as in } while(0);) */
37 __pragma(warning (disable: 4127)) 19 __pragma(warning (disable: 4127))
38 20
39 #define RETURN_ON_FAILURE(tpm_command) do { \ 21 #define RETURN_ON_FAILURE(tpm_command) do { \
40 uint32_t result; \ 22 uint32_t result; \
41 if ((result = (tpm_command)) != TPM_SUCCESS) { \ 23 if ((result = (tpm_command)) != TPM_SUCCESS) { \
42 VBDEBUG(("Rollback: %08x returned by " #tpm_command "\n", (int)result)); \ 24 VBDEBUG(("Rollback: %08x returned by " #tpm_command "\n", (int)result)); \
43 return result; \ 25 return result; \
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 RollbackSpaceKernel* rsk) { 96 RollbackSpaceKernel* rsk) {
115 static const RollbackSpaceFirmware rsf_init = { 97 static const RollbackSpaceFirmware rsf_init = {
116 ROLLBACK_SPACE_FIRMWARE_VERSION, 0, 0, 0}; 98 ROLLBACK_SPACE_FIRMWARE_VERSION, 0, 0, 0};
117 static const RollbackSpaceKernel rsk_init = { 99 static const RollbackSpaceKernel rsk_init = {
118 ROLLBACK_SPACE_KERNEL_VERSION, ROLLBACK_SPACE_KERNEL_UID, 0, 0}; 100 ROLLBACK_SPACE_KERNEL_VERSION, ROLLBACK_SPACE_KERNEL_UID, 0, 0};
119 TPM_PERMANENT_FLAGS pflags; 101 TPM_PERMANENT_FLAGS pflags;
120 uint32_t result; 102 uint32_t result;
121 103
122 VBDEBUG(("TPM: One-time initialization\n")); 104 VBDEBUG(("TPM: One-time initialization\n"));
123 105
106 /* Do a full test. This only happens the first time the device is turned on
107 * in the factory, so performance is not an issue. This is almost certainly
108 * not necessary, but it gives us more confidence about some code paths below
109 * that are difficult to test---specifically the ones that set lifetime
110 * flags, and are only executed once per physical TPM. */
111 result = TlclSelfTestFull();
112 if (result != TPM_SUCCESS)
113 return result;
114
124 result = TlclGetPermanentFlags(&pflags); 115 result = TlclGetPermanentFlags(&pflags);
125 if (result != TPM_SUCCESS) 116 if (result != TPM_SUCCESS)
126 return result; 117 return result;
127 118
128 /* TPM may come from the factory without physical presence finalized. Fix 119 /* TPM may come from the factory without physical presence finalized. Fix
129 * if necessary. */ 120 * if necessary. */
130 VBDEBUG(("TPM: physicalPresenceLifetimeLock=%d\n", 121 VBDEBUG(("TPM: physicalPresenceLifetimeLock=%d\n",
131 pflags.physicalPresenceLifetimeLock)); 122 pflags.physicalPresenceLifetimeLock));
132 if (!pflags.physicalPresenceLifetimeLock) { 123 if (!pflags.physicalPresenceLifetimeLock) {
133 VBDEBUG(("TPM: Finalizing physical presence\n")); 124 VBDEBUG(("TPM: Finalizing physical presence\n"));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 184
194 VBDEBUG(("TPM: SetupTPM(r%d, d%d)\n", recovery_mode, developer_mode)); 185 VBDEBUG(("TPM: SetupTPM(r%d, d%d)\n", recovery_mode, developer_mode));
195 186
196 if (recovery_mode) 187 if (recovery_mode)
197 g_rollback_recovery_mode = 1; /* Global variables are usable in 188 g_rollback_recovery_mode = 1; /* Global variables are usable in
198 * recovery mode */ 189 * recovery mode */
199 190
200 RETURN_ON_FAILURE(TlclLibInit()); 191 RETURN_ON_FAILURE(TlclLibInit());
201 192
202 RETURN_ON_FAILURE(TlclStartup()); 193 RETURN_ON_FAILURE(TlclStartup());
203 /* Use ContinueSelfTest rather than SelfTestFull(). It enables 194 /* Some TPMs start the self test automatically at power on. In that case we
204 * access to the subset of TPM commands we need in the firmware, and 195 * don't need to call ContinueSelfTest. On some (other) TPMs,
205 * allows the full self test to run in paralle with firmware 196 * ContinueSelfTest may block. In that case, we definitely don't want to
206 * startup. By the time we get to the OS, self test will have 197 * call it here. For TPMs in the intersection of these two sets, we're
207 * completed. */ 198 * screwed. (In other words: TPMs that require manually starting the
199 * self-test AND block will have poor performance until we split
200 * TlclSendReceive() into Send() and Receive(), and have a state machine to
201 * control setup.)
202 *
203 * This comment is likely to become obsolete in the near future, so don't
204 * trust it. It may have not been updated.
205 */
206 #ifdef TPM_MANUAL_SELFTEST
207 #ifdef TPM_BLOCKING_CONTINUESELFTEST
208 #warning "lousy TPM!"
209 #endif
208 RETURN_ON_FAILURE(TlclContinueSelfTest()); 210 RETURN_ON_FAILURE(TlclContinueSelfTest());
211 #endif
209 result = TlclAssertPhysicalPresence(); 212 result = TlclAssertPhysicalPresence();
210 if (result != 0) { 213 if (result != 0) {
211 /* It is possible that the TPM was delivered with the physical presence 214 /* It is possible that the TPM was delivered with the physical presence
212 * command disabled. This tries enabling it, then tries asserting PP 215 * command disabled. This tries enabling it, then tries asserting PP
213 * again. 216 * again.
214 */ 217 */
215 RETURN_ON_FAILURE(TlclPhysicalPresenceCMDEnable()); 218 RETURN_ON_FAILURE(TlclPhysicalPresenceCMDEnable());
216 RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); 219 RETURN_ON_FAILURE(TlclAssertPhysicalPresence());
217 } 220 }
218 221
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 290 }
288 291
289 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { 292 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
290 #ifndef CHROMEOS_ENVIRONMENT 293 #ifndef CHROMEOS_ENVIRONMENT
291 /* Initializes the TPM, but ignores return codes. In ChromeOS 294 /* Initializes the TPM, but ignores return codes. In ChromeOS
292 * environment, doesn't even talk to the TPM. */ 295 * environment, doesn't even talk to the TPM. */
293 TlclLibInit(); 296 TlclLibInit();
294 TlclStartup(); 297 TlclStartup();
295 TlclContinueSelfTest(); 298 TlclContinueSelfTest();
296 #endif 299 #endif
297
298 *version = 0; 300 *version = 0;
299 return TPM_SUCCESS; 301 return TPM_SUCCESS;
300 } 302 }
303
304 uint32_t RollbackFirmwareRead(uint32_t* version) {
305 *version = 0;
306 return TPM_SUCCESS;
307 }
301 308
302 uint32_t RollbackFirmwareWrite(uint32_t version) { 309 uint32_t RollbackFirmwareWrite(uint32_t version) {
303 return TPM_SUCCESS; 310 return TPM_SUCCESS;
304 } 311 }
305 312
306 uint32_t RollbackFirmwareLock(void) { 313 uint32_t RollbackFirmwareLock(void) {
307 return TPM_SUCCESS; 314 return TPM_SUCCESS;
308 } 315 }
309 316
310 uint32_t RollbackKernelRecovery(int developer_mode) { 317 uint32_t RollbackKernelRecovery(int developer_mode) {
(...skipping 30 matching lines...) Expand all
341 /* We're on a platform where the TPM maintains power in S3, so 348 /* We're on a platform where the TPM maintains power in S3, so
342 it's already initialized. */ 349 it's already initialized. */
343 return TPM_SUCCESS; 350 return TPM_SUCCESS;
344 } 351 }
345 return result; 352 return result;
346 } 353 }
347 354
348 355
349 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { 356 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
350 RollbackSpaceFirmware rsf; 357 RollbackSpaceFirmware rsf;
351 uint8_t out_digest[20]; /* For PCR extend output */
352 358
353 RETURN_ON_FAILURE(SetupTPM(0, developer_mode, &rsf)); 359 RETURN_ON_FAILURE(SetupTPM(0, developer_mode, &rsf));
354 *version = rsf.fw_versions; 360 *version = rsf.fw_versions;
355 VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)rsf.fw_versions)); 361 VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)rsf.fw_versions));
356 if (developer_mode)
357 RETURN_ON_FAILURE(TlclExtend(DEV_REC_MODE_PCR, DEV_ON_REC_OFF_SHA1_DIGEST,
358 out_digest));
359 else
360 RETURN_ON_FAILURE(TlclExtend(DEV_REC_MODE_PCR, DEV_OFF_REC_OFF_SHA1_DIGEST,
361 out_digest));
362 VBDEBUG(("TPM: RollbackFirmwareSetup dev mode PCR out_digest %02x %02x %02x "
363 "%02x\n", out_digest, out_digest+1, out_digest+2, out_digest+3));
364
365 return TPM_SUCCESS; 362 return TPM_SUCCESS;
366 } 363 }
367 364
365 uint32_t RollbackFirmwareRead(uint32_t* version) {
366 RollbackSpaceFirmware rsf;
367
368 RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf));
369 VBDEBUG(("TPM: RollbackFirmwareRead %x --> %x\n", (int)rsf.fw_versions,
370 (int)version));
371 *version = rsf.fw_versions;
372 VBDEBUG(("TPM: RollbackFirmwareRead %x\n", (int)rsf.fw_versions));
373 return TPM_SUCCESS;
374 }
375
368 uint32_t RollbackFirmwareWrite(uint32_t version) { 376 uint32_t RollbackFirmwareWrite(uint32_t version) {
369 RollbackSpaceFirmware rsf; 377 RollbackSpaceFirmware rsf;
370 378
371 RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf)); 379 RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf));
372 VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)rsf.fw_versions, 380 VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)rsf.fw_versions,
373 (int)version)); 381 (int)version));
374 rsf.fw_versions = version; 382 rsf.fw_versions = version;
375 return WriteSpaceFirmware(&rsf); 383 return WriteSpaceFirmware(&rsf);
376 } 384 }
377 385
378 uint32_t RollbackFirmwareLock(void) { 386 uint32_t RollbackFirmwareLock(void) {
379 return TlclSetGlobalLock(); 387 return TlclSetGlobalLock();
380 } 388 }
381 389
382 uint32_t RollbackKernelRecovery(int developer_mode) { 390 uint32_t RollbackKernelRecovery(int developer_mode) {
383 uint32_t rvs, rve; 391 uint32_t rvs, rve;
384 RollbackSpaceFirmware rsf; 392 RollbackSpaceFirmware rsf;
385 uint8_t out_digest[20]; /* For PCR extend output */
386 393
387 /* In recovery mode we ignore TPM malfunctions or corruptions, and * 394 /* In recovery mode we ignore TPM malfunctions or corruptions, and *
388 * leave the TPM complelely unlocked; we call neither 395 * leave the TPM complelely unlocked; we call neither
389 * TlclSetGlobalLock() nor TlclLockPhysicalPresence(). The recovery 396 * TlclSetGlobalLock() nor TlclLockPhysicalPresence(). The recovery
390 * kernel will fix the TPM (if needed) and lock it ASAP. We leave 397 * kernel will fix the TPM (if needed) and lock it ASAP. We leave
391 * Physical Presence on in either case. */ 398 * Physical Presence on in either case. */
392 rvs = SetupTPM(1, developer_mode, &rsf); 399 rvs = SetupTPM(1, developer_mode, &rsf);
393 if (developer_mode) 400 rve = SetTPMBootModeState(developer_mode,
394 rve = TlclExtend(DEV_REC_MODE_PCR, DEV_ON_REC_ON_SHA1_DIGEST, out_digest); 401 1, /* Recovery Mode Status. */
395 else 402 0); /* In recovery mode, there is no RW firmware
396 rve = TlclExtend(DEV_REC_MODE_PCR, DEV_OFF_REC_ON_SHA1_DIGEST, out_digest); 403 * keyblock flag. */
397 VBDEBUG(("TPM: RollbackKernelRecovery dev mode PCR out_digest %02x %02x %02x "
398 "%02x\n", out_digest, out_digest+1, out_digest+2, out_digest+3));
399 return (TPM_SUCCESS == rvs) ? rve : rvs; 404 return (TPM_SUCCESS == rvs) ? rve : rvs;
400 } 405 }
401 406
402 uint32_t RollbackKernelRead(uint32_t* version) { 407 uint32_t RollbackKernelRead(uint32_t* version) {
403 if (g_rollback_recovery_mode) { 408 RollbackSpaceKernel rsk;
404 *version = 0; 409 uint32_t perms;
405 } else {
406 RollbackSpaceKernel rsk;
407 uint32_t perms;
408 410
409 /* Read the kernel space and verify its permissions. If the kernel 411 /* Read the kernel space and verify its permissions. If the kernel
410 * space has the wrong permission, or it doesn't contain the right 412 * space has the wrong permission, or it doesn't contain the right
411 * identifier, we give up. This will need to be fixed by the 413 * identifier, we give up. This will need to be fixed by the
412 * recovery kernel. We have to worry about this because at any time 414 * recovery kernel. We have to worry about this because at any time
413 * (even with PP turned off) the TPM owner can remove and redefine a 415 * (even with PP turned off) the TPM owner can remove and redefine a
414 * PP-protected space (but not write to it). */ 416 * PP-protected space (but not write to it). */
415 RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); 417 RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
416 RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms)); 418 RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms));
417 if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid) 419 if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid)
418 return TPM_E_CORRUPTED_STATE; 420 return TPM_E_CORRUPTED_STATE;
419 421
420 *version = rsk.kernel_versions; 422 *version = rsk.kernel_versions;
421 VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions)); 423 VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions));
422 }
423 return TPM_SUCCESS; 424 return TPM_SUCCESS;
424 } 425 }
425 426
426 uint32_t RollbackKernelWrite(uint32_t version) { 427 uint32_t RollbackKernelWrite(uint32_t version) {
427 if (g_rollback_recovery_mode) { 428 RollbackSpaceKernel rsk;
428 return TPM_SUCCESS; 429 RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
429 } else { 430 VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n", (int)rsk.kernel_versions,
430 RollbackSpaceKernel rsk; 431 (int)version));
431 RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); 432 rsk.kernel_versions = version;
432 VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n", (int)rsk.kernel_versions, 433 return WriteSpaceKernel(&rsk);
433 (int)version));
434 rsk.kernel_versions = version;
435 return WriteSpaceKernel(&rsk);
436 }
437 } 434 }
438 435
439 uint32_t RollbackKernelLock(void) { 436 uint32_t RollbackKernelLock(void) {
440 if (g_rollback_recovery_mode) { 437 if (g_rollback_recovery_mode) {
441 return TPM_SUCCESS; 438 return TPM_SUCCESS;
442 } else { 439 } else {
443 return TlclLockPhysicalPresence(); 440 return TlclLockPhysicalPresence();
444 } 441 }
445 } 442 }
446 443
447 #endif // DISABLE_ROLLBACK_TPM 444 #endif // DISABLE_ROLLBACK_TPM
OLDNEW
« no previous file with comments | « firmware/lib/include/tpm_bootmode.h ('k') | firmware/lib/tpm_bootmode.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698