From 08efd1ee358c546c968918a24b45219d7003ceca Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 4 Sep 2014 22:53:41 -0700 Subject: futility: preserve preamble flags when resigning BIOS images If we're re-signing a valid BIOS image, we want to be sure that we preserve the original firmware preamble flags (RO_NORMAL and so forth) if the --flags option does not specifically override it. This change adds a test for that case, and makes it happen. BUG=chromium:224734 BRANCH=ToT TEST=make runtests Signed-off-by: Bill Richardson Change-Id: I8cbde66abaf96ec82adf0205bedf57b1fd1b82a1 Reviewed-on: https://chromium-review.googlesource.com/216714 Reviewed-by: Randall Spangler --- futility/cmd_show.c | 9 ++++--- futility/cmd_sign.c | 13 +++++++--- tests/futility/test_resign_firmware.sh | 45 +++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/futility/cmd_show.c b/futility/cmd_show.c index ac43bbf8..0f5eecdf 100644 --- a/futility/cmd_show.c +++ b/futility/cmd_show.c @@ -166,8 +166,9 @@ int futil_cb_show_gbb(struct futil_traverse_state_s *state) bmp = (BmpBlockHeader *)(buf + gbb->bmpfv_offset); if (0 != memcmp(bmp, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE)) { - /* We don't support old formats, so it's not always an error */ printf(" BmpBlock: \n"); + /* We don't support old formats, so it's not always an error */ + /* TODO: Add a --strict option to make this fatal? */ } else { printf(" BmpBlock:\n"); printf(" Version: %d.%d\n", @@ -332,7 +333,8 @@ int futil_cb_show_fw_preamble(struct futil_traverse_state_s *state) if (!fv_data) { printf("No firmware body available to verify.\n"); - return 1; + /* TODO: Add a --strict option to make this fatal? */ + return 0; } if (VBOOT_SUCCESS != @@ -350,7 +352,8 @@ done: printf("Body verification succeeded.\n"); state->my_area->_flags |= AREA_IS_VALID; } else { - printf("Body seems legit, but the signature is unverified.\n"); + printf("Seems legit, but the signature is unverified.\n"); + /* TODO: Add a --strict option to make this fatal? */ } return 0; diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index 3a65b22e..f7481759 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -82,7 +82,6 @@ int futil_cb_sign_fw_preamble(struct futil_traverse_state_s *state) if (state->component == CB_FW_PREAMBLE) return futil_cb_sign_notyet(state); - /* * If we have a valid keyblock and fw_preamble, then we can use them to * determine the size of the firmware body. Otherwise, we'll have to @@ -111,6 +110,9 @@ int futil_cb_sign_fw_preamble(struct futil_traverse_state_s *state) switch (state->component) { case CB_FMAP_VBLOCK_A: fw_body_area = &state->cb_area[CB_FMAP_FW_MAIN_A]; + /* Preserve the flags if they're not specified */ + if (!option.flags) + option.flags = preamble->flags; break; case CB_FMAP_VBLOCK_B: fw_body_area = &state->cb_area[CB_FMAP_FW_MAIN_B]; @@ -287,15 +289,18 @@ static const char usage[] = "\n" " DEV public firmware data key\n" "\n" "Optional OPTIONS:\n" - " -v|--version NUM The firmware version number (%d)\n" - " -f|--flags NUM The preamble flags value (%d)\n" + " -v|--version NUM The firmware version number" + " (default %d)\n" + " -f|--flags NUM The preamble flags value" + " (default is\n" + " unchanged, or 0 if unknown)\n" " -d|--loemdir DIR Local OEM output vblock directory\n" " -l|--loemid STRING Local OEM vblock suffix\n" "\n"; static void help_and_quit(const char *prog) { - fprintf(stderr, usage, prog, option.version, option.flags); + fprintf(stderr, usage, prog, option.version); exit(1); } diff --git a/tests/futility/test_resign_firmware.sh b/tests/futility/test_resign_firmware.sh index b1e397a3..94946a8d 100755 --- a/tests/futility/test_resign_firmware.sh +++ b/tests/futility/test_resign_firmware.sh @@ -44,10 +44,6 @@ for infile in $INFILES; do mkdir -p ${loemdir} - # grep for existing sha1sums (skipping root & recovery keys) - ${FUTILITY} show ${infile} | grep sha1sum \ - | sed -e 's/.*: \+//' | tail -n 4 > ${TMP}.${base}.sha.orig - # resign_firmwarefd.sh works on BIOS image files. The args are: # # infile @@ -82,14 +78,14 @@ for infile in $INFILES; do -B ${KEYDIR}/dev_firmware.keyblock \ -k ${KEYDIR}/kernel_subkey.vbpubk \ -v 14 \ - -f 9 \ + -f 8 \ -d ${loemdir} \ -l ${loemid} \ ${infile} ${outfile} # check the firmware version and preamble flags m=$(${FUTILITY} show ${outfile} | \ - egrep 'Firmware version: +14$|Preamble flags: +9$' | wc -l) + egrep 'Firmware version: +14$|Preamble flags: +8$' | wc -l) [ "$m" = "4" ] # check the sha1sums @@ -126,6 +122,43 @@ ${FUTILITY} dump_fmap -p ${MORE_OUT} \ 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 \ + -S ${KEYDIR}/dev_firmware_data_key.vbprivk \ + -B ${KEYDIR}/dev_firmware.keyblock \ + -k ${KEYDIR}/kernel_subkey.vbpubk \ + ${MORE_OUT} ${MORE_OUT}.2 + +m=$(${FUTILITY} show ${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 \ + -S ${KEYDIR}/dev_firmware_data_key.vbprivk \ + -B ${KEYDIR}/dev_firmware.keyblock \ + -k ${KEYDIR}/kernel_subkey.vbpubk \ + ${MORE_OUT} ${MORE_OUT}.3 + +m=$(${FUTILITY} show ${MORE_OUT}.3 | \ + egrep 'Firmware version: +1$|Preamble flags: +0$' | wc -l) +[ "$m" = "4" ] + + # cleanup rm -rf ${TMP}* ${ONEMORE} exit 0 -- cgit v1.2.1