Fit images and EFI_LOAD_FILE2_PROTOCOL

Ard Biesheuvel ardb at kernel.org
Sat Oct 3 18:59:48 CEST 2020


On Sat, 3 Oct 2020 at 18:35, Heinrich Schuchardt <xypron.glpk at gmx.de> wrote:
>
> On 10/3/20 3:12 PM, Ard Biesheuvel wrote:
> >
> >
> > On Sat, 3 Oct 2020 at 13:16, François Ozog <francois.ozog at linaro.org
> > <mailto:francois.ozog at linaro.org>> wrote:
> >
> >
> >
> >     Le sam. 3 oct. 2020 à 13:14, François Ozog <francois.ozog at linaro.org
> >     <mailto:francois.ozog at linaro.org>> a écrit :
> >
> >
> >
> >         Le sam. 3 oct. 2020 à 10:51, Heinrich Schuchardt
> >         <xypron.glpk at gmx.de <mailto:xypron.glpk at gmx.de>> a écrit :
> >
> >             Hello Ilias, hello Christian,
> >
> >
> >
> >             with commit ec80b4735a59 ("efi_loader: Implement FileLoad2
> >             for initramfs
> >
> >             loading") Ilias provided the possibility to specify a device
> >             path
> >
> >             (CONFIG_EFI_INITRD_FILESPEC) from which an initial RAM disk
> >             can be
> >
> >             served via the EFI_FILE_LOAD2_PROTOCOL.
> >
> >
> >
> >             Ard extended the Linux EFI stub to allow loading the initial
> >             RAM disk
> >
> >             via the EFI_FILE_LOAD2_PROTOCOL with the utmost priority.
> >
> >
> >
> >             With commit ecc7fdaa9ef1 ("bootm: Add a bootm command for type
> >
> >             IH_OS_EFI") Cristian enabled signed FIT images that contain
> >             a device
> >
> >             tree and a UEFI binary (enabled by CONFIG_BOOTM_EFI=y).
> >
> >
> >
> >             In the DTE calls we have discussed that it is unfortunate
> >             that we do not
> >
> >             have a method to validate initial RAM images in the UEFI
> >             context.
> >
> >
> >
> >             To me it would look like a good path forward to combine the
> >             two ideas:
> >
> >
> >
> >             * Let the signed FIT image (of type IH_OS_EFI) contain a RAM
> >             disk
> >
> >             * Pass location and size to the UEFI subsystem and serve
> >             them via
> >
> >               the EFI_FILE_LOAD2_PROTOCOL.
> >
> >
> >
> >             We could also extend the bootefi command to be callable as
> >
> >
> >
> >                bootefi $kernel_addr_r $ramdisk_addr_r:$filesize $fdt_addr_r
> >
> >
> >
> >             like the booti command to serve an initial RAM disk.
> >
> >
> >
> >             What are your thoughts?
> >
> >         that looks super interesting.
> >         I propose something (in the latest desk preparing oct 14th)
> >         similar except the an efi application boots the FIT.
> >         I view UEFI as booting a PE coff and pass a set of config
> >         tables. Today we have DTB, we could just add Initrd (you command
> >         line). Bootefi would be responsible to valide the containing FIT
> >         before pushing initrd (and dTB?)into the table. It would be the
> >         responsibility of the efi stub to get the initrd from the config
> >         table (GUID to be defined).
> >
> >     the memory attributes of the initrd config table should be such that
> >     it can be recovered for normal use. That may be tricky though.
> >
> >
> > The purpose of the EFI_FILE_LOAD2_PROTOCOL based initrd loading
> > mechanism is to allow the EFI stub (which is tightly coupled to the
> > kernel arch/version/etc) to allocate the memory for the initrd, and pass
> > it into the LoadFile2() request, using whichever policy it wants to
> > adhere to for alignment, offset and/or vicinity of the kernel image. It
> > also ensures that any measurement performed by the bootloader for
> > attestation or authentication can be delayed to the point where the
> > booting kernel assumes ownership of the initrd contents, preventing
> > potential TOCTOU issues where intermediate boot stages are involved
> > (shim+grub etc)
>
> Any UEFI binary that you invoke can overwrite the complete system table
> and replace the existing UEFI API by its own implementation which may be
> malicious.
>

I don't see how this has anything to do with what I wrote above.

> So the EFI_FILE_LOAD2_PROTOCOL does not provide any safety guarantees
> whatsoever.
>
> Either you have a chain of trust or not. If you have a chain of trust,
> it is sufficient that user input, e.g. an initrd loaded from disk is
> verified once.
>
> >
> > Creating an initrd config table would mean that the bootloader decides
> > where to load the initrd in memory, and only passesthe address and size.
> > This is exactly what we wanted to avoid, because now, the bootloader has
> > to know all these different rules that vary between kernel version,
> > configurations and architectures.
> >
> > For uboot's implementation of FIT based EFI_FILE_LOAD2_PROTOCOL, this
> > might mean that the initrd is loaded into memory first, and copied to
> > another location (and [re-]authenticated) when LoadFile2() is invoked. I
> > don't think this is a problem in the general case, but we might think
> > about ways to avoid this if this turns out to be a problem for memory
> > constrained devices with huge initrds.
> >
> >
>
> Securitywise this all makes no difference. See above.
>

Yes it does. TPM based measured boot could be used for local
attestation, e.g., to seal the rootfs encryption keys against the
measurements of the boot stages. This is especially useful for
initrds, given that they are created on the target, and so signing
them would involve a secret key on the target as well.

Whether or not measured boot is being used is a platform policy, and
so it is up to the firmware to take the measurement at the right time.
Having a callback from the OS when it is ready to consume the initrd
is a far better moment to take this measurement than some earlier
time, e.g., before interactive boot loaders like GRUB or mokmanager
can be invoked.


More information about the U-Boot mailing list