UEFI Secure boot — Taking Control

Ruchir Khatri
7 min readJan 20, 2020

--

Secure boot is a security standard developed by members of the PC industry to help make sure that a device boots using only software that is trusted by the Original Equipment Manufacturer (OEM). When the PC starts, the firmware checks the signature of each piece of boot software, including UEFI firmware drivers, EFI applications, and the operating system. If the signatures are valid, the PC boots, and the firmware gives control to the operating system.

BIOS Menu for SecureBoot

Secure boot works by installing a set of keys into computer’s firmware. Before jumping into all sorts of keys, let us take a look at what actually keys are. According to wikipedia, a cryptographic key is a string of data that is used to lock or unlock cryptographic functions, including authentication, authorization and encryption. Keys can basically be devided into two categories Symmetric and Asymmetric keys. In case of symmetric keys, algorithm use single key for encryption and decryption whereas in case of asymmetric key, different keys are used for both encryption and decryption. Secure boot uses asymmetric type of cryptography which basically consists of Private and Public key pairs. Most commodity PCs (desktops, laptops, many tablets, and some servers) sold today include keys that Microsoft controls.

SecureBoot Procedure

When secure boot is enabled on system, a series of verification is done before control is handed over to operating system. If verification fails at any step, an error screen is popped and system is not allowed to boot.

  1. When power is turned on, Intel boot-guard verifies the BIOS for integrity using public key burned with it and loads BIOS on successful verification.
  2. BOIS then verifies intgrity of SHIM using keys in db and loads it
  3. SHIM then verifies integrity of GRUB using keys in db or MOK and loads it
  4. GRUB then verifies and loads kernel using keys in db or MOK, kernel further loads filesystem

Secure boot key types

Browsing secure boot menu in side BIOS will ultimately lead to keys named
PK (Platform Key)
KEK (Key Exchange Key)
db (Authorized Keys)
dbx (Unauthorized Keys)

SecureBoot Menu Items

If someone want to use custom shim, grub or kernel with secure boot enabled, the public counterpart of private key used to sign custom utility should be present in either db or MOK (Machine Owner’s Key). Custom shim cannot be verified using MOK and its validation signature should mandatorily be present in db.

Authorized Keys(db) — These are the key types that are used to verify the the utility that is going to be loaded when the secure boot is enabled on system. db will contain a list of public keys that are from sources that are considered to be secure. db can also hold the hash of binaries that are considered to be secure. Validation of source of utility being secure is validated using signature whereas validation of utility itself being secure is done using hash. db is signed using KEK’s private counterpart.

Unauthorized keys (dbx) — These are basically anti-db keys i.e. dbx holds the key sources and hashes that are blacklisted from being secure or marked as malware. dbx is signed using KEK’s private counterpart.

Key Exchange Keys (KEK) — The KEK’s private counterpart is used to sign db or dbx holding the list of keys marked as secure or unsecure. Without the KEK, the firmware would have no way of knowing whether the key present in db or dbx was valid or was being fed by malware. Secure boot is designed in a way that db can only be updated if signed by KEK otherwise rejected. KEK is signed using PK’s private counterpart.

Platform Key (PK) — This the top level key in secure boot architecture. PK is self signed i.e. PK is signed by its own private counterpart.

Machine Owner’s Key (MOK) — These are equivalent to db keys but MOKs are not part of standard secure boot. SHIM and other EFI utilities use them to store keys and hashes which are further considered as having secure source of origin.
Personal thoughts — MOKs should be disabled in order for a system to be secure. Anyone with access to MOK utils can register their keys/hashes and mark their utilities as secure. Disabling can be achieved by completely deleting mok utility from system.

Note : We always share pulbic key with others whereas private keys should be kept very safe(like in a locker) and should not be shared at all. All the keys that are seen in BIOS are public keys.

Chain of trust

In chain of trust, entities are signed in such a way that validation leads to “root of trust”. Root of trust as the name suggests is the origination of trust. In case of SecureBoot, platform owner is considered as root of trust and addition of keys to keystore follows chain of trust. That is no key can be replaces unless signed by preceeding key.

PK is self signed, KEK is signed by PK and db and dbx are signed by KEK. That means to change anything in db or dbx, it should be signed by KEK’s private key, to change KEK itself, it must be signed by PK’s private key and to repace PK the new key should be signed by previous PK’s private key. Generally replacing PK is done using empty key certificate signed by previous platform owner’s private key.

When SecureBoot is enabled, verification of utilities is done using entries only in db and not verified till root CA, because addition of keys to key store follows chain of trust.

