/* Copyright (c) 2013 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.
 *
 * High-level firmware wrapper API - entry points for kernel selection
 */

#include "sysincludes.h"

#include "gbb_header.h"
#include "load_kernel_fw.h"
#include "rollback_index.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_audio.h"
#include "vboot_common.h"
#include "vboot_display.h"
#include "vboot_kernel.h"
#include "vboot_nvstorage.h"

/* Global variables */
static VbNvContext vnc;

#ifdef CHROMEOS_ENVIRONMENT
/* Global variable accessor for unit tests */

VbNvContext *VbApiKernelGetVnc(void)
{
	return &vnc;
}
#endif

/**
 * Set recovery request (called from vboot_api_kernel.c functions only)
 */
static void VbSetRecoveryRequest(uint32_t recovery_request)
{
	VBDEBUG(("VbSetRecoveryRequest(%d)\n", (int)recovery_request));
	VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, recovery_request);
}

/**
 * Attempt loading a kernel from the specified type(s) of disks.
 *
 * If successful, sets p->disk_handle to the disk for the kernel and returns
 * VBERROR_SUCCESS.
 *
 * Returns VBERROR_NO_DISK_FOUND if no disks of the specified type were found.
 *
 * May return other VBERROR_ codes for other failures.
 */
uint32_t VbTryLoadKernel(VbCommonParams *cparams, LoadKernelParams *p,
                         uint32_t get_info_flags)
{
	VbError_t retval = VBERROR_UNKNOWN;
	VbDiskInfo* disk_info = NULL;
	uint32_t disk_count = 0;
	uint32_t i;

	VBDEBUG(("VbTryLoadKernel() start, get_info_flags=0x%x\n",
		 (unsigned)get_info_flags));

	p->disk_handle = NULL;

	/* Find disks */
	if (VBERROR_SUCCESS != VbExDiskGetInfo(&disk_info, &disk_count,
					       get_info_flags))
		disk_count = 0;

	VBDEBUG(("VbTryLoadKernel() found %d disks\n", (int)disk_count));
	if (0 == disk_count) {
		VbSetRecoveryRequest(VBNV_RECOVERY_RW_NO_DISK);
		return VBERROR_NO_DISK_FOUND;
	}

	/* Loop over disks */
	for (i = 0; i < disk_count; i++) {
		VBDEBUG(("VbTryLoadKernel() trying disk %d\n", (int)i));
		/*
		 * Sanity-check what we can. FWIW, VbTryLoadKernel() is always
		 * called with only a single bit set in get_info_flags.
		 *
		 * Ensure 512-byte sectors and non-trivially sized disk (for
		 * cgptlib) and that we got a partition with only the flags we
		 * asked for.
		 */
		if (512 != disk_info[i].bytes_per_lba ||
		    32 > disk_info[i].lba_count ||
		    get_info_flags != disk_info[i].flags) {
			VBDEBUG(("  skipping: bytes_per_lba=%lld "
				 "lba_count=%lld flags=0x%x\n",
				 disk_info[i].bytes_per_lba,
				 disk_info[i].lba_count,
				 disk_info[i].flags));
			continue;
		}
		p->disk_handle = disk_info[i].handle;
		p->bytes_per_lba = disk_info[i].bytes_per_lba;
		p->ending_lba = disk_info[i].lba_count - 1;
		retval = LoadKernel(p);
		VBDEBUG(("VbTryLoadKernel() LoadKernel() = %d\n", retval));

		/*
		 * Stop now if we found a kernel.
		 *
		 * TODO: If recovery requested, should track the farthest we
		 * get, instead of just returning the value from the last disk
		 * attempted.
		 */
		if (VBERROR_SUCCESS == retval)
			break;
	}

	/* If we didn't find any good kernels, don't return a disk handle. */
	if (VBERROR_SUCCESS != retval) {
		VbSetRecoveryRequest(VBNV_RECOVERY_RW_NO_KERNEL);
		p->disk_handle = NULL;
	}

	VbExDiskFreeInfo(disk_info, p->disk_handle);

	/*
	 * Pass through return code.  Recovery reason (if any) has already been
	 * set by LoadKernel().
	 */
	return retval;
}

#define CONFIRM_KEY_DELAY 20  /* Check confirm screen keys every 20ms */

