OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 * | 5 * |
6 * Alternatively, this software may be distributed under the terms of the | 6 * Alternatively, this software may be distributed under the terms of the |
7 * GNU General Public License ("GPL") version 2 as published by the Free | 7 * GNU General Public License ("GPL") version 2 as published by the Free |
8 * Software Foundation. | 8 * Software Foundation. |
9 */ | 9 */ |
10 | 10 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 return 0; | 121 return 0; |
122 } | 122 } |
123 | 123 |
124 /* | 124 /* |
125 * Initialize <params> for LoadFirmware(). | 125 * Initialize <params> for LoadFirmware(). |
126 * | 126 * |
127 * Return 0 if success, non-zero if error. | 127 * Return 0 if success, non-zero if error. |
128 */ | 128 */ |
129 int init_params(LoadFirmwareParams *params, firmware_storage_t *file, | 129 int init_params(LoadFirmwareParams *params, firmware_storage_t *file, |
130 const off_t vblock_offset[], int boot_flags, | 130 const off_t vblock_offset[], int boot_flags, |
131 » » void *kernel_sign_key_blob, uint64_t kernel_sign_key_size) | 131 » » void *vb_shared_data_blob, uint64_t vb_shared_data_size) |
132 { | 132 { |
133 GoogleBinaryBlockHeader gbbh; | |
134 | |
135 memset(params, '\0', sizeof(*params)); | 133 memset(params, '\0', sizeof(*params)); |
136 | 134 |
137 » /* read gbb header */ | 135 » /* read gbb */ |
138 » if (read_firmware_device(file, CONFIG_OFFSET_GBB, &gbbh, | 136 » params->gbb_size = CONFIG_LENGTH_GBB; |
139 » » » » sizeof(gbbh))) { | 137 » params->gbb_data = malloc(CONFIG_LENGTH_GBB); |
140 » » debug(PREFIX "read gbb header fail\n"); | 138 » if (!params->gbb_data) { |
| 139 » » debug(PREFIX "cannot malloc gbb\n"); |
| 140 » » return -1; |
| 141 » } |
| 142 » if (read_firmware_device(file, CONFIG_OFFSET_GBB, |
| 143 » » » » params->gbb_data, |
| 144 » » » » params->gbb_size)) { |
| 145 » » debug(PREFIX "read gbb fail\n"); |
141 return -1; | 146 return -1; |
142 } | 147 } |
143 | 148 |
144 /* read root key from gbb */ | |
145 params->firmware_root_key_blob = malloc(gbbh.rootkey_size); | |
146 if (!params->firmware_root_key_blob) { | |
147 debug(PREFIX "cannot malloc firmware_root_key_blob\n"); | |
148 return -1; | |
149 } | |
150 if (read_firmware_device(file, CONFIG_OFFSET_GBB + gbbh.rootkey_offset, | |
151 params->firmware_root_key_blob, | |
152 gbbh.rootkey_size)) { | |
153 debug(PREFIX "read root key fail\n"); | |
154 return -1; | |
155 } | |
156 | |
157 /* read verification block 0 and 1 */ | 149 /* read verification block 0 and 1 */ |
158 if (read_verification_block(file, vblock_offset[0], | 150 if (read_verification_block(file, vblock_offset[0], |
159 ¶ms->verification_block_0, | 151 ¶ms->verification_block_0, |
160 ¶ms->verification_size_0)) { | 152 ¶ms->verification_size_0)) { |
161 debug(PREFIX "read verification block 0 fail\n"); | 153 debug(PREFIX "read verification block 0 fail\n"); |
162 return -1; | 154 return -1; |
163 } | 155 } |
164 if (read_verification_block(file, vblock_offset[1], | 156 if (read_verification_block(file, vblock_offset[1], |
165 ¶ms->verification_block_1, | 157 ¶ms->verification_block_1, |
166 ¶ms->verification_size_1)) { | 158 ¶ms->verification_size_1)) { |
167 debug(PREFIX "read verification block 1 fail\n"); | 159 debug(PREFIX "read verification block 1 fail\n"); |
168 return -1; | 160 return -1; |
169 } | 161 } |
170 | 162 |
171 params->boot_flags = boot_flags; | 163 params->boot_flags = boot_flags; |
172 params->caller_internal = file; | 164 params->caller_internal = file; |
173 » params->kernel_sign_key_blob = kernel_sign_key_blob; | 165 » params->shared_data_blob = vb_shared_data_blob; |
174 » params->kernel_sign_key_size = kernel_sign_key_size; | 166 » params->shared_data_size = vb_shared_data_size; |
175 | 167 |
176 return 0; | 168 return 0; |
177 } | 169 } |
178 | 170 |
179 /* | 171 /* |
180 * Load and verify rewritable firmware. A wrapper of LoadFirmware() function. | 172 * Load and verify rewritable firmware. A wrapper of LoadFirmware() function. |
181 * | 173 * |
182 * Returns what is returned by LoadFirmware(). | 174 * Returns what is returned by LoadFirmware(). |
183 * | 175 * |
184 * For documentation of return values of LoadFirmware(), <primary_firmware>, and | 176 * For documentation of return values of LoadFirmware(), <primary_firmware>, and |
185 * <boot_flags>, please refer to | 177 * <boot_flags>, please refer to |
186 * vboot_reference/firmware/include/load_firmware_fw.h | 178 * vboot_reference/firmware/include/load_firmware_fw.h |
187 * | 179 * |
188 * The kernel key found in firmware image is stored in <kernel_sign_key_blob> | 180 * The shared data blob for the firmware image is stored in |
189 * and <kernel_sign_key_size>. | 181 * <vb_shared_data_blob> and <vb_shared_data_size>. |
190 * | 182 * |
191 * Pointer to loaded firmware is stored in <firmware_data_ptr>. | 183 * Pointer to loaded firmware is stored in <firmware_data_ptr>. |
192 */ | 184 */ |
193 int load_firmware(uint8_t **firmware_data_ptr, | 185 int load_firmware(uint8_t **firmware_data_ptr, |
194 int primary_firmware, int boot_flags, | 186 int primary_firmware, int boot_flags, |
195 » » void *kernel_sign_key_blob, uint64_t kernel_sign_key_size) | 187 » » void *vb_shared_data_blob, uint64_t vb_shared_data_size) |
196 { | 188 { |
197 /* | 189 /* |
198 * Offsets of verification blocks are | 190 * Offsets of verification blocks are |
199 * vblock_offset[primary_firmware][verification_block_index]. | 191 * vblock_offset[primary_firmware][verification_block_index]. |
200 * | 192 * |
201 * Offsets of firmware data are | 193 * Offsets of firmware data are |
202 * data_offset[primary_firmware][firmware_data_index]. | 194 * data_offset[primary_firmware][firmware_data_index]. |
203 */ | 195 */ |
204 const off_t vblock_offset[2][2] = { | 196 const off_t vblock_offset[2][2] = { |
205 { CONFIG_OFFSET_FW_A_KEY, CONFIG_OFFSET_FW_B_KEY }, | 197 { CONFIG_OFFSET_FW_A_KEY, CONFIG_OFFSET_FW_B_KEY }, |
206 { CONFIG_OFFSET_FW_B_KEY, CONFIG_OFFSET_FW_A_KEY }, | 198 { CONFIG_OFFSET_FW_B_KEY, CONFIG_OFFSET_FW_A_KEY }, |
207 }; | 199 }; |
208 const off_t data_offset[2][2] = { | 200 const off_t data_offset[2][2] = { |
209 { CONFIG_OFFSET_FW_A_DATA, CONFIG_OFFSET_FW_B_DATA }, | 201 { CONFIG_OFFSET_FW_A_DATA, CONFIG_OFFSET_FW_B_DATA }, |
210 { CONFIG_OFFSET_FW_B_DATA, CONFIG_OFFSET_FW_A_DATA }, | 202 { CONFIG_OFFSET_FW_B_DATA, CONFIG_OFFSET_FW_A_DATA }, |
211 }; | 203 }; |
212 int status = LOAD_FIRMWARE_RECOVERY; | 204 int status = LOAD_FIRMWARE_RECOVERY; |
213 LoadFirmwareParams params; | 205 LoadFirmwareParams params; |
214 firmware_storage_t file; | 206 firmware_storage_t file; |
215 | 207 |
216 if (init_firmware_storage(&file)) { | 208 if (init_firmware_storage(&file)) { |
217 debug(PREFIX "init_firmware_storage fail\n"); | 209 debug(PREFIX "init_firmware_storage fail\n"); |
218 return FIRMWARE_RECOVERY; | 210 return FIRMWARE_RECOVERY; |
219 } | 211 } |
220 GetFirmwareBody_setup(&file, data_offset[primary_firmware][0], | 212 GetFirmwareBody_setup(&file, data_offset[primary_firmware][0], |
221 data_offset[primary_firmware][1]); | 213 data_offset[primary_firmware][1]); |
222 | 214 |
223 if (init_params(¶ms, &file, vblock_offset[primary_firmware], | 215 if (init_params(¶ms, &file, vblock_offset[primary_firmware], |
224 » » » » boot_flags, kernel_sign_key_blob, | 216 » » » » boot_flags, vb_shared_data_blob, |
225 » » » » kernel_sign_key_size)) { | 217 » » » » vb_shared_data_size)) { |
226 debug(PREFIX "init LoadFirmware parameters fail\n"); | 218 debug(PREFIX "init LoadFirmware parameters fail\n"); |
227 } else | 219 } else |
228 status = LoadFirmware(¶ms); | 220 status = LoadFirmware(¶ms); |
229 | 221 |
230 if (status == LOAD_FIRMWARE_SUCCESS) { | 222 if (status == LOAD_FIRMWARE_SUCCESS) { |
231 debug(PREFIX "will jump to rewritable firmware %d\n", | 223 debug(PREFIX "will jump to rewritable firmware %d\n", |
232 (int) params.firmware_index); | 224 (int) params.firmware_index); |
233 *firmware_data_ptr = file.firmware_body[params.firmware_index]; | 225 *firmware_data_ptr = file.firmware_body[params.firmware_index]; |
234 | 226 |
235 /* set to null so that *firmware_data_ptr is not disposed */ | 227 /* set to null so that *firmware_data_ptr is not disposed */ |
236 file.firmware_body[params.firmware_index] = NULL; | 228 file.firmware_body[params.firmware_index] = NULL; |
237 } | 229 } |
238 | 230 |
239 release_firmware_storage(&file); | 231 release_firmware_storage(&file); |
240 GetFirmwareBody_dispose(&file); | 232 GetFirmwareBody_dispose(&file); |
241 | 233 |
242 » if (params.firmware_root_key_blob) | 234 » if (params.gbb_data) |
243 » » free(params.firmware_root_key_blob); | 235 » » free(params.gbb_data); |
244 if (params.verification_block_0) | 236 if (params.verification_block_0) |
245 free(params.verification_block_0); | 237 free(params.verification_block_0); |
246 if (params.verification_block_1) | 238 if (params.verification_block_1) |
247 free(params.verification_block_1); | 239 free(params.verification_block_1); |
248 | 240 |
249 return status; | 241 return status; |
250 } | 242 } |
251 | 243 |
252 /* | 244 /* |
253 * Read recovery firmware into <firmware_data_buffer>. | 245 * Read recovery firmware into <firmware_data_buffer>. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 305 |
314 /* FIXME(clchiou) Bring up a sad face as boot has failed */ | 306 /* FIXME(clchiou) Bring up a sad face as boot has failed */ |
315 while (1); | 307 while (1); |
316 } | 308 } |
317 | 309 |
318 int do_cros_bootstub(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 310 int do_cros_bootstub(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
319 { | 311 { |
320 int status = LOAD_FIRMWARE_RECOVERY; | 312 int status = LOAD_FIRMWARE_RECOVERY; |
321 int primary_firmware, boot_flags = 0; | 313 int primary_firmware, boot_flags = 0; |
322 uint8_t *firmware_data; | 314 uint8_t *firmware_data; |
323 » uint8_t *kernel_sign_key_blob = (uint8_t *) CONFIG_KERNEL_SIGN_KEY_BLOB; | 315 » uint8_t *vb_shared_data_blob = (uint8_t *) CONFIG_VB_SHARED_DATA_BLOB; |
324 » uint64_t kernel_sign_key_size = CONFIG_KERNEL_SIGN_KEY_SIZE; | 316 » uint64_t vb_shared_data_size = CONFIG_VB_SHARED_DATA_SIZE; |
325 | 317 |
326 /* TODO Start initializing chipset */ | 318 /* TODO Start initializing chipset */ |
327 | 319 |
328 if (is_firmware_write_protect_gpio_asserted()) | 320 if (is_firmware_write_protect_gpio_asserted()) |
329 WARN_ON_FAILURE(lock_down_eeprom()); | 321 WARN_ON_FAILURE(lock_down_eeprom()); |
330 | 322 |
331 WARN_ON_FAILURE(initialize_tpm()); | 323 WARN_ON_FAILURE(initialize_tpm()); |
332 | 324 |
333 if (is_s3_resume() && !is_debug_reset_mode_field_containing_cookie()) { | 325 if (is_s3_resume() && !is_debug_reset_mode_field_containing_cookie()) { |
334 WARN_ON_FAILURE(lock_tpm()); | 326 WARN_ON_FAILURE(lock_tpm()); |
335 /* TODO Jump to S3 resume pointer and should never return */ | 327 /* TODO Jump to S3 resume pointer and should never return */ |
336 return 0; | 328 return 0; |
337 } | 329 } |
338 | 330 |
339 if (is_recovery_mode_gpio_asserted() || | 331 if (is_recovery_mode_gpio_asserted() || |
340 is_recovery_mode_field_containing_cookie()) { | 332 is_recovery_mode_field_containing_cookie()) { |
341 debug(PREFIX "boot recovery firmware\n"); | 333 debug(PREFIX "boot recovery firmware\n"); |
342 } else { | 334 } else { |
343 if (is_try_firmware_b_field_containing_cookie()) | 335 if (is_try_firmware_b_field_containing_cookie()) |
344 primary_firmware = FIRMWARE_B; | 336 primary_firmware = FIRMWARE_B; |
345 else | 337 else |
346 primary_firmware = FIRMWARE_A; | 338 primary_firmware = FIRMWARE_A; |
347 | 339 |
348 if (is_developer_mode_gpio_asserted()) | 340 if (is_developer_mode_gpio_asserted()) |
349 boot_flags |= BOOT_FLAG_DEVELOPER; | 341 boot_flags |= BOOT_FLAG_DEVELOPER; |
350 | 342 |
351 status = load_firmware(&firmware_data, | 343 status = load_firmware(&firmware_data, |
352 primary_firmware, boot_flags, | 344 primary_firmware, boot_flags, |
353 » » » » kernel_sign_key_blob, kernel_sign_key_size); | 345 » » » » vb_shared_data_blob, vb_shared_data_size); |
354 } | 346 } |
355 | 347 |
356 WARN_ON_FAILURE(lock_tpm_rewritable_firmware_index()); | 348 WARN_ON_FAILURE(lock_tpm_rewritable_firmware_index()); |
357 | 349 |
358 if (status == LOAD_FIRMWARE_SUCCESS) { | 350 if (status == LOAD_FIRMWARE_SUCCESS) { |
359 jump_to_firmware((void (*)(void)) firmware_data); | 351 jump_to_firmware((void (*)(void)) firmware_data); |
360 | 352 |
361 debug(PREFIX "error: should never reach here! " | 353 debug(PREFIX "error: should never reach here! " |
362 "jump to recovery firmware\n"); | 354 "jump to recovery firmware\n"); |
363 } | 355 } |
364 | 356 |
365 debug(PREFIX "jump to recovery firmware and never return\n"); | 357 debug(PREFIX "jump to recovery firmware and never return\n"); |
366 | 358 |
367 firmware_data = malloc(CONFIG_LENGTH_RECOVERY); | 359 firmware_data = malloc(CONFIG_LENGTH_RECOVERY); |
368 WARN_ON_FAILURE(load_firmware_data(firmware_data)); | 360 WARN_ON_FAILURE(load_firmware_data(firmware_data)); |
369 jump_to_firmware((void (*)(void)) firmware_data); | 361 jump_to_firmware((void (*)(void)) firmware_data); |
370 | 362 |
371 debug(PREFIX "error: should never reach here!\n"); | 363 debug(PREFIX "error: should never reach here!\n"); |
372 return 1; | 364 return 1; |
373 } | 365 } |
374 | 366 |
375 U_BOOT_CMD(cros_bootstub, 1, 1, do_cros_bootstub, "verified boot stub firmware", | 367 U_BOOT_CMD(cros_bootstub, 1, 1, do_cros_bootstub, "verified boot stub firmware", |
376 NULL); | 368 NULL); |
OLD | NEW |