Re: Linux DRTM on UEFI platforms
On 3/31/22 09:13, Ard Biesheuvel wrote: On Thu, 31 Mar 2022 at 02:36, Daniel P. Smith wrote: Greetings Matthew, First thank you to you and James for taking time out of your busy schedules to sit down with us and work through all of this. Hey Ard, On 3/30/22 03:02, Ard Biesheuvel wrote:>> 1) From an EFI maintainer perspective, is making the contract between the boot stub and the kernel explicit viable? No. The direction of travel has been to define EFI boot only in terms of the handover from the loader to the stub. What happens next is up to the architecture, and is deliberately not specified, because it is considered to be internal Linux ABI. We've deviated from this once for Xen on ARM, but this means we have already painted ourselves into a corner when it comes the way we use DT internally at the handover point between stub and kernel proper, and I am not eager to repeat that. Locking down the stub-to-kernel protocol for all architectures is not the way to go. To help provide some visual context, for EFI today there is, bzImage [EFI boot manager] -> [[efi-stub] -> [setup kernel] -> [main kernel]] Where the efi-stub is responsible for interacting with firmware to configure the system, store that configuration for the setup kernel and the main kernel, and then call EBS before entering the setup kernel. For Secure Launch the flow (on Intel) is, CPU instruction bzImage [preamble] -> [ACM] -> [[sl-stub] -> [setup kernel] -> [main kernel]] In order to make the CPU instruction call to enter the ACM the system must be in a very specific quiescent state. This includes but not exhaustively, * EBS must have been called * TPM should have all localities closed * IOMMU PMRs must be programmed appropriately * TXT heap space allocated * TXT heap space populated with config structures * All APs must be in a specific idle state * Execution is on the BSP Carrying all this out is what is considered the DRTM preamble. Thanks for the explanation, this is really helpful. This is the wrinkle because the setup kernel and main kernel are both predicated on the efi-stub and the efi-stub is predicated on running before EBS. Matthew suggested this already, but can you explain why handling this in a callback is not an option? I'd by sympathetic to specifying a The idea of the UEFI specification is that it is OS agnostic. So anything that is Linux-, Windows-, BSD-, etc. specific should not live in the UEFI firmware. If you want to implement any Linux specific extra protocol, you should implement it in Shim, GRUB, the kernel stub or any other UEFI binary loaded by the UEFI firmware but, please, don't rely on the UEFI firmware itself to implement it. If you are able to abstract the requirements for furthering secure boot in a way that is OS agnostic, then implementation in the UEFI firmware starts to make sense. But remember that there is a large installed base that is still lagging behind the current UEFI standard. Best regards Heinrich Linux specific protocol that can be grabbed before EBS() but can be invoked after (but not, say after SetVirtualAddressMap(), to keep things simple). That should allow us to call back into firmware to perform the secure launch right before handing over. My other suggestion, to use a minimal EFI environment just to boot the kernel, still seems viable to me as well, but it would boil down to mostly the same, thing, i.e., to inject an intermediate boot stage between the call to the firmware's EBS() and calling the entrypoint of the kernel proper. What I do like about this approach is that the EFI stub could execute unprivileged, which means the secure launch kernel could track *exactly* what the EFI stub is doing in terms of memory accesses and protocol invocations, which seems a bit more robust than the approximation of 'this might be interesting enough to measure' that the industry seems to have settled on. So how can this wrinkle be addressed? The TrenchBoot project proposed that the information collected by the efi-stub be formally documented for two reasons, 1. to allow the sl-stub to be aware of what and where all external data is being injected into the kernel so any data that may be security critical could be measured, and 2. it would allow third parties, e.g. GRUB, could correctly configure the system, pass all EFI related information correctly to the setup kernel and the main kernel before executing the preamble. Where the former is more of a concern than enabling the latter. The reason I am not willing to lock down the stub<->kernel boot protocol is because it doesn't scale: currently, the discussion is about x86, which is a bit different because we already so many ways to boot it, but for other architectures, this is going to create a huge maintenance burden: arm64, RISC-V and now LoongArch are all adding EFI boot support and are looking to support ACPI,
Re: Linux DRTM on UEFI platforms
On Thu, 31 Mar 2022 at 02:36, Daniel P. Smith wrote: > > Greetings Matthew, > > First thank you to you and James for taking time out of your busy > schedules to sit down with us and work through all of this. > > Hey Ard, > > On 3/30/22 03:02, Ard Biesheuvel wrote:>> 1) From an EFI maintainer > perspective, is making the contract between > >> the boot stub and the kernel explicit viable? > >> > > > > No. The direction of travel has been to define EFI boot only in terms > > of the handover from the loader to the stub. What happens next is up > > to the architecture, and is deliberately not specified, because it is > > considered to be internal Linux ABI. We've deviated from this once for > > Xen on ARM, but this means we have already painted ourselves into a > > corner when it comes the way we use DT internally at the handover > > point between stub and kernel proper, and I am not eager to repeat > > that. Locking down the stub-to-kernel protocol for all architectures > > is not the way to go. > > To help provide some visual context, for EFI today there is, > > bzImage > [EFI boot manager] -> [[efi-stub] -> [setup kernel] -> [main kernel]] > > Where the efi-stub is responsible for interacting with firmware to > configure the system, store that configuration for the setup kernel and > the main kernel, and then call EBS before entering the setup kernel. > > For Secure Launch the flow (on Intel) is, > > CPU instruction bzImage > [preamble] -> [ACM] -> [[sl-stub] -> [setup kernel] -> [main kernel]] > > In order to make the CPU instruction call to enter the ACM the system > must be in a very specific quiescent state. This includes but not > exhaustively, > * EBS must have been called > * TPM should have all localities closed > * IOMMU PMRs must be programmed appropriately > * TXT heap space allocated > * TXT heap space populated with config structures > * All APs must be in a specific idle state > * Execution is on the BSP > Carrying all this out is what is considered the DRTM preamble. > Thanks for the explanation, this is really helpful. > This is the wrinkle because the setup kernel and main kernel are both > predicated on the efi-stub and the efi-stub is predicated on running > before EBS. Matthew suggested this already, but can you explain why handling this in a callback is not an option? I'd by sympathetic to specifying a Linux specific protocol that can be grabbed before EBS() but can be invoked after (but not, say after SetVirtualAddressMap(), to keep things simple). That should allow us to call back into firmware to perform the secure launch right before handing over. My other suggestion, to use a minimal EFI environment just to boot the kernel, still seems viable to me as well, but it would boil down to mostly the same, thing, i.e., to inject an intermediate boot stage between the call to the firmware's EBS() and calling the entrypoint of the kernel proper. What I do like about this approach is that the EFI stub could execute unprivileged, which means the secure launch kernel could track *exactly* what the EFI stub is doing in terms of memory accesses and protocol invocations, which seems a bit more robust than the approximation of 'this might be interesting enough to measure' that the industry seems to have settled on. > So how can this wrinkle be addressed? The TrenchBoot project > proposed that the information collected by the efi-stub be formally > documented for two reasons, 1. to allow the sl-stub to be aware of what > and where all external data is being injected into the kernel so any > data that may be security critical could be measured, and 2. it would > allow third parties, e.g. GRUB, could correctly configure the system, > pass all EFI related information correctly to the setup kernel and the > main kernel before executing the preamble. Where the former is more of a > concern than enabling the latter. > The reason I am not willing to lock down the stub<->kernel boot protocol is because it doesn't scale: currently, the discussion is about x86, which is a bit different because we already so many ways to boot it, but for other architectures, this is going to create a huge maintenance burden: arm64, RISC-V and now LoongArch are all adding EFI boot support and are looking to support ACPI, SMBIOS and other features as well, and these are all gated on EFI boot, which requires booting via the stub. I'm not eager to kick this can down the road and go with something that inevitably implies either specifying and maintaining a whole array of internal protocols as external ABI, or revisiting this discussion and coming up with two different ways to do DRTM depending on whether you are running x86 or not. > Relating to what information is security critical, this can be a bit > subjective. For example Dave Weston has a twitter thread[1][2][3] over > what state Azure Attestation can validate for a DRTM Windows system. >