浅析optee中CA调用TA的过程4: Secure storage

OP-TEE 的持久化机制允许 TA 将敏感数据安全地存储在非易失性存储器中,从而在设备重启后仍能恢复使用。这种机制常用于保护密钥材料或认证凭据,在包括移动支付、设备认证等场景中有广泛应用。部分 Android 设备可能利用类似机制来增强用户认证的安全性,但具体实现方式因设备而异。

实现方式

  • 一种方案依赖普通世界(REE)的文件系统。这也是默认启用的实现方式。通过在编译时设置CFG_REE_FS=y参数即可启用此方案,对应的存储标识符为**TEE_STORAGE_PRIVATE_REE。**
  • 第二种方案利用eMMC设备的重放保护内存块(RPMB)分区,需通过设置CFG_RPMB_FS=y参数来启用,对应的存储标识符为**TEE_STORAGE_PRIVATE_RPMB。**

eMMC 全称 embedded MultiMediaCard ,是一种嵌入式多媒体存储卡 ,它将闪存芯片(NAND Flash)和主控芯片(Flash Controller)集成在一个封装中。

  • 它是专门为移动设备和嵌入式系统设计的一种标准化的存储解决方案。
  • 常用于手机、平板电脑、智能电视、车载系统、工控设备等产品中。

若配置为CFG_RPMB_FS=y,则防回滚保护由TEE控制,保护等级设为1000。若配置为CFG_RPMB_FS=n,则不具备防回滚保护功能,保护等级设为0。

防回滚保护 是一种机制,用于防止攻击者将设备恢复到一个已知存在漏洞或不安全状态的旧版本固件/系统
启用了 RPMB 文件系统(RPMB File System),使用 eMMC 的 RPMB 分区来存储持久化数据(如密钥、认证信息等),每次写入 RPMB 数据时都会附带一个递增的 Write Counter(写计数器),如果尝试重放旧数据(即使用更小的写计数器),操作会被拒绝。

在这里插入图片描述

根据编译时的配置,可以选择使用其中一个或多个标识符。若使用通用标识符 TEE_STORAGE_PRIVATE,系统会优先选择REE文件系统,否则自动选择RPMB文件系统。

我使用qemu平台来开发optee,肯定是没有eMMC设备的,查了一下conf,果然:

optee_os/mk/config.mk

# Rich Execution Environment (REE) file system support: normal world OS
# provides the actual storage.
# This is the default FS when enabled (i.e., the one used when
# TEE_STORAGE_PRIVATE is passed to the trusted storage API)
CFG_REE_FS ?= y

# CFG_REE_FS_HTREE_HASH_SIZE_COMPAT, when enabled, supports the legacy
# REE FS hash tree tagging implementation that uses a truncated hash.
# Be warned that disabling this config could break accesses to existing
# REE FS content.
CFG_REE_FS_HTREE_HASH_SIZE_COMPAT ?= y

# RPMB file system support
CFG_RPMB_FS ?= n

REE FS Secure Storage

Secure Storage System Architecture

在这里插入图片描述

Basic File Operation Flow

当可信应用**(TA)调用GP可信存储API(GP Internal API)提供的写入函数将数据写入持久对象时,会触发TEE可信存储服务(TEE Trusted Storage)中实现的相应系统调用。该系统调用进而会调用一系列TEE文件操作(TEE File Operation Interface)来存储数据。随后TEE文件系统(TEE File System)会对数据进行加密(Key Manager),并通过一系列RPC消息向TEE supplicant发送REE文件操作命令和加密数据。TEE supplicant接收这些消息后,会将加密数据相应地存储到Linux文件系统(Linux File System)**中。读取文件的操作也以类似方式处理。

TEE File Structure in Linux File System

OP-TEE默认使用Linux文件系统中的/data/tee/目录作为安全存储空间。每个持久化对象都会被分配一个内部标识符,该标识符为整数值,在Linux文件系统中体现为/data/tee/<文件编号>的路径形式。系统通过目录文件/data/tee/dirf.db记录安全存储中的所有对象。如下文所述,所有普通世界(normal world)文件都实施了完整性保护和加密措施。

但是在我当前版本中安全存储空间并不在这个位置:

