可信任固件(TF-M)

支持的芯片

Ameba SoC

RTL8721Dx

RTL8726E

RTL8720E

RTL8730E

支持状态

Y

N

N

N

概述

在TF-M中,安全服务按类别分组为独立的安全分区。安全分区是 TF-M 内的运行单元,拥有独立资源与执行线程。安全分区同时作为调度与隔离的基础单元。

../../_images/tf_m_secure_partition.png

安全分区

SDK默认提供以下安全分区:

  • 提供受保护存储服务的分区(受保护存储与内部可信任存储)

  • 提供加密服务的分区

  • 提供初始认证服务的分区

安全服务是可升级代码,实现了一组在运行时可供非安全应用使用的功能,并管理与非安全应用隔离的关键资产。非安全应用无法直接访问任何关键资产,但可以通过调用使用这些资产的安全服务来间接访问。

安全分区通过内存保护单元实现了 PSA PRoT 与 ARoT 的隔离,其中 PRoT 运行于特权模式,ARoT 运行于非特权模式。这至少对应于 PSA 隔离等级 2。

../../_images/tf_m_prot_arot.png

PRoT 和 ARoT

SDK 采用TF-M Medium 配置方案实现 PSA 隔离等级 2,该方案定义了以下功能集:

  • 固件框架

    • 进程间通信(IPC)模型

    • 隔离等级 2

  • 内部可信任存储(ITS)

  • 加密

    • 支持对称加密和非对称加密

    • 在 IoT 和 CoAP 协议的 TLS/DTLS 配置文件中建议的非对称密钥套件,包括:

      • 带关联数据的认证加密(AEAD)算法

      • 基于非对称密钥的签名与验证

      • 基于公钥加密的密钥交换

      • 哈希函数

      • 用于默认伪随机函数(PRF)的 HMAC

    • 初始认证令牌(IAT)的非对称数字签名与验证

  • 初始认证

    • 基于非对称密钥算法的初始认证

  • 如果集成了片外存储设备,则提供受保护存储(PS)

    • 数据机密性

    • 数据完整性

    • 防回滚保护

加密服务

As suggested in CoAP, TF-M Profile Medium selects TLS_ECDHE_ECDSA_WITH_AES_128_CCM as reference by default, which requires:

  • ECDHE_ECDSA as key exchange algorithm.

  • AES-128-CCM (AES CCM mode with 128-bit key) as AEAD algorithm. Platforms can implement AES-128-CCM with truncated authentication tag to achieve less network bandwidth.

  • SHA256 as Hash function.

  • HMAC as Message Authentication Code algorithm.

Users can modify the default algorithm in ${CMAKE_SOURCE_DIR}\lib\ext\mbedcrypto\mbedcrypto_config\tfm_mbedcrypto_config_profile_medium.h file, where ${CMAKE_SOURCE_DIR} is {SDK}\component\soc\common\trusted-firmware-m\.

Refer to Chapter 10 Cryptographic operation reference in IHI0086-PSA_Certified_Crypto_API-1.1.2.pdf for more usage.

初始认证

ECC curve secp256r1 should be supported.

Refer to Chapter 4 API reference in IHI0085-PSA_Certified_Attestation_API-1.0.3.pdf for more usage.

TF-M API

当前,SDK 中提供了以下安全服务:

分区

特权 [1]

模型 [1]

加密分区

PRoT

SFN

初始认证

PRoT

SFN

内部可信任存储

PRoT

SFN

受保护存储

ARoT

SFN

平台

PRoT

SFN

NS 代理 [2]

PRoT

IPC

备注

[1] 特权与模型的区别如下:

  • 特权:

    • 在安全世界中,如果 ARoT 分区需要访问系统资源,必须通过调用 PRoT 提供的 API 来实现。

    • 在非安全世界中,只能通过调用 PSA API 来使用安全服务。

  • 模型:

    • 每个分区必须运行在以下两种运行时模型下:​​ 进程间通信(IPC) 模型​​ 或 安全功能(SFN) 模型​​。

    • 对于 IPC 模型分区服务​:分区内部有一个线程持续等待信号。安全分区管理器(SPM)将客户端 API 调用的服务请求转换为消息,向分区发送信号,定位对应分区,并将服务结果返回客户端。​实现流程为:用户依次调用 psa_connect() 建立连接、调用 psa_call() 执行服务、调用 psa_close() 断开连接。由于服务请求可转换为消息且数据在本地缓冲区处理,​​支持并发访问​​。

    • 对于 SFN 模型分区服务​:用户仅需调用 psa_call() 即可执行特定服务,​​类似于库函数调用​​。

[2] NS 代理是一个​​不提供任何服务​​的特殊分区。在 TF-M 初始化完成后,系统将通过 NS 代理分区​​跳转至非安全世界​​。

After the TF-M build is successful, the SDK will automatically copy the API source code provided by each partition under {SDK}\amebadplus_gcc_project\project_km4\asdk\build_tfm\install\interface\src\ to {SDK}\amebadplus_gcc_project\project_km4\ src_tfm\interface\src, so that the Non-Secure World can call these APIs directly because the API source code will also be compiled automatically.

The tfm_psa_ns_api.c file under {SDK}\amebadplus_gcc_project\project_km4\src_tfm\interface\src\ calls the Non-Secure Callable (NSC) APIs provided by TF-M for data interaction. The following sections illustrate the details of these NSC APIs.

tfm_psa_framework_version_veneer

项目

描述

功能

用于获取当前系统实现的 PSA 框架 API 版本信息

参数

返回值

PSA 框架的版本

tfm_psa_version_veneer

项目

描述

功能

用于获取 RoT 服务的版本信息,或返回该服务未部署于当前系统的标识

参数

sid:安全服务 ID

返回值

返回值大于 0 表示 RoT 服务的版本

tfm_psa_connect_veneer

项目

描述

功能

通过 SID 和请求版本号连接至 RoT 服务

参数

  • sid:安全服务 ID

  • version:RoT 服务的版本

返回值

连接句柄

tfm_psa_call_veneer

项目

描述

功能

通过已建立的连接句柄调用安全服务功能

参数

  • handle:连接句柄

  • ctrl_param:uint32_t,包含请求类型

  • in_vec:input/ref psa_invec 结构体数组指针

  • out_vec:output/ref psa_outvec 结构体数组指针

返回值

psa_status_t 结构体

  • 0:成功

  • 其他:失败

tfm_psa_close_veneer

项目

描述

功能

通过连接句柄关闭已建立的安全服务功能连接

参数

handle:连接句柄

返回值

受保护存储服务

  • Protected Storage (PS): The TF-M PS service implements PSA PS APIs that allow data to be encrypted and the results to be written to potentially untrusted storage. As a reference, the PS service uses the AES-CCM algorithm based on the AEAD encryption to protect the integrity and validity of the data.

  • Internal Trusted Storage (ITS): The TF-M ITS service implements the PSA ITS APIs to allow writing data to the built-in Flash memory area. The implemention in the current SDK is to use AES-GCM algorithm provided by IPSEC_S, with File ID as the IV and a derived key as the AAD to protect the integrity and confidentiality of the data.

Refer to Chapter 5 API Reference in IHI0087-PSA_Certified_Secure_Storage_API-1.0.2.pdf for more usage.

TF-M OTP

Realtek 提供基于 PSA 隔离等级 1 的读保护(RDP)机制。在集成TF-M后,原来的 RDP 实现称为 RDP_BASIC,基于 TF-M 的 RDP 实现称为 RDP_TFM。两者共用相同的 OTP 配置位。启用 RDP 功能后,用户需选择启用 RDP_BASIC 还是 RDP_TFM

----TrustZone by RDP or TFM----

      ( ) RDP_BASIC
      (X) RDP_TFM

名称

地址

大小

描述

RDP_EN_PHY

物理映射 0x368[5]

1 比特

当这两个比特位中任意一个被烧录时,RDP功能即被激活。

设备开发或调试阶段建议烧写 RDP_EN_LOG 位(后续可禁用)。

量产阶段则建议烧写 RDP_EN_PHY 位永久启用 RDP。

RDP_EN_LOG

逻辑映射 0x3[4]

(测试用)

1 比特

S_IPSEC_Key1 (RDP)

物理映射 0x200 ~ 0x21F

32 字节

用于存储 RDP 密钥。例如:RDP 密钥为 11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff

需将 0x11 写入地址 0x2000x22 写入地址 0x201,依此类推。

S_IPSEC_Key1_R_Protection_EN

物理映射 0x365[3]

