OPTEE安全存储

news2024/12/27 15:54:35

本文主要介绍OPTEE的安全存储技术,翻译自官方文档:
Secure storage — OP-TEE documentation documentation (optee.readthedocs.io)


一、背景

OP-TEE中的安全存储是根据GlobalPlatform的TEE Internal Core API(这里称为可信存储)中定义的内容实现的。此规范要求应该能够存储通用数据和密钥材料,以保证所存储数据的机密性和完整性以及修改存储的操作的原子性(这里的原子性意味着整个操作成功完成或不完成写入)。

OP-TEE 中目前有两种安全存储实现:

第一个依赖于正常世界 (REE) 文件系统。它在本文档中进行了描述,并且是默认实现。它在编译时由 CFG_REE_FS=y 启用。

第二个使用eMMC设备的重放保护内存块(RPMB)分区,并通过设置CFG_RPMB_FS=y启用。RPMB 安全存储中对此进行了描述。

可以同时使用正常文件系统和 RPMB 实现。为此,定义了两个特定于 OP-TEE 的存储标识符:TEE_STORAGE_PRIVATE_REE 和 TEE_STORAGE_PRIVATE_RPMB。根据编译时配置,可以使用一个或多个值。TEE_STORAGE_PRIVATE值在可用时选择 REE FS,否则选择 RPMB FS(按此顺序)。

二、REE FS安全存储

安全存储系统体系结构 

OP-TEE 操作系统中的源文件:

源文件目的

core/tee/tee_svc_storage.c

TEE 可信存储服务调用

core/tee/tee_ree_fs.c

TEE 文件系统和 REE 文件操作界面

core/tee/fs_htree.c

哈希树

core/tee/tee_fs_key_manager.c

密钥管理器

lib/libutee/

全球平台内部 API 库

1、基本文件操作流程

当 TA 调用 GP 可信存储 API 提供的写入函数将数据写入持久对象时,会调用 TEE 可信存储服务中实现的相应系统调用,进而调用一系列 TEE 文件操作来存储数据。然后,TEE 文件系统将对数据进行加密,并通过一系列 RPC 消息将 REE 文件操作命令和加密数据发送给 TEE 请求方。TEE 请求方将接收消息并将加密数据存储到 Linux 文件系统中。读取文件的处理方式类似。

2、全球平台可信存储要求

以下是规范的摘录,列出了最重要的要求:

1. 受信任的存储可能由非安全资源支持,只要应用了适当的加密保护,其强度必须与用于保护 TEE 代码和数据本身的方法。

2. 可信存储必须绑定到特定设备,这意味着它必须只能由授权的助教访问或修改在与数据相同的 TEE 和同一设备上运行创建。

3. 能够对 TA 本身隐藏敏感密钥材料。

4. 每个 TA 都可以访问自己的存储空间,该存储空间由所有该 TA 的实例,但与其他 TA 分开。

5. 受信任的存储必须提供最低级别的保护回滚攻击。可以接受的是,实际的物理存储可能位于不安全区域,因此容易受到来自TEE之外。通常,实现可能依赖于 REE用于此目的(保护级别 100)或硬件资产由 TEE 控制(防护等级 1000)。

(请参阅 GP TEE 内部核心 API 第 2.5 和 5.2 节)

如果配置为 CFG_RPMB_FS=y,则防回滚保护由 TEE 控制,设置为 1000。如果 CFG_RPMB_FS=n,则没有针对回滚的保护,并且保护级别设置为 0。 

3、Linux 文件系统中的 TEE 文件结构 

OP-TEE 默认使用 /data/tee/ 作为 Linux 文件系统中的安全存储空间。每个持久性对象都分配有一个内部标识符。它是一个整数,在 Linux 文件系统中显示为 /data/tee/<file number>。

目录文件 /data/tee/dirf.db 列出了安全存储中的所有对象。所有正常世界文件都受到完整性保护和加密,如下所述。

三、密钥管理器