# dmesg | grep -i optee
[    0.000000] OF: reserved mem: 0x000000000e100000..0x000000000effffff (15360 KiB) nomap non-reusable optee_core@e100000
[    0.000000] OF: reserved mem: 0x0000000042000000..0x00000000421fffff (2048 KiB) nomap non-reusable optee_shm@42000000
[    1.541640] optee: probing for conduit method.
[    1.542751] **optee: revision 4.6 (be8f86bf3605cf9e)**
[    1.549806] optee: Asynchronous notifications enabled
[    1.550834] optee: dynamic shared memory is enabled
[    1.564964] optee: initialized driver

# ls /var/lib/tee/
0        13       18       1d       3        8        d
1        14       19       1e       4        9        dirf.db
10       15       1a       1f       5        a        e
11       16       1b       2        6        b        f
12       17       1c       20       7        c
# 

安全存储空间的目录定义在此位置:

optee_client/config.mk

# CFG_TEE_FS_PARENT_PATH
#   Path to folder that will contain TEE filesystem.
#   This folder can be created with the required permission in an init
#   script during boot, else it will be created by the tee-supplicant on
#   first REE FS access.
CFG_TEE_FS_PARENT_PATH ?= /var/lib/tee

Key Manager

密钥管理器是TEE文件系统中的一个核心组件,主要负责数据加解密操作及敏感密钥材料的管理。该模块使用以下三类密钥:

安全存储密钥(SSK)

设备唯一密钥,由TEE在初始化阶段基于硬件唯一标识(如芯片ID)派生生成,作为根密钥保护其他密钥。

SSK的派生公式为:

SSK=HMACSHA256(HUK,ChipID∣∣“static string”) SSK = HMAC_{SHA256}(HUK, Chip ID || “static\,string”) SSK=HMACSHA256(HUK,ChipID∣∣“staticstring)

获取硬件唯一密钥(HUK)和芯片ID的函数实现取决于具体平台。当前OP-TEE操作系统中仅配置了用于安全存储子系统的设备专属密钥SSK,但未来可能需要采用与SSK相同的算法为不同子系统生成各自的设备专属密钥;而为不同子系统生成不同设备密钥的简便方法,就是使用不同的静态字符串来生成密钥。

SSK在TEE启动初始化阶段被创建,其生成函数如下:

optee_os/core/tee/tee_fs_key_manager.c

static TEE_Result tee_fs_init_key_manager(void)
{
        TEE_Result res = TEE_SUCCESS;

        COMPILE_TIME_ASSERT(TEE_FS_KM_SSK_SIZE <= HUK_SUBKEY_MAX_LEN);

        **res = huk_subkey_derive(HUK_SUBKEY_SSK, NULL, 0,
                                tee_fs_ssk.key, sizeof(tee_fs_ssk.key));**
        if (res == TEE_SUCCESS)
                tee_fs_ssk.is_init = 1;
        else
                memzero_explicit(&tee_fs_ssk, sizeof(tee_fs_ssk));

        return res;
}

可信应用存储密钥(TSK)

专用于特定可信应用(TA)的密钥,通过SSK与TA身份标识联合派生,实现不同TA间的存储隔离。

TSK的派生公式为:

TSK=HMACSHA256(SSK,TAUUID)TSK = HMAC_{SHA256}(SSK, TA_UUID)TSK=HMACSHA256(SSK,TAUUID)

TSK是生成FEK时使用到的密钥,生成函数见于FEK部分。

文件加密密钥(FEK)

动态生成的数据加密密钥,用于直接加密存储文件内容,其本身通过TSK或SSK进行加密保护后存储。当创建新的TEE文件时,密钥管理器会通过伪随机数生成器(PRNG)为该文件生成新的文件加密密钥(FEK),并将加密后的FEK存储在元数据文件中。

TA在每次使用安全存储功能创建一个安全文件时就会生成一个随机数作为FEK,即每个TA中的每个安全文件都有一个FEK用于加密对应文件中的数据,其生成函数如下:

optee_os/core/tee/tee_fs_key_manager.c

