Skip to content

verified_boot_app.md: Add application requirements specification #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: verified_boot_app_notes
Choose a base branch
from

Conversation

miczyg1
Copy link
Member

@miczyg1 miczyg1 commented May 5, 2025

No description provided.

@pietrushnic pietrushnic self-requested a review May 7, 2025 07:17
Copy link
Member

@pietrushnic pietrushnic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t.b.c.

-->

1.4. The application MUST be OS/HW vendor agnostic and NOT subject to any
branding.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have to decide if we prevent branding or we at this point allow branding, allowing branding can improve adoption IMHO

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this dual layer?

    1. Keep the specification agonist.
    1. The implementation itself might be branded: "$vendor_specific_feature based on $specification"?

There is no need to say anything about branding at this stage. Perhaps simply drop this sentence?

Copy link
Collaborator

@ArrayBolt3 ArrayBolt3 May 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should take branding into account - if we don't, more likely than not the finished product will end up un-brandable which could be a dealbreaker for some vendors. The ability to at least include the vendor's name in a somewhat easy fashion (changing a configuration file or even a C #define at build time, or passing an option to a configure script) would be nice and should be sufficient for a text-only interface. If the UI is going to be graphical, the ability to add a logo too would be nice, but I don't think this needs to be graphical.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we are not discussing implementation yet, nor are mockups needed anyway, but after closing the spec stage.

I would say the application MAY be brandable, but I guess the ultimate decision should be to @adrelanos ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answered in matrix a while ago.

MAY is ok. 3MDEB shall decide.

Comment on lines 160 to 162
2.10. The keys, certificates and bootloaders MAY be stored in different
location on ESP than the default location specified by the operating
system.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use some clarification I think. The operating system isn't the thing that specifies where bootloaders have to be, the firmware (and thus the firmware specifications) are.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the operating system is the thing that places its bootloader on ESP.

It is not the firmware task either to specify where the bootloaders have to be. UEFI Specification only defines the path of the file that is being booted from removable media, e.g. for x64 it is /EFI/BOOT/BOOTX64.EFI. That's the only firmware-defined "bootloader" location. Otherwise, the OS is free to place the bootloader wherever it wants to.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/EFI/BOOT/BOOTX64.EFI should stay supported: Yes. After confirmation, the user should be able to boot it. (Most likely signed by Microsoft key. In rare cases, signed already nowadays by other keys.)

Most likely we will not be able to exclusively use /EFI/BOOT/BOOTX64.EFI. ("EFI legacy")

  • Debian (and presumably other Linux distributions) will refuse to sign /EFI/BOOT/BOOTX64.EFI with two keys. That signing it with Microsoft's key and Debian's own key. This is because they fear two signatures on 1 EFI binary may break compatibility with broken EFI implementations.
  • We therefore MUST (not MAY) support another location such as /EFI/BOOT_ALT/BOOTX64.EFI.
    • The name BOOT_ALT will most likely be signed by distribution (or user) key only. (Such as only signed by Kicksecure's key, Debian's key but most likely not Microsoft's key.)
    • BOOT_ALT is an arbitrary name choice. The folder might have a better name.

If there is both, BOOT and ("EFI legacy") then BOOT_ALT ("EFI user-controlled") exists, then by default the firmware MUST prompt for BOOT_ALT only and ignore BOOT? The firmware MUST still allow other choices after user confirmation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because they fear two signatures on 1 EFI binary may break compatibility with broken EFI implementations.

That's a fair reason.

Broken EFI's and firmwares can be found anywhere though :) And may fail in unexpected ways. There is just too much customization done by IBVs/OEMs which tend to break things.

We therefore MUST (not MAY) support another location such as /EFI/BOOT_ALT/BOOTX64.EFI.
The name BOOT_ALT will most likely be signed by distribution (or user) key only. (Such as only signed by Kicksecure's key, Debian's key but most likely not Microsoft's key.)
BOOT_ALT is an arbitrary name choice. The folder might have a better name.

The thing is that we don't need that BOOT_ALT if the application does a discovery of the bootloaders on its own. The location of such bootloader will not matter. Imposing a fixed directory structure on the user is an extra requirement we don't need IMO.

If there is both, BOOT and ("EFI legacy") then BOOT_ALT ("EFI user-controlled") exists, then by default the firmware MUST prompt for BOOT_ALT only and ignore BOOT? The firmware MUST still allow other choices after user confirmation.

BOOT will be ignored if MS keys are not trusted. Or at least their boot priority will be lower than user-controlled/user-signed bootloaders.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all about getting Linux distributions caring about backwards comparability to start supporting the new convention.

We need a fallback bootloader location. This is in case if booting an ISO / from USB, in case there is no bootloader known yet by the firmware such as first boot ever.

We cannot use \EFI\Boot\bootx64.efi because then distributions such as Debian will be scared to sign it with two keys because it might break comparability with broken EFI implementations.

So we need a different default/fallback bootloader location.

I don't know if we used \EFI\Boot\alt_bootx64.efi if Linux distributions would still scare "that might confuse broken EFI firmware".

So using \EFI_alt\Boot\bootx64.efi seems to have the highest chance to avoid fears of breaking broken EFI firmware.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I want to avoid. A Linux distribution ISO supporting both, EFI_traditional and EFI_ALT should not result in prompting the user with any Microsoft key by default.

Fine, it doesn't have to contain anything signed by MS keys.

Prompting to trust distribution key + Microsoft key would be confusing for users. This is too much of a special status for Microsoft.

Also doesn't have to happen. But I don't see a reason why we should ignore the Microsoft keys (even if we are treating them as a last resort). At least the user will know if the OS he is trying to install, doesn't comply with the requirement of not being signed by Microsoft keys.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I want to avoid. A Linux distribution ISO supporting both, EFI_traditional and EFI_ALT should not result in prompting the user with any Microsoft key by default.

Fine, it doesn't have to contain anything signed by MS keys.

Distributions do not have to, true, but distributions likely want. Reasons:

  • The feasible, economic solution for distributions is to have only 1 ISO.
    • Less confusing.
    • Less build effort.
  • Interested distributions will want to support both:
    • EFI_traditional: The serve the 99% of users that have hardware with EFI_traditional.
    • EFI_ALT: To support users using firmware by (some) security-focused OEMs.

At least the user will know if the OS he is trying to install, doesn't comply with the requirement of not being signed by Microsoft keys.

Non-compliance could be presented in another way. (Rough idea, wording and symbols are TBD.)

Traditional ISO example, here is what the firmware could show:

  • Microsoft Secure Boot: Yes. ✔️
  • Sovereign Secure Boot: Not available. ⛔

EFI_ALT ISO example, here is what the firmware could show:

  • Sovereign Secure Boot: Yes. ✔️

Maybe that would be a way to advertise this feature.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love the name, but I'm not sure if Secure is not implied, so maybe Sovereign Boot?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

Copy link
Collaborator

@ArrayBolt3 ArrayBolt3 May 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this conversation has already run its course or not, but it seems like there's a misunderstanding about "what to implement" and "how to implement it" happening here. Hopefully I can try to clear some things up.

  • Patrick's primary concern, from what I can tell, is avoiding prompting a user with a complicated "Here's all the bootloaders on disk XYZ, which one do you want to start?" dialog when trying to boot an OS that isn't signed by Microsoft's key. If I hand a laptop to someone who is relatively technically unskilled, and upon bootup they get asked whether they want to boot grubx64.efi, shimx64.efi, fbx64.efi, or mmx64.efi, they're going to cry. We don't want crying users, that's sad. Patrick's idea for getting around this while still not requiring trust in Microsoft's key is to have a dedicated alternate fallback bootloader location where a distro can ship a bootloader signed only by the distro themselves (along with the needed key for the bootloader to trust). That way when the system attempts to boot, it will try to boot from that fallback without prompting the user what to boot. Then all the user gets asked is "do you want to trust the people who signed this OS", which is something they will hopefully be able to understand more easily. (@adrelanos)
  • On the other hand, we don't want to break the UEFI spec if it's at all possible. @miczyg1 is pointing out that if we ignore \EFI\BOOT\BOOTX64.efi, we're breaking the spec, and that's not a good thing. His idea is, because we're going to have a dedicated UEFI application for finding bootloaders and offering them to the user, a distro could ship a bootloader anywhere on the drive, and the application will pick them up and offer them to the user. That should allow following the spec perfectly. However, at least from what I gather reading/skimming the above, this would result in the user potentially being prompted with a daunting prompt on first boot, which is the problem Patrick is trying to avoid.

So I think the primary question here is, what will make it so that the user can do something like this:

  • Buy a computer with this special firmware installed,
  • Insert a Debian installation media USB,
  • Power the system on,
  • and get one prompt asking if the user wants to trust Debian before bootup,
  • without breaking the UEFI spec?

If we can make that happen, then I think everyone will be happy. I like @miczyg1's idea of having the UEFI application find all bootloaders on the disk and offer them, but we need some prioritization mechanism so that a distro-signed "normal" bootloader (probably shimx64.efi signed by the distro, not by Microsoft) is the first thing the firmware tries to boot, without user intervention beyond a "do you want to trust the people who signed this OS" prompt.

Obviously, there should be some button a skilled user can press to see all of the available bootloaders and pick whatever one they want. Then we can throw at the user all the "junk" we usually hide with the prioritization mechanism. At that point they've indicated they want to see all that stuff.

AIUI, we're going to need a file that contains the public half of a Secure Boot key that the firmware can find and install if the user chooses to trust the key. Maybe whatever file we store that key in can also store a prioritized list of bootloaders? Then we can do almost exactly what @miczyg1 is saying, and get the UI that @adrelanos is aiming for.

Comment on lines +244 to +266
1. User powers on the platform.
2. Firmware performs boot media enumeration.
3. Firmware detects initial boot or boot with default settings and launches an
application.
4. The application visits all handles with `gEfiSimpleFileSystemProtocolGuid`
and `gEfiPartTypeSystemPartGuid`.
5. For each handle, find operating system bootloader. E.g. GRUB, SHIM, Windows
Boot Manager.
6. For each handle, search for files containing keys and certificates. E.g.
files with `.der`, `.cer`, `.key` extensions.
7. For each bootloader found in step 5, match a key found in step 6 or
`PKDefault`, `KEKDefault`, `dbDefault`, `dbxDefault`.
8. If key not in `dbxDefault`, attempt image verification and report the
result to the user.
9. If verification passed, ask the user to trust the key and optionally offer
to add a boot option.
11. If the user decides to trust the key, the key is added to `DB`.
12. Ask the user to continue boot or proceed with next bootloader verification
(go to step 8).
13. If the user decided to continue boot, ask the user to enroll a `PK` from a
pool of detected keys. Then enable Secure Boot and proceed with booting.
14. If no more bootloaders present and user did not trust any key, go to the
firmware setup menu.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit unclear to me, I can't quite get a picture in my mind of what the user interface will look like as the user chooses what keys to trust or not trust. We want a user interface that is sufficiently simple that if the user only has one OS, they can just mash a "Trust" button and keep going, but powerful enough that if the user has a slew of operating systems, they can tell pretty quickly what bootloaders there are, what keys there are, how they match with each other, which images didn't have any matching key, which keys don't have any matching bootloader, and the identity of the issuer of each key. (Or something similar to this at least.)

Some questions that I think we need to answer to end up with a good, user-friendly design:

  • Should the app trigger if any new untrusted bootloader is detected on the system, or should it only trigger if a trusted bootloader cannot be found and booted? If the latter, how should make it so that the user can manually launch the application even if the system is otherwise bootable for trusting new operating systems that they have introduced into the system?
  • How should we treat not-really-bootloaders that are nonetheless still in the ESP? For instance, fbx64.efi, and mmx64.efi. How do we recognize these so that we don't offer them to the user to boot (or at least don't show them in the main list of bootloaders)?
  • What should the finished UI look like? Do we need some UI mockups? I'd be happy to make some to illustrate what I have in mind if that's something that would be useful.

Copy link
Member Author

@miczyg1 miczyg1 May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flow is deeply technical, thus it may be unclear. I just put your idea from the wiki into how an example implementation could look like. Also this is just the flow of actions done by the application under the hood, not a description of interface exposed to the user.

Should the app trigger if any new untrusted bootloader is detected on the system, or should it only trigger if a trusted bootloader cannot be found and booted? If the latter, how should make it so that the user can manually launch the application even if the system is otherwise bootable for trusting new operating systems that they have introduced into the system?

Like I wrote down in the document, the application would be run on the very first boot and after every settings reset to defaults. I also recommended to run the application when a (previously) trusted bootloader fails verification or there are no bootloaders found. Any manual execution of the application should be made possible by the firmware vendor, by exposing such option in the setup for example.

Another way would be to make firmware always boot the application, then the application would duplicate many parts of the UEFI boot manager built in each UEFI firmware. The application would have to additionally respect the boot options, boot order and other mechanisms defined in UEFI Specification (like BootNext, OSRecovery, etc.) and chainload the bootloader according to the boot options. I would like to avoid it, because it introduces (maybe unnecessary) additional responsibilities to the application beyond the configuration of Verified/Secure Boot. Another reason to avoid it is that many UEFI firmwares are customized and their boot managers may also be. If we design an application that gets in a way of the built-in boot manager, it may impact adoption.

How should we treat not-really-bootloaders that are nonetheless still in the ESP? For instance, fbx64.efi, and mmx64.efi. How do we recognize these so that we don't offer them to the user to boot (or at least don't show them in the main list of bootloaders)?

If we care only about bootloaders, then handling those additional applications is out of scope. I was thinking to look for fixed files, like shim<arch>.efi/grub<arch>.efi (Linux), bootmgfw.efi (Windows), elilo.efi (Red Hat, Suse) or loader.efi (FreeBSD and its derivatives). otherwise the application can inspect the boot options created by the firmware's boot manager.

What should the finished UI look like? Do we need some UI mockups? I'd be happy to make some to illustrate what I have in mind if that's something that would be useful.

I proposed to prepare mockups internally to illustrate the look and feel of the application, however it was rejected and prolonged for a later phase. I suspected that lack of mockups will cause a lot of doubts about the approach and flow. The plan is to use whatever tianocore EDK2 offers. It will look similar to what we have documented in Dasharo here: https://docs.dasharo.com/dasharo-menu-docs/boot-maintenance-mgr/ (the window look, colors, etc.). What the finished UI should look like is still an open question and is probably not subject to the specification. Specification is not the same as implementation. For example the specification define the setup form interactions, events and how to handle them. But there is nothing in the specification that defines the layout of the form, the colors, etc. Thus we have so many different setup menu implementations: graphical, text, semi-graphical. All have different styles and schemes, but under the hood, the interactions must comply with the UEFI specification (the HII and IFR).

Right now the focus is on getting the specification out, it is not the right place to define the UI. The UI may look whatever we like, the specification will just define what scope of tasks the application will be responsible for.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also recommended to run the application when a (previously) trusted bootloader fails verification or there are no bootloaders found. Any manual execution of the application should be made possible by the firmware vendor, by exposing such option in the setup for example.

Good.

Another way would be to make firmware always boot the application, then the application would duplicate many parts of the UEFI boot manager built in each UEFI firmware. The application would have to additionally respect the boot options, boot order and other mechanisms defined in UEFI Specification (like BootNext, OSRecovery, etc.) and chainload the bootloader according to the boot options. I would like to avoid it, because it introduces (maybe unnecessary) additional responsibilities to the application beyond the configuration of Verified/Secure Boot. Another reason to avoid it is that many UEFI firmwares are customized and their boot managers may also be. If we design an application that gets in a way of the built-in boot manager, it may impact adoption.

Agreed. This is best avoided.

otherwise the application can inspect the boot options created by the firmware's boot manager.

As things are already implemented:
https://docs.dasharo.com/dasharo-menu-docs/boot-maintenance-mgr/#add-boot-option shows how to add boot options. As long as secure boot is enabled, each boot option runs a different EFI application.

New:
Prompt for any keys to trust once/always if needed.

That way, no new special handling code for shim<arch>.efi needs to be added. (And anyone else that would need equal treatment such as systemd-boot.)

Copy link
Member Author

@miczyg1 miczyg1 May 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New:
Prompt for any keys to trust once/always if needed.

That will be a bit problematic. Secure Boot has no concept of trust-once. One may put given signature/hash into trusted database, but it will stay there until removed by the user.

As things are already implemented:
https://docs.dasharo.com/dasharo-menu-docs/boot-maintenance-mgr/#add-boot-option shows how to add boot options. As long as secure boot is enabled, each boot option runs a different EFI application.

Yes, and any application is free to modify/add the boot options. And this application will do so.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New:
Prompt for any keys to trust once/always if needed.

That will be a bit problematic. Secure Boot has no concept of trust-once. One may put given signature/hash into trusted database, but it will stay there until removed by the user.

If it's a major hurdle, since it's not crucial, perhaps it's enough for the implementation to point out that keys are trusted until removed by the user.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if we don't include a trust-once feature, I think the ephemeral PK idea is still something we should strongly consider going with. If we don't do it that way, we absolutely have to have a user-managed PK to allow the user full control over what keys they do and don't trust, and that will result in unhappy users. Making the key ephemeral makes it so much easier to handle this kind of thing. It does mean that security vulnerabilities in the firmware could be a problem though (if a malicious user can force their way into firmware setup or into the application without authenticating themselves properly, they can bypass Secure Boot), but hopefully those can be avoided.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BIOS password will not prevent boot order changes.

For embedded systems that have to be locked in, we achieve this by not allowing the platform to boot anything other than an OS signed by the vendor (via UEFI Secure Boot). The BIOS Setup menu has to be password protected. Otherwise, UEFI Secure Boot is useless. Other measures can be taken e.g., sealing the disk password to the state of UEFI Secure Boot or to a state of more options in BIOS Setup, so that any change in platform configuration leads to an unbootable system with data encrypted. This does not prevent attacks on SPI or TPM MITM. For the last one, ultimately, different measures must be considered (Intel Boot Guard, fTPM).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ephemeral key idea sounds really, really good to me. It essentially locks the OS out of modifying Secure Boot settings at all, but allows the firmware to freely modify them as long as it can wipe the PK somehow. Then the only threat (barring software vulns) is an attacker who can get to a firmware menu via physical access, IPMI, or similar, and a BIOS password can prevent that.

Agree.

The only thing that spooks me a bit here is possibly not a concern, but are we considering flash lifespan sufficiently here? Juggling around keys in this fashion will probably result in NVRAM being modified quite a bit if the user chooses to use "trust-once" functionality heavily, and it would be a shame if users who did this ended up bricking their systems by causing premature flash failure.

I don't think this is an issue. First, we never heard (or maybe just a couple of times) about an issue like failure because of wearout. Moreover, Dasharo uses a reference Tianocore implementation of FaultTolerant write and other mechanisms that prevent SPI wearout.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this fully but anything that the user does not need to know about is great.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adrelanos From what I understand, the Platform Key (PK) basically is used to authenticate changes to the Secure Boot keys. If you don't have the private half of the PK, you can't change the Secure Boot keys. The only exception to this rule is if the PK is deleted entirely, in which case UEFI switches to a mode that lets you make arbitrary modifications to the Secure Boot keys until a PK is enrolled. Deleting the PK requires a firmware-specific mechanism (there isn't room in the UEFI spec itself for doing this), but that's something Dasharo can work around.

