/* 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.
 *
 * Display functions used in kernel selection.
 */

#include "bmpblk_font.h"
#include "gbb_header.h"
#include "utility.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_display.h"
#include "vboot_nvstorage.h"

static uint32_t disp_current_screen = VB_SCREEN_BLANK;
static uint32_t disp_width = 0, disp_height = 0;

VbError_t VbGetLocalizationCount(VbCommonParams *cparams, uint32_t *count)
{
	GoogleBinaryBlockHeader *gbb =
		(GoogleBinaryBlockHeader *)cparams->gbb_data;
	BmpBlockHeader *hdr;

	/* Default to 0 on error */
	*count = 0;

	/* Make sure bitmap data is inside the GBB and is non-zero in size */
	if (0 == gbb->bmpfv_size ||
	    gbb->bmpfv_offset > cparams->gbb_size ||
	    gbb->bmpfv_offset + gbb->bmpfv_size > cparams->gbb_size) {
		return VBERROR_INVALID_GBB;
	}

	/* Sanity-check the bitmap block header */
	hdr = (BmpBlockHeader *)(((uint8_t *)gbb) + gbb->bmpfv_offset);
	if ((0 != Memcmp(hdr->signature, BMPBLOCK_SIGNATURE,
			 BMPBLOCK_SIGNATURE_SIZE)) ||
	    (hdr->major_version > BMPBLOCK_MAJOR_VERSION) ||
	    ((hdr->major_version == BMPBLOCK_MAJOR_VERSION) &&
	     (hdr->minor_version > BMPBLOCK_MINOR_VERSION))) {
		return VBERROR_INVALID_BMPFV;
	}

	*count = hdr->number_of_localizations;
	return VBERROR_SUCCESS;
}

char *VbHWID(VbCommonParams *cparams)
{
	GoogleBinaryBlockHeader *gbb =
		(GoogleBinaryBlockHeader *)cparams->gbb_data;

	if (0 == gbb->hwid_size ||
	    gbb->hwid_offset > cparams->gbb_size ||
	    gbb->hwid_offset + gbb->hwid_size > cparams->gbb_size) {
		VBDEBUG(("VbHWID(): invalid hwid offset/size\n"));
		return "{INVALID}";
	}

	return (char *)((uint8_t *)gbb + gbb->hwid_offset);
}

/*
 * TODO: We could cache the font info to speed things up, by making the
 * in-memory font structure distinct from the in-flash version.  We'll do that
 * Real Soon Now. Until then, we just repeat the same linear search every time.
 */
typedef FontArrayHeader VbFont_t;

static VbFont_t *VbInternalizeFontData(FontArrayHeader *fonthdr)
{
	/* Just return the raw data pointer for now. */
	return (VbFont_t *)fonthdr;
}

static void VbDoneWithFontForNow(VbFont_t *ptr)
{
	/* Nothing. */
}

static ImageInfo *VbFindFontGlyph(VbFont_t *font, uint32_t ascii,
                                  void **bufferptr, uint32_t *buffersize)
{
	uint8_t *ptr, *firstptr;
	uint32_t max;
	uint32_t i;
	FontArrayEntryHeader *entry;

	ptr = (uint8_t *)font;
	max = ((FontArrayHeader *)ptr)->num_entries;
	ptr += sizeof(FontArrayHeader);
	firstptr = ptr;

	/*
	 * Simple linear search.
	 *
	 * Note: We're assuming glpyhs are uncompressed. That's true because
	 * the bmpblk_font tool doesn't compress anything. The bmpblk_utility
	 * does, but it compresses the entire font blob at once, and we've
	 * already uncompressed that before we got here.
	 */
	for(i=0; i<max; i++) {
		entry = (FontArrayEntryHeader *)ptr;
		if (entry->ascii == ascii) {
			*bufferptr = ptr + sizeof(FontArrayEntryHeader);
			*buffersize = entry->info.original_size;
			return &(entry->info);
		}
		ptr += sizeof(FontArrayEntryHeader)+entry->info.compressed_size;
	}

	/*
	 * We must return something valid. We'll just use the first glyph in
	 * the font structure (so it should be something distinct).
	 */
	entry = (FontArrayEntryHeader *)firstptr;
	*bufferptr = firstptr + sizeof(FontArrayEntryHeader);
	*buffersize = entry->info.original_size;
	return &(entry->info);
}

