| #!/bin/bash -eux |
| # Copyright 2014 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. |
| |
| me=${0##*/} |
| TMP="$me.tmp" |
| |
| # Work in scratch directory |
| cd "$OUTDIR" |
| |
| KEYDIR=${SRCDIR}/tests/devkeys |
| |
| # The input BIOS images are all signed with MP keys. We resign them with dev |
| # keys, which means we can precalculate the expected results. Note that the |
| # script does not change the root or recovery keys in the GBB. |
| INFILES=" |
| ${SCRIPTDIR}/data/bios_link_mp.bin |
| ${SCRIPTDIR}/data/bios_mario_mp.bin |
| ${SCRIPTDIR}/data/bios_peppy_mp.bin |
| " |
| |
| # We also want to test that we can sign an image without any valid firmware |
| # preambles. That one won't be able to tell how much of the FW_MAIN region is |
| # the valid firmware, so it'll have to sign the entire region. |
| GOOD_VBLOCKS=${SCRIPTDIR}/data/bios_peppy_mp.bin |
| ONEMORE=bios_peppy_mp_no_vblock.bin |
| cp ${GOOD_VBLOCKS} ${ONEMORE} |
| ${FUTILITY} load_fmap ${ONEMORE} VBLOCK_A:/dev/urandom VBLOCK_B:/dev/zero |
| INFILES="${INFILES} ${ONEMORE}" |
| |
| set -o pipefail |
| |
| # We've removed dev_firmware keyblock and private keys from ToT test key dir. |
| # It's currently only available on few legacy (alex, zgb) devices' key folders |
| # on signer bot. Add them to ${KEYDIR} if you need to test that. |
| DEV_FIRMWARE_PARAMS="" |
| if [ -f "${KEYDIR}/dev_firmware.keyblock" ]; then |
| DEV_FIRMWARE_PARAMS=" |
| -S ${KEYDIR}/dev_firmware_data_key.vbprivk |
| -B ${KEYDIR}/dev_firmware.keyblock" |
| INFILES="${INFILES} ${SCRIPTDIR}/data/bios_zgb_mp.bin" |
| fi |
| |
| count=0 |
| for infile in $INFILES; do |
| |
| base=${infile##*/} |
| |
| : $(( count++ )) |
| echo -n "$count " 1>&3 |
| |
| outfile=${TMP}.${base}.new |
| loemid="loem" |
| loemdir=${TMP}.${base}_dir |
| |
| mkdir -p ${loemdir} |
| |
| # resign_firmwarefd.sh works on BIOS image files. The args are: |
| # |
| # infile |
| # outfile |
| # firmware_datakey |
| # firmware_keyblock |
| # dev_firmware_datakey (these are only used if RW A & RW B differ) |
| # dev_firmware_keyblock |
| # kernel_subkey |
| # firmware_version |
| # preamble_flag |
| # loem_output_dir (optional: dir for copy of new vblocks) |
| # loemid (optional: copy new vblocks using this name) |
| # |
| #OLD ${BINDIR}/resign_firmwarefd.sh \ |
| #OLD ${infile} \ |
| #OLD ${outfile} \ |
| #OLD ${KEYDIR}/firmware_data_key.vbprivk \ |
| #OLD ${KEYDIR}/firmware.keyblock \ |
| #OLD ${KEYDIR}/dev_firmware_data_key.vbprivk \ |
| #OLD ${KEYDIR}/dev_firmware.keyblock \ |
| #OLD ${KEYDIR}/kernel_subkey.vbpubk \ |
| #OLD 14 \ |
| #OLD 8 \ |
| #OLD ${loemdir} \ |
| #OLD ${loemid} |
| |
| ${FUTILITY} sign \ |
| -s ${KEYDIR}/firmware_data_key.vbprivk \ |
| -b ${KEYDIR}/firmware.keyblock \ |
| ${DEV_FIRMWARE_PARAMS} \ |
| -k ${KEYDIR}/kernel_subkey.vbpubk \ |
| -v 14 \ |
| -f 8 \ |
| -d ${loemdir} \ |
| -l ${loemid} \ |
| ${infile} ${outfile} |
| |
| # check the firmware version and preamble flags |
| m=$(${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk ${outfile} \ |
| | egrep 'Firmware version: +14$|Preamble flags: +8$' | wc -l) |
| [ "$m" = "4" ] |
| |
| # check the sha1sums |
| ${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk ${outfile} \ |
| | grep sha1sum \ |
| | sed -e 's/.*: \+//' > ${TMP}.${base}.sha.new |
| cmp ${SCRIPTDIR}/data_${base}_expect.txt ${TMP}.${base}.sha.new |
| |
| # and the LOEM stuff |
| ${FUTILITY} dump_fmap -x ${outfile} \ |
| FW_MAIN_A:${loemdir}/fw_main_A FW_MAIN_B:${loemdir}/fw_main_B \ |
| "Firmware A Data":${loemdir}/fw_main_A \ |
| "Firmware B Data":${loemdir}/fw_main_B |
| |
| |
| ${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk \ |
| --fv ${loemdir}/fw_main_A \ |
| ${loemdir}/vblock_A.${loemid} | grep sha1sum \ |
| | sed -e 's/.*: \+//' > ${loemdir}/loem.sha.new |
| ${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk \ |
| --fv ${loemdir}/fw_main_B \ |
| ${loemdir}/vblock_B.${loemid} | grep sha1sum \ |
| | sed -e 's/.*: \+//' >> ${loemdir}/loem.sha.new |
| |
| # the vblocks don't have root or recovery keys |
| tail -4 ${SCRIPTDIR}/data_${base}_expect.txt > ${loemdir}/sha.expect |
| cmp ${loemdir}/sha.expect ${loemdir}/loem.sha.new |
| |
| done |
| |
| # Make sure that the BIOS with the good vblocks signed the right size. |
| GOOD_OUT=${TMP}.${GOOD_VBLOCKS##*/}.new |
| MORE_OUT=${TMP}.${ONEMORE##*/}.new |
| |
| ${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk ${GOOD_OUT} \ |
| | awk '/Firmware body size:/ {print $4}' > ${TMP}.good.body |
| ${FUTILITY} dump_fmap -p ${GOOD_OUT} \ |
| | awk '/FW_MAIN_/ {print $3}' > ${TMP}.good.fw_main |
| # This should fail because they're different |
| if cmp ${TMP}.good.body ${TMP}.good.fw_main; then false; fi |
| |
| # Make sure that the BIOS with the bad vblocks signed the whole fw body |
| ${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk ${MORE_OUT} \ |
| | awk '/Firmware body size:/ {print $4}' > ${TMP}.onemore.body |
| ${FUTILITY} dump_fmap -p ${MORE_OUT} \ |
| | awk '/FW_MAIN_/ {print $3}' > ${TMP}.onemore.fw_main |
| # These should match |
| cmp ${TMP}.onemore.body ${TMP}.onemore.fw_main |
| cmp ${TMP}.onemore.body ${TMP}.good.fw_main |
| |
| |
| # Sign the last one again but don't specify the version or the preamble flags. |
| # The version should default to 1, but the preamble flags should be preserved. |
| : $(( count++ )) |
| echo -n "$count " 1>&3 |
| |
| ${FUTILITY} sign \ |
| -s ${KEYDIR}/firmware_data_key.vbprivk \ |
| -b ${KEYDIR}/firmware.keyblock \ |
| ${DEV_FIRMWARE_PARAMS} \ |
| -k ${KEYDIR}/kernel_subkey.vbpubk \ |
| ${MORE_OUT} ${MORE_OUT}.2 |
| |
| m=$(${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk ${MORE_OUT}.2 \ |
| | egrep 'Firmware version: +1$|Preamble flags: +8$' | wc -l) |
| [ "$m" = "4" ] |
| |
| |
| # If the original preamble is not present, the preamble flags should be zero. |
| : $(( count++ )) |
| echo -n "$count " 1>&3 |
| |
| ${FUTILITY} load_fmap ${MORE_OUT} VBLOCK_A:/dev/urandom VBLOCK_B:/dev/zero |
| ${FUTILITY} sign \ |
| -s ${KEYDIR}/firmware_data_key.vbprivk \ |
| -b ${KEYDIR}/firmware.keyblock \ |
| ${DEV_FIRMWARE_PARAMS} \ |
| -k ${KEYDIR}/kernel_subkey.vbpubk \ |
| ${MORE_OUT} ${MORE_OUT}.3 |
| |
| m=$(${FUTILITY} verify --publickey ${KEYDIR}/root_key.vbpubk ${MORE_OUT}.3 \ |
| | egrep 'Firmware version: +1$|Preamble flags: +0$' | wc -l) |
| [ "$m" = "4" ] |
| |
| |
| # cleanup |
| rm -rf ${TMP}* ${ONEMORE} |
| exit 0 |