UEFI / Controlling Secure Boot

Started as a nightmare by losing my main ArchLinux production machine, thankfully i have already did my backup which the first critical process you should always do, but ended up understanding a piece of art that secure the Boot up process of any computer running UEFI (Unified Extended Firmware Interface).

However, the main problem was installing ArchLinux OS with the Secure Boot option enabled. It's a painful process but it turns out to be the most efficient option to secure the computer.

Without further obscurity let's get into understanding each component separately then, i'm gonna present different solutions to overcome the problem.

Table of content:

  1. What is UEFI ?
  2. Secure Boot overview
  3. Public Key Cryptography
  4. Secure Boot signing flowchart
  5. Taking Control of computer Secure Boot keys
  6. Demo Time
  7. Conclusion

DISCLAIMER: This article provide only some hints of what you should do, the process of taking full control of computer's keys is complaicated and you can run into serious problem during the process. If you decide also to take the adventure i will provide you with links in comments for the full documentation and deepth explanation.

1.What is UEFI ?:

UEFI is a model for the interface between operating systems and firmware. It provides a standard environment for booting an operating system and running pre-boot applications.

No alt text provided for this image
UEFI Boot phases

The UFEI boot combine complex process to achieve a secure running OS, firstly it runs initial firmware integrity check ( SEC ) , the second stage (PEI) it initialize the CPU and start the secure boot process , the DXE phase start hardware initialization and all the module that communicate with the hardware, then the BDS phase initializes the boot manager, i.e selecting where do we wanna boot from Hard Drive, USB or the Network. Then, you could start the Bootloader and finally, the Bootloader starts the actual kernel of the OS.

2. Secure Boot overview:

Secure Boot is a UEFI standard security feature intended to add an extra layer of protection to the pre-boot process, ensure that machine core (boot manager, kernel, initramfs) has not been tampered with, by maintaining a list of cryptographic signatures for binaries that are allowed or disallowed at boot time.

As such, it can be seen as a continuation or complement to efforts to secure computing environments by reducing the attack surface not easily covered by other software security solutions such as encryption system.

When Secure Boot is active, the firmware checks every EFI (Extensible Firmware Interface) program it executes for the presence of a cryptographic signature. The firmware refuses to run the program if it doesn't have a cryptographic signature, doesn't match the key in her NVRAM on the computer, or is blacklisted in NVRAM. Of course, this is just the beginning of the process. A trustworthy EFI boot loader should continue the boot process in a secure manner, ultimately becoming a secure operating system itself. Malware authors have to sign their malware, which is difficult when users control their system her keys (in a secure way). This is how you block pre-boot malware. There are plenty of things that could go wrong further up the chain, but Secure Boot at least provides a foundation for protecting your entire computer. At least in theory!

3. Public Key Cryptography:

So, really the bread and butter of Secure Boot is the Public Key Cryptography. We should be aware that there are four types of Secure Boot keys built into your firmware :

  • Database Key (db): This is the type of key you're most likely to think about when it comes to Secure Boot, as it's used to sign or verify the binaries you run (boot loaders, boot managers, shells, drivers, etc.). Most computers have two Microsoft keys installed. One of these is used by Microsoft itself and the other is used to sign third party software such as Shim (we will talk about later). Some computers also come with a key created by the computer manufacturer or another party.
  • Forbidden Signature Key (dbx): dbx is kind of anti-DB. It contains keys and hashes corresponding to known malware or unwanted software. You can install keys and hashes just like you would with db. If a binary matches a key or hash in both db and dbx, prefer dbx. This allows you to block a single binary (via its hash) even if it was signed with a key that you don't want to revoke because it was used to sign many legitimate binaries.
  • Key Exchange Key (KEK): The KEK is used to sign keys so that the firmware accepts them as valid when entering them into the database (either the db or the dbx). Without the KEK, the firmware would have no way of knowing whether a new key was valid or was being fed by malware. Thus, in the absence of the KEK, Secure Boot would either be a joke or require that the databases remain static. Since a critical point of Secure Boot is the dbx, a static database would be unworkable. Computers often ship with two KEKs, one from Microsoft and one from the motherboard manufacturer. This enables either party to issue updates.
  • Platform Key (PK): The PK is the top-level key for Secure Boot and performs similar functions with respect to the KEK as the KEK for db and dbx. UEFI Secure Boot typically supports a single PK provided by the motherboard manufacturer. Therefore, only the motherboard manufacturer has full control over the computer. A key part of the self-driving secure boot process is replacing the PK with its own version.
  • Machine Owner Key (MOK): MOK corresponds to the db key. It is used to sign bootloaders and other EFI executables, and to store hashes corresponding to individual programs. However, MOK is not a standard part of Secure Boot. Used by Shim and PreLoader programs to store keys and hashes.