int VbUserConfirms(VbCommonParams *cparams, int space_means_no)
{
	uint32_t key;

	VBDEBUG(("Entering %s(%d)\n", __func__, space_means_no));

	/* Await further instructions */
	while (1) {
		if (VbExIsShutdownRequested())
			return -1;
		key = VbExKeyboardRead();
		switch (key) {
		case '\r':
			VBDEBUG(("%s() - Yes (1)\n", __func__));
			return 1;
			break;
		case ' ':
			VBDEBUG(("%s() - Space (%s)\n", __func__,
				 space_means_no));
			if (space_means_no)
				return 0;
			break;
		case 0x1b:
			VBDEBUG(("%s() - No (0)\n", __func__));
			return 0;
			break;
		default:
			VbCheckDisplayKey(cparams, key, &vnc);
		}
		VbExSleepMs(CONFIRM_KEY_DELAY);
	}

	/* Not reached, but compiler will complain without it */
	return -1;
}

VbError_t VbBootNormal(VbCommonParams *cparams, LoadKernelParams *p)
{
	/* Boot from fixed disk only */
	VBDEBUG(("Entering %s()\n", __func__));
	return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED);
}

VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
{
	GoogleBinaryBlockHeader *gbb =
		(GoogleBinaryBlockHeader *)cparams->gbb_data;
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	uint32_t allow_usb = 0, allow_legacy = 0;
	VbAudioContext *audio = 0;

	VBDEBUG(("Entering %s()\n", __func__));

	/* Check if USB booting is allowed */
	VbNvGet(&vnc, VBNV_DEV_BOOT_USB, &allow_usb);
	VbNvGet(&vnc, VBNV_DEV_BOOT_LEGACY, &allow_legacy);

	/* Handle GBB flag override */
	if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_USB)
		allow_usb = 1;
	if (gbb->flags & GBB_FLAG_FORCE_DEV_BOOT_LEGACY)
		allow_legacy = 1;

	/* Show the dev mode warning screen */
	VbDisplayScreen(cparams, VB_SCREEN_DEVELOPER_WARNING, 0, &vnc);

	/* Get audio/delay context */
	audio = VbAudioOpen(cparams);

	/* We'll loop until we finish the delay or are interrupted */
	do {
		uint32_t key;

		if (VbExIsShutdownRequested()) {
			VBDEBUG(("VbBootDeveloper() - shutdown requested!\n"));
			VbAudioClose(audio);
			return VBERROR_SHUTDOWN_REQUESTED;
		}

		key = VbExKeyboardRead();
		switch (key) {
		case 0:
			/* nothing pressed */
			break;
		case '\r':
			/* Only disable virtual dev switch if allowed by GBB */
			if (!(gbb->flags & GBB_FLAG_ENTER_TRIGGERS_TONORM))
				break;
		case ' ':
			/* See if we should disable virtual dev-mode switch. */
			VBDEBUG(("%s shared->flags=0x%x\n",
				 __func__, shared->flags));
			if (shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
			    shared->flags & VBSD_BOOT_DEV_SWITCH_ON) {
				/* Stop the countdown while we go ask... */
				VbAudioClose(audio);
				if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) {
					/*
					 * TONORM won't work (only for
					 * non-shipping devices).
					 */
					VBDEBUG(("%s() - TONORM rejected by "
						 "FORCE_DEV_SWITCH_ON\n",
						 __func__));
					VbExDisplayDebugInfo(
						"WARNING: TONORM prohibited by "
						"GBB FORCE_DEV_SWITCH_ON.\n\n");
					VbExBeep(120, 400);
					break;
				}
				VbDisplayScreen(cparams,
						VB_SCREEN_DEVELOPER_TO_NORM,
						0, &vnc);
				/* Ignore space in VbUserConfirms()... */
				switch (VbUserConfirms(cparams, 0)) {
				case 1:
					VBDEBUG(("%s() - leaving dev-mode.\n",
						 __func__));
					VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST,
						1);
					VbDisplayScreen(
						cparams,
						VB_SCREEN_TO_NORM_CONFIRMED,
						0, &vnc);
					VbExSleepMs(5000);
					return VBERROR_TPM_REBOOT_REQUIRED;
				case -1:
					VBDEBUG(("%s() - shutdown requested\n",
						 __func__));
					return VBERROR_SHUTDOWN_REQUESTED;
				default:
					/* Stay in dev-mode */
					VBDEBUG(("%s() - stay in dev-mode\n",
						 __func__));
					VbDisplayScreen(
						cparams,
						VB_SCREEN_DEVELOPER_WARNING,
						0, &vnc);
					/* Start new countdown */
					audio = VbAudioOpen(cparams);
				}
			} else {
				/*
				 * No virtual dev-mode switch, so go directly
				 * to recovery mode.
				 */
				VBDEBUG(("%s() - going to recovery\n",
					 __func__));
				VbSetRecoveryRequest(
					VBNV_RECOVERY_RW_DEV_SCREEN);
				VbAudioClose(audio);
				return VBERROR_LOAD_KERNEL_RECOVERY;
			}
			break;
		case 0x04:
			/* Ctrl+D = dismiss warning; advance to timeout */
			VBDEBUG(("VbBootDeveloper() - "
				 "user pressed Ctrl+D; skip delay\n"));
			goto fallout;
			break;
		case 0x0c:
			VBDEBUG(("VbBootDeveloper() - "
				 "user pressed Ctrl+L; Try legacy boot\n"));
			/*
			 * If VbExLegacy() succeeds, it will never return.  If
			 * it returns, beep.
			 */
			if (allow_legacy)
				VbExLegacy();
			else
				VBDEBUG(("VbBootDeveloper() - "
					 "Legacy boot is disabled\n"));

			VbExBeep(120, 400);
			VbExSleepMs(120);
			VbExBeep(120, 400);
			break;

		case VB_KEY_CTRL_ENTER:
			/*
			 * The Ctrl-Enter is special for Lumpy test purpose;
			 * fall through to Ctrl+U handler.
			 */
		case 0x15:
			/* Ctrl+U = try USB boot, or beep if failure */
			VBDEBUG(("VbBootDeveloper() - "
				 "user pressed Ctrl+U; try USB\n"));
			if (!allow_usb) {
				VBDEBUG(("VbBootDeveloper() - "
					 "USB booting is disabled\n"));
				VbExDisplayDebugInfo(
					"WARNING: Booting from external media "
					"(USB/SD) has not been enabled. Refer "
					"to the developer-mode documentation "
					"for details.\n");
				VbExBeep(120, 400);
				VbExSleepMs(120);
				VbExBeep(120, 400);
			} else {
				/*
				 * Clear the screen to show we get the Ctrl+U
				 * key press.
				 */
				VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0,
						&vnc);
				if (VBERROR_SUCCESS ==
				    VbTryLoadKernel(cparams, p,
						    VB_DISK_FLAG_REMOVABLE)) {
					VBDEBUG(("VbBootDeveloper() - "
						 "booting USB\n"));
					VbAudioClose(audio);
					return VBERROR_SUCCESS;
				} else {
					VBDEBUG(("VbBootDeveloper() - "
						 "no kernel found on USB\n"));
					VbExBeep(250, 200);
					VbExSleepMs(120);
					/*
					 * Clear recovery requests from failed
					 * kernel loading, so that powering off
					 * at this point doesn't put us into
					 * recovery mode.
					 */
					VbSetRecoveryRequest(
						VBNV_RECOVERY_NOT_REQUESTED);
					/* Show dev mode warning screen again */
					VbDisplayScreen(
						cparams,
						VB_SCREEN_DEVELOPER_WARNING,
						0, &vnc);
				}
			}
			break;
		default:
			VBDEBUG(("VbBootDeveloper() - pressed key %d\n", key));
			VbCheckDisplayKey(cparams, key, &vnc);
			break;
		}
	} while(VbAudioLooping(audio));

 fallout:
	/* Timeout or Ctrl+D; attempt loading from fixed disk */
	VBDEBUG(("VbBootDeveloper() - trying fixed disk\n"));
	VbAudioClose(audio);
	return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED);
}

