Skip to content

[OPTEE-OS] secure storage的使用 #248

@carloscn

Description

@carloscn

说到secure storage,不得不提EMMC里面RPMB的硬件设计。我以德州仪器TDA4V板子为例,来实现secure storage。

TDA4V板子Linux系统,我使用的启动介质是SD卡(SD卡协议很少有RPMB和boot区域),因此RPMB还是板载的eMMC。

image.png512

这里面mmcblk0是板载的emmc,而mmcblk1是我的SD卡:

root@j784s4-evm:~# dmesg | grep mmc
[    1.685035] mmc0: CQHCI version 5.10
[    1.729517] mmc0: SDHCI controller on 4f80000.mmc [4f80000.mmc] using ADMA 64-bit
[    1.821290] mmc0: Command Queue Engine enabled
[    1.825731] mmc0: new HS200 MMC card at address 0001
[    1.831010] mmcblk0: mmc0:0001 G1M15L 29.6 GiB 
[    1.836655] mmcblk0boot0: mmc0:0001 G1M15L 31.5 MiB 
[    1.842263] mmcblk0boot1: mmc0:0001 G1M15L 31.5 MiB 
[    1.847757] mmcblk0rpmb: mmc0:0001 G1M15L 4.00 MiB, chardev (240:0)
[    2.328346] mmc1: CQHCI version 5.10
[    2.372803] mmc1: SDHCI controller on 4fb0000.mmc [4fb0000.mmc] using ADMA 64-bit
[    2.416929] mmc1: new high speed SDHC card at address 59b4
[    2.422782] mmcblk1: mmc1:59b4 SD3.0 30.3 GiB 
[    2.431222]  mmcblk1: p1 p2
[    2.489289] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Quota mode: none.
[    4.702730] EXT4-fs (mmcblk1p2): re-mounted. Quota mode: none.

一个eMMC的结构如下:

image.png512

简言之:

image.png512512

1. RPMB硬件设计

在 eMMC(嵌入式多媒体卡)存储设备中,RPMB(Replay Protected Memory Block)是一个专为安全性设计的特殊分区。它通过一系列安全机制,确保数据的读写操作受到保护,防止非法篡改和重放攻击。RPMB 广泛应用于需要高安全性的场景,例如在智能手机中存储指纹支付的公钥、设备序列号等敏感数据。

RPMB 是 eMMC 存储设备中的一个独立分区,其设计目标是提供防篡改和防重放保护。当主机(Host)向 RPMB 写入数据时,eMMC 会对数据的合法性进行严格校验,只有经过认证的主机才能成功写入。同时,在读取数据时,RPMB 提供签名验证机制,确保主机读取到的数据确实来自 RPMB 分区,而不是被攻击者伪造的数据。

需要注意的是,RPMB 的读取操作并不要求认证,任何主机都可以读取数据。因此,为了进一步保护数据的机密性,通常建议将数据加密后再存储到 RPMB 中。

1.2 RPMB 分区的大小

RPMB 分区的容量由 eMMC 的 Extended CSD 寄存器中的 BOOT_SIZE_MULT 字段决定,其计算公式为:容量 = 128 KB × BOOT_SIZE_MULT

通常,RPMB 分区的容量是 128 KB 的倍数。默认情况下,许多 eMMC 芯片的 RPMB 分区大小为 4 MB(即 BOOT_SIZE_MULT = 32)。部分芯片厂商允许用户通过修改 RPMB_SIZE_MULT 来调整分区大小,最大支持 RPMB_SIZE_MULT = 128,此时 RPMB 分区的容量可达:128 × 128 KB = 16384 KB = 16 MB

1.3 RPMB 的防重放保护机制

RPMB 的核心安全特性在于其防重放保护(Replay Protection),这一功能依赖于以下两个关键元素:

Secure Key:

image.png512512

  • 在设备生产过程中,每个 eMMC 设备都会被写入一个唯一的 256 位(32 字节)安全密钥(Secure Key)。这个密钥会被烧录到 eMMC 的 OTP(One-Time Programmable,一次性可编程)区域,无法修改。
  • 同时,主机(Host)也会在安全环境中(例如 TEE,Trusted Execution Environment)存储相同的 Secure Key。

Write Counter:

  • eMMC 内部维护一个 RPMB Write Counter(写入计数器)。每次合法的写入操作完成后,该计数器会自动递增。
  • 这个计数器用于防止重放攻击,确保写入操作的唯一性。

通过 Secure Key 和 Write Counter 的协同工作,RPMB 能够有效防止非法数据篡改和重放攻击。

image.png512

1.4 RPMB 数据读取流程

image.png512

RPMB 的数据读取过程通过签名验证机制,确保读取到的数据未被篡改。以下是读取流程的详细步骤:

  1. 主机发起读取请求:
    • 主机向 eMMC 发送读取 RPMB 数据的请求,并生成一个 16 字节的随机数(nonce),一同发送给 eMMC。
  2. eMMC 生成签名并返回数据:
    • eMMC 从 RPMB 分区中读取请求的数据。
    • eMMC 使用 Secure Key,通过 HMAC-SHA-256 算法对读取的数据和主机发送的随机数进行签名计算。
    • eMMC 将读取的数据、原始随机数以及计算得到的签名一起返回给主机。
  3. 主机验证数据:
    • 主机收到数据后,首先检查返回的随机数是否与自己发送的随机数一致,以防止重放攻击。
    • 如果随机数一致,主机使用相同的 Secure Key,通过 HMAC-SHA-256 算法对接收到的数据和随机数进行签名计算。
    • 主机将计算得到的签名与 eMMC 返回的签名进行比较。如果两者一致,主机可以确认数据是从 RPMB 分区读取的真实数据,而非攻击者伪造的。

