| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 return LOAD_FIRMWARE_RECOVERY; | 52 return LOAD_FIRMWARE_RECOVERY; |
| 53 } | 53 } |
| 54 | 54 |
| 55 /* Must have a root key */ | 55 /* Must have a root key */ |
| 56 if (!root_key) { | 56 if (!root_key) { |
| 57 VBDEBUG(("No root key\n")); | 57 VBDEBUG(("No root key\n")); |
| 58 return LOAD_FIRMWARE_RECOVERY; | 58 return LOAD_FIRMWARE_RECOVERY; |
| 59 } | 59 } |
| 60 | 60 |
| 61 /* Initialize the TPM and read rollback indices. */ | 61 /* Initialize the TPM and read rollback indices. */ |
| 62 VBPERFSTART("VB_TPMI"); |
| 62 status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER, | 63 status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER, |
| 63 &tpm_version); | 64 &tpm_version); |
| 64 if (0 != status) { | 65 if (0 != status) { |
| 65 VBDEBUG(("Unable to setup TPM and read stored versions.\n")); | 66 VBDEBUG(("Unable to setup TPM and read stored versions.\n")); |
| 67 VBPERFEND("VB_TPMI"); |
| 66 return (status == TPM_E_MUST_REBOOT ? | 68 return (status == TPM_E_MUST_REBOOT ? |
| 67 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); | 69 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); |
| 68 } | 70 } |
| 71 VBPERFEND("VB_TPMI"); |
| 69 | 72 |
| 70 /* Allocate our internal data */ | 73 /* Allocate our internal data */ |
| 71 lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); | 74 lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); |
| 72 if (!lfi) | 75 if (!lfi) |
| 73 return LOAD_FIRMWARE_RECOVERY; | 76 return LOAD_FIRMWARE_RECOVERY; |
| 77 |
| 74 params->load_firmware_internal = (uint8_t*)lfi; | 78 params->load_firmware_internal = (uint8_t*)lfi; |
| 75 | 79 |
| 76 /* Loop over indices */ | 80 /* Loop over indices */ |
| 77 for (index = 0; index < 2; index++) { | 81 for (index = 0; index < 2; index++) { |
| 78 VbKeyBlockHeader* key_block; | 82 VbKeyBlockHeader* key_block; |
| 79 uint64_t vblock_size; | 83 uint64_t vblock_size; |
| 80 VbFirmwarePreambleHeader* preamble; | 84 VbFirmwarePreambleHeader* preamble; |
| 81 RSAPublicKey* data_key; | 85 RSAPublicKey* data_key; |
| 82 uint64_t key_version; | 86 uint64_t key_version; |
| 83 uint64_t combined_version; | 87 uint64_t combined_version; |
| 84 uint8_t* body_digest; | 88 uint8_t* body_digest; |
| 85 | 89 |
| 86 /* Verify the key block */ | 90 /* Verify the key block */ |
| 91 VBPERFSTART("VB_VKB"); |
| 87 if (0 == index) { | 92 if (0 == index) { |
| 88 key_block = (VbKeyBlockHeader*)params->verification_block_0; | 93 key_block = (VbKeyBlockHeader*)params->verification_block_0; |
| 89 vblock_size = params->verification_size_0; | 94 vblock_size = params->verification_size_0; |
| 90 } else { | 95 } else { |
| 91 key_block = (VbKeyBlockHeader*)params->verification_block_1; | 96 key_block = (VbKeyBlockHeader*)params->verification_block_1; |
| 92 vblock_size = params->verification_size_1; | 97 vblock_size = params->verification_size_1; |
| 93 } | 98 } |
| 94 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key, 0))) { | 99 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key, 0))) { |
| 95 VBDEBUG(("Key block verification failed.\n")); | 100 VBDEBUG(("Key block verification failed.\n")); |
| 101 VBPERFEND("VB_VKB"); |
| 96 continue; | 102 continue; |
| 97 } | 103 } |
| 104 VBPERFEND("VB_VKB"); |
| 98 | 105 |
| 99 /* Check for rollback of key version. */ | 106 /* Check for rollback of key version. */ |
| 100 key_version = key_block->data_key.key_version; | 107 key_version = key_block->data_key.key_version; |
| 101 if (key_version < (tpm_version >> 16)) { | 108 if (key_version < (tpm_version >> 16)) { |
| 102 VBDEBUG(("Key rollback detected.\n")); | 109 VBDEBUG(("Key rollback detected.\n")); |
| 103 continue; | 110 continue; |
| 104 } | 111 } |
| 105 | 112 |
| 106 /* Get the key for preamble/data verification from the key block. */ | 113 /* Get the key for preamble/data verification from the key block. */ |
| 107 data_key = PublicKeyToRSA(&key_block->data_key); | 114 data_key = PublicKeyToRSA(&key_block->data_key); |
| 108 if (!data_key) { | 115 if (!data_key) { |
| 109 VBDEBUG(("Unable to parse data key.\n")); | 116 VBDEBUG(("Unable to parse data key.\n")); |
| 110 continue; | 117 continue; |
| 111 } | 118 } |
| 112 | 119 |
| 113 /* Verify the preamble, which follows the key block. */ | 120 /* Verify the preamble, which follows the key block. */ |
| 121 VBPERFSTART("VB_VPB"); |
| 114 preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + | 122 preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + |
| 115 key_block->key_block_size); | 123 key_block->key_block_size); |
| 116 if ((0 != VerifyFirmwarePreamble(preamble, | 124 if ((0 != VerifyFirmwarePreamble(preamble, |
| 117 vblock_size - key_block->key_block_size, | 125 vblock_size - key_block->key_block_size, |
| 118 data_key))) { | 126 data_key))) { |
| 119 VBDEBUG(("Preamble verfication failed.\n")); | 127 VBDEBUG(("Preamble verfication failed.\n")); |
| 120 RSAPublicKeyFree(data_key); | 128 RSAPublicKeyFree(data_key); |
| 129 VBPERFEND("VB_VPB"); |
| 121 continue; | 130 continue; |
| 122 } | 131 } |
| 132 VBPERFEND("VB_VPB"); |
| 123 | 133 |
| 124 /* Check for rollback of firmware version. */ | 134 /* Check for rollback of firmware version. */ |
| 125 combined_version = ((key_version << 16) | | 135 combined_version = ((key_version << 16) | |
| 126 (preamble->firmware_version & 0xFFFF)); | 136 (preamble->firmware_version & 0xFFFF)); |
| 127 if (combined_version < tpm_version) { | 137 if (combined_version < tpm_version) { |
| 128 VBDEBUG(("Firmware version rollback detected.\n")); | 138 VBDEBUG(("Firmware version rollback detected.\n")); |
| 129 RSAPublicKeyFree(data_key); | 139 RSAPublicKeyFree(data_key); |
| 130 continue; | 140 continue; |
| 131 } | 141 } |
| 132 | 142 |
| 133 /* Check for lowest key version from a valid header. */ | 143 /* Check for lowest key version from a valid header. */ |
| 134 if (lowest_version > combined_version) | 144 if (lowest_version > combined_version) |
| 135 lowest_version = combined_version; | 145 lowest_version = combined_version; |
| 136 | 146 |
| 137 /* If we already have good firmware, no need to read another one; | 147 /* If we already have good firmware, no need to read another one; |
| 138 * we only needed to look at the versions to check for | 148 * we only needed to look at the versions to check for |
| 139 * rollback. */ | 149 * rollback. */ |
| 140 if (-1 != good_index) | 150 if (-1 != good_index) |
| 141 continue; | 151 continue; |
| 142 | 152 |
| 143 /* Read the firmware data */ | 153 /* Read the firmware data */ |
| 154 VBPERFSTART("VB_RFD"); |
| 144 DigestInit(&lfi->body_digest_context, data_key->algorithm); | 155 DigestInit(&lfi->body_digest_context, data_key->algorithm); |
| 145 lfi->body_size_accum = 0; | 156 lfi->body_size_accum = 0; |
| 146 if (0 != GetFirmwareBody(params, index)) { | 157 if (0 != GetFirmwareBody(params, index)) { |
| 147 VBDEBUG(("GetFirmwareBody() failed for index %d\n", index)); | 158 VBDEBUG(("GetFirmwareBody() failed for index %d\n", index)); |
| 148 RSAPublicKeyFree(data_key); | 159 RSAPublicKeyFree(data_key); |
| 160 VBPERFEND("VB_RFD"); |
| 149 continue; | 161 continue; |
| 150 } | 162 } |
| 151 if (lfi->body_size_accum != preamble->body_signature.data_size) { | 163 if (lfi->body_size_accum != preamble->body_signature.data_size) { |
| 152 VBDEBUG(("Hash updated %d bytes but expected %d\n", | 164 VBDEBUG(("Hash updated %d bytes but expected %d\n", |
| 153 (int)lfi->body_size_accum, | 165 (int)lfi->body_size_accum, |
| 154 (int)preamble->body_signature.data_size)); | 166 (int)preamble->body_signature.data_size)); |
| 155 RSAPublicKeyFree(data_key); | 167 RSAPublicKeyFree(data_key); |
| 168 VBPERFEND("VB_RFD"); |
| 156 continue; | 169 continue; |
| 157 } | 170 } |
| 171 VBPERFEND("VB_RFD"); |
| 158 | 172 |
| 159 /* Verify firmware data */ | 173 /* Verify firmware data */ |
| 174 VBPERFSTART("VB_VFD"); |
| 160 body_digest = DigestFinal(&lfi->body_digest_context); | 175 body_digest = DigestFinal(&lfi->body_digest_context); |
| 161 if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) { | 176 if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) { |
| 162 VBDEBUG(("Firmware body verification failed.\n")); | 177 VBDEBUG(("Firmware body verification failed.\n")); |
| 163 RSAPublicKeyFree(data_key); | 178 RSAPublicKeyFree(data_key); |
| 164 Free(body_digest); | 179 Free(body_digest); |
| 180 VBPERFEND("VB_VFD"); |
| 165 continue; | 181 continue; |
| 166 } | 182 } |
| 183 VBPERFEND("VB_VFD"); |
| 167 | 184 |
| 168 /* Done with the digest and data key, so can free them now */ | 185 /* Done with the digest and data key, so can free them now */ |
| 169 RSAPublicKeyFree(data_key); | 186 RSAPublicKeyFree(data_key); |
| 170 Free(body_digest); | 187 Free(body_digest); |
| 171 | 188 |
| 172 /* If we're still here, the firmware is valid. */ | 189 /* If we're still here, the firmware is valid. */ |
| 173 VBDEBUG(("Firmware %d is valid.\n", index)); | 190 VBDEBUG(("Firmware %d is valid.\n", index)); |
| 174 if (-1 == good_index) { | 191 if (-1 == good_index) { |
| 175 VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; | 192 VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; |
| 176 | 193 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 203 | 220 |
| 204 /* Free internal data */ | 221 /* Free internal data */ |
| 205 Free(lfi); | 222 Free(lfi); |
| 206 params->load_firmware_internal = NULL; | 223 params->load_firmware_internal = NULL; |
| 207 | 224 |
| 208 /* Handle finding good firmware */ | 225 /* Handle finding good firmware */ |
| 209 if (good_index >= 0) { | 226 if (good_index >= 0) { |
| 210 | 227 |
| 211 /* Update TPM if necessary */ | 228 /* Update TPM if necessary */ |
| 212 if (lowest_version > tpm_version) { | 229 if (lowest_version > tpm_version) { |
| 230 VBPERFSTART("VB_TPMU"); |
| 213 status = RollbackFirmwareWrite((uint32_t)lowest_version); | 231 status = RollbackFirmwareWrite((uint32_t)lowest_version); |
| 232 VBPERFEND("VB_TPMU"); |
| 214 if (0 != status) { | 233 if (0 != status) { |
| 215 VBDEBUG(("Unable to write stored versions.\n")); | 234 VBDEBUG(("Unable to write stored versions.\n")); |
| 216 return (status == TPM_E_MUST_REBOOT ? | 235 return (status == TPM_E_MUST_REBOOT ? |
| 217 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); | 236 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); |
| 218 } | 237 } |
| 219 } | 238 } |
| 220 | 239 |
| 221 /* Lock firmware versions in TPM */ | 240 /* Lock firmware versions in TPM */ |
| 241 VBPERFSTART("VB_TPML"); |
| 222 status = RollbackFirmwareLock(); | 242 status = RollbackFirmwareLock(); |
| 243 VBPERFEND("VB_TPML"); |
| 223 if (0 != status) { | 244 if (0 != status) { |
| 224 VBDEBUG(("Unable to lock firmware versions.\n")); | 245 VBDEBUG(("Unable to lock firmware versions.\n")); |
| 225 return (status == TPM_E_MUST_REBOOT ? | 246 return (status == TPM_E_MUST_REBOOT ? |
| 226 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); | 247 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY_TPM); |
| 227 } | 248 } |
| 228 | 249 |
| 229 /* Success */ | 250 /* Success */ |
| 230 VBDEBUG(("Will boot firmware index %d\n", (int)params->firmware_index)); | 251 VBDEBUG(("Will boot firmware index %d\n", (int)params->firmware_index)); |
| 231 return LOAD_FIRMWARE_SUCCESS; | 252 return LOAD_FIRMWARE_SUCCESS; |
| 232 } | 253 } |
| 233 | 254 |
| 234 /* If we're still here, no good firmware, so go to recovery mode. */ | 255 /* If we're still here, no good firmware, so go to recovery mode. */ |
| 235 VBDEBUG(("Alas, no good firmware.\n")); | 256 VBDEBUG(("Alas, no good firmware.\n")); |
| 236 return LOAD_FIRMWARE_RECOVERY; | 257 return LOAD_FIRMWARE_RECOVERY; |
| 237 } | 258 } |
| 238 | 259 |
| 239 | 260 |
| 240 int S3Resume(void) { | 261 int S3Resume(void) { |
| 241 /* Resume the TPM */ | 262 /* Resume the TPM */ |
| 242 uint32_t status = RollbackS3Resume(); | 263 uint32_t status = RollbackS3Resume(); |
| 243 | 264 |
| 244 if (status == TPM_SUCCESS) | 265 if (status == TPM_SUCCESS) |
| 245 return LOAD_FIRMWARE_SUCCESS; | 266 return LOAD_FIRMWARE_SUCCESS; |
| 246 else if (status == TPM_E_MUST_REBOOT) | 267 else if (status == TPM_E_MUST_REBOOT) |
| 247 return LOAD_FIRMWARE_REBOOT; | 268 return LOAD_FIRMWARE_REBOOT; |
| 248 else | 269 else |
| 249 return LOAD_FIRMWARE_RECOVERY_TPM; | 270 return LOAD_FIRMWARE_RECOVERY_TPM; |
| 250 } | 271 } |
| OLD | NEW |