RPMB详解

article/2025/10/16 9:00:22

这里写自定义目录标题

  • RPMB详解
    • 1. 简介
      • 1.1. 概述
      • 1.2. 基本原理
    • 2. 命令需求
    • 3. 用于RPMB访问的数据帧
    • 4. RPMB的组成
    • 5. mac计算
    • 6. 访问流程
      • 6.1. 写认证密钥(write Authentication Key)
      • 6.2. 读计数器值(Reading of the Counter Value)
      • 6.3. 写认证数据(Authenticated Data Write)
      • 6.3. 读认证数据(Authenticated Data Read)
      • 6.4. 写认证设备配置(Authenticated Device Configuration Write)
      • 6.5. 读认证设备配置(Authenticated Device Configuration Read)

RPMB详解

1. 简介

1.1. 概述

RPMB(Replay Protected Memory Block重放保护内存块)Partition 是 eMMC 中的一个具有安全特性的分区。eMMC 在写入数据到 RPMB 时,会校验数据的合法性,只有指定的 Host 才能够写入,同时在读数据时,也提供了签名机制,保证 Host 读取到的数据是 RPMB 内部数据,而不是攻击者伪造的数据。

RPMB 在实际应用中,通常用于存储一些有防止非法篡改需求的数据,例如手机上指纹支付相关的公钥、序列号等。RPMB 可以对写入操作进行鉴权,但是读取并不需要鉴权,任何人都可以进行读取操作,因此存储到 RPMB 的数据通常会进行加密后再存储。

1.2. 基本原理

RPMB提供了对重播保护内存块的签名访问。此功能为系统提供了以经过身份验证和重放保护的方式将数据存储到特定存储区域的方法 。这是通过第一个编程身份验证密钥信息提供给eMMC内存(共享秘密)。

由于在此阶段还不能对系统进行身份验证,因此身份验证密钥编程必须在像OEM生产中那样的安全环境中进行。此外,认证密钥用消息认证码(MAC)对重放保护内存区域进行的读写访问进行签名。

随机数生成和计数寄存器的使用提供了额外的保护,防止消息回放,消息可以被攻击者记录和回放。

2. 命令需求

  • CMD18
    • 缩写词:READ_MULTIPLE_BLOCK
    • 参数:[31:0] data address
    • 描述:连续将数据块从设备传输到主机,直到被停止命令中断,或传输请求的数据块数如果作为打包读命令的一部分发送,参数应包含包中的第一个读数据地址(包内的第一个单独读命令的地址)。
  • CMD23(default)
    • 缩写词:SET_BLOCK_COUNT
    • 参数:
      • [31] Reliable Write Request
      • [30] ‘0’ non- packed
      • [29] tag request
      • [28:25] context ID
      • [24]: forced programming
      • [23:16] set to 0
      • [15:0] number of blocks
    • 描述:定义块读或写命令的块数(读/写)和可靠的写入器参数(写入)。
  • CMD25
    • 缩写词:WRITE_MULTIPLE_BLOCK
    • 参数:[31:0] data address
    • 描述:连续写入数据块,直到出现STOP_TRANSMISSION或收到请求的块数。如果作为打包命令(打包写入或打包读取的标题)发送,则参数应包含包中的第一个读/写数据地址(包中第一个单独命令的地址)。

3. 用于RPMB访问的数据帧

在这里插入图片描述

  • Request/Response Type:定义内存的请求和响应类型。表18列出了已定义的请求和响应。响应类型对应于以前的RPMB读/写请求。在这里插入图片描述

  • Authentication Key / Message Authentication Code (MAC) :根据请求/响应类型,认证密钥或消息认证码(MAC)。MAC将在最后一个(或唯一的)数据块中交付。

  • Operation Result:包括有关写计数器的状态(有效、过期)和对重播保护内存块的访问成功的信息。表19为RPMB操作结果数据结构。表20列出了已定义的结果和可能的故障原因。 在这里插入图片描述
    在这里插入图片描述

  • Write Counter:主机写认证数据成功次数和写认证设备配置次数之和的计数器值。

  • Data Address:要编程或从重播保护内存块读取的数据的地址。地址是被访问的半扇区的序列号(256B),第一个地址是0x0000 。CMD 18和CMD 25中的地址参数将被忽略。

  • Nonce:由主机为请求生成的随机数,并由RPMB引擎复制到响应中。

  • Data:要通过签名访问权限写入或读取的数据。

  • Block Count:要求读取/编程的块数(半扇区,256B)。此值等于CMD23参数中的计数值。