1 比特

烧录后,S_IPSEC_Key1 不能被读取(除 IPSEC-S 模块外)

S_IPSEC_Key1_W_Forbidden_EN

物理映射 0x365[4]

1 比特

烧录后,S_IPSEC_Key1 无法做任何修改

  • 当启用 RDP_BASIC 时,引导加载程序在完成固件加载后将直接跳转至非安全世界。

  • 当启用 RDP_TFM 时,引导加载程序将首先跳转至TF-M,待完成TF-M中的安全服务初始化后,再跳转至非安全世界。

../../_images/boot_flow_with_tf_m.svg

基于 TF-M 的安全启动流程

使用方法

如何编译 TF-M

小心

  • In order to simplify the operation steps, when in the device-development stage, both step 3 and RDP key programming in step 1 can be skipped, ch means that the RDP image would be stored in plaintext and the bootloader would not decrypt it. This method should be used only in device-development stage!

  • Carefully use the efuse wraw command, and it cannot be changed once written. Do not power off or reset during writing!

The following steps illustrate how to enable RDP.

  1. Program RDP-related OTP bits after the system boots up.

    1. RDP enable bit

      • When in the device-development stage, it is recommended to program RDP_EN_LOG bit, which can be disabled afterward. Use efuse rmap first to check value in 0x3, then enable RDP_EN_LOG bit (0x3[4]).

        efuse rmap
        EFUSE[000]: ff ff 00 00 ff ff ff ff ff ff ff ff ff ff ff ff
        EFUSE[010]: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
        EFUSE[020]: fe fe fe fe fd fe fc fc fc fb fc ff ff ff ff ff
        EFUSE[030]: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
        
        efuse wmap 0x3 1 10
        
      • When in the device-MP stage, the RDP_EN_PHY bit should be programmed to enable RDP permanently.

        efuse rraw
        RawMap[350]: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
        RawMap[360]: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
        RawMap[370]: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
        RawMap[380]: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
        
        efuse wraw 0x368 1 DF
        
    2. RDP key

      When in the device-MP stage, RDP key must be programmed. Using the following command to program RDP key:

      efuse wraw 0x200 0x20 11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff
      

      RDP key length must be 32 bytes. Key value is defined by users, here we take this for example.

    3. Other security-related bits

      For MP devices, some security-related bits should also be programmed for security reasons, such as key read/write protection bits, S_IPSEC_Key1_R_Protection_EN/S_IPSEC_Key1_W_Forbidden_EN bits, etc.

  2. Enable TF-M in SDK

    1. Switch to the directory: {SDK}\amebadplus_gcc_project

    2. Type command make menuconfig and select CONFIG TrustZone > Enable TrustZone > TrustZone by RDP or TFM in order

    备注

    To perform the regression test or API test on TF-M, enable the TFM Test Suite and select the appropriate test items as needed.

    • Regression test: including TF-M secure regression tests (cmake -DTEST_S=ON) and TFM non-secure regression tests (cmake -DTEST_NS=ON)

    • API test: including tests for STORAGE, CRYPTO, and INITIAL_ATTESTATION

  1. Modify KM4 secure image manifest configuration

    The KM4 secure image manifest configuration file is {SDK}\amebadplus_gcc_project\manifest.json.

    1. Set RDP_EN to 1.

    2. Fill in RDP_IV, which must be 8 bytes, and another 8 bytes is RSIP_IV in app section.

    3. Fill in RDP_KEY, which must be 32 bytes and equal to the key programmed into OTP in Step 1.

    "//": "cert/app share IMG_ID/IMG_VER, rdp img is in app",
    "app":
    {
       "IMG_ID": "1",
       "IMG_VER_MAJOR": 1,
       "IMG_VER_MINOR": 1,
       "SEC_EPOCH": 1,
    
       "HASH_ALG": "sha256",
    
       "RSIP_IV": "213253647586a7b8",
    },
    
    "SECURE_BOOT_EN": 0,
    "//": "HASH_ALG: sha256/sha384/sha512/hmac256/hmac384/hmac512, hamc need key",
    "HMAC_KEY": "9874918301909234686574856692873911223344556677889900aabbccddeeff",
    
    "RSIP_EN": 0,
    "//": "RSIP_MODE: 1 is XTS(CTR+ECB), 0 is CTR",
    "RSIP_MODE": 1,
    "CTR_KEY": "6AA34203018334474B25A0600996CA0968AA6228B886FF234B4EB9628B703C0A",
    "ECB_KEY": "E2A0D6500BBF1DD8DC212098C230EB731ECE3A81AA11D0E6E538FA36BBA4FF6E",
    
    "//": "Actual RDP IV is 16Byte which is composed by app RSIP_IV[7:0] + RDP_IV[15:8]",
    "RDP_EN": 0,
    "RDP_IV": "0123456789abcdef",
    "RDP_KEY": "11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff"
    
  2. 通过 make 命令重新编译工程,会自动生成如下表所示的加密固件,将这些固件下载至 Flash 中。

    项目

    加密固件

    下载地址

    km4_bootloader

    km4_boot_all.bin

    0x0800_0000

    cert.bin

    km0_km4_app.bin

    0x0801_4000

    km0_application

    km4_application(非安全)

    kM4 安全固件

    备注

    The IMG3 will be overflow when building TF-M with the default layout in the current SDK, refer to Section Advanced Usages to modify the layout.

  3. 重启设备。

    RDP 固件加载成功时,会显示以下日志:

    ROM:[V1.0]
    FLASH RATE:1, Pinmux:1
    IMG1(OTA1) VALID, ret: 0
    IMG1 ENTRY[3000ad39:0]
    [KM4] [MODULE_BOOT-LEVEL_INFO]:IMG1 ENTER MSP:[30009fe4]
    [KM4] [MODULE_BOOT-LEVEL_INFO]:IMG1 SECURE STATE: 1
    [KM4] [MODULE_BOOT-LEVEL_INFO]:Flash ID: c8-65-17
    [KM4] [MODULE_BOOT-LEVEL_INFO]:Flash Read 4IO
    [KM4] FLASH HandShake[0x1 OK]
    [KM4] [MODULE_BOOT-LEVEL_INFO]:KM0 XIP IMG[0c000000:5020]
    ...
    [KM4] [MODULE_BOOT-LEVEL_INFO]:IMG2 BOOT from OTA 1
    [KM4] [MODULE_BOOT-LEVEL_INFO]:RDP EN
    [KM4] [MODULE_BOOT-LEVEL_INFO]:DEC KM4 IMG3[30075000:5a0]
    [KM4] [MODULE_BOOT-LEVEL_INFO]:DEC KM4 NSC[20070000:1320]
    [KM4] [MODULE_BOOT-LEVEL_INFO]:IMG3 BOOT from OTA 0
    [KM4] [MODULE_BOOT-LEVEL_INFO]:Start NonSecure @ 0xe000115 ...
    [KM4] [MODULE_BOOT-LEVEL_INFO]:Start TFM @ 0x30071031 ...
    [KM0] [MODULE_BOOT-LEVEL_INFO]:KM0 BOOT UP
    [KM4] [MODULE_BOOT-LEVEL_INFO]:VTOR: 20005000, VTOR_NS:0
    [KM0] [MODULE_BOOT-LEVEL_INFO]:KM0 APP_START
    [KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 APP START
    ...
    [KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 MAIN
    [KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 START SCHEDULER
    

    备注

    RDP 不会对固件进行验证。为防止固件被篡改,应当启用安全启动功能进行验证。详情请参考 安全启动

如何调整 TrustZone 服务区域大小

  1. Config TF-M code location:

    1. Switch to the directory: {SDK}\amebadplus_gcc_project

    2. Type command make menuconfig and select CONFIG TrustZone > CONFIG Link Option > IMG3(SecureImage) running on PSRAM or SRAM? in order

    ../../_images/tf_m_code_config.png
  2. Adjust the size of TrustZone Secure Area by modify the flollowing macros (the total size of TZ_NSC_SIZE/TZ_ENTRY_SIZE/TZ_S_SIZE should be a multiple of 4KB).

../../_images/tf_m_amebadplus_layout_ld.png

amebaDplus_layout.ld file

如何创建新的分区

  1. Add a new partition folder under {SDK}\component\soc\common\trusted-firmware-m\secure_fw\partitions\.

    For example, add a partition_example folder if you want to create a new example parition, refer to Rules for Creating New Files in partition_example Folder.

  2. Add the following codes to {SDK}\component\soc\common\trusted-firmware-m\config\profile\profile_medium.cmake to determine whether to enable the example_partition or not when compiling TF-M (default enable).

    ############################ PARTITION CONFIGURATION  ##########################
    
    set(TFM_PARTITION_CRYPTO                   ON    CACHE BOOL "Enable Crypto partition")
    set(TFM_PARTITION_INTERNAL_TRUSTED_STORAGE ON    CACHE BOOL "Enable Internal Trusted Storage partition")
    set(TFM_PARTITION_PLATFORM                 ON    CACHE BOOL "Enable the TF-M Platform partition")
    set(TFM_PARTITION_EXAMPLE                  OFF    CACHE BOOL "Enable the TF-M Example partition")
    set(TFM_PARTITION_PROTECTED_STORAGE        ON    CACHE BOOL "Enable Protected Storage partition")
    set(TFM_PARTITION_INITIAL_ATTESTATION      ON    CACHE BOOL "Enable Initial Attestation partition")
    set(SYMMETRIC_INITIAL_ATTESTATION          OFF   CACHE BOOL "Use symmetric crypto for inital attestation")
    set(TFM_PARTITION_FIRMWARE_UPDATE          OFF   CACHE BOOL "Enable firmware update partition")
    
  3. Add the following codes to {SDK}\component\soc\common\trusted-firmware-m\secure_fw\partitions\CMakeLists.txt to compile the source files under partition_example folder.

    add_subdirectory(lib/runtime)
    add_subdirectory(crypto)
    add_subdirectory(initial_attestation)
    add_subdirectory(protected_storage)
    add_subdirectory(internal_trusted_storage)
    add_subdirectory(platform)
    add_subdirectory(partition_example)
    add_subdirectory(firmware_update)
    add_subdirectory(ns_agent_tz)
    add_subdirectory(ns_agent_mailbox)
    if (CONFIG_TFM_SPM_BACKEND_IPC)
    
  4. Add the following codes to {SDK}\component\soc\common\trusted-firmware-m\secure_fw\CMakeLists.txt to add the compile path.

    target_include_directories(tfm_config
       INTERFACE
          ${CMAKE_CURRENT_SOURCE_DIR}/include
          ${CMAKE_CURRENT_SOURCE_DIR}/partitions/crypto
          ${CMAKE_CURRENT_SOURCE_DIR}/partitions/firmware_update
          ${CMAKE_CURRENT_SOURCE_DIR}/partitions/initial_attestation
          ${CMAKE_CURRENT_SOURCE_DIR}/partitions/internal_trusted_storage
          ${CMAKE_CURRENT_SOURCE_DIR}/partitions/platform
          ${CMAKE_CURRENT_SOURCE_DIR}/partitions/partition_example
          ${CMAKE_CURRENT_SOURCE_DIR}/partitions/protected_storage
          ${CMAKE_CURRENT_SOURCE_DIR}/spm/include
          ${CMAKE_BINARY_DIR}/generated/interface/include
    )
    
  5. Add the following codes to {SDK}/component/soc/common/trusted-firmware-m/tools/tfm_manifest_list.yaml

    • Specify partition ID (pid), where pid needs to be unique

    • tfm_partition_example.yaml: used to automaticlly generate the load_info_tfm_partition_example.c file, which is located at {SDK}\amebadplus_gcc_project\project_km4\asdk\build_tfm\generated\secure_fw\partitions\partition_example\auto_generated .

    {
       "description": "TFM partition example Partition",
       "manifest": "../secure_fw/partitions/partition_example/tfm_partition_example.yaml",
       "output path": "secure_fw/partitions/ partition_example",
       "conditional": "TFM_PARTITION_EXAMPLE",
       "version_major": 0,
       "version_minor": 1,
       "pid": 300,
       "linker_pattern": {
       "library_list": [
          "*tfm_*partition_example.*"
          ]
       }
    }
    

在 partition_example 文件夹下创建新文件的规则

The partition_example folder under the path {SDK}\component\soc\common\trusted-firmware-m\secure_fw\partitions\partition_ example contains at least the following files:

  • CMakeLists.txt

  • tfm_partition_example.yaml

  • partition_example.c

  • partition_example.h

CMakeLists.txt

The CMakeLists.txt file specify how to compile, where,

target_sources:

the compiled source files

target_include_directories:

the path to the compiled source files

if (NOT TFM_PARTITION_EXAMPLE)
   return()
endif()

cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0079 NEW)

add_library(tfm_psa_rot_partition_example STATIC)

target_sources(tfm_psa_rot_partition_example PRIVATE
   partition_example.c
)

# The generated sources
target_sources(tfm_psa_rot_partition_example
   PRIVATE
      ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/partition_example/auto_generated/intermedia_tfm_partition_example.c
)
target_sources(tfm_partitions
   INTERFACE
      ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/partition_example/auto_generated/load_info_tfm_partition_example.c
)

# Set include directory
target_include_directories(tfm_psa_rot_partition_example
   PRIVATE
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
      ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/partition_example
)
target_include_directories(tfm_partitions
   INTERFACE
      ${CMAKE_BINARY_DIR}/generated/secure_fw/partitions/partition_example
)

target_link_libraries(tfm_psa_rot_partition_example
   PRIVATE
      platform_s
      tfm_config
      tfm_sprt
)

tfm_partition_example.yaml

The tfm_partition_example.yaml file specify how to generate the file load_info_tfm_partition_example.c

sid:

needs to be unique

stateless_handle:

must be less than 32 and needs to be unique

TFM_PARTITION_EXAMPLE_SERVICE determines the name of .sfn, that is the default value of .sfn in the automaticlly generated file load_info_tfm_partition_example.c

{
   "psa_framework_version": 1.1,
   "name": "TFM_SP_PARTITION_EXAMPLE",
   "type": "PSA-ROT",
   "priority": "NORMAL",
   "model": "SFN",
   "entry_init": "tfm_example_init",
   "stack_size": "PLATFORM_SP_STACK_SIZE",
   "services": [
      {
         "name": "TFM_PARTITION_EXAMPLE_SERVICE",
         "sid": "0x00000090",
         "non_secure_clients": true,
         "connection_based": false,
         "stateless_handle": 16,
         "minor_version": 1,
         "minor_policy": "STRICT"
      },
   ],
}
.services = {
   {
      .name_strid = STRING_PTR_TO_STRID("TFM_PARTITION_EXAMPLE_SERVICE"),
      .sfn        = ENTRY_TO_POSITION(tfm_partition_example_service_sfn),
      .signal     = 1,

      .sid        = 0x00000090,
      .flags      = 0
                  | SERVICE_FLAG_NS_ACCESSIBLE
                  | SERVICE_FLAG_STATELESS | 0xf
                  | SERVICE_VERSION_POLICY_STRICT,
      .version    = 1,
   }
},

partition_example.c

The partition_example.c file needs to implement the entry function and provide functions for stateless SFN services.

  • tfm_example_init: corresponds to entry_init in tfm_partition_example.yaml

  • tfm_partition_example_service_sfn: corresponds to name of services in tfm_partition_example.yaml

psa_status_t tfm_partition_example_service_sfn(const psa_msg_t *msg)
{
   switch (msg->type) {
   case TFM_EXAMPLE_API_ID_IOCTL:
      return example_ioctl_psa_api(msg);
   default:
      return PSA_ERROR_NOT_SUPPORTED;
   }

   return PSA_ERROR_GENERIC_ERROR;
}

psa_status_t tfm_example_init(void)
{
   /* Initialize the non-volatile counters */

   return PSA_SUCCESS;
}

提供 TF-M API 给其他分区

Add the following files under the folder {SDK}\component\soc\common\trusted-firmware-m\interface\:

  • {SDK}\component\soc\common\trusted-firmware-m\interface\src\tfm_example_api.c

  • {SDK}\component\soc\common\trusted-firmware-m\interface\include\tfm_example_api.h

The handle parameter used by function psa_call in tfm_example_api.c is automatically generated by TF-M. That is, in the file \interface\include\psa_manifest\sid.h, the type parameter corresponds to the type of msg->type in the file partition_example.c.

  • TF-M APIs used by Non-Secure World: Add the following codes to {SDK}\component\soc\common\trusted-firmware-m\cmake\ install.cmake, and compile the project to provide the APIs used by Non-Secure World.

####################### export headers #########################################

if(TFM_PARTITION_EXAMPLE)
      install(FILES       ${INTERFACE_INC_DIR}/tfm_example_api.h
               DESTINATION ${INSTALL_INTERFACE_INC_DIR})
endif()

if(TFM_PARTITION_PLATFORM)
   install(FILES       ${INTERFACE_INC_DIR}/tfm_platform_api.h
            DESTINATION ${INSTALL_INTERFACE_INC_DIR})
endif()

####################### export sources #########################################

if(TFM_PARTITION_EXAMPLE)
   install(FILES       ${INTERFACE_SRC_DIR}/tfm_example_api.c
            DESTINATION ${INSTALL_INTERFACE_SRC_DIR})
endif()

if(TFM_PARTITION_PLATFORM)
   install(FILES       ${INTERFACE_SRC_DIR}/tfm_platform_api.c
            DESTINATION ${INSTALL_INTERFACE_SRC_DIR})
endif()
  • TF-M APIs used by Secure World: Add the following codes to {SDK}\component\soc\common\trusted-firmware-m\interface\ CMakeLists.txt, after that you can use the example APIs in Secure World.

###################### PSA api (S lib) #########################################

target_sources(tfm_sprt
   PRIVATE
      $<$<BOOL:${TFM_PARTITION_INITIAL_ATTESTATION}>:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_attest_api.c>
      $<$<BOOL:${TFM_PARTITION_CRYPTO}>:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_crypto_api.c>
      $<$<BOOL:${TFM_PARTITION_FIRMWARE_UPDATE}>:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_fwu_api.c>
      $<$<BOOL:${TFM_PARTITION_INTERNAL_TRUSTED_STORAGE}>:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_its_api.c>
      $<$<BOOL:${TFM_PARTITION_EXAMPLE}>:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_example_api.c>
      $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_platform_api.c>
      $<$<BOOL:${TFM_PARTITION_PROTECTED_STORAGE}>:${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_ps_api.c>
      ${CMAKE_CURRENT_SOURCE_DIR}/src/tfm_psa_call_pack.c
)

TF-M Flash 布局

项目

物理地址

大小

描述

必须?

PS_AREA

0x081F_4000

20KB

为受保护的存储分区服务存储数据

ITS_AREA

0x081F_9000

16KB

为内部可信任的存储分区服务存储数据

OTP_NV_COUNTERS

0x081F_D000

8KB

为平台的分区服务存储数据,其中 4KB 作为主数据,另外 4KB 作为备份数据

备注

此分区存储 32 字节的集成认证密钥(Integration Attestation Key,IAK)。因此,SDK 使用 GCM 算法确保数据的完整性和机密性,

通过派生密钥作为初始化向量(IV),并将防回滚版本号作为附加认证数据(AAD),以防止此分区中的新数据被旧数据覆盖。

(当版本升级时,需先更新此分区中的数据,再更新防回滚版本号之前)

PSA API Test

0x081F_F000

4KB

存储 PSA API 测试过程中的中间结果

X

  • 如果用户需要修改对应 Flash 区域的大小,修改 {SDK}\component\soc\common\trusted-firmware-m\platform\ext\target\realtek\amebadplus\partition\flash_layout.h 文件即可。

#define FLASH_PS_AREA_OFFSET           (0x001F4000)
#define FLASH_PS_AREA_SIZE             (0x5000)   /* 20KB */
#define FLASH_ITS_AREA_OFFSET          (FLASH_PS_AREA_OFFSET + \FLASH_PS_AREA_SIZE)
#define FLASH_ITS_AREA_SIZE             (0x4000)   /* 16KB */
#define FLASH_OTP_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + \FLASH_ITS_AREA_SIZE)
// 0x1FD000
#define FLASH_OTP_NV_COUNTERS_AREA_SIZE   (FLASH_AREA_IMAGE_SECTOR_SIZE * 2) /* 8KB */
#define FLASH_OTP_NV_COUNTERS_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
  • 如果用户需要修改 PSA API 测试的位置,修改文件 {SDK}\component\soc\common\trusted-firmware-m\lib\ext\psa_arch_tests-src\api-tests\platform\targets\tgt_dev_apis_tfm_amebadplus\target.cfg 即可。

// Range of 1KB Non-volatile memory to preserve data over reset. Ex, NVRAM and FLASH
nvmem.num =1;
nvmem.0.start = 0x001FF000;
/*Shall reserve 4KB for sector erase, offset based on flash die */
nvmem.0.end = 0x001FF3FF;
nvmem.0.permission = TYPE_READ_WRITE;