Add doc/usage/efi_secureboot.rst describing how to enable and use
UEFI Secure Boot in U-Boot.

Link the new document from doc/usage/index.rst, and add a "See also"
pointer from doc/board/qualcomm/index.rst so Qualcomm-board readers
can still discover it easily.

Signed-off-by: Aswin Murugan <[email protected]>
---
 doc/board/qualcomm/index.rst |   6 ++
 doc/usage/efi_secureboot.rst | 176 +++++++++++++++++++++++++++++++++++
 doc/usage/index.rst          |   1 +
 3 files changed, 183 insertions(+)
 create mode 100644 doc/usage/efi_secureboot.rst

diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst
index 3238a68e859..7785ef945c8 100644
--- a/doc/board/qualcomm/index.rst
+++ b/doc/board/qualcomm/index.rst
@@ -14,3 +14,9 @@ Qualcomm
    iq8
    phones
    rdp
+
+See also
+--------
+
+For enabling and using UEFI Secure Boot, see the 
:doc:`../../usage/efi_secureboot`
+guide.
diff --git a/doc/usage/efi_secureboot.rst b/doc/usage/efi_secureboot.rst
new file mode 100644
index 00000000000..69a019dec6c
--- /dev/null
+++ b/doc/usage/efi_secureboot.rst
@@ -0,0 +1,176 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+EFI Secure Boot
+================
+
+About this
+-----------
+This document describes how to enable and use UEFI Secure Boot in U-Boot,
+and how to generate and enroll the keys required to authenticate EFI images
+(such as GRUB, the Linux EFI stub kernel, or a Unified Kernel Image) before
+they are executed.
+
+This guide uses the variable preseeding method, where the PK/KEK/db keys
+are generated on a build host and embedded into the U-Boot image at build
+time via ``CONFIG_EFI_VARIABLES_PRESEED``, so that they are already
+enrolled the first time the board boots. This is different from
+interactively enrolling keys at runtime.
+
+Secure Boot trust model
+------------------------
+UEFI Secure Boot relies on a hierarchy of keys and signature databases:
+
+- **PK (Platform Key)** - the root authority. The PK owner controls updates
+  to the KEK database.
+- **KEK (Key Exchange Key)** - authorizes updates to the ``db``/``dbx``
+  signature databases.
+- **db (Signature Database)** - contains the certificates/hashes that are
+  allowed to sign EFI images which U-Boot will execute.
+- **dbx (Forbidden Signature Database)** - contains revoked certificates or
+  hashes.
+
+At boot, U-Boot validates the signature of an EFI image against ``db`` and
+rejects images that are untrusted or that have been revoked via ``dbx``.
+
+Preseeded variable store
+^^^^^^^^^^^^^^^^^^^^^^^^^
+The authenticated variables (``PK``, ``KEK``, ``db``, ``dbx``) are normally
+enrolled at runtime through the platform firmware. For an embedded boot
+flow, U-Boot instead supports *preseeding* these variables at build time.
+
+A file named ``ubootefi.var`` is generated on the build host and embedded
+into the U-Boot image when ``CONFIG_EFI_VARIABLES_PRESEED`` is enabled, so
+that the PK/KEK/db are already enrolled the first time the board boots.
+
+Required build configuration
+-----------------------------
+To enable EFI Secure Boot support, the following options must be enabled in
+the U-Boot configuration. A ready-made config fragment is provided at
+``configs/efi_secureboot.config``::
+
+    CONFIG_EFI_VARIABLES_PRESEED=y
+    CONFIG_EFI_SECURE_BOOT=y
+    CONFIG_FIT_SIGNATURE=y
+    CONFIG_SHA512=y
+    CONFIG_SHA384=y
+
+To enable Secure Boot for a given board, configure U-Boot for that board
+and then merge the ``configs/efi_secureboot.config`` fragment into the
+resulting ``.config`` using ``scripts/kconfig/merge_config.sh``::
+
+    make CROSS_COMPILE=<toolchain-prefix> <your_board>_defconfig
+    scripts/kconfig/merge_config.sh .config configs/efi_secureboot.config
+
+Generating keys and enrolling them
+-----------------------------------
+The following steps are performed once, on a controlled Linux signing host,
+to generate the PK/KEK/db key pairs and certificates, and to produce the
+preseeded variable store that gets embedded into U-Boot. The examples use
+RSA-2048 and SHA-256.
+
+Step 1: Generate PK, KEK, and db credentials
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Generate a random GUID to identify the owner, then generate the three
+self-signed certificates::
+
+    uuidgen --random > GUID.txt
+
+    # PK | Platform Key
+    openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Custom PK/" \
+      -keyout PK.key -out PK.crt -days 3650 -nodes -sha256
+
+    # KEK | Key Exchange Key
+    openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Custom KEK/" \
+      -keyout KEK.key -out KEK.crt -days 3650 -nodes -sha256
+
+    # db | Image signing key
+    openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Custom DB Signing Key 
1/" \
+      -keyout db.key -out db.crt -days 3650 -nodes -sha256
+
+This produces the following outputs: ``PK.key``/``PK.crt``,
+``KEK.key``/``KEK.crt`` and ``db.key``/``db.crt``.
+
+Step 2: Create EFI Signature Lists
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Using the ``efitools`` package, convert each certificate into an EFI
+Signature List (``.esl``)::
+
+    cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt  PK.esl
+    cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl
+    cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt  db.esl
+
+Step 3: Preseed ubootefi.var
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+From the U-Boot source tree, use ``tools/efivar.py`` (matching the branch
+being built) to populate the preseeded variable store with the ``.esl``
+files generated above.
+
+The global (platform) GUID ``8be4df61-93ca-11d2-aa0d-00e098032b8c`` is used
+for ``PK`` and ``KEK``, while the image security GUID
+``d719b2cb-3d3a-4596-a3bc-dad00e67656f`` is used for ``db`` and ``dbx``::
+
+    tools/efivar.py set --infile ubootefi.var --name PK \
+      --attrs nv,bs,rt,at --guid 8be4df61-93ca-11d2-aa0d-00e098032b8c \
+      --type file --data PK.esl
+
+    tools/efivar.py set --infile ubootefi.var --name KEK \
+      --attrs nv,bs,rt,at --guid 8be4df61-93ca-11d2-aa0d-00e098032b8c \
+      --type file --data KEK.esl
+
+    tools/efivar.py set --infile ubootefi.var --name db \
+      --attrs nv,bs,rt,at --guid d719b2cb-3d3a-4596-a3bc-dad00e67656f \
+      --type file --data db.esl
+
+The resulting ``ubootefi.var`` file is picked up by the build when
+``CONFIG_EFI_VARIABLES_PRESEED`` is enabled, and gets embedded into the
+U-Boot image so the keys are enrolled from first boot.
+
+Step 4: Sign the EFI images that will be booted
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Every EFI PE/COFF executable that U-Boot will load directly (bootloader
+stub, GRUB, EFI stub kernel or UKI, etc.) must be signed with the ``db`` key
+so that it validates against the enrolled signature database. Using
+``sbsign`` (from ``sbsigntool``), mount the EFI System Partition image,
+sign the executables, and replace the originals::
+
+    mkdir -p efimountedbin
+    sudo mount -o loop efi.bin efimountedbin
+
+    cp efimountedbin/EFI/BOOT/bootaa64.efi ./bootaa64.efi
+    # Copy the EFI-stub kernel or UKI only if it is directly loaded as an EFI 
executable
+    cp efimountedbin/EFI/Linux/<linux-image>.efi ./<linux-image>.efi
+
+    sbsign --key db.key --cert db.crt --output bootaa64.efi.signed bootaa64.efi
+    sbsign --key db.key --cert db.crt --output <linux-image>.efi.signed 
<linux-image>.efi
+
+    sudo cp bootaa64.efi.signed efimountedbin/EFI/BOOT/bootaa64.efi
+    sudo cp <linux-image>.efi.signed efimountedbin/EFI/Linux/<linux-image>.efi
+
+    sync && sudo umount efimountedbin
+
+.. note::
+   ``<linux-image>.efi`` refers to the EFI-stub kernel image name used on
+   the target. Replace it with the actual kernel/UKI file name being
+   signed.
+
+Step 5: Build U-Boot with Secure Boot enabled
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+With the configuration above merged into ``.config``, build U-Boot as
+usual::
+
+    make CROSS_COMPILE=<toolchain-prefix> -j$(nproc)
+
+Using Secure Boot
+------------------
+Once U-Boot boots with the preseeded PK/KEK/db enrolled:
+
+- Only EFI images signed with a key present in ``db`` (and not present in
+  ``dbx``) will be allowed to execute via the ``bootefi``/``bootmgr``
+  commands.
+- Unsigned images, or images signed by a key that is not enrolled, will be
+  rejected, and U-Boot will print ``Image not authenticated`` on the
+  console.
+- ``dbx`` can be updated (via a properly signed authenticated variable
+  update, following the same process as Steps 1-3 above) to revoke a
+  previously trusted signing key, for example if a signing key is
+  compromised.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 6f477b842ca..aad2454c773 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -16,6 +16,7 @@ Use U-Boot
    cmdline
    semihosting
    measured_boot
+   efi_secureboot
    upl
 
 Shell commands
-- 
2.34.1

Reply via email to