/* Delay in recovery mode */
#define REC_DISK_DELAY 1000     /* Check disks every 1s */
#define REC_KEY_DELAY  20       /* Check keys every 20ms */

VbError_t VbBootRecovery(VbCommonParams *cparams, LoadKernelParams *p)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	uint32_t retval;
	uint32_t key;
	int i;

	VBDEBUG(("VbBootRecovery() start\n"));

	/*
	 * If the dev-mode switch is off and the user didn't press the recovery
	 * button, require removal of all external media.
	 */
	if (!(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
	    !(shared->flags & VBSD_BOOT_REC_SWITCH_ON)) {
		VbDiskInfo *disk_info = NULL;
		uint32_t disk_count = 0;

		VBDEBUG(("VbBootRecovery() forcing device removal\n"));

		while (1) {
			if (VBERROR_SUCCESS !=
			    VbExDiskGetInfo(&disk_info, &disk_count,
					    VB_DISK_FLAG_REMOVABLE))
				disk_count = 0;

			VbExDiskFreeInfo(disk_info, NULL);

			if (0 == disk_count) {
				VbDisplayScreen(cparams, VB_SCREEN_BLANK,
						0, &vnc);
				break;
			}

			VBDEBUG(("VbBootRecovery() "
				 "waiting for %d disks to be removed\n",
				 (int)disk_count));

			VbDisplayScreen(cparams, VB_SCREEN_RECOVERY_REMOVE,
					0, &vnc);

			/*
			 * Scan keyboard more frequently than media, since x86
			 * platforms don't like to scan USB too rapidly.
			 */
			for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
				VbCheckDisplayKey(cparams, VbExKeyboardRead(),
						  &vnc);
				if (VbExIsShutdownRequested())
					return VBERROR_SHUTDOWN_REQUESTED;
				VbExSleepMs(REC_KEY_DELAY);
			}
		}
	}

	/* Loop and wait for a recovery image */
	while (1) {
		VBDEBUG(("VbBootRecovery() attempting to load kernel2\n"));
		retval = VbTryLoadKernel(cparams, p, VB_DISK_FLAG_REMOVABLE);

		/*
		 * Clear recovery requests from failed kernel loading, since
		 * we're already in recovery mode.  Do this now, so that
		 * powering off after inserting an invalid disk doesn't leave
		 * us stuck in recovery mode.
		 */
		VbSetRecoveryRequest(VBNV_RECOVERY_NOT_REQUESTED);

		if (VBERROR_SUCCESS == retval)
			break; /* Found a recovery kernel */

		VbDisplayScreen(cparams, VBERROR_NO_DISK_FOUND == retval ?
				VB_SCREEN_RECOVERY_INSERT :
				VB_SCREEN_RECOVERY_NO_GOOD,
				0, &vnc);

		/*
		 * Scan keyboard more frequently than media, since x86
		 * platforms don't like to scan USB too rapidly.
		 */
		for (i = 0; i < REC_DISK_DELAY; i += REC_KEY_DELAY) {
			key = VbExKeyboardRead();
			/*
			 * We might want to enter dev-mode from the Insert
			 * screen if all of the following are true:
			 *   - user pressed Ctrl-D
			 *   - we can honor the virtual dev switch
			 *   - not already in dev mode
			 *   - user forced recovery mode
			 *   - EC isn't pwned
			 */
			if (key == 0x04 &&
			    shared->flags & VBSD_HONOR_VIRT_DEV_SWITCH &&
			    !(shared->flags & VBSD_BOOT_DEV_SWITCH_ON) &&
			    (shared->flags & VBSD_BOOT_REC_SWITCH_ON) &&
			    VbExTrustEC()) {
				/* Ask the user to confirm entering dev-mode */
				VbDisplayScreen(cparams,
						VB_SCREEN_RECOVERY_TO_DEV,
						0, &vnc);
				/* SPACE means no... */
				switch (VbUserConfirms(cparams, 1)) {
				case 1:
					VBDEBUG(("%s() Enabling dev-mode...\n",
						 __func__));
					if (TPM_SUCCESS != SetVirtualDevMode(1))
						return VBERROR_TPM_SET_BOOT_MODE_STATE;
					VBDEBUG(("%s() Reboot so it will take "
						 "effect\n", __func__));
					return VBERROR_TPM_REBOOT_REQUIRED;
				case -1:
					VBDEBUG(("%s() - Shutdown requested\n",
						 __func__));
					return VBERROR_SHUTDOWN_REQUESTED;
				default: /* zero, actually */
					VBDEBUG(("%s() - Not enabling "
						 "dev-mode\n", __func__));
					/*
					 * Jump out of the outer loop to
					 * refresh the display quickly.
					 */
					i = 4;
					break;
				}
			} else {
				VbCheckDisplayKey(cparams, key, &vnc);
			}
			if (VbExIsShutdownRequested())
				return VBERROR_SHUTDOWN_REQUESTED;
			VbExSleepMs(REC_KEY_DELAY);
		}
	}

	return VBERROR_SUCCESS;
}