4. RPMB的组成

  • 认证密钥(Authentication Key)
    • 大小:32Byte
    • 类型:一次写入(与主机交互,只能写一次)
    • 描述:一次性可编程认证密钥寄存器。此寄存器不能被主机覆盖、擦除或读取。在设备生产过程中写入,当计算MAC时,eMMC重播保护内存块引擎用来验证访问。
  • 写入计数器(Write Counter)
    • 大小:4Byte
    • 类型:只读(与主机交互,是只读的)
    • 描述:主机写认证数据成功次数和写认证设备配置次数之和的计数器值。eMMC生产后的初始值为0x000000000。值将由eMMC重播保护内存块引擎与成功的编程访问。无法重置该值。当计数器达到其最大值0x FFFF FFFF后,它将不再增加(防止溢出),数组帧中操作结果(result)的位[7]值将被永久设置为1,表示计数器过期。
  • 数据(data)
    • 大小: 最小128kB (RPMB_SIZE_MULT x 128kB)
    • 类型:可读可写(与主机交互,是可读可写的)
    • 描述:只能通过成功验证的读写访问来读写的数据。此数据可能会被主机覆盖,但永远无法被擦除。

5. mac计算

协议规定算法选sha256.
mac = HMAC(Authentication Key, data + Nonce + Write + Counter + Address + Block + Count + Result + Req/ Resp );

6. 访问流程

6.1. 写认证密钥(write Authentication Key)

认证密钥在生产阶段的时候写入。

认证密钥使用写多块命令CMD25进行编程。在命令CMD25之前,CMD23将块计数设置为1,参数位[31]设置为1,以表示编程的可靠的写类型。如果块计数未设置为1和/或参数位[31]未设置为1,则随后的写多块命令必须失败,并且应指示一般失败( General Failure)。

应该通过读取重播保护内存块的结果寄存器来检查键的编程是否成功。结果读取序列由写多块命令CMD25启动。在CMD25之前,CMD23将块计数设置为1。如果块计数未设置为1,则随后的写入多块命令必须失败,并且应指示常规失败( General Failure)。

如果身份验证密钥的编程成功,则返回的结果为0x00。如果身份验证密钥的编程失败,则返回的结果为0x05(写入失败)。如果在身份验证密钥编程过程中出现其他错误,则返回的结果为0x01(一般失败)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.2. 读计数器值(Reading of the Counter Value)

计数器读取序列由写多块命令CMD25启动。在CMD25之前,CMD23将块计数设置为1。如果块计数未设置为1,则随后的写入多块命令必须失败, 并且应指示常规失败。

如果读取计数器值成功,则返回的结果为0x00(读取失败)。如果读取计数器值失败,则返回的结果为0x06(读取失败)。如果发生其他错误,则结果为0x01(一般故障)。如果计数器已过期,则返回结果中的第7位也被设置为1(结果值分别为0x80、0x86和0x81)。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

6.3. 写认证数据(Authenticated Data Write)

重播保护内存块的数据用写多块命令CMD25编程。在命令CMD25之前,块计数由CMD23设置,参数位[31]设置为1,表示编程访问的可靠写类型。块计数是要编程的半扇区的数目(256B)。

RPMB写访问支持的数据大小由EN_RPMB_REL_WR(EXT_CSD[166]位)决定。一次RPMB写访问中的整个数据是原子的,应包含旧数据或新数据。每个RPMB写访问的 起始地址应与相应的RPMB写访问的传输大小对齐。

EN_RPMB_REL_WR=0:RPMB分区支持两种不同的大小:256B(单个512B帧)和512B(两个512B帧)。

EN_RPMB_REL_WR=1:RPMB分区支持三种不同的大小:256B(单个512B帧)、512B(2个512B帧)和8KB(32个512B帧)。

