Last edited 3 months ago

How to configure OP-TEE

Applicable for STM32MP13x lines, STM32MP15x lines

1. Purpose[edit source]

This article describes the configuration and process used for building several OP-TEE components from sources and deploying them the target.

The build example is based on the OpenSTLinux Developer Package or Distribution Package, and also presents build instructions for a bare environment.

2. Overview[edit source]

OP-TEE is a trusted execution environment for Arm®v7-A and Arm®v8-A platforms. OP-TEE is made of several components described in OP-TEE architecture overview.

OP-TEE components generate boot images and files stored in the filesystem embedded in the target.

  • OP-TEE OS generates 3 boot image files to be loaded in the platform boot media, in the predefined partitions. The generated boot images include a STM32 binary header enabling the use of the authenticated boot and flash programming facilities.
  • OP-TEE client (package optee_client) can be built to generate non-secure services for the OP-TEE OS. The files generated from optee_client build are stored in the embedded filesystem.
  • OP-TEE project releases other packages intended for test and demonstration. These can be built and embedded in the target filesystem. Building optee_examples and optee_test generates client and trusted applications together with libraries which are all stored in the target filesystem. Note the OP-TEE Linux driver is built into the Linux kernel image and is part of the OP-TEE ecosystem.

OP-TEE can be embedded as BL32 in the STM32 MPU platforms for the ST trusted configuration.

Warning white.png Warning
OP-TEE boot images must be embedded in the FIP binary that is loaded by BL2 and can be automatically authentified

3. OP-TEE core configuration[edit source]

OP-TEE services STM32MP13x lines More info.png STM32MP15x lines More info.png
STM32MP15x lines More info.png
SCMI services
PSCI services
Oscillator calibration service
Random generation service
Wakeup source management
Power Domain service
OTP access services
NVMEM provisioning services
User Trusted application support
Trustworthiness of secure services
OPP request management
Remote proc services

3.1. SCMI services[edit source]

SCMI services STM32MP13x lines More info.png STM32MP15x lines More info.png
STM32MP15x lines More info.png
Clock management
Reset management
Performance management
Regulator management

3.2. PSCI services[edit source]

PSCI services STM32MP13x lines More info.png STM32MP15x lines More info.png
STM32MP15x lines More info.png
System reset
CPU hotplug
Low power

3.3. STM32MP13x lines More info.png[edit source]

OP-TEE OS is loaded in DDR. Thanks to DDRMCE, the DDR area is encrypted.

3.4. STM32MP15x lines More info.png[edit source]

Warning white.png Warning
Enabling OP-TEE secure services in STM32MP15x lines More info.png for ecosystem release ≥ v5.0.0 More info.png

Before ecosystem release v5.0.0 More info.png , OP-TEE for STM32MP15x lines More info.png default configuration builds OP-TEE so that the firmware and the Trusted Applications execute in secure SYSRAM insternal secure memory.

With ecosystem release ≥ v5.0.0 More info.png OP-TEE OS for STM32MP15x lines More info.png default configuration makes it loaded in DDR, relaxed from hardware constraints of running in the secure SYSRAM. Running OP-TEE in secure SYSRAM does not offer strong real-time performances of the system nor permits low power standby state on STM32MP15A* and STM32MP15D* chips that do embed CRYP support required for saving and restoring SYSRAM secure content during such power states transitions. Because the DDR is not encrypted, OP-TEE cannot enforce trustworthiness of its secure services. Therefore this default configuration disables OP-TEE support for Trusted Applications and secure services. This default configuration only embeds support for power management and system services.

From ecosystem release v5.0.0 More info.png , OP-TEE for STM32MP15x lines More info.png, one can enable back OP-TEE secure services by changing the components build configuration switches so that OP-TEE executes in the secure SYSRAM, refer to Details on build directives when using the Developer Package or Bare environment, or simply set ST_OPTEE_IN_SYSRAM="1" in your conf/local.conf configuration file when using the Distribution Package.

When OP-TEE is running in SYSRAM:

OP-TEE OS requires more than 256Ko RAM to execute. STM32MP15x lines More info.png SYSRAM is only 256Ko large therefore OP-TEE core, when executing from SYSRAM must enable its pager mode (configuration switch CFG_WITH_PAGER=y) to extend secure memory using virtual memory means and paging on demand mechanisms to save secure data into DDR, protected by hash tables and software encryption keys.

When so, OP-TEE boot image is made of 2 binary images: one (the unpaged part) is loaded at the beginning of the SYSRAM by the FSBL, the second (the pageable part) is loaded in DDR by the FSBL, in a DDR area that can be accessed by the CPU secure world.

OP-TEE OS manages low power mode by saving an encrypted image of the SYSRAM content in DDR before it is suspended. OP-TEE restores this content back into the SYSRAM when it resumes from the suspended state. This sequence is achieved using CPU instructions and encryption keys saved in the secure and retained backup SRAM.

For more information on OP-TEE's pager implementation and integration, one can refer to the OP-TEE documenation related to pager [1]

Assigning SRAM1/2/3/4 to OP-TEE pager

STM32MP15x lines More info.png embeds internal RAMs (SRAMx) initially intended for the co-processor. It is possible however to assign these internal RAMs to OP-TEE pager to enlarge its page pool and enhance OP-TEE pager performances. Note that this implies a rework of the co-processor firmware's memory mapping for it to be functional. As OP-TEE pager requires a physically contiguous page pool memory area, not all combinations of SRAM1/SRAM2/SRAM3/SRAM4 can be assigned to OP-TEE pager. Possible combinations are listed in the table below.

To assign one or more SRAMx memories to OP-TEE secure firmware, one shall change update OP-TEE DeviceTree file to configure these as secure access only and change OP-TEE configuration switch CFG_TZSRAM_SIZE according to the desired size secure RAM size:

RAMs assigned to OP-TEE Configuration