/**
 * Wrapper around VbExEcProtectRW() which sets recovery reason on error.
 */
static VbError_t EcProtectRW(void)
{
	int rv = VbExEcProtectRW();

	if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
		VBDEBUG(("VbExEcProtectRW() needs reboot\n"));
	} else if (rv != VBERROR_SUCCESS) {
		VBDEBUG(("VbExEcProtectRW() returned %d\n", rv));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_PROTECT);
	}
	return rv;
}

VbError_t VbEcSoftwareSync(VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	int in_rw = 0;
	int rv;
	const uint8_t *ec_hash = NULL;
	int ec_hash_size;
	const uint8_t *rw_hash = NULL;
	int rw_hash_size;
	const uint8_t *expected = NULL;
	int expected_size;
	uint8_t expected_hash[SHA256_DIGEST_SIZE];
	int need_update = 0;
	int i;

	/* Determine whether the EC is in RO or RW */
	rv = VbExEcRunningRW(&in_rw);

	if (shared->recovery_reason) {
		/* Recovery mode; just verify the EC is in RO code */
		if (rv == VBERROR_SUCCESS && in_rw == 1) {
			/*
			 * EC is definitely in RW firmware.  We want it in
			 * read-only code, so preserve the current recovery
			 * reason and reboot.
			 *
			 * We don't reboot on error or unknown EC code, because
			 * we could end up in an endless reboot loop.  If we
			 * had some way to track that we'd already rebooted for
			 * this reason, we could retry only once.
			 */
			VBDEBUG(("VbEcSoftwareSync() - "
				 "want recovery but got EC-RW\n"));
			VbSetRecoveryRequest(shared->recovery_reason);
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}

		VBDEBUG(("VbEcSoftwareSync() in recovery; EC-RO\n"));
		return VBERROR_SUCCESS;
	}

	/*
	 * Not in recovery.  If we couldn't determine where the EC was,
	 * reboot to recovery.
	 */
	if (rv != VBERROR_SUCCESS) {
		VBDEBUG(("VbEcSoftwareSync() - "
			 "VbEcEcRunningRW() returned %d\n", rv));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_UNKNOWN_IMAGE);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	/* If AP is read-only normal, EC should be in its RO code also. */
	if (shared->flags & VBSD_LF_USE_RO_NORMAL) {
		/* If EC is in RW code, request reboot back to RO */
		if (in_rw == 1) {
			VBDEBUG(("VbEcSoftwareSync() - "
				 "want RO-normal but got EC-RW\n"));
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}

		/* Protect the RW flash and stay in EC-RO */
		rv = EcProtectRW();
		if (rv != VBERROR_SUCCESS)
			return rv;

		rv = VbExEcStayInRO();
		if (rv != VBERROR_SUCCESS) {
			VBDEBUG(("VbEcSoftwareSync() - "
				 "VbExEcStayInRO() returned %d\n", rv));
			VbSetRecoveryRequest(VBNV_RECOVERY_EC_SOFTWARE_SYNC);
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}

		VBDEBUG(("VbEcSoftwareSync() in RO-Normal; EC-RO\n"));

		/*
		 * If shutdown is requested, just power the AP back off.  This
		 * covers the case where the lid is closed when then system
		 * boots.
		 */
		if (VbExIsShutdownRequested()) {
			VBDEBUG(("VbEcSoftwareSync() "
				 "sees shutdown-requested\n"));
			return VBERROR_SHUTDOWN_REQUESTED;
		}

		return VBERROR_SUCCESS;
	}

	/* Get hash of EC-RW */
	rv = VbExEcHashRW(&ec_hash, &ec_hash_size);
	if (rv) {
		VBDEBUG(("VbEcSoftwareSync() - "
			 "VbExEcHashRW() returned %d\n", rv));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_HASH_FAILED);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}
	if (ec_hash_size != SHA256_DIGEST_SIZE) {
		VBDEBUG(("VbEcSoftwareSync() - "
			 "VbExEcHashRW() says size %d, not %d\n",
			 ec_hash_size, SHA256_DIGEST_SIZE));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_HASH_SIZE);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	VBDEBUG(("EC hash:"));
	for (i = 0; i < SHA256_DIGEST_SIZE; i++)
		VBDEBUG(("%02x", ec_hash[i]));
	VBDEBUG(("\n"));

	/*
	 * Get expected EC-RW hash. Note that we've already checked for
	 * RO_NORMAL, so we know that the BIOS must be RW-A or RW-B, and
	 * therefore the EC must match.
	 */
	rv = VbExEcGetExpectedRWHash(shared->firmware_index ?
				 VB_SELECT_FIRMWARE_B : VB_SELECT_FIRMWARE_A,
				 &rw_hash, &rw_hash_size);

	if (rv == VBERROR_EC_GET_EXPECTED_HASH_FROM_IMAGE) {
		/*
		 * BIOS has verified EC image but doesn't have a precomputed
		 * hash for it, so we must compute the hash ourselves.
		 */
		rw_hash = NULL;
	} else if (rv) {
		VBDEBUG(("VbEcSoftwareSync() - "
			 "VbExEcGetExpectedRWHash() returned %d\n", rv));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_EXPECTED_HASH);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	} else if (rw_hash_size != SHA256_DIGEST_SIZE) {
		VBDEBUG(("VbEcSoftwareSync() - "
			 "VbExEcGetExpectedRWHash() says size %d, not %d\n",
			 rw_hash_size, SHA256_DIGEST_SIZE));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_EXPECTED_HASH);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	} else {
		VBDEBUG(("Expected hash:"));
		for (i = 0; i < SHA256_DIGEST_SIZE; i++)
			VBDEBUG(("%02x", rw_hash[i]));
		VBDEBUG(("\n"));

		need_update = SafeMemcmp(ec_hash, rw_hash, SHA256_DIGEST_SIZE);
	}

	/*
	 * Get expected EC-RW image if we're sure we need to update (because the
	 * expected hash didn't match the EC) or we still don't know (because
	 * there was no expected hash and we need the image to compute one
	 * ourselves).
	 */
	if (need_update || !rw_hash) {
		/* Get expected EC-RW image */
		rv = VbExEcGetExpectedRW(shared->firmware_index ?
					 VB_SELECT_FIRMWARE_B :
					 VB_SELECT_FIRMWARE_A,
					 &expected, &expected_size);
		if (rv) {
			VBDEBUG(("VbEcSoftwareSync() - "
				 "VbExEcGetExpectedRW() returned %d\n", rv));
			VbSetRecoveryRequest(VBNV_RECOVERY_EC_EXPECTED_IMAGE);
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}
		VBDEBUG(("VbEcSoftwareSync() - expected len = %d\n",
			 expected_size));

		/* Hash expected image */
		internal_SHA256(expected, expected_size, expected_hash);
		VBDEBUG(("Computed hash of expected image:"));
		for (i = 0; i < SHA256_DIGEST_SIZE; i++)
			VBDEBUG(("%02x", expected_hash[i]));
		VBDEBUG(("\n"));
	}

	if (!rw_hash) {
		/*
		 * BIOS didn't have expected EC hash, so check if we need
		 * update by comparing EC hash to the one we just computed.
		 */
		need_update = SafeMemcmp(ec_hash, expected_hash,
					 SHA256_DIGEST_SIZE);
	} else if (need_update &&
		   SafeMemcmp(rw_hash, expected_hash, SHA256_DIGEST_SIZE)) {
		/*
		 * We need to update, but the expected EC image doesn't match
		 * the expected EC hash we were given.
		 */
		VBDEBUG(("VbEcSoftwareSync() - "
			 "VbExEcGetExpectedRW() returned %d\n", rv));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_HASH_MISMATCH);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	/*
	 * TODO: GBB flag to override whether we need update; needed for EC
	 * development.
	 */

	if (in_rw) {
		if (need_update) {
			/*
			 * EC is running the wrong RW image.  Reboot the EC to
			 * RO so we can update it on the next boot.
			 */
			VBDEBUG(("VbEcSoftwareSync() - "
				 "in RW, need to update RW, so reboot\n"));
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}

		VBDEBUG(("VbEcSoftwareSync() in EC-RW and it matches\n"));

		/*
		 * If shutdown is requested, just power the AP back off.  This
		 * covers the case where the lid is closed when then system
		 * boots.
		 */
		if (VbExIsShutdownRequested()) {
			VBDEBUG(("VbEcSoftwareSync() "
				 "sees shutdown-requested\n"));
			return VBERROR_SHUTDOWN_REQUESTED;
		}

		return VBERROR_SUCCESS;
	}

	/* Update EC if necessary */
	if (need_update) {
		VBDEBUG(("VbEcSoftwareSync() updating EC-RW...\n"));

		if (shared->flags & VBSD_EC_SLOW_UPDATE) {
			VBDEBUG(("VbEcSoftwareSync() - "
				 "EC is slow. Show WAIT screen.\n"));
			/*
			 * FIXME(crosbug.com/p/12257): Ensure the VGA Option
			 * ROM is loaded!
			 */
			VbDisplayScreen(cparams, VB_SCREEN_WAIT, 0, &vnc);
		}

		rv = VbExEcUpdateRW(expected, expected_size);
		if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
			/*
			 * Reboot required.  May need to unprotect RW before
			 * updating, or may need to reboot after RW updated.
			 * Either way, it's not an error requiring recovery
			 * mode.
			 */
			VBDEBUG(("VbEcSoftwareSync() - "
				 "VbExEcUpdateRW() needs reboot\n"));
			return rv;
		} else if (rv != VBERROR_SUCCESS) {
			VBDEBUG(("VbEcSoftwareSync() - "
				 "VbExEcUpdateRW() returned %d\n", rv));
			VbSetRecoveryRequest(VBNV_RECOVERY_EC_UPDATE);
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}

		/*
		 * TODO: should ask EC to recompute its hash to verify it's
		 * correct before continuing?
		 */
	}

	/* Protect EC-RW flash */
	rv = EcProtectRW();
	if (rv != VBERROR_SUCCESS)
		return rv;

	/* Tell EC to jump to its RW image */
	VBDEBUG(("VbEcSoftwareSync() jumping to EC-RW\n"));
	rv = VbExEcJumpToRW();
	if (rv != VBERROR_SUCCESS) {
		VBDEBUG(("VbEcSoftwareSync() - "
			 "VbExEcJumpToRW() returned %d\n", rv));
		VbSetRecoveryRequest(VBNV_RECOVERY_EC_JUMP_RW);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	VBDEBUG(("VbEcSoftwareSync() in RW; done\n"));

	/*
	 * If shutdown is requested, just power the AP back off.  This covers
	 * the case where the lid is closed when then system boots.
	 */
	if (VbExIsShutdownRequested()) {
		VBDEBUG(("VbEcSoftwareSync() sees shutdown-requested\n"));
		return VBERROR_SHUTDOWN_REQUESTED;
	}

	return VBERROR_SUCCESS;
}

VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
                                VbSelectAndLoadKernelParams *kparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	VbError_t retval = VBERROR_SUCCESS;
	LoadKernelParams p;
	uint32_t tpm_status = 0;

	/* Start timer */
	shared->timer_vb_select_and_load_kernel_enter = VbExGetTimer();

	VbExNvStorageRead(vnc.raw);
	VbNvSetup(&vnc);

	/* Clear output params in case we fail */
	kparams->disk_handle = NULL;
	kparams->partition_number = 0;
	kparams->bootloader_address = 0;
	kparams->bootloader_size = 0;
	Memset(kparams->partition_guid, 0, sizeof(kparams->partition_guid));

	/* Do EC software sync if necessary */
	if (shared->flags & VBSD_EC_SOFTWARE_SYNC) {
		retval = VbEcSoftwareSync(cparams);
		if (retval != VBERROR_SUCCESS)
			goto VbSelectAndLoadKernel_exit;
	}

	/* Read kernel version from the TPM.  Ignore errors in recovery mode. */
	tpm_status = RollbackKernelRead(&shared->kernel_version_tpm);
	if (0 != tpm_status) {
		VBDEBUG(("Unable to get kernel versions from TPM\n"));
		if (!shared->recovery_reason) {
			VbSetRecoveryRequest(VBNV_RECOVERY_RW_TPM_R_ERROR);
			retval = VBERROR_TPM_READ_KERNEL;
			goto VbSelectAndLoadKernel_exit;
		}
	}
	shared->kernel_version_tpm_start = shared->kernel_version_tpm;

	/* Fill in params for calls to LoadKernel() */
	Memset(&p, 0, sizeof(p));
	p.shared_data_blob = cparams->shared_data_blob;
	p.shared_data_size = cparams->shared_data_size;
	p.gbb_data = cparams->gbb_data;
	p.gbb_size = cparams->gbb_size;

	/*
	 * This could be set to NULL, in which case the vboot header
	 * information about the load address and size will be used.
	 */
	p.kernel_buffer = kparams->kernel_buffer;
	p.kernel_buffer_size = kparams->kernel_buffer_size;

	p.nv_context = &vnc;
	p.boot_flags = 0;
	if (shared->flags & VBSD_BOOT_DEV_SWITCH_ON)
		p.boot_flags |= BOOT_FLAG_DEVELOPER;

	/* Handle separate normal and developer firmware builds. */