/**
 * Try to display the specified text at a particular position.
 */
static void VbRenderTextAtPos(char *text, int right_to_left,
                              uint32_t x, uint32_t y, VbFont_t *font)
{
	int i;
	ImageInfo *image_info = 0;
	void *buffer;
	uint32_t buffersize;
	uint32_t cur_x = x, cur_y = y;

	if (!text || !font) {
		VBDEBUG(("  VbRenderTextAtPos: invalid args\n"));
		return;
	}

	for (i=0; text[i]; i++) {

		if (text[i] == '\n') {
			if (!image_info)
				image_info = VbFindFontGlyph(font, text[i],
							     &buffer,
							     &buffersize);
			cur_x = x;
			cur_y += image_info->height;
			continue;
		}

		image_info = VbFindFontGlyph(font, text[i], &buffer,
					     &buffersize);

		if (right_to_left)
			cur_x -= image_info->width;

		if (VBERROR_SUCCESS != VbExDisplayImage(cur_x, cur_y, buffer,
							buffersize)) {
			VBDEBUG(("  VbRenderTextAtPos: "
				 "can't display ascii 0x%x\n", text[i]));
		}

		if (!right_to_left)
			cur_x += image_info->width;
	}
}

#define OUTBUF_LEN 128

VbError_t VbDisplayScreenFromGBB(VbCommonParams *cparams, uint32_t screen,
                                 VbNvContext *vncptr)
{
	GoogleBinaryBlockHeader *gbb =
		(GoogleBinaryBlockHeader *)cparams->gbb_data;
	static uint8_t *bmpfv;
	void *fullimage = NULL;
	BmpBlockHeader *hdr;
	ScreenLayout *layout;
	ImageInfo *image_info;
	uint32_t screen_index;
	uint32_t localization = 0;
	VbError_t retval = VBERROR_UNKNOWN;   /* Assume error until proven ok */
	uint32_t inoutsize;
	uint32_t offset;
	uint32_t i;
	VbFont_t *font;
	char *text_to_show;
	int rtol = 0;
	char outbuf[OUTBUF_LEN] = "";
	uint32_t used = 0;

	/* Make sure bitmap data is inside the GBB and is non-zero in size */
	if (0 == gbb->bmpfv_size ||
	    gbb->bmpfv_offset > cparams->gbb_size ||
	    gbb->bmpfv_offset + gbb->bmpfv_size > cparams->gbb_size) {
		VBDEBUG(("VbDisplayScreenFromGBB(): "
			 "invalid bmpfv offset/size\n"));
		return VBERROR_INVALID_GBB;
	}

	/* Copy bitmap data from GBB into RAM for speed */
	if (!bmpfv) {
#ifdef COPY_BMP_DATA
		bmpfv = (uint8_t *)VbExMalloc(gbb->bmpfv_size);
		Memcpy(bmpfv, ((uint8_t *)gbb) + gbb->bmpfv_offset,
		       gbb->bmpfv_size);
#else
		bmpfv = ((uint8_t *)gbb) + gbb->bmpfv_offset;
#endif
	}

	/* Sanity-check the bitmap block header */
	hdr = (BmpBlockHeader *)bmpfv;
	if ((0 != Memcmp(hdr->signature, BMPBLOCK_SIGNATURE,
			 BMPBLOCK_SIGNATURE_SIZE)) ||
	    (hdr->major_version > BMPBLOCK_MAJOR_VERSION) ||
	    ((hdr->major_version == BMPBLOCK_MAJOR_VERSION) &&
	     (hdr->minor_version > BMPBLOCK_MINOR_VERSION))) {
		VBDEBUG(("VbDisplayScreenFromGBB(): "
			 "invalid/too new bitmap header\n"));
		retval = VBERROR_INVALID_BMPFV;
		goto VbDisplayScreenFromGBB_exit;
	}

	/*
	 * Translate screen ID into index.  Note that not all screens are in
	 * the GBB.
	 *
	 * TODO: ensure screen IDs match indices?  Having this translation here
	 * is awful.
	 */
	switch (screen) {
	case VB_SCREEN_DEVELOPER_WARNING:
		screen_index = SCREEN_DEVELOPER_WARNING;
		break;
	case VB_SCREEN_RECOVERY_REMOVE:
		screen_index = SCREEN_RECOVERY_REMOVE;
		break;
	case VB_SCREEN_RECOVERY_NO_GOOD:
		screen_index = SCREEN_RECOVERY_NO_GOOD;
		break;
	case VB_SCREEN_RECOVERY_INSERT:
		screen_index = SCREEN_RECOVERY_INSERT;
		break;
	case VB_SCREEN_RECOVERY_TO_DEV:
		screen_index = SCREEN_RECOVERY_TO_DEV;
		break;
	case VB_SCREEN_DEVELOPER_TO_NORM:
		screen_index = SCREEN_DEVELOPER_TO_NORM;
		break;
	case VB_SCREEN_WAIT:
		screen_index = SCREEN_WAIT;
		break;
	case VB_SCREEN_TO_NORM_CONFIRMED:
		screen_index = SCREEN_TO_NORM_CONFIRMED;
		break;
	case VB_SCREEN_BLANK:
	case VB_SCREEN_DEVELOPER_EGG:
	default:
		/* Screens which aren't in the GBB */
		VBDEBUG(("VbDisplayScreenFromGBB(): screen %d not in the GBB\n",
			 (int)screen));
		retval = VBERROR_INVALID_SCREEN_INDEX;
		goto VbDisplayScreenFromGBB_exit;
	}

	if (screen_index >= hdr->number_of_screenlayouts) {
		VBDEBUG(("VbDisplayScreenFromGBB(): "
			 "screen %d index %d not in the GBB\n",
			 (int)screen, (int)screen_index));
		retval = VBERROR_INVALID_SCREEN_INDEX;
		goto VbDisplayScreenFromGBB_exit;
	}

	/* Clip localization to number of localizations present in the GBB */
	VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &localization);
	if (localization >= hdr->number_of_localizations) {
		localization = 0;
		VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, localization);
	}

	/*
	 * Calculate offset of screen layout = start of screen stuff + correct
	 * locale + correct screen.
	 */
	offset = sizeof(BmpBlockHeader) +
		localization * hdr->number_of_screenlayouts *
			sizeof(ScreenLayout) +
		screen_index * sizeof(ScreenLayout);
	layout = (ScreenLayout *)(bmpfv + offset);

	/* Display all bitmaps for the image */
	for (i = 0; i < MAX_IMAGE_IN_LAYOUT; i++) {
		if (!layout->images[i].image_info_offset)
			continue;

		offset = layout->images[i].image_info_offset;
		image_info = (ImageInfo *)(bmpfv + offset);
		fullimage = bmpfv + offset + sizeof(ImageInfo);
		inoutsize = image_info->original_size;
		if (inoutsize &&
		    image_info->compression != COMPRESS_NONE) {
			fullimage = VbExMalloc(inoutsize);
			retval = VbExDecompress(
					bmpfv + offset + sizeof(ImageInfo),
					image_info->compressed_size,
					image_info->compression,
					fullimage, &inoutsize);
			if (VBERROR_SUCCESS != retval) {
				VbExFree(fullimage);
				goto VbDisplayScreenFromGBB_exit;
			}
		}

		switch(image_info->format) {
		case FORMAT_BMP:
			retval = VbExDisplayImage(layout->images[i].x,
						  layout->images[i].y,
						  fullimage, inoutsize);
			break;

		case FORMAT_FONT:
			/*
			 * The uncompressed blob is our font structure. Cache
			 * it as needed.
			 */
			font = VbInternalizeFontData(fullimage);

			/* TODO: handle text in general here */
			if (TAG_HWID == image_info->tag ||
			    TAG_HWID_RTOL == image_info->tag) {
				text_to_show = VbHWID(cparams);
				rtol = (TAG_HWID_RTOL == image_info->tag);
			} else {
				text_to_show = "";
				rtol = 0;
			}

			VbRenderTextAtPos(text_to_show, rtol,
					  layout->images[i].x,
					  layout->images[i].y, font);

			VbDoneWithFontForNow(font);
			break;

		default:
			VBDEBUG(("VbDisplayScreenFromGBB(): "
				 "unsupported ImageFormat %d\n",
				 image_info->format));
			retval = VBERROR_INVALID_GBB;
		}

		if (COMPRESS_NONE != image_info->compression)
			VbExFree(fullimage);

		if (VBERROR_SUCCESS != retval)
			goto VbDisplayScreenFromGBB_exit;
	}

	/* Successful if all bitmaps displayed */
	retval = VBERROR_SUCCESS;

	/*
	 * If GBB flags is nonzero, complain because that's something that the
	 * factory MUST fix before shipping. We only have to do this here,
	 * because it's obvious that something is wrong if we're not displaying
	 * screens from the GBB.
	 */
	if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1 &&
	    (gbb->flags != 0)) {
		used += Strncat(outbuf + used, "gbb.flags is nonzero: 0x",
				OUTBUF_LEN - used);
		used += Uint64ToString(outbuf + used, OUTBUF_LEN - used,
				       gbb->flags, 16, 8);
		used += Strncat(outbuf + used, "\n", OUTBUF_LEN - used);
		(void)VbExDisplayDebugInfo(outbuf);
	}

 VbDisplayScreenFromGBB_exit:
	VBDEBUG(("leaving VbDisplayScreenFromGBB() with %d\n",retval));
	return retval;
}

