| 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 |