Hi Michał,

Sorry for being more confused than helpful on this topic in the
meeting. As usual, once one has 5 minutes to sit down and calmly think
the problem through, things became much clearer. :D

So, at the fundamental level, vboot is a mechanism (based on PKI
crypto) to verify a mutable part of firmware (RW) from an immutable
part of firmware (RO), so that the mutable part can get regular
updates while the immutable part remains trusted. That is its entire
reason for existence. If you don't need that, then you don't need
vboot and all its RSA signature stuff.

What you're proposing here is that the topswap RW bootblock+verstage
remain mutable (and maybe protected by some other mechanism involving
flash protection registers and capsule updates and stuff). In that
case, you don't need PKI crypto, you don't need RSA keys. You can
simply use hash-based verification only, which is basically what
CBFS_VERIFICATION is (which can be used without vboot), because every
time you update your romstage/ramstage/etc. (meaning their hashes
change), you can also update your bootblock (which stores the top
metadata hash that all those other file hashes are verified from). The
only situations where you ever really need PKI keys and signatures are
situations where you want something that cannot be updated to verify
something that can be updated, and that's no longer the case for the
model you want.

So let's talk about the solution you want in a vacuum first, without
relating to vboot: I don't think you can have both a "recovery" slot
and A/B update slots at the same time, because that requires three
separate slots and you only have two. You will need to decide which of
the two options (recovery+normal or A+B) you care about more. To
clarify, by "recovery" slot I mean a slot that will always have
exactly the code your device was first built with (ideally ensured by
hard write-protection). This is mostly useful if you're worried that
some bug or malicious attack might erase all the writable firmware
flash and disk on your system, so that you will still have some
firmware left to recover from. However, to allow this your recovery
firmware actually needs to be able to do that recovery all by itself
(without assuming that there's still something on the disk it can
boot, because when someone erases all your firmware flash they'll
probably also erase your disk). On Chromebooks, we do that by letting
it boot from a USB stick, but if you don't have a mechanism like that
in your bootloader payload, a recovery slot is probably not that
important to you. (Also, if you use other mechanisms like flash
protection registers to protect the rest of your firmware, maybe this
scenario isn't as relevant to you.)

An A/B slot system, on the other hand, means that you always have one
"active" slot that you boot out of and one "update" slot that you can
safely write new updates to. This allows you to both protect against
asynchronous resets during the update, and to fall back from the
updated version to the older version if the update didn't work for
some reason. In this case, both of those slots need to be mutable
(from the perspective of your update system, not necessarily from your
running OS). I assume(?) that this is probably more what you care
about in your situation.

So if we want to design an A/B update system based on topswap, we need
a flash layout that's split into two areas (let's say RW_SECTION_A and
RW_SECTION_B, but no RO_SECTION) which each contain a separate CBFS.
You probably also need extra sections for the bootblock outside of
those CBFSes since the topswap mechanism requires those to be in a
special place, let's call those BOOTBLOCK_A and BOOTBLOCK_B. You also
need some mechanism to select which of the two bootblocks to boot
(this must be provided by the Intel hardware already, right? How do
they do that? Via CMOS?). If you want the "fall back to older version
when newer version doesn't work" thing, then you also need some extra
NVRAM mechanism (e.g. CMOS) to store a counter that can be decremented
by your bootblock every time it attempts to boot the new slot
(however, note that if the new bootblock itself gets corrupted during
the update, or is so broken that it doesn't even reach the part where
it updates the try counter, the system may not be so easily
recoverable... unless Intel themselves integrated a try counter
mechanism directly in the topswap hardware?).

From a coreboot build perspective, you need the CBFS verification from
BOOTBLOCK_A to tie through to the CBFS in RW_SECTION_A and from
BOOTBLOCK_B to the CBFS in RW_SECTION_B. We could try to make cbfstool
aware of all that, but maybe the easier option is that cbfstool only
knows about BOOTBLOCK_A and RW_SECTION_A, and you only copy the entire
sections into the B slots when you are performing an update. So
basically, while the flash image is in a file only the A slot is
valid, but when your system wants to do an update and the A slot is
currently active (meaning B is the target slot for the update), your
update system would flash BOOTBLOCK_A and RW_SECTION_A from the new
image file into BOOTBLOCK_B and RW_SECTION_B on your flash. (This
requires that all code including the bootblock itself is
position-independent, I'm not sure if that's true nowadays on x86? Or
can be made true by moving the page table setup a bit earlier, maybe?
Otherwise, the build and update process would become a lot more
complicated.)

I think this scheme would be so different from vboot that it probably
wouldn't make sense to try to integrate it into vboot as a separate
option. Because vboot is a solution built around PKI crypto
verification and you don't need the PKI crypto part. The only things
worth reusing for what you need might be the NVRAM storage solution
(but the underlying code to access CMOS NVRAM in coreboot is outside
of vboot anyway) and maybe a small part of the slot selection logic.
It would basically be like trying to design a new car based on an
existing model, but the only thing you want to keep are the tires and
the windshield wipers (and not the chassis or the engine). I think
designing this as a completely separate new mechanism (based on the
underlying CBFS_VERIFICATION) makes more sense.
_______________________________________________
coreboot mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to