Skip to content

Commit

Permalink
Cleanup of security-boot-software-updates-stm32mp1
Browse files Browse the repository at this point in the history
Changes made according to the style guidelines and to improve readability.

QA Steps: Ran Linter/spellcheck, built and visually inspected output. No issues spotted in rendering.

This commit applies to FFTK-2795

Signed-off-by: Katrina Prosise <katrina.prosise@foundries.io>
  • Loading branch information
kprosise committed Feb 6, 2024
1 parent e51e4d9 commit 5a8f141
Showing 1 changed file with 78 additions and 106 deletions.
184 changes: 78 additions & 106 deletions source/reference-manual/security/boot-software-updates-stm32mp1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,48 +11,41 @@ Boot Artifacts
STM32 TF-A BL2 Image
~~~~~~~~~~~~~~~~~~~~

The **TF-A BL2** image is the first boot image loaded by the application processor's
trusted ROM. It is in charge of loading the next-stage images (secure and
non-secure) and preliminary initialization of required peripherals:
The **TF-A BL2** image is the first boot image loaded by the application processor's trusted ROM.
It is in charge of loading the next-stage images (secure and non-secure) and preliminary initialization of required peripherals:

- SoC clocks, DRAM
- Security IPs: memory firewalls, crypto engines
- Storage (MMC, QSPI etc).

The image is prepended with `STM32 header <https://wiki.st.com/stm32mpu/wiki/STM32_header_for_binary_files>`_.
The image is prepended with a `STM32 header <https://wiki.st.com/stm32mpu/wiki/STM32_header_for_binary_files>`_.

It can also be signed using the STM32 Signing tool.

TF-A FIP Image
~~~~~~~~~~~~~~

The Trusted Firmware-A Firmware Image Package (TF-A FIP) the signed
FIP-image that contains U-Boot proper (``u-boot.bin``) and other firmware.
This file is verified by TF-A BL2 using RoT HASH (of the public key) in the BL2
device tree blob and public key, which are provided by the FIP image.
This artifact may be signed (on closed boards) as a part of CI and
can be included automatically in a boot software OTA package.
The *Trusted Firmware-A Firmware Image Package* (TF-A FIP) is the signed FIP-image containing U-Boot proper (``u-boot.bin``) and other firmware.
This file is verified by TF-A BL2 using RoT HASH (of the public key) in the BL2 device tree blob and public key.
These are provided by the FIP image.
This artifact may be signed—on closed boards—as part of CI, and can be included automatically in a boot software OTA package.

List of images inside FIP Image container:
List of images inside a FIP Image container:

- U-boot-nodtb.bin (U-Boot proper binary)
- U-boot.dtb (U-Boot device tree)
- ``U-boot-nodtb.bin`` (U-Boot proper binary)
- ``U-boot.dtb`` (U-Boot device tree)
- OP-TEE runtime (OP-TEE core, which provides PSCI and secure services)

If the CI signing key has been rotated since the last OTA,
update the BL2 verification data prior to trying to boot the
new FIP-image.
If the CI signing key has been rotated since the last OTA, update the BL2 verification data prior to trying to boot the new FIP-image.

MMC Boot Image Layout
---------------------

The location of the boot image depends on what boot media is being used.
For eMMC, the initial boot images are flashed to a *0x0* offset of the boot
hw partitions.
For eMMC, the initial boot images are flashed to a ``0x0`` offset of the boot hw partitions.

When using a SD as boot media, boot images of different offsets are used within
the same HW partition. For additional details see :ref:`flash-layout-emmc`
and :ref:`wks-layout-sd`.
When using a SD card as boot media, boot images of different offsets are used within the same HW partition.
For additional details see :ref:`flash-layout-emmc` and :ref:`wks-layout-sd`.

Update Procedure
----------------
Expand All @@ -65,84 +58,70 @@ The STM32MP1 SoC supports booting from two copies of First Stage Boot Loaders:
- First Stage Boot Loader Copy 1 (FSBL1)
- First Stage Boot Loader Copy 2 (FSBL2)

