80fe12fbe5
This file required an editorial scrub. Poorly structured and formatted. Several instances of uncommented narrative text in code-blocks. Grammer and punct. errors. Etc. Signed-off-by: Ron Stone <ronald.stone@windriver.com> Change-Id: I3fdb3982b162fdc4ce50d4b034a649d0589648df
383 lines
15 KiB
ReStructuredText
383 lines
15 KiB
ReStructuredText
|
|
.. fyl1552681364538
|
|
.. _use-uefi-secure-boot:
|
|
|
|
====================
|
|
Use UEFI Secure Boot
|
|
====================
|
|
|
|
Secure Boot is supported in |UEFI| installations only. It is not used when
|
|
booting |prod| as a legacy boot target.
|
|
|
|
.. contents:: |minitoc|
|
|
:local:
|
|
:depth: 1
|
|
|
|
|prod| currently does not support switching from legacy to |UEFI| mode after a
|
|
system has been installed. Doing so requires a reinstallation of the system.
|
|
This also means that upgrading from a legacy install to a secure boot install
|
|
(|UEFI|) is not supported.
|
|
|
|
When upgrading a |prod| system from a version which does not support secure
|
|
boot to a version that does, do not enable secure boot in |UEFI| firmware until
|
|
the upgrade is complete.
|
|
|
|
For each node that is going to use secure boot, you must populate the |prod|
|
|
public certificate/key in the |UEFI| Secure Boot authorized database in
|
|
accordance with the board manufacturer's process. This must be done for each
|
|
node before starting installation.
|
|
|
|
You may need to work with your hardware vendor to have the certificate
|
|
installed.
|
|
|
|
There is often an option in the |UEFI| setup utility which allows a user to
|
|
browse to a file containing a certificate to be loaded in the authorized
|
|
database. This option may be hidden in the |UEFI| setup utility unless |UEFI|
|
|
mode is enabled, and secure boot is enabled.
|
|
|
|
Many motherboards ship with Microsoft secure boot certificates
|
|
pre-programmed in the |UEFI| certificate database. These certificates may be
|
|
required to boot |UEFI| drivers for video cards, RAID controllers, or NICs
|
|
(for example, the |PXE| boot software for a NIC may have been signed by a
|
|
Microsoft certificate). While certificates can usually be removed from the
|
|
certificate database (again, this is |UEFI| implementation specific) it
|
|
may be required that you keep the Microsoft certificates to allow for
|
|
complete system operation.
|
|
|
|
Mixed combinations of secure boot and non-secure boot nodes are supported.
|
|
For example, a controller node may secure boot, while a worker node may not.
|
|
Secure boot must be enabled in the |UEFI| firmware of each node for that node
|
|
to be protected.
|
|
|
|
.. only:: partner
|
|
|
|
.. include:: /_includes/extract-certificate-from-iso-181be684e2e5.rest
|
|
|
|
.. only:: starlingx
|
|
|
|
------------------------------------------------------------------------------
|
|
Build considerations for signing packages for UEFI Secure Boot -- CentOS build
|
|
------------------------------------------------------------------------------
|
|
|
|
The |prod| build environment has provisions for calling out to a signing
|
|
server for purposes of creating a secure boot load. At this time |prod|
|
|
does not include an implementation of the signing server. The following
|
|
describes how the signing process is intended to work in the context of a
|
|
CentOS build. You may find it helpful in implementing your own signing
|
|
server.
|
|
|
|
The following environmental variables should be defined before attempting
|
|
to request a secure boot signing:
|
|
|
|
.. code-block:: bash
|
|
|
|
export SIGNING_SERVER=<signing-host>
|
|
export SIGNING_USER=<signing-user>
|
|
export SIGNING_SERVER_SCRIPT=<path-to-signing-script>
|
|
|
|
``build-pkgs`` further requires that ``$USER`` be set to "jenkins", and
|
|
:command:`export FORMAL_BUILD=1``.
|
|
|
|
If the above criteria is met, it calls into ``sign-secure-boot``.
|
|
|
|
This is an example of the call sequence:
|
|
|
|
.. code-block:: bash
|
|
|
|
# 1. Set up the server side directory for files transfers.
|
|
UPLOAD_PATH=`ssh $SIGNING_USER@$SIGNING_SERVER sudo $SIGNING_SCRIPT -r`
|
|
|
|
# 2. upload the original package
|
|
scp -q $FILE $SIGNING_USER@$SIGNING_SERVER:$UPLOAD_PATH
|
|
|
|
# 3. Request that the package be signed
|
|
ssh $SIGNING_USER@$SIGNING_SERVER sudo $SIGNING_SCRIPT -v -i $UPLOAD_PATH/$(basename $FILE) $UNSIGNED_OPTION -t $TYPE > $TMPFILE
|
|
|
|
# 4. Download the file from the signing server
|
|
DOWNLOAD_FILENAME=$(basename $OUTPUT_FILE)
|
|
scp -q $SIGNING_USER@$SIGNING_SERVER:$OUTPUT_FILE $(dirname $FILE)
|
|
|
|
|
|
Within the signing server there are two keys used for signing, known as the
|
|
`boot` key and the `shim` key. The public `boot` key file must be manually
|
|
added to the secure boot keychain in the firmware. The `boot` key signs the
|
|
first executable loaded, contained in the `shim` package. The first
|
|
executable must then install the public `shim` key file (automatically)
|
|
before passing control to the grub, and ultimately the kernel, both of
|
|
which are signed by the private `shim` key.
|
|
|
|
Three packages need to be passed to the signing server. The RPMs need to be
|
|
unpacked, the relevant binaries signed with the correct keys, and the RPMs
|
|
reassembled.
|
|
|
|
.. table::
|
|
:widths: auto
|
|
|
|
+---------+------+------------------------------------+
|
|
| Package | Key | Files to sign |
|
|
+=========+======+====================================+
|
|
| shim | boot | BOOTX64, shim, shimx64 |
|
|
| | shim | MokManager, fallback, mmx64, fbx64 |
|
|
+---------+------+------------------------------------+
|
|
| grub | shim | grubx64.efi, gcdx64.efi |
|
|
+---------+------+------------------------------------+
|
|
| kernel | shim | |
|
|
+---------+------+------------------------------------+
|
|
|
|
.. note::
|
|
|
|
`shim` files that are required to be signed might might include a
|
|
``.efi`` or ``.EFI`` suffix.
|
|
|
|
Some files may be absent in newer packages.
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
sbsign --key $KEYPATH/$KEYNAME.key --cert $KEYPATH/$KEYNAME.crt --output $SIGNEDFILE $UNSIGNEDFILE
|
|
|
|
.. rubric:: Keys and certificates:
|
|
|
|
* ``boot.crt`` - Certificate to boot (to be programmed in firmware)
|
|
|
|
* ``boot.key`` - Private key with which to sign shim
|
|
|
|
* ``shim.crt`` - Certificated embedded within shim used to validate kernel, grub
|
|
|
|
* ``shim.key`` - Private key with which to sign kernel/grub
|
|
|
|
.. rubric:: Key generation:
|
|
|
|
.. code-block:: none
|
|
|
|
openssl req -new -x509 -newkey rsa:2048 -keyout $KEY.key -out $KEY.pem -days 3650
|
|
openssl x509 -in $KEY.pem -out $KEY.crt -outform DER
|
|
|
|
.. note::
|
|
|
|
``boot.crt`` should be copied to
|
|
``cgcs-root/build-tools/certificates/TiBoot.crt`` for inclusion during the
|
|
``build-iso`` step.
|
|
|
|
------------------------------------------------------------------------------
|
|
Build considerations for signing packages for UEFI Secure Boot -- Debian build
|
|
------------------------------------------------------------------------------
|
|
|
|
The |prod| build environment has provisions for calling out to a signing
|
|
server for purposes of creating a secure boot load. At this time |prod|
|
|
does not include an implementation of the signing server. The following
|
|
describes how the signing process is intended to work in the context of a
|
|
``Debian`` build. You may find it helpful in implementing your own signing
|
|
server.
|
|
|
|
The secure boot verification sequence of StarlingX Debian is:
|
|
|
|
#. UEFI firmware verify shim image
|
|
|
|
#. shim verify grub image
|
|
|
|
#. grub verify kernel image and initramfs image
|
|
|
|
The bootloader shim will enroll the public key to verify grub image.
|
|
|
|
The bootloader grub-efi will enroll the public key to verify kernel and
|
|
initramfs image.
|
|
|
|
The following process should be followed to request a secure boot signing:
|
|
|
|
.. code-block:: none
|
|
|
|
......
|
|
stx control keys-add --key-type=signing-server --key=[key file]
|
|
stx shell
|
|
downloader
|
|
build-pkgs
|
|
export SIGNING_SERVER="signing_user@signing_server_ip"
|
|
sign-secure-boot_debian
|
|
build-image
|
|
|
|
The "key file" is the private key generated by :command:`ssh-keygen -t rsa`
|
|
and used to setup signing server access without password.
|
|
|
|
The signing script ``sign-secure-boot_debian`` does secure boot signing for
|
|
|prod| Debian as follows:
|
|
|
|
|
|
#. Sign shim / grub images
|
|
|
|
The shim/grub efi images are obtained from extracted shim/grub
|
|
packages, and they are sent to signing server and signed there and
|
|
copied back. Then the shim/grub packages are repacked with the
|
|
signed efi images.
|
|
|
|
#. Sign kernel images and ``LockDown.efi``
|
|
|
|
The file sign_rootfs-post-scripts is inserted to where the hook script
|
|
"rootfs-post-scripts" is defined in the LAT config file
|
|
``base-bullseye.yaml``. This will sign kernel images and
|
|
``LockDown.efi`` on signing server in the LAT build process. The
|
|
"rootfs-post-scripts" is the hook in LAT tool running after rootfs is
|
|
created.
|
|
|
|
#. Sign initramfs and mini initrd
|
|
|
|
The file`` sign_initramfs-sign-script`` is inserted to where the hook
|
|
script ``initramfs-sign-script`` is defined in the LAT config file
|
|
``base-bullseye.yaml``. This will sign initramfs and mini initrd on
|
|
signing server in the LAT build process. The ``initramfs-sign-script``
|
|
is the hook in LAT tool running after initramfs is created.
|
|
|
|
**2** and **3** above prepare the signing codes in the LAT config file.
|
|
After build-image is triggered, the signing codes inserted into the LAT
|
|
config files will run on the LAT container in the correct sequence.
|
|
|
|
Here is an example for signing an image file in sign-secure-boot_debian:
|
|
|
|
.. code-block:: bash
|
|
|
|
# Request upload path from signing server.
|
|
REQUEST=$(ssh ${SSH_OPTION_NOCHECKING} ${SIGNING_SERVER} sudo /opt/signing/sign-debian.sh -r)
|
|
UPLOAD_PATH=${REQUEST#*Upload: }
|
|
|
|
# Copy shimx64.efi to signing server
|
|
scp ${SSH_OPTION_NOCHECKING} shimx64.efi ${SIGNING_SERVER}:${UPLOAD_PATH}
|
|
# Sign shimx64.efi
|
|
ssh ${SSH_OPTION_NOCHECKING} ${SIGNING_SERVER} sudo /opt/signing/sign-debian.sh -i ${UPLOAD_PATH}/shimx64.efi -t shim
|
|
# Copy back signed shimx64.efi which is renamed as bootx64.efi
|
|
sudo scp ${SSH_OPTION_NOCHECKING} ${SIGNING_SERVER}:${UPLOAD_PATH}/bootx64.efi ./
|
|
|
|
``sign-debian.sh``, above, is the script running on signing server whose
|
|
interface is defined as below:
|
|
|
|
.. code-block:: none
|
|
|
|
Usage:
|
|
sign-debian.sh [options]
|
|
|
|
[-i <file>] - input unsigned file
|
|
[-t <type>] - type of signing to do
|
|
[-r] - request an upload path
|
|
|
|
Types of signing:
|
|
-t shim - signs a shim EFI binary with the boot key
|
|
-t grub - signs a GRUB EFI binary with the shim key
|
|
-t shimtool - signs a shim tool EFI binary with the shim key
|
|
-t grub-gpg - signs a kernel/initrd/grub.cfg with the grub gpg key
|
|
|
|
.. _key-management-use-uefi-secure-boot:
|
|
|
|
.. rubric:: Keys management:
|
|
|
|
|
|
Upstream stx public keys repo: https://opendev.org/starlingx/public-keys
|
|
|
|
The keys under cgcs-root/public-keys are the public keys used in
|
|
the verification process of secure boot process for StarlingX
|
|
Debian.
|
|
|
|
.. rubric:: Keys Introduction:
|
|
|
|
``tis-boot.crt``: The public key flashed into |UEFI| to verify
|
|
``bootx64.efi`` (signed shim image ``shimx64.efi``)
|
|
|
|
``tis-shim.der``: The public key used by shim to verify
|
|
``grubx64.efi`` (signed grub image) and ``mmx64.efi``
|
|
(signed shim tool image);
|
|
|
|
``boot_pub_key``: it is the public key used by grub to verify signed
|
|
kernel image and initramfs image and efitools image and so on.
|
|
|
|
``TiBoot.crt``: it is the same pub key with ``tis-boot.crt`` (pem) as a
|
|
der format. It is installed as ``/CERTS/TiBoot.crt`` in the ``efi.img``
|
|
which is in the iso image.
|
|
|
|
The following methods can be used to create substitute keys:
|
|
|
|
#. Example to create ``tis-boot.crt/TiBoot.crt``.
|
|
|
|
.. code-block:: bash
|
|
|
|
openssl req -new -x509 -newkey rsa:2048 -keyout BOOT.priv -outform DER -out BOOT.der -days 36500 -subj "/CN=My Boot/" -nodes
|
|
openssl x509 -inform der -in BOOT.der -out BOOT.pem
|
|
cp BOOT.pem tis-boot.crt
|
|
cp BOOT.priv tis-boot.key
|
|
cp BOOT.der TiBoot.crt
|
|
|
|
|
|
The ``tis-boot.crt`` and ``tis-boot.key`` are used to sign images
|
|
mentioned above (shim image).
|
|
|
|
The ``tis-shim.crt``/``tis-shim.der``/``tis-shim.key`` can be created in
|
|
the same way, and used to sign images mentioned above (grub image and
|
|
shim tool image).
|
|
|
|
#. Example to create ``boot_pub_key``.
|
|
|
|
.. code-block:: bash
|
|
|
|
#!/bin/bash
|
|
key_dir="./"
|
|
priv_key="${key_dir}/BOOT-GPG-PRIVKEY-SecureBootCore"
|
|
pub_key="${key_dir}/BOOT-GPG-KEY-SecureBootCore"
|
|
name_real="SecureBootCore"
|
|
pw="PASSWORD"
|
|
USE_PW="Passphrase: PASSWORD"
|
|
cat >"${key_dir}/gen_keyring" <<EOF
|
|
Key-Type: RSA
|
|
Key-Length: 4096
|
|
Name-Real: ${name_real}
|
|
Name-Comment: EXAMPLE
|
|
Name-Email: a@b.com
|
|
Expire-Date: 0
|
|
${USE_PW}
|
|
%commit
|
|
%echo keyring ${name_real} created
|
|
EOF
|
|
|
|
gpg --homedir "${key_dir}" --batch --yes --gen-key "${key_dir}/gen_keyring"
|
|
gpg --homedir "${key_dir}" -k
|
|
gpg --homedir "${key_dir}" --export --armor "${name_real}" > "${pub_key}"
|
|
gpg --homedir "${key_dir}" --export-secret-keys --pinentry-mode=loopback --passphrase "${pw}" --armor "${name_real}" > "${priv_key}"
|
|
gpg --homedir "${key_dir}" --export "${name_real}" > ${key_dir}/boot_pub_key
|
|
|
|
The ``BOOT-GPG-PRIVKEY-SecureBootCore`` is used to sign images mentioned
|
|
above (kernel image, initramfs image and efitools image and so on).
|
|
|
|
#. Signing commands to sign image files:
|
|
|
|
* Signing command to sign type shim/grub/shimtool image files:
|
|
|
|
.. code-block:: none
|
|
|
|
sbsign --key $KEYPATH/$KEYNAME.key \
|
|
--cert $KEYPATH/$KEYNAME.crt \
|
|
--output $SIGNEDFILE \
|
|
$UNSIGNEDFILE
|
|
|
|
* for ``-t shim``, the output file name is ``bootx64.efi``
|
|
|
|
* for ``-t grub``, the output file name is ``grubx64.efi``
|
|
|
|
* for ``-t shimtool``, the output file name is ${UNSIGNEDFILE}.signed
|
|
|
|
* Signing command to sign type grub-gpg files:
|
|
|
|
.. code-block::
|
|
|
|
gpg2 --batch \
|
|
--homedir ${GPGHOME} \
|
|
--passphrase PASSWORD \
|
|
--import ${KEYPATH}/${BOOT_GPG_PRI_KEY}
|
|
echo 'PASSWORD' | \
|
|
gpg2 --pinentry-mode loopback \
|
|
--batch \
|
|
--homedir ${GPGHOME} \
|
|
-u SecureBootCore \
|
|
--detach-sign \
|
|
--passphrase-fd 0 \
|
|
${FILEIN}
|
|
|
|
Refer to :ref:`Key management <key-management-use-uefi-secure-boot>`
|
|
to determine the keys they should use.
|