通过这一流程,RPMB 确保主机读取到的数据是可信的。

1.4 RPMB 数据写入流程

image.png512

RPMB 的写入操作更加严格,需要通过认证才能成功写入数据,以防止未经授权的篡改。以下是写入流程的详细步骤:

  1. 主机获取 Write Counter:
    • 主机首先通过读取流程获取当前的 RPMB Write Counter 值,以确保后续写入操作的有效性。
  2. 主机准备数据并生成签名:
    • 主机将要写入的数据与当前的 Write Counter 值拼接在一起。
    • 使用 Secure Key,通过 HMAC-SHA-256 算法计算数据的签名。
    • 主机将数据、Write Counter 和签名一起发送给 eMMC。
  3. eMMC 验证并写入数据:
    • eMMC 接收到数据后,首先检查接收到的 Write Counter 是否与当前内部计数器值相同,以防止重放攻击。
    • 如果 Write Counter 匹配,eMMC 使用相同的 Secure Key,通过 HMAC-SHA-256 算法对数据和 Write Counter 进行签名计算。
    • eMMC 将计算得到的签名与主机发送的签名进行比较。如果签名一致,认证通过,eMMC 将数据写入 RPMB 分区,并递增 Write Counter。

通过这一流程,RPMB 确保只有经过认证的主机才能写入数据,防止非法篡改。

1.5 嵌入式Linux对PRMB的验证

由于我的RPMB被OPTEE-OS的CFG_RPMB_TESTKEY写入,这个Key在板子上无法更改了。

static const uint8_t rpmb_test_key[RPMB_KEY_MAC_SIZE] = {
	0xD3, 0xEB, 0x3E, 0xC3, 0x6E, 0x33, 0x4C, 0x9F,
	0x98, 0x8C, 0xE2, 0xC0, 0xB8, 0x59, 0x54, 0x61,
	0x0D, 0x2B, 0xCF, 0x86, 0x64, 0x84, 0x4D, 0xF2,
	0xAB, 0x56, 0xE6, 0xC6, 0x1B, 0xB7, 0x01, 0xE4
};

正常CASE:正确密钥读取

1. 创建密钥文件 (rpmb_key.bin)

您可以使用 echoxxd 命令组合来创建密钥文件。

echo -n -e '\xd3\xeb\x3e\xc3\x6e\x33\x4c\x9f\x98\x8c\xe2\xc0\xb8\x59\x54\x61\x0d\x2b\xcf\x86\x64\x84\x4d\xf2\xab\x56\xe6\xc6\x1b\xb7\x01\xe4' > rpmb_key.bin

使用 mmc rpmb read-block 命令读取 RPMB 数据块,并指定密钥文件。

假设您要读取地址为 0x02 的 2 个数据块,并将数据保存到 rpmb_data.bin 文件中,命令如下:

mmc rpmb read-block /dev/mmcblk0rpmb 0x02 2 rpmb_data.bin rpmb_key.bin

512

可以正常读出来。

异常CASE:错误的密钥读取

1. 準備一個錯誤的密鑰
首先,我們需要準備一個與正確密鑰不同的錯誤密鑰。為了方便起見,我們可以簡單地將正確密鑰的最後一個字節更改為不同的值。

# 複製正確的密鑰文件
cp rpmb_key.bin rpmb_wrong_key.bin

# 修改最後一個字節
dd if=/dev/urandom of=rpmb_wrong_key.bin bs=1 seek=31 count=1 conv=notrunc

這將創建一個名為 rpmb_wrong_key.bin 的文件,其中包含一個與正確密鑰只有最後一個字節不同的錯誤密鑰。

2. 使用錯誤的密鑰讀取 RPMB 數據塊

現在,我們可以使用 mmc rpmb read-block 命令和錯誤的密鑰來讀取 RPMB 數據塊。

mmc rpmb read-block /dev/mmcblk0rpmb 0x02 2 rpmb_wrong_data.bin rpmb_wrong_key.bin

image.png512

读取counter

mmc rpmb read-counter 命令不需要密鑰。

root@j784s4-evm:~# mmc rpmb read-counter /dev/mmcblk0rpmb
Counter value: 0x0000000a

2. OPTEE-OS Secure Storage

RPMB(Replay Protected Memory Block)和 OP-TEE OS 的 secure storage 之间有着密切的关系,主要体现在 OP-TEE OS 可以利用 RPMB 作为其安全存储的底层实现之一,以提供更高级别的安全性和防回滚保护。

OP-TEE OS 提供了两种主要的 secure storage 实现方式,用于存储 Trusted Application(TA)的持久化数据:

  • REE 文件系统(默认实现):通过 CFG_REE_FS=y 启用,数据存储在非安全世界(REE,Rich Execution Environment)的文件系统中,例如 Linux 的 /data/tee/ 目录。数据会经过加密和完整性保护,但依赖 REE 的存储,安全性较低。 image.png512

  • RPMB 分区:通过 CFG_RPMB_FS=y 启用,数据存储在 eMMC 设备的 RPMB 分区中。RPMB 是一种硬件支持的安全存储区域,提供防篡改和防重放保护,安全性更高。

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions