Hi Nico, Krystian.
This feature sounds in general quite nice as it will improve the user experience for the firmware update scenario and align with the standard scenarios available out there nowadays.
From the implementation point of view it looks a bit tricky to me: We do weave two independent projects (coreboot and Tianocore) quite a lot together in order to accomplish this task. Though there might be justifications to do that (coreboot owns SMM and unrestricted flash access can most complete be done from SMM while EDK II is the place to which the OS communicates to in order to provide the capsule), we should be careful doing so. There is just this one configuration out there which uses this feature (both sides, coreboot and Tianocore, need to enable capsule update). How shall be make sure that either side stays functional and will not logically break when the independent projects are getting developed further over the future?
Do you plan to add any kind of unit test to both projects so that it can be guaranteed? Because I otherwise fear that this feature can break quite easy without being noticed by both communities on time.
Is there a way forward to reduce the intersection between coreboot and Tianocore by limiting the task coreboot needs to serve, maybe to just temporarily disable the flash write protection? This way the update could be implemented mostly on Tianocore side reducing the dependencies a lot.
Regards Werner
Hi Nico,
On 11.07.24 13:17, Beata Skierka wrote:
We are pleased to announce the launch of a project by 3mdeb aimed at integrating UEFI Capsule Update for coreboot with EDK II as a payload. This initiative aims to bring the capsule-based update method, providing an alternative to the traditional flashrom-based method, which becomes more and more difficult
to
implement, due to the restricted OS-level access to the firmware storage.
I wonder if this is the only incentive? Because it seems like an unfortunate myth :-/ You generally have these restrictions when using the user-space drivers. However, there are also kernel dri- vers and interfaces (e.g. `spi-intel` and the MTD interface in Linux). Flashrom and Flashprog both have a `linux_mtd` driver for this.
Those drivers can't handle all of the protection mechanisms, for example SMM BWP (BIOS Write Protection) can only be disabled by a reset (bugs like broken S3 resume or misconfigured GPIO that would allow accessing the pins directly to bit-bang raw commands don't count).
So flash access shouldn't be a problem in general. Of course it needs to be secured, but that's independent of the way that gets the actual update to the program that writes it to the flash.
One of the main goals is also to ease the integration and firmware update deployments via the fwupd for devices running open-source firmware (based on coreboot + EDK II).
Is fwupd still Linux only? Because on Linux flashing should be ea- sier than in firmware. It may need some work on the kernel drivers but that's probably far, far less effort. Just because the update is performed by firmware doesn't mean that the user has to interact with it directly. Flashing can be initialized from OS, but it can also be done by UEFI app in case of lack of support for capsules in OS.
Yes, AFAICT fwupd is Linux only. However, this isn't the only software that uses capsules to perform the update, Windows also uses it (although this would require creating and distributing firmware as drivers through Windows Update, which is beyond the scope of this project). Linux can also be compiled with EFI_CAPSULE_LOADER [1] which exposes an interface for sending capsules to the firmware by a simple write to file. Can it really get easier than `cat firmware.bin > /dev/efi_capsule_loader` [2]?
For a detailed project outline, please visit our Dasharo documentation [1].
This left me wondering: Where in the process are signatures verified? And which parts are signed? each chunk that is gathered from memory individually? or only the coalesced data? If it's the latter, we'd likely have a lot of code that is processing / influenced by untrusted input. Then I would strongly recommend not to implement it in C. SPARK would be the language of my choice. It integrates well with coreboot.
Signatures are verified by edk2, on coalesced data. There are decisions made earlier based on presence of data, not on it's content. This is why we will take care to not allow booting an OS with full access to flash enabled when edk2 decides that the capsule isn't valid.
I doubt that SPARK integrates with edk2 as nicely as it does with coreboot. That said, we don't have any professional SPARK / Ada developers in our team (at least nobody mentioned it), which leaves us with C. Another thing that I didn't get yet: Why is coreboot involved? Couldn't edk2 gather the capsule chunks from memory? Because it is coreboot that applies flash write protections, which must temporarily be lifted for edk2 to perform the update. coreboot also implements code for writing to flash (as an extension of SMMSTORE_V2), so edk2 doesn't even need to be aware of each chipset's unique way of interacting with the SPI controller.
Capsule chunks are possibly written by the OS, after UEFI Boot Services are terminated and their memory regions potentially overwritten. This may include memory region to which coreboot loads the payload, so it must be aware of which regions to avoid. As it requires traversing through scatter-gather list anyway, copying the data to coalesced form at that point is easy, and it helps in avoiding accidentally overwriting capsules data when the payload is loaded. [1]
https://github.com/torvalds/linux/blob/v6.10/drivers/firmware/efi/Kconfig#L1 24
[2]
https://lore.kernel.org/all/1454042394-21507-1-git-send-email-hock.leong.kwe h@intel.com/T/
Best regards, Krystian