The usual way things would be done is that the OS would update Secure Boot keys as needed, using information provided by the hardware manufacturer and signed by that manufacturer's PK. If the end-user is acting as their own authority over the Secure Boot keys though, that means they need to manage the PK themselves. If they don't, the whole system won't work...

...unless you simply delete the PK before making any Secure Boot changes. That's the idea @miczyg1 had - make it so that the trust management application we're designing will simply wipe the PK when it is started, so that it can make any needed changes to the Secure Boot keys. Then, when it writes the keys the user has chosen to trust, it will generate a random PK, throw away the private half, enroll the public half, and now the Secure Boot configuration is locked down and can't be modified by anything except for things that can trigger the PK to be deleted. Only the firmware is capable of that, so this effectively means no changes to Secure Boot keys can be made unless you can drop to a firmware menu, but Secure Boot keys can be changed freely if you can drop to a firmware menu. This avoids the user having to manage their own PK, and they can secure their keys against unauthorized tampering by simply preventing access to the firmware menu via a BIOS password.

Comment on lines 177 to 184
2.11. The application SHALL verify the signatures of each bootloader located
on ESP and match it with a key/certificate located either on the ESP or
the default certificate set. The application MUST display the bootloader
path, key information and verification result.

2.12. The application SHALL ask the user to trust the key used to sign each
bootloader, if the key has been found in either ESP or firmware default
key set and the image passes the verification.
Copy link
Member Author