TEE_Result tee_fs_fek_crypt(const TEE_UUID *uuid, TEE_OperationMode mode,
                            const uint8_t *in_key, size_t size,
                            uint8_t *out_key)
{
        TEE_Result res;
        void *ctx = NULL;
        uint8_t tsk[TEE_FS_KM_TSK_SIZE];
        uint8_t dst_key[size];
	
				// 参数检查
        if (!in_key || !out_key)
                return TEE_ERROR_BAD_PARAMETERS;

        if (size != TEE_FS_KM_FEK_SIZE)
                return TEE_ERROR_BAD_PARAMETERS;

        if (tee_fs_ssk.is_init == 0)
                return TEE_ERROR_GENERIC;

				// 如果存在uuid,使用uuid生成tsk,如果不存在uuid,使用dummy代替uuid
        if (uuid) {
                res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key,
                              TEE_FS_KM_SSK_SIZE, uuid, sizeof(*uuid));
                if (res != TEE_SUCCESS)
                        return res;
        } else {
                 /*
                 * Pick something of a different size than TEE_UUID to
                 * guarantee that there's never a conflict.
                 */
                uint8_t dummy[1] = { 0 };

                res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key,
                              TEE_FS_KM_SSK_SIZE, dummy, sizeof(dummy));
                if (res != TEE_SUCCESS)
                        return res;
        }

				// 使用tsk将fek加密
        res = crypto_cipher_alloc_ctx(&ctx, TEE_FS_KM_ENC_FEK_ALG);
        if (res != TEE_SUCCESS)
                return res;

        res = crypto_cipher_init(ctx, mode, tsk, sizeof(tsk), NULL, 0, NULL, 0);
        if (res != TEE_SUCCESS)
                goto exit;

        res = crypto_cipher_update(ctx, mode, true, in_key, size, dst_key);
        if (res != TEE_SUCCESS)
                goto exit;

        crypto_cipher_final(ctx);

        memcpy(out_key, dst_key, sizeof(dst_key));

exit:
        crypto_cipher_free_ctx(ctx);
        memzero_explicit(tsk, sizeof(tsk));
        memzero_explicit(dst_key, sizeof(dst_key));

        return res;
}            

// 创建随机数
static TEE_Result generate_fek(uint8_t *key, uint8_t len)
{
        return crypto_rng_read(key, len);
}

// 创建FEK
TEE_Result tee_fs_generate_fek(const TEE_UUID *uuid, void *buf, size_t buf_size)
{
        TEE_Result res;

        if (buf_size != TEE_FS_KM_FEK_SIZE)
                return TEE_ERROR_BAD_PARAMETERS;

        res = generate_fek(buf, TEE_FS_KM_FEK_SIZE);
        if (res != TEE_SUCCESS)
                return res;

        return tee_fs_fek_crypt(uuid, TEE_MODE_ENCRYPT, buf,
                                TEE_FS_KM_FEK_SIZE, buf);
}

Hash Tree

哈希树负责处理安全存储文件的数据加解密操作。该哈希树采用二叉树结构实现,其中每个节点(如下方的struct tee_fs_htree_node_image)负责保护其两个子节点和一个数据块。元数据存储在头部结构(如下方的struct tee_fs_htree_image)中,该头部同时保护顶层节点。

所有字段(头部、节点和数据块)均采用0和1两个版本进行双重存储,以确保原子化更新。具体实现详见core/tee/fs_htree.c文件。

Meta Data Encryption Flow

Meta data encryption

在这里插入图片描述

当需要更新元数据时,系统会通过伪随机数生成器(PRNG)生成新的元数据初始化向量(IV)。元数据IV的大小定义在core/include/tee/fs_htree.h头文件中,同时该文件还定义了元数据和节点数据的数据结构。

Block Data Encryption Flow

Block data encryption

在这里插入图片描述

当需要更新块数据时,将通过伪随机数生成器(PRNG)生成新的块初始化向量(IV)。块IV的大小定义于core/include/tee/fs_htree.h头文件中。

Hash Tree Data structure

optee_os/core/include/tee/fs_htree.h

// 块数据数据结构
struct tee_fs_htree_node_image {
				// 当前节点所保护的两个子节点和一个数据块的联合哈希值
        uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
        // 加密向量
        uint8_t iv[TEE_FS_HTREE_IV_SIZE];
        // 认证标签
        uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
				// 节点状态或类型标识(如是否为叶子节点、是否有效等)
        uint16_t flags;
};

struct tee_fs_htree_meta {
        uint64_t length;
};

struct tee_fs_htree_imeta {
        struct tee_fs_htree_meta meta;
        uint32_t max_node_id;
};

// 元数据哈希树
struct tee_fs_htree_image {
				//加密根节点时使用的初始化向量(IV),确保相同数据加密结果不同。
        uint8_t iv[TEE_FS_HTREE_IV_SIZE];
        //根节点的认证标签(如 AES-GCM 的 MAC 值),用于验证数据完整性。
        uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
        //加密后的文件加密密钥(File Encryption Key, FEK),由 TEE 主密钥保护。
        uint8_t enc_fek[TEE_FS_HTREE_FEK_SIZE];
        //内联元数据(如哈希树高度、块大小等),用于描述哈希树结构。
        uint8_t imeta[sizeof(struct tee_fs_htree_imeta)];
        //版本计数器(用于双版本管理)
        uint32_t counter;
};

