mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-31 07:20:55 +00:00
doc: Setup secureboot with GRUB
Add guide to enable grub secure boot on ACRN. Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Signed-off-by: David B. Kinder <david.b.kinder@intel.com>
This commit is contained in:
parent
124752fcf7
commit
4759735c99
@ -72,6 +72,7 @@ Enable ACRN Features
|
||||
tutorials/setup_openstack_libvirt
|
||||
tutorials/acrn_on_qemu
|
||||
tutorials/using_grub
|
||||
tutorials/acrn-secure-boot-with-grub
|
||||
tutorials/pre-launched-rt
|
||||
tutorials/enable_ivshmem
|
||||
|
||||
|
259
doc/tutorials/acrn-secure-boot-with-grub.rst
Normal file
259
doc/tutorials/acrn-secure-boot-with-grub.rst
Normal file
@ -0,0 +1,259 @@
|
||||
.. _how-to-enable-acrn-secure-boot-with-grub:
|
||||
|
||||
Enable ACRN Secure Boot with GRUB
|
||||
#################################
|
||||
|
||||
This document shows how to enable ACRN secure boot with GRUB including:
|
||||
|
||||
- ACRN Secure Boot Sequence
|
||||
- Generate GPG Key
|
||||
- Setup Standalone GRUB EFI Binary
|
||||
- Enable UEFI Secure Boot
|
||||
|
||||
**Validation Environment:**
|
||||
|
||||
- Hardware Platform: TGL-I7, Supported hardware described in
|
||||
:ref:`hardware`.
|
||||
- ACRN Scenario: Industry
|
||||
- Service VM: Yocto & Ubuntu
|
||||
- GRUB: 2.04
|
||||
|
||||
.. note::
|
||||
Note that GRUB may stop booting in case of problems, make sure you
|
||||
know how to recover a bootloader on your platform.
|
||||
|
||||
ACRN Secure Boot Sequence
|
||||
*************************
|
||||
|
||||
ACRN can be booted by Multiboot compatible bootloader, following diagram
|
||||
illustrates the boot sequence of ACRN with GRUB:
|
||||
|
||||
.. image:: images/acrn_secureboot_flow.png
|
||||
:align: center
|
||||
:width: 800px
|
||||
|
||||
|
||||
For details on enabling GRUB on ACRN, see :ref:`using_grub`.
|
||||
|
||||
From a secureboot point of view:
|
||||
|
||||
- UEFI firmware verifies shim/GRUB
|
||||
- GRUB verifies ACRN, Service VM kernel, and pre-launched User VM kernel
|
||||
- Service VM OS kernel verifies the Device Model (``acrn-dm``) and User
|
||||
VM OVMF bootloader (with the help of ``acrn-dm``)
|
||||
- User VM virtual bootloader (e.g. OVMF) starts the guest side verified boot process
|
||||
|
||||
This document shows you how to enable GRUB to
|
||||
verify ACRN binaries such ``acrn.bin``, Service VM kernel (``bzImage``), and
|
||||
if present, a pre-launched User VM kernel image.
|
||||
|
||||
.. rst-class:: numbered-step
|
||||
|
||||
Generate GPG Key
|
||||
****************
|
||||
|
||||
GRUB supports loading GPG signed files only if digital signatures are
|
||||
enabled. Here's an example of generating a GPG signing key::
|
||||
|
||||
mkdir --mode 0700 keys
|
||||
gpg --homedir keys --gen-key
|
||||
gpg --homedir keys --export > boot.key
|
||||
|
||||
The :command:`gpg --gen-key` generates a public and private key pair.
|
||||
The private key is used to sign GRUB configuration files and ACRN
|
||||
binaries. The public key will be embedded in GRUB and is used to verify
|
||||
GRUB configuration files or binaries GRUB tries to load.
|
||||
|
||||
.. rst-class:: numbered-step
|
||||
|
||||
Setup Standalone GRUB EFI Binary
|
||||
********************************
|
||||
|
||||
Prepare Initial GRUB Configuration grub.init.cfg
|
||||
================================================
|
||||
|
||||
Create file ``grub.init.cfg`` to store the following minimal GRUB
|
||||
configuration. The environment variable ``check_signatures=enforce``
|
||||
tells GRUB to enable digital signatures::
|
||||
|
||||
set check_signatures=enforce
|
||||
export check_signatures
|
||||
|
||||
search --no-floppy --fs-uuid --set=root ESP_UUID
|
||||
configfile /grub.cfg
|
||||
echo /grub.cfg did not boot the system, rebooting in 10 seconds.
|
||||
sleep 10
|
||||
reboot
|
||||
|
||||
Replace the ESP_UUID with the UUID of your EFI system partition (found
|
||||
by running the :command:`lsblk -f`. In the example output below,
|
||||
the UUID is ``24FC-BE7A``:
|
||||
|
||||
.. code-block:: console
|
||||
:emphasize-lines: 2
|
||||
|
||||
sda
|
||||
├─sda1 vfat ESP 24FC-BE7A /boot/efi
|
||||
├─sda2 vfat OS 7015-557F
|
||||
├─sda3 ext4 UBUNTU e8640994-b2a3-45ad-9b72-e68960fb22f0 /
|
||||
└─sda4 swap 262d1113-64be-4910-a700-670b9d2277cc [SWAP]
|
||||
|
||||
|
||||
Enable Authentication in GRUB
|
||||
=============================
|
||||
|
||||
With authentication enabled, a user/password is required to restrict
|
||||
access to the GRUB shell, where arbitrary commands could be run.
|
||||
A typical GRUB configuration fragment (added to ``grub.init.cfg``) might
|
||||
look like this::
|
||||
|
||||
set superusers="root"
|
||||
export superusers
|
||||
password_pbkdf2 root GRUB_PASSWORD_HASH
|
||||
|
||||
Replace the ``GRUB_PASSWORD_HASH`` with the result of the :command:`grub-mkpasswd-pbkdf2`
|
||||
with your custom passphrase.
|
||||
|
||||
Use this command to sign the :file:`grub.init.cfg` file with your private
|
||||
GPG key and create the :file:`grub.init.cfg.sig`::
|
||||
|
||||
gpg --homedir keys --detach-sign grub.init.cfg
|
||||
|
||||
|
||||
Create Standalone GRUB EFI Binary
|
||||
=================================
|
||||
|
||||
Use the ``grub-mkstandalone`` tool to create a standalone GRUB EFI binary
|
||||
file with the buit-in modules and the signed ``grub.init.cfg`` file.
|
||||
The ``--pubkey`` option adds a GPG public key that will be used for
|
||||
verification. The public key ``boot.key`` is no longer required.
|
||||
|
||||
.. note::
|
||||
You should make a backup copy of your current GRUB image
|
||||
(:file:`grubx64.efi`) before replacing it with the new signed GRUB image.
|
||||
This would allow you to restore GRUB in case of errors updating it.
|
||||
|
||||
Here's an example sequence to do this build::
|
||||
|
||||
#!/bin/bash
|
||||
#
|
||||
|
||||
TARGET_EFI='path/to/grubx64.efi'
|
||||
|
||||
# GRUB doesn't allow loading new modules from disk when secure boot is in
|
||||
# effect, therefore pre-load the required modules.
|
||||
|
||||
MODULES="all_video archelp boot bufio configfile crypto echo efi_gop efi_uga ext2 extcmd \
|
||||
fat font fshelp gcry_dsa gcry_rsa gcry_sha1 gcry_sha512 gettext gfxterm linux linuxefi ls \
|
||||
memdisk minicmd mmap mpi normal part_gpt part_msdos password_pbkdf2 pbkdf2 reboot relocator \
|
||||
search search_fs_file search_fs_uuid search_label sleep tar terminal verifiers video_fb"
|
||||
|
||||
grub-mkstandalone \
|
||||
--directory /usr/lib/grub/x86_64-efi \
|
||||
--format x86_64-efi \
|
||||
--modules "$MODULES" \
|
||||
--pubkey ./boot.key \
|
||||
--output ./grubx64.efi \
|
||||
"boot/grub/grub.cfg=./grub.init.cfg" \
|
||||
"boot/grub/grub.cfg.sig=./grub.init.cfg.sig"
|
||||
|
||||
echo "writing signed grub.efi to '$TARGET_EFI'"
|
||||
sudo cp ./grubx64.efi "$TARGET_EFI"
|
||||
|
||||
|
||||
.. rst-class:: numbered-step
|
||||
|
||||
Prepare grub.cfg
|
||||
****************
|
||||
|
||||
Define the menu entry for your system in a new GRUB configuration :file:`grub.cfg`.
|
||||
For example::
|
||||
|
||||
# @/boot/efi/grub.cfg for grub secure boot
|
||||
set timeout_style=menu
|
||||
set timeout=5
|
||||
set gfxmode=auto
|
||||
set gfxpayload=keep
|
||||
terminal_output gfxterm
|
||||
|
||||
menuentry "ACRN Multiboot Ubuntu Service VM" --users "" --id ubuntu-service-vm {
|
||||
|
||||
search --no-floppy --fs-uuid --set 3df12ea1-ef12-426b-be98-774665c7483a
|
||||
|
||||
echo 'loading ACRN...'
|
||||
multiboot2 /boot/acrn/acrn.bin root=PARTUUID="c8ee7d92-8935-4e86-9e12-05dbeb412ad6"
|
||||
module2 /boot/bzImage Linux_bzImage
|
||||
}
|
||||
|
||||
Use the output of the :command:`blkid` to find the right values for the
|
||||
UUID (``--set``) and PARTUUID (``root=PARTUUID=`` parameter) of the root
|
||||
partition (e.g. `/dev/nvme0n1p2`) according to your your hardware.
|
||||
|
||||
Copy this new :file:`grub.cfg` to your ESP (e.g. `/boot/efi/EFI/`).
|
||||
|
||||
|
||||
.. rst-class:: numbered-step
|
||||
|
||||
Sign grub.cfg and ACRN Binaries
|
||||
*******************************
|
||||
|
||||
The :file:`grub.cfg` and all ACRN binaries that will be loaded by GRUB
|
||||
**must** be signed with the same GPG key.
|
||||
|
||||
Here's sequence example of signing the individual binaries::
|
||||
|
||||
gpg --homedir keys --detach-sign path/to/grub.cfg
|
||||
gpg --homedir keys --detach-sign path/to/acrn.bin
|
||||
gpg --homedir keys --detach-sign path/to/sos_kernel/bzImage
|
||||
|
||||
Now, you can reboot and the system will boot with the signed GRUB EFI binary.
|
||||
GRUB will refuse to boot if any files it attempts to load have been tampered
|
||||
with.
|
||||
|
||||
|
||||
.. rst-class:: numbered-step
|
||||
|
||||
Enable UEFI Secure Boot
|
||||
***********************
|
||||
|
||||
Creating UEFI Secure Boot Key
|
||||
=============================
|
||||
|
||||
-Generate your own keys for Secure Boot::
|
||||
|
||||
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=PK/" -keyout PK.key -out PK.crt -days 7300 -nodes -sha256
|
||||
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=KEK/" -keyout KEK.key -out KEK.crt -days 7300 -nodes -sha256
|
||||
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=db/" -keyout db.key -out db.crt -days 7300 -nodes -sha256
|
||||
|
||||
-Convert ``*.crt`` keys to the ESL format understood for UEFI::
|
||||
|
||||
cert-to-efi-sig-list PK.crt PK.esl
|
||||
cert-to-efi-sig-list KEK.crt KEK.esl
|
||||
cert-to-efi-sig-list db.crt db.esl
|
||||
|
||||
-Sign ESL files::
|
||||
|
||||
sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth
|
||||
sign-efi-sig-list -k PK.key -c PK.crt KEK KEK.esl KEK.auth
|
||||
sign-efi-sig-list -k KEK.key -c KEK.crt db db.esl db.auth
|
||||
|
||||
The keys to be enrolled in UEFI firmware: :file:`PK.der`, :file:`KEK.der`, :file:`db.der`.
|
||||
The keys to sign bootloader image: :file:`grubx64.efi`, :file:`db.key` , :file:`db.crt`.
|
||||
|
||||
Sign GRUB Image With ``db`` Key
|
||||
================================
|
||||
|
||||
sbsign --key db.key --cert db.crt path/to/grubx64.efi
|
||||
|
||||
:file:`grubx64.efi.signed` will be created, it will be your bootloader.
|
||||
|
||||
Enroll UEFI Keys To UEFI Firmware
|
||||
=================================
|
||||
|
||||
Enroll ``PK`` (:file:`PK.der`), ``KEK`` (:file:`KEK.der`) and ``db``
|
||||
(:file:`db.der`) in Secure Boot Configuration UI, which depends on your
|
||||
platform UEFI firmware. In UEFI configuration menu UI, follow the steps
|
||||
in :ref:`this section <qemu_inject_boot_keys>` that shows how to enroll UEFI
|
||||
keys, using your own key files. From now on, only EFI binaries
|
||||
signed with any ``db`` key (:file:`grubx64.efi.signed` in this case) can
|
||||
be loaded by UEFI firmware.
|
BIN
doc/tutorials/images/acrn_secureboot_flow.png
Normal file
BIN
doc/tutorials/images/acrn_secureboot_flow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -473,6 +473,8 @@ Notes:
|
||||
|
||||
- Make sure your GCC is 5.X. GCC 6 and above is NOT supported.
|
||||
|
||||
.. _qemu_inject_boot_keys:
|
||||
|
||||
Use QEMU to inject secure boot keys into OVMF
|
||||
*********************************************
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user