@miczyg1 miczyg1 May 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have looked once again into the UEFI 2.7 spec and found a synergy here with the AuditMode:

Audit Mode enables programmatic discovery of signature list combinations that
successfully authenticate installed EFI images without the risk of rendering a system
unbootable. Chosen signature lists configurations can be tested to ensure the system will
continue to boot after the system is transitioned out of Audit Mode. Details on how to
transition to Audit Mode are detailed below in the section "Transitioning to Audit Mode."
After transitioning to Audit Mode, signature enforcement is disabled such that all images
are initialized and enhanced Image Execution Information Table (IEIT) logging is
performed including recursive validation for multi-signed images.

This is essentially what we need. The application may transition the Secure Boot to Audit Mode, which will cause the PK to be deleted (and without PK we can modify any Secure Boot variable and take control over the keys) without requesting the user to enter the setup and delete the Secure Boot variables manually. Additionally, the firmware should construct Image Execution Information Table for all files the application will attempt to load and verify. So the application will have much less to do. Just parse the table and present the results.

EDK2 does not currently support AuditMode and DeployedMode, but it was once implemented:
tianocore/edk2@79e7b64
tianocore/edk2@0f4f6d2
tianocore/edk2@4fc08e8

Bringing it back shouldn't be a big problem.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather hard for be to understand what that means. Instead, I've described the goal in detail here:

