diff options
author | Jakub Czapiga <jacz@semihalf.com> | 2022-04-07 14:44:44 +0200 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-06-30 14:55:17 +0000 |
commit | 9ae9d2c03f42b25238f803a26ebae4902541317e (patch) | |
tree | 4fb994c865757570ca5a40a5b376e7779dc9a584 /tests | |
parent | 57eb6ea8e8ebf6ecb859815ef15b962a38803bd2 (diff) | |
download | vboot-9ae9d2c03f42b25238f803a26ebae4902541317e.tar.gz |
futility/file_type_bios: Rework image signing
This patch reworks whole BIOS image signing to support images with CBFS,
and with ponly RW/A slot. CBFS images will now be truncated to eliminate
unnecessary empty space, and will sign only the part of firmware area
which contains the data, and not empty space.
This patch also adds more checks for potential errors, and does not
allow for signing incorrect nor uses data from structures, which might
not be valid.
futility sign command tests are also greatly extended to cover a wide
variety of possible errors, which have to be handled correctly.
BUG=b:197114807
TEST=sudo emerge vboot_reference
TEST=build whole chromeos-bootimage after making it and coreboot use
`futility sign --type bios ...`
TEST=make runtests
BRANCH=none
Signed-off-by: Jakub Czapiga <jacz@semihalf.com>
Cq-Depend: chromium:3707104
Change-Id: I7c84aa38776e8890a87f0e9b7ec7f32d86f82c13
Disallow-Recycled-Builds: test-failures
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3575325
Tested-by: Jakub Czapiga <czapiga@google.com>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Auto-Submit: Jakub Czapiga <czapiga@google.com>
Commit-Queue: Jakub Czapiga <czapiga@google.com>
Diffstat (limited to 'tests')
30 files changed, 431 insertions, 37 deletions
diff --git a/tests/futility/data/README b/tests/futility/data/README index 933de029..3d577b82 100644 --- a/tests/futility/data/README +++ b/tests/futility/data/README @@ -2,3 +2,6 @@ These are officially signed BIOS images from existing Chromebooks. bios_link_mp.bin uses the RO_NORMAL flag to skip RW firmware validation bios_peppy_mp.bin doesn't do any of those things + +This is dev-signed BIOS image with CBFS support: + bios_voxel_dev.bin diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_data_key_offset_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_data_key_offset_too_big.xxd.patch new file mode 100644 index 00000000..cb79555c --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_data_key_offset_too_big.xxd.patch @@ -0,0 +1 @@ +00200050: b808 0000 0000 0000 0804 0000 0000 0000 ................ diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_data_key_size_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_data_key_size_big.xxd.patch new file mode 100644 index 00000000..8667c3f9 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_data_key_size_big.xxd.patch @@ -0,0 +1 @@ +00200050: 2000 0000 0000 0000 3412 0100 0000 0000 .......4....... diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_fmap_too_small.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_fmap_too_small.xxd.patch new file mode 100644 index 00000000..2c01f2aa --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_fmap_too_small.xxd.patch @@ -0,0 +1,2 @@ +00610100: 0000 0000 0000 0000 0100 0000 2000 6e00 ............ .n. +00610110: 0000 5642 4c4f 434b 5f41 0000 0000 0000 ..VBLOCK_A...... diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_fmap_too_small_for_whole.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_fmap_too_small_for_whole.xxd.patch new file mode 100644 index 00000000..3d797038 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_fmap_too_small_for_whole.xxd.patch @@ -0,0 +1,2 @@ +00610100: 0000 0000 0000 0000 0100 0000 2000 b608 ............ ... +00610110: 0000 5642 4c4f 434b 5f41 0000 0000 0000 ..VBLOCK_A...... diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_data_size_too_small.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_data_size_too_small.xxd.patch new file mode 100644 index 00000000..4f284d90 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_data_size_too_small.xxd.patch @@ -0,0 +1 @@ +00200040: 6c00 0000 0000 0000 1700 0000 0000 0000 l............... diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_invalid_contents.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_invalid_contents.xxd.patch new file mode 100644 index 00000000..8b5fefd2 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_invalid_contents.xxd.patch @@ -0,0 +1 @@ +00200470: babb 3f4b 95db d458 4142 4344 4142 4344 ..?K...XABCDABCD diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_offset_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_offset_too_big.xxd.patch new file mode 100644 index 00000000..1a7044cf --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_offset_too_big.xxd.patch @@ -0,0 +1 @@ +00200030: 9808 0000 0000 0000 4000 0000 0000 0000 ........@....... diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_size_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_size_too_big.xxd.patch new file mode 100644 index 00000000..e6d90bf8 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_hash_size_too_big.xxd.patch @@ -0,0 +1 @@ +00200030: 4804 0000 0000 0000 b808 0000 0000 0000 H............... diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_invalid_magic.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_invalid_magic.xxd.patch new file mode 100644 index 00000000..00015e2e --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_invalid_magic.xxd.patch @@ -0,0 +1 @@ +00200000: 4142 4344 4143 4244 0200 0000 0100 0000 ABCDACBD........ diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_invalid_major_version.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_invalid_major_version.xxd.patch new file mode 100644 index 00000000..637b90ac --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_invalid_major_version.xxd.patch @@ -0,0 +1 @@ +00200000: 4348 524f 4d45 4f53 0200 0000 0200 0000 CHROMEOS........ diff --git a/tests/futility/data/bios_peppy_dev.bad_keyblock_size_not_fully_signed.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_keyblock_size_not_fully_signed.xxd.patch new file mode 100644 index 00000000..1a24d433 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_keyblock_size_not_fully_signed.xxd.patch @@ -0,0 +1 @@ +00200010: 7604 0000 0000 0000 a004 0000 0000 0000 v............... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_body_signature_offset_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_body_signature_offset_too_big.xxd.patch new file mode 100644 index 00000000..31408e53 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_body_signature_offset_too_big.xxd.patch @@ -0,0 +1 @@ +00200900: 0100 0000 0000 0000 7408 0000 0000 0000 ........t....... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_body_signature_size_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_body_signature_size_too_big.xxd.patch new file mode 100644 index 00000000..083cfbe6 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_body_signature_size_too_big.xxd.patch @@ -0,0 +1 @@ +00200910: 7408 0000 0000 0000 183c 0200 0000 0000 t........<...... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_fmap_too_small.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_fmap_too_small.xxd.patch new file mode 100644 index 00000000..0f0968dd --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_fmap_too_small.xxd.patch @@ -0,0 +1,2 @@ +00610100: 0000 0000 0000 0000 0100 0000 2000 ee08 ............ ... +00610110: 0000 5642 4c4f 434b 5f41 0000 0000 0000 ..VBLOCK_A...... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_fmap_too_small_for_whole.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_fmap_too_small_for_whole.xxd.patch new file mode 100644 index 00000000..bd756243 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_fmap_too_small_for_whole.xxd.patch @@ -0,0 +1,2 @@ +00610100: 0000 0000 0000 0000 0100 0000 2000 2411 ............ .$. +00610110: 0000 5642 4c4f 434b 5f41 0000 0000 0000 ..VBLOCK_A...... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_header_version_major.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_header_version_major.xxd.patch new file mode 100644 index 00000000..456a753d --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_header_version_major.xxd.patch @@ -0,0 +1 @@ +002008d0: 7406 0000 0000 0000 0300 0000 0100 0000 t............... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_header_version_minor.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_header_version_minor.xxd.patch new file mode 100644 index 00000000..140b44e1 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_header_version_minor.xxd.patch @@ -0,0 +1 @@ +002008d0: 7406 0000 0000 0000 0200 0000 0000 0000 t............... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_kernel_subkey_offset_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_kernel_subkey_offset_too_big.xxd.patch new file mode 100644 index 00000000..3c5a14c7 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_kernel_subkey_offset_too_big.xxd.patch @@ -0,0 +1 @@ +002008f0: 7408 0000 0000 0000 0700 0000 0000 0000 t............... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_kernel_subkey_size_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_kernel_subkey_size_too_big.xxd.patch new file mode 100644 index 00000000..3c5a14c7 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_kernel_subkey_size_too_big.xxd.patch @@ -0,0 +1 @@ +002008f0: 7408 0000 0000 0000 0700 0000 0000 0000 t............... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_signature_data_size_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_data_size_too_big.xxd.patch new file mode 100644 index 00000000..f23f2e11 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_data_size_too_big.xxd.patch @@ -0,0 +1 @@ +002008d0: 8408 0000 0000 0000 0200 0000 0100 0000 ................ diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_signature_data_size_too_small.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_data_size_too_small.xxd.patch new file mode 100644 index 00000000..b02b4976 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_data_size_too_small.xxd.patch @@ -0,0 +1 @@ +002008d0: 6400 0000 0000 0000 0200 0000 0100 0000 d............... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_signature_invalid_contents.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_invalid_contents.xxd.patch new file mode 100644 index 00000000..0fed2fe6 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_invalid_contents.xxd.patch @@ -0,0 +1,2 @@ +00200f20: 78c9 3a24 85ab ca17 498e c238 4142 4344 x.:$....I..8ABCD +00200f30: 4142 4344 1cef bf68 b86b cdbc 3782 9f85 ABCD...h.k..7... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_signature_offset_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_offset_too_big.xxd.patch new file mode 100644 index 00000000..5159fef1 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_offset_too_big.xxd.patch @@ -0,0 +1 @@ +002008c0: 7408 0000 0000 0000 0002 0000 0000 0000 t............... diff --git a/tests/futility/data/bios_peppy_dev.bad_preamble_signature_size_too_big.xxd.patch b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_size_too_big.xxd.patch new file mode 100644 index 00000000..9afc0abf --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bad_preamble_signature_size_too_big.xxd.patch @@ -0,0 +1 @@ +002008c0: 6c06 0000 0000 0000 7408 0000 0000 0000 l.......t....... diff --git a/tests/futility/data/bios_peppy_dev.bin b/tests/futility/data/bios_peppy_dev.bin Binary files differnew file mode 100644 index 00000000..f241cd03 --- /dev/null +++ b/tests/futility/data/bios_peppy_dev.bin diff --git a/tests/futility/data/bios_voxel_dev.bin b/tests/futility/data/bios_voxel_dev.bin Binary files differnew file mode 100644 index 00000000..7cd85355 --- /dev/null +++ b/tests/futility/data/bios_voxel_dev.bin diff --git a/tests/futility/data/bios_voxel_dev.no_b_slot.xxd.patch b/tests/futility/data/bios_voxel_dev.no_b_slot.xxd.patch new file mode 100644 index 00000000..6a01277c --- /dev/null +++ b/tests/futility/data/bios_voxel_dev.no_b_slot.xxd.patch @@ -0,0 +1,20 @@ +01804030: 0000 0000 0000 1e00 0000 0000 0000 5000 ..............P. +018043a0: 0000 0000 0000 0000 0000 c0ff 4f01 4000 ............O.@. +018043b0: 0000 5257 5f46 5749 445f 4200 0000 0000 ..RW_FWID_B..... +018043d0: 0000 0000 0000 5001 0000 3000 4d45 5f52 ......P...0.ME_R +018043e0: 575f 4200 0000 0000 0000 0000 0000 0000 W_B............. +018043f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ +01804400: 8001 0000 8000 5750 5f52 4f00 0000 0000 ......WP_RO..... +01804420: 0000 0000 0000 0000 0000 8001 0040 0000 .............@.. +01804430: 524f 5f56 5044 0000 0000 0000 0000 0000 RO_VPD.......... +01804450: 0800 0040 8001 00c0 7f00 524f 5f53 4543 ...@......RO_SEC +01804460: 5449 4f4e 0000 0000 0000 0000 0000 0000 TION............ +01804470: 0000 0000 0000 0000 0000 0000 0040 8001 .............@.. +01804480: 0008 0000 464d 4150 0000 0000 0000 0000 ....FMAP........ +018044a0: 0000 0000 0000 0048 8001 4000 0000 524f .......H..@...RO +018044b0: 5f46 5249 4400 0000 0000 0000 0000 0000 _FRID........... +018044d0: 0050 8001 0000 0700 4742 4200 0000 0000 .P......GBB..... +018044f0: 0000 0000 0000 0000 0000 0050 8701 00b0 ...........P.... +01804500: 7800 434f 5245 424f 4f54 0000 0000 0000 x.COREBOOT...... +01804520: 0000 0000 0050 8701 00b0 7800 434f 5245 .....P....x.CORE +01804530: 424f 4f54 0000 0000 0000 0000 0000 0000 BOOT............ diff --git a/tests/futility/data_bios_voxel_dev.bin_expect.txt b/tests/futility/data_bios_voxel_dev.bin_expect.txt new file mode 100644 index 00000000..60cd1eab --- /dev/null +++ b/tests/futility/data_bios_voxel_dev.bin_expect.txt @@ -0,0 +1,6 @@ +b11d74edd286c144e1135b49e7f0bc20cf041f10 +c14bd720b70d97394257e3e826bd8f43de48d4ed +e2c1c92d7d7aa7dfed5e8375edd30b7ae52b7450 +5d2b220899c4403d564092ada3f12d3cc4483223 +e2c1c92d7d7aa7dfed5e8375edd30b7ae52b7450 +5d2b220899c4403d564092ada3f12d3cc4483223 diff --git a/tests/futility/test_sign_firmware.sh b/tests/futility/test_sign_firmware.sh index 587eed9f..c373803f 100755 --- a/tests/futility/test_sign_firmware.sh +++ b/tests/futility/test_sign_firmware.sh @@ -10,24 +10,90 @@ TMP="${me}.tmp" cd "$OUTDIR" KEYDIR="${SRCDIR}/tests/devkeys" +DATADIR="${SCRIPT_DIR}/futility/data" # 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=" -${SCRIPT_DIR}/futility/data/bios_link_mp.bin -${SCRIPT_DIR}/futility/data/bios_peppy_mp.bin +${DATADIR}/bios_link_mp.bin +${DATADIR}/bios_peppy_mp.bin +" + +# BIOS image containing CBFS RW/A and RW/B, and signed with developer keys. +GOOD_CBFS="${DATADIR}/bios_voxel_dev.bin" + +# BIOS image containing CBFS RW/A and RW/B, and signed with developer keys. +INFILES="${INFILES} +${GOOD_CBFS} " # 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="${SCRIPT_DIR}/futility/data/bios_peppy_mp.bin" +GOOD_VBLOCKS="${DATADIR}/bios_peppy_mp.bin" ONEMORE=bios_peppy_mp_no_vblock.bin +CLEAN_B=bios_peppy_mp_clean_b_slot.bin cp "${GOOD_VBLOCKS}" "${ONEMORE}" +cp "${GOOD_VBLOCKS}" "${CLEAN_B}" + +GOOD_DEV="${DATADIR}/bios_peppy_dev.bin" + +NO_B_SLOT_PATCH="${DATADIR}/bios_voxel_dev.no_b_slot.xxd.patch" + +BAD_KEYBLOCK_PATCHES=( +"${DATADIR}/bios_peppy_dev.bad_keyblock_data_key_offset_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_data_key_size_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_hash_data_size_too_small.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_hash_invalid_contents.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_hash_offset_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_hash_size_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_invalid_magic.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_invalid_major_version.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_size_not_fully_signed.xxd.patch" +) + +BAD_PREAMBLE_PATCHES=( +"${DATADIR}/bios_peppy_dev.bad_preamble_body_signature_offset_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_body_signature_size_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_header_version_major.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_header_version_minor.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_kernel_subkey_offset_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_kernel_subkey_size_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_signature_data_size_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_signature_data_size_too_small.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_signature_invalid_contents.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_signature_offset_too_big.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_signature_size_too_big.xxd.patch" +) + +BAD_FMAP_KEYBLOCK_PATCHES=( +"${DATADIR}/bios_peppy_dev.bad_keyblock_fmap_too_small_for_whole.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_keyblock_fmap_too_small.xxd.patch" +) + +BAD_FMAP_PREAMBLE_PATCHES=( +"${DATADIR}/bios_peppy_dev.bad_preamble_fmap_too_small_for_whole.xxd.patch" +"${DATADIR}/bios_peppy_dev.bad_preamble_fmap_too_small.xxd.patch" +) + "${FUTILITY}" load_fmap "${ONEMORE}" VBLOCK_A:/dev/urandom VBLOCK_B:/dev/zero INFILES="${INFILES} ${ONEMORE}" +# args: xxd_patch_file input_file +function apply_xxd_patch { + xxd -r "${1}" "${2}" +} + +# args: file1 file2 +function cmp_first_line { + cmp <(head -n1 "${1}") <(head -n1 "${2}") +} + +function cmp_last_line { + cmp <(tail -n1 "${1}") <(tail -n1 "${2}") +} + set -o pipefail count=0 @@ -44,33 +110,6 @@ for infile in $INFILES; do 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 ${BIN_DIR}/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" \ @@ -94,10 +133,7 @@ for infile in $INFILES; do # 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" - + "FW_MAIN_A:${loemdir}/fw_main_A" "FW_MAIN_B:${loemdir}/fw_main_B" "${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ --fv "${loemdir}/fw_main_A" \ @@ -118,6 +154,7 @@ 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" +GOOD_CBFS_OUT="${TMP}.${GOOD_CBFS##*/}.new" "${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" "${GOOD_OUT}" \ | awk '/Firmware body size:/ {print $4}' > "${TMP}.good.body" @@ -135,9 +172,52 @@ if cmp "${TMP}.good.body" "${TMP}.good.fw_main"; then false; fi cmp "${TMP}.onemore.body" "${TMP}.onemore.fw_main" cmp "${TMP}.onemore.body" "${TMP}.good.fw_main" +"${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ + "${GOOD_CBFS_OUT}" \ + | awk '/Firmware body size:/ {print $4}' > "${TMP}.good_cbfs.body" +"${FUTILITY}" dump_fmap -p "${GOOD_CBFS_OUT}" \ + | awk '/FW_MAIN_/ {print $3}' > "${TMP}.good_cbfs.fw_main" +if cmp "${TMP}.good_cbfs.body" "${TMP}.good_cbfs.fw_main"; then false; fi -# 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. + +# Sign CBFS image after adding new files. Size should increase but still be +# smaller than FlashMap size. +: $(( count++ )) +echo -n "${count} " 1>&3 + +cp "${GOOD_CBFS_OUT}" "${GOOD_CBFS_OUT}.1" +truncate -s 512 "${TMP}.zero_512" +cbfstool "${GOOD_CBFS_OUT}.1" expand -r FW_MAIN_A,FW_MAIN_B +cbfstool "${GOOD_CBFS_OUT}.1" add \ + -r FW_MAIN_A,FW_MAIN_B -f "${TMP}.zero_512" -n new-data-file -t raw + +"${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + "${GOOD_CBFS_OUT}.1" + +"${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ + "${GOOD_CBFS_OUT}.1" \ + | awk '/Firmware body size:/ {print $4}' > "${TMP}.good_cbfs.1.body" +"${FUTILITY}" dump_fmap -p "${GOOD_CBFS_OUT}" \ + | awk '/FW_MAIN_/ {print $3}' > "${TMP}.good_cbfs.1.fw_main" + +# Check if size increased, but also if it was correctly truncated, +# so it does not span over whole FlashMap area. +[[ $(head -n1 "${TMP}.good_cbfs.body") \ + < $(head -n1 "${TMP}.good_cbfs.1.body") ]] +[[ $(tail -n1 "${TMP}.good_cbfs.body") \ + < $(tail -n1 "${TMP}.good_cbfs.1.body") ]] +[[ $(head -n1 "${TMP}.good_cbfs.1.body") \ + < $(head -n1 "${TMP}.good_cbfs.1.fw_main") ]] +[[ $(tail -n1 "${TMP}.good_cbfs.1.body") \ + < $(tail -n1 "${TMP}.good_cbfs.1.fw_main") ]] + + +# Sign image again but don't specify the version or the preamble flags. +# The firmware version and preamble flags should be preserved. +# NOTICE: Version preservation behavior changed from defaulting to 1. : $(( count++ )) echo -n "${count} " 1>&3 @@ -148,7 +228,7 @@ echo -n "${count} " 1>&3 "${MORE_OUT}" "${MORE_OUT}.2" m=$("${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ - "${MORE_OUT}.2" | grep -c -E 'Firmware version: +1$|Preamble flags: +8$') + "${MORE_OUT}.2" | grep -c -E 'Firmware version: +14$|Preamble flags: +8$') [ "${m}" = "4" ] @@ -168,6 +248,262 @@ m=$("${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ [ "${m}" = "4" ] +# Check signing when B slot is empty +: $(( count++ )) +echo -n "${count} " 1>&3 + +"${FUTILITY}" load_fmap "${CLEAN_B}" VBLOCK_B:/dev/zero FW_MAIN_B:/dev/zero +"${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + "${CLEAN_B}" "${CLEAN_B}.1" + +"${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" "${CLEAN_B}.1" \ + | awk '/Firmware body size:/ {print $4}' > "${TMP}.clean_b.body" +"${FUTILITY}" dump_fmap -p "${CLEAN_B}.1" \ + | awk '/FW_MAIN_/ {print $3}' > "${TMP}.clean_b.fw_main" + +# These should not be equal, as FW_MAIN_A size should be kept intact, when size +# of FW_MAIN_B should be taken from FlashMap. +if cmp "${TMP}.clean_b.body" "${TMP}.clean_b.fw_main" ; then false; fi +if cmp "${TMP}.clean_b.body" "${TMP}.good.body" ; then false; fi +cmp_first_line "${TMP}.clean_b.body" "${TMP}.good.body" +cmp_last_line "${TMP}.clean_b.body" "${TMP}.clean_b.fw_main" + +# Version for slot A should be kept intact, while for B slot it should default +# to 1. All flags should be zero. +m=$("${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ + "${CLEAN_B}.1" \ + | grep -c -E \ + 'Firmware version: +1$|Preamble flags: +0$|Firmware version: +2$') +[ "${m}" = "4" ] + +# Check signing when there is no B slot +: $(( count++ )) +echo -n "${count} " 1>&3 + +NO_B_SLOT="${TMP}.${GOOD_CBFS##*/}.no_b_slot" +NO_B_SLOT_SIGNED_IMG="${NO_B_SLOT}.signed" + +cp "${GOOD_CBFS}" "${NO_B_SLOT}" +apply_xxd_patch "${NO_B_SLOT_PATCH}" "${NO_B_SLOT}" + +"${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + -v 1 \ + "${NO_B_SLOT}" "${NO_B_SLOT_SIGNED_IMG}" + +"${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ + "${NO_B_SLOT_SIGNED_IMG}" \ + | awk '/Firmware body size:/ {print $4}' > "${TMP}.no_b_slot.body" +"${FUTILITY}" dump_fmap -p "${NO_B_SLOT_SIGNED_IMG}" \ + | awk '/FW_MAIN_/ {print $3}' > "${TMP}.no_b_slot.fw_main" + +if cmp "${TMP}.no_b_slot.body" "${TMP}.no_b_slot.fw_main" ; then false; fi +cmp "${TMP}.no_b_slot.body" <(tail -n1 "${TMP}.good_cbfs.body") + +m=$("${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" \ + "${NO_B_SLOT_SIGNED_IMG}" \ + | grep -c -E 'Firmware version: +1$|Preamble flags: +0$') +[ "${m}" = "2" ] + +# Check signing when cbfstool reports incorrect size +# Signing should fail, as it should not be possible for CBFS contents to be +# bigger than FlashMap size of the area +: $(( count++ )) +echo -n "${count} " 1>&3 + +CBFSTOOL_STUB="$(realpath "${TMP}.cbfs_stub.sh")" +echo -en 'echo "0xFFEEDD0"; exit 0;' > "${CBFSTOOL_STUB}" +chmod +x "${CBFSTOOL_STUB}" + +if CBFSTOOL="${CBFSTOOL_STUB}" "${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + -v 1 \ + "${GOOD_CBFS}" "${TMP}.1.${GOOD_CBFS##*/}" +then + false +fi + +# Redefine cbfstool stub to return valid value for FW_MAIN_A and invalid for +# FW_MAIN_B size. With this behavior futility should fail to sign this image, +# as cbfstool should never return incorrect size (larger than area). +cp "${GOOD_CBFS}" "${TMP}.good_cbfs.bin" +FW_MAIN_A_SIZE="$(printf '0x%x' \ + "$(cbfstool "${TMP}.good_cbfs.bin" truncate -r FW_MAIN_A)")" +MARK_FILE="$(realpath "${TMP}.mark1")" +rm -f "${MARK_FILE}" + +cat << EOF > "${CBFSTOOL_STUB}" +#!/usr/bin/env bash +if ! [ -f "${MARK_FILE}" ]; then + echo "${FW_MAIN_A_SIZE}"; + echo 1 > "${MARK_FILE}"; +else + echo 0xFFFFAA0; +fi +exit 0; +EOF + +if CBFSTOOL="${CBFSTOOL_STUB}" "${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + -v 1 \ + "${GOOD_CBFS}" "${TMP}.2.${GOOD_CBFS##*/}" +then + false +fi + + +# Check various incorrect values in VBLOCK (keyblock and preamble) +: $(( count++ )) +echo -n "${count} " 1>&3 + +bad_counter=1 +for keyblock_patch in "${BAD_KEYBLOCK_PATCHES[@]}"; do + echo -n "${count}.${bad_counter} " 1>&3 + BAD_IN="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.in.bin" + BAD_OUT="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.out.bin" + cp "${GOOD_DEV}" "${BAD_IN}" + apply_xxd_patch "${keyblock_patch}" "${BAD_IN}" + + FUTIL_OUTPUT="$(if "${FUTILITY}" verify \ + --publickey "${KEYDIR}/root_key.vbpubk" "${BAD_IN}"; \ + then false; fi)" + grep -q 'VBLOCK_A keyblock component is invalid' <<< "${FUTIL_OUTPUT}" + + FUTIL_OUTPUT="$("${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + "${BAD_IN}" "${BAD_OUT}" 2>&1)" + grep -q 'VBLOCK_A keyblock is invalid' <<< "${FUTIL_OUTPUT}" + + "${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" "${BAD_OUT}" \ + | awk '/Firmware body size:/ {print $4}' > "${BAD_OUT}.body" + "${FUTILITY}" dump_fmap -p "${BAD_OUT}" \ + | awk '/FW_MAIN_/ {print $3}' > "${BAD_OUT}.fw_main" + + cmp "${BAD_OUT}.fw_main" "${TMP}.good.fw_main" + cmp_first_line "${BAD_OUT}.body" "${TMP}.good.fw_main" + cmp_last_line "${BAD_OUT}.body" "${TMP}.good.body" + + : $(( bad_counter++ )) +done + +for vblock_patch in "${BAD_PREAMBLE_PATCHES[@]}"; do + echo -n "${count}.${bad_counter} " 1>&3 + BAD_IN="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.in.bin" + BAD_OUT="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.out.bin" + cp "${GOOD_DEV}" "${BAD_IN}" + apply_xxd_patch "${vblock_patch}" "${BAD_IN}" + + FUTIL_OUTPUT="$(if "${FUTILITY}" verify \ + --publickey "${KEYDIR}/root_key.vbpubk" "${BAD_IN}"; \ + then false; fi)" + grep -q 'VBLOCK_A is invalid' <<< "${FUTIL_OUTPUT}" + + FUTIL_OUTPUT="$("${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + "${BAD_IN}" "${BAD_OUT}" 2>&1)" + grep -q 'VBLOCK_A preamble is invalid' <<< "${FUTIL_OUTPUT}" + + "${FUTILITY}" verify --publickey "${KEYDIR}/root_key.vbpubk" "${BAD_OUT}" \ + | awk '/Firmware body size:/ {print $4}' > "${BAD_OUT}.body" + "${FUTILITY}" dump_fmap -p "${BAD_OUT}" \ + | awk '/FW_MAIN_/ {print $3}' > "${BAD_OUT}.fw_main" + + cmp "${BAD_OUT}.fw_main" "${TMP}.good.fw_main" + cmp_first_line "${BAD_OUT}.body" "${TMP}.good.fw_main" + cmp_last_line "${BAD_OUT}.body" "${TMP}.good.body" + + : $(( bad_counter++ )) +done + +for vblock_patch in "${BAD_FMAP_KEYBLOCK_PATCHES[@]}"; do + echo -n "${count}.${bad_counter} " 1>&3 + BAD_IN="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.in.bin" + BAD_OUT="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.out.bin" + cp "${GOOD_DEV}" "${BAD_IN}" + apply_xxd_patch "${vblock_patch}" "${BAD_IN}" + + FUTIL_OUTPUT="$(if "${FUTILITY}" verify \ + --publickey "${KEYDIR}/root_key.vbpubk" "${BAD_IN}"; \ + then false; fi)" + grep -q 'VBLOCK_A keyblock component is invalid' <<< "${FUTIL_OUTPUT}" + + FUTIL_OUTPUT="$(if "${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + "${BAD_IN}" "${BAD_OUT}" 2>&1; \ + then false; fi)" + m="$(grep -c -E \ + 'VBLOCK_A keyblock is invalid|Keyblock and preamble do not fit in VBLOCK' \ + <<< "${FUTIL_OUTPUT}")" + [ "${m}" = "2" ] + + : $(( bad_counter++ )) +done + +echo -n "${count}.${bad_counter} " 1>&3 +BAD_IN="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.in.bin" +BAD_OUT="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.out.bin" +cp "${GOOD_DEV}" "${BAD_IN}" +apply_xxd_patch "${BAD_FMAP_PREAMBLE_PATCHES[0]}" "${BAD_IN}" + +FUTIL_OUTPUT="$(if "${FUTILITY}" verify \ + --publickey "${KEYDIR}/root_key.vbpubk" "${BAD_IN}"; \ + then false; fi)" +grep -q 'VBLOCK_A is invalid' <<< "${FUTIL_OUTPUT}" + +FUTIL_OUTPUT="$(if "${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + "${BAD_IN}" "${BAD_OUT}" 2>&1; \ + then false; fi)" +m="$(grep -c -E \ + 'VBLOCK_A preamble is invalid|Keyblock and preamble do not fit in VBLOCK' \ + <<< "${FUTIL_OUTPUT}")" +[ "${m}" = "2" ] + +: $(( bad_counter++ )) + +echo -n "${count}.${bad_counter} " 1>&3 +BAD_IN="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.in.bin" +BAD_OUT="${TMP}.${GOOD_DEV##*/}.bad.${bad_counter}.out.bin" +cp "${GOOD_DEV}" "${BAD_IN}" +apply_xxd_patch "${BAD_FMAP_PREAMBLE_PATCHES[1]}" "${BAD_IN}" + +FUTIL_OUTPUT="$(if "${FUTILITY}" verify \ + --publickey "${KEYDIR}/root_key.vbpubk" "${BAD_IN}"; \ + then false; fi)" +grep -q 'VBLOCK_A is invalid' <<< "${FUTIL_OUTPUT}" + +FUTIL_OUTPUT="$(if "${FUTILITY}" sign \ + -s "${KEYDIR}/firmware_data_key.vbprivk" \ + -b "${KEYDIR}/firmware.keyblock" \ + -k "${KEYDIR}/kernel_subkey.vbpubk" \ + "${BAD_IN}" "${BAD_OUT}" 2>&1; \ + then false; fi)" +m="$(grep -c -E \ + -e 'VBLOCK_A is invalid\. Keyblock and preamble do not fit' \ + -e 'Keyblock and preamble do not fit in VBLOCK' \ + <<< "${FUTIL_OUTPUT}")" +[ "${m}" = "2" ] + +: $(( bad_counter++ )) + + # cleanup rm -rf "${TMP}"* "${ONEMORE}" exit 0 |