/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * * TEMPORARY stub for calling LoadFirmware() which looks like the old * VerifyFirmwareDriver_f() call. * (Firmware portion) */ #include "load_firmware_fw.h" #include "utility.h" #include "vboot_api.h" #define BOOT_FIRMWARE_A_CONTINUE 1 #define BOOT_FIRMWARE_B_CONTINUE 2 #define BOOT_FIRMWARE_RECOVERY_CONTINUE 3 typedef struct CallerInternal { uint8_t *firmwareA; uint64_t firmwareA_size; uint8_t *firmwareB; uint64_t firmwareB_size; } CallerInternal; int GetFirmwareBody(LoadFirmwareParams* params, uint64_t index) { CallerInternal* ci = (CallerInternal*)params->caller_internal; uint8_t *fw; uint64_t size; /* In a real implementation, GetFirmwareBody() should be what reads * and decompresses the firmware volume. In this temporary hack, we * just pass the pointer which we got from * VerifyFirmwareDriver_Stub(). */ switch(index) { case 0: size = ci->firmwareA_size; fw = ci->firmwareA; break; case 1: size = ci->firmwareB_size; fw = ci->firmwareB; break; default: /* Anything else is invalid */ return 1; } /* Need to call UpdateFirmwareBodyHash() with the firmware volume * data. In this temporary hack, the FV is already decompressed, so * we pass in the entire volume at once. In a real implementation, * you should call this as the FV is being decompressed. */ UpdateFirmwareBodyHash(params, fw, size); /* Success */ return 0; } /* Where you're currently calling VerifyFirmwareDriver_f(), call this * function instead. Because you still need to read in both firmware * volumes, this call will still be slow. Once we reach feature * complete, you should modify your code to call LoadImage() * directly. */ int VerifyFirmwareDriver_stub(uint8_t* gbb_data, uint64_t gbb_size, uint8_t* verification_headerA, uint8_t* firmwareA, uint8_t* verification_headerB, uint8_t* firmwareB) { int rv; CallerInternal ci; LoadFirmwareParams p; VbNvContext vnc; /* TODO: YOU SHOULD CALL LoadFirmwareSetup() AS SOON AS THE TPM * INTERFACE IS AVAILABLE */ LoadFirmwareSetup(); /* Copy the firmware volume pointers to our global variables. */ ci.firmwareA = firmwareA; ci.firmwareB = firmwareB; /* TODO: YOU NEED TO PASS IN THE FIRMWARE VOLUME SIZES SOMEHOW */ ci.firmwareA_size = 0; ci.firmwareB_size = 0; /* TODO: YOU NEED TO LOAD vnc.raw[] FROM NON-VOLATILE STORAGE */ /* Set up the params for LoadFirmware() */ p.caller_internal = &ci; p.gbb_data = gbb_data; p.gbb_size = gbb_size; p.verification_block_0 = verification_headerA; p.verification_block_1 = verification_headerB; p.nv_context = &vnc; /* Allocate a shared data buffer */ p.shared_data_blob = VbExMalloc(VB_SHARED_DATA_REC_SIZE); p.shared_data_size = VB_SHARED_DATA_REC_SIZE; /* TODO: YOU NEED TO SET THE BOOT FLAGS SOMEHOW */ p.boot_flags = 0; /* Call LoadFirmware() */ rv = LoadFirmware(&p); if (vnc.raw_changed) { /* TODO: YOU NEED TO SAVE vnc.raw TO NON-VOLATILE STORAGE */ } if (LOAD_FIRMWARE_SUCCESS == rv) { /* TODO: YOU NEED TO KEEP TRACK OF p.shared_data_blob AND * p.shared_data_size SO YOU CAN PASS THEM TO LoadKernel(). */ return (0 == p.firmware_index ? BOOT_FIRMWARE_A_CONTINUE : BOOT_FIRMWARE_B_CONTINUE); } else { /* Error */ return BOOT_FIRMWARE_RECOVERY_CONTINUE; } }