6.4. 镜像格式
BROM 在启动过程中解析专有的启动镜像,第一级引导程序的镜像格式必须符合下表的要求。
数据区域 |
数据分块 |
字段 |
字节 |
描述 |
---|---|---|---|---|
Signed Area |
Block1 (256B) |
Magic |
4 |
特征字符串,固定为 ”AIC ” |
Checksum |
4 |
32 bit 累加和校验的校验值。安全启动方案设为0. |
||
Header version |
4 |
本文件头结构的版本号,当前版本为v1.0: 0x00010001 |
||
Image length |
4 |
从文件开头到结束的总数据长度 |
||
Firmware version |
4 |
固件版本号,不同版本之间应单调递增 |
||
Loader length |
4 |
第一级引导程序的有效数据的长度,不包括填充数据 |
||
Load address |
4 |
镜像数据加载到内存的目标地址 |
||
Entry point |
4 |
第一级引导程序的可执行代码入口地址 |
||
Signature algorithm |
4 |
0:没有签名,仅计算Checksum;1:RSA-2048; |
||
Encryption algorithm |
4 |
0:固件不加密;1:AES-128-CBC 加密 |
||
Signature result offset |
4 |
数字签名数据区域的偏移,从文件头开始计算 |
||
Signature result length |
4 |
数字签名的长度 |
||
Signature key offset |
4 |
RSA 公钥数据区域的偏移 |
||
Signature key length |
4 |
RSA 公钥数据的长度 |
||
IV data offset |
4 |
AES-CBC IV数据区域的偏移 |
||
IV data length |
4 |
IV 的长度 |
||
Private data offset |
4 |
第一级引导程序私有数据区域的偏移 |
||
Private data length |
4 |
第一级引导程序私有数据区域的长度 |
||
PBP offset |
4 |
PBP 数据区域的偏移 |
||
PBP length |
4 |
PBP 数据的长度 |
||
Loader ext offset |
4 |
扩展的 Loader 内容的开始存放位置 |
||
Padding |
172 |
填充,使得头部刚好 256 字节 |
||
Block2 |
Loader binary data |
X |
第一级引导程序的保存区域 |
|
Padding |
X |
增加填充,使得 256 字节对齐 |
||
Block3 |
Private data area |
X |
存放镜像代码中可能使用的私有数据。 |
|
Signature key area |
X |
存放 RSA 公钥,DER 格式的密钥文件。应4字节对齐。 |
||
IV data area |
16 |
存放 AES IV 数据,16字节。应4字节对齐。 |
||
PBP area |
X |
存放 PBP 程序。应16字节对齐。 |
||
Padding |
X |
填充,使得 256 byte 对齐,方便计算数字签名 |
||
Block4 |
Signature result area |
256 |
前面所有内容的数字签名 |
这里所描述的启动镜像是 BROM 读取的第一级引导程序 (First Stage Boot Loader),当前方案第一级引导程序为u-boot-spl。 BROM 需要启动镜像提供必要的信息,以帮助 BROM 做初始化,并且找到正确的引导代码运行。在打开安全启动的情况下, 还需要提供必要的信息以帮助 BROM 对镜像进行签名认证,甚至对相关数据段进行解密。 这里的安全镜像格式固定前面 256 字节保存相关的信息,第一级引导程序的内容固定存放在 Block2 区域中。
在非安全启动的应用中,Block3, Block4的内容是不需要的。
在安全启动的应用中,如果方案中需要对第一级引导程序进行加密,则只需要加密 Block2 的内容。 安全启动的应用中,总是需要对 Block1/Block2/Block3 的数据进行签名。 在签名和加密都使能的情况下,PC 工具总是先对 Block2 进行加密,再对 Block1/Block2/Block3 进行签名。
备注
RSA 签名,使用的签名方案为 RSASSA-PKCS1-v1_5。具体格式参考 《RFC 3447》第9.2章节。
6.4.1. 校验值的计算
在不打开安全启动的情况下,BROM 需要使用 Checksum 对读取的固件数据进行校验,Checksum 的计算和校验方法如下:
计算的方法
首先将固件的 check sum 字段置为0;然后按照32 bit 的方式计算整个固件的累加和;将累加和的值按位取反,然后填写到 check sum 字段中。校验的方法
将固件按照32 bit 的方式,计算整个固件的累加和;累加和的结果应该是 0xFFFFFFFF, 或者加1应该是0;如果不是,则校验失败。
load_address 和 entry_point 如果设置为0,则表示当前固件应在当前位置运行,并且 entry_point 就在 Block2 区域的开始位置。
6.4.2. 版本号信息
固件的版本号格式为:Major.Minor.Revision 与版本号相对应的还有一个防回滚版本计数值(Anti-Rollback Version Counter),每一次版本变更,该计数值都应该累加1。 在使能固件防回滚功能时,BROM 会检查该值。
上述版本信息在镜像格式头(Firmware version)中的存放顺序如下:
名字 |
字节 |
说明 |
---|---|---|
Anti-Rollback Version Counter |
1 |
第一字节,防回滚版本计数值,应从1开始计数 |
Revision |
1 |
第二字节,修改编号 |
Minor |
1 |
第三字节,小版本号 |
Major |
1 |
第四字节,主版本号 |
备注
固件版本号是给用户填写,用来进行固件版本管理使用的。BROM 程序不会对固件版本号的 Major.Minor.Revision 值进行检查。
但在使能 Anti-Rollback 功能时,BROM 会检查 Anti-Rollback Version Counter 值。