Support dev vs consumer firmware in vboot_reference

Change-Id: I5a42ba017974b3d591abc574ef7b9b7c9ac579e8

BUG=chrome-os-partner:1824
TEST=make && make runtests

Review URL: http://codereview.chromium.org/6462010
This commit is contained in:
Randall Spangler
2011-02-14 11:12:09 -08:00
parent 61362d65fc
commit a8e0f94b94
5 changed files with 47 additions and 7 deletions

View File

@@ -22,10 +22,14 @@
/* Boot flags for LoadKernel().boot_flags */ /* Boot flags for LoadKernel().boot_flags */
#define BOOT_FLAG_DEVELOPER UINT64_C(0x01) /* Developer switch is on */ /* Developer switch is on */
#define BOOT_FLAG_RECOVERY UINT64_C(0x02) /* In recovery mode */ #define BOOT_FLAG_DEVELOPER UINT64_C(0x01)
#define BOOT_FLAG_SKIP_ADDR_CHECK UINT64_C(0x04) /* Skip check of kernel /* In recovery mode */
* buffer address */ #define BOOT_FLAG_RECOVERY UINT64_C(0x02)
/* Skip check of kernel buffer address */
#define BOOT_FLAG_SKIP_ADDR_CHECK UINT64_C(0x04)
/* Active main firmware is developer-type, not normal-type or recovery-type. */
#define BOOT_FLAG_DEV_FIRMWARE UINT64_C(0x08)
typedef struct LoadKernelParams { typedef struct LoadKernelParams {
/* Inputs to LoadKernel() */ /* Inputs to LoadKernel() */

View File

@@ -40,6 +40,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
uint64_t lowest_version = 0xFFFFFFFF; uint64_t lowest_version = 0xFFFFFFFF;
uint32_t status; uint32_t status;
int good_index = -1; int good_index = -1;
int is_dev;
int index; int index;
/* Clear output params in case we fail */ /* Clear output params in case we fail */
@@ -58,10 +59,12 @@ int LoadFirmware(LoadFirmwareParams* params) {
return LOAD_FIRMWARE_RECOVERY; return LOAD_FIRMWARE_RECOVERY;
} }
/* Parse flags */
is_dev = (params->boot_flags & BOOT_FLAG_DEVELOPER ? 1 : 0);
/* Initialize the TPM and read rollback indices. */ /* Initialize the TPM and read rollback indices. */
VBPERFSTART("VB_TPMI"); VBPERFSTART("VB_TPMI");
status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER, status = RollbackFirmwareSetup(is_dev, &tpm_version);
&tpm_version);
if (0 != status) { if (0 != status) {
VBDEBUG(("Unable to setup TPM and read stored versions.\n")); VBDEBUG(("Unable to setup TPM and read stored versions.\n"));
VBPERFEND("VB_TPMI"); VBPERFEND("VB_TPMI");
@@ -103,6 +106,19 @@ int LoadFirmware(LoadFirmwareParams* params) {
} }
VBPERFEND("VB_VKB"); VBPERFEND("VB_VKB");
/* Check the key block flags against the current boot mode. */
if (!(key_block->key_block_flags &
(is_dev ? KEY_BLOCK_FLAG_DEVELOPER_1 :
KEY_BLOCK_FLAG_DEVELOPER_0))) {
VBDEBUG(("Developer flag mismatch.\n"));
continue;
}
/* RW firmware never runs in recovery mode. */
if (!(key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)) {
VBDEBUG(("Recovery flag mismatch.\n"));
continue;
}
/* Check for rollback of key version. */ /* Check for rollback of key version. */
key_version = key_block->data_key.key_version; key_version = key_block->data_key.key_version;
if (key_version < (tpm_version >> 16)) { if (key_version < (tpm_version >> 16)) {

View File

@@ -146,8 +146,16 @@ int LoadKernel(LoadKernelParams* params) {
return LOAD_KERNEL_INVALID; return LOAD_KERNEL_INVALID;
} }
is_dev = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0);
is_rec = (BOOT_FLAG_RECOVERY & params->boot_flags ? 1 : 0); is_rec = (BOOT_FLAG_RECOVERY & params->boot_flags ? 1 : 0);
if (is_rec || (BOOT_FLAG_DEV_FIRMWARE & params->boot_flags)) {
/* Recovery or developer firmware, so accurately represent the
* state of the developer switch for the purposes of verified boot. */
is_dev = (BOOT_FLAG_DEVELOPER & params->boot_flags ? 1 : 0);
} else {
/* Normal firmware always does a fully verified boot regardless of
* the state of the developer switch. */
is_dev = 0;
}
is_normal = (!is_dev && !is_rec); is_normal = (!is_dev && !is_rec);
/* Clear output params in case we fail */ /* Clear output params in case we fail */

View File

@@ -92,6 +92,9 @@ int VerifyFirmwareDriver_stub(uint8_t* root_key_blob,
p.kernel_sign_key_blob = Malloc(LOAD_FIRMWARE_KEY_BLOB_REC_SIZE); p.kernel_sign_key_blob = Malloc(LOAD_FIRMWARE_KEY_BLOB_REC_SIZE);
p.kernel_sign_key_size = LOAD_FIRMWARE_KEY_BLOB_REC_SIZE; p.kernel_sign_key_size = LOAD_FIRMWARE_KEY_BLOB_REC_SIZE;
/* TODO: YOU NEED TO SET THE BOOT FLAGS SOMEHOW */
p.boot_flags = 0;
/* Call LoadFirmware() */ /* Call LoadFirmware() */
rv = LoadFirmware(&p); rv = LoadFirmware(&p);
if (LOAD_FIRMWARE_SUCCESS == rv) { if (LOAD_FIRMWARE_SUCCESS == rv) {

View File

@@ -144,6 +144,15 @@ int main(int argc, char* argv[]) {
* heap instead of its actual target address in the firmware. */ * heap instead of its actual target address in the firmware. */
lkp.boot_flags |= BOOT_FLAG_SKIP_ADDR_CHECK; lkp.boot_flags |= BOOT_FLAG_SKIP_ADDR_CHECK;
/* If the boot flags are for developer mode, non-recovery, add the dev-type
* firmware bit. LoadKernel() masks off the developer bit if the dev
* firmware bit is absent, to keep normal firmware from verifying dev
* kernels. */
if ((lkp.boot_flags & BOOT_FLAG_DEVELOPER)
&& !(lkp.boot_flags & BOOT_FLAG_RECOVERY)) {
lkp.boot_flags |= BOOT_FLAG_DEV_FIRMWARE;
}
printf("bootflags = %" PRIu64 "\n", lkp.boot_flags); printf("bootflags = %" PRIu64 "\n", lkp.boot_flags);
/* Get image size */ /* Get image size */