OP-TEE安全存储中用于保证原子性的策略是异地更新(out-of-place update)

哈希树中的双版本管理

🎯 目的:

双版本管理(Dual Version Management)用于实现 原子化更新 ,确保数据更新过程的 一致性断电恢复能力

🧱 核心设计:

  1. 每个关键结构保存两个版本
    • version 0version 1
    • 包括头部(tee_fs_htree_image)、节点(tee_fs_htree_node_image)和数据块。
  2. 版本切换通过 counter 字段控制
    • uint32_t counter; // 版本计数器(0或1)
    • 当前使用版本由 counter 的奇偶性决定(0表示使用 version 0,1表示使用 version 1)。
  3. 更新流程
    • 步骤 1:写入备用版本
      • 将新数据写入当前未使用的版本(例如,如果当前使用 version 0,则写入 version 1)。
    • 步骤 2:原子切换
      • 更新 counter 的值(递增或取反),指向新版本。
      • 这一步通常是原子操作(如写入一个标志位或更新指针)。
    • 步骤 3:清理旧版本 (可选):
      • 删除旧版本的数据以节省空间。
  4. 断电恢复
    • 如果在更新过程中断电,系统会检测到 counter 的值不匹配。
    • 自动回滚到最近的完整版本(通过验证哈希树的完整性)。

📌 示例流程:

  1. 初始状态:
    • counter = 0,使用 version 0 的数据。
  2. 写入新数据:
    • 将新数据写入 version 1。
    • 验证 version 1 的哈希树完整性。
  3. 切换版本:
    • 更新 counter = 1,指向 version 1。
  4. 成功后:
    • version 0 的数据可以安全删除(或保留作为备份)。

REE FS Secure Storage 中的dirf.db

正如前文提到的:OP-TEE将会在/data/tee目录中生成两个文件:dirf.db文件和以数字命名的文件。dirf.db文件保存的是整个安全存储功能管理的所有文件的目录信息和节点信息。

当用户使用某个已经存在的安全文件时,OP-TEE首先会读取dirf.db文件中的相关内容,然后根据需要操作的安全文件名字的哈希值在dirf.db文件中找到对应的文件编号,最终按照这个编号实现对文件的打开、关闭、写入、读出、重命名、裁剪等操作。

保存在/data/tee目录以数字命名的文件是被安全存储保护的用户文件。该文件保存的是加密之后的用户数据,加密使用的密钥则是对应的FEK。

dirf.db文件和安全文件的格式

使用安全存储功能生成的文件都会使用相同的格式被保存,而且dirf.db文件与安全文件的格式也相同。安全文件中的内容分为三个区域,分别用于保存文件头、结点、数据,文件的内容。

dirf.db文件的格式:

在这里插入图片描述

其中Tee_fs_htree_image表示哈希树的元数据,Tee_fs_htree_node_image表示哈希树的节点数据,Ver1/0用于安全存储的双版本管理。Data block存储的是,所有使用安全存储功能保存的文件的相关信息,在安全存储功能中使用dirfile_entry结构体来表示每个安全文件的基本信息,该结构体定义如下:

optee_os/core/tee/fs_dirfile.c

struct dirfile_entry {
				// 创建该安全文件的TA的UUID
        TEE_UUID uuid;
        // 安全文件的名字
        uint8_t oid[TEE_OBJECT_ID_MAX_LEN];
        // 文件名字的长度
        uint32_t oidlen;
        // 哈希值(用于完整性校验)
        uint8_t hash[TEE_FS_HTREE_HASH_SIZE];
        // 文件编号(用于定位实际文件)
        uint32_t file_number;
};

安全存储功能中使用的重要结构体

在整个安全存储功能的操作过程中,存在一些很重要的结构体,这些结构体用于记录或保存所有安全文件和dirf.db文件的操作信息。

在这里插入图片描述

相关重要结构体作用说明如下:

  • tee_fs_htree_node_image:用于保存文件的节点信息,通过节点可找到对应文件的头部或数据块信息
  • tee_fs_htree_image:用于保存安全文件的头部数据,从头部数据中可获取安全文件的加密密钥和加密头部时使用的IV值
  • tee_fs_fd:安全存储操作时使用的重要结构体,存放对文件操作时使用的fd、dir、TA的UUID等信息

