Secure Firmware Update

Revision as of 08:27, 10 May 2022 by Registered User
Applicable for STM32MP13x lines, STM32MP15x lines

The secure firmware update implemented in STM32MP family follows the ARM proposal Platform Security Firmware Update for the A-profile Arm[1]


1. Firmware update overview[edit source]


Secure update firmware purpose is to be able to update the boot loader. TF-A itself is not updated by this process, only the FIP (optee, uboot, and their respective signatures and certificates). This is a secure update because wrong images (due to error while download, flash, or tamper) won't boot, but system is still runable, it will boot the previous known working FIP after a some (system defined) attempts.

The next figure explains how the update data go through all components.

Next figure explains how the boot occurs, taking into account the secure firmware update.

Describe Secure Firmware Update boot process

2. TF-A[edit source]

TF-A manages the secure boot, it checks each element in FIP are correctly signed, decipher if needed, manage anti-rollback, and if all is fine, run them.

Firmware update is enabled with PSA_FWU_SUPPORT=1 in makefile. TF-A will manage FIP selection (to boot the expected FIP), and will manage recovery and error management after a new FIP has been downloaded from non secure world.

In nominal use case, TF-A selects which FIP to load. (in OpenSTLinux TF-A can choose between 2 FIP, 2 areas are reserved in the the boot flash to store these images). TF-A will read metadata from the boot flash (2 metadata area are reserved, the 2 metadata should be the same, and TF-A check that they are valid before using them)

2.1. Metadata[edit source]

Metadata structure is defined in include/drivers/fwu/fwu_metadata.h Note that Metadata are only read by the TF-A, only the Update Agent will write/update them.

Important fields for TFA in metadata are:

	metadata->active_index
	metadata->previous_active_index

These fields define the index of img_prop[] currently active and the previous working index. TF-A will load, verify, then boot software of the FIP found at the active_index.

	metadata->img_entry[0]
	metadata->img_entry[0].img_type_uuid
	metadata->img_entry[0].location_uuid

We only have one img_entry, has we only need to find one FIP (define by the haredcodec FIP UUID in img_type_uuid) from one filesystem (the boot device UUID define in location_uuid

	metadata->img_entry[0].img_prop[X]
	metadata->img_entry[0].img_prop[X].img_uuid
	metadata->img_entry[0].img_prop[X].accepted

X (X can ben 0 to 1 in OpenSTLinux (deinfined by NR_OF_FW_BANK) img_uuid define where to find the image X, directly with the UUID with a GPT partitioned device (EMMC or SD-CARD) or thanks to a correspondance between the UUID and an offset in case of RAW-NAND and NOR boot device) accepted is set to 1 by the Update Agent after a full boot success on this image.

2.2. Firmware update boot process[edit source]

On boot TF-A reads values from metadata: metadata->active_index, metadata->previous_active_index, metadata->img_entry[0].img_prop[metadata->active_index].accepted

2.2.1. After a FIP update[edit source]

After a FIP update the active_index is not yet accepted (we have metadata->img_entry[0].img_prop[metadata->active_index].accepted == 0) we are in Trial mode. To avoid infinite boot loop with a non working FIP, as long as we are in Trial mode, before selecting FIP, we decrement the trial counter (a Backup Register). If the trial counter is not 0, we load, authenticate, run the active_index FIP, (after a succefull boot in this configuration, the Update Agent has to update the accepted field to 1). If the trial counter is 0, we know the boot didn't go till the Update Agent in all previous attempt, this 4th time, the TF-A will load, authenticate, and run the the FIP at previous_active_index (a FIP image that was known working). This is the responsability of the Update Agent to detect that the over the air update failed, and take actions (retry download, ...). Indeed the Update Agent can read the metatadata, and knows, thanks to a Backup Register, which index value was used to select the FIP.

2.2.2. Regular start[edit source]

In regular case, the active_index FIP is known working (accepted value is 1). We load, verify, run entries from the selected FIP, and will set the Backup Register that store the number trial boot to FWU_MAX_TRIAL_REBOOT[2] (default value: 3) to prepare any future trial mode.

3. Update Agent[edit source]

The Update Agent responsibility is to manage the FIP update.

  • check if a new FIP image is availlable
  • download the new image
  • program the new FIP in correct place.
  • manage metadata:
    • set new value for active_index and previous_active_index and accepted after flashing a new FIP.
    • set metadata->img_entry[0].img_prop[boot_index].accepted to 1, if it detects that the boot_index saved in backup register is not yet accepted.
    • manage the case a newly flashed FIP failed (when the backup register storing firware update information value is metadata->previous_active_index).