密钥管理器是 TEE 文件系统中的一个组件,负责处理数据加密和解密以及敏感密钥材料的管理。密钥管理器使用三种类型的密钥:安全存储密钥 (SSK)、TA 存储密钥 (TSK) 和文件加密密钥 (FEK)。

1、安全存储密钥 (SSK)

SSK 是每个设备的密钥,在 OP-TEE 启动时生成并存储在安全内存中。SSK 用于派生 TA 存储密钥 (TSK)。

SSK派生自

获取硬件唯一密钥 (HUK) 和芯片 ID 的函数取决于平台实现。目前,在 OP-TEE OS 中,我们只有一个用于安全存储子系统的每设备密钥 SSK,但是,将来我们可能需要使用生成 SSK 时相同的算法为不同的子系统创建不同的每设备密钥;为不同子系统生成不同的每设备密钥的一种简单方法是使用不同的静态字符串来生成密钥。

2、受信任的应用程序存储密钥 (TSK)

TSK 是每个受信任的应用程序密钥,由 SSK 和 TA 的标识符 (UUID) 生成。它用于保护FEK,换句话说,加密/解密FEK。

TSK派生自:

 

3、文件加密密钥 (FEK)

创建新的 TEE 文件时,密钥管理器将通过 PRNG(pesudo 随机数生成器)为 TEE 文件生成新的 FEK,并将加密的 FEK 存储在元文件中。FEK用于加密/解密存储在元文件中的TEE文件信息或存储在块文件中的数据。

四、哈系树

哈希树负责处理安全存储文件的数据加密和解密。哈希树被实现为二叉树,其中树中的每个节点(下面的结构tee_fs_htree_node_image)保护其两个子节点和一个数据块。元数据存储在标头(下面的结构tee_fs_htree_image)中,该标头也保护顶部节点。

所有字段(标头、节点和块)都与两个版本(0 和 1)重复,以确保原子更新。有关详细信息,请参阅core/tee/fs_htree.c。

1、元数据加密流程

 元数据加密

当元数据需要更新时,PRNG 将生成一个新的元 IV。meta IV 的大小在 core/include/tee/fs_htree.h 中定义,元数据和节点数据的数据结构在 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 {
        uint8_t iv[TEE_FS_HTREE_IV_SIZE];
        uint8_t tag[TEE_FS_HTREE_TAG_SIZE];
        uint8_t enc_fek[TEE_FS_HTREE_FEK_SIZE];
        uint8_t imeta[sizeof(struct tee_fs_htree_imeta)];
        uint32_t counter;
};

2、块数据加密流程

 块数据加密

当需要更新区块数据时,PRNG 将生成一个新的区块 IV。块IV的大小在core/include/tee/fs_htree.h中定义。

五、原子操作

根据GP可信存储规范的原子性要求,以下操作应支持原子更新:

写入、截断、重命名、创建和删除

OP-TEE安全存储中用于保证原子性的策略是异地更新。 

六、RPMB 安全存储

本文介绍 OP-TEE 中的 RPMB 安全存储实现,通过设置 CFG_RPMB_FS=y 启用。 受信任的应用程序可以通过传递等于 TEE_STORAGE_PRIVATE_RPMB 的存储 ID 来使用此实现,如果禁用CFG_REE_FS则传递TEE_STORAGE_PRIVATE。有关RPMB的详细信息,请参阅JEDEC eMMC规范(JESD84-B51)。

架构如下图所示:

|          NORMAL WORLD           :            SECURE WORLD              |
                                  :
U        tee-supplicant           :        Trusted application
S           (rpmb.c)              :        (secure storage API)
E         ^          ^            :                  ^
R         |          |            :                  |
~~~~~~~ ioctl ~~~~~~~|~~~~~~~~~~~~:~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~
K         |          |            :               OP-TEE
E         v          v            :         (tee_svc_storage.c)
R  MMC/SD subsys.  OP-TEE driver  : (tee_rpmb_fs.c, tee_fs_key_manager.c)
N         ^                 ^     :                  ^
E         |                 |     :                  |
L         v                 |     :                  |
    Controller driver       |     :                  |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~
                            v                        v
                          Secure monitor / EL3 firmware

有关 Linux 内核中 MMC/SD 子系统的 ioctl() 接口的信息,请参阅 Linux core MMC 头文件 linux/mmc/core.h 和 mmc-utils 存储库。 

1、安全存储 API

这部分在基于 REE 的文件系统中是通用的。core/tee/tee_svc_storage.c 中的系统调用与 RPMB 文件系统之间的接口是tee_file_operations,即结构tee_file_ops。

2、RPMB 文件系统

FS 实现完全在 core/tee/tee_rpmb_fs.c 中,RPMB 分区分为三个部分:

前 128 个字节保留用于分区数据(结构 rpmb_fs_partition)。

偏移量 512 处是文件分配表 (FAT)。它是一个结构rpmb_fat_entry元素数组,每个文件一个。FAT 随着文件添加到文件系统而动态增长。除此之外,每个条目都有文件数据的开始地址、大小和文件名。

从 RPMB 分区的末尾开始向下延伸是文件数据区域。

分区中的空间由通用分配器函数 tee_mm_alloc(...) 和 tee_mm_alloc2(...) 分配。

所有文件操作都是原子操作。这要归功于以下属性:

根据 eMMC 规范,将单个数据块写入 RPMB 分区是原子的。

在成功写入数据后,修改文件的 FAT 块始终最后更新。

仅当数据跨度不超过“可靠写入块计数”块时,才会就地更新文件内容。否则,或者如果需要扩展文件,则会创建一个新文件。

3、设备访问

OP-TEE 中没有 eMMC 控制器驱动程序。设备操作都必须经过正常世界。它们由 tee 请求进程处理,该进程进一步依赖于内核的 ioctl() 接口来访问设备。三通请求方还具有仿真模式,该模式可实现用于测试目的的虚拟 RPMB 设备。

RPMB 操作如下:

读取设备信息(分区大小、可靠的写入块计数)。

对安全密钥进行编程。此密钥用于身份验证目的。请注意,它与下面定义的用于加密的安全存储密钥 (SSK) 不同。但是,与 SSK 一样,安全密钥也派生自硬件唯一密钥或标识符。

目前,函数 tee_otp_get_hw_unique_key() 用于生成 RPMB 安全密钥。

读取写入计数器值。写入计数器在读取和写入请求期间用于 HMAC 计算。该值在初始化时读取,并存储在结构tee_rpmb_ctx中,即rpmb_ctx->wr_cnt。

读取或写入数据块。

 RPMB 操作是根据 FS 层的请求启动的。请求和响应的内存缓冲区使用 thread_rpc_alloc_payload(...) 在共享内存中分配。缓冲区在TEE_RPC_RPMB_CMD消息中传递到正常世界,这要归功于 thread_rpc_cmd() 函数。大多数 RPMB 请求和响应使用 JEDEC eMMC 规范定义的数据帧格式。HMAC 身份验证也在此处实现。

4、安全注意事项

在设备上对密钥进行编程之前,无法访问 eMMC 中的 RPMB 分区:这是设备生命周期内的一次性操作。在 eMMC 控制器上写入密钥后,控制器将使用它对请求进行身份验证。

可以通过多种方式对此密钥进行编程。如果您希望OP-TEE执行此操作,则必须将OP-TEE配置为CFG_RPMB_WRITE_KEY=y。

警告:注意,此配置会将 RPMB 密钥明文发送到将 RPMB 密钥编程请求中继到 eMMC 硬件设备的非安全端。

OP-TEE 可以嵌入内置的 RPMB 密钥 (CFG_RPMB_TESTKEY=y),也可以从特定于平台的机密 (CFG_RPMB_TESTKEY=n) 派生它。前一种情况在开发过程中可能很有用,而后一种情况则建议用于生产设备。