如果没有设置块计数,并且/或参数位[31]没有设置为1和/或大小与EN_RPMB_REL_WR定义的支持的数据大小不同,则随后的写入多块命令必须失败,并指示一般故障。
在这里插入图片描述
当eMMC收到此消息时,它首先检查写计数器是否已经过期。如果写计数器已过期,则eMMC将结果设置为0x85(写失败,写计数器已过期)。没有任何数据被写入到eMMC中。

接下来,将检查该地址。如果在地址中出现错误(超出范围),则该结果将设置为0x04(地址失败)。在多个块写入的情况下,如果数据地址没有与其自己的数据大小对齐,则结果被设置为0x04(地址失败)。没有任何数据被写入eMMC。如果写计数器未过期,则通过字节[283:0]计算MAC(请求类型、结果= 0x00、块计数、写计数器、地址、一次= 0x00和数据),并将其与请求中的MAC进行比较。

如果两个MAC不同,则eMMC将结果设置为0x02(身份验证失败)。没有任何数据被写入eMMC。

如果请求中的MAC和计算出的MAC相等,那么eMMC将请求中的写计数器与存储在eMMC中的写计数器进行比较。如果两个计数器不同,则eMMC将结果设置为0x03(计数器失败)。没有任何数据被写入eMMC。如果MAC和写计数器比较成功,则认为写请求进行身份验证。来自请求的数据被写入请求中指示的地址,并且写计数器增加1。

如果写入失败,则返回的结果为0x05(写入失败)。如果在写入过程中发生了其他错误,则返回的结果为0x01(一般失败)。

主机应该通过读取重播保护内存块的结果寄存器来检查数据的编程是否成功。结果读取序列由写多块命令CMD 25启动。在CMD25之前,CMD23将块计数设置为1。如果块计数未设置为1,则随后的写入多块命令必须失败,并且应指示常规失败。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.3. 读认证数据(Authenticated Data Read)

数据读取序列由写多块命令CMD25启动。在CMD25之前,CMD23将块计数设置为1。如果块计数未设置为1,则随后的写入多块命令必须失败,并且应指示常规失败。
在这里插入图片描述
当eMMC收到此请求时,它首先检查该地址。如果地址有错误(超出范围),则结果设置为0x04(地址失败)。数据读取操作无效。通过“多读取块”命令CMD18读出数据本身。在读取命令之前,块计数由CMD23设置。

块计数是要读取的半扇区的数量(256B)。如果未设置块计数,则读取多块命令必须失败,并且应指示一般故障。MAC按字节[283:0]计算(响应类型、一次、地址、块计数、写计数器= 0x00、数据和结果)。如果MAC计算失败,则返回的结果为0x02(身份验证失败)。
在这里插入图片描述
如果从eMMC内的寻址位置获取数据失败,则返回的结果为0x06(读取失败)。如果在读取过程中出现其他错误,则返回的结果为0x01(一般故障)。
在这里插入图片描述

6.4. 写认证设备配置(Authenticated Device Configuration Write)

设备配置区域通过RPMB过程使用写多块命令CMD25编程。在命令CMD25之前,块计数由CMD23设置,参数位[31]设置为1 ,表示编程访问的可靠写类型。块计数是要编程的半扇区数(256B),且块计数应为0x1。因此,只使用一个256B (单512B帧)。如果块计数和参数位[31]未设置为1,则随后的写多块命令将失败,并在RPMB操作结果中显示一般故障。

该地址是要更新的设备配置寄存器的索引,即0x0001或0x0002为有效索引。请求类型值0x0006表示对数据的编程。
在这里插入图片描述
当eMMC收到此消息时,它首先检查写计数器是否已经过期。如果写计数器已过期,则eMMC将结果设置为0x85(写失败,写计数器已过期)。没有任何数据被写入到eMMC中。

如果主机访问预留区域(地址[0]和地址[3~255]),则设备不应返回错误。没有任何数据被写入eMMC。如果写计数器未过期,则通过字节[283:0](请求类型、结果= 0x00、块计数、写计数器、地址、nonce= 0x00和数据)计算MAC,并将其与请求中的MAC进行比较。如果两个MAC不同,则eMMC将结果设置为0x02(身份验证失败)。没有任何数据被写入eMMC。

如果请求中的MAC和计算出的MAC相等,那么eMMC将请求中的写计数器与存储在eMMC中的写计数器进行比 较。如果两个计数器不同,则eMMC将结果设置为0x03(计数器失败)。没有任何数据被写入eMMC。