VbError_t VbDisplayScreen(VbCommonParams *cparams, uint32_t screen, int force,
                          VbNvContext *vncptr)
{
	VbError_t retval;

	/* Initialize display if necessary */
	if (!disp_width) {
		retval = VbExDisplayInit(&disp_width, &disp_height);
		if (VBERROR_SUCCESS != retval)
			return retval;
	}

	/* If requested screen is the same as the current one, we're done. */
	if (disp_current_screen == screen && 0 == force)
		return VBERROR_SUCCESS;

	/* If the screen is blank, turn off the backlight; else turn it on. */
	VbExDisplayBacklight(VB_SCREEN_BLANK == screen ? 0 : 1);

	/* Request the screen */
	disp_current_screen = screen;

	/* Look in the GBB first */
	if (VBERROR_SUCCESS == VbDisplayScreenFromGBB(cparams, screen, vncptr))
		return VBERROR_SUCCESS;

	/* If screen wasn't in the GBB bitmaps, fall back to a default */
	return VbExDisplayScreen(screen);
}

static void Uint8ToString(char *buf, uint8_t val)
{
	const char *trans = "0123456789abcdef";
	*buf++ = trans[val >> 4];
	*buf = trans[val & 0xF];
}

static void FillInSha1Sum(char *outbuf, VbPublicKey *key)
{
	uint8_t *buf = ((uint8_t *)key) + key->key_offset;
	uint64_t buflen = key->key_size;
	uint8_t *digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM);
	int i;
	for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
		Uint8ToString(outbuf, digest[i]);
		outbuf += 2;
	}
	*outbuf = '\0';
	VbExFree(digest);
}