#30 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AuditMode is great code that could be leveraged in the application, giving a lot of introspection into the trust model of the platform we boot, but it is too complex. Also, I would not be surprised if the edk2 implementation were buggy; I tried it and had many problems. This is part of our DS08MSA training, so you can check in the materials how I approached that.

Copy link
Member Author

@miczyg1 miczyg1 May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it is too complex

AuditMode is essentially 70% of what the application will do logic-wise. That implies our application is complex too?

Complexity of a thing is a function of time spent in attempts to understand how given thing works. When you look at something long enough, it becomes less complex. The Secure Boot is probably in such a bad state, because nobody looks at it for long enough. The application is supposed to change it, so we have to deal with that complexity anyways. And if we don't leverage AuditMode, we put even more complexity on our shoulders, because we will need more verification and crypto logic on the application side.

tl;dr

Complexity is not an argument for the core of this application.

Also, I would not be surprised if the edk2 implementation were buggy; I tried it and had many problems.

Yes, this code is a couple of years old. Some refresh is inevitable. but a great base is already there, all we need is to reach and grasp it.

Copy link
Member

@pietrushnic pietrushnic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @ArrayBolt3 that we should start visualizing/mocking something, should be something simple, could be PlantUML diagram or hand drawn flow, but flow analysis is much easier on the graphics. Maybe even online call 1h could move stuff much further by working together.

-->

1.4. The application MUST be OS/HW vendor agnostic and NOT subject to any
branding.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we are not discussing implementation yet, nor are mockups needed anyway, but after closing the spec stage.

I would say the application MAY be brandable, but I guess the ultimate decision should be to @adrelanos ?

1. User powers on the platform.
2. Firmware performs boot media enumeration.
3. Firmware detects initial boot or boot with default settings and launches an
application.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should focus on initial boot and then design the following boot and other potential error paths, like recovery/fallback. Mixing seems to be complex.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just put the use case written down in the wiki in a more technical way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is fine, but what help would it provide here? I thought we placed it here to refine it and make it something we will implement, not as an ephemeral checkbox, just to clean up what was on the wiki.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I did. But it seems I don't understand what Mixing seems to be complex. means or what am I mixing here?

8. If key not in `dbxDefault`, attempt image verification and report the
result to the user.
9. If verification passed, ask the user to trust the key and optionally offer
to add a boot option.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we have a split, two paths can happen here, either the user chooses to add a boot option or not, then it determines what will happen at the next boot.

result to the user.
9. If verification passed, ask the user to trust the key and optionally offer
to add a boot option.
11. If the user decides to trust the key, the key is added to `DB`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the user chooses not to trust?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loop to the next bootloader.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be reflected in documented flow.

3. Firmware attempts to boot a boot option according to boot order.
4. Image pointed by the boot option fails the verification.
5. The firmware launches the application to handle possibly new operating
system or a change in the operating system keys/components.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would firmware know that? I think there is edk2 way to handle recovery, but I cannot recall the correct flow. I have one slide in DS08MSA.

Copy link
Member Author

@miczyg1 miczyg1 May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is described in https://github.com/3mdeb/verified-boot/pull/31/files (Integration Considerations)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, didn't get there yet. Maybe we should decouple to not confuse, or maybe we should start with Integration Consideration and reverse the spec?

Copy link
Member Author

@miczyg1 miczyg1 May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the whole usecase section should be dropped from here and just be a part of the spec...

8. The application present the key to the user and asks to add a new key to
the trusted database `DB` if the verification passes.
9. If the user added the key as trusted, continue to boot. Otherwise go back
to the firmware setup or attempt the next boot option in order.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen if the application finds no suitable bootloader?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go to firmware setup.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have it in flow.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise go back to the firmware setup ??

8. The application present the key to the user and asks to add a new key to
the trusted database `DB` if the verification passes.
9. If the user added the key as trusted, continue to boot. Otherwise go back
to the firmware setup or attempt the next boot option in order.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have it in flow.

3. Firmware attempts to boot a boot option according to boot order.
4. Image pointed by the boot option fails the verification.
5. The firmware launches the application to handle possibly new operating
system or a change in the operating system keys/components.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, didn't get there yet. Maybe we should decouple to not confuse, or maybe we should start with Integration Consideration and reverse the spec?