如果MAC和写计数器比较成功,则认为写请求进行身份验证。来自请求的数据被写入由请求中的地址指示的设备配置区域,并且写入计数器被增加1。

如果写入失败,则返回的结果为0x05(写入失败)。如果在写入过程中发生了其他错误,则返回的结果为0x01(一般失败)。主机应该通过读取重播保护内存块的结果寄存器来检查数据的编程是否成功。结果读取序列由写多块命令CMD 25启动。在CMD25之前,CMD23将块计数设置为1。如果块计数未设置为1,则随后的写入多块命令将失败,并应在RPMB操作结果中显示一般故障。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.5. 读认证设备配置(Authenticated Device Configuration Read)

经过验证的设备配置读序列由写多块命令CMD25启动。在CMD25之前,CMD23将块计数设置为1。如果块计数未设置为1,则随后的写入多块命令将失败,并且在RPMB操作结果中应显示一般故障。
在这里插入图片描述
在读取命令之前,块计数由CMD23设置,块计数应设置为0x1。如果块计数未设置为0x1,则读取多块命令将失败,并应在RPMB操作结果中显示一般故障。
在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/byyrUEq7.shtml

相关文章

python项目使用setuptools和rpmbuild构建rpm包

python项目使用setuptools和rpmbuild构建rpm包 文章目录 python项目使用setuptools和rpmbuild构建rpm包一、setuptools二、使用rpmbuild,编写.spec文件构建rpm包三、使用pyinstaller四、参考文献: 一、setuptools 作为 Python 标准的打包及分发工具&…

rpm(基本命令、Makefile、建立rpmbuild编包)

文章目录 一、rpm基本命令介绍1.安装软件2、升级软件3、查询软件包的详细信息4、查询某个文件是属于那个rpm包的5、查该软件包所包含的文件6、查看软件包所依赖的软件7、查看某个包是否被安装8、卸载 二、rpm命令实践三、把c语言程序和makefile内容,编译情况和执行情…

rpmbuild制作rpm 包

什么是rpm包? rpm 相当于windows中的安装文件,它会自动处理软件包之间的依赖关系。 rpm优点: 包管理系统简单,通过几个命令就可以实现包的安装、升级、卸载。 安装速度比源码包快的多。缺点: 经过编译&#xff0c…

项目打包rpm包(rpmbuild)

这里以python项目为例,通过rpmbuild工具打包成rpm包,并进行安装验证 rpmbuild打包 rpm流程 构建rpmbuild打包目录 rpmbuild 默认变量配置文件 将我们的python项目和依赖包压缩成xx.tar.gz格式,并copy到SOURCE目录 我们这里以datalake-demo…

前向星和链式前向星

链接:https://blog.csdn.net/ACdreamers/article/details/16902023 我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序, 并记录下以某个点为起点的所有边在数组中的…

关于链式前向星

最近看了许多题目都用了比较奇怪的东西… 后面才发现是神奇的链式前向星….. 听名字就觉得很牛啊! 然而其实很简单…… 组成:begin,next,to,w,与一个用来标记的e begin[n]数组:代表编号为n的点,最后一条边的储存位置 next[n]:是用来保存从同一个点…

链式前向星(加快图的搜索)

存储一个图通常有两种方式:邻接矩阵和邻接表。如果一个图中的边非常少,那么邻接矩阵就比较稀疏,浪费空间,如果点非常多,则矩阵的内存有可能会爆掉。用向量实现的邻接表在点非常多的时候同样比较慢,在一些题…

链式前向星存储图

第七天链式前向星存图 图片如下所示 本代码存的是有向图&#xff0c;图示为无向图。 #include<iostream> using namespace std; const int maxn 100; struct node//to 边的终点编号&#xff0c;w 权值&#xff0c; next 以 x 为起点的上一条边的编号 {int to,w,next;…

链式前向星存图 详细解析

文章目录 链式前向星完整代码 链式前向星 链式前向星是一种图的存储方式&#xff0c;相比于 邻接矩阵和邻接表 &#xff0c;链式前向星是一种静态链表存储&#xff0c;用边集数组和邻接表相结合&#xff0c;可以快速访问一个顶点的所有邻接点。 在某些算法题中使用还很频繁&a…

