You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the LZ was first created a rough layout of the binary was devised. As the code has evolved the layout has languished a bit and it needs to be revisited. An approach needs to be devised and implemented that ensures only static/predictable information is in the region measured by SKINIT instruction while providing a means for the bootloader to communicate setup details to the LZ.
Tasks
Establish a detailed layout and boot protocol
Update LZ with the new layout and protocol
Update GRUB implementation
The text was updated successfully, but these errors were encountered:
My notes on the subject below. Opinions are welcome.
List of constant fields, can/should/must be measured:
SL header, two fields required by SKINIT
MSB key hash
UUID - not sure about this one, it may be used to locate/validate location of bootloader data
version number/capabilities of boot protocol to enable changes in the future without breaking compatibility
The hashes of LZ also have to be included somewhere to be included in the event log. While they are constant, they cannot be located in the measured part or the hashes would change, obviously.
List of data passed by bootloader:
data used by the boot protocol of the kernel
pointer to zero page for Linux boot protocol
pointer to MBI, kernel size for Multiboot2
possible future protocols
event log address and size
I also had an idea about some kind of "I know it is not secure, but I really want to boot it nonetheless" switch that would clear R_INIT and do STGI in the LZ. The former one is done in the LZ already, but it should be kernel's responsibility.
The size of kernel boot protocol data passed by the bootloader depends on the given protocol. It may get bigger for the new protocols implemented. For that reason, and to keep additions to the LZ boot protocol relatively painless, a structure similar to Multiboot2 boot information may be created by a bootloader, located in the unmeasured part of SLB.
The contents of data provided by a bootloader should be measured, as it controls the flow of the LZ. Should we use PCR18 or leave that one for kernel's measurements and use a different one for this?
It seems that much of the precious space is wasted by alignment of structures. Right now, all page-aligned structures are located at the end of measured part of LZ, as a consequence of this the bootloader data is also page-aligned. This gives at least 4K bytes used for a structure that is just over a hundred bytes long.
To improve this situation, we can move all page-aligned data to the very beginning of SLB and just fix up the first 4 bytes (used by SKINIT) in code. If the first page would be the Device Table for the IOMMU, the SL length field would overlay a part of the Page Table Root Pointer which is not used for a simple "block everything" IOMMU configuration. We can leave that field unmodified and read it later from the kernel, if necessary (e.g. in order to get access to the TPM Event Log), so only the SL entry point offset must be overwritten, which is no longer useful.
The downside of that approach is that we cannot put too many other fields into the SLB header, so the rest of the constant data listed above must be located in another structure. We can use next 16 bits of the Page Table Root Pointer to hold the pointer to that structure.
Description
When the LZ was first created a rough layout of the binary was devised. As the code has evolved the layout has languished a bit and it needs to be revisited. An approach needs to be devised and implemented that ensures only static/predictable information is in the region measured by SKINIT instruction while providing a means for the bootloader to communicate setup details to the LZ.
Tasks
The text was updated successfully, but these errors were encountered: