Some scripts to simplify the process of taking control of UEFI secure boot.
Most of the scripts in this repository were originally written for the author's own convenience, and were only designed to be used internally. They have now been published in this repository, under the permissive MIT license, to allow others to be able to use the scripts and benefit from them. Documentation on how they work and how to use them (part of which you are currently reading) has been written. Stability and functionality are not guaranteed. Use them at your own risk, and make sure you understand what the scripts are actually doing under the hood. The author assumes no resonsibility for any negative consequences which may occur as a result of you (mis)using these scripts.
The following sections contain some recommended and/or interesting reading about how secure boot works under the hood, and the purpose of these scripts' existence. It also contains some discussion about the ethical issues around secure boot. If you don't care about any of this and want to get straight on with the process, we have written a simplified no-fluff guide just for you - see here. However, even if you don't want to read all the mumbo jumbo, we would still recommend reading the section below titled Why take control of secure boot?.
You should be aware that the term "Key" traditionally refers to the private signing key which is used to sign binaries and signature lists, while the term "Certificate" refers to the public certificate which is used to validate that the signature(s), produced by the process of signing with the private key, are correct and authentic.
The UEFI secure boot environment has four main databases:
- Platform Key (PK) - The "master" certificate which controls the entire
secure boot environment. By default, it will be the OEM's certificate. With
the scripts in this repository, it will be your own personal certificate. The
PK is signed by its own key. The PK of the system can only be replaced and/or
installed when the machine is booted in "Setup Mode". On GNU/Linux systems,
you can run the command
bootctl statusto verify whether the machine is in Setup Mode or User Mode (default/normal mode). - Key Exchange Keys (KEK) - The database of certificates which control what can be added to, removed from, or modified in, the Authorized Signatures (db) and Forbidden Signatures (dbx) databases. Unlike the PK, the KEK can contain multiple certificates, any of which can be used to sign (and hence authorize) updates/modifications to the db and dbx. By default, the KEK will contain both the OEM's certificate and Microsoft's certificate. With the scripts in this repository, it will contain your own KEK certificate, and you will make the decision of whether or not Microsoft's certificate (plus any other custom certificates you may wish to add) shall also be included in the KEK. All KEK entries are signed by the PK's key.
- Authorized Signatures (db) - The database of certificates which control whether or not a signed EFI executable (e.g., bootloader or operating system) is allowed to start up on the machine. The certificates in this database can also be referred to as "UEFI Signing Certificates", amongst other names. This is because their corresponding keys are used for the purpose of signing real EFI binaries that may be booted on the system. By default, the db will hold all of Microsoft's various signing certificates, as well as the OEM's own certificate. With the scripts in this repository, it will contain your own signing certificate, and (if desired) Microsoft's certificates, as well as any other signing certificates you wish to trust by default. All db entries are signed by one of the KEK keys, and any updates/modifications to the db must also be signed by such. Which means that, if Microsoft's key is in the KEK, then Microsoft can also supply db updates themselves (not just you), which may or may not be desirable, depending upon your own personal preferences. Ultimately, however, it is your decision to make.
- Forbidden Signatures (dbx) - The database of certificates and/or binary hashes which are known to be untrusted, vulnerable, or even outright malware. Anything in the dbx overrides db, so even if a certificate is in the db, EFI binaries signed by its key will be unable to load if that certificate is also in the dbx, or if the hash of the EFI binary itself is in the dbx. By default, the list of signatures/hashes that Microsoft considers "bad" are frequently updated, through Windows Update, or through LVFS (fwupd) on Linux. For this reason, whether or not you can really utilise dbx depends on whether or not Microsoft's certificate is in your KEK (in which case, as previously mentioned, they can supply dbx updates). If this is not the case, then only you can manage/update the dbx, which again may or may not be desirable, depending upon your personal preferences. On the one hand, Microsoft can do the work of keeping your system safe of malware themselves, but on the other hand, it may be considered by some individuals to be a "backdoor", as Microsoft can at their own discretion update the databases of what is/isn't trusted to load on your machine.
As shown in the Overview section above, you can clearly see that, in the default state of secure boot, the only entities that have control over the secure boot environment on the computer you are using are the device OEM and Microsoft. This means only they can decide what is or isn't allowed to boot on your system. As we have also established, this means you cannot "alter" the certificate list that control what can or can't boot, because any updates to Authorized Signatures (db) requires one of the Key Exchange Keys (KEK) to sign (therefore "authorize") the update.
There is an exception on some systems, primarily ones which use AMI Aptio V firmwares. Such firmwares are special, because they actually expose options for direct key management within the firmware settings. This allows you to directly update any of the variables, including Authorized Signatures (db), without those updates needing to be signed by the authority above the variable you are updating. This means you don't need to take control of secure boot at all in order to be able to modify the certificates that the system trusts (however you may still want to, due to the obvious benefits of having control and freedom). Although the interface is complicated and unintuitive to naviagate, there is an article in the MassOS documentation which contains a section with detailed instructions of how to import a custom certificate using this firmware interface. Although that article is specifically centered around the MassOS secure boot certificate, you could theoretically follow the same instructions to import any secure boot certificate, or a group of certificates.
However, most other systems, particularly laptops, do not have such options in the firmware settings. Therefore, the only way to import custom certificates is to take control of the secure boot environment, such that your own certificates are in PK and KEK, and therefore can sign any db updates you want. This is where the scripts in this repository are invaluable, so we'd highly recommend reading on.
As for why not just disable secure boot, well there are two main reasons. One is a pragmatic reason - if you dual-boot your GNU/Linux system with Windows, then some Windows-only features will be blocked without secure boot. These include the Windows Device Encryption feature (which is an alternative to BitLocker on Home editions of Windows which don't support BitLocker), as well as several other security-related features. Furthermore, online multiplayer video games often make use of aggressive anti-cheat engines, and these engines frequently require secure boot to be enabled, and will prevent you from running the game if secure boot is disabled. If you therefore dual-boot with a distro of GNU/Linux which is not Microsoft-signed, and play such a video game under Windows, you'd be stuck between having secure boot enabled or disabled. This is until now - whereby you can use these scripts to take ownership of secure boot yourself, instead of disabling it outright.
It should be noted that the system requirements of Windows 11 do NOT require secure boot to enabled - this is a common misconception. However they do require secure boot to be supported by the system.
The second reason you may not want to disable it is simply for the security it
should offer. The whole point of the system is to block malware and other
undesirable code from loading during the early boot stage. The secure boot
system doesn't only apply to the .efi binaries that boot from the firmware -
it also initiates a chain of trust that ensures security during the entirety of
the system boot-up process. In the context of GNU/Linux, having secure boot
enabled should trigger the bootloader to verify that the Linux kernel image it
loads is signed, and then the Linux kernel should verify all its modules are
signed (and refuse to load unsigned modules, by making use of the kernel
lockdown feature).
Unfortunately, whether or not the factory state of secure boot is really "secure", depends on whether or not you trust Microsoft. The presence of the OEM's certificate is likely negligible, since it will only be used to sign the OEM's own internal debugging/diagnostics, but the presense of Microsoft's certificates, especially their KEK, could be considered a "backdoor", since it allows them to update your system's db or dbx databases at any time. While the scripts in this repo do give you the option of having Microsoft's KEK installed alongside your own KEK, the choice is entirely yours, and you can choose to exclude Microsoft's KEK certificate from your KEK database if desired, without affecting your ability to boot Windows (assuming you keep Microsoft's db certificates). And whatever you choose, you will still have your own certs installed in the firmware too - so YOU, yes YOU can override what Microsoft "authorizes" and be given the autonomy to choose what to boot on your own hardware - WITHOUT giving up the security benefits of secure boot which are described above.
| Mode | Factory state | Secure boot disabled | Using these scripts |
|---|---|---|---|
| Owner | OEM | N/A | You |
| Controlled by | OEM + Microsoft | N/A | You (+ OPTIONALLY Microsoft/OEM) |
| Security level | Debatable | Requires common sense | Secure |
| Some Windows features | Available | Blocked | Available |
| Video game anti-cheat | Permitted | Forbidden | Permitted |
| Think of it as | Restricted boot | YOLO | Secure boot |
Either you have just kept secure boot disabled as you've seen it as useless, or you have always used a distro which is signed by Microsoft, and hence is authorized by Microsoft to boot on any system even with the factory secure boot setup.
Since the GRUB 2 bootloader, used by most modern GNU/Linux distributions, is licensed under the GPLv3, Microsoft will refuse to sign it. This is because the GPLv3 license is intentionally designed to protect you from the problem of TiVoization - whereby free software is effectively rendered non-free, due to it existing in an environment (e.g., on a hardware device) that itself does not permit running modified versions of the software. So in other words, you could download and modify the free software program, but would have no way to run it on the locked-down device that the original version runs on. In the context of a factory secure boot system, this applies because only Microsoft-signed binaries are allowed to run on the system by default, and your modified version would not be Microsoft-signed.
To work around this problem, distributions instead use a companion bootloader called shim. shim is licensed under a more permissive license, and can therefore be signed by Microsoft - and then shim can use its own internal database, known as the MOKList (Machine Owner Keys) to verify if the main bootloader (e.g., GRUB 2) is allowed to start up. By this logic, Microsoft only needs to sign shim, and then any other binaries can be signed by keys that are either compiled in to shim's vendor database, or in the MOKList.
Unfortunately, this still creates an non-level playing field, since shim is essentially useless if it's not Microsoft-signed. This is because, although shim uses its own internal database (MOKList) separate to the main UEFI secure boot databases, shim has to be signed by a key trusted by the firmware to be able to load in the first place. From an end user's perspective, this is not a big deal, since the distribution maintainers will deal with it. From a distribution maintainer's perspective, this is problematic. In order to have your shim build signed by Microsoft, you first have to submit it to the shim review board, who, besides having the audacity to directly state that they are the ones who decide what "the world is able to boot" (although the scripts in this repository make every effort to change who REALLY should have control of this, and the answer is only the device owner), also require the entity submitting the shim binary to be officially recognised as a corporation or organization under their jurisdiction with a full registered legal address. Clearly this is not practical for small, community-driven projects. And this problem was one of the reasons for these scripts' existence to begin with - to level out the playing field and give people back control over their own computers. WITHOUT compromising on security hardening features that operating systems enable if secure boot is turned on.
From the perspective of a distribution maintainer, one solution is just to yoink a Microsoft-signed shim binary from another distribution, such as Ubuntu or Fedora. This is what MassOS does, as it turns out to be the easiest way to just make secure boot work. All users need to do is import the MassOS secure boot certificate into shim's internal MokList database, which is uncomplicated using MokManager (the companion program distributed alongside shim). However, this does not resolve the underlying ethical issues described above. This method is a convenient workaround, but the scripts in this repository go one step further. They retaliate AGAINST this problem by giving users back control over their own computers. With these scripts, the user can decide what can or cannot boot on their own machine. And this is done in two ways. One, by choosing which signing certificates to include in their firmware (such as Microsoft's - to still allow booting MS signed binaries), and two, by including their own personal signing key in their firmware, so they themself can sign binaries that they judge to be safe for booting on their system. However, while we absolutely should stand up for freedom and autonomy over one's own computing, we cannot deny that this comes at a cost. The cost being time and knowledge. We have, in fact, written a simplified guide designed to make it as easy, fast and painless as possible for anyone to be able to take control of secure boot using this repository's scripts. However, it is not possible to totally bridge the gap. Some users will not even be aware of secure boot and how it works in the first place. Therefore, using "easy" workarounds like MassOS does is still the most ideal option for a distribution of its kind.
But then again, this doesn't matter for you at the end of the day. The fact that you personally are reading this document right now indicates that you are interested in what has been described so far. You will very likely proceed with the process of taking control of your own PC's secure boot environment, because you want freedom and control over your own computing, WITHOUT giving up on security hardening which otherwise gets turned off if secure boot is off. Let's not forget it's also fun! Turning off secure boot is the easy and boring way out. Arguably so is just using a pre-existing Microsoft-signed shim. Whereas these scripts add a little bit of spice and excitement. Combined with the inevitable feeling of liberation after you have completed the process, What more could you want?
The first step is to generate your own keys for PK, KEK and db. This forms the foundation of your control over the secure boot environment. If you don't already have keys for each, you can use the following command:
./generate-keys.shYou will receive three prompts, to enter your desired CN for each key. You can name them whatever you want, but we'd recommend using a sensible name that is both easy to identify, and consistent between your three different keys. For example, here are the following which could be used (but again, you may use whichever name you want):
- PK: "John Smith Platform Key"
- KEK: "John Smith Key Exchange Key"
- db: "John Smith UEFI Signing Key"
Once the generation is complete, the keys and their corresponding certificates
will be placed under the mykeys/ directory. The private keys will be under
mykeys/private/, and the public certificates will be under mykeys/public/.
You can freely share the public certificates to anyone, but DO NOT share
the private keys! They are private for a reason. The aforementioned script will
also generate a random owner GUID for your key set, which will be written to
the file mykeys/owner.guid. Owner GUIDs serve a purely informational purpose
only - the UEFI firmware itself does not care whether a fixed or random GUID is
used, but having a unique GUID is useful for convention. GUIDs are generally
per-individual / per-vendor / per-organization / etc. Microsoft's GUID, for
example, is 77fa9abd-0359-4d32-bd60-28f4e78f784b.
Before generating the new secure boot databases, you will most likely want to
add additional certificates into the db and, optionally, the KEK. These can
include the Microsoft certificates (for booting Windows and Microsoft-signed
GNU/Linux distributions), the device OEM's certificate(s), and others. All
additional certificates are placed under the extracerts/ directory. More
specifically, extracerts/kek/ for additional KEK certificates, and
extracerts/db/ for additional db certificates. By default, there are none
under this directory, but there is a default directory in the top-level of this
repository, named extracerts.DEFAULT, which contains some common certificates
you may wish to use directly (namely, the Microsoft ones). You can copy these
over to the extracerts/ directory by running the following command:
cp -r extracerts.DEFAULT/{db,kek} extracerts/To copy over the OEM certificate(s), you first need to dump them:
./dump-existing.sh
And then copy over the OEM certificates (see the README.md file under
extracerts/ for full details):
cp -r dumped/oem-crt/{db,kek} extracerts/
Finally, there are some optional third-party certificates which aren't included
by default, as some people may not need them. For example, the MassOS db cert
now lives here. You can use the same command as above to copy them over if
desired, replacing DEFAULT with OPTIONAL. But they are usually not needed.
Full descriptions about each of these default certificates, as well as detailed
information on how to customize them and add your own, such as device OEM
certificates, can be found in extracerts/README.md. We
recommend reading through this before continuing on further, since it also
displays an annotated example image showing a finalized extracerts directory
that is ready for moving on to the next step.
With your own keys generated, and any desired third-party certificates added, you can generate the complete secure boot databases by running the following command:
./create-databases.shA message will be displayed on the command-line for every certificate that has
been added after being found under the extracerts/ directory. You should
check this output to verify that it matches the certificates you have placed
under this directory. Once the script finishes, the final database files will
be placed inside the final/ directory, each with the .auth extension. These
will all be signed as appropriate:
- The PK will be signed by itself.
- The KEK will be signed by the PK.
- The db will be signed by the KEK.
The final step is to import the new secure boot databases into your firmware. This will replace the factory secure boot databases, and will conclude the process of taking control of the secure boot environment. You can do this with the following command:
sudo ./import-to-firmware.shHOWEVER, it is very likely this command will fail at the PK import stage. This
is because, in order to install a new Platform Key, the existing Platform Key
must be erased. The process of doing this involves entering "Setup Mode", which
clears the PK (and ideally all other secure boot variables too), thus allowing
you to replace the PK with your own, and replace the KEK and db too, as the
import-to-firmware.sh script tries to do. In order to enter setup mode, you
need to restart into your UEFI firmware settings. This can be done by pressing
a specific hotkey during system startup, or can alternatively be done with the
following command:
systemctl reboot --firmware-setupOnce you are in the firmware setup, you need to find where the secure boot
option is located - it is often under the "Security" tab. "Secure Boot" may or
may not also be a submenu of the firmware settings you can descend into. But in
or around it, there should be an option to "Reset to Setup Mode", which does
exactly what it suggests. Once you select this option and restart back into the
main system, you can use the command bootctl status to verify whether or not
you are in setup mode:
bootctl statusIt will give one of the following outputs on the "Secure Boot:"" line:
Secure Boot: enabled (user) #Secure boot is enabled - PK is locked.
Secure Boot: disabled #Secure boot is disabled - PK is still locked.
Secure Boot: disabled (setup) #Setup mode - PK is cleared and replaceable.Clearly, you want the line which reads disabled (setup). If this is the case,
you are good to proceed! Try to run the previously mentioned command again:
sudo ./import-to-firmware.shAnd now, it should work. The secure boot variables in your firmware should now contain your newly created databases consisting of only your certificates and the specific certificates you want your system to include. However, secure boot may not become enabled by default after this process. So you should restart into your firmware settings again, and enable secure boot if it is not already enabled. After doing so, you should be good to go. You can run the following commands to inspect the contents of each variable, and check it contains the entries you expect:
# Platform Key (PK).
efi-readvar -v PK
# Key Exchange Keys (KEK).
efi-readvar -v KEK
# Authorized Signatures (db).
efi-readvar -v dbYou now have control of secure boot - great! But what comes next? This section will demonstrate how to perform common tasks as the owner of the secure boot environment, including adding new certificates into the Authorized Signatures (db) list, as well as how to sign EFI binaries so they can be booted under your secure boot environment.
You do NOT need to sign Windows, as it is already signed by Microsoft, and the Microsoft certificates should be in your Authorized Signatures (db) list. You also do NOT need to sign the binaries of any distro that is signed by Microsoft, such as Ubuntu or Fedora, for the same reason. You will need to sign any custom/loose EFI binaries which are not signed, and you will also need to sign the bootloader/kernel if you use a distribution that does not sign such out of the box, such as Arch Linux. If the distribution does sign stuff out of the box, then you will simply need to import that distribution's secure boot certificate into your firmware - instructions for this are given in the section below titled Importing new certificates.
To sign binaries, you need to have the sbsign program installed. It comes
from a package named sbsigntools or sbsigntool on most distributions.
Once you have it installed, signing a binary is simple:
sbsign --key path/to/your/db.key --cert path/to/your/db.crt mybinary.efi
This will produce the output signed file as mybinary.efi.signed - you can
then move/rename/copy this as desired (such as removing .signed extension).
The arguments for --key and --cert are the paths to your UEFI signing
private key and PEM-encoded public certificate respectively. If you followed
the steps in this repository, these will be saved as mykeys/private/db.key
and mykeys/public/db.crt. Note that only the db key/cert is used for signing;
you do not sign binaries using the PK or KEK keys..
The scripts are Copyright (C) Daniel Massey and MIT licensed. See the LICENSE file for the license text.
The efitools binary distribution stored in this repository, under the
efitools/distrib/ and efitools/distribarm/ directories, have the license
covering them contained within the tarball once it is decoded from the format
used to store the binary distribution in this repository. This license is
wholly separate to the licensing of this repository's own scripts.
Signing certificates belonging to Microsoft Corporation and other entities are distributed here under the understanding that copyright law cannot protect what are essentially just very large randomly-generated numbers. As these are not considered creative works nor pieces of software.