安全存储中的文件节点组成

二叉树的保存方式如图所示,第一个节点作为dirf.db文件或安全文件的根节点使用。

在这里插入图片描述

查询安全文件中的特定数据块

在这里插入图片描述

RPMB Secure Storage

在这里插入图片描述

MMC/SD 子系统是 Linux 内核中用于管理 MMC(MultiMediaCard)SD(Secure Digital)eMMC(embedded MMC) 设备的框架,涵盖从物理层协议到块设备驱动的完整功能栈。

The Secure Storage API

这部分实现与基于REE(Rich Execution Environment)的文件系统通用。系统调用(位于core/tee/tee_svc_storage.c)与RPMB文件系统之间的接口通过tee_file_operations(即结构体tee_file_ops)进行交互。

The RPMB filesystem

FS(文件系统)实现完全位于core/tee/tee_rpmb_fs.c文件中,RPMB分区被划分为三个部分:

  • 前128字节保留用于分区数据(结构体rpmb_fs_partition)。
  • 在偏移量512处是文件分配表(FAT)。它是一个由struct rpmb_fat_entry元素组成的数组,每个文件对应一个元素。随着文件被添加到文件系统中,FAT会动态增长。每个条目包含文件数据的起始地址、大小和文件名等信息。
  • 从RPMB分区的末尾开始向上延伸的是文件数据区域。

optee_os/core/tee/tee_rpmb_fs.c

/**
 * RPMB_FS partition data
 */
struct rpmb_fs_partition {
				// 魔数,标识该结构有效性
        uint32_t rpmb_fs_magic;
        // 文件系统版本号
        uint32_t fs_version;
        // 写计数器(用于防回滚攻击)
        uint32_t write_counter;
        // FAT 表起始地址(偏移量)
        uint32_t fat_start_address;
        /* Do not use reserved[] for other purpose than partition data. */
        uint8_t reserved[112];
};

/**
 * File entry for a single file in a RPMB_FS partition.
 */
struct rpmb_fat_entry {
				// 文件数据起始地址(偏移量)
        uint32_t start_address;
        // 文件数据大小(字节)
        uint32_t data_size;
        // 标志位(如是否有效、只读等)
        uint32_t flags;
        // 保留字段
        uint32_t unused;
        // 加密该文件所使用的 FEK(加密后)
        uint8_t fek[TEE_FS_KM_FEK_SIZE];
        // 文件名
        char filename[TEE_RPMB_FS_FILENAME_LENGTH];
};

RPMB分区空间通过通用分配器函数tee_mm_alloc(...)tee_mm_alloc2(...)进行分配。

static inline tee_mm_entry_t *tee_mm_alloc(tee_mm_pool_t *pool, size_t size):从pool中分配大小为size的内存空间
tee_mm_entry_t *tee_mm_alloc2(tee_mm_pool_t *pool, paddr_t base, size_t size):从pool中分配从base开始长度为size的内存区域

所有文件操作都是原子性的。这一特性通过以下机制实现:

  1. eMMC规范保证:向RPMB分区写入单个数据块的操作具有原子性,这是由eMMC规范确保的。
  2. FAT块最后更新:文件数据成功写入后,才会最后更新该文件的FAT块(文件分配表条目)。
  3. 就地更新限制
    • 仅当文件修改范围不超过“可靠写入块计数”(reliable write block count)时,才直接在原位置更新数据。
    • 若文件需要扩展或修改跨越多个块,则会创建新文件而非就地更新,以确保数据一致性。

Device access

OP-TEE中并未集成eMMC控制器驱动,所有设备操作都必须经由普通世界(Normal World)完成。这些操作由tee-supplicant进程处理,该进程进一步依赖内核的ioctl()接口来访问设备。tee-supplicant还提供了模拟模式,可通过虚拟RPMB设备实现测试功能。

RPMB operations are the following:

  • 读取设备信息(分区大小、可靠写入块数)。
  • 编程安全密钥。该密钥用于身份验证目的。请注意,它不同于下文定义的Secure Storage Key(SSK,安全存储密钥),后者用于加密。但与SSK类似,安全密钥同样衍生自硬件唯一密钥或标识符。当前通过调用tee_otp_get_hw_unique_key()函数生成RPMB安全密钥。
  • 读取写入计数器值。该计数器用于读写请求时的HMAC计算。初始化阶段读取该值后,会存储于tee_rpmb_ctx结构体(即rpmb_ctx->wr_cnt)中。
  • 读取或写入数据块。

