1.. _how-to-enable-acrn-secure-boot-with-grub: 2 3Enable ACRN Secure Boot With GRUB 4################################# 5 6This document shows how to enable ACRN secure boot with GRUB including: 7 8- `ACRN Secure Boot Sequence`_ 9- `Generate GPG Key`_ 10- `Setup Standalone GRUB EFI Binary`_ 11- `Enable UEFI Secure Boot`_ 12 13**Validation Environment:** 14 15- Hardware Platform: Tiger Lake, supported hardware described in 16 :ref:`hardware`. 17- ACRN Scenario: Shared 18- Service VM: Yocto & Ubuntu 19- GRUB: 2.04 20 21.. note:: 22 Note that GRUB may stop booting in case of problems, make sure you 23 know how to recover a bootloader on your platform. 24 25ACRN Secure Boot Sequence 26************************* 27 28ACRN can be booted by a multiboot compatible bootloader. The following diagram 29illustrates the boot sequence of ACRN with GRUB: 30 31.. image:: images/acrn_secureboot_flow.png 32 :align: center 33 :width: 800px 34 35 36For details on enabling GRUB on ACRN, see :ref:`using_grub`. 37 38From a secure boot point of view: 39 40- UEFI firmware verifies shim/GRUB 41- GRUB verifies ACRN, Service VM kernel, and pre-launched User VM kernel 42- Service VM OS kernel verifies the Device Model (``acrn-dm``) and User 43 VM OVMF bootloader (with the help of ``acrn-dm``) 44- User VM virtual bootloader (e.g., OVMF) starts the guest side verified boot process 45 46This document shows you how to enable GRUB to 47verify ACRN binaries such as ``acrn.bin``, Service VM kernel (``bzImage``), and 48if present, a pre-launched User VM kernel image. 49 50.. rst-class:: numbered-step 51 52Generate GPG Key 53**************** 54 55GRUB supports loading GPG signed files only if digital signatures are 56enabled. Here's an example of generating a GPG signing key:: 57 58 mkdir --mode 0700 keys 59 gpg --homedir keys --gen-key 60 gpg --homedir keys --export > boot.key 61 62The :command:`gpg --gen-key` generates a public and private key pair. 63The private key is used to sign GRUB configuration files and ACRN 64binaries. The public key will be embedded in GRUB and is used to verify 65GRUB configuration files or binaries GRUB tries to load. 66 67.. rst-class:: numbered-step 68 69Setup Standalone GRUB EFI Binary 70******************************** 71 72Prepare Initial GRUB Configuration grub.init.cfg 73================================================ 74 75Create file ``grub.init.cfg`` to store the following minimal GRUB 76configuration. The environment variable ``check_signatures=enforce`` 77tells GRUB to enable digital signatures:: 78 79 set check_signatures=enforce 80 export check_signatures 81 82 search --no-floppy --fs-uuid --set=root ESP_UUID 83 configfile /grub.cfg 84 echo /grub.cfg did not boot the system, rebooting in 10 seconds. 85 sleep 10 86 reboot 87 88Replace the ESP_UUID with the UUID of your EFI system partition (found 89by running the :command:`lsblk -f`. In the example output below, 90the UUID is ``24FC-BE7A``: 91 92.. code-block:: console 93 :emphasize-lines: 2 94 95 sda 96 ├─sda1 vfat ESP 24FC-BE7A /boot/efi 97 ├─sda2 vfat OS 7015-557F 98 ├─sda3 ext4 UBUNTU e8640994-b2a3-45ad-9b72-e68960fb22f0 / 99 └─sda4 swap 262d1113-64be-4910-a700-670b9d2277cc [SWAP] 100 101 102Enable Authentication in GRUB 103============================= 104 105With authentication enabled, a user/password is required to restrict 106access to the GRUB shell, where arbitrary commands could be run. 107A typical GRUB configuration fragment (added to ``grub.init.cfg``) might 108look like this:: 109 110 set superusers="root" 111 export superusers 112 password_pbkdf2 root GRUB_PASSWORD_HASH 113 114Replace the ``GRUB_PASSWORD_HASH`` with the result of the :command:`grub-mkpasswd-pbkdf2` 115with your custom passphrase. 116 117Use this command to sign the :file:`grub.init.cfg` file with your private 118GPG key and create the :file:`grub.init.cfg.sig`:: 119 120 gpg --homedir keys --detach-sign grub.init.cfg 121 122 123Create Standalone GRUB EFI Binary 124================================= 125 126Use the ``grub-mkstandalone`` tool to create a standalone GRUB EFI binary 127file with the buit-in modules and the signed ``grub.init.cfg`` file. 128The ``--pubkey`` option adds a GPG public key that will be used for 129verification. The public key ``boot.key`` is no longer required. 130 131.. note:: 132 You should make a backup copy of your current GRUB image 133 (:file:`grubx64.efi`) before replacing it with the new signed GRUB image. 134 This would allow you to restore GRUB in case of errors updating it. 135 136Here's an example sequence to do this build:: 137 138 #!/bin/bash 139 # 140 141 TARGET_EFI='path/to/grubx64.efi' 142 143 # GRUB doesn't allow loading new modules from disk when secure boot is in 144 # effect, therefore pre-load the required modules. 145 146 MODULES="all_video archelp boot bufio configfile crypto echo efi_gop efi_uga ext2 extcmd \ 147 fat font fshelp gcry_dsa gcry_rsa gcry_sha1 gcry_sha512 gettext gfxterm linux ls \ 148 memdisk minicmd mmap mpi normal part_gpt part_msdos password_pbkdf2 pbkdf2 reboot relocator \ 149 search search_fs_file search_fs_uuid search_label sleep tar terminal verifiers video_fb" 150 151 grub-mkstandalone \ 152 --directory /usr/lib/grub/x86_64-efi \ 153 --format x86_64-efi \ 154 --modules "$MODULES" \ 155 --pubkey ./boot.key \ 156 --output ./grubx64.efi \ 157 "boot/grub/grub.cfg=./grub.init.cfg" \ 158 "boot/grub/grub.cfg.sig=./grub.init.cfg.sig" 159 160 echo "writing signed grub.efi to '$TARGET_EFI'" 161 sudo cp ./grubx64.efi "$TARGET_EFI" 162 163 164Prepare grub.cfg 165================ 166 167Define the menu entry for your system in a new GRUB configuration :file:`grub.cfg`. 168For example:: 169 170 # @/boot/efi/grub.cfg for grub secure boot 171 set timeout_style=menu 172 set timeout=5 173 set gfxmode=auto 174 set gfxpayload=keep 175 terminal_output gfxterm 176 177 menuentry "ACRN Multiboot Ubuntu Service VM" --users "" --id ubuntu-service-vm { 178 179 search --no-floppy --fs-uuid --set 3df12ea1-ef12-426b-be98-774665c7483a 180 181 echo 'loading ACRN...' 182 multiboot2 /boot/acrn/acrn.bin root=PARTUUID="c8ee7d92-8935-4e86-9e12-05dbeb412ad6" 183 module2 /boot/bzImage Linux_bzImage 184 } 185 186Use the output of the :command:`blkid` to find the right values for the 187UUID (``--set``) and PARTUUID (``root=PARTUUID=`` parameter) of the root 188partition (e.g., ``/dev/nvme0n1p2``) according to your hardware. 189 190Copy this new :file:`grub.cfg` to your ESP (e.g., ``/boot/efi/EFI/``). 191 192 193Sign grub.cfg and ACRN Binaries 194=============================== 195 196The :file:`grub.cfg` and all ACRN binaries that will be loaded by GRUB 197**must** be signed with the same GPG key. 198 199Here's a sequence example of signing the individual binaries:: 200 201 gpg --homedir keys --detach-sign path/to/grub.cfg 202 gpg --homedir keys --detach-sign path/to/acrn.bin 203 gpg --homedir keys --detach-sign path/to/service_vm_kernel/bzImage 204 205Now, you can reboot and the system will boot with the signed GRUB EFI binary. 206GRUB will refuse to boot if any files it attempts to load have been tampered 207with. 208 209 210.. rst-class:: numbered-step 211 212Enable UEFI Secure Boot 213*********************** 214 215Creating UEFI Secure Boot Key 216============================= 217 218- Generate your own keys for Secure Boot:: 219 220 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=PK/" -keyout PK.key -out PK.crt -days 7300 -nodes -sha256 221 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=KEK/" -keyout KEK.key -out KEK.crt -days 7300 -nodes -sha256 222 openssl req -new -x509 -newkey rsa:2048 -subj "/CN=db/" -keyout db.key -out db.crt -days 7300 -nodes -sha256 223 224- Convert ``*.crt`` keys to the ESL format understood for UEFI:: 225 226 cert-to-efi-sig-list PK.crt PK.esl 227 cert-to-efi-sig-list KEK.crt KEK.esl 228 cert-to-efi-sig-list db.crt db.esl 229 230- Sign ESL files:: 231 232 sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth 233 sign-efi-sig-list -k PK.key -c PK.crt KEK KEK.esl KEK.auth 234 sign-efi-sig-list -k KEK.key -c KEK.crt db db.esl db.auth 235 236- Convert to DER format:: 237 238 openssl x509 -outform DER -in PK.crt -out PK.der 239 openssl x509 -outform DER -in KEK.crt -out KEK.der 240 openssl x509 -outform DER -in db.crt -out db.der 241 242 243The keys to be enrolled in UEFI firmware: :file:`PK.der`, :file:`KEK.der`, :file:`db.der`. 244The keys to sign bootloader image: :file:`grubx64.efi`, :file:`db.key` , :file:`db.crt`. 245 246Sign GRUB Image With db Key 247=========================== 248 249Command example:: 250 251 sbsign --key db.key --cert db.crt path/to/grubx64.efi 252 253:file:`grubx64.efi.signed` will be created, it will be your bootloader. 254 255Enroll UEFI Keys to UEFI Firmware 256================================= 257 258Enroll ``PK`` (:file:`PK.der`), ``KEK`` (:file:`KEK.der`) and ``db`` 259(:file:`db.der`) in Secure Boot Configuration UI, which depends on your 260platform UEFI firmware. In UEFI configuration menu UI, follow the steps 261in :ref:`this section <qemu_inject_boot_keys>` that shows how to enroll UEFI 262keys, using your own key files. From now on, only EFI binaries 263signed with any ``db`` key (:file:`grubx64.efi.signed` in this case) can 264be loaded by UEFI firmware. 265