| OLD | NEW |
| 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 12 matching lines...) Expand all Loading... |
| 23 VBDEBUG(("Rollback: %08x returned by " #tpm_command "\n", (int)result)); \ | 23 VBDEBUG(("Rollback: %08x returned by " #tpm_command "\n", (int)result)); \ |
| 24 return result; \ | 24 return result; \ |
| 25 } \ | 25 } \ |
| 26 } while (0) | 26 } while (0) |
| 27 | 27 |
| 28 uint32_t TPMClearAndReenable(void) { | 28 uint32_t TPMClearAndReenable(void) { |
| 29 VBDEBUG(("TPM: Clear and re-enable\n")); | 29 VBDEBUG(("TPM: Clear and re-enable\n")); |
| 30 RETURN_ON_FAILURE(TlclForceClear()); | 30 RETURN_ON_FAILURE(TlclForceClear()); |
| 31 RETURN_ON_FAILURE(TlclSetEnable()); | 31 RETURN_ON_FAILURE(TlclSetEnable()); |
| 32 RETURN_ON_FAILURE(TlclSetDeactivated(0)); | 32 RETURN_ON_FAILURE(TlclSetDeactivated(0)); |
| 33 | 33 |
| 34 return TPM_SUCCESS; | 34 return TPM_SUCCESS; |
| 35 } | 35 } |
| 36 | 36 |
| 37 /* Like TlclWrite(), but checks for write errors due to hitting the 64-write | 37 /* Like TlclWrite(), but checks for write errors due to hitting the 64-write |
| 38 * limit and clears the TPM when that happens. This can only happen when the | 38 * limit and clears the TPM when that happens. This can only happen when the |
| 39 * TPM is unowned, so it is OK to clear it (and we really have no choice). | 39 * TPM is unowned, so it is OK to clear it (and we really have no choice). |
| 40 * This is not expected to happen frequently, but it could happen. | 40 * This is not expected to happen frequently, but it could happen. |
| 41 */ | 41 */ |
| 42 static uint32_t SafeWrite(uint32_t index, uint8_t* data, uint32_t length) { | 42 static uint32_t SafeWrite(uint32_t index, uint8_t* data, uint32_t length) { |
| 43 uint32_t result = TlclWrite(index, data, length); | 43 uint32_t result = TlclWrite(index, data, length); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 } | 92 } |
| 93 return result; | 93 return result; |
| 94 } | 94 } |
| 95 | 95 |
| 96 /* Creates the NVRAM spaces, and sets their initial values as needed. | 96 /* Creates the NVRAM spaces, and sets their initial values as needed. |
| 97 */ | 97 */ |
| 98 static uint32_t InitializeSpaces(void) { | 98 static uint32_t InitializeSpaces(void) { |
| 99 uint32_t zero = 0; | 99 uint32_t zero = 0; |
| 100 uint32_t firmware_perm = TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE; | 100 uint32_t firmware_perm = TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE; |
| 101 uint8_t nvlocked = 0; | 101 uint8_t nvlocked = 0; |
| 102 uint32_t i; | |
| 103 | 102 |
| 104 VBDEBUG(("TPM: Initializing spaces\n")); | 103 VBDEBUG(("TPM: Initializing spaces\n")); |
| 105 | 104 |
| 106 #ifdef FORCE_CLEAR_ON_INIT | |
| 107 /* Force the TPM clear, in case it previously had an owner, so that we can | 105 /* Force the TPM clear, in case it previously had an owner, so that we can |
| 108 * redefine the NVRAM spaces. */ | 106 * redefine the NVRAM spaces. */ |
| 109 RETURN_ON_FAILURE(TPMClearAndReenable()); | 107 RETURN_ON_FAILURE(TPMClearAndReenable()); |
| 110 #endif | |
| 111 | 108 |
| 112 /* The TPM will not enforce the NV authorization restrictions until the | 109 /* The TPM will not enforce the NV authorization restrictions until the |
| 113 * execution of a TPM_NV_DefineSpace with the handle of TPM_NV_INDEX_LOCK. | 110 * execution of a TPM_NV_DefineSpace with the handle of TPM_NV_INDEX_LOCK. |
| 114 * Create that space if it doesn't already exist. */ | 111 * Create that space if it doesn't already exist. */ |
| 115 RETURN_ON_FAILURE(TlclGetFlags(NULL, NULL, &nvlocked)); | 112 RETURN_ON_FAILURE(TlclGetFlags(NULL, NULL, &nvlocked)); |
| 116 VBDEBUG(("TPM: nvlocked=%d\n", nvlocked)); | 113 VBDEBUG(("TPM: nvlocked=%d\n", nvlocked)); |
| 117 if (!nvlocked) { | 114 if (!nvlocked) { |
| 118 VBDEBUG(("TPM: Enabling NV locking\n")); | 115 VBDEBUG(("TPM: Enabling NV locking\n")); |
| 119 RETURN_ON_FAILURE(TlclSetNvLocked()); | 116 RETURN_ON_FAILURE(TlclSetNvLocked()); |
| 120 } | 117 } |
| 121 | 118 |
| 122 /* If the spaces were previously defined, we need to undefine them before we | |
| 123 * can redefine them. Undefine by setting size=0. Ignore these return codes, | |
| 124 * since they fail if the spaces aren't actually defined? */ | |
| 125 for (i = FIRST_ROLLBACK_NV_INDEX; i <= LAST_ROLLBACK_NV_INDEX; i++) | |
| 126 SafeDefineSpace(i, firmware_perm, 0); | |
| 127 | |
| 128 RETURN_ON_FAILURE(SafeDefineSpace(FIRMWARE_VERSIONS_NV_INDEX, | 119 RETURN_ON_FAILURE(SafeDefineSpace(FIRMWARE_VERSIONS_NV_INDEX, |
| 129 firmware_perm, sizeof(uint32_t))); | 120 firmware_perm, sizeof(uint32_t))); |
| 130 RETURN_ON_FAILURE(SafeWrite(FIRMWARE_VERSIONS_NV_INDEX, | 121 RETURN_ON_FAILURE(SafeWrite(FIRMWARE_VERSIONS_NV_INDEX, |
| 131 (uint8_t*) &zero, sizeof(uint32_t))); | 122 (uint8_t*) &zero, sizeof(uint32_t))); |
| 132 | 123 |
| 133 RETURN_ON_FAILURE(InitializeKernelVersionsSpaces()); | 124 RETURN_ON_FAILURE(InitializeKernelVersionsSpaces()); |
| 134 | 125 |
| 135 /* The space KERNEL_VERSIONS_BACKUP_NV_INDEX is used to protect the kernel | 126 /* The space KERNEL_VERSIONS_BACKUP_NV_INDEX is used to protect the kernel |
| 136 * versions. The content of space KERNEL_MUST_USE_BACKUP determines whether | 127 * versions. The content of space KERNEL_MUST_USE_BACKUP determines whether |
| 137 * only the backup value should be trusted. | 128 * only the backup value should be trusted. |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 VBDEBUG(("TPM: SetupTPM() succeeded\n")); | 322 VBDEBUG(("TPM: SetupTPM() succeeded\n")); |
| 332 return TPM_SUCCESS; | 323 return TPM_SUCCESS; |
| 333 } | 324 } |
| 334 | 325 |
| 335 /* disable MSVC warnings on unused arguments */ | 326 /* disable MSVC warnings on unused arguments */ |
| 336 __pragma(warning (disable: 4100)) | 327 __pragma(warning (disable: 4100)) |
| 337 | 328 |
| 338 | 329 |
| 339 #ifdef DISABLE_ROLLBACK_TPM | 330 #ifdef DISABLE_ROLLBACK_TPM |
| 340 | 331 |
| 341 /* Dummy implementations which don't call into the tpm_lite library */ | 332 /* Dummy implementations which don't support TPM rollback protection */ |
| 342 | 333 |
| 343 uint32_t RollbackFirmwareSetup(int developer_mode) { | 334 uint32_t RollbackFirmwareSetup(int developer_mode) { |
| 335 #ifndef CHROMEOS_ENVIRONMENT |
| 336 /* Initialize the TPM, but ignore return codes. In ChromeOS |
| 337 * environment, don't even talk to the TPM. */ |
| 338 TlclLibInit(); |
| 339 TlclStartup(); |
| 340 #endif |
| 344 return TPM_SUCCESS; | 341 return TPM_SUCCESS; |
| 345 } | 342 } |
| 346 | 343 |
| 347 uint32_t RollbackFirmwareRead(uint16_t* key_version, uint16_t* version) { | 344 uint32_t RollbackFirmwareRead(uint16_t* key_version, uint16_t* version) { |
| 348 *key_version = *version = 0; | 345 *key_version = *version = 0; |
| 349 return TPM_SUCCESS; | 346 return TPM_SUCCESS; |
| 350 } | 347 } |
| 351 | 348 |
| 352 uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version) { | 349 uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version) { |
| 353 return TPM_SUCCESS; | 350 return TPM_SUCCESS; |
| 354 } | 351 } |
| 355 | 352 |
| 356 uint32_t RollbackFirmwareLock(void) { | 353 uint32_t RollbackFirmwareLock(void) { |
| 357 return TPM_SUCCESS; | 354 return TPM_SUCCESS; |
| 358 } | 355 } |
| 359 | 356 |
| 360 uint32_t RollbackKernelRecovery(int developer_mode) { | 357 uint32_t RollbackKernelRecovery(int developer_mode) { |
| 358 #ifndef CHROMEOS_ENVIRONMENT |
| 359 /* Initialize the TPM, but ignore return codes. In ChromeOS |
| 360 * environment, don't even talk to the TPM. */ |
| 361 TlclLibInit(); |
| 362 TlclStartup(); |
| 363 #endif |
| 361 return TPM_SUCCESS; | 364 return TPM_SUCCESS; |
| 362 } | 365 } |
| 363 | 366 |
| 364 uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) { | 367 uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) { |
| 365 *key_version = *version = 0; | 368 *key_version = *version = 0; |
| 366 return TPM_SUCCESS; | 369 return TPM_SUCCESS; |
| 367 } | 370 } |
| 368 | 371 |
| 369 uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version) { | 372 uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version) { |
| 370 return TPM_SUCCESS; | 373 return TPM_SUCCESS; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 | 449 |
| 447 uint32_t RollbackKernelLock(void) { | 450 uint32_t RollbackKernelLock(void) { |
| 448 if (!g_rollback_recovery_mode) { | 451 if (!g_rollback_recovery_mode) { |
| 449 return TlclLockPhysicalPresence(); | 452 return TlclLockPhysicalPresence(); |
| 450 } else { | 453 } else { |
| 451 return TPM_SUCCESS; | 454 return TPM_SUCCESS; |
| 452 } | 455 } |
| 453 } | 456 } |
| 454 | 457 |
| 455 #endif // DISABLE_ROLLBACK_TPM | 458 #endif // DISABLE_ROLLBACK_TPM |
| OLD | NEW |