Registered User mNo edit summary |
Registered User mNo edit summary Tag: 2017 source edit |
||
(32 intermediate revisions by 6 users not shown) | |||
Line 5: | Line 5: | ||
== Article purpose == | == Article purpose == | ||
This article explains how to protect the software loaded by the main processor into the coprocessor | This article explains how to protect the software loaded by the main processor into the coprocessor and ensure the authentication of the loaded firmware. | ||
{{Info| | {{Info| | ||
The protection of the coprocessor firmware by authentication is enabled by default on the {{MicroprocessorDevice | device=25}}. | The protection of the coprocessor firmware by authentication is enabled by default on the {{MicroprocessorDevice | device=25}}. | ||
}} | }} | ||
== Introduction == | == Introduction == | ||
The Linux<sup>®</sup> | The Linux<sup>®</sup> OS, (through the [[Linux_remoteproc_framework_overview|remoteproc framework]]) or the [[How_to_start_the_coprocessor_from_the_bootloader|U-Boot]] enables the loading of firmware into control remote processors. Thanks to a specific [[STM32 MPU OP-TEE_overview | OP-TEE trusted application (TA)]] and the resource isolation framework running on the [[Security_overview | Arm<sup>®</sup> TrustZone]], it is possible to authenticate a Cortex<sup>®</sup>-M firmware image and install them on [[#Memory management | isolated RAMs]] to ensure its integrity during the execution. | ||
From user's point of view the management of a | From the user's point of view the management of a nonauthenticated or authenticated firmware does not differ, whether the firmware is managed by the Linux or by the U-Boot. The difference is that the management of the authenticated firmware is delegated to the [[STM32 MPU OP-TEE_overview | OP-TEE]] firmware running in the Arm<sup>®</sup> TrustZone. | ||
== Principles == | == Principles == | ||
The protection of the coprocessor firmware relies on hash computation and on the encryption key to authenticate a firmware, as does the isolation of the execution memories to ensure execution integrity. | The protection of the coprocessor firmware relies on hash computation and on the encryption key to authenticate a firmware, as does the isolation of the execution memories to ensure execution integrity.<br /> | ||
<br /> | The firmware is signed using an [[STM32 MPU OP-TEE_overview | OP-TEE]] signature script. This script concatenates one or several ELF binaries, then adds a header and TLV (type length value) metadata that provide elements for the authentication among other firmware information: | ||
:* | :* A hash table, which contains the hash of the segment to load. | ||
:* | :* A signature computed with the private key. | ||
* During the execution phase: | * During the execution phase: | ||
:* | :* The signed firmware binary is read from the file system by the [[Linux_remoteproc_framework_overview|remoteproc framework]] and the image is provided to the OP-TEE trusted application. | ||
:* | :* The firmware image is authenticated and installed by the OP-TEE trusted application in the protected Cortex<sup>®</sup>-M memories. | ||
[[File:authenticate_rproc_fw.png|950px|link=]] | [[File:authenticate_rproc_fw.png|950px|link=]] | ||
=== Firmware signature === | === Firmware signature === | ||
Line 32: | Line 31: | ||
{{ImageMap | File:rproc_fw_signature.png {{!}} 900px {{!}} Signature procedure | {{ImageMap | File:rproc_fw_signature.png {{!}} 900px {{!}} Signature procedure | ||
rect 31 1689 456 2150 [[# | rect 31 1689 456 2150 [[#STM32Cube_firmware | STM32Cube firmware]] | ||
rect 48 886 474 1356 [[# | rect 48 886 474 1356 [[#Generate_private_and_public_keys | Keys generation]] | ||
rect 1022 904 2654 2207 [[# | rect 1022 904 2654 2207 [[#Cortex-M_firmware_signature | Sign the STM32CubeMP1_firmware]] | ||
rect 1014 162 2659 851 [[#OP- | rect 1014 162 2659 851 [[#OP-TEE_configuration | OP-TEE OS with public Key]] | ||
}} | }} | ||
*The signature consists in: | *The signature consists in: | ||
:# | :# Parsing the program table in the ELF file to identify the segments to load. | ||
:# | :# Computing the hash of each segment and saving the result in the hash table chunk of the header. | ||
:# | :# Computing the hash of the header and signing the hash with the private key. | ||
*The public key is embedded in the OP-TEE OS firmware that is in charge of the Cortex-M firmware authentication. | *The public key is embedded in the OP-TEE OS firmware that is in charge of the Cortex<sup>®</sup>-M firmware authentication. | ||
=== Memory management === | === Memory management === | ||
===={{MicroprocessorDevice | device=15}} ==== | ===={{MicroprocessorDevice | device=15}} ==== | ||
The [[STM32MP15 MCU SRAM internal memory | MCU SRAM]] and the [[RETRAM internal memory|RETRAM]] memories can be dedicated to Cortex-M usage (isolated), shared with the Cortex-A | The [[STM32MP15 MCU SRAM internal memory | MCU SRAM]] and the [[RETRAM internal memory|RETRAM]] memories can be dedicated to Cortex<sup>®</sup>-M usage (isolated), shared with the Cortex<sup>®</sup>-A nonsecure context, or protected for Cortex<sup>®</sup>-A secure access only.<br> | ||
The [[ETZPC_internal_peripheral | ETZPC]] mechanism is used: | The [[ETZPC_internal_peripheral | ETZPC]] mechanism is used: | ||
* | * During the load and authentication phase: to lock the memories for Cortex<sup>®</sup>-A secure access only. | ||
* | * During the execution phase: to isolate the memories for coprocessor usage (such as code execution and data) or share them with the Cortex<sup>®</sup>-A nonsecure context (such as RPMsg shared buffers). | ||
* On coprocessor stop: to lock the memories for Cortex<sup>®</sup>-A secure access only to clean up the memories. | |||
{{ Info |When creating a Cortex-M firmware build, developers must be careful to pack in a same memory bank all the data shared with the Cortex-A. This enables the isolation of the rest of the memory banks for the Cortex-M context. }} | |||
{{ Info |When creating a Cortex<sup>®</sup>-M firmware build, developers must be careful to pack in a same memory bank all the data shared with the Cortex<sup>®</sup>-A (for example, resource table and trace buffer). This enables the isolation of the rest of the memory banks for the Cortex<sup>®</sup>-M context. }} | |||
The information provided in this article | The information provided in this article respects the memory mapping described in [[STM32MP15_RAM_mapping#Zoom in the Cortex-A7/Cortex-M4 shared memory|memory mapping]] section: | ||
* '''RETRAM''', '''MCU SRAM1''' and '''MCU SRAM2''' | * '''RETRAM''', '''MCU SRAM1''' and '''MCU SRAM2''' are used for code execution and data. They are only accessible by the Cortex<sup>®</sup>-A secure context when no firmware is running, and assigned to Cortex<sup>®</sup>-M context during authenticated firmware execution. | ||
* '''MCU SRAM3''' (IPC buffers) is shared between the Cortex-A | * '''MCU SRAM3''' (IPC buffers) is shared between the Cortex<sup>®</sup>-A nonsecure context and the Cortex<sup>®</sup>-M. No protection is applied to this memory bank. | ||
* '''MCU SRAM4''' is reserved for the Cortex-A | * '''MCU SRAM4''' is reserved for the Cortex<sup>®</sup>-A nonsecure context. It is thus free for other usage. | ||
This mapping can be customized depending on project requirements. In this case, the code has to be updated in a synchronized manner in [[STM32CubeMP15_Package | STM32CubeMP15]] firmware, [[Device_tree |Linux | This memory mapping can be customized depending on project requirements. In this case, the code has to be updated in a synchronized manner in [[STM32CubeMP15_Package | STM32CubeMP15]] firmware, [[Device_tree |Linux kernel device tree]] and the [[STM32 MPU OP-TEE_overview |OP-TEE rproc PTA]] code. | ||
===={{MicroprocessorDevice | device=25}} ==== | ===={{MicroprocessorDevice | device=25}} ==== | ||
The DDR, [[ STM32MP2_SRAM_internal_memory | SRAM]] and/or [[RETRAM_internal_memory | RETRAM]] memory regions can be dedicated to Cortex-M usage (isolated), shared with the Cortex-A | The DDR, [[ STM32MP2_SRAM_internal_memory | SRAM]] and/or [[RETRAM_internal_memory | RETRAM]] memory regions can be dedicated to Cortex<sup>®</sup>-M usage (isolated), shared with the Cortex<sup>®</sup>-A nonsecure context, or protected for Cortex<sup>®</sup>-A secure access only.<br> | ||
The RIF | The [[Resource_Isolation_Framework_overview | RIF]] is used: | ||
* | * During the load and authentication phase: To lock the memories for Cortex<sup>®</sup>-A secure access only. | ||
* | * During the execution phase: To apply the access right defined in the OP-TEE device-tree to isolate the memories for the coprocessor usage. | ||
* On coprocessor stop: to lock the memories for Cortex<sup>®</sup>-A secure access only to clean up the memories. | |||
{{ Info |When creating a Cortex<sup>®</sup>-M firmware build, developers must be careful to pack in a same memory bank all the data shared with the Cortex<sup>®</sup>-A (e.g resource table and trace buffer). This enables the isolation of the rest of the memory banks for the Cortex<sup>®</sup>-M context. }} | |||
The information provided in this article respects the memory mapping described in [[STM32MP25_memory_mapping |memory mapping]] section: | |||
* Some '''DDR''' memory regions and the '''MCU SRAM2''' are prereserved for code execution and data. They are only accessible by the Cortex<sup>®</sup>-M secure or nonsecure contexts thanks to the [[Resource_Isolation_Framework_overview | RIF]] CID filtering. | |||
* A dedicated '''DDR''' memory region is shared between the Cortex<sup>®</sup>-A nonsecure context and the Cortex<sup>®</sup>-M. No protection is applied to this memory bank. | |||
This mapping can be customized depending on project requirements. In this case, the code has to be updated in a synchronized manner in the STM32CubeMP2, the TF-M firmware, the [[Device_tree |Linux | This [[STM32MP25_memory_mapping | memory mapping]] can be customized depending on project requirements. In this case, the code has to be updated in a synchronized manner in the [[STM32CubeMP2_Package | STM32CubeMP2]], the [[TF-M_overview | TF-M]] firmware, the [[Device_tree |Linux kernel device tree]] and the [[STM32 MPU OP-TEE_overview |OP-TEE device tree]] code. | ||
=== Authentication === | === Authentication === | ||
Line 81: | Line 82: | ||
[[File:Authentication_Fw_load_phase1.png|950px|link=]] | [[File:Authentication_Fw_load_phase1.png|950px|link=]] | ||
'''1.''' The firmware is copied by the Linux | '''1.''' The firmware is copied by the Linux kernel (or U-Boot) to nonsecure DDR memory.<BR> | ||
'''2.''' The firmware header is copied to a secure memory to ensure its integrity during the authentication steps.<BR> | '''2.''' The firmware header is copied to a secure memory to ensure its integrity during the authentication steps.<BR> | ||
'''3.''' The header hash is computed.<BR> | '''3.''' The header hash is computed.<BR> | ||
Line 96: | Line 97: | ||
=== Authenticated firmware live-cycle === | === Authenticated firmware live-cycle === | ||
[[File:Authentication_software_overview.png|950px|link=]] | [[File:Authentication_software_overview.png|950px|link=]] | ||
From the user's point of view, the management of a firmware live-cycle does not change, whether the firmware is managed by OP-TEE or not. The management of firmware is described in the [[Linux_remoteproc_framework_overview#How_to_use_the_framework | remoteproc]] article. | From the user's point of view, the management of a firmware live-cycle does not change, whether the firmware is managed by OP-TEE or not. The management of firmware is described in the [[Linux_remoteproc_framework_overview#How_to_use_the_framework | remoteproc]] article. | ||
The main difference compared to a | The main difference compared to a nonauthenticated firmware is that the remote processor framework delegates the coprocessor management to the OP-TEE. | ||
{{Info| Since the | {{Info| Since the authentication is activated, it is no longer possible to load and start a nonauthenticated firmware.}} | ||
{{Info| The authenticated firmware can also be [[How_to_start_the_coprocessor_from_the_bootloader | | {{Info| The authenticated firmware can also be [[How_to_start_the_coprocessor_from_the_bootloader |preloaded and started]] by the U-Boot.}} | ||
==== Firmware loading and authentication ==== | ==== Firmware loading and authentication ==== | ||
* As for a | * As for a nonauthenticated firmware, the firmware is read from the file system by the [[Linux_remoteproc_framework_overview|remoteproc framework]]. The image is then sent to the OP-TEE trusted application. | ||
* The OP-TEE remoteproc trusted application manages authentication and memory isolation in the secure context. | * The OP-TEE remoteproc trusted application manages authentication and memory isolation in the secure context. | ||
==== Firmware start and stop ==== | ==== Firmware start and stop ==== | ||
* As for a | * As for a nonauthenticated firmware, the firmware start and stop requests are handled by the [[Linux_remoteproc_framework_overview|remoteproc framework]], but they are delegated to the Arm<sup>®</sup> TrustZone. | ||
* The firmware start and stop are executed by the OP-TEE. The reset and RAM access rights are only accessible by the secure context. | * The firmware start and stop are executed by the OP-TEE. The reset and RAM access rights are only accessible by the secure context. | ||
:* | :* During the firmware loading step, the Cortex<sup>®</sup>-M memories access rights are updated to provide access to the Cortex<sup>®</sup>-A secure context. Once the firmware is loaded, the default memory access right defined in the OP-TEE device tree are reapplied. | ||
:* After stopping the firmware, the Cortex-M memories | :* After stopping the firmware, the Cortex<sup>®</sup>-M memories are cleaned by OP-TEE. | ||
==== RPMsg management ==== | ==== RPMsg management ==== | ||
As the resource tables and RPMsg vrings and buffers are in a | As the resource tables and RPMsg vrings and buffers are in a shared memory and accessible by both Cortex, it is possible to communicate with the authenticated firmware. | ||
==== Firmware core dump ==== | ==== Firmware core dump ==== | ||
Line 124: | Line 125: | ||
==== OP-TEE configuration==== | ==== OP-TEE configuration==== | ||
The OP-TEE OS firmware has to embed: | The OP-TEE OS firmware has to embed: | ||
* | * The remote processor trusted application (TA). | ||
* | * The remote processor platform pseudo trusted application (PTA). | ||
* | * The stm32mp remoteproc driver. | ||
* | * The public key to authenticate the firmware. | ||
The ''' | ===== Remoteproc framework and driver ===== | ||
The '''CFG_DRIVERS_REMOTEPROC''' and '''CFG_STM32MP_REMOTEPROC''' configurations enable the OP-TEE remoteproc driver. | |||
The '''CFG_REMOTEPROC_PTA''' configuration enables the OP-TEE remoteproc framework. | |||
* For '''{{MicroprocessorDevice | device=15 }}''': To enable the remoteproc framework, the '''CFG_STM32MP_REMOTEPROC''' configuration should be enabled | |||
{{PC$}}make ''<other directives>'' '''CFG_STM32MP_REMOTEPROC=y''' | |||
{{Info| | |||
For '''{{MicroprocessorDevice | device=15 }}''': <BR> | |||
The default configuration of OP-TEE disables secure services, leaving only system services such as PSCI and SCMI.<br> | |||
To embed an OP-TEE firmware with the remoteproc firmware authentication secure service, one must build: | |||
* '''OP-TEE''' with configuration switch '''CFG_STM32MP1_OPTEE_IN_SYSRAM{{=}}y''' so that OP-TEE executes in secure SYSRAM. | |||
* '''TF-A''' with configuration switch '''STM32MP1_OPTEE_IN_SYSRAM{{=}}1''' so that TF-A/BL2 loads OP-TEE in secure SYSRAM, unless what TF-A will fail to boot OP-TEE images. | |||
Refer to [[STM32MPU_OP-TEE_profiles#Details_on_build_directives|OP-TEE OS configuration]] and [[How_to_configure_TF-A_FW_CONFIG | TF-A configuration]]}} | |||
The ''' | *For '''{{MicroprocessorDevice | device=2 }}''': The build configurations are enabled by default. | ||
===== Signature key ===== | |||
The '''RPROC_SIGN_KEY= <key file path name>''' directive can be added to specify the public key file to use to authenticate the remote processor firmware.This directive is optional. If it is not defined, the {{ CodeSource | OP-TEE_OS | keys/default.pem}} default key is used. | |||
Example of build command specifying the public key (where ''<other directives>'' has to be replaced by usual directives to [[How to configure OP-TEE#Build_OP-TEE_OS | | Example of build command specifying the public key (where ''<other directives>'' has to be replaced by usual directives to [[How to configure OP-TEE#Build_OP-TEE_OS | | ||
build OP-TEE OS]]): | build OP-TEE OS]]): | ||
{{PC$}} make ''<other directives>'' | {{PC$}} make ''<other directives>'' RPROC_SIGN_KEY=my_public_key.pem | ||
See [[How to configure OP-TEE | here]] for how to information. | See [[How to configure OP-TEE | here]] for how to information. | ||
Line 144: | Line 160: | ||
For '''{{MicroprocessorDevice | device=15 }}''', '''{{EcosystemRelease | revision=5.0.0 | range=and after}}''': <BR> | For '''{{MicroprocessorDevice | device=15 }}''', '''{{EcosystemRelease | revision=5.0.0 | range=and after}}''': <BR> | ||
The default configuration of OP-TEE disables secure services, leaving only system services such as PSCI and SCMI.<br> | The default configuration of OP-TEE disables secure services, leaving only system services such as PSCI and SCMI.<br> | ||
To embed an OP-TEE firmware with the remoteproc firmware authentication secure service, one must build: | |||
* '''OP-TEE''' with configuration switch '''CFG_STM32MP1_OPTEE_IN_SYSRAM{{=}}y''' so that OP-TEE executes in secure SYSRAM | * '''OP-TEE''' with configuration switch '''CFG_STM32MP1_OPTEE_IN_SYSRAM{{=}}y''' so that OP-TEE executes in secure SYSRAM. | ||
* '''TF-A''' with configuration switch '''STM32MP1_OPTEE_IN_SYSRAM{{=}}1''' so that TF-A/BL2 loads OP-TEE in secure SYSRAM, unless what TF-A will fail to boot OP-TEE images. | * '''TF-A''' with configuration switch '''STM32MP1_OPTEE_IN_SYSRAM{{=}}1''' so that TF-A/BL2 loads OP-TEE in secure SYSRAM, unless what TF-A will fail to boot OP-TEE images. | ||
Refer to [[ | Refer to [[STM32MPU_OP-TEE_profiles#Details_on_build_directives|OP-TEE OS configuration]] and [[How_to_configure_TF-A_FW_CONFIG | TF-A configuration]]}} | ||
==== Linux kernel configuration ==== | ==== Linux kernel configuration ==== | ||
Activate the '''TEE_REMOTEPROC''' in the kernel configuration, using the Linux | Activate the '''TEE_REMOTEPROC''' in the kernel configuration, using the Linux menuconfig tool: [[Menuconfig or how to configure kernel]]. | ||
Device drivers ---> | Device drivers ---> | ||
Remoteproc drivers ---> | Remoteproc drivers ---> | ||
Line 164: | Line 180: | ||
=== Device tree configuration === | === Device tree configuration === | ||
==== | ==== stm32-rproc compatible property==== | ||
As described in {{CodeSource | Linux kernel | Documentation/devicetree/bindings/remoteproc/stm32-rproc.yaml}} a specific compatible is used to select the management of the remoteproc firmware enabling the signature: | |||
* Use '''"st,stm32mp1-m4"''' for the {{MicroprocessorDevice | device=15}} Cortex<sup>®</sup>-M4 coprocessor management by Linux (support of ELF format) | |||
* Use '''"st,stm32mp1-m4-tee"''' for the {{MicroprocessorDevice | device=15}} Cortex<sup>®</sup>-M4 coprocessor management by OPTEE(support of signed format) | |||
* Use '''"st,stm32mp2-m33"''' for the {{MicroprocessorDevice | device=25}} Cortex<sup>®</sup>-M33 coprocessor management by Linux (support of ELF format) | |||
* Use '''"st,stm32mp2-m33-tee"''' for the {{MicroprocessorDevice | device=25}} Cortex<sup>®</sup>-M33 coprocessor management by OPTEE (support of signed format) | |||
The stm32mp_remoteproc driver is in charge of configuring the memories based on the | {{Warning| The '''compatible''' field must be updated to be identical in both the OP-TEE device tree and the Linux device tree.}} | ||
==== OP-TEE device tree ==== | |||
The stm32mp_remoteproc driver is in charge of configuring the memories based on the ''memory region'' properties declared in the OP-TEE device tree. | |||
* '''Memory regions declarations''': | * '''Memory regions declarations''': | ||
:The memory regions are defined in the Device tree. | :The memory regions are defined in the Device tree. As example on {{MicroprocessorDevice | device=25}}, the STM32CubeMP2 firmware and TF-M firmware memory regions in the DDR are declared in the {{CodeSource | OP-TEE_OS | core/arch/arm/dts/stm32mp257f-ev1-ca35tdcid-resmem.dtsi | stm32mp257f-ev1-ca35tdcid-resmem.dtsi}} file. | ||
reserved-memory { | reserved-memory { | ||
Line 198: | Line 223: | ||
}; | }; | ||
:A [[RISAF_device_tree_configuration | RIF]] | * '''Memory regions access right''' | ||
: A '''firewall''' configuration must be associated to these memory regions to: | |||
:* Isolate the memory regions that embedded the Cortex<sup>®</sup>-M firmware code and data. | |||
:* Share the memory regions used for the interprocessor communication. | |||
: The firewall configuration is applied thanks to: | |||
:* The [[ETZPC_device_tree_configuration | ETZPC]] on {{MicroprocessorDevice | device=15}}. | |||
:* The [[RISAF_device_tree_configuration | RIF]] on {{MicroprocessorDevice | device=25}}. | |||
{{ReviewsComments|-- [[User:Alexandre Torgue|Alexandre Torgue]] ([[User talk:Alexandre Torgue|talk]]) 17:44, 22 August 2024 (CEST)<br />we must explain how configure firewall in this page}} | |||
{{ReviewsComments|-- [[User:Alexandre Torgue|Alexandre Torgue]] ([[User talk:Alexandre Torgue|talk]]) 15:59, 22 August 2024 (CEST)<br />Would be nice to inform user that he must also change the OPTEE devicetree. Note also that DT compatible of V5.1 for mp15 is not aligned with rproc driver compatible.}} | |||
* '''Memory region references''': | * '''Memory region references''': | ||
: During the firmware loading process, the OP-TEE remoteproc verifies whether the address and size of the segments to be loaded match with the memory regions declared in the OP-TEE device tree. The memory regions that | : During the firmware loading process, the OP-TEE remoteproc verifies whether the address and size of the segments to be loaded match with the memory regions declared in the OP-TEE device tree. The memory regions that contain the Cortex<sup>®</sup>-M firmware must be referenced in the device tree remoteproc node. | ||
&m33_rproc { | &m33_rproc { | ||
{{highlight|memory-region {{=}} <&cm33_cube_fw>, <&cm33_cube_data>, | {{highlight|memory-region {{=}} <&cm33_cube_fw>, <&cm33_cube_data>, | ||
<&ipc_shmem>, <&tfm_code>, <&tfm_data | <&ipc_shmem>, <&tfm_code>, <&tfm_data>;}} | ||
}; | |||
}; | |||
In following | Refer to the [[OP-TEE_remoteproc_framework_overview#Device_tree_configuration |OP-TEE remoteproc device tree configuration]] for more details. | ||
==== Linux kernel device tree ==== | |||
The firmware images are loaded by the OP-TEE remoteproc framework. The Linux device only needs to reference memory regions shared with the Cortex<sup>®</sup>-M for the interprocessor communication, including: | |||
* The [[Coprocessor_resource_table| resource table]]. | |||
* The [[Coprocessor_resource_table#How_to_add_trace_for_the_log_buffer_-28STM32MP15x_lines_only-29 | log buffer]] shared through the resource table. | |||
* The shared buffers for [[Linux_RPMsg_framework_overview | RPMsg]] communication. | |||
* Other shared buffers defined by the developer for its project. | |||
In the following example, the "ipc_shmem_1" memory region contains the resource table and the remoteproc trace buffer. The "vdev0<xxx>" memory regions reference the shared memories for the RPMsg protocol. | |||
* '''Memory regions declarations''': | * '''Memory regions declarations''': | ||
Line 244: | Line 279: | ||
}; | }; | ||
}; | }; | ||
Refer to the [[Linux_remoteproc_framework_overview#Device_tree_configuration |Linux kernel remoteproc device tree configuration]] for more details. | |||
==== U-boot device tree ==== | |||
The U-Boot device tree can be aligned with the [[#Linux_kernel_device_tree| Linux kernel device tree]], but the reserved memory declarations are optional (No interprocessor communication in U-Boot)). Only the 'compatible' field is important to specify that OP-TEE is responsible for authenticating and loading the firmware. | |||
* '''Memory region references''': | * '''Memory region references''': | ||
Line 252: | Line 292: | ||
}; | }; | ||
{{info| on ({{MicroprocessorDevice | device=25}} only), the [[RISAF_device_tree_configuration | RIF]] configuration | {{info| on ({{MicroprocessorDevice | device=25}} only), the [[RISAF_device_tree_configuration | RIF]] configuration must allow the Cortex<sup>®</sup>-A and Cortex<sup>®</sup>-M to access to theses shared memory regions. | ||
}} | }} | ||
=== STM32Cube firmware === | === STM32Cube firmware === | ||
The memory mappings for the STM32Cube firmware are defined in the STM32Cube firmware linker script, which must be aligned with the values defined in the OP-TEE and Linux device trees. | The memory mappings for the STM32Cube firmware are defined in the STM32Cube firmware linker script, which must be aligned with the values defined in the OP-TEE and Linux device trees. | ||
Most of the STM32Cube firmware code and data can be isolated but some memories have to shared with the Cortex-A, including: | Most of the STM32Cube firmware code and data can be isolated but some memories have to be shared with the Cortex<sup>®</sup>-A, including: | ||
* | * The [[Coprocessor_resource_table| resource table]]. | ||
* | * The [[Coprocessor_resource_table#How_to_add_trace_for_the_log_buffer_-28STM32MP15x_lines_only-29 | log buffer]] shared through the resource table. | ||
* | * The shared buffers for [[Linux_RPMsg_framework_overview | RPMsg]] communication. | ||
* | * Other shared buffers defined by the developer for its project. | ||
The following example shows a linker script for a stm32mp2Cube firmware, aligned with the [[#Device_tree_configuration | device tree example]] above: | The following example shows a linker script for a stm32mp2Cube firmware on {{MicroprocessorDevice | device=25}}, aligned with the [[#Device_tree_configuration | device tree example]] above: | ||
* The memory regions definition: | * The memory regions definition: | ||
MEMORY | MEMORY | ||
Line 296: | Line 336: | ||
} > IPC_SHMEM}} | } > IPC_SHMEM}} | ||
... | ... | ||
} | } | ||
* The RPMsg shared buffers: | * The RPMsg shared buffers: | ||
The '''VIRTIO_SHMEM''' memory region is already reserved for the RPMsg | The '''VIRTIO_SHMEM''' memory region is already reserved for the RPMsg virtio rings and buffers defining following symbol in the linker script: | ||
/* Symbols needed for OpenAMP to enable rpmsg */ | /* Symbols needed for OpenAMP to enable rpmsg */ | ||
__OPENAMP_region_start__ = ORIGIN(VIRTIO_SHMEM); | __OPENAMP_region_start__ = ORIGIN(VIRTIO_SHMEM); | ||
__OPENAMP_region_end__ = ORIGIN(VIRTIO_SHMEM)+LENGTH(VIRTIO_SHMEM); | __OPENAMP_region_end__ = ORIGIN(VIRTIO_SHMEM)+LENGTH(VIRTIO_SHMEM); | ||
=== Cortex-M firmware signature=== | === Cortex<sup>®</sup>-M firmware signature=== | ||
==== Generate private and public keys ==== | ==== Generate private and public keys ==== | ||
An RSA key has to be generated to sign and authenticate the Cortex-M firmware. For instance, the ssh-keygen command can be used. | An RSA key has to be generated to sign and authenticate the Cortex<sup>®</sup>-M firmware. For instance, the ssh-keygen command can be used. | ||
{{PC$}} ssh-keygen | {{PC$}} ssh-keygen | ||
Line 315: | Line 355: | ||
==== Firmware signature==== | ==== Firmware signature==== | ||
The [[How to configure OP-TEE |OP-TEE STMicroelectronics]] distribution integrates the '''sign_rproc_fw.py''' which can concatenate several firmware ELF binary files and sign them. <br> | The [[How to configure OP-TEE |OP-TEE STMicroelectronics]] distribution integrates the '''sign_rproc_fw.py''', which can concatenate several firmware ELF binary files and sign them. <br> | ||
This script: | This script: | ||
* | * Adds a header on top of the ELF binaries. | ||
* | * Adds a TLV (Type Length Value) chunk that contains information to authenticate the firmware images. | ||
* | * Computes the hash of the program segments of each ELF binary that is loaded in the Cortex<sup>®</sup>-M memories and fill the hash table included in the TLV. | ||
* | * Computes the hash of the header and the TLV and signs it using the private key. | ||
===== Prerequisites===== | ===== Prerequisites===== | ||
Install | Install Python libraries needed by OP-TEE signature Python script: | ||
pip install pyelftools pycryptodomex | pip install pyelftools pycryptodomex | ||
===== Sign the firmware ===== | ===== Sign the firmware ===== | ||
* Use the default RSA key available in the OP-TEE repository (that can be updated) : {{ CodeSource | OP-TEE_OS | keys/ | * Use the default RSA key available in the OP-TEE repository (that can be updated): {{ CodeSource | OP-TEE_OS | keys/default.pem}} | ||
{{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> | {{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> '''--key keys/default.pem''' | ||
* | * Or specify the key to use as a parameter: | ||
{{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --key <id_rsa private key> | {{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --key <id_rsa private key> | ||
* | * Specify the boot address and the TrustZone<sup>®</sup> state ({{MicroprocessorDevice | device=25}} only): | ||
: | {{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --plat-tlv BOOTADDR 0x80100000 | ||
{{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --plat-tlv | :* Secure boot address is the Cortex<sup>®</sup>-M TrustZone<sup>®</sup> is enabled: | ||
:* | {{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --plat-tlv BOOTADDR 0x80000000 --plat-tlv BOOTSEC 0x1 | ||
{{PC$}} ./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --plat-tlv | |||
* For more script options: | * For more script options: | ||
Line 352: | Line 391: | ||
{{CodeSource | U-Boot | drivers/remoteproc/rproc-optee.c}} | {{CodeSource | U-Boot | drivers/remoteproc/rproc-optee.c}} | ||
=== | === STM32Cube example=== | ||
* '''On {{MicroprocessorDevice | device=15}}''' | |||
{{CodeSource | STM32CubeMP1 | Projects/STM32MP157C-DK2/Applications/OpenAMP/OpenAMP_for_signed_fw}} | {{CodeSource | STM32CubeMP1 | Projects/STM32MP157C-DK2/Applications/OpenAMP/OpenAMP_for_signed_fw}} | ||
* '''On {{MicroprocessorDevice | device=25}}''' | |||
{{CodeSource | STM32CubeMP2 | Projects/STM32MP257F-EV1/Applications/TFM/TFM_Protected_Storage}} | |||
{{CodeSource | STM32CubeMP2 | Projects/STM32MP257F-EV1/Applications/OpenAMP/OpenAMP_TTY_echo}} | |||
<noinclude> | <noinclude> | ||
{{PublicationRequestId | 18837 | {{PublicationRequestId |31429| 2024-06-17| previous: 18837 2021-12-07 }} | ||
[[Category:How to customize software]] | [[Category:How to customize software]] | ||
[[Category:Coprocessor management Linux]] | [[Category:Coprocessor management Linux]] | ||
[[Category:OP-TEE Remoteproc]] | |||
[[Category:Coprocessor management STM32Cube]] | [[Category:Coprocessor management STM32Cube]] | ||
</noinclude> | </noinclude> | ||
Latest revision as of 17:21, 8 November 2024
1. Article purpose
This article explains how to protect the software loaded by the main processor into the coprocessor and ensure the authentication of the loaded firmware.
2. Introduction
The Linux® OS, (through the remoteproc framework) or the U-Boot enables the loading of firmware into control remote processors. Thanks to a specific OP-TEE trusted application (TA) and the resource isolation framework running on the Arm® TrustZone, it is possible to authenticate a Cortex®-M firmware image and install them on isolated RAMs to ensure its integrity during the execution.
From the user's point of view the management of a nonauthenticated or authenticated firmware does not differ, whether the firmware is managed by the Linux or by the U-Boot. The difference is that the management of the authenticated firmware is delegated to the OP-TEE firmware running in the Arm® TrustZone.
3. Principles
The protection of the coprocessor firmware relies on hash computation and on the encryption key to authenticate a firmware, as does the isolation of the execution memories to ensure execution integrity.
The firmware is signed using an OP-TEE signature script. This script concatenates one or several ELF binaries, then adds a header and TLV (type length value) metadata that provide elements for the authentication among other firmware information:
- A hash table, which contains the hash of the segment to load.
- A signature computed with the private key.
- During the execution phase:
- The signed firmware binary is read from the file system by the remoteproc framework and the image is provided to the OP-TEE trusted application.
- The firmware image is authenticated and installed by the OP-TEE trusted application in the protected Cortex®-M memories.
3.1. Firmware signature
A common strategy to sign a firmware consists in adding a header that contains the signature required for authentication. The signature is generated by computing a hash on the whole binary including the header, and encrypting this hash using a private key.
On the STM32MP microprocessors, the signature procedure is similar except that it is optimized to minimize the use of memory and speed up the authentication process. The principle is to compute the hash of the segments to load, instead of computing the hash of the full image.

- The signature consists in:
- Parsing the program table in the ELF file to identify the segments to load.
- Computing the hash of each segment and saving the result in the hash table chunk of the header.
- Computing the hash of the header and signing the hash with the private key.
- The public key is embedded in the OP-TEE OS firmware that is in charge of the Cortex®-M firmware authentication.
3.2. Memory management
3.2.1. STM32MP15x lines 
The MCU SRAM and the RETRAM memories can be dedicated to Cortex®-M usage (isolated), shared with the Cortex®-A nonsecure context, or protected for Cortex®-A secure access only.
The ETZPC mechanism is used:
- During the load and authentication phase: to lock the memories for Cortex®-A secure access only.
- During the execution phase: to isolate the memories for coprocessor usage (such as code execution and data) or share them with the Cortex®-A nonsecure context (such as RPMsg shared buffers).
- On coprocessor stop: to lock the memories for Cortex®-A secure access only to clean up the memories.
The information provided in this article respects the memory mapping described in memory mapping section:
- RETRAM, MCU SRAM1 and MCU SRAM2 are used for code execution and data. They are only accessible by the Cortex®-A secure context when no firmware is running, and assigned to Cortex®-M context during authenticated firmware execution.
- MCU SRAM3 (IPC buffers) is shared between the Cortex®-A nonsecure context and the Cortex®-M. No protection is applied to this memory bank.
- MCU SRAM4 is reserved for the Cortex®-A nonsecure context. It is thus free for other usage.
This memory mapping can be customized depending on project requirements. In this case, the code has to be updated in a synchronized manner in STM32CubeMP15 firmware, Linux kernel device tree and the OP-TEE rproc PTA code.
3.2.2. STM32MP25x lines 
The DDR, SRAM and/or RETRAM memory regions can be dedicated to Cortex®-M usage (isolated), shared with the Cortex®-A nonsecure context, or protected for Cortex®-A secure access only.
The RIF is used:
- During the load and authentication phase: To lock the memories for Cortex®-A secure access only.
- During the execution phase: To apply the access right defined in the OP-TEE device-tree to isolate the memories for the coprocessor usage.
- On coprocessor stop: to lock the memories for Cortex®-A secure access only to clean up the memories.
The information provided in this article respects the memory mapping described in memory mapping section:
- Some DDR memory regions and the MCU SRAM2 are prereserved for code execution and data. They are only accessible by the Cortex®-M secure or nonsecure contexts thanks to the RIF CID filtering.
- A dedicated DDR memory region is shared between the Cortex®-A nonsecure context and the Cortex®-M. No protection is applied to this memory bank.
This memory mapping can be customized depending on project requirements. In this case, the code has to be updated in a synchronized manner in the STM32CubeMP2, the TF-M firmware, the Linux kernel device tree and the OP-TEE device tree code.
3.3. Authentication
The authentication is executed in the secure context by an OP-TEE trusted application.
1. The firmware is copied by the Linux kernel (or U-Boot) to nonsecure DDR memory.
2. The firmware header is copied to a secure memory to ensure its integrity during the authentication steps.
3. The header hash is computed.
4. The signature is decrypted using the public key. The result is the hash of the header computed by the signing tools. Both hashes are compared to authenticate the firmware header.
5. At this step the firmware header is valid. The next step, the loading of the firmware in coprocessor memories, can start:
For each segment to load:
6. The segment is copied to the RAMs that can be accessed only by the secure context to ensure their integrity.
7. The hash of the copied segment is computed and compared to the hash stored in the firmware header.
8. At this step all segments have been copied and authenticated. The firmware is loaded and ready for execution.
3.4. Authenticated firmware live-cycle
From the user's point of view, the management of a firmware live-cycle does not change, whether the firmware is managed by OP-TEE or not. The management of firmware is described in the remoteproc article.
The main difference compared to a nonauthenticated firmware is that the remote processor framework delegates the coprocessor management to the OP-TEE.
3.4.1. Firmware loading and authentication
- As for a nonauthenticated firmware, the firmware is read from the file system by the remoteproc framework. The image is then sent to the OP-TEE trusted application.
- The OP-TEE remoteproc trusted application manages authentication and memory isolation in the secure context.
3.4.2. Firmware start and stop
- As for a nonauthenticated firmware, the firmware start and stop requests are handled by the remoteproc framework, but they are delegated to the Arm® TrustZone.
- The firmware start and stop are executed by the OP-TEE. The reset and RAM access rights are only accessible by the secure context.
- During the firmware loading step, the Cortex®-M memories access rights are updated to provide access to the Cortex®-A secure context. Once the firmware is loaded, the default memory access right defined in the OP-TEE device tree are reapplied.
- After stopping the firmware, the Cortex®-M memories are cleaned by OP-TEE.
3.4.3. RPMsg management
As the resource tables and RPMsg vrings and buffers are in a shared memory and accessible by both Cortex, it is possible to communicate with the authenticated firmware.
3.4.4. Firmware core dump
Since the memories are protected, it is not possible to dump the firmware when a crash occurs.
4. Implementation
The authentication mechanisms require STM32MPU Embedded Software distribution with OP-TEE running in the Arm® TrustZone context.
4.1. Components configuration
4.1.1. OP-TEE configuration
The OP-TEE OS firmware has to embed:
- The remote processor trusted application (TA).
- The remote processor platform pseudo trusted application (PTA).
- The stm32mp remoteproc driver.
- The public key to authenticate the firmware.
4.1.1.1. Remoteproc framework and driver
The CFG_DRIVERS_REMOTEPROC and CFG_STM32MP_REMOTEPROC configurations enable the OP-TEE remoteproc driver. The CFG_REMOTEPROC_PTA configuration enables the OP-TEE remoteproc framework.
- For STM32MP15x lines
: To enable the remoteproc framework, the CFG_STM32MP_REMOTEPROC configuration should be enabled
make <other directives> CFG_STM32MP_REMOTEPROC=y
- For STM32MP2 series: The build configurations are enabled by default.
4.1.1.2. Signature key
The RPROC_SIGN_KEY= <key file path name> directive can be added to specify the public key file to use to authenticate the remote processor firmware.This directive is optional. If it is not defined, the keys/default.pem default key is used.
Example of build command specifying the public key (where <other directives> has to be replaced by usual directives to build OP-TEE OS):
make <other directives> RPROC_SIGN_KEY=my_public_key.pem
See here for how to information.
4.1.2. Linux kernel configuration
Activate the TEE_REMOTEPROC in the kernel configuration, using the Linux menuconfig tool: Menuconfig or how to configure kernel.
Trusted firmware support by a trusted applicationDevice drivers ---> Remoteproc drivers ---> <*> Support for Remote Processor subsystem <*> STM32 remoteproc support <*>
4.1.3. U-Boot Configuration
Activate the REMOTEPROC_OPTEE in the U-Boot configuration, using the menuconfig tool.
Support for the remoteproc in OPTEE [*] Support for STM32 coprocessorRemote Processor drivers ---> [*]
4.2. Device tree configuration
4.2.1. stm32-rproc compatible property
As described in Documentation/devicetree/bindings/remoteproc/stm32-rproc.yaml a specific compatible is used to select the management of the remoteproc firmware enabling the signature:
- Use "st,stm32mp1-m4" for the STM32MP15x lines
Cortex®-M4 coprocessor management by Linux (support of ELF format)
- Use "st,stm32mp1-m4-tee" for the STM32MP15x lines
Cortex®-M4 coprocessor management by OPTEE(support of signed format)
- Use "st,stm32mp2-m33" for the STM32MP25x lines
Cortex®-M33 coprocessor management by Linux (support of ELF format)
- Use "st,stm32mp2-m33-tee" for the STM32MP25x lines
Cortex®-M33 coprocessor management by OPTEE (support of signed format)
4.2.2. OP-TEE device tree
The stm32mp_remoteproc driver is in charge of configuring the memories based on the memory region properties declared in the OP-TEE device tree.
- Memory regions declarations:
- The memory regions are defined in the Device tree. As example on STM32MP25x lines
, the STM32CubeMP2 firmware and TF-M firmware memory regions in the DDR are declared in the stm32mp257f-ev1-ca35tdcid-resmem.dtsi file.
tfm_code: tfm-code@80000000 { compatible = "shared-dma-pool"; reg = <0x0 0x80000000 0x0 0x100000>; no-map; }; cm33_cube_fw: cm33-cube-fw@80100000 { compatible = "shared-dma-pool"; reg = <0x0 0x80100000 0x0 0x800000>; no-map; }; tfm_data: tfm-data@80900000 { compatible = "shared-dma-pool"; reg = <0x0 0x80900000 0x0 0x100000>; no-map; }; cm33_cube_data: cm33-cube-data@80a00000 { compatible = "shared-dma-pool"; reg = <0x0 0x80a00000 0x0 0x800000>; no-map; }; };reserved-memory { ...
- Memory regions access right
- A firewall configuration must be associated to these memory regions to:
- Isolate the memory regions that embedded the Cortex®-M firmware code and data.
- Share the memory regions used for the interprocessor communication.
- The firewall configuration is applied thanks to:
- Memory region references:
- During the firmware loading process, the OP-TEE remoteproc verifies whether the address and size of the segments to be loaded match with the memory regions declared in the OP-TEE device tree. The memory regions that contain the Cortex®-M firmware must be referenced in the device tree remoteproc node.
memory-region = <&cm33_cube_fw>, <&cm33_cube_data>, <&ipc_shmem>, <&tfm_code>, <&tfm_data>; };&m33_rproc {
Refer to the OP-TEE remoteproc device tree configuration for more details.
4.2.3. Linux kernel device tree
The firmware images are loaded by the OP-TEE remoteproc framework. The Linux device only needs to reference memory regions shared with the Cortex®-M for the interprocessor communication, including:
- The resource table.
- The log buffer shared through the resource table.
- The shared buffers for RPMsg communication.
- Other shared buffers defined by the developer for its project.
In the following example, the "ipc_shmem_1" memory region contains the resource table and the remoteproc trace buffer. The "vdev0<xxx>" memory regions reference the shared memories for the RPMsg protocol.
- Memory regions declarations:
ipc_shmem_1: ipc-shmem-1@81200000 { compatible = "shared-dma-pool"; reg = <0x0 0x81200000 0x0 0xf8000>; no-map; }; vdev0vring0: vdev0vring0@812f8000 { compatible = "shared-dma-pool"; reg = <0x0 0x812f8000 0x0 0x1000>; no-map; }; vdev0vring1: vdev0vring1@812f9000 { compatible = "shared-dma-pool"; reg = <0x0 0x812f9000 0x0 0x1000>; no-map; }; vdev0buffer: vdev0buffer@812fa000 { compatible = "shared-dma-pool"; reg = <0x0 0x812fa000 0x0 0x6000>; no-map; }; };reserved-memory { ...
Refer to the Linux kernel remoteproc device tree configuration for more details.
4.2.4. U-boot device tree
The U-Boot device tree can be aligned with the Linux kernel device tree, but the reserved memory declarations are optional (No interprocessor communication in U-Boot)). Only the 'compatible' field is important to specify that OP-TEE is responsible for authenticating and loading the firmware.
- Memory region references:
memory-region = <&ipc_shmem_1>, <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>; };&m33_rproc {
4.3. STM32Cube firmware
The memory mappings for the STM32Cube firmware are defined in the STM32Cube firmware linker script, which must be aligned with the values defined in the OP-TEE and Linux device trees.
Most of the STM32Cube firmware code and data can be isolated but some memories have to be shared with the Cortex®-A, including:
- The resource table.
- The log buffer shared through the resource table.
- The shared buffers for RPMsg communication.
- Other shared buffers defined by the developer for its project.
The following example shows a linker script for a stm32mp2Cube firmware on STM32MP25x lines , aligned with the device tree example above:
- The memory regions definition:
MEMORY
{
NS_VECTOR_TBL (xrw) : ORIGIN = 0x80100000, LENGTH = 0x00000600
FLASH (rx) : ORIGIN = 0x80100600, LENGTH = 8M - LENGTH(NS_VECTOR_TBL)
RAM (rwx) : ORIGIN = 0x80A00000, LENGTH = 8M
VIRTIO_SHMEM (rw) : ORIGIN = 0x812F8000, LENGTH = 32K
IPC_SHMEM (rw) : ORIGIN = 0x81200000, LENGTH = 8M - LENGTH(VIRTIO_SHMEM)
}
- The resource table and remoteproc trace buffer:
SECTIONS
{
...
/* resource table */
.resource_table :
{
. = ALIGN(4);
KEEP (*(.resource_table*))
. = ALIGN(4);
} >IPC_SHMEM
/* remoteproc trace buffer */
.sys_logs :
{
. = ALIGN(4);}}
KEEP (*(.sys_logs*))}}
. = ALIGN(4);}}
} > IPC_SHMEM}}
...
}
- The RPMsg shared buffers:
The VIRTIO_SHMEM memory region is already reserved for the RPMsg virtio rings and buffers defining following symbol in the linker script:
/* Symbols needed for OpenAMP to enable rpmsg */
__OPENAMP_region_start__ = ORIGIN(VIRTIO_SHMEM);
__OPENAMP_region_end__ = ORIGIN(VIRTIO_SHMEM)+LENGTH(VIRTIO_SHMEM);
4.4. Cortex®-M firmware signature
4.4.1. Generate private and public keys
An RSA key has to be generated to sign and authenticate the Cortex®-M firmware. For instance, the ssh-keygen command can be used.
ssh-keygen
Two files are created:
- id_rsa: the private key to sign the firmware.
- id_rsa.pub: the public key to authenticate the firmware.
4.4.2. Firmware signature
The OP-TEE STMicroelectronics distribution integrates the sign_rproc_fw.py, which can concatenate several firmware ELF binary files and sign them.
This script:
- Adds a header on top of the ELF binaries.
- Adds a TLV (Type Length Value) chunk that contains information to authenticate the firmware images.
- Computes the hash of the program segments of each ELF binary that is loaded in the Cortex®-M memories and fill the hash table included in the TLV.
- Computes the hash of the header and the TLV and signs it using the private key.
4.4.2.1. Prerequisites
Install Python libraries needed by OP-TEE signature Python script: pip install pyelftools pycryptodomex
4.4.2.2. Sign the firmware
- Use the default RSA key available in the OP-TEE repository (that can be updated): keys/default.pem
./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --key keys/default.pem
- Or specify the key to use as a parameter:
./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --key <id_rsa private key>
./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --plat-tlv BOOTADDR 0x80100000
- Secure boot address is the Cortex®-M TrustZone® is enabled:
./scripts/sign_rproc_fw.py sign --in <firmware 1> --in<firmware 2> --out <signed firmware name> --plat-tlv BOOTADDR 0x80000000 --plat-tlv BOOTSEC 0x1
- For more script options:
./scripts/sign_rproc_fw.py sign --help
5. Code source
5.1. OP-TEE
ta/remoteproc/remoteproc_core.c core/pta/stm32mp/remoteproc_pta.c core/drivers/remoteproc/stm32_remoteproc.c
5.2. Linux Kernel
drivers/remoteproc/tee_remoteproc.c drivers/remoteproc/stm32_rproc.c
5.3. U-Boot
drivers/remoteproc/rproc-optee.c
5.4. STM32Cube example
Projects/STM32MP157C-DK2/Applications/OpenAMP/OpenAMP_for_signed_fw
Projects/STM32MP257F-EV1/Applications/TFM/TFM_Protected_Storage Projects/STM32MP257F-EV1/Applications/OpenAMP/OpenAMP_TTY_echo