C++之链式前向星

链式前向星 基本定义以及实现链式前向星实现DFSBFS 基本定义以及实现 (若果有一定了解&#xff0c;可以跳过第一部分&#xff0c;直接看第二部分) 我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按…

图的存储 —— 链式前向星

图的存储 —— 链式前向星 链式前向星采用了一种静态链表存储方式&#xff0c;将边集数组和邻接表相结合&#xff0c;可以快速访问一个节点的所有邻接点&#xff0c;在算法竞赛中被广泛应用。 链式前向星有如下两种存储结构。 边集数组&#xff1a;edge[]&#xff0c;edge[i…

简述链式前向星

一、前言 我们常见的存图数据结构有两种&#xff0c;一种是邻接矩阵&#xff0c;另一种是邻接表。而在邻接矩阵中&#xff0c;空间复杂度为 O ( n 2 ) O(n^2) O(n2)&#xff0c;在稀疏图的情况下&#xff0c;相较于邻接表浪费了许多空间。而常规的邻接表是用链表进行操作&…

链式前向星 详解

链式前向星 链式前向星是一种类似于邻接表的存图方式&#xff0c;同样适用于有向 图和无向图。 他建立的是边与边之间的联系 它将边里的所有边都进行编号 int cnt; //边的编号 struct edge{ //边的结构体int from,to,w,next; //from是边的起点&#xff08;这个可有可无&a…

用链式前向星存储图

图最常用的存储结构主要是邻接矩阵和邻接表。当顶点数太大时&#xff0c;用二维数组表示的邻接矩阵可能超内存&#xff08;MLE&#xff09;&#xff0c;而用邻接表的编码工作量较大&#xff0c;此时&#xff0c;使用vector数组或链式前向星模拟邻接表是不错的选择。因vector数组…

链表、链式前向星

讲链表的时候就卡在这里了&#xff0c;最短路又卡在链式前向星上了&#xff0c;毕竟是图论基础&#xff0c;觉得还是有必要写一写防止下次再懵。 链表都是头插法&#xff01;&#xff01;即每次我们给他插一个头。 普通链表 先初始化令head-1,idx-1. void add_tohead(int x…

链式前向星(详细讲述)

在dalao的压迫下本蒟蒻发个博客&#xff0c;给大家讲一下链式前向星&#xff08;新手&#xff0c;写错了轻喷&#xff09; 首先说明一点链式前向星适合于稀疏图&#xff0c;而邻接矩阵则更适合稠密图&#xff0c;所以最好看好数据范围再决策使用哪个方法&#xff0c;当然有些题…

链式前向星与邻接表对比

本文图片及数据 对于这样一张有向图&#xff1a; 输入边的顺序如下&#xff1a; 1 2 2 3 3 4 1 3 4 1 1 5 4 5 对于邻接表来说是这样的&#xff1a; 1 -> 2 -> 3 -> 5 2 -> 3 3 -> 4 4 -> 1 -> 5 5 ->^ 对于链式前向星来说是这样的&…

链式前向星存图(有图详解)

链式前向星:既然是链式那么肯定和链表相关,前向星是每次指向都向前 链式前向星存图是以边为中心,并不是以结点为中心,它记录的是边的一些属性,包括边边的id、头节点、尾结点、权值、边的指向! 边的指向是遍历图的时候需要按照一定顺序去遍历,而不能胡乱的去遍历,那么就需要这些…

链式前向星的详解

目录 1&#xff1a;链式前向星的概念解释 2&#xff1a;代码展现 链式前向星是一种非常好用的有向图存储方式&#xff0c;但是它的代码难度却有点大。作者在这上面花了很长的时间才弄懂。虽然有其他的博客大佬写的很好&#xff0c;但总感觉不太适合小白选手&#xff08;比如说…

链式前向星基本原理

一、概述 我们在学习图论的时候学习了一种图的存储结构--二维数组邻接矩阵储存&#xff0c;他虽然可以表达直观&#xff0c;快速访问连接两点的边&#xff0c;但是它占用空间大&#xff0c;只适用于点少的图&#xff0c;所以我们需要一种能够可以存储大型图的东西--链式前向星…