const char *RecoveryReasonString(uint8_t code)
{
	switch(code) {
	case VBNV_RECOVERY_NOT_REQUESTED:
		return "Recovery not requested";
	case VBNV_RECOVERY_LEGACY:
		return "Recovery requested from legacy utility";
	case VBNV_RECOVERY_RO_MANUAL:
		return "recovery button pressed";
	case VBNV_RECOVERY_RO_INVALID_RW:
		return "RW firmware failed signature check";
	case VBNV_RECOVERY_RO_S3_RESUME:
		return "S3 resume failed";
	case VBNV_RECOVERY_DEP_RO_TPM_ERROR:
		return "TPM error in read-only firmware";
	case VBNV_RECOVERY_RO_SHARED_DATA:
		return "Shared data error in read-only firmware";
	case VBNV_RECOVERY_RO_TEST_S3:
		return "Test error from S3Resume()";
	case VBNV_RECOVERY_RO_TEST_LFS:
		return "Test error from LoadFirmwareSetup()";
	case VBNV_RECOVERY_RO_TEST_LF:
		return "Test error from LoadFirmware()";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_NOT_DONE:
		return "RW firmware check not done";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_DEV_MISMATCH:
	  return "RW firmware developer flag mismatch";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_REC_MISMATCH:
		return "RW firmware recovery flag mismatch";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
		VBSD_LF_CHECK_VERIFY_KEYBLOCK:
		return "RW firmware unable to verify key block";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_KEY_ROLLBACK:
		return "RW firmware key version rollback detected";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
		VBSD_LF_CHECK_DATA_KEY_PARSE:
		return "RW firmware unable to parse data key";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
		VBSD_LF_CHECK_VERIFY_PREAMBLE:
		return "RW firmware unable to verify preamble";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_FW_ROLLBACK:
		return "RW firmware version rollback detected";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_GET_FW_BODY:
		return "RW firmware unable to get firmware body";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN +
		VBSD_LF_CHECK_HASH_WRONG_SIZE:
		return "RW firmware hash is wrong size";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_VERIFY_BODY:
		return "RW firmware unable to verify firmware body";
	case VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + VBSD_LF_CHECK_NO_RO_NORMAL:
		return "RW firmware read-only normal path is not supported";
	case VBNV_RECOVERY_RO_FIRMWARE:
		return "Firmware problem outside of verified boot";
	case VBNV_RECOVERY_RO_TPM_REBOOT:
		return "TPM requires a system reboot (should be transient)";
	case VBNV_RECOVERY_EC_SOFTWARE_SYNC:
		return "EC software sync error";
	case VBNV_RECOVERY_EC_UNKNOWN_IMAGE:
		return "EC software sync unable to determine active EC image";
	case VBNV_RECOVERY_DEP_EC_HASH:
		return "EC software sync error obtaining EC image hash";
	case VBNV_RECOVERY_EC_EXPECTED_IMAGE:
		return "EC software sync error "
			"obtaining expected EC image from BIOS";
	case VBNV_RECOVERY_EC_EXPECTED_HASH:
		return "EC software sync error "
			"obtaining expected EC hash from BIOS";
	case VBNV_RECOVERY_EC_HASH_MISMATCH:
		return "EC software sync error "
			"comparing expected EC hash and image";
	case VBNV_RECOVERY_EC_UPDATE:
		return "EC software sync error updating EC";
	case VBNV_RECOVERY_EC_JUMP_RW:
		return "EC software sync unable to jump to EC-RW";
	case VBNV_RECOVERY_EC_PROTECT:
		return "EC software sync protection error";
	case VBNV_RECOVERY_RO_UNSPECIFIED:
		return "Unspecified/unknown error in RO firmware";
	case VBNV_RECOVERY_RW_DEV_SCREEN:
		return "User requested recovery from dev-mode warning screen";
	case VBNV_RECOVERY_RW_NO_OS:
		return "No OS kernel detected (or kernel rollback attempt?)";
	case VBNV_RECOVERY_RW_INVALID_OS:
		return "OS kernel failed signature check";
	case VBNV_RECOVERY_DEP_RW_TPM_ERROR:
		return "TPM error in rewritable firmware";
	case VBNV_RECOVERY_RW_DEV_MISMATCH:
		return "RW firmware in dev mode, but dev switch is off";
	case VBNV_RECOVERY_RW_SHARED_DATA:
		return "Shared data error in rewritable firmware";
	case VBNV_RECOVERY_RW_TEST_LK:
		return "Test error from LoadKernel()";
	case VBNV_RECOVERY_DEP_RW_NO_DISK:
		return "No bootable disk found";
	case VBNV_RECOVERY_TPM_E_FAIL:
		return "TPM error that was not fixed by reboot";
	case VBNV_RECOVERY_RO_TPM_S_ERROR:
		return "TPM setup error in read-only firmware";
	case VBNV_RECOVERY_RO_TPM_W_ERROR:
		return "TPM write error in read-only firmware";
	case VBNV_RECOVERY_RO_TPM_L_ERROR:
		return "TPM lock error in read-only firmware";
	case VBNV_RECOVERY_RO_TPM_U_ERROR:
		return "TPM update error in read-only firmware";
	case VBNV_RECOVERY_RW_TPM_R_ERROR:
		return "TPM read error in rewritable firmware";
	case VBNV_RECOVERY_RW_TPM_W_ERROR:
		return "TPM write error in rewritable firmware";
	case VBNV_RECOVERY_RW_TPM_L_ERROR:
		return "TPM lock error in rewritable firmware";
	case VBNV_RECOVERY_EC_HASH_FAILED:
		return "EC software sync unable to get EC image hash";
	case VBNV_RECOVERY_EC_HASH_SIZE:
		return "EC software sync invalid image hash size";
	case VBNV_RECOVERY_LK_UNSPECIFIED:
		return "Unspecified error while trying to load kernel";
	case VBNV_RECOVERY_RW_NO_DISK:
		return "No bootable storage device in system";
	case VBNV_RECOVERY_RW_NO_KERNEL:
		return "No bootable kernel found on disk";
	case VBNV_RECOVERY_RW_UNSPECIFIED:
		return "Unspecified/unknown error in RW firmware";
	case VBNV_RECOVERY_KE_DM_VERITY:
		return "DM-verity error";
	case VBNV_RECOVERY_KE_UNSPECIFIED:
		return "Unspecified/unknown error in kernel";
	case VBNV_RECOVERY_US_TEST:
		return "Recovery mode test from user-mode";
	case VBNV_RECOVERY_US_UNSPECIFIED:
		return "Unspecified/unknown error in user-mode";
	}
	return "We have no idea what this means";
}