Comment on lines +244 to +266
1. User powers on the platform.
2. Firmware performs boot media enumeration.
3. Firmware detects initial boot or boot with default settings and launches an
application.
4. The application visits all handles with `gEfiSimpleFileSystemProtocolGuid`
and `gEfiPartTypeSystemPartGuid`.
5. For each handle, find operating system bootloader. E.g. GRUB, SHIM, Windows
Boot Manager.
6. For each handle, search for files containing keys and certificates. E.g.
files with `.der`, `.cer`, `.key` extensions.
7. For each bootloader found in step 5, match a key found in step 6 or
`PKDefault`, `KEKDefault`, `dbDefault`, `dbxDefault`.
8. If key not in `dbxDefault`, attempt image verification and report the
result to the user.
9. If verification passed, ask the user to trust the key and optionally offer
to add a boot option.
11. If the user decides to trust the key, the key is added to `DB`.
12. Ask the user to continue boot or proceed with next bootloader verification
(go to step 8).
13. If the user decided to continue boot, ask the user to enroll a `PK` from a
pool of detected keys. Then enable Secure Boot and proceed with booting.
14. If no more bootloaders present and user did not trust any key, go to the
firmware setup menu.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do commercial vendors achieve this feature? I don't think they are doing it the way you describe.

Can't we imagine a different way of implementing that feature?

1. User powers on the platform.
2. Firmware performs boot media enumeration.
3. Firmware detects initial boot or boot with default settings and launches an
application.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is fine, but what help would it provide here? I thought we placed it here to refine it and make it something we will implement, not as an ephemeral checkbox, just to clean up what was on the wiki.

result to the user.
9. If verification passed, ask the user to trust the key and optionally offer
to add a boot option.
11. If the user decides to trust the key, the key is added to `DB`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be reflected in documented flow.

@miczyg1
Copy link
Member Author

miczyg1 commented May 20, 2025

Starting a new thread here, because I apparently misunderstand the purpose of EFI_ALT.

EFI_ALT has been proposed in the wiki, so that when an ISO with distro installer is booted, it will contain to EFI executables (shim, grub, BOOTX64, etc.) signed with an alternative key. Preferrably the BOOTX64 would be the verified boot application, so that it will be the first EFI executable running to establish the trust relationships and trusted keys.

To sum up information from various thread (that simply became too long to extract relevant facts):

  1. Ignoring EFI/BOOT and prioritizing EFI_ALT essentially means breaking the UEFI spec or a need to modify the spec.
  2. We must not touch files under /EFI/BOOT for distro's compatibility reasons.
  3. The application isn't supposed to be integrated into the firmware(?), but should reside on ESP. And it is the distro's responsibility to put that on ESP (?)
  4. We want to force the firmware to add options to ignore EFI/BOOT and use EFI_ALT.

Ad.1. It is basically a no-go. The adoption rate would be so small and we would need to wait years for new spec and the firmware vendors to pick up new standard. I am not even considering whether ignoring /EFI/BOOT would even be accepted into the new spec version.
Ad.2. If it is a hard requirement, then we have no way to boot the application on the very first system start, assuming we boot an ISO/OS installer from removable media. As @pietrushnic proposed in one of the comments, the ISO should be constructed in a way that the application is /EFI/BOOT/BOOTX64.efi. Then after OS is installed, replace the BOOTX64.efi with shim or whatever the distro needs there. Same answer for point 3.
Ad.4. That won't happen it is against the spec. We also can't expect that the firmware will have empty Secure Boot database (meaning no key will be trusted by default). Major share of the UEFI firmware market will not do that, they care too much about being compatible with Windows. So the application will have to be responsible of wiping out the trusted database.

The best course of action is for the application to manage the boot options and be booted as the default file BOOTX64.efi on the ISO. Because firmware implementation also tend to look for other files like /efi/ubuntu/shimx64.efi and create Ubuntu boot options automatically. It is not described in the spec, but also nto prohibited. To avoid these options getting into the way, the application must take initiative of prioritizing the boot options according to our policies.


