| 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  * High-level firmware API for loading and verifying rewritable firmware. | 5  * High-level firmware API for loading and verifying rewritable firmware. | 
| 6  * (Firmware portion) | 6  * (Firmware portion) | 
| 7  */ | 7  */ | 
| 8 | 8 | 
| 9 #include "load_firmware_fw.h" | 9 #include "load_firmware_fw.h" | 
| 10 #include "rollback_index.h" | 10 #include "rollback_index.h" | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 33 | 33 | 
| 34 int LoadFirmware(LoadFirmwareParams* params) { | 34 int LoadFirmware(LoadFirmwareParams* params) { | 
| 35 | 35 | 
| 36   VbPublicKey* root_key = (VbPublicKey*)params->firmware_root_key_blob; | 36   VbPublicKey* root_key = (VbPublicKey*)params->firmware_root_key_blob; | 
| 37   VbLoadFirmwareInternal* lfi; | 37   VbLoadFirmwareInternal* lfi; | 
| 38 | 38 | 
| 39   uint16_t tpm_key_version = 0; | 39   uint16_t tpm_key_version = 0; | 
| 40   uint16_t tpm_fw_version = 0; | 40   uint16_t tpm_fw_version = 0; | 
| 41   uint64_t lowest_key_version = 0xFFFF; | 41   uint64_t lowest_key_version = 0xFFFF; | 
| 42   uint64_t lowest_fw_version = 0xFFFF; | 42   uint64_t lowest_fw_version = 0xFFFF; | 
|  | 43   uint32_t status; | 
| 43   int good_index = -1; | 44   int good_index = -1; | 
| 44   int index; | 45   int index; | 
| 45 | 46 | 
| 46   /* Clear output params in case we fail */ | 47   /* Clear output params in case we fail */ | 
| 47   params->firmware_index = 0; | 48   params->firmware_index = 0; | 
| 48 | 49 | 
| 49   VBDEBUG(("LoadFirmware started...\n")); | 50   VBDEBUG(("LoadFirmware started...\n")); | 
| 50 | 51 | 
| 51   if (params->kernel_sign_key_size < sizeof(VbPublicKey)) { | 52   if (params->kernel_sign_key_size < sizeof(VbPublicKey)) { | 
| 52     VBDEBUG(("Kernel sign key buffer too small\n")); | 53     VBDEBUG(("Kernel sign key buffer too small\n")); | 
| 53     return LOAD_FIRMWARE_RECOVERY; | 54     return LOAD_FIRMWARE_RECOVERY; | 
| 54   } | 55   } | 
| 55 | 56 | 
| 56   /* Must have a root key */ | 57   /* Must have a root key */ | 
| 57   if (!root_key) { | 58   if (!root_key) { | 
| 58     VBDEBUG(("No root key\n")); | 59     VBDEBUG(("No root key\n")); | 
| 59     return LOAD_FIRMWARE_RECOVERY; | 60     return LOAD_FIRMWARE_RECOVERY; | 
| 60   } | 61   } | 
| 61 | 62 | 
| 62   /* Initialize the TPM and read rollback indices. */ | 63   /* Initialize the TPM and read rollback indices. */ | 
| 63   if (0 != RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER)) { | 64   status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER); | 
|  | 65   if (0 != status) { | 
| 64     VBDEBUG(("Unable to setup TPM.\n")); | 66     VBDEBUG(("Unable to setup TPM.\n")); | 
| 65     return LOAD_FIRMWARE_RECOVERY; | 67     return (status == TPM_E_MUST_REBOOT ? | 
|  | 68             LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); | 
| 66   } | 69   } | 
| 67   if (0 != RollbackFirmwareRead(&tpm_key_version, &tpm_fw_version)) { | 70   status = RollbackFirmwareRead(&tpm_key_version, &tpm_fw_version); | 
|  | 71   if (0 != status) { | 
| 68     VBDEBUG(("Unable to read stored versions.\n")); | 72     VBDEBUG(("Unable to read stored versions.\n")); | 
| 69     return LOAD_FIRMWARE_RECOVERY; | 73     return (status == TPM_E_MUST_REBOOT ? | 
|  | 74             LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); | 
| 70   } | 75   } | 
| 71 | 76 | 
| 72   /* Allocate our internal data */ | 77   /* Allocate our internal data */ | 
| 73   lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); | 78   lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); | 
| 74   if (!lfi) | 79   if (!lfi) | 
| 75     return LOAD_FIRMWARE_RECOVERY; | 80     return LOAD_FIRMWARE_RECOVERY; | 
| 76   params->load_firmware_internal = (uint8_t*)lfi; | 81   params->load_firmware_internal = (uint8_t*)lfi; | 
| 77 | 82 | 
| 78   /* Loop over indices */ | 83   /* Loop over indices */ | 
| 79   for (index = 0; index < 2; index++) { | 84   for (index = 0; index < 2; index++) { | 
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 212   Free(lfi); | 217   Free(lfi); | 
| 213   params->load_firmware_internal = NULL; | 218   params->load_firmware_internal = NULL; | 
| 214 | 219 | 
| 215   /* Handle finding good firmware */ | 220   /* Handle finding good firmware */ | 
| 216   if (good_index >= 0) { | 221   if (good_index >= 0) { | 
| 217 | 222 | 
| 218     /* Update TPM if necessary */ | 223     /* Update TPM if necessary */ | 
| 219     if ((lowest_key_version > tpm_key_version) || | 224     if ((lowest_key_version > tpm_key_version) || | 
| 220         (lowest_key_version == tpm_key_version && | 225         (lowest_key_version == tpm_key_version && | 
| 221          lowest_fw_version > tpm_fw_version)) { | 226          lowest_fw_version > tpm_fw_version)) { | 
| 222       if (0 != RollbackFirmwareWrite((uint16_t)lowest_key_version, | 227 | 
| 223                                      (uint16_t)lowest_fw_version)) { | 228 | 
|  | 229       status = RollbackFirmwareWrite((uint16_t)lowest_key_version, | 
|  | 230                                      (uint16_t)lowest_fw_version); | 
|  | 231       if (0 != status) { | 
| 224         VBDEBUG(("Unable to write stored versions.\n")); | 232         VBDEBUG(("Unable to write stored versions.\n")); | 
| 225         return LOAD_FIRMWARE_RECOVERY; | 233         return (status == TPM_E_MUST_REBOOT ? | 
|  | 234                 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); | 
| 226       } | 235       } | 
| 227     } | 236     } | 
| 228 | 237 | 
| 229     /* Lock firmware versions in TPM */ | 238     /* Lock firmware versions in TPM */ | 
| 230     if (0 != RollbackFirmwareLock()) { | 239     status = RollbackFirmwareLock(); | 
|  | 240     if (0 != status) { | 
| 231       VBDEBUG(("Unable to lock firmware versions.\n")); | 241       VBDEBUG(("Unable to lock firmware versions.\n")); | 
| 232       return LOAD_FIRMWARE_RECOVERY; | 242       return (status == TPM_E_MUST_REBOOT ? | 
|  | 243               LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); | 
| 233     } | 244     } | 
| 234 | 245 | 
| 235     /* Success */ | 246     /* Success */ | 
| 236     VBDEBUG(("Will boot firmware index %d\n", (int)params->firmware_index)); | 247     VBDEBUG(("Will boot firmware index %d\n", (int)params->firmware_index)); | 
| 237     return LOAD_FIRMWARE_SUCCESS; | 248     return LOAD_FIRMWARE_SUCCESS; | 
| 238   } | 249   } | 
| 239 | 250 | 
| 240   /* If we're still here, no good firmware, so go to recovery mode. */ | 251   /* If we're still here, no good firmware, so go to recovery mode. */ | 
| 241   VBDEBUG(("Alas, no good firmware.\n")); | 252   VBDEBUG(("Alas, no good firmware.\n")); | 
| 242   return LOAD_FIRMWARE_RECOVERY; | 253   return LOAD_FIRMWARE_RECOVERY; | 
| 243 } | 254 } | 
| OLD | NEW | 
|---|