#if defined(VBOOT_FIRMWARE_TYPE_NORMAL)
	/* Normal-type firmware always acts like the dev switch is off. */
	p.boot_flags &= ~BOOT_FLAG_DEVELOPER;
#elif defined(VBOOT_FIRMWARE_TYPE_DEVELOPER)
	/* Developer-type firmware fails if the dev switch is off. */
	if (!(p.boot_flags & BOOT_FLAG_DEVELOPER)) {
		/*
		 * Dev firmware should be signed with a key that only verifies
		 * when the dev switch is on, so we should never get here.
		 */
		VBDEBUG(("Developer firmware called with dev switch off!\n"));
		VbSetRecoveryRequest(VBNV_RECOVERY_RW_DEV_MISMATCH);
		retval = VBERROR_DEV_FIRMWARE_SWITCH_MISMATCH;
		goto VbSelectAndLoadKernel_exit;
	}
#else
	/*
	 * Recovery firmware, or merged normal+developer firmware.  No need to
	 * override flags.
	 */
#endif

	/* Select boot path */
	if (shared->recovery_reason) {
		/* Recovery boot */
		p.boot_flags |= BOOT_FLAG_RECOVERY;
		retval = VbBootRecovery(cparams, &p);
		VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0, &vnc);

	} else if (p.boot_flags & BOOT_FLAG_DEVELOPER) {
		/* Developer boot */
		retval = VbBootDeveloper(cparams, &p);
		VbDisplayScreen(cparams, VB_SCREEN_BLANK, 0, &vnc);

	} else {
		/* Normal boot */
		retval = VbBootNormal(cparams, &p);

		if ((1 == shared->firmware_index) &&
		    (shared->flags & VBSD_FWB_TRIED)) {
			/*
			 * Special cases for when we're trying a new firmware
			 * B.  These are needed because firmware updates also
			 * usually change the kernel key, which means that the
			 * B firmware can only boot a new kernel, and the old
			 * firmware in A can only boot the previous kernel.
			 *
			 * Don't advance the TPM if we're trying a new firmware
			 * B, because we don't yet know if the new kernel will
			 * successfully boot.  We still want to be able to fall
			 * back to the previous firmware+kernel if the new
			 * firmware+kernel fails.
			 *
			 * If we found only invalid kernels, reboot and try
			 * again.  This allows us to fall back to the previous
			 * firmware+kernel instead of giving up and going to
			 * recovery mode right away.  We'll still go to
			 * recovery mode if we run out of tries and the old
			 * firmware can't find a kernel it likes.
			 */
			if (VBERROR_INVALID_KERNEL_FOUND == retval) {
				VBDEBUG(("Trying firmware B, "
					 "and only found invalid kernels.\n"));
				VbSetRecoveryRequest(VBNV_RECOVERY_NOT_REQUESTED);
				goto VbSelectAndLoadKernel_exit;
			}
		} else {
			/* Not trying a new firmware B. */

			/* See if we need to update the TPM. */
			VBDEBUG(("Checking if TPM kernel version needs "
				 "advancing\n"));
			if (shared->kernel_version_tpm >
			    shared->kernel_version_tpm_start) {
				tpm_status = RollbackKernelWrite(
						shared->kernel_version_tpm);
				if (0 != tpm_status) {
					VBDEBUG(("Error writing kernel "
						 "versions to TPM.\n"));
					VbSetRecoveryRequest(VBNV_RECOVERY_RW_TPM_W_ERROR);
					retval = VBERROR_TPM_WRITE_KERNEL;
					goto VbSelectAndLoadKernel_exit;
				}
			}
		}
	}

	if (VBERROR_SUCCESS != retval)
		goto VbSelectAndLoadKernel_exit;

	/* Save disk parameters */
	kparams->disk_handle = p.disk_handle;
	kparams->partition_number = (uint32_t)p.partition_number;
	kparams->bootloader_address = p.bootloader_address;
	kparams->bootloader_size = (uint32_t)p.bootloader_size;
	Memcpy(kparams->partition_guid, p.partition_guid,
	       sizeof(kparams->partition_guid));

	/* Lock the kernel versions.  Ignore errors in recovery mode. */
	tpm_status = RollbackKernelLock();
	if (0 != tpm_status) {
		VBDEBUG(("Error locking kernel versions.\n"));
		if (!shared->recovery_reason) {
			VbSetRecoveryRequest(VBNV_RECOVERY_RW_TPM_L_ERROR);
			retval = VBERROR_TPM_LOCK_KERNEL;
			goto VbSelectAndLoadKernel_exit;
		}
	}

 VbSelectAndLoadKernel_exit:

	VbNvTeardown(&vnc);
	if (vnc.raw_changed)
		VbExNvStorageWrite(vnc.raw);

	/* Stop timer */
	shared->timer_vb_select_and_load_kernel_exit = VbExGetTimer();

	kparams->kernel_buffer = p.kernel_buffer;
	kparams->kernel_buffer_size = p.kernel_buffer_size;

	VBDEBUG(("VbSelectAndLoadKernel() returning %d\n", (int)retval));

	/* Pass through return value from boot path */
	return retval;
}
