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 18 matching lines...) Expand all Loading... |
29 DigestUpdate(&lfi->body_digest_context, data, size); | 29 DigestUpdate(&lfi->body_digest_context, data, size); |
30 lfi->body_size_accum += size; | 30 lfi->body_size_accum += size; |
31 } | 31 } |
32 | 32 |
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 uint32_t tpm_version = 0; |
40 uint16_t tpm_fw_version = 0; | 40 uint64_t lowest_version = 0xFFFFFFFF; |
41 uint64_t lowest_key_version = 0xFFFF; | |
42 uint64_t lowest_fw_version = 0xFFFF; | |
43 uint32_t status; | 41 uint32_t status; |
44 int good_index = -1; | 42 int good_index = -1; |
45 int index; | 43 int index; |
46 | 44 |
47 /* Clear output params in case we fail */ | 45 /* Clear output params in case we fail */ |
48 params->firmware_index = 0; | 46 params->firmware_index = 0; |
49 | 47 |
50 VBDEBUG(("LoadFirmware started...\n")); | 48 VBDEBUG(("LoadFirmware started...\n")); |
51 | 49 |
52 if (params->kernel_sign_key_size < sizeof(VbPublicKey)) { | 50 if (params->kernel_sign_key_size < sizeof(VbPublicKey)) { |
53 VBDEBUG(("Kernel sign key buffer too small\n")); | 51 VBDEBUG(("Kernel sign key buffer too small\n")); |
54 return LOAD_FIRMWARE_RECOVERY; | 52 return LOAD_FIRMWARE_RECOVERY; |
55 } | 53 } |
56 | 54 |
57 /* Must have a root key */ | 55 /* Must have a root key */ |
58 if (!root_key) { | 56 if (!root_key) { |
59 VBDEBUG(("No root key\n")); | 57 VBDEBUG(("No root key\n")); |
60 return LOAD_FIRMWARE_RECOVERY; | 58 return LOAD_FIRMWARE_RECOVERY; |
61 } | 59 } |
62 | 60 |
63 /* Initialize the TPM and read rollback indices. */ | 61 /* Initialize the TPM and read rollback indices. */ |
64 status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER, | 62 status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER, |
65 &tpm_key_version, &tpm_fw_version); | 63 &tpm_version); |
66 if (0 != status) { | 64 if (0 != status) { |
67 VBDEBUG(("Unable to setup TPM and read stored versions.\n")); | 65 VBDEBUG(("Unable to setup TPM and read stored versions.\n")); |
68 return (status == TPM_E_MUST_REBOOT ? | 66 return (status == TPM_E_MUST_REBOOT ? |
69 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); | 67 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); |
70 } | 68 } |
71 | 69 |
72 /* Allocate our internal data */ | 70 /* Allocate our internal data */ |
73 lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); | 71 lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); |
74 if (!lfi) | 72 if (!lfi) |
75 return LOAD_FIRMWARE_RECOVERY; | 73 return LOAD_FIRMWARE_RECOVERY; |
76 params->load_firmware_internal = (uint8_t*)lfi; | 74 params->load_firmware_internal = (uint8_t*)lfi; |
77 | 75 |
78 /* Loop over indices */ | 76 /* Loop over indices */ |
79 for (index = 0; index < 2; index++) { | 77 for (index = 0; index < 2; index++) { |
80 VbKeyBlockHeader* key_block; | 78 VbKeyBlockHeader* key_block; |
81 uint64_t vblock_size; | 79 uint64_t vblock_size; |
82 VbFirmwarePreambleHeader* preamble; | 80 VbFirmwarePreambleHeader* preamble; |
83 RSAPublicKey* data_key; | 81 RSAPublicKey* data_key; |
84 uint64_t key_version; | 82 uint64_t key_version; |
| 83 uint64_t combined_version; |
85 uint8_t* body_digest; | 84 uint8_t* body_digest; |
86 | 85 |
87 /* Verify the key block */ | 86 /* Verify the key block */ |
88 if (0 == index) { | 87 if (0 == index) { |
89 key_block = (VbKeyBlockHeader*)params->verification_block_0; | 88 key_block = (VbKeyBlockHeader*)params->verification_block_0; |
90 vblock_size = params->verification_size_0; | 89 vblock_size = params->verification_size_0; |
91 } else { | 90 } else { |
92 key_block = (VbKeyBlockHeader*)params->verification_block_1; | 91 key_block = (VbKeyBlockHeader*)params->verification_block_1; |
93 vblock_size = params->verification_size_1; | 92 vblock_size = params->verification_size_1; |
94 } | 93 } |
95 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) { | 94 if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) { |
96 VBDEBUG(("Key block verification failed.\n")); | 95 VBDEBUG(("Key block verification failed.\n")); |
97 continue; | 96 continue; |
98 } | 97 } |
99 | 98 |
100 /* Check for rollback of key version. */ | 99 /* Check for rollback of key version. */ |
101 key_version = key_block->data_key.key_version; | 100 key_version = key_block->data_key.key_version; |
102 if (key_version < tpm_key_version) { | 101 if (key_version < (tpm_version >> 16)) { |
103 VBDEBUG(("Key rollback detected.\n")); | 102 VBDEBUG(("Key rollback detected.\n")); |
104 continue; | 103 continue; |
105 } | 104 } |
106 | 105 |
107 /* Get the key for preamble/data verification from the key block. */ | 106 /* Get the key for preamble/data verification from the key block. */ |
108 data_key = PublicKeyToRSA(&key_block->data_key); | 107 data_key = PublicKeyToRSA(&key_block->data_key); |
109 if (!data_key) { | 108 if (!data_key) { |
110 VBDEBUG(("Unable to parse data key.\n")); | 109 VBDEBUG(("Unable to parse data key.\n")); |
111 continue; | 110 continue; |
112 } | 111 } |
113 | 112 |
114 /* Verify the preamble, which follows the key block. */ | 113 /* Verify the preamble, which follows the key block. */ |
115 preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + | 114 preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + |
116 key_block->key_block_size); | 115 key_block->key_block_size); |
117 if ((0 != VerifyFirmwarePreamble(preamble, | 116 if ((0 != VerifyFirmwarePreamble(preamble, |
118 vblock_size - key_block->key_block_size, | 117 vblock_size - key_block->key_block_size, |
119 data_key))) { | 118 data_key))) { |
120 VBDEBUG(("Preamble verfication failed.\n")); | 119 VBDEBUG(("Preamble verfication failed.\n")); |
121 RSAPublicKeyFree(data_key); | 120 RSAPublicKeyFree(data_key); |
122 continue; | 121 continue; |
123 } | 122 } |
124 | 123 |
125 /* Check for rollback of firmware version. */ | 124 /* Check for rollback of firmware version. */ |
126 if (key_version == tpm_key_version && | 125 combined_version = ((key_version << 16) | |
127 preamble->firmware_version < tpm_fw_version) { | 126 (preamble->firmware_version & 0xFFFF)); |
| 127 if (combined_version < tpm_version) { |
128 VBDEBUG(("Firmware version rollback detected.\n")); | 128 VBDEBUG(("Firmware version rollback detected.\n")); |
129 RSAPublicKeyFree(data_key); | 129 RSAPublicKeyFree(data_key); |
130 continue; | 130 continue; |
131 } | 131 } |
132 | 132 |
133 /* Check for lowest key version from a valid header. */ | 133 /* Check for lowest key version from a valid header. */ |
134 if (lowest_key_version > key_version) { | 134 if (lowest_version > combined_version) |
135 lowest_key_version = key_version; | 135 lowest_version = combined_version; |
136 lowest_fw_version = preamble->firmware_version; | |
137 } | |
138 else if (lowest_key_version == key_version && | |
139 lowest_fw_version > preamble->firmware_version) { | |
140 lowest_fw_version = preamble->firmware_version; | |
141 } | |
142 | 136 |
143 /* If we already have good firmware, no need to read another one; | 137 /* If we already have good firmware, no need to read another one; |
144 * we only needed to look at the versions to check for | 138 * we only needed to look at the versions to check for |
145 * rollback. */ | 139 * rollback. */ |
146 if (-1 != good_index) | 140 if (-1 != good_index) |
147 continue; | 141 continue; |
148 | 142 |
149 /* Read the firmware data */ | 143 /* Read the firmware data */ |
150 DigestInit(&lfi->body_digest_context, data_key->algorithm); | 144 DigestInit(&lfi->body_digest_context, data_key->algorithm); |
151 lfi->body_size_accum = 0; | 145 lfi->body_size_accum = 0; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 | 189 |
196 /* Save the good index, now that we're sure we can actually use | 190 /* Save the good index, now that we're sure we can actually use |
197 * this firmware. That's the one we'll boot. */ | 191 * this firmware. That's the one we'll boot. */ |
198 good_index = index; | 192 good_index = index; |
199 params->firmware_index = index; | 193 params->firmware_index = index; |
200 | 194 |
201 /* If the good firmware's key version is the same as the tpm, | 195 /* If the good firmware's key version is the same as the tpm, |
202 * then the TPM doesn't need updating; we can stop now. | 196 * then the TPM doesn't need updating; we can stop now. |
203 * Otherwise, we'll check all the other headers to see if they | 197 * Otherwise, we'll check all the other headers to see if they |
204 * contain a newer key. */ | 198 * contain a newer key. */ |
205 if (key_version == tpm_key_version && | 199 if (combined_version == tpm_version) |
206 preamble->firmware_version == tpm_fw_version) | |
207 break; | 200 break; |
208 } | 201 } |
209 } | 202 } |
210 | 203 |
211 /* Free internal data */ | 204 /* Free internal data */ |
212 Free(lfi); | 205 Free(lfi); |
213 params->load_firmware_internal = NULL; | 206 params->load_firmware_internal = NULL; |
214 | 207 |
215 /* Handle finding good firmware */ | 208 /* Handle finding good firmware */ |
216 if (good_index >= 0) { | 209 if (good_index >= 0) { |
217 | 210 |
218 /* Update TPM if necessary */ | 211 /* Update TPM if necessary */ |
219 if ((lowest_key_version > tpm_key_version) || | 212 if (lowest_version > tpm_version) { |
220 (lowest_key_version == tpm_key_version && | 213 status = RollbackFirmwareWrite((uint32_t)lowest_version); |
221 lowest_fw_version > tpm_fw_version)) { | |
222 | |
223 status = RollbackFirmwareWrite((uint16_t)lowest_key_version, | |
224 (uint16_t)lowest_fw_version); | |
225 if (0 != status) { | 214 if (0 != status) { |
226 VBDEBUG(("Unable to write stored versions.\n")); | 215 VBDEBUG(("Unable to write stored versions.\n")); |
227 return (status == TPM_E_MUST_REBOOT ? | 216 return (status == TPM_E_MUST_REBOOT ? |
228 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); | 217 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); |
229 } | 218 } |
230 } | 219 } |
231 | 220 |
232 /* Lock firmware versions in TPM */ | 221 /* Lock firmware versions in TPM */ |
233 status = RollbackFirmwareLock(); | 222 status = RollbackFirmwareLock(); |
234 if (0 != status) { | 223 if (0 != status) { |
235 VBDEBUG(("Unable to lock firmware versions.\n")); | 224 VBDEBUG(("Unable to lock firmware versions.\n")); |
236 return (status == TPM_E_MUST_REBOOT ? | 225 return (status == TPM_E_MUST_REBOOT ? |
237 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); | 226 LOAD_FIRMWARE_REBOOT : LOAD_FIRMWARE_RECOVERY); |
238 } | 227 } |
239 | 228 |
240 /* Success */ | 229 /* Success */ |
241 VBDEBUG(("Will boot firmware index %d\n", (int)params->firmware_index)); | 230 VBDEBUG(("Will boot firmware index %d\n", (int)params->firmware_index)); |
242 return LOAD_FIRMWARE_SUCCESS; | 231 return LOAD_FIRMWARE_SUCCESS; |
243 } | 232 } |
244 | 233 |
245 /* If we're still here, no good firmware, so go to recovery mode. */ | 234 /* If we're still here, no good firmware, so go to recovery mode. */ |
246 VBDEBUG(("Alas, no good firmware.\n")); | 235 VBDEBUG(("Alas, no good firmware.\n")); |
247 return LOAD_FIRMWARE_RECOVERY; | 236 return LOAD_FIRMWARE_RECOVERY; |
248 } | 237 } |
OLD | NEW |