My Avatar

Shilong ZHAO

Secure Boot, Signed Modules and Signed ELF Binaries

2015-12-03 00:00:00 +0100

In case you have any questions or suggestions, you can leave comments HERE . Thanks!

Secure boot is a booting feature of Unified Extensible Firmware Interface (UEFI). Secure boot secures the boot process by preventing the loading of drivers or OS loaders that are not signed with an acceptable digital signature.

Download the PDF or LaTeX format report here.

UEFI Secure Boot

Platform Keys (PK)

PK establishes a trust relationship between the owner and firmware. The platform owner enrolls the PKpub into the platform firmware. The owner later can use the PKpriv to change ownership or to enroll a KEK

The PKpub must be stored in non-volatile storage which is tamper and delete resistant.

Authenticated PK variable can always be read but can only be written if

Key Exchange Keys (KEK)

KEKs establish a trust relationship between the operating system and the platform firmware. Each operating system and potentially, each 3rd party application which need to communicate with platform firmware (i.e. Shim, boot loader), enrolls a public key (KEKpub) into the platform firmware.

The public key must be stored in non-volatile storage which is tamper resistant.

KEKs can always be read but only be written if:

DB and DBX

Signature database (db) stores signatures or image hashes of UEFI applications, operating system loaders, and UEFI drivers that can be loaded.

The Revoked signatures database (dbx) stores no longer trusted/loadable signers or image hashes.

if one wants to build a custom kernel or load 3rd party kernel modules, he will need to disable secure boot, or setup his own keys and sign everything with them.

Secure Boot with Windows

Windows Hardware Certification Program

Windows Hardware Certification Program is formerly known as Windows Logo Program

For a PC vendor to receive a certification/logo/sticker from Windows, his product must meet certain requirements Requirements concerning the Secure Boot, i.e.

Windows Secure Boot Requirements

As a conformance to the Windows Hardware Certification Program, On the non-ARM systems, the platform MUST implement the ability for a physically present user to select between two Secure Boot modes in firmware setup, i.e. “Custom” and “Standard”.

When in Custom Mode, a physically present user should be able to modify the signature database and the PK. And this could be implemented as first cleaning all Secure Boot databases (db, dbx, PK, KEK) and then enter Setup Mode

Also, a physically present user MUST be allowed to disable Secure Boot via firmware setup without possession of PKpriv.

Sadly, nothing mentioned above is allowed on ARM Platforms.

Wiping Out Secure Boot Keys

On a ACER Aspire PC Press ‘Delete’ when system boots up and enter BIOS Setup Utility Go to tab ‘Authentication’ and set the options as indicated in the following

Secure Boot                                 [Enabled]
Secure Boot Mode                          [Custom]
Default Key Provisioning            [Disabled]

If Default Key Provisioning enabled, the factory default keys will be loaded after reboot Choose Clear Secure Boot Keys, pops up message Deleting all variables will reset Platform to Setup Mode. Do you wish to proceed?, choose Yes

Secure Boot with Linux

For the Linux distributors, they could either work with hardware vendors to have them endorse a Key and sign the boot loader with that key Or using a boot loader signed by M$, which seems to be the most simple and direct way to deal with secure boot.

But GRUB/GRUB2 is NOT signed by M$, because

Fedora Shim

As a work-around, Fedora created the Shim program, which is a front-end to boot loaders, meaning it loads the boot loader during the boot process.

The shim program itself changes very rarely and signed by M$.

It has public key build-in (i.e. during the make process, specify the public key file), used to verify the boot loader and for the purpose of development flexibility, it allow to enroll additional keys (i.e. Machine Owner Keys) and boot loader calls back into Shim to verify the kernel signature.

Machine Owner Keys (MOK)

MoKs are managed by Shim, not that they are not part of UEFI and are generated by users to sign EFI binaries.

MoKs empower users to run locally-compiled kernels and boot loaders which are delivered by the distribution maintainer.

MOKs are stored in Non-Volatile RAM (NVRAM) However, it should be noted that, the ability to use MOKs creates risk, if the user is tricked to enroll a MOK generated by malware author.

Embedded Signatures

The signatures for signing the UEFI executables (conforming to the PE format)are directly embedded inside executable itself.

Portable Executable (PE) format is a file format for executables, object code, DLLs and others used in 32-bit and 64-bit Windows operating systems. PE is a modified version of Unix Common Object File Format (COFF).