OP-TEE configuration switch: CFG_TZSRAM_SIZE=0x60000
OP-TEE device tree file update:

 &etzpc {
 	st,decprot = <

OP-TEE configuration switch: CFG_TZSRAM_SIZE=0x80000
OP-TEE device tree file update:

 &etzpc {
 	st,decprot = <

OP-TEE configuration switch: CFG_TZSRAM_SIZE=0x90000
OP-TEE device tree file update:

 &etzpc {
 	st,decprot = <

OP-TEE configuration switch: CFG_TZSRAM_SIZE=0xa0000
OP-TEE device tree file update:

 &etzpc {
 	st,decprot = <

Note that configuration DECPROT_LOCK can be replaced with DECPROT_UNLOCK if the firewall configuration is not to be locked for some platform reason.

4. Build with the Distribution Package[edit source]

The Distribution Package provides means to build the following OP-TEE components from their related bitbake target:

 bitbake optee-os-stm32mp                # OP-TEE core firmware
 bitbake optee-os-sdk-stm32mp            # OP-TEE development kit for Trusted Applications
 bitbake optee-client                    # OP-TEE client
 bitbake optee-test                      # OP-TEE test suite (optional)
 bitbake optee-examples                  # TA and CA examples

Distribution Package build process includes fetching the source files, compiling them and installing them to the target images.

The Yocto recipes for the OP-TEE packages can be found in:


5. Build with the Developer Package or a Bare Environment[edit source]

Both Developer Package and bare build environments expect you to fetch/download the OP-TEE package source file trees in order to build the embedded binary images.

The instruction set below assumes all OP-TEE package source trees are available in the base directory referred as <sources>/. The source files are available from the github repositories:

 cd <sources>/
 git clone
 git clone
 git clone
 git clone
 ls -1 <sources>/

Warning white.png Warning
Pay attention to use a consistent tag version for all optee components eg 3.12.0 for DV3.1
Warning white.png Warning
The STM32 MPU platform may not be fully merged in the official OP-TEE repository [2] hence the URL provided above refers to the ST distribution [3]

5.1. Initialize the cross compile environment[edit source]

The compilation toolchain provided by the Developer Package can be used, refer to Setup Cross Compile Environment.

Alternatively other bare toolchains can be used to build the OP-TEE secure parts. In such case, the instructions below expect the toolchain to be part of the PATH and its prefix is defined by CROSS_COMPILE. One can use something like:

 export PATH=<path-to-toolchain>:$PATH
 export CROSS_COMPILE=<toolchain-prefix>-

5.2. Build OP-TEE OS[edit source]

5.2.1. Developer Package SDK[edit source]

The OP-TEE OS can be built from the Developer Package Makefile.sdk script that is present in the tarball. It automatically sets the proper configuration for the OP-TEE OS build. To build from shell command:

 make -f $PWD/../Makefile.sdk CFG_EMBED_DTB_SOURCE_FILE=<board_dts_file_name>.dts

5.2.2. Bare Environment[edit source]

Alternatively one can also build OP-TEE OS based a bare cross compilation toolchains, for example for the stm32mp157c-ev1 board:

 cd <optee-os>
 make PLATFORM=stm32mp1 \
           CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts \
           CFG_TEE_CORE_LOG_LEVEL=2 O=build all

5.2.3. Generated Files[edit source]

The 3 OP-TEE boot images are generated at following paths:


One can get the configuration directives used for the build are available in this file:


The build also generates a development kit used to build Trusted Application binaries:


5.2.4. Details on build directives[edit source]

Mandatory directives to build OP-TEE OS:

  • PLATFORM=<platform>
    • Ex: PLATFORM=stm32mp1
  • CFG_EMBED_DTB_SOURCE_FILE=<device-tree-source-file>: in-tree (core/arch/arm/dts/ ) device tree filename with its .dts extension.
    • Ex: CFG_EMBED_DTB_SOURCE_FILE=stm32mp157f-dk2.dts

OP-TEE generic optional directives commonly used, described in OP-TEE OS mk/ file:

  • CFG_CORE_HEAP_SIZE=<VALUE>: define the byte size of OP-TEE core memory allocation pool
  • CFG_NUM_THREADS=<VALUE>: define the number of TEE threads provisioned in OP-TEE
  • CFG_REE_FS={n|y}: disable/enable OP-TEE REE filsystem based secure storage area
  • CFG_RPMB_FS={n|y}: disable/enable OP-TEE eMMC/RPMB based secure storage area
  • CFG_RPMB_FS_DEV_ID=<VALUE>: define the mmcblk block device used by REE for eMMC/RPMB accesses
    (e.g. "1" on stm32mp157x-ev1 boards)
  • CFG_WITH_USER_TA={n|y}: disable/enable support for Trusted Applications in OP-TEE secure memory (default is y)

OP-TEE generic optional debugging and test directives commonly used, described in OP-TEE OS mk/ file:

  • CFG_TEE_CORE_DEBUG={n|y}: disable/enable debug support
  • CFG_TEE_CORE_LOG_LEVEL={0|1|2|3|4}: define OP-TEE core trace level (0: no trace, 4: overflow of traces) (default is 2: info)
  • CFG_TEE_CORE_TA_LEVEL={0|1|2|3|4}: define OP-TEE Trusted Applications (TAs) trace level (default is 1: error)
  • CFG_TEE_CORE_TA_TRACE={n|y}: disable/enable TAs trace message at define OP-TEE core level (default is y)
  • CFG_UNWIND={n|y}: disable/enable stack unwind debug trace messages
  • CFG_ENABLE_EMBEDDED_TESTS={n|y}; disable/enable embedded test, used by xtest tool (default is y)
  • CFG_WITH_STATS={n|y}: disable/enable OP-TEE statistics retrieve from the Stats PTA service.
  • CFG_WERROR={n|y}: disable/enable build error trigger on OP-TEE build warning occurences.
  • CFG_TA_GPROF_SUPPORT={n|y}: disable/enable profiling of Trusted Application implementation based on gprof standard tool
  • CFG_FTRACE_SUPPORT={n|y}: disable/enable function trace support in Trusted Applications based on ftrace standard tool
  • CFG_SYSCALL_FTRACE={n|y}: disable/enable support for ftrace syscall graph generation

OP-TEE optional directives commonly used on STM32MP1 series:

  • CFG_STM32_EARLY_CONSOLE_UART={0|1|2|...}: define the USART instance used for early console trace messages (default is 4)
  • CFG_STM32_BSEC_WRITE={n|y}: disable/enable the program/write fuses capabilities (default n to avoid briking the chip)

OP-TEE optional directives specific to STM32MP15x lines More info.png ecosystem release ≥ v5.0.0 More info.png :

  • CFG_STM32MP1_OPTEE_IN_SYSRAM={n|y}: See warning section below and STM32MP15x lines for details (default is n).
    Note that when CFG_STM32MP1_OPTEE_IN_SYSRAM=n, CFG_WITH_USER_TA default value is n,
    and when CFG_STM32MP1_OPTEE_IN_SYSRAM=y, CFG_WITH_USER_TA default value is y.
  • CFG_STM32MP15_HUK={n|y}: disable/enable reading of OP-TEE's HUK (Hardware Unique Key) from BSEC fuses.
  • CFG_STM32_HUK_FROM_DT={n|y}: disable/enable reading of HUK location in BSEC fuses from OP-TEE's embedded Device Tree.
  • CFG_STM32_HUK_TESTKEY={n|y}: disable/enable use of a test (default is y)
    Supersedes CFG_OTP_HW_TESTKEY used in before ecosystem release v5.0.0 More info.png .

Info white.png Information

For ecosystem release ≤ v3.0.0 compatibility:
It is still possible to generate the the STM32 binary files with an option flag:
CFG_STM32MP15x_STM32IMAGE=1: Generate the STM32 files for ecosystem release ≤ v3.0.0 compatibility.

Warning white.png Warning

"To enable OP-TEE secure service for STM32MP15x lines More info.png on ecosystem release ≥ v5.0.0 More info.png , one must configure OP-TEE to execute in secure SYSRAM. TF-A boot loader must also be configured to load OP-TEE in internal SYSRAM, not is DDR.
To make OP-TEE for STM32MP15x lines More info.png to execute in SYSRAM, one shall:

  • enable OP-TEE configuration switch CFG_STM32MP1_OPTEE_IN_SYSRAM=y
  • enable TF-A configuration switch STM32MP1_OPTEE_IN_SYSRAM=1 for both TF-A BL2 and TF-A FIP images.

Note: internal memory size constrains the debug support level that can be provided.

5.2.5. Troubleshoot[edit source]

The Developer Package toolchain may report dependency error in the traces such as:

 make PLATFORM=stm32mp1 ...
arm-ostl-linux-gnueabi-ld.bfd: unrecognized option '-Wl,-O1' 
arm-ostl-linux-gnueabi-ld.bfd: use the --help option for usage information
core/arch/arm/kernel/ recipe for target 'build/arm-plat-stm32mp1/core/tee.elf' failed
make: *** [build/arm-plat-stm32mp1/core/tee.elf] Error 1

This is linked to default CFLAGS and LDFLAGS exported by SDK. Just remove them from the environment and rebuild


Other reported issues:

 make PLATFORM=stm32mp1 ...
arm-openstlinux_weston-linux-gnueabi-ld.bfd: cannot find libgcc.a: No such file or directory

To overcome the issue, add the directive CFLAGS32=--sysroot=$SDKTARGETSYSROOT. For example:

 cd <optee-os>
 make PLATFORM=stm32mp1 \
           CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts \
           CFG_TEE_CORE_LOG_LEVEL=2 \
           CFLAGS32=--sysroot=${SDKTARGETSYSROOT} \
           O=build all

5.3. Build commands for other OP-TEE components[edit source]

This section describes how the several OP-TEE components (excluding OP-TEE OS described in above section) can be built. All those components generate files targeting the embedded Linux OS based filesystem (i.e the rootfs). These files are the secure Trusted Applications (TAs) binaries as well as non-secure Client Applications (CAs), libraries and test files.

There are several ways to build the OP-TEE components. The examples given below refer to OP-TEE client, test and examples source file tree paths as <optee-client>, <optee-test> and <optee-examples>.

Building these components expect, at least for the trusted applications, that the OP-TEE OS was built and the generated TA development kit is available at <optee-os>/build/export-ta_arm32/.

It is recommended to use CMake for building the Linux userland part whereas secure world binaries (TAs) must be build from their GNU makefiles as the OP-TEE project has not yet ported the secure world binaries build process over CMake.

5.3.1. Build the secure components[edit source]

Build the TAs: This step expects OP-TEE OS is built to generate the 32bit TA development kit. Assuming OP-TEE OS was built at path <optee-os>/build, the TA development kit is available from path <optee-os>/build/export-ta_arm32/.

Instructions below build and copy the Trusted Application binaries to a local ./target/ directory that can be used to populate the target filesystem.

 export TA_DEV_KIT_DIR=$PWD/optee_os/build/export-ta_arm32
 mkdir -p ./target/lib/optee_armtz
 for f in optee_test/ta/*/Makefile; do \
            make -C `dirname $f` O=build; \
            cp -f `dirname $f`/build/*.ta ./target/lib/optee_armtz; \

Content in local directory ./target/ are the TA binary files:

 tree target/
└── lib
  └── optee_armtz
   ├── 614789f2-39c0-4ebf-b235-92b32ac107ed.ta
   ├── 731e279e-aafb-4575-a771-38caa6f0cca6.ta
   └── (...)

These files need to be copied to the the target filesystem.

5.3.2. Build the non-secure components[edit source]

Download the OP-TEE source files in a base directory and create a CMakeLists.txt file in the base directory that lists all package to be built through CMake. For example:

 cat CMakeLists.txt
add_subdirectory (optee_client)
add_subdirectory (optee_test)
add_subdirectory (optee_examples)

From base directory, run cmake then make. The example below also creates the tree file system ./target/ that is populated with files generated that need to be installed in the target file system.
Note this examples also sets the toolchain environment:

 cmake -DOPTEE_TEST_SDK=$PWD/optee_os/build/export-ta_arm32 \
 make DESTDIR=target install 

Note the empty CMAKE_INSTALL_PREFIX value to get thing installed from root /, not from /usr/. DESTDIR=target makes the embedded files be populated in the local ./target/ directory.

Note also that stm32mp1 expects tool tee-supplicant to be located in directory /usr/bin whereas CMake installs it in directory /usr/sbin. To overcome this issue, one can build a link to the effective location, i.e:

 ln -s ../bin/tee-supplicant target/sbin/tee-supplicant

Once done, local directory ./target/ contains the files to be copied in the target filesystem.

 tree target/
├── bin
│   ├── benchmark
│   ├── optee_example_acipher
│   ├── optee_example_aes
│   ├── optee_example_hello_world
│   ├── optee_example_hotp
│   ├── optee_example_random
│   ├── optee_example_secure_storage
│   ├── tee-supplicant
│   └── xtest
├── include
│   ├── tee_bench.h
│   ├── tee_client_api_extensions.h
│   ├── tee_client_api.h
│   └── teec_trace.h
├── lib
│   ├── ->
│   ├── ->
│   └──
│   └── optee_armtz
│       └── (...)                 # This directory was previously filled with TAs
└── sbin
    └── tee-supplicant -> ../bin/tee-supplicant

6. Update OP-TEE boot images[edit source]

OP-TEE boot images are part of the FIP binary.
The next step to deploy the OP-TEE OS is to update the FIP binary following the FIP update process.

7. Update OP-TEE Linux files[edit source]

7.1. Update on board[edit source]

The other OP-TEE images are stored in the target filesystem.

For example, if using an SD card as target boot media, the card can be plugged in its PC card reader and the images copied. The files can be simply copied into the mounted rootfs.

7.2. Update in a SD card[edit source]

The OP-TEE files that need to be copied to the target filesystem were installed in a local directory ./target/.

They can now be copied to the target SD card rootfs partition once the SD card is plugged to the host computer and its filesystems are mounted in the host, i.e

 cp -ar target/* /media/$USERNAME/rootfs/

8. Update your boot device (including SD card on the target)[edit source]

Refer to the STM32CubeProgrammer documentation to update your target.

9. References[edit source]