从机密派生密钥可避免 OP-TEE 将其存储在内存中,从而减少攻击面;OP-TEE 从包含 eMMC 序列号的内部集派生 RPMB 密钥,更重要的是硬件唯一密钥 (HUK)。

要使此配置生效,硬件唯一密钥(SoC 特定实例化的唯一标识符)不得公开访问(请注意,并非所有平台都可能强制实施此要求)。

保持 HUK 机密的需要是为什么在安全感知系统上,硬件将根据平台的安全状态生成不同的 HUK 值的原因:换句话说,SoC 将生成不同的 HUK,具体取决于是否将 BOOT ROM 配置为启动签名映像。

但请注意,由于 RPMB 密钥只能在控制器上写入一次,因此在保护电路板之前访问 RPMB 将导致在保护板后拒绝未来的 RPMB 访问。为了防止这种情况发生,OP-TEE提供了一个软件钩子,平台应使用该钩子来实现其安全逻辑plat_rpmb_key_is_ready()。

警告:为了使 OP-TEE 能够写入 RPMB 密钥,必须配置 CFG_RPMB_WRITE_KEY=y,并且 plat_rpmb_key_is_ready() 必须在运行时允许它。

5、加密

FS 加密例程位于 core/tee/tee_fs_key_manager.c 中。块加密可保护文件数据。该算法是密码块链 (CBC) 模式下的 128 位 AES,具有加密盐扇区初始化向量 (ESSIV),有关详细信息,请参阅 CBC-ESSIV。

在 OP-TEE 初始化期间,128 位 AES 安全存储密钥 (SSK) 派生自硬件唯一密钥 (HUK)。它保存在安全内存中,永远不会写入磁盘。受信任的应用程序存储密钥派生自 SSK 和 TA UUID。

对于每个文件,在创建文件时随机生成一个 128 位加密文件加密密钥 (FEK),使用 TSK 加密并存储在文件的 FAT 条目中。

然后,每个 256 字节的数据块在 CBC 模式下加密。初始化向量是通过ESSIV算法获得的,即通过FEK的哈希对块号进行加密。这允许直接访问文件中的任何块,如下所示:

FEK = AES-Decrypt(TSK, encrypted FEK);
k = SHA256(FEK);
IV = AES-Encrypt(128 bits of k, block index padded to 16 bytes)
Encrypted block = AES-CBC-Encrypt(FEK, IV, block data);
Decrypted block = AES-CBC-Decrypt(FEK, IV, encrypted block data);

 SSK、TSK 和 FEK 处理在基于 REE 的安全存储中很常见,而 AES CBC 块加密仅用于 RPMB(REE 实现使用 GCM)。FAT 未加密。

6、REE FS 哈希状态

如果同时配置了CFG_REE_FS=y和CFG_RPMB_FS=y,REE FS将在RPMB中创建一个特殊文件dirfile.db.hash,其中包含一个表示REE FS状态的哈希。

七、重要注意事项

警告

目前,某些OP-TEE平台不支持检索安全操作所需的硬件唯一密钥或芯片ID。对于这些平台,使用常量密钥,导致无法防止解密或安全存储复制到其他设备。这是因为有关如何从 SoC 检索密钥数据的信息被某些供应商视为敏感信息,并且不公开。

要允许安全存储在您的平台上安全运行,您必须在平台代码中定义以下实现:

void tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey);

int tee_otp_get_die_id(uint8_t *buffer, size_t len);

 这些实现应根据 SoC 供应商定义的方法从特定于 SoC 的电子保险丝或加密单元中提取密钥数据。

八、参考资料

有关安全存储的更多信息,请参阅演示文稿(Presentations — OP-TEE documentation documentation (optee.readthedocs.io))中的 SFO15-503、LAS16-504、SFO17-309 和 TEE Internal Core API 规范GlobalPlatform API — OP-TEE documentation documentation (optee.readthedocs.io))。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023/1/13总结

