blob: 3bdc5b052b52b114f491a279c2ad082095b5138a [file] [log] [blame]
#!/bin/sh
# 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.
#
# Derived from dev_debug_vboot.
#
# This script checks if system firmware and SSD images are ready for verified
# booting.
#
if [ "$#" != "2" ]; then
echo "ERROR: Usage: $0 kernel_device main_firmware" 1>&2
exit 1
fi
TMPDIR="$(mktemp -d)"
KERN_DEV="$(readlink -f "$1")"
FIRMWARE_IMAGE="$(readlink -f "$2")"
RETURN=0
invoke() {
# Usage: invoke "message" "shell-command"
result=0
message="$1"
shift
eval "$@" >_stdout 2>_stderr || result=$?
if [ "$result" != 0 ]; then
echo "ERROR: Failed to $message" 1>&2
echo "Command detail: $@" 1>&2
cat _stdout _stderr 1>&2
RETURN=1
fi
}
detect_section_name() {
# Usage: detect_section_name official_name alias_name
if [ -f "$2" ]; then
echo "$2"
else
echo "$1"
fi
}
verify_keys() {
# Usage: verify_keys kernel_device main_firmware
# Define section names
GBB="$(detect_section_name GBB GBB_Area)"
FW_MAIN_A="$(detect_section_name FW_MAIN_A Firmware_A_Data)"
FW_MAIN_B="$(detect_section_name FW_MAIN_B Firmware_B_Data)"
VBLOCK_A="$(detect_section_name VBLOCK_A Firmware_A_Key)"
VBLOCK_B="$(detect_section_name VBLOCK_B Firmware_B_Key)"
invoke "dump kernel" dd if="$1" bs=1M count=64 of=hd_kern.blob
invoke "extract firmware" dump_fmap -x "$2"
invoke "get keys from firmware" \
gbb_utility -g --rootkey rootkey.vbpubk "$GBB"
invoke "unpack rootkey" \
vbutil_key --unpack rootkey.vbpubk
# Verify firmware A/B with root key
invoke "verify VBLOCK_A with FW_MAIN_A" \
vbutil_firmware --verify "$VBLOCK_A" --signpubkey rootkey.vbpubk \
--fv "$FW_MAIN_A" --kernelkey kernel_subkey_a.vbpubk
invoke "verify VBLOCK_B with FW_MAIN_B" \
vbutil_firmware --verify "$VBLOCK_B" --signpubkey rootkey.vbpubk \
--fv "$FW_MAIN_B" --kernelkey kernel_subkey_b.vbpubk
# Unpack keys and keyblocks
for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk; do
invoke "unpack $key" vbutil_key --unpack $key
done
for keyblock in *kern*.blob; do
invoke "unpack $keyblock" vbutil_keyblock --unpack $keyblock
done
# Test each kernel by each key
for key in kernel_subkey_a.vbpubk kernel_subkey_b.vbpubk
do
for kern in *kern*.blob; do
invoke "verify $kern by $key" \
vbutil_kernel --verify $kern --signpubkey $key
done
done
return $RETURN
}
# verify_keys is run inside a sub-shell, so we need to check its return value
# instead of reading the global variable RETURN.
( cd "$TMPDIR"
verify_keys "$KERN_DEV" "$FIRMWARE_IMAGE" ) || RETURN=1
/bin/rm -rf "$TMPDIR"
exit $RETURN