Generation of keys

Generation of keys is demonstrated using ubuntu 16.04 OS with openssl and efitools installed.

PK, KEK and DB key can be generated using

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Test PK/" \
-keyout PK.key -out PK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Test KEK/" \
-keyout KEK.key -out KEK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Test DB/" \
-keyout DB.key -out DB.crt -days 3650 -nodes -sha256

Since keys are expected in DER format, Convert keys to DER format.

openssl x509 -in PK.crt -out PK.cer -outform DER
openssl x509 -in KEK.crt -out KEK.cer -outform DER
openssl x509 -in DB.crt -out DB.cer -outform DER

Next step is to get Globally Unique Identifier and generate EFI signature list

GUID=`python -c 'import uuid; print(str(uuid.uuid1()))'`
echo $GUID > guid.txt
cert-to-efi-sig-list -g $GUID PK.crt PK.esl
cert-to-efi-sig-list -g $GUID KEK.crt KEK.esl
cert-to-efi-sig-list -g $GUID DB.crt DB.esl

Signing the keys generated in previous steps

sign-efi-sig-list -t "$(date --date='1 second' \
+'%Y-%m-%d %H:%M:%S')" \
-k PK.key -c PK.crt PK PK.esl PK.auth
sign-efi-sig-list -t "$(date --date='1 second' \
+'%Y-%m-%d %H:%M:%S')" \
-k PK.key -c PK.crt KEK KEK.esl KEK.auth
sign-efi-sig-list -t "$(date --date='1 second' \
+'%Y-%m-%d %H:%M:%S')" \
-k KEK.key -c KEK.crt db DB.esl DB.auth

Create and empty certificate and sign using PK’s private key so that if PK is to be changed again in future, there is an empty signed certificate.

touch noPK.esl
sign-efi-sig-list -t "$(date --date='1 second' \
+'%Y-%m-%d %H:%M:%S')" \
-k PK.key -c PK.crt PK noPK.esl noPK.auth

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

Signing Tools For SecureBoot

Once machine is updated with new set of keys, it will not be able to boot. Therefore before updating the keys eith key store, it is necessary to sign and replace all binaries (all EFI tools and Kernel). For signing, command snippet is mentioned below. After signing the utility, utility-signed should replace original file in correct directory.

sbsign --key DB.key --cert DB.crt --output utility-signed.efi \
utility.efi

Adding keys to KeyStore

One can either use BIOS menu or EFI keytools to add the keys to KeyStore. Please note that before replacing PK there should be an empty signature signed by previos platform owner. Most BIOS present till date does not verify chain of trust while adding keys, which is ideally not correct and keys might get added to keystore without verification.
Note: It is important to take backup of keys in keystore before replacing them with new ones.

Using Machine Owner’s Key (MOK)

If someone does not want to go with hassle of changing the complete key set in key store and are OK with vulnerability which comes with using MOK, they can use the MOK utility to register their key or hash and UEFI firmware treat them as secure.

For using MOK utility, one should generate a key pair, sign their module with private key and register it’s public counterpart with MOKutility. After the registration is complete, the module will be treated as secure.

After the keys for MOK are generated and enrolled, one can use sbsign to sign kernel and efi applications as depicted above in Signing Tools for SecureBoot

Generating and Enrolling MOK key pair

For generating MOK key pair, create openssl.cnf file with contents mentioned below and change fileds in req_distinguished_name acording to ones need.

# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3
string_mask = utf8only
prompt = no
[ req_distinguished_name ]
countryName = IN
stateOrProvinceName = Haryana
localityName = Gurgaon
0.organizationName = Wavenet
commonName = Secure Boot Signing
emailAddress = ruchir.khatri@wavenetcorp.com
[ v3 ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical,CA:FALSE
extendedKeyUsage = codeSigning,1.3.6.1.4.1.311.10.3.6,1.3.6.1.4.1.2312.16.1.2
nsComment = "OpenSSL Generated Certificate"

“1.3.6.1.4.1.2312.16.1.2” is included in extendedKeyUsage which tells shim that this is a module signing certificate. For generating key pair use

openssl req -config ./openssl.cnf \
-new -x509 -newkey rsa:2048 \
-nodes -days 3650 -outform DER \
-keyout "MOK.priv" \
-out "MOK.der"
openssl x509 -in MOK.der -inform DER -outform PEM -out MOK.pem

For enrolling keys with MOK use

sudo mokutil --import MOK.der

Conclusions

Taking control over system’s SecureBoot improves machine security by ensuring that only boot modules and kernels that are specifically approved can run.

--

--