hpm包格式说明以及重新签名指导

说明

openubmc升级真机环境时会验证hpm包的cms签名,确保软件包来源可信且完整。

本文档用于指定开发者完成hpm包签名。

  • 注意: 签名依赖的工具由bmcgo提供,openubmc社区版本的bingo还不支持签名。

签名hpm包格式

签名hpm包由包头、签名原文、CMS签名、CRL吊销列表、裸HPM包共五部分组成。

包头

包头记录了签名文件的数量和每个文件的大小,每8个字符组成一个大端的十六进制数字,格式为<file_count><file1_id><file1_len><file2_id><file2_len><file3_id><file3_len>

  1. <file_count>:表示签名由几个文件组成,当前格式签名由3个文件组成,故值一般为00000003
  2. <filex_id>:第x个文件的文件ID,从1开始编码,如文件1为00000001
  3. <filex_len>:第x个文件的文件长度。

例如:00000003000000010000001800000002000000280000000300000038表示签名由3个文件组成,每1个文件长度为0x18,第二个文件长度为0x28,第3个文件长度为0x38。

签名原文

内容是一段文本,内容由Manifest VersionCreate ByNameSHA256-Digest组成,其中:

  1. Manifest Version:一般为1.0
  2. Create By:签名者,一般为厂商包
  3. Name:文件名
  4. SHA256-Digest:裸HPM包的sh256

CMS签名

签名工具生成的cms签名文件

CRL吊销列表

签名根证书的吊销列表

hpm裸包

由hpm打包工具生成的裸包。

重签HPM包

某些场景我们需要将已签名的hpm包重新签名,需要执行以下步骤:

  1. 按文件头描述的依次从hpm包中剥离出包头、签名原文、CMS签名、CRL吊销列表、裸HPM包
  2. 修改签名原文,只能修改Create ByName
  3. 使用hpm_signer工具生成新的签名cms文件,同时需要签名根证书最新的CRL吊销列表文件。
  4. 将所有文件放置在同一目录并重命名文件,要求签名原文文件名为name.filelist、CMS签名文件名为name.filelist.cms、吊销列表为cms.crl、裸HPM包为name.hpm,其中name可以修改但要保持一致。
  5. 执行打包命令:cms_sign_hpm.sh 2 name.hpm,该命令会生成一个名为name.hpm.signed为签名hpm包。
  6. 正式升级的hpm包尾缀必须是.hpm,需要将name.hpm.signed重命名为name.hpm。

示例

假设有一个名为origin.hpm包的hpm包,其包头为00000003000000010000001800000002000000280000000300000038,重新签名流程:

# 导出name.filelist,文件大小为0x18(24字节),偏移为56
dd if=origin.hpm of=name.filelist bs=1 skip=56 count=24
# 导出name.filelist.cms,文件大小为0x24(40字节),偏移为80(56 + 24)
dd if=origin.hpm of=name.filelist.cms bs=1 skip=80 count=40
# 导出cms.crl,文件大小为0x38(56字节),偏移为120(80 + 40)
dd if=origin.hpm of=cms.crl bs=1 skip=120 count=56
# 导出hpm裸包,文件偏移为176(120 + 56),截取剩余内容
dd if=origin.hpm of=name.filelist bs=1 skip=176
# 执行签名,签名name.filelist文件并生成name.filelist.cms
hpm_signer -s signer.pem.enc -t ts_signer.pem.enc -T tsa.cnf -i name.filelist -o name.filelist.cms -p <签名证书加密密码>
# 重新打包,生成name.hpm.signed
cms_sign_hpm.sh 2 name.hpm
# 重命名
mv name.hpm.signed name.hpm
4 个赞

按文档已经重新签名了bios hpm包,在ubmc web界面已经可以更新了 :handshake:,以下是一些实践记录

#容器中文件所在路径

/usr/local/bin/mkhpm.sh
/usr/local/bin/hpm_signer

#新建/usr/local/bin/_hpm目录,专门用来签名包,文件如下

hpm_signer(从上级目录拷贝)
mkhpm.sh(从上级目录拷贝)
rootca.crl
serial
signer.pem
ts_signer.pem
tsa.cnf

#清除_hpm目录临时文件

rm -rf *.hpm
rm -rf bios.filelist
rm -rf bios.cms
rm -rf bios.crl
rm -rf bios.bin
rm -rf bios.cms1

#查看hpm包头信息
image
00000003 00000001 00000081 00000002 00000db1 00000003 000002ab
0x81 = 129
0xdb1 = 3505
0x2ab = 683

#生成新的hpm包

mv /workdir/bjuci_bios.hpm /usr/local/bin/_hpm

dd if=bjuci_bios.hpm of=bios.filelist bs=1 count=129 skip=56
dd if=bjuci_bios.hpm of=bios.cms bs=1 count=3505 skip=185
dd if=bjuci_bios.hpm of=bios.crl bs=1 count=683 skip=3690
dd if=bjuci_bios.hpm of=bios.bin bs=1 skip=4373

hpm_signer -s signer.pem -t ts_signer.pem -T tsa.cnf -i bios.filelist -o bios.cms1

mkhpm.sh bios.filelist bios.cms1 rootca.crl bios.bin bjuci_bios_new.hpm

mv bjuci_bios_new.hpm /workdir/

1 个赞

hpm_signer和mkhpm.sh不用拷贝,可以直接执行。

海军哥,这个是转华为或者其他厂商版本的过渡包的操作方法吗。

此方法主要用于像电源、风扇、cpld、bios、bbu等非bmc固件升级。

如果是BMC的固件,切换签名会比较复杂,我们需要将B签名的根证书导入到环境,A签名过渡到B签名的流程请参考:

  1. 将B签名的根证书预置到opt/bmc/trust/partner/rootca.der,使用A签名出hpm包。
    注意:如果是华为的签名可以从官方网站下载,链接是https://support.huawei.com/pki/pkidetail!loadCatagoryPkiData.action?type=PKI_TYPE-ROOT,证书名为Huawei Integrity Root CA - G2
  2. 升级A签名的hpm包。
  3. 升级B签名的hpm包。

上述步骤中的第二步会将B根证书升级到环境上,第三步的升级程序将在校验cms签名时执行双根校验,B签名的固件也能通过校验。

2 个赞


海军哥,没有这路径opt/bmc/trust/partner/,只能看到opt/bmc/trust/路径

了解一下manifest.yml同级目录的rootfs,里面的内容会原样打包到环境上。

1 个赞

谢谢海军哥指导。珊瑚灌顶。牛蛙。给你个大赞

海军哥,请问现在社区版本docker镜像swr.cn-north-4.myhuaweicloud.com/openubmc/ubuntu:24.04.1里的bingo支持签名了吗?

想请教一下,对于没有做成hpm包格式的文件,比如一个.bin文件,可以自己制作一个.filelist的签名原文进行制作吗?但是我看签名原文中有
SHA256-Digest: 46e2c24737e9df576a02a673eff9053c94822d99ceb8becf99f124f82a2b288a
以及一些未知二进制内容
在没有hpm文件的情况下不知道.filelist文件应该怎么制作,或者换一个方式,.bin文件如何打包为带签名的hpm包

制作hpm的源码实现在`bmcgo/tasks/task_sign_and_pack_hpm.py`。

你好,请问这个mkhpm.sh包是在哪里获取的,我使用25.09的环境没有这个脚本

刚看了下2509开发容器里确实没这个脚本了,不过脚本内容就是主题帖子中的示例代码,可以参考自行创建一个。

1 个赞