/* Test displaying debug info */ static void DebugInfoTest(void) { char hwid[VB_REGION_HWID_LEN]; int i; /* Recovery string should be non-null for any code */ for (i = 0; i < 0x100; i++) TEST_PTR_NEQ(RecoveryReasonString(i), NULL, "Non-null reason"); /* HWID should come from the gbb */ ResetMocks(); VbRegionReadHWID(&cparams, hwid, sizeof(hwid)); TEST_EQ(strcmp(hwid, "Test HWID"), 0, "HWID"); VbApiKernelFree(&cparams); ResetMocks(); cparams.gbb_size = 0; VbRegionReadHWID(&cparams, hwid, sizeof(hwid)); TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID bad gbb"); VbApiKernelFree(&cparams); ResetMocks(); cparams.gbb->hwid_size = 0; VbRegionReadHWID(&cparams, hwid, sizeof(hwid)); TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID missing"); VbApiKernelFree(&cparams); ResetMocks(); cparams.gbb->hwid_offset = cparams.gbb_size + 1; VbRegionReadHWID(&cparams, hwid, sizeof(hwid)); TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID past end"); VbApiKernelFree(&cparams); ResetMocks(); cparams.gbb->hwid_size = cparams.gbb_size; VbRegionReadHWID(&cparams, hwid, sizeof(hwid)); TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID overflow"); VbApiKernelFree(&cparams); /* Display debug info */ ResetMocks(); VbDisplayDebugInfo(&cparams, &vnc); TEST_NEQ(*debug_info, '\0', "Some debug info was displayed"); VbApiKernelFree(&cparams); }
VbError_t VbDisplayDebugInfo(VbCommonParams *cparams, VbNvContext *vncptr) { VbSharedDataHeader *shared = (VbSharedDataHeader *)cparams->shared_data_blob; GoogleBinaryBlockHeader *gbb = cparams->gbb; char buf[DEBUG_INFO_SIZE] = ""; char sha1sum[SHA1_DIGEST_SIZE * 2 + 1]; char hwid[256]; uint32_t used = 0; VbPublicKey *key; VbError_t ret; uint32_t i; /* Redisplay current screen to overwrite any previous debug output */ VbDisplayScreen(cparams, disp_current_screen, 1, vncptr); /* Add hardware ID */ VbRegionReadHWID(cparams, hwid, sizeof(hwid)); used += StrnAppend(buf + used, "HWID: ", DEBUG_INFO_SIZE - used); used += StrnAppend(buf + used, hwid, 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 */ ret = VbGbbReadRootKey(cparams, &key); if (!ret) { FillInSha1Sum(sha1sum, key); VbExFree(key); used += StrnAppend(buf + used, "\ngbb.rootkey: ", DEBUG_INFO_SIZE - used); used += StrnAppend(buf + used, sha1sum, DEBUG_INFO_SIZE - used); } ret = VbGbbReadRecoveryKey(cparams, &key); if (!ret) { FillInSha1Sum(sha1sum, key); VbExFree(key); 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); }
VbError_t VbDisplayScreenFromGBB(VbCommonParams *cparams, uint32_t screen, VbNvContext *vncptr) { char *fullimage = NULL; BmpBlockHeader hdr; uint32_t screen_index; uint32_t localization = 0; VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven ok */ uint32_t inoutsize; uint32_t i; VbFont_t *font; const char *text_to_show; int rtol = 0; VbError_t ret; ret = VbGbbReadBmpHeader(cparams, &hdr); if (ret) return ret; /* * 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); } /* Display all bitmaps for the image */ for (i = 0; i < MAX_IMAGE_IN_LAYOUT; i++) { ScreenLayout layout; ImageInfo image_info; char hwid[256]; ret = VbGbbReadImage(cparams, localization, screen_index, i, &layout, &image_info, &fullimage, &inoutsize); if (ret == VBERROR_NO_IMAGE_PRESENT) { continue; } else if (ret) { retval = ret; goto VbDisplayScreenFromGBB_exit; } switch(image_info.format) { case FORMAT_BMP: if (i == 0) { /** * In current version GBB bitmaps, first image * is always the background. */ ret = VbExDisplaySetDimension( image_info.width, image_info.height); if (ret) { VBDEBUG(("VbExDisplaySetDimension" "(%d,%d): failed (%#x).\n", image_info.width, image_info.height, ret)); } } 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( (FontArrayHeader *)fullimage); /* TODO: handle text in general here */ if (TAG_HWID == image_info.tag || TAG_HWID_RTOL == image_info.tag) { VbRegionReadHWID(cparams, hwid, sizeof(hwid)); text_to_show = hwid; 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; } VbExFree(fullimage); if (VBERROR_SUCCESS != retval) goto VbDisplayScreenFromGBB_exit; } /* Successful if all bitmaps displayed */ retval = VBERROR_SUCCESS; VbRegionCheckVersion(cparams); VbDisplayScreenFromGBB_exit: VBDEBUG(("leaving VbDisplayScreenFromGBB() with %d\n",retval)); return retval; }