Within the PE file header is an array of directory entries. Each of these entries points to interesting places within the executable image. The fifth data directory entry contains a pointer to a list of certificates along with the length of the certificate areas. Each certificate may contain a digital signature used for validating the driver.

When embedding the signature in the file, the signing process can modify the certificate areas without affecting the file’s hash value.

The following diagram illustrates how the PE file is organized.

+-----------------------+
| MS-DOS Header         |
+-----------------------+
| PE Header Offset      |
+-----------------------+
| PE Header             |
+-----------------------+
| Sections Directory    |
+-----------------------+
| Section #1            |
+-----------------------+
| Section #2            |
+-----------------------+
.    ...                .
+-----------------------+
| Section #n            |
+-----------------------+
| Debug Information     |
+-----------------------+
| Certificate #1        |
+-----------------------+
| Certificate #2        |
+-----------------------+
.     ...               .
+-----------------------+
| Certificate #n        |
+-----------------------+

The PE Header structure

+-----------------------+
| PE Signature          |
+-----------------------+
| Standard Header       |
+-----------------------+
| Optional Header       |
+-----------------------+
|Optional Data Directory|
+-----------------------+

The Optional Data Directory is an array of five data entry directories, and the fifth one (the last one) contains the address to the beginning of the certificate list.

+-----------------------------------+
| Image Data Directory Entry #1     |
+-----------------------------------+
| Image Data Directory Entry #2     |
+-----------------------------------+
| Image Data Directory Entry #3     |
+-----------------------------------+
| Image Data Directory Entry #4     |
+-----------------------------------+
| Image Data Directory Entry #5     | -------> Points Certificate #1
+-----------------------------------+

For windows, Authenticode is a digital signature format that is used to determine the origin and integrity of software binaries. Authenticode is based on Public-Key Cryptography Standards (PKCS) #7 signed data and X.509 certificates to bind an Authenticode-signed binary to the identity of a software publisher. the PKCS #7 structures include the PE file hash, the signer’s X.509 certificates, and the signed hash.

See Windows Authenticode Portable Executable Signature Format for more.

Singing Linux Kernel Modules for Secure Boot

Create a NSS database

[szhao@localhost Documents]$ mkdir db
[szhao@localhost Documents]$ cd db
[szhao@localhost db]$ ls
[szhao@localhost db]$ certutil -d $PWD -N
Enter a password which will be used to encrypt your keys.
The password should be at least 8 characters long,
and should contain at least one non-alphabetic character.

Enter new password: shilong.zhao
Re-enter password: shilong.zhao

Generate a self signed certificate

efikeygen -d $PWD --ca --self-sign --nickname='My Fedora CA' \
--common-name='CN=ALT UEFI SB CA 2015,\
OU=Example Certification Authority,O=Example Linux Team,C=US' \
--url='http://example.org/UEFI' --serial=00
Enter Password or Pin for "NSS Certificate DB":shilong.zhao

Export the certificate and private key

[szhao@localhost db]$ certutil -d $PWD -L -n "My Fedora CA" -r \
> fedora-ca.cer
[szhao@localhost db]$ ls
cert8.db fedora-ca.cer key3.db secmod.db
[szhao@localhost db]$ pk12util -d $PWD -o fedora-ca.p12 \
-n "My Fedora CA"
Enter Password or Pin for "NSS Certificate DB": shilong.zhao
Enter password for PKCS12 file: shilong.zhao
Re-enter password: shilong.zhao
pk12util: PKCS12 EXPORT SUCCESSFUL
[szhao@localhost db]$ certutil -d $PWD -L
Certificate Nickname                         Trust Attributes
                                            SSL,S/MIME,JAR/XPI
My Fedora CA                                     u,u,u

Copy kernel image to current directory

[szhao@localhost db]$ cp /boot/vmlinuz-3.10.0-123.el7.x86_64 .
[szhao@localhost db]$ ls
cert8.db fedora-ca.cer fedora-ca.p12 key3.db secmod.db vmlinux
vmlinuz-3.10.0-123.el7.x86_64

Remove all previous signatures of the file to be signed

[szhao@localhost db]$ pesign -i vmlinuz-3.10.0-123.el7.x86_64 -o \
vmlinuz-3.10.0-123.el7-unsigned.x86_64 -r -u 0
[szhao@localhost db]$ ls
cert8.db fedora-ca.p12 secmod.db vmlinuz-3.10.0-123.el7.x86_64
fedora-ca.cer key3.db vmlinuz-3.10.0-123.el7-unsigned.x86_64