Unfortunately, the SoC does not provide any mechanisms for a user to control in
runtime what FSBL copy to boot —only the SoC ROM can make this decision based
on image authentication/checksum results. As such, the setup for FSBL1
is treated as the primary boot path, with FSBL2 as a recovery path (secondary
boot path) in case the authentication/loading of FSBL1 fails.
Unfortunately, the SoC does not provide any mechanisms for a user to control in runtime what FSBL copies to boot.
Only the SoC ROM can make this decision based on image authentication/checksum results.
As such, the setup for FSBL1 is treated as the primary boot path, with FSBL2 as a recovery path (secondary boot path) in case the authentication/loading of FSBL1 fails.

Libaktualizr and Aktualizr-lite
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Libaktualizr and Aktualizr-lite make decisions during the boot
phase. Those decisions are listed below, ordered as they appear in the source code:
Libaktualizr and aktualizr-lite make decisions during the boot phase.
Those decisions are listed below, ordered as they appear in the source code:

1. aktualizr-lite makes the decision if boot firmware needs to be updated based
on the contents of ``${ostree_root}/usr/lib/firmware/version.txt`,
where ``ostree_root`` is root of newly deployed ostree sysroot.
1. Aktualizr-lite makes the decision if boot firmware needs to be updated based on the contents of ``${ostree_root}/usr/lib/firmware/version.txt``.
Here, ``ostree_root`` is root of the newly deployed ostree sysroot.
For example, ``bootfirmware_version=10``.

2. After parsing ``bootfirmware_version``, it compares version number with
the existing one, which is obtained via **fiovb** or **ubootenv**.
2. After parsing ``bootfirmware_version``, it compares the version number with the existing one, obtained via ``fiovb`` or ``ubootenv``.

3. If ``bootfirmware_version`` from ``version.txt`` is higher than existing
one, Aktualizr-lite sets ``bootupgrade_available`` via **fiovb** or **ubootenv**.
3. If ``bootfirmware_version`` from ``version.txt`` is higher than the existing one, Aktualizr-lite sets ``bootupgrade_available`` via ``fiovb`` or ``ubootenv``.

4. Reboot is to be performed.

The U-Boot boot.cmd Script
~~~~~~~~~~~~~~~~~~~~~~~~~~
The U-Boot ``boot.cmd`` Script
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following steps represent the boot path from U-Boot's perspective.

1. The update is done via the U-Boot **boot.cmd** (boot.scr) script.
1. The update is done via the U-Boot ``boot.cmd`` (``boot.scr``) script.

2. The **boot.cmd** script checks if the primary path was booted.
2. ``boot.cmd`` checks if the primary path was booted.

3. In case ``upgrade_available`` is set, the script checks if a boot firmware
upgrade is needed by looking into ``bootupgrade_available`` flag.
If both are true, boot firmware images are then obtained from the newly
deployed ostree sysroot and written to the primary boot path offsets.
Afterwards, ``bootupgrade_primary_updated`` is set, and a regular reset signal is
issued.
3. If ``upgrade_available`` is set, check if a boot firmware upgrade is needed by checking the ``bootupgrade_available`` flag.
If both are true, boot firmware images are obtained from the newly deployed ostree sysroot, and written to the primary boot path offsets.
Afterwards, ``bootupgrade_primary_updated`` is set, and a regular reset signal is issued.

4. After the reboot, the SoC ROM tries to boot newly updated images from the primary
boot path (FSBL1). If image verification fails, it will automatically fall
back to FSBL2. When FSBL2 is booted, a rollback procedure will be issued,
the previous version of FSBL1 will be restored. If FSBL1 *does* boot, but *bootcount*
hits *bootlimit* (meaning the boot procedure has not finished
successfully), the rollback procedure will be also issued.
4. After the reboot, the SoC ROM tries to boot newly updated images from the primary boot path (FSBL1).
If image verification fails, it will automatically fall back to FSBL2.
When FSBL2 is booted, a rollback procedure will be issued, and the previous version of FSBL1 will be restored.
If FSBL1 *does* boot, but *bootcount* hits *bootlimit* (meaning the boot procedure has not finished successfully), the rollback procedure will be also issued.

5. After Linux is booted, Aktualizr-lite confirms a successful update by clearing
the ``upgrade_available`` flag. At this point, new boot firmware images are
already validated. An additional reboot is needed after this step.
5. After Linux is booted, Aktualizr-lite confirms a successful update by clearing the ``upgrade_available`` flag.
At this point, new boot firmware images are already validated.
An additional reboot is needed after this step.

6. After rebooting, U-Boot checks if ``bootupgrade_primary_updated`` is set and
if ``upgrade_available`` is cleared. This means that Aktualizr-lite
has confirmed a successful boot, and U-Boot clears
``bootupgrade_primary_updated`` flag. Otherwise the ``bootcount`` value is
incremented.
6. After rebooting, U-Boot checks if ``bootupgrade_primary_updated`` is set and if ``upgrade_available`` is cleared.
This means that Aktualizr-lite has confirmed a successful boot, and U-Boot clears ``bootupgrade_primary_updated``.
Otherwise ``bootcount`` is incremented.

Adding a new Board
Adding a New Board
------------------

meta-lmp
~~~~~~~~
``meta-lmp``
~~~~~~~~~~~~

.. _flash-layout-emmc:

Flash Layout File (eMMC Boot)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To deploy boot images to the destination board, **STM32CubeProg** is used.
This tool uses a special configuration file (with a **tsv** extension) that contains
the eMMC flash layout. For additional details, refer to the official
To deploy boot images to the destination board, ``STM32CubeProg`` is used.
This tool uses a special configuration file (with a ``tsv`` extension) that contains the eMMC flash layout.
For additional details, refer to the official
`documentation <https://wiki.st.com/stm32mpu/wiki/STM32CubeProgrammer_flashlayout>`_.

