Differences between revisions 1 and 77 (spanning 76 versions)
Revision 1 as of 2015-10-02 16:34:58
Size: 1129
Editor: PaulWise
Comment: borp
Revision 77 as of 2021-01-05 07:17:02
Size: 10616
Editor: PaulWise
Comment: use comment chars for comments
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
= Implementation choices =


= Open questions =

 * Can the signature on shim be detached from the binary and combined with it during the build? This would allow reproducible builds.
 * How to verify that Microsoft hasn't tampered with the shim binary before signing?
 * How many people and who should hold the private keys for the certificate(s)? DSA? Secure Boot team? How should we backup the private keys?

= Information =

== Software ==

[[https://github.com/mjg59/shim|shim]]
...

= Task list =

== Certificate ==

== Packaging ==

= References =

 * [[https://summit.debconf.org/debconf14/meeting/150/uefi-secure-boot/|DebConf14 secure boot BoF ([[https://gobby.debian.org/export/debconf14/bof/UEFI%20BoF|notes]], [[http://meetings-archive.debian.net/pub/debian-meetings/2014/debconf14/webm/UEFI_Secure_Boot.webm|video]])
 * [[https://mjg59.dreamwidth.org/20303.html?thread=783183#cmt783183|mjg59 on how to get a signed shim binary]]
 * [[http://blogs.msdn.com/b/windows_hardware_certification/archive/2013/12/03/microsoft-uefi-ca-signing-policy-updates.aspx|Microsoft UEFI CA Signing policy]]
<<TableOfContents()>>

= What is UEFI? =

Unified Extensible Firmware Interface. See the main [[UEFI]] page for
more details.

= What is UEFI Secure Boot? =

UEFI Secure Boot (SB) is a verification mechanism for ensuring that
code launched by a computer's UEFI firmware is trusted. It is designed
to protect a system against malicious code being loaded and executed
early in the boot process, before the operating system has been
loaded.

SB works using cryptographic checksums and signatures. Each program
that is loaded by the firmware includes a signature and a checksum,
and before allowing execution the firmware will verify that the
program is trusted by validating the checksum and the signature. When
SB is enabled on a system, any attempt to execute an untrusted program
will not be allowed. This stops unexpected / unauthorised code from
running in the UEFI environment.

Most x86 hardware comes from the factory pre-loaded with Microsoft
keys. This means the firmware on these systems will trust binaries
that are signed by Microsoft. Most modern systems will ship with SB
enabled - they will ''not'' run any unsigned code by default, but it
is possible to change the firmware configuration to either disable SB
or to enrol extra signing keys.

Most of the programs that are expected to run in the UEFI environment
are boot loaders, but others exist too. There are also programs to
deal with firmware updates before operating system startup (like
DebianPkg:fwupdate and DebianPkg:fwupd), and other utilities may live
here too.

Other Linux distros (Red Hat, Fedora, SUSE, Ubuntu, etc.) have had SB
working for a while, but Debian has been slow in getting this
working. This meant that on many new computer systems, users had to
first disable SB to be able to install and use Debian. The methods for
doing this vary massively from one system to another, making this
potentially quite difficult for users.

Starting with Debian version 10 ("Buster"), we have working UEFI
Secure Boot to make things easier.

= What is UEFI Secure Boot NOT? =

UEFI Secure Boot is '''not''' an attempt by Microsoft to lock Linux
out of the PC market here; SB is a security measure to protect against
malware during early system boot. Microsoft act as a Certification
Authority (CA) for SB, and they will sign programs on behalf of other
trusted organisations so that their programs will also run. There are
certain identification requirements that organisations have to meet
here, and code has to be audited for safety. But these are not too
difficult to achieve.

SB is also '''not''' meant to lock users out of controlling their own
systems. Users can enrol extra keys into the system, allowing them to
sign programs for their own systems. Many SB-enabled systems also
allow users to remove the platform-provided keys altogether, forcing
the firmware to only trust user-signed binaries.

= Shim =

DebianPkg:shim is a simple software package that is designed to work
as a first-stage bootloader on UEFI systems.

It was developed by a group of Linux developers from various distros,
working together to make SB work using Free Software. It is a common
piece of code that is safe, well-understood and audited so that it can
be trusted and signed using platform keys. This means that Microsoft
(or other potential firmware CA providers) only have to worry about
signing shim, and not all of the other programs that distro vendors
might want to support.

Shim then becomes the root of trust for all the other distro-provided
UEFI programs. It embeds a further distro-specific CA key that is
itself used for signing further programs (e.g. Linux, GRUB,
fwupdate). This allows for a clean delegation of trust - the distros
are then responsible for signing the rest of their packages. Shim
itself should ideally not need to be updated very often, reducing the
workload on the central auditing and CA teams.

For extra trust and safety, from version 15 onwards the shim binary
build is 100% reproducible - you can rebuild the Debian shim binary
yourself to verify that no unexpected changes have been embedded in
this key piece of security software.

= MOK - Machine Owner Key =

== Generalities ==

A key part of the shim design is to allow users to control their own
systems. The distro CA key is built in to the shim binary itself, but
there is also an extra database of keys that can be managed by the
user, the so-called '''Machine Owner Key''' (MOK for short).

Keys can be added and removed in the MOK list by the user, entirely
separate from the distro CA key. The '''mokutil''' utility can be used
to help manage the keys here from Linux userland, but changes to the
MOK keys may '''only''' be confirmed directly from the console at boot
time. This removes the risk of userland malware potentially enrolling
new keys and therefore bypassing the entire point of SB.

There are more docs online for how to work with MOK, for example:

 * https://www.rodsbooks.com/efi-bootloaders/secureboot.html#initial_shim

== Generating a new key ==

{{{
$ openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -days 36500 -subj "/CN=My Name/" -nodes
$ openssl x509 -inform der -in MOK.der -out MOK.pem
}}}

== Enrolling your key ==

If you also have a kernel to sign, you may wish to do the next step first as it will save you one reboot.

{{{
$ sudo mokutil --import MOK.der # prompts for one-time password
$ sudo mokutil --list-new # recheck your key will be prompted on next boot

<rebooting machine then enters MOK manager EFI utility: enroll MOK, continue, confirm, enter password, reboot>

$ sudo dmesg | grep cert # verify your key is loaded
}}}

== Using your key to sign your kernel ==

First, install DebianPkg:sbsigntool

{{{
$ sbsign --key MOK.priv --cert MOK.pem /boot/vmlinuz-$ver --output vmlinuz-$ver
$ sudo mv vmlinux-$ver /boot/vmlinux-$ver
}}}

== Using your key to sign modules ==

{{{
# cd /lib/modules/4.19.0-6-amd64/updates/dkms
# /usr/lib/linux-kbuild-4.19/scripts/sign-file sha256 /root/MOK.priv /root/MOK.der vboxdrv.ko
}}}

== Disabling/re-enabling Secure Boot ==

In case it is difficult to control Secure Boot state through the EFI setup program, mokutil can also be used to disable or re-enable Secure Boot for operating systems loaded through shim and GRUB:

 1. Run: `mokutil --disable-validation` or `mokutil --enable-validation`.
 2. Choose a password between 8 and 16 characters long. Enter the same password to confirm it.
 3. Reboot.
 4. When prompted, press a key to perform MOK management.
 5. Select "Change Secure Boot state".
 6. Enter each requested character of your chosen password to confirm the change. Note that you have to press Return/Enter after each character.
 7. Select "Yes".
 8. Select "Reboot".

= Supported architectures and packages =

On each architecture, Debian includes various packages containing
signed binaries:

||'''Name''' || '''amd64''' || '''i386''' ||'''arm64''' ||'''Signed by''' ||'''Purpose''' ||
||'''fwupd''' ||fwupd-amd64-signed ||fwupd-i386-signed ||fwupd-arm64-signed ||Debian ||Tools to manage UEFI firmware updates automatically ||
||'''fwupdate''' ||fwupdate-amd64-signed ||fwupdate-i386-signed ||fwupdate-arm64-signed ||Debian ||Tools to manage UEFI firmware updates manually ||
||'''grub''' ||grub-efi-amd64-signed ||grub-efi-ia32-signed ||grub-efi-arm64-signed ||Debian ||GRUB boot loader ||
||'''linux''' ||linux-image-*-amd64 (*) ||linux-image-*-686* (*) ||linux-image-*-arm64 (*) ||Debian ||Linux kernel, various flavours ||
||'''shim''' ||shim-signed ||shim-signed ||shim-signed ||Microsoft ||Main shim binary ||
||'''shim-helpers'''||shim-helpers-amd64-signed||shim-helpers-i386-signed||shim-helpers-arm64-signed||Debian ||Shim helper binaries - MokManager and FallBack||

(*) The various linux-image packages in Debian are now signed by
default. The ''unsigned'' packages are called linux-image-*-unsigned.

= Testing UEFI Secure Boot =

Focusing on Debian Buster, some tests have been performed to make sure
that everything is ready. You can help us testing our setup on real
hardware, including the installer and the live images. If you want to
help us testing Secure Boot you can find more information
[[SecureBoot/Testing|here]].

= Secure Boot limitations =

By its very design, SB may affect or limit some things that users want
to do.

If you want to build and run your own kernel (e.g. for development or
debugging), then you will obviously end up making binaries that are
not signed with the Debian key. If you wish to use those binaries, you
will need to either sign them yourself and enrol the key used with MOK
or disable SB.

Using SB activates "lockdown" mode in the Linux kernel. This disables
various features that can be used to modify the kernel:

 * Loading kernel modules that are not signed by a trusted key. By default, this will block out-of-tree modules including DKMS-managed drivers. However, you can create your own signing key for modules and add its certificate to the trusted list using [[#MOK_-_Machine_Owner_Key|MOK]].
 * Using kexec to start an unsigned kernel image.
 * Hibernation and resume from hibernation.
 * User-space access to physical memory and I/O ports.
 * Module parameters that allow setting memory and I/O port addresses.
 * Writing to MSRs through `/dev/cpu/*/msr`.
 * Use of custom ACPI methods and tables.
 * ACPI APEI error injection.

You can avoid this by disabling Secure Boot through the EFI setup program or through [[#MOK_-_Machine_Owner_Key|MOK]].

Example docs from elsewhere:

 * [[https://wiki.ubuntu.com/UEFI/SecureBoot/DKMS]]
 * [[https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Kernel_Administration_Guide/sect-signing-kernel-modules-for-secure-boot.html]]
 * [[https://www.linuxjournal.com/content/take-control-your-pc-uefi-secure-boot]]

= Infrastructure - how signing works in Debian =

If you want to know the implementation details and the current
discussions on improvements, see [[SecureBoot/Discussion]].

= Testing Secure Boot in a virtual machine =

If you want to test Secure Boot in a virtual machine without having to deal with an actual machine, see [[SecureBoot/VirtualMachine]].

What is UEFI?

Unified Extensible Firmware Interface. See the main UEFI page for more details.

What is UEFI Secure Boot?

UEFI Secure Boot (SB) is a verification mechanism for ensuring that code launched by a computer's UEFI firmware is trusted. It is designed to protect a system against malicious code being loaded and executed early in the boot process, before the operating system has been loaded.

SB works using cryptographic checksums and signatures. Each program that is loaded by the firmware includes a signature and a checksum, and before allowing execution the firmware will verify that the program is trusted by validating the checksum and the signature. When SB is enabled on a system, any attempt to execute an untrusted program will not be allowed. This stops unexpected / unauthorised code from running in the UEFI environment.

Most x86 hardware comes from the factory pre-loaded with Microsoft keys. This means the firmware on these systems will trust binaries that are signed by Microsoft. Most modern systems will ship with SB enabled - they will not run any unsigned code by default, but it is possible to change the firmware configuration to either disable SB or to enrol extra signing keys.

Most of the programs that are expected to run in the UEFI environment are boot loaders, but others exist too. There are also programs to deal with firmware updates before operating system startup (like fwupdate and fwupd), and other utilities may live here too.

Other Linux distros (Red Hat, Fedora, SUSE, Ubuntu, etc.) have had SB working for a while, but Debian has been slow in getting this working. This meant that on many new computer systems, users had to first disable SB to be able to install and use Debian. The methods for doing this vary massively from one system to another, making this potentially quite difficult for users.

Starting with Debian version 10 ("Buster"), we have working UEFI Secure Boot to make things easier.

What is UEFI Secure Boot NOT?

UEFI Secure Boot is not an attempt by Microsoft to lock Linux out of the PC market here; SB is a security measure to protect against malware during early system boot. Microsoft act as a Certification Authority (CA) for SB, and they will sign programs on behalf of other trusted organisations so that their programs will also run. There are certain identification requirements that organisations have to meet here, and code has to be audited for safety. But these are not too difficult to achieve.

SB is also not meant to lock users out of controlling their own systems. Users can enrol extra keys into the system, allowing them to sign programs for their own systems. Many SB-enabled systems also allow users to remove the platform-provided keys altogether, forcing the firmware to only trust user-signed binaries.

Shim

shim is a simple software package that is designed to work as a first-stage bootloader on UEFI systems.

It was developed by a group of Linux developers from various distros, working together to make SB work using Free Software. It is a common piece of code that is safe, well-understood and audited so that it can be trusted and signed using platform keys. This means that Microsoft (or other potential firmware CA providers) only have to worry about signing shim, and not all of the other programs that distro vendors might want to support.

Shim then becomes the root of trust for all the other distro-provided UEFI programs. It embeds a further distro-specific CA key that is itself used for signing further programs (e.g. Linux, GRUB, fwupdate). This allows for a clean delegation of trust - the distros are then responsible for signing the rest of their packages. Shim itself should ideally not need to be updated very often, reducing the workload on the central auditing and CA teams.

For extra trust and safety, from version 15 onwards the shim binary build is 100% reproducible - you can rebuild the Debian shim binary yourself to verify that no unexpected changes have been embedded in this key piece of security software.

MOK - Machine Owner Key

Generalities

A key part of the shim design is to allow users to control their own systems. The distro CA key is built in to the shim binary itself, but there is also an extra database of keys that can be managed by the user, the so-called Machine Owner Key (MOK for short).

Keys can be added and removed in the MOK list by the user, entirely separate from the distro CA key. The mokutil utility can be used to help manage the keys here from Linux userland, but changes to the MOK keys may only be confirmed directly from the console at boot time. This removes the risk of userland malware potentially enrolling new keys and therefore bypassing the entire point of SB.

There are more docs online for how to work with MOK, for example:

Generating a new key

$ openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -days 36500 -subj "/CN=My Name/" -nodes
$ openssl x509 -inform der -in MOK.der -out MOK.pem

Enrolling your key

If you also have a kernel to sign, you may wish to do the next step first as it will save you one reboot.

$ sudo mokutil --import MOK.der # prompts for one-time password
$ sudo mokutil --list-new # recheck your key will be prompted on next boot

<rebooting machine then enters MOK manager EFI utility: enroll MOK, continue, confirm, enter password, reboot>

$ sudo dmesg | grep cert # verify your key is loaded

Using your key to sign your kernel

First, install sbsigntool

$ sbsign --key MOK.priv --cert MOK.pem /boot/vmlinuz-$ver --output vmlinuz-$ver
$ sudo mv vmlinux-$ver /boot/vmlinux-$ver

Using your key to sign modules

# cd /lib/modules/4.19.0-6-amd64/updates/dkms
# /usr/lib/linux-kbuild-4.19/scripts/sign-file sha256 /root/MOK.priv /root/MOK.der vboxdrv.ko

Disabling/re-enabling Secure Boot

In case it is difficult to control Secure Boot state through the EFI setup program, mokutil can also be used to disable or re-enable Secure Boot for operating systems loaded through shim and GRUB:

  1. Run: mokutil --disable-validation or mokutil --enable-validation.

  2. Choose a password between 8 and 16 characters long. Enter the same password to confirm it.
  3. Reboot.
  4. When prompted, press a key to perform MOK management.
  5. Select "Change Secure Boot state".
  6. Enter each requested character of your chosen password to confirm the change. Note that you have to press Return/Enter after each character.
  7. Select "Yes".
  8. Select "Reboot".

Supported architectures and packages

On each architecture, Debian includes various packages containing signed binaries:

Name

amd64

i386

arm64

Signed by

Purpose

fwupd

fwupd-amd64-signed

fwupd-i386-signed

fwupd-arm64-signed

Debian

Tools to manage UEFI firmware updates automatically

fwupdate

fwupdate-amd64-signed

fwupdate-i386-signed

fwupdate-arm64-signed

Debian

Tools to manage UEFI firmware updates manually

grub

grub-efi-amd64-signed

grub-efi-ia32-signed

grub-efi-arm64-signed

Debian

GRUB boot loader

linux

linux-image-*-amd64 (*)

linux-image-*-686* (*)

linux-image-*-arm64 (*)

Debian

Linux kernel, various flavours

shim

shim-signed

shim-signed

shim-signed

Microsoft

Main shim binary

shim-helpers

shim-helpers-amd64-signed

shim-helpers-i386-signed

shim-helpers-arm64-signed

Debian

Shim helper binaries - ?MokManager and ?FallBack

(*) The various linux-image packages in Debian are now signed by default. The unsigned packages are called linux-image-*-unsigned.

Testing UEFI Secure Boot

Focusing on Debian Buster, some tests have been performed to make sure that everything is ready. You can help us testing our setup on real hardware, including the installer and the live images. If you want to help us testing Secure Boot you can find more information here.

Secure Boot limitations

By its very design, SB may affect or limit some things that users want to do.

If you want to build and run your own kernel (e.g. for development or debugging), then you will obviously end up making binaries that are not signed with the Debian key. If you wish to use those binaries, you will need to either sign them yourself and enrol the key used with MOK or disable SB.

Using SB activates "lockdown" mode in the Linux kernel. This disables various features that can be used to modify the kernel:

  • Loading kernel modules that are not signed by a trusted key. By default, this will block out-of-tree modules including DKMS-managed drivers. However, you can create your own signing key for modules and add its certificate to the trusted list using MOK.

  • Using kexec to start an unsigned kernel image.
  • Hibernation and resume from hibernation.
  • User-space access to physical memory and I/O ports.
  • Module parameters that allow setting memory and I/O port addresses.
  • Writing to MSRs through /dev/cpu/*/msr.

  • Use of custom ACPI methods and tables.
  • ACPI APEI error injection.

You can avoid this by disabling Secure Boot through the EFI setup program or through MOK.

Example docs from elsewhere:

Infrastructure - how signing works in Debian

If you want to know the implementation details and the current discussions on improvements, see SecureBoot/Discussion.

Testing Secure Boot in a virtual machine

If you want to test Secure Boot in a virtual machine without having to deal with an actual machine, see SecureBoot/VirtualMachine.