RPMB操作由文件系统(FS)层发起请求。通过thread_rpc_alloc_payload(...)函数在共享内存中分配请求与响应的内存缓冲区。借助thread_rpc_cmd()函数,这些缓冲区会以TEE_RPC_RPMB_CMD消息形式传递至普通世界( Normal World )。大多数RPMB请求和响应采用JEDEC eMMC规范定义的数据帧格式,同时在此也实现了HMAC认证机制。

Encryption

文件系统加密例程位于core/tee/tee_fs_key_manager.c文件中。块加密用于保护文件数据,采用128位AES算法的密码块链接模式(CBC)结合加密盐扇区初始化向量(ESSIV)技术,具体实现可参阅CBC-ESSIV规范。

SSK(安全存储密钥)、TSK(可信应用存储密钥)和FEK(文件加密密钥)的处理方式与基于REE(富执行环境)的安全存储方案相同,而AES CBC块加密仅用于RPMB(REE实现则使用GCM模式)。需注意的是,文件分配表(FAT)本身并未加密。

操作安全存储对象的接口

TEE_CreatePersistentObject

TEE_Result TEE_CreatePersistentObject(
							uint32_t storageID,          //存储标识符,指定该对象保存在哪个存储区域
																					 //通常使用TEE_STORAGE_PRIVATE
							const void *objectID,        //对象的唯一标识符
				      size_t objectIDLen,          //objectID的长度(字节数)
																			     //最大长度为TEE_OBJECT_ID_MAX_LEN
				      uint32_t flags,              //标志位,控制对象的行为和访问权限
				      TEE_ObjectHandle attributes, //与对象关联的安全属性句柄
				      const void *initialData,     //要写入对象的初始数据指针
				      size_t initialDataLen,       //初始数据的长度
				      TEE_ObjectHandle *object)    //输出参数,用于返回创建的对象句柄。

其中storageID,objectID,objectIDLen,flags,object为必填参数。attributes,initialData,initialDataLen为选填参数,可以填写attributes将句柄中的数据写入,或者填写initialData,initialDataLen直接写入数据。

TEE_CloseObject

void TEE_CloseObject(TEE_ObjectHandle object)

TEE_WriteObjectData

TEE_Result TEE_WriteObjectData(
						TEE_ObjectHandle object,  //持久化对象的句柄
						const void *buffer,       //偏移量(字节),可以是正数或负数
			      size_t size)              //起始位置,决定偏移的基准点

该函数用于设置当前持久化对象的数据访问位置偏移(seek),以便后续调用TEE_ReadObjectData() 或 TEE_WriteObjectData() 时从指定位置开始操作。

TEE_ReadObjectData

TEE_Result TEE_ReadObjectData(
						TEE_ObjectHandle object,   //持久化对象的句柄
						void *buffer,              //用于接收数据的缓冲区
			      size_t size,               //要读取的数据大小(字节数)
			      size_t *count)             //实际读取的字节数(输出参数)

TEE_WriteObjectData

TEE_Result TEE_WriteObjectData(
						TEE_ObjectHandle object,   //持久化对象的句柄
						const void *buffer,        //待写入数据的缓冲区地址
						size_t size)               //要写入的数据长度

TEE_RenamePersistentObject

TEE_Result TEE_RenamePersistentObject(
							TEE_ObjectHandle object,   //持久化对象的句柄
				      const void *newObjectID,   //对象的唯一标识符
				      size_t newObjectIDLen)     //对象的唯一标识符长度

TEE_CloseAndDeletePersistentObject1

TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)

TEE_CloseAndDeletePersistentObject is deprecated new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead

These functions will be removed at some future major revision of this specification。

执行此函数前需要先通过TEE_OpenPersistentObject 函数获得对象句柄

TEE_OpenPersistentObject

TEE_Result TEE_OpenPersistentObject(
						uint32_t storageID,        
						const void *objectID,
				    size_t objectIDLen, 
				    uint32_t flags,
				    TEE_ObjectHandle *object)

等等….

参考资料:

  • https://optee.readthedocs.io/en/latest/architecture/secure_storage.html
  • 《手机安全和可信应用开发指南:TrustZone与OP-TEE技术详解》
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