As **STM32CubeProg** does not support defining offsets
inside boot0/boot1 hw partitions, **TF-A BL2** and **FIP** are both combined
into one image in advance. This is done with correct padding between them,
so they are flashed to the correct offsets during STM32CubeProg execution:
As ``STM32CubeProg`` does not support defining offsets inside boot0/boot1 hw partitions, **TF-A BL2** and **FIP** are both combined into one image in advance.
This is done with the correct padding between them, so that they are flashed to the correct offsets during ``STM32CubeProg`` execution:

::

Expand All @@ -151,9 +130,9 @@ so they are flashed to the correct offsets during STM32CubeProg execution:

.. note::

Concatenation is done automatically via the flashlayouts-stm32mp1.bb recipe.
Concatenation is done automatically via the ``flashlayouts-stm32mp1.bb`` recipe.

Example of TSV file:
Example TSV file:

::

Expand All @@ -175,8 +154,7 @@ In a SD setup, two sets of FSBL images are stored, each with different offsets:
- FSBL1 *17KB*
- FSBL2 *256KB*

To support both images, the WKS file should be adjusted so that both copies
are placed at the correct offsets:
To support both images, the WKS file should be adjusted so that both copies are placed at the correct offsets:

::

Expand All @@ -191,23 +169,21 @@ are placed at the correct offsets:
Testing FSBL Set and Auth Status
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

After applying the updates from previous steps, we should validate that
everything is in place. This consists of two steps:
After applying the updates from previous steps, we should validate that everything is in place.
This consists of two steps:

- FSBL1 vs FSBL2 detection (primary or secondary path)
- Obtain board security state (results of FSBL authentication)

To test FSBP copy detection, check the ``boot\_part`` variable
using U-Boot shell:
To test FSBP copy detection, check ``boot\_part`` using U-Boot shell:

::

STM32MP> print boot_part
boot_part=1


To check if the security status of your board is shown correctly, check
the ``boot\_auth`` variable:
To check if the security status of your board is shown correctly, check ``boot\_auth``:

::

Expand All @@ -216,21 +192,18 @@ the ``boot\_auth`` variable:

Possible values are:

- **0** - No authentication done
- **1** - Authentication done and failed
- **2** - Authentication done and success
- **0** No authentication done
- **1** Authentication done and failed
- **2** Authentication done and success

