Greetings Coreboot community!
I’m currently engaged in an effort to bring support for vboot on the Asus KGPE-D16 for use in the Heads boot environment. Things had been going well until I hit a bit of a snag detailed below.
In both situations below vboot was started in the romstage by defining VBOOT_STARTS_IN_ROMSTAGE as true, VBOOT_VBNV_OFFSET was defined and corresponds to cmos.layout and VBOOT_NO_BOARD_SUPPORT defined as true. The coreboot version in use is 4.11. In both situations coreboot builds without error.
Situation 1 (working):
A flashmap (.fmd) is used spanning a 16M rom with the about the first half dedicated to RW_SECTION_A, a bit in the middle for MISC_RW and about the second half dedicated to WP_RO (including GBB) with COREBOOT(CBFS) aligned at the end. VBOOT_SLOTS_RW_A is defined as true.
Monitoring the console output via serial, it is noted that vboot passes Phase 1, 2, 3 and 4 without error. It is also noted that during Phase 3, area GBB is found and area VBLOCK_A is found. The payload is launched.
Situation 2 (not working):
There is no `RW_SECTION_A` in the flashmap, a few hundred kilobytes is allocated to `MISC_RW` at the begging the the remainder is occupied by `WP_RO` as above. VBOOT_SLOTS_RW_A is left undefined (and is not configured further by `make olddefconfig`.
Monitoring the console output in this situation notes that Phase 1 and 2 passes, Phase 3 begins and area GBB is found followed by `Reboot requested (100a0003)`, `Saving nvdata` and `board_reset() called`. The system will reboot (presumably) indefinitely.
I presume based on the difference in the logs that in situation 2 vboot is looking for `VBLOCK_A`, not finding it, failing and rebooting but vboot isn’t very verbose so I find it difficult to find the fault and ultimately, the solution.
While I understand the KGPE-D16 was dropped in 4.12 things are really looking hopeful for having this supported under Heads. Providing I can pass this roadblock, this will be the only blob free, RYF certified, Qubes compatible board that has firmware verifiable provided a compatible TPM is used.
Thank you for taking the time to read this, and I welcome any feedback.
Kind regards,
Thomas
Hi Thomas,
On Tue, Oct 6, 2020 at 11:07 AM Thomas Clarke via coreboot < coreboot@coreboot.org> wrote:
This sounds correct to me based on what you are describing. The error code you are looking for is here: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/refs... (VB2_ERROR_EX_READ_RESOURCE_SIZE). If you grep through coreboot's sources for that, you'll find it in `src/security/vboot/vboot_logic.c`, where it is going to load either the GBB or VBLOCK_{A,B} (depending on the slot), and if it is unable to either locate or read from those, then it will return that error, and vboot will be stuck in that reboot loop forever (that kind of sounds like a bug somewhere; this is a fatal error, a reboot won't fix this issue).
Since you mention the logs say it found the GBB, then it sounds like it either can't read the GBB or one of the VBLOCK_{A,B} section is missing, as you point out.
That sounds like a worthy project!
Good luck, - Tim
Hi Tim thanks for getting back to me,
Your correct in the error spawns from `src/security/vboot/vboot_logic.c`. I took the liberty of having the `name` variable printed to the console to confirm what regions were being read. `GBB` (appears) to read without error however, despite leaving `VBOOT_SLOTS_RW_A` undefined (and not in the .fmd) it appears that `VBLOCK_A` is still attempted to be read.
My understanding was that when using a read-only flashmap for use in vboot, a `VBLOCK_A` section was not required, is this correct? I can add a `VBLOCK_A` section but it is not populated unless `VBOOT_SLOTS_RW_A` is defined, and make will fail due to no CBFS in `RW_SECTION_A`.
Thanks again!
Kind regards,
Thomas
On Tuesday, October 6, 2020 6:21 PM, Tim Wawrzynczak via coreboot coreboot@coreboot.org wrote:
/coreboot@coreboot.org/coreboot@coreboot.org
Hi Thomas,
I think the combination you're trying to build just doesn't work and isn't really supposed to work, honestly. Unfortunately, the current state of those Kconfig options was implemented by contributors who weren't the primary vboot developers and pushed through somewhat hastily without really working out what option combinations make sense. There have been a couple of discussions about how this should be changed for the better (although I can't really find them anymore right now, some random Gerrit CLs two years ago) but I think basically it's just been stuck like this for a while with nobody having the time or pressure to clean things up.
vboot was originally designed to be used with VBOOT_SLOTS_RW_AB, that's the most supported and most tested mode. I guess running it with VBOOT_SLOTS_RW_A should also work, although some of the internal logic is going to get a bit confused about the missing slot B, but eventually it should end up falling into the correct high-level behavior (that when slot A is broken, it falls into recovery mode). But building vboot without any RW slots makes no sense: the whole point of vboot is to verify RW slots. Without RW slots you don't need vboot. If your whole flash is write-protected (and therefore trusted) anyway, there's no reason to cryptographically verify any of it on boot.
The third combination that would actually make sense is to have one RW slot but to have no recovery mode fallback in the RO_SECTION. That would be what you want for the tiniest possible flash usage, basically (accepting the risk that if the RW_A section becomes corrupted your device would just be a brick). But that combination is currently not implemented.
Hi Julius,
Actually the behaviour you described in the 'third combination' I've been able to achieve by having a tiny RO_SECTION and a large RW_A and excluding the payload from being written to the RO_SECTION. It just felt a bit like cheating but I may invest more time into it to see if its usable. Ultimately the goal (at this time) is to have measured boot by expanding hashs into PCR's which can be verified by the end user using TOTP.
Another question if I may, does the behaviour you described apply to 4.12 also? I ask as there are a lot of boards that have a vboot-ro.fmd. Would these also fail for the reasons you have described or is there better support for this in 4.12 opposed to 4.11?
Regards,
Thomas-------- Original Message -------- On 9 Oct 2020, 10:53 pm, Julius Werner wrote:
Actually the behaviour you described in the 'third combination' I've been able to achieve by having a tiny RO_SECTION and a large RW_A and excluding the payload from being written to the RO_SECTION. It just felt a bit like cheating but I may invest more time into it to see if its usable.
Well yeah, you can leave out the payload and that may be the biggest part for you. But technically you could also leave out romstage and ramstage in that situation, and the build system currently doesn't yet offer an option to allow that.
Ultimately the goal (at this time) is to have measured boot by expanding hashs into PCR's which can be verified by the end user using TOTP.
Note that measured boot is independent from verified boot. The main point of verified boot is to allow keeping a part of the flash writable so it can be updated but is still cryptographically verified. If you don't care about that, you can just write-protect your whole flash and only enable CONFIG_TPM_MEASURED_BOOT. (Or, you know, not write-protect anything, but then both measured and verified boot become somewhat pointless because your trust anchor is not secure.)
Another question if I may, does the behaviour you described apply to 4.12 also? I ask as there are a lot of boards that have a vboot-ro.fmd. Would these also fail for the reasons you have described or is there better support for this in 4.12 opposed to 4.11?
Are you talking about coreboot versions? Sorry, I don't follow the tags we cut super closely. The behavior I described has been pretty much unchanged since 2018, I think (so long before 4.12 or 4.11).