SCSI-8.UFS_RPMB
RPMB 介绍
**RPMB(Replay Protected Memory Block)**是一种基于硬件的安全存储区域,其结构设计旨在确保数据的机密性、完整性以及防重放攻击的能力。RPMB通常嵌入在eMMC、UFS等存储设备中,由专用硬件电路管理和访问。
在UFS里,有这么一个LU,四大LU之一,主机往该LU写数据时,UFS设备会校验数据的合法性,只有特定的主机才能写入;他相当于生活中宝箱,数据就是我们的财产,有些东西是放在公共区域的任何人都可以拿走,都可以访问,但是例如你的珠宝、房产证、黄金、你总不能放在一个公共空间让别人拿走吧,所以有一个非常非常私密的地方,一个密码宝箱,需要密码认证才能打开你珍贵的数据。同时,主机在读取数据时,也提供了校验机制,保证了主机读取到的数据是从该LU上读的数据,而不是攻击者伪造的数据,保证大家的老婆和财产。
RPMB的实现,类似于两个见不到面的人相互传递一个带锁的箱子,有钥匙的人才能打开。箱子上有个计数器,每打开一次,计数器就会加一这样来保证获取数据的正确性。
数据访问机制
RPMB的读写操作通过一套认证和计数器机制(密码)来保证安全性和完整性。它不同于传统存储的操作流程,访问RPMB的数据需要通过专门的命令集并满足以下要求:
- 认证机制:RPMB的所有操作(包括读写)都需要通过认证密钥进行验证。只有持有正确认证密钥的实体才能执行相应操作。这种认证方式通过消息认证码(Message Authentication Code,MAC)进行,确保只有授权实体能够访问RPMB。
- 计数器机制:每次写入操作必须包含一个递增的计数器值。RPMB内部会存储上一次操作的计数器值,每次写入数据时必须包含一个比当前计数器更高的值。该机制确保相同的操作不会重复执行,从而防止重放攻击。
- 数据完整性校验:每次写入的同时,RPMB会计算该数据的哈希值,用于校验数据的完整性。在后续的读取操作中,可以通过比较当前哈希值与存储的哈希值来检测数据是否被篡改或损坏。
数据访问流程
1.现在我淘金淘到了财宝,现在要把财宝放进宝箱,共享密钥就是自己宝箱的钥匙,准备好把数据放入宝箱。
2.在发送数据给设备之前,将数据和密钥组合使用哈希算法 生成消息验证码(Messages Authentication Code)。
3.UFS 主机将MAC 以及数据发送到UFS 设备
4.UFS 设备仍然会使用收到的数据和共享密钥作哈希运算,将计算的出的MAC 值和收到的MAC值进行对比,相同则进行存入操作,反则不进行相关操作。
数据访问流程实例
下面用 Python 代码演示这个过程,并说明当数据发生任何改变时,MAC 验证会失败。
pythonCopy codeimport hmac
import hashlib
# 定义共享密钥和数据
key = b"secret_key" # 共享密钥
message = b"Hello, World!" # 财宝(数据)
# 生成消息认证码(MAC)
mac = hmac.new(key, message, hashlib.sha256).hexdigest()
# 打印生成的MAC值
print(f"原始数据的 MAC: {mac}")
# 假设数据在传输过程中被篡改
tampered_message = b"Hello, World?" # 改动了一个字符
# 重新计算篡改后数据的MAC
tampered_mac = hmac.new(key, tampered_message, hashlib.sha256).hexdigest()
# 打印篡改后数据的MAC值
print(f"篡改数据的 MAC: {tampered_mac}")
# 比较原始 MAC 和 篡改后的 MAC
if mac == tampered_mac:
print("数据验证通过!")
else:
print("数据验证失败!")
输出结果
-
对于原始数据
"Hello, World!"
生成的 MAC 是:Copy code 原始数据的 MAC: 3e4a8052b6be0063b5adf31e36cfc67da54ab0f397f8e30200fa9f0f0d3f91a0
-
如果数据发生了轻微的变化,比如把
"Hello, World!"
改成"Hello, World?"
,即仅仅改变了一个字符,生成的 MAC 会完全不同:篡改数据的 MAC: 63d02dc59dbb5fc58c4cb27c54efefbc68b94792e04e36f6877bb322dc5b8e45
-
最终,UFS 设备会将原始 MAC 与重新计算的 MAC 进行对比。如果它们不相同,则数据验证失败。
重放攻击
注意:共享密钥不能被恶意攻击者获取,否则,恶意攻击者完全可以模拟主机行为:把自己的恶意数据和共享密钥生成MAC,然后把恶意数据和其对应的MAC发送给UFS设备。UFS设备会认证成功,恶意数据被写入。所以,保管好你的密码!
另外恶意攻击者可能会劫持你的数据,获得"主机数据 + MAC",攻击者可以一直不断发送这个命令,这样会有缓存会被写爆的风险。
所以我们不能束手就擒啊,所以就有了RPWB的措施:UFS维护了一个写计数(Write Counter),初始化为0。UFS设备每次成功处理完一个RPMB写命令,写计数加一。主机在往设备写入数据前,获得该计数。然后把用户数据和该计数一起做MAC计算。这样,即使恶意攻击者窃听到某次合法的“用户数据 + MAC”,往设备写入时,由于写计数发生变化,它无法生成写计数改变之后的MAC值,因此就无法一直重复往设备写入某次合法的“用户数据 + MAC”。
计数器是否在原生数据中?
- 计数器不是原生用户数据的一部分,它是由设备专门维护的一个值,用户无法直接控制或操作它。
- 当主机准备写入数据时,主机会先从设备读取当前的计数器值,然后在发送写入请求时携带这个值加 1 的计数器作为本次写入的计数器。
- 计数器的维护和更新是由设备的 RPMB 硬件或固件自动进行的,用户的数据本身不会包含计数器信息。
RPMB LU
RPMB与普通存储的对比
特性 | RPMB | 普通存储(如eMMC、UFS等) |
---|---|---|
访问方式 | 需要认证密钥和特殊命令 | 标准读写操作 |
防重放攻击 | 有计数器机制,防止重放攻击 | 无防重放机制 |
数据安全性 | 高,使用加密和认证保护 | 低,易于被篡改或攻击 |
应用场景 | 安全引导、密钥存储、金融应用等 | 常规数据存储 |
UFS2.1中,RPMB LU最小逻辑空间为128KB,最大为16MB。它的逻辑块大小为256B(普通LU逻辑块大小一般为4KB)。应用层不是通过普通的Read/Write命令读/写RPMB上的数据,而是通过SECURITY PROTOCOL OUT/IN命令来访问RPMB的。
数据帧大小是512字节,组成如下:
-
认证密钥(Key)是32字节;
-
1使用SHA-256计算MAC,就是任意长度的数据,产生的MAC值总是256比特,即MAC大小为32字节。
-
逻辑块数据大小为256字节。
-
写计数(Write Counter)为4字节,当该值涨到0xFFFF FFFF,它就保持不动,不会继续增长了。
-
Address,RPMB的逻辑地址,同LBA。两个字节,最多表示65536个逻辑块,每个逻辑块大小为256字节,因此RPMB逻辑空间最大为
-
Block Count,逻辑块数,即指定读写多少个逻辑块。
-
Result,RPMB操作结果(状态)。
ress,RPMB的逻辑地址,同LBA。两个字节,最多表示65536个逻辑块,每个逻辑块大小为256字节,因此RPMB逻辑空间最大为
-
Block Count,逻辑块数,即指定读写多少个逻辑块。
-
Result,RPMB操作结果(状态)。