#define DEBUG_INFO_SIZE 512

VbError_t VbDisplayDebugInfo(VbCommonParams *cparams, VbNvContext *vncptr)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	GoogleBinaryBlockHeader *gbb =
		(GoogleBinaryBlockHeader *)cparams->gbb_data;
	char buf[DEBUG_INFO_SIZE] = "";
	char sha1sum[SHA1_DIGEST_SIZE * 2 + 1];
	uint32_t used = 0;
	uint32_t i;

	/* Redisplay current screen to overwrite any previous debug output */
	VbDisplayScreen(cparams, disp_current_screen, 1, vncptr);

	/* Add hardware ID */
	used += Strncat(buf + used, "HWID: ", DEBUG_INFO_SIZE - used);
	if (0 == gbb->hwid_size ||
	    gbb->hwid_offset > cparams->gbb_size ||
	    gbb->hwid_offset + gbb->hwid_size > cparams->gbb_size) {
		VBDEBUG(("VbDisplayDebugInfo(): invalid hwid offset/size\n"));
		used += Strncat(buf + used,
				"(INVALID)", DEBUG_INFO_SIZE - used);
  } else {
		used += Strncat(buf + used,
				(char *)((uint8_t *)gbb + gbb->hwid_offset),
				DEBUG_INFO_SIZE - used);
  }

	/* Add recovery reason */
	used += Strncat(buf + used,
			"\nrecovery_reason: 0x", DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
			       shared->recovery_reason, 16, 2);
	used += Strncat(buf + used, "  ", DEBUG_INFO_SIZE - used);
	used += Strncat(buf + used,
			RecoveryReasonString(shared->recovery_reason),
			DEBUG_INFO_SIZE - used);

	/* Add VbSharedData flags */
	used += Strncat(buf + used, "\nVbSD.flags: 0x", DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
			       shared->flags, 16, 8);

	/* Add raw contents of VbNvStorage */
	used += Strncat(buf + used, "\nVbNv.raw:", DEBUG_INFO_SIZE - used);
	for (i = 0; i < VBNV_BLOCK_SIZE; i++) {
		used += Strncat(buf + used, " ", DEBUG_INFO_SIZE - used);
		used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
				       vncptr->raw[i], 16, 2);
	}

	/* Add dev_boot_usb flag */
	VbNvGet(vncptr, VBNV_DEV_BOOT_USB, &i);
	used += Strncat(buf + used, "\ndev_boot_usb: ", DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);

	/* Add dev_boot_legacy flag */
	VbNvGet(vncptr, VBNV_DEV_BOOT_LEGACY, &i);
	used += Strncat(buf + used,
			"\ndev_boot_legacy: ", DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);

	/* Add dev_boot_signed_only flag */
	VbNvGet(vncptr, VBNV_DEV_BOOT_SIGNED_ONLY, &i);
	used += Strncat(buf + used, "\ndev_boot_signed_only: ",
			DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used, i, 10, 0);

	/* Add TPM versions */
	used += Strncat(buf + used, "\nTPM: fwver=0x", DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
			       shared->fw_version_tpm, 16, 8);
	used += Strncat(buf + used, " kernver=0x", DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
			       shared->kernel_version_tpm, 16, 8);

	/* Add GBB flags */
	used += Strncat(buf + used, "\ngbb.flags: 0x", DEBUG_INFO_SIZE - used);
	if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1) {
		used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
				       gbb->flags, 16, 8);
	} else {
		used += Strncat(buf + used,
				"0 (default)", DEBUG_INFO_SIZE - used);
	}

	/* Add sha1sum for Root & Recovery keys */
	FillInSha1Sum(sha1sum,
		(VbPublicKey *)((uint8_t *)gbb + gbb->rootkey_offset));
	used += Strncat(buf + used, "\ngbb.rootkey: ", DEBUG_INFO_SIZE - used);
	used += Strncat(buf + used, sha1sum, DEBUG_INFO_SIZE - used);
	FillInSha1Sum(sha1sum,
		(VbPublicKey *)((uint8_t *)gbb + gbb->recovery_key_offset));
	used += Strncat(buf + used,
			"\ngbb.recovery_key: ", DEBUG_INFO_SIZE - used);
	used += Strncat(buf + used, sha1sum, DEBUG_INFO_SIZE - used);

	/* If we're in dev-mode, show the kernel subkey that we expect, too. */
	if (0 == shared->recovery_reason) {
		FillInSha1Sum(sha1sum, &shared->kernel_subkey);
		used += Strncat(buf + used,
				"\nkernel_subkey: ", DEBUG_INFO_SIZE - used);
		used += Strncat(buf + used, sha1sum, DEBUG_INFO_SIZE - used);
	}

	/* Make sure we finish with a newline */
	used += Strncat(buf + used, "\n", DEBUG_INFO_SIZE - used);

	/* TODO: add more interesting data:
	 * - Information on current disks */

	buf[DEBUG_INFO_SIZE - 1] = '\0';
	return VbExDisplayDebugInfo(buf);
}