As to why in the document I chose UEFI Secure Boot:

  1. As pointed out by @pietrushnic in one of the threads, the application is supposed to secure the chain of trust. UEFI Secure Boot is a standard mechanism for the chain of trust for UEFI firmware (which is, citing, "99%" of the market).
  2. Given that we want to keep the chain of trust we should use standardized mechanisms that are already used in the field, like Secure Boot. If we come up with our own implementation of verified boot, I am afraid we will break the chain of trust. Linux checks the Secure Boot state and based on its state performs lockdown (if enabled). So Secure Boot is needed for the Linux kernel to harden itself. Also without shim and MOK I don't know what will happen to the kernel module verification.
  3. Giving up on Secure Boot would decrease adoption rate. And essentially it would mean that we have to launch the application on each boot, so it would perform the verification with our own implementation.

Although having a trust-once feature with Secure Boot is problematic, and I am not aware such feature exists anywhere, it would not be possible to achieve without firmware modification (which we want to avoid as far as I understand). Without firmware modification the user would have to sign the addition of the key and removal of the key to/from the trusted database. Also the application would have to probably run on each boot to account for that situations, which essentially makes the application an intermediate bootloader rather than application launched when needed.


The whole design decisions I was proposing in this document were to minimize the adoption barrier for the ecosystem and reuse as much existing infrastructure and standards as possible.

I still have to modify some of them, due to the new conclusions present in the comment.

If am am wrong somehwere here please let me know.

And let's start closing some of the threads.

@miczyg1 miczyg1 force-pushed the verified_boot_app_spec branch from 90a55d3 to 52ae96e Compare May 21, 2025 08:47
@adrelanos
Copy link
Collaborator

Ignoring EFI/BOOT and prioritizing EFI_ALT essentially means breaking the UEFI spec or a need to modify the spec.

Ad.1. It is basically a no-go. The adoption rate would be so small and we would need to wait years for new spec and the firmware vendors to pick up new standard. I am not even considering whether ignoring /EFI/BOOT would even be accepted into the new spec version.

Not sure we're talking past each other.

EFI/BOOT would only be ignored if there is an EFI_ALT folder. Why would that harm adoption?

I think this would not harming existing workflows. Windows and non-participating Linux distribution users wouldn't notice. [1]

And those who wish to use EFI_ALT can easily opt-in by providing additional files on the ISO?

The application isn't supposed to be integrated into the firmware(?), but should reside on ESP. And it is the distro's responsibility to put that on ESP (?)

We'd hope that this application would be integrated into Dasharo one day. That's hopefully the next step. That's the goal.

I don't think the application can be located in the ESP because then how would the application itself be verified?

Maybe space is scarce inside the ESP and distributions should be asked to have some files in the ESP. Technical details. That might be OK. TBD.

The "simple" way from my perspective would be if this was a firmware-only feature. No files required in ESP.

Also without shim and MOK I don't know what will happen to the kernel module verification.

We'll have shim and MOK. These layers aren't touched - by design.

The Linux kernel shouldn't notice a difference during the boot process. It's basically just shim, in a different folder, signed by a different key.

I am not even considering whether ignoring /EFI/BOOT would even be accepted into the new spec version.

I am pretty sure this feature would only be picked up by alternative OEMs, the "security-focused OEMs" (there is no good definition for this yet - but one criteria would be, it's the kind of OEMs that are interested in disabling/neutering/etc. Intel ME by default).

While political and opinionated on this point... Speculation: I would also predict that Microsoft won't like this feature. Most OEMs will due to Microsoft's opinion either ignore this feature or even speak up against it. Microsoft might have a vested interested that Linux on desktop computers is more difficult to use than Microsoft Windows. From an economic and competitive viewpoint, it's great that only Windows boots out-of-the box. Linux booting is appreciated if more complicated and more scary. Short of that, Microsoft being in control, Linux distributions being at the mercy of Microsoft (by controlling which Linux distribution's shim gets signed by Microsoft) is also appreciated by Microsoft.

firmware modification (which we want to avoid as far as I understand)

I don't know how this impression was created. My hope is that Dasharo would get this feature and that OEMs based on Dasharo would also be excited to get this feature.


[1] Except for needing to trust the Microsoft key at first boot.

@pietrushnic
Copy link
Member

@miczyg1, if the spec reflects the approved design, we should merge it. I think that further discussion can be done in separate issues. We can also convert open discussions to issues if needed. If we don't do it right now, it will remain open forever.

@miczyg1
Copy link
Member Author

miczyg1 commented Jul 7, 2025

@miczyg1, if the spec reflects the approved design, we should merge it. I think that further discussion can be done in separate issues. We can also convert open discussions to issues if needed. If we don't do it right now, it will remain open forever.

I have to go through this file once again, since it has not been touched for very long time.

@pietrushnic
Copy link
Member

@miczyg1, if needed, we can target M2/RC2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants