| 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 | 165 |
| 166 g_firmware_key_version = firmware_versions >> 16; | 166 g_firmware_key_version = firmware_versions >> 16; |
| 167 g_firmware_version = firmware_versions && 0xffff; | 167 g_firmware_version = firmware_versions && 0xffff; |
| 168 g_kernel_key_version = kernel_versions >> 16; | 168 g_kernel_key_version = kernel_versions >> 16; |
| 169 g_kernel_version = kernel_versions && 0xffff; | 169 g_kernel_version = kernel_versions && 0xffff; |
| 170 | 170 |
| 171 return 1; | 171 return 1; |
| 172 } | 172 } |
| 173 | 173 |
| 174 | 174 |
| 175 void SetupTPM(void) { | 175 int SetupTPM(void) { |
| 176 uint8_t disable; | 176 uint8_t disable; |
| 177 uint8_t deactivated; | 177 uint8_t deactivated; |
| 178 TlclLibinit(); | 178 TlclLibinit(); |
| 179 TlclStartup(); | 179 TlclStartup(); |
| 180 /* TODO(gauravsh): The call to self test should probably be deferred. | 180 /* TODO(gauravsh): The call to self test should probably be deferred. |
| 181 * As per semenzato@chromium.org - | 181 * As per semenzato@chromium.org - |
| 182 * TlclStartup should be called before the firmware initializes the memory | 182 * TlclStartup should be called before the firmware initializes the memory |
| 183 * controller, so the selftest can run in parallel with that. Here we should | 183 * controller, so the selftest can run in parallel with that. Here we should |
| 184 * just call TlclSelftestFull to make sure the self test has | 184 * just call TlclSelftestFull to make sure the self test has |
| 185 * completed---unless we want to rely on the NVRAM operations being available | 185 * completed---unless we want to rely on the NVRAM operations being available |
| 186 * before the selftest completes. */ | 186 * before the selftest completes. */ |
| 187 TlclSelftestfull(); | 187 TlclSelftestfull(); |
| 188 TlclAssertPhysicalPresence(); | 188 TlclAssertPhysicalPresence(); |
| 189 /* Check that the TPM is enabled and activated. */ | 189 /* Check that the TPM is enabled and activated. */ |
| 190 if(TlclGetFlags(&disable, &deactivated) != TPM_SUCCESS) { | 190 if(TlclGetFlags(&disable, &deactivated) != TPM_SUCCESS) { |
| 191 debug("failed to get TPM flags"); | 191 debug("failed to get TPM flags"); |
| 192 EnterRecovery(1); | 192 return 1; |
| 193 } | 193 } |
| 194 if (disable || deactivated) { | 194 if (disable || deactivated) { |
| 195 TlclSetEnable(); | 195 TlclSetEnable(); |
| 196 if (TlclSetDeactivated(0) != TPM_SUCCESS) { | 196 if (TlclSetDeactivated(0) != TPM_SUCCESS) { |
| 197 debug("failed to activate TPM"); | 197 debug("failed to activate TPM"); |
| 198 EnterRecovery(1); | 198 return 1; |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 /* We expect this to fail the first time we run on a device, indicating that | 201 /* We expect this to fail the first time we run on a device, indicating that |
| 202 * the TPM has not been initialized yet. */ | 202 * the TPM has not been initialized yet. */ |
| 203 if (!GetTPMRollbackIndices()) { | 203 if (!GetTPMRollbackIndices()) { |
| 204 debug("failed to get rollback indices"); | 204 debug("failed to get rollback indices"); |
| 205 if (!InitializeSpaces()) { | 205 if (!InitializeSpaces()) { |
| 206 /* If InitializeSpaces() fails (possibly because it had been executed | 206 /* If InitializeSpaces() fails (possibly because it had been executed |
| 207 * already), something is wrong. */ | 207 * already), something is wrong. */ |
| 208 EnterRecovery(1); | 208 return 1; |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 |
| 212 return 0; |
| 211 } | 213 } |
| 212 | 214 |
| 213 void GetStoredVersions(int type, uint16_t* key_version, uint16_t* version) { | 215 int GetStoredVersions(int type, uint16_t* key_version, uint16_t* version) { |
| 216 |
| 217 /* TODO: should verify that SetupTPM() has been called. Note that |
| 218 * SetupTPM() does hardware setup AND sets global variables. When we |
| 219 * get down into kernel verification, the hardware setup persists, but |
| 220 * we don't have access to the global variables. So I guess we DO need |
| 221 * to call SetupTPM() there, and have it be smart enough not to redo the |
| 222 * hardware init, but it still needs to re-read the flags... */ |
| 223 |
| 214 switch (type) { | 224 switch (type) { |
| 215 case FIRMWARE_VERSIONS: | 225 case FIRMWARE_VERSIONS: |
| 216 *key_version = g_firmware_key_version; | 226 *key_version = g_firmware_key_version; |
| 217 *version = g_firmware_version; | 227 *version = g_firmware_version; |
| 218 break; | 228 break; |
| 219 case KERNEL_VERSIONS: | 229 case KERNEL_VERSIONS: |
| 220 *key_version = g_kernel_key_version; | 230 *key_version = g_kernel_key_version; |
| 221 *version = g_kernel_version; | 231 *version = g_kernel_version; |
| 222 break; | 232 break; |
| 223 } | 233 } |
| 234 |
| 235 return 0; |
| 224 } | 236 } |
| 225 | 237 |
| 226 int WriteStoredVersions(int type, uint16_t key_version, uint16_t version) { | 238 int WriteStoredVersions(int type, uint16_t key_version, uint16_t version) { |
| 227 uint32_t combined_version = (key_version << 16) & version; | 239 uint32_t combined_version = (key_version << 16) & version; |
| 228 switch (type) { | 240 switch (type) { |
| 229 case FIRMWARE_VERSIONS: | 241 case FIRMWARE_VERSIONS: |
| 230 return (TPM_SUCCESS == TlclWrite(FIRMWARE_VERSIONS_NV_INDEX, | 242 return (TPM_SUCCESS != TlclWrite(FIRMWARE_VERSIONS_NV_INDEX, |
| 231 (uint8_t*) &combined_version, | 243 (uint8_t*) &combined_version, |
| 232 sizeof(uint32_t))); | 244 sizeof(uint32_t))); |
| 233 break; | 245 |
| 234 case KERNEL_VERSIONS: | 246 case KERNEL_VERSIONS: |
| 235 return (TPM_SUCCESS == TlclWrite(KERNEL_VERSIONS_NV_INDEX, | 247 return (TPM_SUCCESS != TlclWrite(KERNEL_VERSIONS_NV_INDEX, |
| 236 (uint8_t*) &combined_version, | 248 (uint8_t*) &combined_version, |
| 237 sizeof(uint32_t))); | 249 sizeof(uint32_t))); |
| 238 break; | |
| 239 } | 250 } |
| 240 /* TODO(nelson): ForceClear and reboot if unowned. */ | 251 /* TODO(nelson): ForceClear and reboot if unowned. */ |
| 241 | 252 |
| 253 return 1; |
| 254 } |
| 255 |
| 256 int LockFirmwareVersions() { |
| 257 if (TlclSetGlobalLock() != TPM_SUCCESS) { |
| 258 debug("failed to set global lock"); |
| 259 return 1; |
| 260 } |
| 242 return 0; | 261 return 0; |
| 243 } | 262 } |
| 244 | 263 |
| 245 void LockFirmwareVersions() { | 264 int LockKernelVersionsByLockingPP() { |
| 246 if (TlclSetGlobalLock() != TPM_SUCCESS) { | |
| 247 debug("failed to set global lock"); | |
| 248 EnterRecovery(1); | |
| 249 } | |
| 250 } | |
| 251 | |
| 252 void LockKernelVersionsByLockingPP() { | |
| 253 if (TlclLockPhysicalPresence() != TPM_SUCCESS) { | 265 if (TlclLockPhysicalPresence() != TPM_SUCCESS) { |
| 254 debug("failed to turn off PP"); | 266 debug("failed to turn off PP"); |
| 255 EnterRecovery(1); | 267 return 1; |
| 256 } | 268 } |
| 269 return 0; |
| 257 } | 270 } |
| OLD | NEW |