#!/bin/sh # Copyright (c) 2010 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. # # Usage: dev_debug_vboot [ --cleanup | DIRECTORY ] # # This extracts some useful debugging information about verified boot. A short # summary is printed on stdout, more detailed information and working files are # left in a log directory. # TMPDIR=/tmp/debug_vboot LOGFILE=noisy.log # TODO(wfrichar): Need to support ARM. The hard disk path is likely different. HD=/dev/sda ACPI=/sys/devices/platform/chromeos_acpi cleanup() { if [ -n "${CLEANUP}" ]; then find "${TMPDIR}" -type f -not -name "${LOGFILE}" -exec rm {} ";" fi } die() { echo "$*" 1>&2 exit 1 } info() { echo "$@" echo "#" "$@" >> "$LOGFILE" } infon() { echo -n "$@" echo "#" "$@" >> "$LOGFILE" } log() { echo "+" "$@" >> "$LOGFILE" "$@" >> "$LOGFILE" 2>&1 } logdie() { echo "+" "$@" >> "$LOGFILE" "$@" >> "$LOGFILE" 2>&1 die "$@" } result() { if [ "$?" = "0" ]; then info "OK" else info "FAILED" fi } require_chromeos_bios() { log cgpt show "${HD}" log rootdev -s if [ ! -e "${ACPI}/HWID" ]; then info "Not running Chrome OS BIOS, no further information available" exit 0 fi # including /dev/null just to get final "\n" log head "${ACPI}"/*ID "${ACPI}"/BINF* "${ACPI}"/CHSW /dev/null } # Here we go... umask 022 trap cleanup EXIT # Parse args if [ -n "$1" ]; then if [ "$1" = "--cleanup" ]; then CLEANUP=1 else TMPDIR="$1" [ -d ${TMPDIR} ] || die "${TMPDIR} doesn't exist" USE_EXISTING=yes fi fi [ -d ${TMPDIR} ] || mkdir -p ${TMPDIR} || exit 1 cd ${TMPDIR} echo "$0 $*" > "$LOGFILE" log date echo "Saving verbose log as $(pwd)/$LOGFILE" BIOS=bios.rom # Find BIOS and kernel images if [ -n "$USE_EXISTING" ]; then info "Using images in $(pwd)/" else require_chromeos_bios info "Extracting BIOS image from flash..." log flashrom -r ${BIOS} HD_KERN_A="${HD}2" HD_KERN_B="${HD}4" tmp=$(rootdev -s -d)2 if [ "$tmp" != "$HD_KERN_A" ]; then USB_KERN_A="$tmp" fi info "Extracting kernel images from drives..." log dd if=${HD_KERN_A} of=hd_kern_a.blob log dd if=${HD_KERN_B} of=hd_kern_b.blob if [ -n "$USB_KERN_A" ]; then log dd if=${USB_KERN_A} of=usb_kern_a.blob fi fi # Make sure we have something to work on [ -f "$BIOS" ] || logdie "no BIOS image found" ls *kern*.blob >/dev/null 2>&1 || logdie "no kernel images found" info "Extracting BIOS components..." log dump_fmap -x ${BIOS} || logdie "Unable to extract BIOS components" info "Pulling root and recovery keys from GBB..." log gbb_utility -g --rootkey rootkey.vbpubk --recoverykey recoverykey.vbpubk \ GBB_Area || logdie "Unable to extract keys from GBB" log vbutil_key --unpack rootkey.vbpubk log vbutil_key --unpack recoverykey.vbpubk infon "Verify firmware A with root key... " log vbutil_firmware --verify Firmware_A_Key --signpubkey rootkey.vbpubk \ --fv Firmware_A_Data --kernelkey kernel_subkey_a.vbpubk ; result infon "Verify firmware B with root key... " log vbutil_firmware --verify Firmware_B_Key --signpubkey rootkey.vbpubk \ --fv Firmware_B_Data --kernelkey kernel_subkey_b.vbpubk ; result for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk; do infon "Test $key... " log vbutil_key --unpack $key ; result done for keyblock in *kern*.blob; do infon "Test $keyblock... " log vbutil_keyblock --unpack $keyblock ; result done # Test each kernel with each key for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk recoverykey.vbpubk; do for kern in *kern*.blob; do infon "Verify $kern with $key... " log vbutil_kernel --verify $kern --signpubkey $key ; result done done