今天学习了链式向前星和唯一分解定理&#xff08;数论&#xff09;。 链式向前星 链式向前星是一种存储图的方法&#xff0c;在此之前我们学到过存储图的方式&#xff1a;邻接表以及邻接矩阵&#xff0c;邻接矩阵浪费了很大的空间&#xff0c;而邻接表 写起来的代码有一点点…

微信小程序wxml的数据和事件的绑定,以及条件和列表的渲染

文章目录1.数据绑定的基本原则在data中定义页面的数据2.事件绑定bingtap的语法格式:在事件处理函数中为data中的数据赋值事件传参bindinput的语法格式实现文本框和data之间的数据同步1.定义数据2.渲染结构3.美化样式4.绑定input事件处理函数3.条件渲染hiddenwx:if与hidden的对比…

数据库 表设计 MySQL

表设计 约束 为了保证入库数据的合理性&#xff0c;添加的各种规则。 约束的分类 准备测试用的表格&#xff1a; CREATE TABLE emp ( id INT, -- 员工id&#xff0c;主键且自增长 ename VARCHAR(50), -- 员工姓名&#xff0c;非空且唯一 joindate DATE, -- 入职日期&…

【uniapp】渲染列表数据删除项导致每项数据重置的问题解决方案

开发uniapp项目&#xff0c;使用的是JavaScript Vue写法&#xff0c;操作wList数组列表更新的时候&#xff0c;如果每一项都带input 或 radio组件&#xff0c;要操作移除的话&#xff0c;那么组件的输入数据会被清除重置&#xff0c;若不希望这样&#xff0c;那应该怎么做才好呢…

设计模式相关内容介绍—软件设计原则(六个)

在软件开发中&#xff0c;为了提高软件系统的可维护性和可复用性&#xff0c;增加软件的可扩展性和灵活性&#xff0c;程员要尽量根据6条原则来开发程序&#xff0c;从而提高软件开发效率、节约软件开发成本和维护成本。 目录 1.开闭原则 2.里氏代替原则 3.依赖倒转原则 4.接…

dvwa中的文件包含攻击

环境&#xff1a;dvwa: 192.168.11.135 dvwa版本&#xff1a; Version 1.9 (Release date: 2015-09-19)kail机器&#xff1a;192.168.11.156一、什么是文件包含漏洞?为简化代码&#xff0c;会把重复的code内容单独写到一个页面文件&#xff0c;然后再需要调用重复内容的页面中…

C语言:初识C语言

目录前言1. 什么是c语言呢2. 第一个c语言程序2. 数据类型3. 变量和常量3.1 变量3.1.1 变量的定义3.1.2 变量的分类3.1.3 变量的使用3.1.4 变量的作用域和生命周期3.2 常量4. 字符串、转义字符、注释4.1 字符串4.2 转义字符4.3 注释5. 选择语句6. 循环语句7. 函数8. 数组9. 操作…

学习笔记——keep-alive缓存组件,再次返回组件data数据重置

前言&#xff1a;使用keep-alive缓存组件&#xff0c;当再次返回该组件后&#xff0c;希望其组件中的数据或状态&#xff0c;保持上次离开该组件时的情况。 一、当前组件树 希望缓存HomeMain组件的状态。 二、错误处理 我在HomeMain的祖先组件HomeLayout中&#xff0c;写了如下…

sqlplus 连接数据库

终端直连 Oracle 数据库 ORA-12162 错误 出于各种网络原因&#xff0c;无法直连数据库&#xff0c;但又必须查询数据库数据 我们只能选择直连数据库的服务器 然后通过 sqlplus 连接 Oracle 从配置文件里获取这样一段信息 urljdbc:oracle:thin:192.168.1.3:1521:testdb use…

【SpringCloud08】SpringCloud Consul服务注册与发现

1.Consul简介 1.1是什么 官网 Consul 是一套开源的分布式服务发现和配置管理系统&#xff0c;由 HashiCorp 公司用Go 语言开发 提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用&#xff0c;也可以一起使用以构建全方位…

