在UFS里,有这么一个LU,主机往该LU写数据时,UFS设备会校验数据的合法性,只有特定的主机才能写入;同时,主机在读取数据时,也提供了校验机制,保证了主机读取到的数据是从该LU上读的数据,而不是攻击者伪造的数据。这个LU就是RPMB(Replay Protected Memory Block)LU,四大“名撸”(四个Well Known LU)之一。
有些人家里有保险箱,用以存放他们认为重要的东西,比如现金、存折、房产证、情书等。输入密码,打开密码箱,然后放东西进去;取的时候,首先需要密码打开保险箱,然后把东西取出。没有密码,老婆是万万看不到老公和他初恋之间的情书的。RPMB就像是手机里的密码箱,用户可以把一些重要数据存储其中。
我们来看看RPMB这个保险箱。
UFS主机通过认证(authenticated)的方式访问RPMB LU。下图展示了数据写过程:
- 首先,UFS主机和UFS设备共享密钥,该密钥在UFS设备出厂时就保存在UFS设备;
- UFS主机在发送主机数据给UFS设备前,会用该密钥和哈希算法生成消息认证码(Message Authentication Code, MAC);
- UFS主机把主机数据连同MAC一起发给UFS设备;
- UFS设备把收到的主机数据和共享密钥在本地重新计算MAC,然后把计算出的MAC和收到的MAC做对比,如果一致,则认证成功,写入到闪存;否则,拒绝该笔数据的写。
UFS使用HMAC(Hash-based Message Authentication Code)SHA-256算法生成消息认证码。HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。关于HMAC具体算法,可参看https://en.wikipedia.org/wiki/HMAC,我们这里不深入。
消息认证码本质是哈希值。哈希的一个特点是,即使只改变原数据一比特数据,两者的哈希值也是完全不同的。如果恶意攻击者在数据传输过程中篡改了用户数据,那么UFS设备根据收到的数据和共享密钥生成的MAC肯定与接收到的MAC不一样,认证通不过,数据就不会写入UFS设备。
这里的前提是共享密钥不能被恶意攻击者获取,否则,恶意攻击者完全可以模拟主机行为:把自己的恶意数据和共享密钥生成MAC,然后把恶意数据和其对应的MAC发送给UFS设备。UFS设备会认证成功,恶意数据被写入。所以,请保管好你的密码!
但是,恶意攻击者是狡猾的,即使他没有办法获得你的密钥,它还是有办法对你进行攻击的。
恶意攻击者监听到UFS主机和UFS设备之间某次数据传输,得到“主机数据 + MAC”,然后该恶意攻击者重复发送该“主机数据 + MAC”给UFS设备,由于“主机数据 + MAC”是合法的,认证通过,UFS设备就会接收该数据并写到闪存。恶意攻击者如果一直重复发这些数据给UFS设备,UFS设备RPMB LU将会被写爆!这就是重放攻击, Replay Attack。
RPMB的全名是:Replay Protection Memory Block,它的名字暗示了RPMB是能抵御重放攻击的。那么RPMB是怎么对付重放攻击的呢?
UFS维护了一个写计数(Write Counter),初始化为0。UFS设备每次成功处理完一个RPMB写命令,写计数加一。主机在往设备写入数据前,获得该计数。然后把用户数据和该计数一起做MAC计算。这样,即使恶意攻击者窃听到某次合法的“用户数据 + MAC”,往设备写入时,由于写计数发生变化,它无法生成写计数改变之后的MAC值,因此就无法一直重复往设备写入某次合法的“用户数据 + MAC”。魔高一尺,道高一丈,正义终战胜邪恶!
上面就是RPMB数据安全性背后的原理。下面再回到UFS RPMB协议上来。
UFS2.1中,RPMB LU最小逻辑空间为128KB,最大为16MB。它的逻辑块大小为256B(普通LU逻辑块大小一般为4KB)。应用层不是通过普通的Read/Write命令读/写RPMB上的数据,而是通过SECURITY PROTOCOL OUT/IN命令来访问RPMB的。
UFS主机在访问设备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操作结果(状态)。
下面举几个RPMB操作例子来理解上面的消息:
- 主机读取写计数
如前所述,写计数的目的是抵御重放攻击。写计数是UFS设备管理和维护的,UFS设备递增该计数。主机在写数据时,需要知道该计数,然后加上用户数据,一起计算MAC。
命令层发SECURITY PROTOCOL OUT/IN命令读取写计数,然后传输层生成相应的UPIU进行主机与设备之间的交互,具体见上图。
- 主机写认证数据
主机命令层通过SECURITY PROTOCOL OUT命令把用户数据和对应的MAC发送给设备,然后通过SECURITY PROTOCOL OUT请求获取前面数据写结果,最后通过SECURITY PROTOCOL IN读取写结果。写结果中包含新的写计数,这样下次主机利用新的写计数计算MAC。注意,只有本次写认证数据成功,设备才会递增该计数。
- 主机读认证数据
首先,主机通过SECURITY PROTOCOL OUT命令发送读取认证数据请求给设备,然后发送SECURITY PROTOCOL IN命令读取数据。
注意,主机读取数据也是需要认证的。在设备端,UFS设备会计算MAC,然后主机端根据MAC认证该数据。这样可以防止恶意攻击者在数据传输过程中(从设备到主机),用恶意数据更换原始数据。
RPMB提供了认证访问方式和抵御重放攻击的机制,保证了存储在RPMB LU上数据的安全。因此,用户可以把一些敏感和重要的信息写在RPMB上。在实际应用中,它通常用于存储一些有防止非法篡改需求的数据,例如手机上指纹支付相关的公钥、序列号等敏感信息。