/* Copyright (c) 2011 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;


/* Get the number of localizations in the GBB bitmap data. */
static 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 the 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;
}



/* Return a fixed string representing the HWID */
static 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. */
  for(i=0; i<max; i++)
  {
    entry = (FontArrayEntryHeader *)ptr;
    if (entry->ascii == ascii) {
      /* Note: We're assuming the glpyh is 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.
       */
      *bufferptr = ptr + sizeof(FontArrayEntryHeader);
      *buffersize = entry->info.original_size;
      return &(entry->info);
    }
    ptr += sizeof(FontArrayEntryHeader)+entry->info.compressed_size;
  }

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


/* Display a screen from the GBB. */
#define OUTBUF_LEN 128
VbError_t VbDisplayScreenFromGBB(VbCommonParams* cparams, uint32_t screen,
                                 VbNvContext *vncptr) {
  GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data;
  uint8_t* bmpfv = NULL;
  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 the 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 */
  bmpfv = (uint8_t*)VbExMalloc(gbb->bmpfv_size);
  Memcpy(bmpfv, ((uint8_t*)gbb) + gbb->bmpfv_offset, gbb->bmpfv_size);

  /* 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 = 0;
    break;
  case VB_SCREEN_RECOVERY_REMOVE:
    screen_index = 1;
    break;
  case VB_SCREEN_RECOVERY_NO_GOOD:
    screen_index = 2;
    break;
  case VB_SCREEN_RECOVERY_INSERT:
    screen_index = 3;
    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 the 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) {
      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:

  /* Free the bitmap data copy */
  VbExFree(bmpfv);
  return retval;
}


/* Display a screen, initializing the display if necessary.  If force!=0,
 * redisplays the screen even if it's the same as the current screen. */
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 the 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 the screen wasn't in the GBB bitmaps, fall back to a default screen. */
  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);
}


static 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_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_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_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_RW_NO_DISK:
    return "No bootable disk found";
  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

/* Display debug info to the screen */
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 the 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_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?), so set to 0 (default) */
    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);
    /* Workaround for coreboot on x86, which will power off asynchronously
     * without giving us a chance to react. This is not an example of the Right
     * Way to do things. See chrome-os-partner:7689, and the commit message
     * that made this change.
     */
    VbNvTeardown(vncptr);               /* really only computes checksum */
    if (vncptr->raw_changed)
      VbExNvStorageWrite(vncptr->raw);

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