/* 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 "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_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;
}