Sign with your own certificate and show the result

[szhao@localhost db]$ pesign -n $PWD -c "My Fedora CA" -s -i \
vmlinuz-3.10.0-123.el7-unsigned.x86_64 \
-o vmlinuz-3.10.0-123.el7-signed.x86-64
Enter Password or Pin for "NSS Certificate DB":shilong.zhao
[szhao@localhost db]$pesign -n $PWD -S -i \
vmlinuz-3.10.0-123.el7-signed.x86-64
---------------------------------------------
certificate address is 0x7fb45b86ff88
Content was not encrypted.
Content is detached; signature cannot be verified.
The signer s common name is ALT UEFI SB CA 2015
No signer email address.
Signing time: Wed Feb 03, 2016
There were certs or crls included.
---------------------------------------------

If the signatures are not cleaned, there could be multiple signatures available.

[root@localhost sign_kernel_for_secure_book]# pesign -n certdb \
-c "shilong" -s -i centos/shim.efi -o centos/shim-signed.efi
Enter Password or Pin for "NSS Certificate DB":

[root@localhost sign_kernel_for_secure_book]# pesign -n certdb \
-S -i centos/shim-signed.efi
---------------------------------------------
certificate address is 0x7f1ba74beff8
Content was not encrypted.
Content is detached; signature cannot be verified.
The signer's common name is Microsoft Windows UEFI Driver Publisher
No signer email address.
No signing time included.
There were certs or crls included.
---------------------------------------------
certificate address is 0x7f1ba74c11e0
Content was not encrypted.
Content is detached; signature cannot be verified.
The signer's common name is Red Hat Inc.
No signer email address.
Signing time: Wed Jul 02, 2014
There were certs or crls included.
---------------------------------------------
certificate address is 0x7f1ba74c2160
Content was not encrypted.
Content is detached; signature cannot be verified.
The signer's common name is shilong
No signer email address.
Signing time: Tue Feb 02, 2016
There were certs or crls included.
---------------------------------------------

Here the message showing content is detached, because to verify the signature, the signature should first be extracted from the signed PE/COFF executable. And pesign itself cannot verify the signature (function not implemented), that’s the reason why it’s saying signature cannot be verified;

In the end you have to enroll the signing public key to the MOK database (or PK or KEK databases depending if you want to change also Shim and Grub).

Sign Linux Modules

Suppose there’s already a compiled module named hello.ko and when trying to insert the module

# insmod ./hello.ko
insmod: ERROR: could not insert module
./hello.ko: Required key not available

The same will happen if you try to install Virtual Box.

$ sudo keyctl list %:.system_keyring

keys loaded at boot time

$ dmesg | grep "EFI: Loaded cert"
$ sudo mokutil --import signing_key_pub.der

and reboot

$ reboot
$ sudo keyctl list %:.system_keyring
$ sudo /usr/src/kernels/`uname -r`/scripts/sign-file \
sha256 private_key.priv public_key.der my_module.ko

Signed ELF Binaries

DigSig, is a Linux kernel module, which checks RSA digital signatures of ELF binaries and libraries before they are run. Binaries are to be signed with BSign.

DSI (Distributed Security Infrastructure), is a security framework which targets distributed environments, and is meant to address any specific security issue such platforms may be concerned with. More particularly, it is meant to address security needs of carrier-grade Linux clusters, for the telecommunication domain.

User can check md5, so do we really need signature, considering the Linux culture is about tampering and hacking? Or, maybe, in some other situations, you do not want the hacker to hack.

$ gpg --verify signature_filename

One developer of DigSig told the reasons why they decided to stop maintaining such a project.

References

UEFI

[1] Fedora UEFI secure boot guide

[2] Wikipedia UEFI

[3] Create your own public/private keys and add public key to Machine-Owner-Keychain

[4] VirtualBox not working with Fedora 20

[5] RedHat: signing kernel modules for secure boot

[6] Windows Authenticode Portable Executable Signature Format

Sign UEFI Binaries

[1] AltLinux Secure Boot

[2] Fedora Secure Boot Self Signing

[3] Fedora Secure Boot Smart Card Deploymeng

[4] OpenSUSE UEFI Image File Sign Tools

[5] Bug Report

Signed Executables

[1] Design and implementation of signed executables for Linux

[2] DigSig

[3] DigSig developers tell why they stop it at March 2012

[4] Signing ELF Binaries

[5] ELF executable signing and verification