#define MAGIC_WORD_LEN 5
#define MAGIC_WORD "xyzzy"
static uint8_t MagicBuffer[MAGIC_WORD_LEN];

VbError_t VbCheckDisplayKey(VbCommonParams *cparams, uint32_t key,
                            VbNvContext *vncptr)
{
	int i;

	/* Update key buffer */
	for(i = 1; i < MAGIC_WORD_LEN; i++)
		MagicBuffer[i - 1] = MagicBuffer[i];
	/* Save as lower-case ASCII */
	MagicBuffer[MAGIC_WORD_LEN - 1] = (key | 0x20) & 0xFF;

	if ('\t' == key) {
		/* Tab = display debug info */
		return VbDisplayDebugInfo(cparams, vncptr);
	} else if (VB_KEY_LEFT == key || VB_KEY_RIGHT == key ||
		   VB_KEY_DOWN == key || VB_KEY_UP == key) {
		/* Arrow keys = change localization */
		uint32_t loc = 0;
		uint32_t count = 0;

		VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &loc);
		if (VBERROR_SUCCESS != VbGetLocalizationCount(cparams, &count))
			loc = 0;  /* No localization count (bad GBB?) */
		else if (VB_KEY_RIGHT == key || VB_KEY_UP == key)
			loc = (loc < count - 1 ? loc + 1 : 0);
		else
			loc = (loc > 0 ? loc - 1 : count - 1);
		VBDEBUG(("VbCheckDisplayKey() - change localization to %d\n",
			 (int)loc));
		VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, loc);

#ifdef SAVE_LOCALE_IMMEDIATELY
		VbNvTeardown(vncptr);  /* really only computes checksum */
		if (vncptr->raw_changed)
			VbExNvStorageWrite(vncptr->raw);
#endif

		/* Force redraw of current screen */
		return VbDisplayScreen(cparams, disp_current_screen, 1, vncptr);
	}

	if (0 == Memcmp(MagicBuffer, MAGIC_WORD, MAGIC_WORD_LEN)) {
		if (VBEASTEREGG)
			(void)VbDisplayScreen(cparams, disp_current_screen,
					      1, vncptr);
	}

  return VBERROR_SUCCESS;
}
