| OLD | NEW |
| 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 } | 269 } |
| 288 | 270 |
| 289 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { | 271 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { |
| 290 #ifndef CHROMEOS_ENVIRONMENT | 272 #ifndef CHROMEOS_ENVIRONMENT |
| 291 /* Initializes the TPM, but ignores return codes. In ChromeOS | 273 /* Initializes the TPM, but ignores return codes. In ChromeOS |
| 292 * environment, doesn't even talk to the TPM. */ | 274 * environment, doesn't even talk to the TPM. */ |
| 293 TlclLibInit(); | 275 TlclLibInit(); |
| 294 TlclStartup(); | 276 TlclStartup(); |
| 295 TlclContinueSelfTest(); | 277 TlclContinueSelfTest(); |
| 296 #endif | 278 #endif |
| 297 | |
| 298 *version = 0; | 279 *version = 0; |
| 299 return TPM_SUCCESS; | 280 return TPM_SUCCESS; |
| 300 } | 281 } |
| 301 | 282 |
| 302 uint32_t RollbackFirmwareWrite(uint32_t version) { | 283 uint32_t RollbackFirmwareWrite(uint32_t version) { |
| 303 return TPM_SUCCESS; | 284 return TPM_SUCCESS; |
| 304 } | 285 } |
| 305 | 286 |
| 306 uint32_t RollbackFirmwareLock(void) { | 287 uint32_t RollbackFirmwareLock(void) { |
| 307 return TPM_SUCCESS; | 288 return TPM_SUCCESS; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 /* We're on a platform where the TPM maintains power in S3, so | 322 /* We're on a platform where the TPM maintains power in S3, so |
| 342 it's already initialized. */ | 323 it's already initialized. */ |
| 343 return TPM_SUCCESS; | 324 return TPM_SUCCESS; |
| 344 } | 325 } |
| 345 return result; | 326 return result; |
| 346 } | 327 } |
| 347 | 328 |
| 348 | 329 |
| 349 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { | 330 uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { |
| 350 RollbackSpaceFirmware rsf; | 331 RollbackSpaceFirmware rsf; |
| 351 uint8_t out_digest[20]; /* For PCR extend output */ | |
| 352 | 332 |
| 353 RETURN_ON_FAILURE(SetupTPM(0, developer_mode, &rsf)); | 333 RETURN_ON_FAILURE(SetupTPM(0, developer_mode, &rsf)); |
| 354 *version = rsf.fw_versions; | 334 *version = rsf.fw_versions; |
| 355 VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)rsf.fw_versions)); | 335 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; | 336 return TPM_SUCCESS; |
| 366 } | 337 } |
| 367 | 338 |
| 339 |
| 368 uint32_t RollbackFirmwareWrite(uint32_t version) { | 340 uint32_t RollbackFirmwareWrite(uint32_t version) { |
| 369 RollbackSpaceFirmware rsf; | 341 RollbackSpaceFirmware rsf; |
| 370 | 342 |
| 371 RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf)); | 343 RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf)); |
| 372 VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)rsf.fw_versions, | 344 VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)rsf.fw_versions, |
| 373 (int)version)); | 345 (int)version)); |
| 374 rsf.fw_versions = version; | 346 rsf.fw_versions = version; |
| 375 return WriteSpaceFirmware(&rsf); | 347 return WriteSpaceFirmware(&rsf); |
| 376 } | 348 } |
| 377 | 349 |
| 378 uint32_t RollbackFirmwareLock(void) { | 350 uint32_t RollbackFirmwareLock(void) { |
| 379 return TlclSetGlobalLock(); | 351 return TlclSetGlobalLock(); |
| 380 } | 352 } |
| 381 | 353 |
| 382 uint32_t RollbackKernelRecovery(int developer_mode) { | 354 uint32_t RollbackKernelRecovery(int developer_mode) { |
| 383 uint32_t rvs, rve; | 355 uint32_t rvs, rve; |
| 384 RollbackSpaceFirmware rsf; | 356 RollbackSpaceFirmware rsf; |
| 385 uint8_t out_digest[20]; /* For PCR extend output */ | 357 uint8_t out_digest[20]; /* For PCR extend output */ |
| 386 | 358 |
| 387 /* In recovery mode we ignore TPM malfunctions or corruptions, and * | 359 /* In recovery mode we ignore TPM malfunctions or corruptions, and * |
| 388 * leave the TPM complelely unlocked; we call neither | 360 * leave the TPM complelely unlocked; we call neither |
| 389 * TlclSetGlobalLock() nor TlclLockPhysicalPresence(). The recovery | 361 * TlclSetGlobalLock() nor TlclLockPhysicalPresence(). The recovery |
| 390 * kernel will fix the TPM (if needed) and lock it ASAP. We leave | 362 * kernel will fix the TPM (if needed) and lock it ASAP. We leave |
| 391 * Physical Presence on in either case. */ | 363 * Physical Presence on in either case. */ |
| 392 rvs = SetupTPM(1, developer_mode, &rsf); | 364 rvs = SetupTPM(1, developer_mode, &rsf); |
| 393 if (developer_mode) | 365 rve = SetTPMBootModeState(developer_mode, |
| 394 rve = TlclExtend(DEV_REC_MODE_PCR, DEV_ON_REC_ON_SHA1_DIGEST, out_digest); | 366 1, /* Recovery Mode Status. */ |
| 395 else | 367 0); /* In recovery mode, there is no RW firmware |
| 396 rve = TlclExtend(DEV_REC_MODE_PCR, DEV_OFF_REC_ON_SHA1_DIGEST, out_digest); | 368 * 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; | 369 return (TPM_SUCCESS == rvs) ? rve : rvs; |
| 400 } | 370 } |
| 401 | 371 |
| 402 uint32_t RollbackKernelRead(uint32_t* version) { | 372 uint32_t RollbackKernelRead(uint32_t* version) { |
| 403 if (g_rollback_recovery_mode) { | 373 if (g_rollback_recovery_mode) { |
| 404 *version = 0; | 374 *version = 0; |
| 405 } else { | 375 } else { |
| 406 RollbackSpaceKernel rsk; | 376 RollbackSpaceKernel rsk; |
| 407 uint32_t perms; | 377 uint32_t perms; |
| 408 | 378 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 438 | 408 |
| 439 uint32_t RollbackKernelLock(void) { | 409 uint32_t RollbackKernelLock(void) { |
| 440 if (g_rollback_recovery_mode) { | 410 if (g_rollback_recovery_mode) { |
| 441 return TPM_SUCCESS; | 411 return TPM_SUCCESS; |
| 442 } else { | 412 } else { |
| 443 return TlclLockPhysicalPresence(); | 413 return TlclLockPhysicalPresence(); |
| 444 } | 414 } |
| 445 } | 415 } |
| 446 | 416 |
| 447 #endif // DISABLE_ROLLBACK_TPM | 417 #endif // DISABLE_ROLLBACK_TPM |
| OLD | NEW |