跳转至

Sigmastar Secureboot_debugsop手册

REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 03/06/2024


    1. 签章流程说明

    1.1 签章和验签相关的Key说明

    • private-otp.pem用于对IPL签章

    • 将public-otp.pem烧录到OTP,在ROM code中用于验签IPL

    • private-cust.pem用于对IPL_CUST签章

    • 将public-cust.pem插入到IPL中,在IPL flow用于验签IPL_CUST

    • private-image.pem用于对 UBOOT/TFA/SMF/OPTEE/Kernel签章

    • 将public-image.pem插入到IPL_CUST中,在IPL_CUST flow用于验签UBOOT/TFA/SMF/OPTEE

    • UBOOT下读取IPL_CUST中public-image.pem对Kernel/rootfs等进行验签

    1.2 IPL

    1.2.1 未签章的IPL.bin

    • Branch Command(4byte)放的是一条指令,用来让程序指针直接跳到IPL 的Plain text部分,因为IPL的前32字节是IPL header,并没有程序,所以不需要执行。

    • Magic(4byte)用来标识文本类型,IPL的Magic为0x5F4C5049,对应的Ascii字符是IPL_。

    • IPL Size(2byte)保存整个IPL.bin文件的大小,若IPL Version>=5,则真实IPL Size = header保存的IPL Size << 4。

    • Customer ID(1byte)保存客户ID

    • AUTH(1byte)为0xFA,则进入调试模式,调试模式下即使OTP中的Secure Boot栏位没启用,ROM也会对IPL进行验签。

    • CheckSum(2byte)是对IPL.bin中的plain text+end部分进行计算得到的一个校验和数据,用来防止IPL数据在传输过程中出现错误。如果plain text变了,Checksum也会变化。

    • IPL Version(1byte)版本号,当前版本为05,05及之后的版本,实际的IPL Size需要将header中的IPL Size数据右移4位。

    • Anti_rollback Version(1byte)防回滚版本号,防回滚机制,其目的是为了防止IPL/IPL_CUST/TF-A/OPTEE/UBOOT/KERNEL降级到以前的版本

    • IV Value(16byte),用于AES CBC和CTR模式下的解密。

    • IPL Plain text,IPL.bin的 Payload Data(有效数据)。

    • Plain text END byte(16byte)为IPL Payload Data的结束标志符,总共16byte,固定为[12byte0x00+(_LPI)]。

    1.2.2 签章的IPL.bin

    签章的IPL对比未签章的IPL

    1. header部分

      (a) IPL Size变化,增加RSA Public N Key的Size,Key Size取决于对IPL_CUST做签章时用的2048(256byte)的Key,还是4096(512byte)的Key。

      (b) Checksum变化,因为PlainText和END间新增Public N Key数据,重新计算校验值

    2. Plain Text

      (a)在Plain Text和END之间增加Public N Key数据,Key数据大小取决于对IPL_CUST做签章时的私钥大小

    1.2.3 IPL设置调试模式

    通过将IPL header第11byte的AUTH位设为0xFA,进入调试模式,调试模式下即使OTP中的Secure Boot栏位没启用,ROM也会对IPL进行验签。

    ./add_ipl_header.py ./IPL.cipher.bin ./IPL.cipher2.bin 0 1 // 调试模式

    ./add_ipl_header.py ./IPL.cipher.bin ./IPL.cipher2.bin 0 0 // 正常模式

    对比header:可以看到,只有AUTH位从0x00变为0xFA,其他均无变化

    1.2.4 签章加密的IPL bin结构

    只有plaintext部分参与加密,其他位置不参与,并且加密时,如果plaintext非16byte对齐,则会给plaintext填充0到16byte对齐后,再进行加密

    1.2.5 IPL签章指令说明

    (1) 插入rsa key到IPL中,这把key用于对IPL_CUST验签

    tools/key_proc.py --insert --rsa=tools/../rsa2048/public-cust.pem --IV=tools/../aeskey/IV.bin -f sboot_sign/IPL.bin

    (2) 设置调试模式

    tools/add_ipl_header.py sboot_sign/IPL.cipher.bin sboot_sign/IPL.cipher2.bin 0 1 0 0

    (3) 对IPL进行加密

    tools/key_proc.py --encrypt --encAlg=aes --mode=cbc --IV=tools/../aeskey/IV.bin --aes=tools/../aeskey/aesKey128_1.bin -f sboot_sign/IPL.cipher2.bin

    (4) 对IPL进行签章

    tools/key_proc.py --sign --rsa=tools/../rsa2048/private-otp.pem --bcb_rsa=tools/../rsa2048/private-cust.pem -f sboot_sign/IPL.cipher2.aes.bin

    1.3 IPL_CUST

    IPL_CUST部分的签章与IPL完全相同,只不过IPL_CUST无加解密流程

    1.3.1 IPL_CUST签章指令说明

    (1) 插入rsa key到IPL_CUST中,这把key用于对UBOOT验签

    tools/key_proc.py --insert --rsa=tools/../rsa2048/public-image.pem -f sboot_sign/IPL_CUST.bin

    (2) 设置调试模式

    tools/add_ipl_header.py sboot_sign/IPL_CUST.cipher.bin sboot_sign/IPL_CUST.cipher2.bin 0 1 0 0

    (3) 对IPL_CUST进行签章

    tools/key_proc.py --sign --rsa=tools/../rsa2048/private-cust.pem -f sboot_sign/IPL_CUST.cipher2.bin

    1.4 UIMAGE

    UIMAGE包括TFA、OPTEE、UBOOT、KERNEL、RISCV的签章流程是相同的

    签章前后的image结构:

    主要区别在于,签章后的image增加了sbot header、padding、signature部分

    (a) sbot header是secureboot额外增加的一层头,结构与uimage header相同,内容有所差别

    (b) padding : 额外增加的32byte数据,用来保存如下数据

    © signature :签章数据

    1.4.1 UIMAGE签章指令说明

    这里以uboot签章指令进行说明,上述的uimage是相同的流程

    (1) 插入rsa key到uboot中,用于验签roofs或kernel

    tools/uboot_deal.sh sboot_sign/u-boot.img.bin sboot_sign/u-boot.img.bin.processed public-image

    (2) 加密uboot

    tools/key_proc.py --encrypt --encAlg=aes --aes=tools/../aeskey/aesKey128_1.bin -f sboot_sign/u-boot.img.bin.processed

    (3) 添加append数据到uboot尾部

    tools/key_proc.py --append --anti=0 --encAlg=aes --aeskeylen=128 --aeskeynum=1 --mode=ecb --IV=tools/../aeskey/IV.bin -f sboot_sign/u-boot.img.bin.aes.processed

    (4) 对uboot进行签章

    tools/key_proc.py --sign --rsa=tools/../rsa2048/private-image.pem -f sboot_sign/u-boot.img.bin.aes.append.processed

    cp sboot_sign/u-boot.img.bin.aes.append.sig.processed sboot_sign/u-boot.img.bin.processed.sigout

    (5) 在uboot头部添加sbot头

    tools/mkimage -A arm -C none -a 0 -e 0 -n sbot -d sboot_sign/u-boot.img.bin.processed.sigout sboot_sign/u-boot.img.bin.processed.sigout.sbot

    1.5 ROOTFS

    rootfs的签章流程与上述uimage相同,只不过rootfs不会增加sbot header,并且如果开启dmverity的话,rootfs中padding数据的结构会变成下面这样,用来保存dmverity相关的参数

    1.5.1 ROOTFS签章指令说明

    1. 不走dm verity的签章指令说明:

      (1) 添加append数据

      tools/key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=ecb --IV=tools/../aeskey/IV.bin -f sboot_sign/rootfs.ext4

      (2) 添加签章数据

      tools/key_proc.py --sign --rsa=tools/../rsa2048/private-image.pem -f sboot_sign/rootfs.append.ext4

    2. 走dm verity的签章指令说明:

      (1) 计算dm verify相关数据

      veritysetup format sboot_sign/rootfs.ubifs tools/rootfs_hash_device.bin --data-block-size=4096 --hash-block-size=4096 --hash=sha256 --debug

      (2) 将dmverify数据添加到append data

      tools/key_proc.py --append --append_version=1 --anti=0 --dm_verity=73c0a043-9b9e-4a37-b53f-344695bb3bfd,0,0,7440,4096,4096,930,10,932,sha256,7149ef0ab7c487925dc0b12d6be5a673c349e0b4a3fad0733280e57a3f040720,def09292e4f32935b520c639ded67df82dc8b023718e22f0b65f12d23f699383 -f sboot_sign/rootfs.ubifs

      (3) 添加签章数据

      tools/key_proc.py --sign --rsa=tools/../rsa2048/private-image.pem -f sboot_sign/rootfs.append.ubifs

      (4) 将rootfs长度对齐1024

      dd if=/dev/zero bs=1 count=3328 >> sboot_sign/rootfs.append.sig.ubifs

      (5) 拼接数据

      cat sboot_sign/rootfs.ubifs sboot_sign/rootfs.append.sig.ubifs sboot_sign/rootfs.ubifs.hash > sboot_sign/rootfs.ubifs.sigout

    2. Secureboot相关问题

    2.1. 签章失败

    图1 签章失败排查图
    流程 方法 出口条件 下一步 需要提供给RD的资料 相关可参考的FAQ
    A 在alkaid目录下 image/security_boot_tools/执行make clean;make(或者make clean;make image_prepare;make secure_boot) 1. 异常log
    2. 无异常log
    1. 联系RD
    2. 结束
    image/security_boot_tools/下的编译log,以及sign_image.config文件
    B 在alkaid目录下 image/security_boot_tools/ 执行./mannul_sign_img.sh,注,必须先自动签章pass,才会有mannul_sign_img.sh 1. 异常log
    2. 无异常log
    1. 联系RD
    2. 结束
    image/security_boot_tools/下的编译log,以及sign_image.config文件
    C 旧版没有自动签章,需要根据SOP中的命令一步步执行 1. 异常log
    2. 无异常log
    1. 优先检查文件和key是否存在,若存在,则联系RD进一步分析
    2. 结束
    编译的命令,以及出错的log SecureBoot_SOP

    2.2. 验签失败

    图2 验签失败排查图
    流程 方法 出口条件 下一步 需要提供给RD的资料 相关可参考的FAQ
    A Rom Code:
    1. 未烧写OTP_SECUREBOOT,切成normalboot,进入到uboot,使用otpctrl cmd读出OTP中的RSA N key和E key
    2.烧写了SECUREBOOT ENABLE,且未烧写RSA key
    其他阶段:
    查看上一阶段的binary中是否带有RSA N key数据
    然后和签章所用的public.pem进行对比【public.pem内容查看有两种方法:
    1. ./key_proc.py --keyN -f public.pem 后查看public.bin
    2.openssl rsa -text -in private.pem命令可查看N E key的值,见图3 private.pem内容】
    1.正确烧写
    2.烧写了SECUREBOOT ENABLE,且未烧写RSA key或者不确定是否正确烧写RSAkey
    3.部分正确
    4.未烧写
    1.进入流程B
    2.联系RD
    3.确认整包代码是否为tip code,更换芯片重新烧写
    4.在uboot下重新烧写otp
    需要找RD要OTP RSA read script,来确认otp中是否正确写入RSA
    B 若是alkaid下的image/security_boot_tools/tools/下的python,则拉新代码,即为最新。 1.python为最新
    2.python不是最新
    1.进入流程C
    C 根据image中的header信息,找到IPL尾部,是否尾部有签章数据(签章数据256/512 byte不计入header中记录的size信息) 1.image尾部带有256/512byte信息
    2.尾部不带有签章数据
    1.联系RD,并提供资料
    2.手动签章的话,根据文档重新签章,自动签章(alkaid下的image/security_boot_tools/tools/)则联系RD
    1.自动签章需要提供image/security_boot_tools/tools/下的编译log,以及sign_image.config文件,手动签需要提供签章命令
    2.dump register bank:0x1122和0x12a0
    图3 private.pem

    验签错误log原因说明

    2.2.1. ROM code阶段出现 AUTH ERR,可能原因:

    1. OTP RSA N/E key未正确烧写

    2. OTP RSA_KEY_LEN_SELECT/ROM_SELECT_AESKEY 未正确烧写

    3. OTP中烧录的RSA N/E key与签章IPL时使用的私钥不匹配

    4. IPL末尾未插入签章数据,或者插入的签章数据不正确

    2.2.2. IPL验签IPL_CUST

    "[SECURE] get keyN fail" 原因:IMI中的IPL header中的magic校验失败,说明IPL没有正确load到IMI中

    2.2.3. IPL/IPL_CUST 阶段

    "[SECURE] get ipl_cust keyN fail" 原因:DDR中的IPL_CUST header中magic校验失败,说明IPL_CUST没有正确load到DDR对应地址中。

    2.2.4. "[SECURE] chk sboot magic fail" 原因:

    TFA/OPTEE/UBOOT 等uimage类型的image末尾没有正确插入appending部分的数据,导致append数据的magic校验失败。

    2.2.5. "-Authenticate image XXX failed!" 可能原因:

    1. IPL和IPL_CUST末尾没有插入对应的公钥,或者插入的公钥与签章时使用的私钥不匹配

    2. 要验签的image没有插入签章数据

    3. 要验签的image没有成功烧录到flash中

    UBOOT阶段

    2.2.6. "[U-Boot] CUST RSA Key fail" 原因:

    从flash中读取IPL_CUST数据到DDR之后,校验IPL_CUST的magic失败,说明没有成功从flash中读取到IPL_CUST的数据。

    2.2.7. "[U-Boot] chk image magic fail." 原因:

    1. sigauth后第一个参数指定的地址中没有正确的kernel image数据

    2. 如果是验签rootfs,说明rootfs_size(十六进制)环境变量没有设置。

    2.2.8. "[U-Boot] check data fail!" 原因:

    kernel/rootfs等image末尾没有正确插入appending部分的数据,导致append数据的magic校验失败。

    2.2.9. "[U-Boot] Authenticate failed!" 原因:

    1. 查看Dump出的两组数据,第一组32byte的数据是对image算出的sha256值,第二组与签章长度相同的数据是验签后的数据。

    2. 如果验签数据符合pkcs填充标准(前大部分数据内容是0xff),说明RSA计算结果没问题,sha256的计算出错,说明DDR中的image错误。

    3. 如果RSA结果出错,需要检查插入IPL_CUST中的公钥与签章kernel/rootfs等image使用的私钥是否配对,并且检查DDR中的签章数据是否正确

    2.3. 解密失败

    图4 解密失败排查图
    流程 方法 出口条件 下一步 需要提供给RD的资料 **相关可参考的FAQ **
    A 查看签章命令,是否有做加密的动作 1.有做加密且卡在要启动UBOOT
    2.有做加密且卡在要启动IPL
    3.没有做加密
    1.进入B流程
    2.进入C流程
    3.重新做加密签章
    B Souffle之前的芯片需要关心这个flow,IPL编译必须带AES=1 1.编译已经带了 AES=1
    2.编译不带AES=1
    1.进入D流程
    C 查看ROM_SEL_KEY中的值,确认它用的是哪把key。可以读1023_1E[3:0]的值,读到的值和key关系对照图见图5 1.keynum的选择符合预期
    2.keynum的选择和预想的选择不一样
    1.进入D流程
    2.OTP无法改变,请使用对应的key来做解密
    D 在debug mode下,切成normalboot,进入到uboot,使用otpctrl cmd读出OTP中的AESKEY[1-4](按需读)。需要确认签章使用的keynum中的值和OTP中keynum的值是一样的,保证用的同一把key。 1.一致
    2.不一致
    1.联系RD,并提供资料
    2.将读到的aeskey更新到加密所用的aeskey.bin,或者更换芯片
    dump register bank:0x1122和0x12a0
    图5 rom_sel_aeskey对应图

    3. AESDMA相关问题

    3.1. aes计算数据出错

    图1 aes计算数据出错排查图
    流程 方法 出口条件 下一步 需提供给SWRD的资料 相关可参考FAQ
    A 1.关闭kernel menuconfig SigmaStar Crypto driver
    2.继续跑客户的场景,看看是否还会复现到问题。
    出口条件1:
    有复现到问题==》是客户应用层程序问题
    出口条件2:
    无问题
    出口条件1:
    >流程结束
    出口条件2:
    》B
    出口条件1:==》让客户工程师自行检查应用程序的问题
    B 检查客户场景中是否有aes并发场景,尽可能取消所有的并发逻辑,改为单线程测试 出口条件1:
    强制单线程后,正常
    出口条件2:仍然能复现到现象
    出口条件1:
    联系owner处理
    出口条件2:
    ==》C
    C 1.确认aesdma计算多大size时会出错,已经准备好相应case对应位置如下:
    cd drivers/sstar/crypto/cryptodev/examples/
    make clean;make
    ssbuild output
    在板端运行output/install/cipher_aes*和output/aes
    出口条件1:
    至少有一个出了fail case
    出口条件2:
    测试程序无问题,但是实际运行有问题
    出口条件1:
    》fail 情况报告给owner
    出口条件2:
    》D
    D 1.打印出加密出错时的具体size,设计特定数据的demo进行复现 出口条件1:能复现到现象
    2:不能复现到现象
    出口条件1:
    联系owner处理
    出口条件2:
    联系owner进一步定位问题

    3.2. aes/sha cpu loading高

    图2 排查aes/sha cpu loading高流程图
    流程 方法 出口条件 下一步 需提供给SWRD的资料 相关可参考FAQ
    A 检查是否存在并发使用硬件aes/sha算法 出口条件1:

    出口条件2:
    不是
    出口条件1:
    进入B
    出口条件2:
    联系owner优化程序
    B 降低aes,sha其中一个硬件算法的优先级,也可以直接在code关闭其中一个算法的注册,修改后运行example/output中的aes/sha程序,能看到对应被降级的hw算法,打印提示 出口条件1:
    打印提示拿到的driver为aes-generic/sha256-generic(软件通用算法)
    出口条件2:
    打印仍然为原来的硬件算法(sha256-sstar,*-aes-sstar)
    出口条件1:==》
    C
    出口条件2:
    出现该情况找owner修改
    C 重新测试同时跑hw aes/sha的cpu loading 出口条件1:
    cpu loading 降低
    出口条件2:

    cpu loading 没有降低,或者有降低但是没有达到客户的需求
    出口条件1:
    结束流程
    出口条件2:
    需要找owner针对场景优化code

    3.3. aesdma响应超时

    图3 aes计算数据出错排查图
    流程 方法 出口条件 下一步 需提供给SWRD的资料 相关可参考FAQ
    A riu_r 1122(aesdma bank) 出口条件1:
    系统卡死
    出口条件2:
    没有卡死,但是读到bank全空
    出口条件1:
    >B
    出口条件2:
    >C
    B 检查aesdma的时钟配置 出口条件1:
    时钟没有正确配置
    出口条件2:
    时钟有正确配置
    出口条件1:
    进入D
    出口条件2:
    联系owner处理
    C 使用trace32检查aesdma nonsecure是否有被设置 出口条件1:
    aesdma nonsecure没有被设置
    出口条件2:
    aesdma nonsecure有被设置
    出口条件1:
    进入E
    出口条件2.联系owner处理
    D 手动配置aesdma时钟 出口条件1:
    配置后恢复正常
    出口条件2:
    没有恢复正常,还能复现到问题
    出口条件1:
    联系owner处理
    出口条件2:
    联系owner处理
    E 用trace32手动配置aesdma nonsecure,配置bank1122 offset0 为0x9d 出口条件1:
    配置后恢复正常
    出口条件2:
    没有恢复正常,还能复现到问题
    出口条件1:
    联系owner处理
    出口条件2:
    联系owner处理