基于MPLS-V**多分部互访的ensp企业网络规划与设计_ensp综合实验

作者&#xff1a;BSXY_19计科_陈永跃BSXY_信息学院注&#xff1a;未经允许禁止转发任何内容基于MPLS-V**多分部互访的ensp企业网络规划与设计_ensp综合实验前言及技术/资源下载说明&#xff08; **未经允许禁止转发任何内容** &#xff09;插曲&#xff1a;基于eNSP中大型校园/…

卡特加特数字中控主机,数字家庭控制中心!没它智能家居就是智障!

数字中控主机是数字家庭的核心&#xff0c;承担着“协调各方、总揽全局”的作用&#xff0c;是打造未来数字家庭空间必不可少的设备。区别于传统家居智能&#xff0c;它真正意义上告别了过去以设备为中心的架构&#xff0c;而是以人的个性化需求为中心&#xff0c;以数据作为资…

2020统考真题-距离最小三元组

2020年统考真题 定义三元组$ (a,b,c)$ &#xff08; a,b,c 均为正数&#xff09;的距离 D∣a−b∣∣b−c∣∣c−a∣D|a−b||b−c||c−a|D∣a−b∣∣b−c∣∣c−a∣ 。给定 3个非空整数集合 S1 、 S2 和 S3 &#xff0c;按升序分别存储在 3 个数组中。请设计一个尽可能高效的算…

蓝队攻击的四个阶段(三)

目录 一&#xff0c; 专业技能储备 1.工具开发技能 2.漏洞挖掘技能 3.代码调试技能 4.侦破拓展技能 二&#xff0c;目标网情搜集 1 何为网情搜集 2. 网情搜集的主要工作 三&#xff0c; 网情搜集的途径 1.专业网站 2.专业开发资源网站 3.目标官网 一&#xff0c; 专…

算法训练营 day17 二叉树 平衡二叉树 二叉树的所以路径 左叶子之和

算法训练营 day17 二叉树 平衡二叉树 二叉树的所以路径 左叶子之和 平衡二叉树 110. 平衡二叉树 - 力扣&#xff08;LeetCode&#xff09; 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每…

osg fbo(五) 通过shader计算纹理坐标并采样

在前边几节&#xff0c;纹理坐标数组是在生成geometry前指定的。 这里在shader里计算&#xff0c; 一&#xff0c;注释掉geometry中的纹理坐标 //osg::ref_ptr<osg::Vec2Array> texCoord new osg::Vec2Array; //texCoord->push_back(osg::Vec2(0.0, 0.0)); //texCoo…

1.13UART串口实验

UART总线&#xff1a; 异步全双工串行总线。用于芯片与外设之间的通信 UART通信协议&#xff1a; 空闲状态处于高电平 起始位&#xff1a;串口通信的起始标志 数据位&#xff1a;传输数据时先从低位开始传输&#xff0c;再传输高位 奇偶校验位&#xff1a; 奇校验&#x…

MacOS 系统中如何使用EF Core进行数据迁移?

原有 笔者最近在使用MacOS系统做asp.net core mvc项目开发。可是一直习惯了使用宇宙最强大的vs2019工具。突然换到苹果系统就感觉什么都是问题了。现在我将遇到该问题的解决方案做下记录&#xff0c;方便自己也是方便别的同学快速的解决问题。 发现有坑 其实最开始我也是翻阅…

RocketMQ 存储优化技术 解析——图解、源码级解析

&#x1f34a; Java学习&#xff1a;Java从入门到精通总结 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2023年1月13日 &#x…

Django 后端没有接收到前端anxios的 post 内容

前端使用 vue 无论怎样 post 后端都说没有接收到值&#xff0c;&#xff08;后端接口正确&#xff09; 寻找原因&#xff1a; 1、前端查看自己的请求类型 Content-Type:application/json 我们的请求是这样的&#xff1a; axios({method:post,url:/video/upload,data:{"…