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

const 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.
 */

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

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

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);
}

void VbRenderTextAtPos(const 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;
	const 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 += StrnAppend(outbuf + used, "gbb.flags is nonzero: 0x",
				OUTBUF_LEN - used);
		used += Uint64ToString(outbuf + used, OUTBUF_LEN - used,
				       gbb->flags, 16, 8);
		used += StrnAppend(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 += StrnAppend(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 += StrnAppend(buf + used,
				"(INVALID)", DEBUG_INFO_SIZE - used);
  } else {
		used += StrnAppend(buf + used,
				(char *)((uint8_t *)gbb + gbb->hwid_offset),
				DEBUG_INFO_SIZE - used);
  }

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

	/* Add VbSharedData flags */
	used += StrnAppend(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 += StrnAppend(buf + used, "\nVbNv.raw:", DEBUG_INFO_SIZE - used);
	for (i = 0; i < VBNV_BLOCK_SIZE; i++) {
		used += StrnAppend(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 += StrnAppend(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 += StrnAppend(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 += StrnAppend(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 += StrnAppend(buf + used, "\nTPM: fwver=0x", DEBUG_INFO_SIZE - used);
	used += Uint64ToString(buf + used, DEBUG_INFO_SIZE - used,
			       shared->fw_version_tpm, 16, 8);
	used += StrnAppend(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 += StrnAppend(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 += StrnAppend(buf + used,
				"0 (default)", DEBUG_INFO_SIZE - used);
	}

	/* Add sha1sum for Root & Recovery keys */
	FillInSha1Sum(sha1sum,
		(VbPublicKey *)((uint8_t *)gbb + gbb->rootkey_offset));
	used += StrnAppend(buf + used, "\ngbb.rootkey: ", DEBUG_INFO_SIZE - used);
	used += StrnAppend(buf + used, sha1sum, DEBUG_INFO_SIZE - used);
	FillInSha1Sum(sha1sum,
		(VbPublicKey *)((uint8_t *)gbb + gbb->recovery_key_offset));
	used += StrnAppend(buf + used,
			"\ngbb.recovery_key: ", DEBUG_INFO_SIZE - used);
	used += StrnAppend(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 += StrnAppend(buf + used,
				"\nkernel_subkey: ", DEBUG_INFO_SIZE - used);
		used += StrnAppend(buf + used, sha1sum, DEBUG_INFO_SIZE - used);
	}

	/* Make sure we finish with a newline */
	used += StrnAppend(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;
}
