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 |