| 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 16 matching lines...) Expand all Loading... |
| 27 } while (0) | 27 } while (0) |
| 28 | 28 |
| 29 static uint32_t InitializeKernelVersionsSpaces(void) { | 29 static uint32_t InitializeKernelVersionsSpaces(void) { |
| 30 RETURN_ON_FAILURE(TlclDefineSpace(KERNEL_VERSIONS_NV_INDEX, | 30 RETURN_ON_FAILURE(TlclDefineSpace(KERNEL_VERSIONS_NV_INDEX, |
| 31 TPM_NV_PER_PPWRITE, KERNEL_SPACE_SIZE)); | 31 TPM_NV_PER_PPWRITE, KERNEL_SPACE_SIZE)); |
| 32 RETURN_ON_FAILURE(TlclWrite(KERNEL_VERSIONS_NV_INDEX, KERNEL_SPACE_INIT_DATA, | 32 RETURN_ON_FAILURE(TlclWrite(KERNEL_VERSIONS_NV_INDEX, KERNEL_SPACE_INIT_DATA, |
| 33 KERNEL_SPACE_SIZE)); | 33 KERNEL_SPACE_SIZE)); |
| 34 return TPM_SUCCESS; | 34 return TPM_SUCCESS; |
| 35 } | 35 } |
| 36 | 36 |
| 37 /* When the return value is TPM_SUCCESS, this function sets *|initialized| to 1 |
| 38 * if the spaces have been fully initialized, to 0 if not. Otherwise |
| 39 * *|initialized| is not changed. |
| 40 */ |
| 37 static uint32_t GetSpacesInitialized(int* initialized) { | 41 static uint32_t GetSpacesInitialized(int* initialized) { |
| 38 uint32_t space_holder; | 42 uint32_t space_holder; |
| 39 uint32_t result; | 43 uint32_t result; |
| 40 result = TlclRead(TPM_IS_INITIALIZED_NV_INDEX, | 44 result = TlclRead(TPM_IS_INITIALIZED_NV_INDEX, |
| 41 (uint8_t*) &space_holder, sizeof(space_holder)); | 45 (uint8_t*) &space_holder, sizeof(space_holder)); |
| 42 switch (result) { | 46 switch (result) { |
| 43 case TPM_SUCCESS: | 47 case TPM_SUCCESS: |
| 44 *initialized = 1; | 48 *initialized = 1; |
| 45 break; | 49 break; |
| 46 case TPM_E_BADINDEX: | 50 case TPM_E_BADINDEX: |
| 47 *initialized = 0; | 51 *initialized = 0; |
| 48 result = TPM_SUCCESS; | 52 result = TPM_SUCCESS; |
| 49 break; | 53 break; |
| 50 } | 54 } |
| 51 return result; | 55 return result; |
| 52 } | 56 } |
| 53 | 57 |
| 58 /* Creates the NVRAM spaces, and sets their initial values as needed. |
| 59 */ |
| 54 static uint32_t InitializeSpaces(void) { | 60 static uint32_t InitializeSpaces(void) { |
| 55 uint32_t zero = 0; | 61 uint32_t zero = 0; |
| 56 uint32_t firmware_perm = TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE; | 62 uint32_t firmware_perm = TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE; |
| 57 | 63 |
| 58 debug("Initializing spaces\n"); | 64 debug("Initializing spaces\n"); |
| 59 | 65 |
| 60 RETURN_ON_FAILURE(TlclSetNvLocked()); | 66 RETURN_ON_FAILURE(TlclSetNvLocked()); |
| 61 | 67 |
| 62 RETURN_ON_FAILURE(TlclDefineSpace(FIRMWARE_VERSIONS_NV_INDEX, | 68 RETURN_ON_FAILURE(TlclDefineSpace(FIRMWARE_VERSIONS_NV_INDEX, |
| 63 firmware_perm, sizeof(uint32_t))); | 69 firmware_perm, sizeof(uint32_t))); |
| 64 RETURN_ON_FAILURE(TlclWrite(FIRMWARE_VERSIONS_NV_INDEX, | 70 RETURN_ON_FAILURE(TlclWrite(FIRMWARE_VERSIONS_NV_INDEX, |
| 65 (uint8_t*) &zero, sizeof(uint32_t))); | 71 (uint8_t*) &zero, sizeof(uint32_t))); |
| 66 | 72 |
| 67 RETURN_ON_FAILURE(InitializeKernelVersionsSpaces()); | 73 RETURN_ON_FAILURE(InitializeKernelVersionsSpaces()); |
| 68 | 74 |
| 69 /* The space KERNEL_VERSIONS_BACKUP_NV_INDEX is used to protect the kernel | 75 /* The space KERNEL_VERSIONS_BACKUP_NV_INDEX is used to protect the kernel |
| 70 * versions when entering recovery mode. The content of space | 76 * versions. The content of space KERNEL_MUST_USE_BACKUP determines whether |
| 71 * KERNEL_MUST_USE_BACKUP determines whether the backup value (1) or the | 77 * only the backup value should be trusted. |
| 72 * regular value (0) should be trusted. | |
| 73 */ | 78 */ |
| 74 RETURN_ON_FAILURE(TlclDefineSpace(KERNEL_VERSIONS_BACKUP_NV_INDEX, | 79 RETURN_ON_FAILURE(TlclDefineSpace(KERNEL_VERSIONS_BACKUP_NV_INDEX, |
| 75 firmware_perm, sizeof(uint32_t))); | 80 firmware_perm, sizeof(uint32_t))); |
| 76 RETURN_ON_FAILURE(TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, | 81 RETURN_ON_FAILURE(TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, |
| 77 (uint8_t*) &zero, sizeof(uint32_t))); | 82 (uint8_t*) &zero, sizeof(uint32_t))); |
| 78 RETURN_ON_FAILURE(TlclDefineSpace(KERNEL_MUST_USE_BACKUP_NV_INDEX, | 83 RETURN_ON_FAILURE(TlclDefineSpace(KERNEL_MUST_USE_BACKUP_NV_INDEX, |
| 79 firmware_perm, sizeof(uint32_t))); | 84 firmware_perm, sizeof(uint32_t))); |
| 80 RETURN_ON_FAILURE(TlclWrite(KERNEL_MUST_USE_BACKUP_NV_INDEX, | 85 RETURN_ON_FAILURE(TlclWrite(KERNEL_MUST_USE_BACKUP_NV_INDEX, |
| 81 (uint8_t*) &zero, sizeof(uint32_t))); | 86 (uint8_t*) &zero, sizeof(uint32_t))); |
| 87 RETURN_ON_FAILURE(TlclDefineSpace(DEVELOPER_MODE_NV_INDEX, |
| 88 firmware_perm, sizeof(uint32_t))); |
| 89 RETURN_ON_FAILURE(TlclWrite(DEVELOPER_MODE_NV_INDEX, |
| 90 (uint8_t*) &zero, sizeof(uint32_t))); |
| 82 | 91 |
| 83 /* The space TPM_IS_INITIALIZED_NV_INDEX is used to indicate that the TPM | 92 /* The space TPM_IS_INITIALIZED_NV_INDEX is used to indicate that the TPM |
| 84 * initialization has completed. Without it we cannot be sure that the last | 93 * initialization has completed. Without it we cannot be sure that the last |
| 85 * space to be created was also initialized (power could have been lost right | 94 * space to be created was also initialized (power could have been lost right |
| 86 * after its creation). | 95 * after its creation). |
| 87 */ | 96 */ |
| 88 RETURN_ON_FAILURE(TlclDefineSpace(TPM_IS_INITIALIZED_NV_INDEX, | 97 RETURN_ON_FAILURE(TlclDefineSpace(TPM_IS_INITIALIZED_NV_INDEX, |
| 89 firmware_perm, sizeof(uint32_t))); | 98 firmware_perm, sizeof(uint32_t))); |
| 90 return TPM_SUCCESS; | 99 return TPM_SUCCESS; |
| 91 } | 100 } |
| 92 | 101 |
| 93 /* Enters the recovery mode. If |unlocked| is true, there is some problem with | 102 static uint32_t SetDistrustKernelSpaceAtNextBoot(uint32_t distrust) { |
| 94 * the TPM, so do not attempt to do any more TPM operations, and particularly | |
| 95 * do not set bGlobalLock. | |
| 96 */ | |
| 97 void EnterRecovery(int unlocked) { | |
| 98 uint32_t combined_versions; | |
| 99 uint32_t backup_versions; | |
| 100 uint32_t must_use_backup; | 103 uint32_t must_use_backup; |
| 101 uint32_t result; | 104 RETURN_ON_FAILURE(TlclRead(KERNEL_MUST_USE_BACKUP_NV_INDEX, |
| 102 | 105 (uint8_t*) &must_use_backup, sizeof(uint32_t))); |
| 103 if (!unlocked) { | 106 if (must_use_backup != distrust) { |
| 104 /* Saves the kernel versions and indicates that we should trust the saved | 107 RETURN_ON_FAILURE(TlclWrite(KERNEL_MUST_USE_BACKUP_NV_INDEX, |
| 105 * ones. | 108 (uint8_t*) &distrust, sizeof(uint32_t))); |
| 106 */ | |
| 107 if (TlclRead(KERNEL_VERSIONS_NV_INDEX, (uint8_t*) &combined_versions, | |
| 108 sizeof(uint32_t)) != TPM_SUCCESS) | |
| 109 goto recovery_mode; | |
| 110 if (TlclRead(KERNEL_VERSIONS_BACKUP_NV_INDEX, (uint8_t*) &backup_versions, | |
| 111 sizeof(uint32_t)) != TPM_SUCCESS) | |
| 112 goto recovery_mode; | |
| 113 /* Avoids idempotent writes. */ | |
| 114 if (combined_versions != backup_versions) { | |
| 115 result = TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, | |
| 116 (uint8_t*) &combined_versions, sizeof(uint32_t)); | |
| 117 if (result == TPM_E_MAXNVWRITES) { | |
| 118 goto forceclear_and_reboot; | |
| 119 } else if (result != TPM_SUCCESS) { | |
| 120 goto recovery_mode; | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 if (TlclRead(KERNEL_MUST_USE_BACKUP_NV_INDEX, (uint8_t*) &must_use_backup, | |
| 125 sizeof(uint32_t)) != TPM_SUCCESS) | |
| 126 goto recovery_mode; | |
| 127 if (must_use_backup != 1) { | |
| 128 must_use_backup = 1; | |
| 129 result = TlclWrite(KERNEL_MUST_USE_BACKUP_NV_INDEX, | |
| 130 (uint8_t*) &must_use_backup, sizeof(uint32_t)); | |
| 131 if (result == TPM_E_MAXNVWRITES) { | |
| 132 goto forceclear_and_reboot; | |
| 133 } else if (result != TPM_SUCCESS) { | |
| 134 goto recovery_mode; | |
| 135 } | |
| 136 } | |
| 137 /* Protects the firmware and backup kernel versions. */ | |
| 138 if (LockFirmwareVersions() != TPM_SUCCESS) | |
| 139 goto recovery_mode; | |
| 140 } | 109 } |
| 141 | 110 return TPM_SUCCESS; |
| 142 recovery_mode: | |
| 143 debug("entering recovery mode"); | |
| 144 | |
| 145 /* TODO(nelson): code for entering recovery mode. */ | |
| 146 | |
| 147 forceclear_and_reboot: | |
| 148 if (TlclForceClear() != TPM_SUCCESS) { | |
| 149 goto recovery_mode; | |
| 150 } | |
| 151 /* TODO: reboot */ | |
| 152 } | 111 } |
| 153 | 112 |
| 154 static uint32_t GetTPMRollbackIndices(void) { | 113 static uint32_t GetTPMRollbackIndices(int type) { |
| 155 uint32_t firmware_versions; | 114 uint32_t firmware_versions; |
| 156 uint32_t kernel_versions; | 115 uint32_t kernel_versions; |
| 157 | 116 |
| 158 /* We perform the reads, making sure they succeed. A failure means that the | 117 /* We perform the reads, making sure they succeed. A failure means that the |
| 159 * rollback index locations are missing or somehow messed up. We let the | 118 * rollback index locations are missing or somehow messed up. We let the |
| 160 * caller deal with that. | 119 * caller deal with that. |
| 161 */ | 120 */ |
| 162 RETURN_ON_FAILURE(TlclRead(FIRMWARE_VERSIONS_NV_INDEX, | 121 switch (type) { |
| 163 (uint8_t*) &firmware_versions, | 122 case FIRMWARE_VERSIONS: |
| 164 sizeof(firmware_versions))); | 123 RETURN_ON_FAILURE(TlclRead(FIRMWARE_VERSIONS_NV_INDEX, |
| 165 RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX, | 124 (uint8_t*) &firmware_versions, |
| 166 (uint8_t*) &kernel_versions, | 125 sizeof(firmware_versions))); |
| 167 sizeof(kernel_versions))); | 126 g_firmware_key_version = firmware_versions >> 16; |
| 168 | 127 g_firmware_version = firmware_versions && 0xffff; |
| 169 g_firmware_key_version = firmware_versions >> 16; | 128 break; |
| 170 g_firmware_version = firmware_versions && 0xffff; | 129 case KERNEL_VERSIONS: |
| 171 g_kernel_key_version = kernel_versions >> 16; | 130 RETURN_ON_FAILURE(TlclRead(KERNEL_VERSIONS_NV_INDEX, |
| 172 g_kernel_version = kernel_versions && 0xffff; | 131 (uint8_t*) &kernel_versions, |
| 132 sizeof(kernel_versions))); |
| 133 g_kernel_key_version = kernel_versions >> 16; |
| 134 g_kernel_version = kernel_versions && 0xffff; |
| 135 break; |
| 136 } |
| 173 | 137 |
| 174 return TPM_SUCCESS; | 138 return TPM_SUCCESS; |
| 175 } | 139 } |
| 176 | 140 |
| 177 /* Checks if the kernel version space has been mucked with. If it has, | 141 /* Checks if the kernel version space has been mucked with. If it has, |
| 178 * reconstructs it using the backup value. | 142 * reconstructs it using the backup value. |
| 179 */ | 143 */ |
| 180 uint32_t RecoverKernelSpace(void) { | 144 uint32_t RecoverKernelSpace(void) { |
| 181 uint32_t perms = 0; | 145 uint32_t perms = 0; |
| 182 uint8_t buffer[KERNEL_SPACE_SIZE]; | 146 uint8_t buffer[KERNEL_SPACE_SIZE]; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 return TPM_SUCCESS; | 198 return TPM_SUCCESS; |
| 235 } else if (kernel_versions < backup_versions) { | 199 } else if (kernel_versions < backup_versions) { |
| 236 /* This cannot happen. We're screwed. */ | 200 /* This cannot happen. We're screwed. */ |
| 237 return TPM_E_INTERNAL_INCONSISTENCY; | 201 return TPM_E_INTERNAL_INCONSISTENCY; |
| 238 } | 202 } |
| 239 RETURN_ON_FAILURE(TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, | 203 RETURN_ON_FAILURE(TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, |
| 240 (uint8_t*) &kernel_versions, sizeof(uint32_t))); | 204 (uint8_t*) &kernel_versions, sizeof(uint32_t))); |
| 241 return TPM_SUCCESS; | 205 return TPM_SUCCESS; |
| 242 } | 206 } |
| 243 | 207 |
| 244 static uint32_t SetupTPM_(void) { | 208 /* Checks for transitions between protected mode to developer mode. When going |
| 209 * into developer mode, clear the TPM. |
| 210 */ |
| 211 static uint32_t CheckDeveloperModeTransition(uint32_t current_developer) { |
| 212 uint32_t past_developer; |
| 213 int must_clear; |
| 214 RETURN_ON_FAILURE(TlclRead(DEVELOPER_MODE_NV_INDEX, |
| 215 (uint8_t*) &past_developer, |
| 216 sizeof(past_developer))); |
| 217 must_clear = current_developer && !past_developer; |
| 218 if (must_clear) { |
| 219 RETURN_ON_FAILURE(TlclForceClear()); |
| 220 } |
| 221 if (past_developer != current_developer) { |
| 222 /* (Unauthorized) writes to the TPM succeed even when the TPM is disabled |
| 223 * and deactivated. |
| 224 */ |
| 225 RETURN_ON_FAILURE(TlclWrite(DEVELOPER_MODE_NV_INDEX, |
| 226 (uint8_t*) ¤t_developer, |
| 227 sizeof(current_developer))); |
| 228 } |
| 229 return must_clear ? TPM_E_MUST_REBOOT : TPM_SUCCESS; |
| 230 } |
| 231 |
| 232 static uint32_t SetupTPM_(int mode, int developer_flag) { |
| 245 uint8_t disable; | 233 uint8_t disable; |
| 246 uint8_t deactivated; | 234 uint8_t deactivated; |
| 247 TlclLibInit(); | 235 TlclLibInit(); |
| 248 RETURN_ON_FAILURE(TlclStartup()); | 236 RETURN_ON_FAILURE(TlclStartup()); |
| 249 RETURN_ON_FAILURE(TlclContinueSelfTest()); | 237 RETURN_ON_FAILURE(TlclContinueSelfTest()); |
| 250 RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); | 238 RETURN_ON_FAILURE(TlclAssertPhysicalPresence()); |
| 251 /* Checks that the TPM is enabled and activated. */ | 239 /* Checks that the TPM is enabled and activated. */ |
| 252 RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated)); | 240 RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated)); |
| 253 if (disable || deactivated) { | 241 if (disable || deactivated) { |
| 254 RETURN_ON_FAILURE(TlclSetEnable()); | 242 RETURN_ON_FAILURE(TlclSetEnable()); |
| 255 RETURN_ON_FAILURE(TlclSetDeactivated(0)); | 243 RETURN_ON_FAILURE(TlclSetDeactivated(0)); |
| 256 /* TODO: Reboot */ | 244 return TPM_E_MUST_REBOOT; |
| 257 return 9999; | |
| 258 } | 245 } |
| 259 /* We expect this to fail the first time we run on a device, indicating that | 246 /* We expect this to fail the first time we run on a device, because the TPM |
| 260 * the TPM has not been initialized yet. */ | 247 * has not been initialized yet. |
| 248 */ |
| 261 if (RecoverKernelSpace() != TPM_SUCCESS) { | 249 if (RecoverKernelSpace() != TPM_SUCCESS) { |
| 262 int initialized = 0; | 250 int initialized = 0; |
| 263 RETURN_ON_FAILURE(GetSpacesInitialized(&initialized)); | 251 RETURN_ON_FAILURE(GetSpacesInitialized(&initialized)); |
| 264 if (initialized) { | 252 if (initialized) { |
| 265 return TPM_E_ALREADY_INITIALIZED; | 253 return TPM_E_ALREADY_INITIALIZED; |
| 266 } else { | 254 } else { |
| 267 RETURN_ON_FAILURE(InitializeSpaces()); | 255 RETURN_ON_FAILURE(InitializeSpaces()); |
| 268 RETURN_ON_FAILURE(RecoverKernelSpace()); | 256 RETURN_ON_FAILURE(RecoverKernelSpace()); |
| 269 } | 257 } |
| 270 } | 258 } |
| 271 RETURN_ON_FAILURE(BackupKernelSpace()); | 259 RETURN_ON_FAILURE(BackupKernelSpace()); |
| 272 RETURN_ON_FAILURE(GetTPMRollbackIndices()); | 260 RETURN_ON_FAILURE(SetDistrustKernelSpaceAtNextBoot(mode == RO_RECOVERY_MODE)); |
| 261 RETURN_ON_FAILURE(GetTPMRollbackIndices(FIRMWARE_VERSIONS)); |
| 262 RETURN_ON_FAILURE(GetTPMRollbackIndices(KERNEL_VERSIONS)); |
| 273 | 263 |
| 264 RETURN_ON_FAILURE(CheckDeveloperModeTransition(developer_flag)); |
| 265 |
| 266 /* As a courtesy (I hope) to the caller, lock the firmware versions if we are |
| 267 * in recovery mode. The normal mode may need to update the firmware |
| 268 * versions, so they cannot be locked here. |
| 269 */ |
| 270 if (mode == RO_RECOVERY_MODE) { |
| 271 RETURN_ON_FAILURE(LockFirmwareVersions()); |
| 272 } |
| 274 return TPM_SUCCESS; | 273 return TPM_SUCCESS; |
| 275 } | 274 } |
| 276 | 275 |
| 277 uint32_t SetupTPM(void) { | 276 /* SetupTPM starts the TPM and establishes the root of trust for the |
| 278 uint32_t result = SetupTPM_(); | 277 * anti-rollback mechanism. SetupTPM can fail for three reasons. 1 A bug. 2 a |
| 279 if (result == TPM_E_MAXNVWRITES) { | 278 * TPM hardware failure. 3 An unexpected TPM state due to some attack. In |
| 280 /* ForceClears and reboots */ | 279 * general we cannot easily distinguish the kind of failure, so our strategy is |
| 281 RETURN_ON_FAILURE(TlclForceClear()); | 280 * to reboot in recovery mode in all cases. The recovery mode calls SetupTPM |
| 282 /* TODO: reboot */ | 281 * again, which executes (almost) the same sequence of operations. There is a |
| 283 return 9999; | 282 * good chance that, if recovery mode was entered because of a TPM failure, the |
| 284 } else { | 283 * failure will repeat itself. (In general this is impossible to guarantee |
| 285 return result; | 284 * because we have no way of creating the exact TPM initial state at the |
| 285 * previous boot.) In recovery mode, we ignore the failure and continue, thus |
| 286 * giving the recovery kernel a chance to fix things (that's why we don't set |
| 287 * bGlobalLock). The choice is between a knowingly insecure device and a |
| 288 * bricked device. |
| 289 * |
| 290 * As a side note, observe that we go through considerable hoops to avoid using |
| 291 * the STCLEAR permissions for the index spaces. We do this to avoid writing |
| 292 * to the TPM flashram at every reboot or wake-up, because of concerns about |
| 293 * the durability of the NVRAM. |
| 294 */ |
| 295 uint32_t SetupTPM(int mode, int developer_flag) { |
| 296 switch (mode) { |
| 297 case RO_RECOVERY_MODE: |
| 298 case RO_NORMAL_MODE: { |
| 299 uint32_t result = SetupTPM_(mode, developer_flag); |
| 300 if (result == TPM_E_MAXNVWRITES) { |
| 301 /* ForceClears and reboots */ |
| 302 RETURN_ON_FAILURE(TlclForceClear()); |
| 303 return TPM_E_MUST_REBOOT; |
| 304 } else if (mode == RO_NORMAL_MODE) { |
| 305 return result; |
| 306 } else { |
| 307 /* In recovery mode we want to keep going even if there are errors. */ |
| 308 return TPM_SUCCESS; |
| 309 } |
| 310 } |
| 311 case RW_NORMAL_MODE: |
| 312 /* There are no TPM writes here, so no need to check for write limit errors. |
| 313 */ |
| 314 RETURN_ON_FAILURE(GetTPMRollbackIndices(KERNEL_VERSIONS)); |
| 315 default: |
| 316 return TPM_E_INTERNAL_INCONSISTENCY; |
| 286 } | 317 } |
| 287 } | 318 } |
| 288 | 319 |
| 289 uint32_t GetStoredVersions(int type, uint16_t* key_version, uint16_t* version) { | 320 uint32_t GetStoredVersions(int type, uint16_t* key_version, uint16_t* version) { |
| 290 | 321 /* TODO: should verify that SetupTPM() has been called. |
| 291 /* TODO: should verify that SetupTPM() has been called. Note that | 322 * |
| 292 * SetupTPM() does hardware setup AND sets global variables. When we | 323 * Note that SetupTPM() does hardware setup AND sets global variables. When |
| 293 * get down into kernel verification, the hardware setup persists, but | 324 * we get down into kernel verification, the hardware setup persists, but we |
| 294 * we don't have access to the global variables. So I guess we DO need | 325 * lose the global variables. |
| 295 * to call SetupTPM() there, and have it be smart enough not to redo the | 326 */ |
| 296 * hardware init, but it still needs to re-read the flags... */ | |
| 297 | |
| 298 switch (type) { | 327 switch (type) { |
| 299 case FIRMWARE_VERSIONS: | 328 case FIRMWARE_VERSIONS: |
| 300 *key_version = g_firmware_key_version; | 329 *key_version = g_firmware_key_version; |
| 301 *version = g_firmware_version; | 330 *version = g_firmware_version; |
| 302 break; | 331 break; |
| 303 case KERNEL_VERSIONS: | 332 case KERNEL_VERSIONS: |
| 304 *key_version = g_kernel_key_version; | 333 *key_version = g_kernel_key_version; |
| 305 *version = g_kernel_version; | 334 *version = g_kernel_version; |
| 306 break; | 335 break; |
| 307 } | 336 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 326 return TPM_SUCCESS; | 355 return TPM_SUCCESS; |
| 327 } | 356 } |
| 328 | 357 |
| 329 uint32_t LockFirmwareVersions() { | 358 uint32_t LockFirmwareVersions() { |
| 330 return TlclSetGlobalLock(); | 359 return TlclSetGlobalLock(); |
| 331 } | 360 } |
| 332 | 361 |
| 333 uint32_t LockKernelVersionsByLockingPP() { | 362 uint32_t LockKernelVersionsByLockingPP() { |
| 334 return TlclLockPhysicalPresence(); | 363 return TlclLockPhysicalPresence(); |
| 335 } | 364 } |
| OLD | NEW |