diff options
-rw-r--r-- | futility/cmd_sign.c | 25 | ||||
-rw-r--r-- | tests/futility/data_bios_peppy_mp_no_vblock.bin_expect.txt | 6 | ||||
-rwxr-xr-x | tests/futility/test_resign_firmware.sh | 31 |
3 files changed, 58 insertions, 4 deletions
diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index 41f3d9f7..3a65b22e 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -76,21 +76,37 @@ int futil_cb_sign_fw_main(struct futil_traverse_state_s *state) int futil_cb_sign_fw_preamble(struct futil_traverse_state_s *state) { VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)state->my_area->buf; - struct cb_area_s *fw_body_area = 0; + uint32_t len = state->my_area->len; /* We don't (yet) handle standalone VBLOCKs */ if (state->component == CB_FW_PREAMBLE) return futil_cb_sign_notyet(state); + /* - * We've already checked the Keyblock hash and taken a look at the - * preamble or we wouldn't be here. + * 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 + * just sign the whole region. */ + if (VBOOT_SUCCESS != KeyBlockVerify(key_block, len, NULL, 1)) { + fprintf(stderr, "Warning: %s keyblock is invalid. " + "Signing the entire FW FMAP region...\n", + state->name); + goto whatever; + } + RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key); + if (!rsa) { + fprintf(stderr, "Warning: %s public key is invalid. " + "Signing the entire FW FMAP region...\n", + state->name); + goto whatever; + } uint32_t more = key_block->key_block_size; VbFirmwarePreambleHeader *preamble = (VbFirmwarePreambleHeader *)(state->my_area->buf + more); uint32_t fw_size = preamble->body_signature.data_size; + struct cb_area_s *fw_body_area = 0; switch (state->component) { case CB_FMAP_VBLOCK_A: @@ -111,8 +127,11 @@ int futil_cb_sign_fw_preamble(struct futil_traverse_state_s *state) } /* Update the firmware size */ + fprintf(stderr, "HEY: set FW size from %d to %d\n", + fw_body_area->len, fw_size); fw_body_area->len = fw_size; +whatever: state->my_area->_flags |= AREA_IS_VALID; return 0; diff --git a/tests/futility/data_bios_peppy_mp_no_vblock.bin_expect.txt b/tests/futility/data_bios_peppy_mp_no_vblock.bin_expect.txt new file mode 100644 index 00000000..616530c5 --- /dev/null +++ b/tests/futility/data_bios_peppy_mp_no_vblock.bin_expect.txt @@ -0,0 +1,6 @@ +fc68bcb88bf9af1907289a9f377d658b3b9fe5b0 +bf39d0d3e30cbf6a121416d04df4603ad5310779 +e2c1c92d7d7aa7dfed5e8375edd30b7ae52b7450 +5d2b220899c4403d564092ada3f12d3cc4483223 +e2c1c92d7d7aa7dfed5e8375edd30b7ae52b7450 +5d2b220899c4403d564092ada3f12d3cc4483223 diff --git a/tests/futility/test_resign_firmware.sh b/tests/futility/test_resign_firmware.sh index d72ea05b..b1e397a3 100755 --- a/tests/futility/test_resign_firmware.sh +++ b/tests/futility/test_resign_firmware.sh @@ -21,6 +21,15 @@ ${SCRIPTDIR}/data/bios_peppy_mp.bin ${SCRIPTDIR}/data/bios_zgb_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}" + count=0 for infile in $INFILES; do @@ -97,6 +106,26 @@ for infile in $INFILES; do 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} show ${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} show ${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 + # cleanup -rm -rf ${TMP}* +rm -rf ${TMP}* ${ONEMORE} exit 0 |