All of these key types are similar. These are examples of Public Key Infrastructure (PKI), which uses two long numbers to encrypt or (for secure boot) authenticate data.

4. Secure Boot Singing flowchart:

The following diagram describe how the signing process works with Secure Boot, The PK is used to sign the KEK then we use the KEK to sign both databases (DB and DBX).

No alt text provided for this image

Now for Linux it get little more interesting.

No alt text provided for this image

Linux has MOK ( Machine Owner Key) which only used by Linux implementation. The best example for this is shim, a small UEFI bootloader distributed in binary (source) form and signed by Microsoft. At its most basic level, the shim allows you to run Canonical, RHEL/Fedora, and other signed Grub bootloaders when UEFI Secure Boot is enabled. Shims allow system owners to extend trust beyond Microsoft without modifying protected UEFI variables.

Although MOK is not part of UEFI Secure Boot standard, it's allow users to add a signing key to the MOK DB also it's checks the kernel modules signatures against that exist in MOK DB for example, if you run NVIDIA kernel module you need put there a key for the shim and the kernel validate against.But if you are not running Ubuntu you to sign you kernel and modules each time you got update.

In my case, ArchLinux, i had to go the complex way and replacing Microsoft's keys with my own, which enables us to gain the benefits of Secure Boot without using either Shim or PreLoader and run our favorite Linux distribution.

5. Taking Control of computer Secure Boot keys:

Taking control of your computer's Secure Boot keys offers several advantages over other solution:

  • Locking out threats from the standard keys: it's always possible for an attacker to trick Microsoft into signing malware. Or the signed software may have errors such as boot hole bug discovered in 2020. Using Shim with the default key leaves your computer vulnerable to these threats, at least until they are detected and the blacklist database is updated.
  • Locking out threats from your distribution's keys : it's the greatest level of protection but will require extra effort on your part.
  • Eliminating the need for MOKs: Eliminating MOK is therefore an easy way to increase security, especially if you manage a collection of desktop computers used by others.
  • Enabling Secure Boot on systems without keys : Some servers ship without Microsoft's Secure Boot keys installed. Using Secure Boot with such a server requires adding keys.

When you replace the computer's public key set with your own, you also create a private key set. These keys should be kept safe. Ideally stored on encrypted external media locked to a vault.

6. Demo Time:

Now act! The first step in replacing your computer's default key set is to generate your own key. To do this, you need to install some packages on your Linux computer. In particular you need openssl and efitools.

Note! The following commands are executed from an ArchLinux based system which are similar to other distributions. Otherwise, understand the idea and implement it using your? tools, there are many helper scripts out there on the internet.

  • Backing up current variables:

Before creating new keys and modifying EFI variables, it is advisable to backup the current variables, so that they may be restored in case of error.

$ efi-readvar -v PK -o old_PK.es
$ efi-readvar -v KEK -o old_KEK.esl
$ efi-readvar -v db -o old_db.esl
$ efi-readvar -v dbx -o old_dbx.esll        

If you perform these commands on a new computer or motherboard, the variables you extract will most likely be the ones provided by Microsoft.

  • Creating keys:

we will need private keys and certificates in multiple formats:

All .cer, .crt, .esl and .auth files are public keys, whereas all .key files are private keys and should be kept very safe.

we start by genrating globally unique identifier for owner identification:


$ uuidgen --random > GUID.txt        

Platform key:


$ openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509  \

 -sha256 -days 3650 -subj "/CN=my Platform Key/" -out PK.crt

$ openssl x509 -outform DER -in PK.crt -out PK.cer

$ cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl

$ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth        

Sign an empty file to allow removing Platform Key when in "User Mode":


$ sign-efi-sig-list -g "$(< GUID.txt)" -c PK.crt -k PK.key PK
 
/dev/null rm_PK.auth        

Key Exchange Key:


$ openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 \
 
  -sha256 -days 3650 -subj "/CN=my Key Exchange Key/" -out KEK.cr

$ openssl x509 -outform DER -in KEK.crt -out KEK.cer

$ cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl

$ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl
 KEK.auth        

Signature Database key:


$ openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 \

-sha256 -days 3650 -subj "/CN=my Signature Database key/" -out db.crt

$ openssl x509 -outform DER -in db.crt -out db.cer

$ cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl

$ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth        


At this point, it's worth considering precisely how you intend to lock down your computer. Broadly speaking, you have three options:

  1. Extreme self-reliance : Only your own key can be trusted. This means that every program that runs firmware and possibly every Linux kernel that boots must be signed. This is an extreme solution and can be difficult to maintain. However, good security can be provided by properly backing up the private key.
  2. Trusting some third parties : Adding the third party's key to the database allows binaries signed by the third party to run without modification. Doing this makes maintaining distributions like Fedora, OpenSUSE, and Ubuntu easier. They all distribute signed copies of GRUB and its Linux kernel. Similarly, if you want to run Windows or third-party programs signed with Microsoft's key, you can add one or both of Microsoft's public keys. (Note that plug-in cards may contain firmware signed with Microsoft's third-party keys.) On the other hand, relying on these keys means that, at least in theory, the private key computer is vulnerable to attack if it is compromised or encounters an error su as Boot holes.
  3. Hybrid with Shim : ?You can take partial or complete control of your Secure Boot keys by using your own PK, KEK, and perhaps db keys, and optionally add Microsoft's db keys as well; but rely on Shim (signed with Microsoft's keys or your own) to add its built-in keys with which to launch Linux. This approach gives you significant control over your computer, while also enabling use of the Shim-dbx

  • Signing EFI Binaries

After you lock your computer with a new set of keys, it won't be able to run programs that aren't signed by one of the keys that correspond to the public database keys you installed. As a result, you'll likely want to sign your most important EFI programs before proceeding. Depending on your bootloader, you may also need to sign your Linux kernels. If you run into problems, you can always temporarily disable Secure Boot to sign more binaries.

Install sbsigntools to sign EFI binaries with sbsign. esp directory replaced with path where EFI partition is mounted, my ArchLinux case was /boot/efi.


# sbsign --key db.key --cert db.crt --output /boot/vmlinuz-linux 
/boot/vmlinuz-linux

# sbsign --key db.key --cert db.crt --output esp/EFI/BOOT/BOOTx64.EFI esp/EFI/BOOT/BOOTx64.EFI        

Warning: Signing kernel only will not protect the initramfs from tampering, you should produce a combined image that you can then manually sign with sbsign. To get rid of each time sign kernel you had an update you can create a hook to do the job for you.

  • Replacing Keys

For this stage the choice depends on the situation your computer is running, if you have access to your firmeware's setup utility, you can manage to do that using the GUI (you have to look for your laptop manufacturer specification).

The second option is using KeyTool which is a key and certificate management utility. It allows users to administer their own public/private key pairs and associated certificates for use in self-authentication

  • Adding keys

As discussed earlier it is up to you to take full control or trust a third party by adding their keys using the efi-updatevar command.

The efi-updatevar command is more complicated. You can use it to update the db or KEK database, but only if you have the private key of the next higher database. In other words, adding a db entry requires a KEK private key, and adding a KEK requires a private PK. key. So efi-updatevar is probably only useful if you have full control over your computer's secure boot keys.

7. Conclusion

Taking full control of your computer's Secure Boot keys is not for everybody. In my case , i take it as a new challenge to understand that process .This process is tedious and error prone. However, it may improve the security of your computer by only allowing you to run boot loaders and kernels that you explicitly approve.

Ayoub BA-HADDOU

Cloud-DevOps Engineer | AWS {SAA-C03} | Kubernetes {CKA}

2 年

nice work ?, keep going

回复

要查看或添加评论,请登录

社区洞察

其他会员也浏览了