Setup Secure Boot on Arch Linux
- Prerequisites
- Prepare the VM
- A short explanation of Secure Boot
- Setup
- Automate signing on updates
- Closing thoughts
- Suggested readings
This article explains how to setup UEFI Secure Boot on Arch Linux, so that the firmware can verify all components that sit between itself and the kernel. This is useful if you need to dual-boot a PC that came with Windows preinstalled and with Secure Boot enabled and you don’t want to keep it disabled after installing Arch.
To keep things simple, we’ll use a VirtualBox machine running Arch as our target system. This way, we do not have to worry about damaging a working system by modifying the keys pre-enrolled in the firmware.
Only Secure Boot itself is covered: full disk encryption will be covered in a separate article.
Prerequisites
To prepare our Arch machine, we’ll use arch-ansible, a playbook designed to provision Arch VMs in minutes. There is already a preset that builds a VirtualBox VM in UEFI mode.
This guide assumes the host is a Linux system, but it should work on Windows hosts as well, although you’ll have to adapt the commands run on the host or perform equivalent operations from the GUI.
Before starting, you’ll need to install the following tools:
Note that VirtualBox can’t usually run alongside other hypervisors. If you are currently running another virtualization tools such as QEMU, the Android Emulator, VMWare Workstation or Hyper-V, you may need to stop your VMs or disable the hypervisor first, in order to release the hardware virtualization features of the CPU for VirtualBox to use.
Prepare the VM
Now that the tools are in place, download arch-ansible’s source. From the host CLI type:
# We'll keep our configurations, the playbook and the produced
# OVF files here.
mkdir -p ~/arch-secure-boot/
cd ~/arch-secure-boot/
curl -sLo arch-ansible.zip https://github.com/binary-manu/arch-ansible/archive/refs/heads/master.zip
unzip -q arch-ansible.zip
cd arch-ansible-master
WARNING: the snippet above always fetches the most recent version of the playbook. Due to Arch’s rolling release nature, older versions may stop working every now and then. For the same reason, some commands may have changed slightly over time. If the snippets below do not work as expected, check manual pages to see if something changed.
Now we are in the root of the playbook. Before running it we must add an extra configuration file: these extra settings prepare the disk for UEFI boot by creating an ESP, and also add a user account:
cat << 'EOF' >> ansible/group_vars/all/50-uefi.yaml
# Use the gpt_singlepart partitioning flow, which creates
# a FAT32 ESP and installs GRUB to it.
disksetup_roles_prefix: "disksetup/gpt_singlepart/"
# Set root's password
users_root_info:
password: "secboot"
# Create a 'secboot' user with password 'secboot'
users_info:
secboot:
password: "secboot"
is_admin: true
groups: []
EOF
After that, we can start the provisioning using Packer. This will create a new VirtualBox VM with GUI, so you’ll see it on your screen. Inside the VM, a complete Arch installation goes on. When it’s over, the VM will be exported to OVF format. Don’t interact with the VM during the process, as this may interfere with installation: for example, the provisioner will simulate keyboard input to the machine, and if you also type text this will disrupt the process.
The installation can take a while, depending on your Internet connection.
cd packer
# Build the machine
packer build -force -only virtualbox-uefi packer-template.json
# Import it into VirtualBox
VBoxManage import --vsys 0 output-virtualbox-uefi/*.ovf
Now you’ll find the new VM (named packer-<something>
) in VirtualBox.
Run it and Arch should start. Login with user secboot
and password
secboot
, then run startx
to start XFCE.
A short explanation of Secure Boot
UEFI keys
Secure Boot is a feature of UEFI firmwares which increases the security of the system by booting only components (such as bootloaders and kernels) which are trusted. There are two ways to mark a component as trusted:
- sign it: the component is signed using the private part of an asymmetric key pair (usually RSA2048); the public part then needs to be loaded into the firmware database of trusted keys;
- enroll its hash: the digest (usually SHA256) of such component is stored into the firmware database of trusted hashes. In UEFI, keys and hashes share the same database, which is described below.
Both methods work, but each one have drawbacks: hashes are easier than keys to work with. However, they change every time a file is modified, so if a boot component is updated frequently (for example, GRUB gets updated), the new hash must be enrolled in the firmware, which can be a hassle.
Signing is more articulated, but since we only enroll the keys, as long as those keys can be used (i.e. the have not been compromised) there is no need to update the firmware database.
In this guide, we will go the signing route. Before that, we need to briefly talk about the key infrastructure in UEFI. More details are available in this article.
Every UEFI Secure Boot implementation starts with the PK (Platform Key). This is the most important key, as it is used as the root of trust chains. Secure Boot cannot be enabled unless a PK has been enrolled and there is usually only one PK. The PK is not directly used to sign boot components. Instead, it is used to:
- disable Secure Boot;
- sign KEKs, the next level of keys.
A KEK (Key Exchange Key) can be added to the UEFI only if it’s signed with the PK, and it’s role is to sign updates to the keys/hashes database. There can be many KEKs enrolled at the same time.
The keys and hashes used to validate boot components reside in the DB and DBX databases:
- DB is an allowlist that contains keys and/or hashes. If a component is signed with a key stored here, or its hash is stored here, the component is allowed to boot;
- DBX is a denylist and works just like DB, with the obvious exception that if a key or hash is stored here, components signed with that key or matching that hash will not be allowed to boot.
DBX takes precedence over DB when doing checks: a component will be allowed to boot if it doesn’t match DBX but matches DB. If it matches neither, it will not boot, since it cannot be verified using the enrolled keys. Updates to DB or DBX are accepted only if signed by a KEK.
This diagram summarizes signed-by relationships between keys and databases:
While a user can generate and enroll it own PK, KEKs, and DB keys, doing so poses some issues. First, some systems, like corporate laptops, come with Secure Boot on, so there must already be a PK and KEK, plus some keys or hashes in the DB. Removing them will make the system unbootable unless they are re-enrolled or the boot components are signed with the new keys. Second, these keys are sometimes used to sign UEFI drivers and again, removing them prevents these drivers from loading. This is especially painful when the driver in question is the GPU one, since it means you will no longer get video output (see this post on Reddit).
However, to enroll keys to DB, we need to know the private part of at least one KEK or enroll a new one. And to enroll a new KEK we need the private part of the PK. Which we don’t usually have if these came pre-enrolled and belong to some big vendor. There are two solutions to this problem.
The first solution involves the fact that most UEFI management GUIs allow the enrollment of new keys even if you don’t know the PK or a KEK. However, for the reasons above, I’d prefer not to fiddle with PK/KEK/DB. So we move to the second solution. Meet shim.
The shim bootloader
shim is an open source bootloader, designed to work as a bridge between the default keys that come pre-enrolled in most Windows PCs and boot components signed by the user.
We said that when Secure Boot is on, only signed components can boot. And the trusted keys pre-enrolled in the UEFI usually belong to Microsoft for a Windows PC. Thus, only Microsoft can sign stuff, And they usually don’t. First, they don’t sign GNU GPL licensed software for policy reasons. Second, having to sign builds of fast-moving FOSS projects for different distros (since every distro ships its own binary for GRUB and the kernel) would be impractical. However, Microsoft signs official pre-built shim binaries. Thus, shim will usually boot on PCs that come with Windows preinstalled, even when Secure Boot is enabled.
shim, by itself, does very little. It simply verifies the signature of a next-stage bootloader (usually GRUB) and loads it. The very important thing to note is that, in addition to the keys/hashes in DB, shim can also use its own, dedicated database of keys and hashes, called the MOK (Machine Owner Key) database.
MOKs can be enrolled by the user using a combination of command line utilities from Linux plus a shim helper called MOKManager. Altering the MOK database may make your Linux distro unbootable, but has no effect on things signed using the other UEFI keys, so there is no risk of loosing the video card.
The rest of this article will show how to setup shim and MOKManager, generate our MOK, enroll it and use it to sign GRUB and the kernel. We’ll start with an Arch Linux installation on a UEFI system with Secure Boot disabled, prepare it for Secure Boot and then enable it.
To avoid generating and enrolling our own set of PK/KEK/DB keys into the VM UEFI, we’ll use a new feature of VirtualBox 7.x, which can automatically enroll well-known Microsoft keys.
Setup
Install shim and other utils
The very first thing to do is installing shim and a bunch of utilities
that will be needed to enrolls MOKs and sign files. You’ll need to use
an AUR helper to install shim. The test machine comes with yay
.
yay -S shim-signed mokutil sbsigntools efitools
Installing this packages will not put shim into the ESP. We’ll need to
copy files manually. pacman -Ql shim-signed
reveals the following:
shim-signed /usr/
shim-signed /usr/share/
shim-signed /usr/share/shim-signed/
shim-signed /usr/share/shim-signed/fbia32.efi
shim-signed /usr/share/shim-signed/fbx64.efi
shim-signed /usr/share/shim-signed/mmia32.efi
shim-signed /usr/share/shim-signed/mmx64.efi
shim-signed /usr/share/shim-signed/shimia32.efi
shim-signed /usr/share/shim-signed/shimx64.efi
We need to copy the 64-bit versions of shim and MOKManager, which
correspond to shimx64.efi
and mmx64.efi
. They will go under
/boot/efi/EFI/arch
, where arch
is the folder that GRUB created
during the install. Don’t worry about breaking the non-Secure Boot
setup, this folder is duplicated as /boot/efi/EFI/Boot
, the default
boot path to use when no boot variable is defined in the UEFI.
# Copy shim and MOKManager
sudo cp /usr/share/shim-signed/{shim,mm}x64.efi /boot/efi/EFI/arch
# Add a new boot entry for shim
sudo efibootmgr -c --loader '\EFI\arch\shimx64.efi' --label ArchLinux
Note how efibootmgr
created a new entry:
BootCurrent: 0001
Timeout: 0 seconds
👉 BootOrder: 0004,0000,0001,0002,0003
Boot0000* UiApp FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)
Boot0001* UEFI VBOX HARDDISK VBbd970c88-d62b41ba PciRoot(0x0)/Pci(0xd,0x0)/Sata(0,65535,0){auto_created_boot_option}
Boot0002* UEFI PXEv4 (MAC:080027DE02FE) PciRoot(0x0)/Pci(0x3,0x0)/MAC(080027de02fe,1)/IPv4(0.0.0.00.0.0.0,0,0){auto_created_boot_option}
Boot0003* EFI Internal Shell FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1)
👉 Boot0004* ArchLinux HD(1,GPT,7e16b474-4294-4fe3-8570-0dfec47972a9,0x800,0x100000)/File(\EFI\arch\shimx64.efi
The BootOrder
line shows in which order boot entries are tried. shim
is 0004, the first item, so if we rebooted now, shim would be loaded.
Don’t do that yet, because shim is only a bridge that calls a next stage
bootloader, but we haven’t installed one yet. We’ll use GRUB as our
next-stage bootloader, but before that we need to sign it, and before
signing anything, we must generate and enroll our MOK.
MOK generation
MOKs are simply X.509 certificates paired with their private keys, and
can be generated using openssl
. Pay attention to the opening and
closing parentheses in the snippet below, they must be copied too.
(
umask 077
sudo mkdir /etc/secure-boot
sudo openssl req \
-new \
-x509 \
-nodes \
-newkey rsa:2048 \
-keyout /etc/secure-boot/mok.key.pem \
-out /etc/secure-boot/mok.crt.pem \
-subj "/CN=Manu's MOK/" \
-days 9999
sudo openssl x509 \
-in /etc/secure-boot/mok.crt.pem \
-out /etc/secure-boot/mok.crt.der \
-outform DER
)
We have created a folder /etc/secure-boot
only accessible to root,
that will store all our Secure Boot related stuff. Inside it, we have a
PEM private key (RSA 2048) and a self-signed certificate. The private
key is not encrypted: a fact that will make it easier to automatically
sign GRUB and kernels on updates, but also means than anyone who can
read the file can get our MOK. That’s why it is critical that the folder
can only be accesses by root. In addition, we converted the certificate
from PEM to DER form: mok.crt.*
files store the same exact data in two
different representations. This is because some tools require the
former, while others require the latter.
Schedule the MOK for enrollment
The mokutil
tool can be used to inspect, add and remove keys from the
MOK database. Actually, it doesn’t really add (or remove) keys, it
schedules them for addition (or removal). The real update will be
performed during the next reboot when shim is loaded.
To schedule our new MOK for addition, type:
sudo mokutil --import /etc/secure-boot/mok.crt.der
You’ll be asked for a password twice: type whatever you want. This
password will be asked by MOKManager when enrolling the key later after
reboot. Pay attention to the fact that you may also be asked for your
system password by sudo
before that.
Note two things:
-
mokutil
requires DER data; - we are uploading the certificate, not the key file. Only the public key is added to the MOK database, and the certificate contains the public key as well as other information such as the Common Name of the owner.
Install GRUB
Normally, we would install GRUB using the grub-install
script. This
installation mode places a small EFI executable on the ESP, while
leaving the rest of GRUB (such as modules) on /boot
. GRUB can
dynamically load the rest of its modules at runtime. However, when
running under Secure Boot, loading code from external files is disabled:
everything must reside into the EFI executable on the ESP.
To create such an image, GRUB provides grub-mkstandalone
. It builds an
EFI image containing all (or a user-supplied list of) GRUB modules, plus
an initial configuration file. This is what we’ll sign and deploy.
The initial configuration file can be used to customize the behaviour of
GRUB when it starts. A typical use case is to make it load an external
configuration file located on the ESP. The external file can then be
regenerated using grub-mkconfig
without altering (and thus re-signing)
the EFI image. Note that, unlike modules, loading external configuration
is allowed.
To create our image, type:
# Generate the embedded configuration file
sudo dd status=none of=/etc/secure-boot/grub.cfg << 'EOF'
configfile ${cmdpath}/grub.cfg
EOF
# Generate the EFI all-in-one image
sudo grub-mkstandalone \
--compress=xz \
--format=x86_64-efi \
--modules='part_gpt part_msdos' \
--sbat=/usr/share/grub/sbat.csv \
--output=/boot/efi/EFI/arch/grubx64.efi \
/boot/grub/grub.cfg=/etc/secure-boot/grub.cfg
# Generate full configuration
sudo grub-mkconfig -o /boot/efi/EFI/arch/grub.cfg
Let’s explain some of the options:
-
compress
requests that the EFI file is compressed to save space. Here we used XZ compression, the slowest but most efficient one; -
format
specifies the format of the output file.x86_64-efi
means we want something suitable for a 64-bit UEFI system; -
output
is the place where the output file will live. We are going to reuse thearch
entry created by the installer, so GRUB is placed there. Important: don’t change the base name: it MUST begrubx64.efi
. shim will only load a file with this name; -
modules
lists which modules must be preloaded when GRUB starts: here we ask to preload modules that parse legacy and GPT partitioning schemes. Without this, GRUB may be unable to detect disk partitions at boot; -
sbat
is the most interesting. Secure Boot Advanced Targeting is a feature that embeds generation numbers of boot components inside them to make it easier for a bootloader to determine if a boot component is vulnerable. Arch’s GRUB package comes with its own SBAT definition file, which must be embedded into the final EFI image. shim will refuse to load stuff without SBAT information. For more details about SBAT, see this page; - the last line copies the embedded configuration file into the image,
making it available as
/boot/grub/grub.cfg
. The GRUB image contains an embedded filesystem known as(ramdisk)
which can be accessed like any other volume, for example(hd0,gpt1)
.
The syntax of files copied into the ramdisk is
/path/into/image=/path/on/filesystem
. /boot/grub/grub.cfg
is the default
configuration file loaded by GRUB when it starts, so we must name it as
such. Its contents do nothing more than immediately directing GRUB to
load an external configuration ${cmdpath}/grub.cfg
. The cmdpath
variable is a runtime value provided by GRUB that points to the folder
containing the EFI image. It allows referring to files installed
alongside GRUB without having to explicitly state paths and thus makes
configurations reusable. In our case, it will expand to GRUB’s notion of
/boot/efi/EFI/arch
, which may be something like (hd0,gpt1)/EFI/arch
.
The last thing to do to have a working GRUB is to sign it. For this, we
must use sbsign
:
sudo sbsign \
--key /etc/secure-boot/mok.key.pem \
--cert /etc/secure-boot/mok.crt.pem \
--output /boot/efi/EFI/arch/grubx64.efi \
/boot/efi/EFI/arch/grubx64.efi
The PEM MOK key and certificate plus the unsigned GRUB image get in, and
a signed image gets out. Note that you can use the same pathname for
both input and output and that, unlike mokutil
, the DER certificate is
not used here.
With this step, we have completed your deployment of shim and GRUB, including configuration files and signatures. Secure Boot is still disabled, since the machine lacks a PK, as can be proven by issuing:
sudo efi-readvar
The output reports that all key DBs are empty.
Sign the kernel
Just like GRUB, the kernel must also be signed, while initramfses need
not be signed. Again, sbsign
comes to the rescue. For simplicity,
we’ll sign just one kernel here, in spite of the fact that a real system
may have multiple kernels installed and all of them need to be signed.
We’ll handle this issue later, when we’ll setup pacman
hooks to
automatically sign GRUB and the kernels on updates.
sudo sbsign \
--key /etc/secure-boot/mok.key.pem \
--cert /etc/secure-boot/mok.crt.pem \
--output /boot/vmlinuz-linux \
/boot/vmlinuz-linux
We’ll now reboot the system to trigger MOKManager and add the new MOK to the database.
Enroll the MOK via MOKManager
Restart the machine. Now, instead of GRUB, we’ll see a blue screen. This is MOKManager, a UEFI application that takes care of enrolling and removing MOKs from the system. The following short video shows how to enroll the keys. A textual description of the steps follow.
shim noticed that some MOKs are scheduled for addition and launched
MOKManager to handle that. We have 10 seconds to press a key, otherwise
the boot will continue and our scheduled MOK will be forgotten,
requiring us to call mokutil
again.
We can choose to enroll a MOK from a disk file or from the list of
pending keys. Choose Enroll MOK
to do the latter, since MOKManager
cannot read ext4
or other POSIX filesystems.
Is it possible to view the key before enrolling it, to be sure of its contents. That confirms the key’s identity.
Press a key to go back to menu and now choose Continue
: MOKManager
will ask for confirmation to enroll. The last step is to enter the
password chosen previously when calling mokutil
. After, that it asks
for a reboot, which we accept. The MOK is now enrolled, altough Secure
Boot is still disabled.
Enable Secure Boot in VirtualBox
After shutting down the VM, open its settings and go under System
. The
lower part of the window shows the Secure Boot settings. First, check
the Enable Secure Boot
box, then click the Reset Keys to Default
button. Answer Yes
to the confirmation dialog. Now restart the
machine.
On a real machine, the keys would be already there, so the only step needed would be to switch Secure Boot on.
WARNING: don’t press Reset Keys to Default
more than once. If you
uncheck and then check Enable Secure Boot
the button becomes active
again, but it seems that every time it’s clicked, VirtualBox appends,
rather than replacing, UEFI keys. This results in a weird state that
makes Secure Boot unusable.
Linux should now boot and prove that we deployed and signed all pieces correctly. When in Linux, use the following commands to list all keys:
sudo mokutil --list-enrolled # Shows the MOKs
sudo efi-readvar # Shows PK/KEK/DB/DBX
Automate signing on updates
Until now, we’ve signed stuff manually. This is educational, but will break as soon as the kernel is upgraded: the new kernel won’t be signed and won’t boot. Also, we signed just the default kernel, but realistically we may have a bunch of them installed: LTS, Zen, …
Luckily, pacman
hooks can be used to automatically run scripts during
the installation of packages. We can setup a couple of them to
automatically sign new kernels and GRUB.
Sign GRUB
We’ll arrange that, when the GRUB package is updates, a hook takes care of regenerating the standalone image, signing it and copying it in place of the old one, while preserving the most recent old version, in case the new image has problems.
This is the hook definition:
sudo mkdir -p /etc/pacman.d/hooks
sudo dd status=none of=/etc/pacman.d/hooks/99-sign-grub-for-secure-boot.hook << 'EOF'
[Trigger]
Operation = Upgrade
Type = Package
Target = grub
[Action]
Description = Sign GRUB with Machine Owner Key for Secure Boot
When = PostTransaction
Exec = /etc/secure-boot/sign-grub
Depends = sbsigntools
EOF
The actual code is located in a separate script file for readability:
sudo dd status=none of=/etc/secure-boot/sign-grub << 'EOF'
#!/bin/sh
set -e
GRUB_ENTRY=/boot/efi/EFI/arch
GRUB_TMP="$GRUB_ENTRY/grubx64.efi.tmp"
GRUB_TARGET="$GRUB_ENTRY/grubx64.efi"
GRUB_BACKUP="$GRUB_ENTRY/grubx64.efi.bkp"
GRUB_CFG="$GRUB_ENTRY/grub.cfg"
GRUB_CFG_TMP="$GRUB_ENTRY/grub.cfg.tmp"
GRUB_CFG_BACKUP="$GRUB_ENTRY/grub.cfg.bkp"
GRUB_SBAT="/usr/share/grub/sbat.csv"
trap '/usr/bin/rm -f "$GRUB_TMP" "$GRUB_CFG_TMP"' QUIT TERM INT EXIT
/usr/bin/grub-mkstandalone \
--compress=xz \
--format=x86_64-efi \
--modules='part_gpt part_msdos' \
--sbat="$GRUB_SBAT" \
--output="$GRUB_TMP" \
'/boot/grub/grub.cfg=/etc/secure-boot/grub.cfg'
/usr/bin/sbsign \
--key /etc/secure-boot/mok.key.pem \
--cert /etc/secure-boot/mok.crt.pem \
--output "$GRUB_TMP" \
"$GRUB_TMP"
/usr/bin/grub-mkconfig -o "$GRUB_CFG_TMP"
/usr/bin/cp "$GRUB_TARGET" "$GRUB_BACKUP"
/usr/bin/cp "$GRUB_CFG" "$GRUB_CFG_BACKUP"
/usr/bin/mv "$GRUB_TMP" "$GRUB_TARGET"
/usr/bin/mv "$GRUB_CFG_TMP" "$GRUB_CFG"
EOF
sudo chmod a+x /etc/secure-boot/sign-grub
Every time the package named grub
is updated, the hook script runs. It
generates a new standalone image in a temporary file, so that the real
GRUB loaded by shim is not overwritten until the very end. It then signs
the new image and regenerates the configuration file. The last step
moves both temporary files into their final positions. Since the two
rename operations are not atomic, there is chance that an error between
them could leave GRUB and its configuration out of sync. All files
already reside on the correct volume: the probability should be pretty
low.
To test if it’s working, we can reinstall grub
:
sudo pacman -S grub --noconfirm
If pacman spits no errors, everything went fine. You should also see log messages produced by the hook.
Sign kernels
The last step is to also arrange for kernel images to be signed. The procedure is very similar to what we did for GRUB, but we must handle
sudo dd status=none of=/etc/pacman.d/hooks/99-sign-kernels-for-secure-boot.hook << 'EOF'
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux
Target = linux-lts
Target = linux-zen
Target = linux-hardened
[Action]
Description = Sign kernels with Machine Owner Key for Secure Boot
When = PostTransaction
Exec = /etc/secure-boot/sign-kernels
Depends = sbsigntools
Depends = findutils
Depends = grep
EOF
Every Target
line matches a kernel package. You should add any
additional kernel you are using.
sudo dd status=none of=/etc/secure-boot/sign-kernels << 'EOF'
#!/bin/sh
set -e
/usr/bin/find /boot/ -maxdepth 1 -name 'vmlinuz-*' -exec /bin/sh -c '
if ! /usr/bin/sbverify --list {} 2>/dev/null |
/usr/bin/grep -q "signature certificates"; then
/usr/bin/sbsign \
--key /etc/secure-boot/mok.key.pem \
--cert /etc/secure-boot/mok.crt.pem \
--output {} {}
fi
' \;
EOF
sudo chmod a+x /etc/secure-boot/sign-kernels
Again, reinstall a kernel to verify it’s working:
sudo pacman -S linux --noconfirm
Closing thoughts
This guide shows how to setup your Arch Linux installation to work under Secure Boot, using shim, GRUB and your own MOK keys. This solution is probably the less invasive ones, as the standard UEFI variables and databases are not touched. This should prove sufficient to run your distribution alongside Windows.
There is one point we have not covered here: disk encryption. Secure Boot can make you system more hard to crack, but it’s pretty useless if your partitions are accessible in the clear to anyone who can simply remove the disk and place it into another machine. Normally, one would use LUKS together with Secure Boot. Disk encryption will be the topic for another article.
It is also recommended to lock the UEFI management UI with a password. Otherwise, an attacker could just enter the firmware and disable Secure Boot.