boot.cmd
~~~~~~~~
``boot.cmd``
~~~~~~~~~~~~

Currently, LmP uses template-based generation for the final boot.cmd.
It's constructed from common boot files
(``./meta-lmp-base/recipes-bsp/u-boot/u-boot-ostree-scr-fit``),
which contains all SoC agnostic "DEFINEs" and common functionality, and
board-specific ``boot.cmd``, which includes the common scripts.
LmP uses template-based generation for the final ``boot.cmd``.
It is constructed from common boot files (``./meta-lmp-base/recipes-bsp/u-boot/u-boot-ostree-scr-fit``).
These contain all SoC agnostic "DEFINEs", common functionality, and board-specific ``boot.cmd``, including common scripts.

Example of board boot.cmd
(``./meta-lmp-bsp/recipes-bsp/u-boot/u-boot-ostree-scr-fit/stm32mp15-eval/boot.cmd``):
Example of ``boot.cmd`` (``./meta-lmp-bsp/recipes-bsp/u-boot/u-boot-ostree-scr-fit/stm32mp15-eval/boot.cmd``):

::

Expand Down Expand Up @@ -308,23 +281,21 @@ Example of board boot.cmd
Sysroot and Signed Boot Artifacts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Boot artifacts (TF-A BL2 and FIP) are automatically deployed
to sysroot during build time. On closed boards however, where the initial boot
image has to be signed in advance by a subscriber private key, there is a way to
add a signed binary instead of relying on the automatic inclusion of unsigned boot artifacts.
Boot artifacts (TF-A BL2 and FIP) are automatically deployed to sysroot during build time.
On closed boards however, where the initial boot image has to be signed in advance by a private key,
there is a way to add a signed binary instead.

To do that, just add ``lmp-boot-firmware.bbappend`` to your *meta-subscriber-overrides*
layer, adding the path to the signed binary and the signed binary itself.
Add ``lmp-boot-firmware.bbappend`` to your ``meta-subscriber-overrides`` layer.
Add both the path and the signed binary itself.

Then define boot firmware version number by setting ``LMP_BOOT_FIRMWARE_VERSION``
global variable in your ``lmp-factory-custom.inc``. Boot firmware version
information will be automatically added to `${osroot}/usr/lib/firmware/version.txt`
file and U-Boot Device Tree Blob.
Then define the boot firmware version number by setting the ``LMP_BOOT_FIRMWARE_VERSION`` global variable in ``lmp-factory-custom.inc``.
Boot firmware version information will be automatically added to both ``${osroot}/usr/lib/firmware/version.txt`` and the U-Boot Device Tree Blob.

Versioning convention is up to user, the only requirement is that the version
string should be unique and there should not be duplicates.
Versioning convention is up to you.
The only requirement is that the version string be unique; there should not be duplicates.

Example:

::

diff --git a/recipes-bsp/lmp-boot-firmware/lmp-boot-firmware.bbappend b/recipes-bsp/lmp-boot-firmware/lmp-boot-firmware.bbappend
Expand Down Expand Up @@ -352,9 +323,10 @@ Example:

.. note::

As ``LMP_BOOT_FIRMWARE_VERSION`` is now a preferable way to set boot firmware version, defining ``PV`` in ``lmp-boot-firmware.bbappend``
is deprecated and should not be used. To switch to a new approach just remove ``PV = "<version>"`` line from
``lmp-boot-firmware.bbappend`` and define ``LMP_BOOT_FIRMWARE_VERSION`` with appropriate version value as shown above in the example.
``LMP_BOOT_FIRMWARE_VERSION`` is now the preferred way to set the boot firmware version.
Defining ``PV`` in ``lmp-boot-firmware.bbappend`` is deprecated and should not be used.
To switch, first remove ``PV = "<version>"`` from ``lmp-boot-firmware.bbappend`` .
Then define ``LMP_BOOT_FIRMWARE_VERSION`` with the appropriate version value, as in the above example.

.. seealso::
* :ref:`ref-secure-boot-stm32mp1`

0 comments on commit 5a8f141

Please sign in to comment.