跳转至

Security Boot使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 07/20/2023
    1.1
  • Added anti rollback function
  • Updated automatic signature function
  • 01/04/2024
    1.2
  • Reorganize the document structure
  • 01/31/2024
    1.3
  • securityboot new bootflow
  • 02/02/2024

    1. Security Boot概述


    为防止用户产品的固件被抄板或者刷机,Sigmastar固件在启动过程自动进行验签(或验签+解密),验签即签章的验证,防止软件加载的镜像内容被恶意篡改。其中加密和解密为可选,一般情况下镜像加密是为了防止镜像中的信息被泄露,而镜像验章是为了防止镜像的信息被篡改,用户可根据自身需求取舍。使用Security Boot的核心工作有两步:人为将镜像文件进行签章(或加密+签章),以及将签章使用到的对应key通过烧录保存在芯片OTP中。


    图1 验签和解密总体流程

    图中系统启动的详细流程请参考Security boot system flow章节)

    烧录芯片OTP的常用方式是使用uboot下的otpctrl cmd,(详见《OTP栏位介绍》)。请注意OTP烧录无法反悔,为了防止误操作导致系统无法启动甚至IC作废,一般建议开发者先使用调试流程确认key内容正确。签章镜像的常用方式是使用security_boot_tools自动处理alkaid image包,(详见5. Security_boot_tools工具使用介绍章节),如果客户有特殊需要,也可以选择手动签章方式《Security Boot手动签章使用参考》。

    Security Boot还提供了防回滚机制(Anti-rollback),确保能正常加载和启动的镜像版本一定比用户在OTP里存储的版本号高,(详见3. Anti-rollback原理介绍章节),用户可根据自身需求使用。开启Anti-rollback的核心工作有两步:使用security_boot_tools签章过程将版本号嵌入镜像中,以及将拦截的镜像版本号保存在芯片OTP中。

    Sigmastar芯片内部还提供了防止错误注入和信号分析的硬件设计(Multiple Round、SCA、key2sha1),防止新型密码分析方法对芯片加解密过程进行干扰或者分析,有效地增加系统破解难度,(详见4. 防止错误注入和信号分析原理介绍章节),用户可根据自身需求使用。开启(Multiple Round、SCA、key2sha1)功能与镜像本身无关,核心工作只有一步:烧录OTP使能指定功能。


    2. Security Boot原理介绍


    2.1. 开启Security Boot

    当烧录完OTP Key后,真正启动Security Boot需要烧录OTP里的OTP_Secure_Boot相应的栏位(OTP烧录方法详见《OTP栏位介绍》),将该栏位烧录为0xFFFFFFFF,则会启动OTP的Security Boot(注:开启后无法关闭,每次启动都将会强制走Security Boot flow)。


    2.2. 单个镜像签章和Security Boot流程

    Generate Signature一般是在local端执行security_boot_tools脚本完成,流程如下:

    1. security_boot_tools对Image file进行SHA-256的计算,生成Digest
    2. 通过RSA-2048做加密动作,生成256Bytes的signature
    3. 将signature嵌入至Image尾端
    4. 将Image烧录把系统存储器中启动。

    Verify Signature是在固件boot flow中执行,流程如下:

    1. 各阶段的boot code会对下一段的Image进行SHA-256计算,生成Digest
    2. 根据header信息取出嵌入在尾部的signature来做RSA-2048的解密生成Digest'
    3. 对比Digest和Digest',若对比一致,则Verify success,否则Verify fail。

    图2 签章Security Boot流程


    2.3. 单个镜像签章+加密和Security Boot流程

    Generate Signature一般是在local端执行security_boot_tools脚本完成:security_boot_tools先对Image通过AES加密成Cipher file,再对Cipher file进行SHA-256计算,生成Digest,再通过RSA-2048做加密动作,生成256Bytes的signature,再将signature嵌入至Image后端,最后将Image烧录把系统存储器中启动。

    Verify Signature是在boot flow中,各阶段的boot code会对下一段的Image进行SHA-256计算,生成Digest,并根据header信息取出嵌入在取出Signature来做RSA-2048的解密后,生成Digest',最后对比Digest和Digest'。如对比成功,则对Cipher file进行AES解密的动作,最后解密为能开机的image。

    图3 签章+加密Security Boot流程

    需要注意: IPL只支持AES-CBC加密,而IPL_CUST不支持加密。 其他image支持AES (ECB/CBC/CTR加密),当使用CBC/CTR模式时,对应的IV key会被security_boot_tools制作成32字节的append段落,嵌入在image信息里,(详见3.1. Append data说明章节)。


    2.4. Security Boot流程中Image File变化


    图3.1 Image File变化

    需要注意:

    • IPL/IPL_CUST没有uimage header,但有自己特殊的header且此header不参与加密,此头部的具体变化在2.5.1介绍
    • 除IPL/IPL_CUST/Rootfs外,其他image的头部会加上一层独立的secure_boot header表示image已经支持secure boot,且此header不参与加密和签章

    2.5. 密钥介绍

    从密钥使用的角度看,同一个image签章和验签必须使用一对RSA Private KeyRSA Public Key,加密和解密使用同一把AES Key

    2.5.1. RSA Public Key

    验签流程中所用的RSA Public Key最多有三组。

    第一把为 OTP Key,该把Key会在系统Power On后,Hardware会自动从OTP中载入,用来做验签IPL的可靠性,加载和验签过程Software是无法介入的。而OTP Key的内容,可以通过U-Boot的Command Line烧录至OTP的指定地址中。一旦OTP KEY锁读后,cpu或其他调试工具再也无法access rsakey(otp aes key同理)此时只有aesdma engine can access。

    第二把为CUST Key,该Key会嵌在IPL的bin文件中,通过Software在整个boot flow中用来验签IPL_CUST的可靠性,因为IPL的可靠性有保证,因此验签IPL_CUST/TF-A/OPTEE的过程也是可靠的。而 CUST KEY的内容,一般是使用security_boot_tools工具将key文件insert到IPL的bin文件内容的指定位置。


    图4 IPL结构

    第三把为Image Key,该Key会嵌在IPL_CUST的bin文件中,通过Software在整个boot flow中用来验签UBOOT/VMM/RTOS/LINUX/ROOTFS的可靠性,因为IPL_CUST的可靠性有保证,因此验签后面所有镜像的过程也是可靠的。而Image Key的内容,一般是使用security_boot_tools工具将key文件insert到IPL_CUST的bin文件内容的指定位置。


    图5 IPL_CUST结构

    2.5.2. AES KEY

    解密流程中所用的AES Key最多为8把。

    在Sigmastar固件在bootflow过程,由Hardware载入OTP里指定的AES key到crypto engine进行镜像解密。至于镜像使用8把AES key中的哪一把,一般是使用security_boot_tools工具在镜像中嵌入指定AES key 信息,(详见3.1. Append data说明章节)。除了IPL只支持CBC mode以及IPL_CUST不支持加密,其余image都支持ECB/CBC/CTR mode,一般也是使用security_boot_tools工具在镜像中嵌入IV信息。

    所有bootload image用于解密的AES Key需要烧录到OTP存储单元中,OTP存储单元最多保存8把128bit的AESKEY或者4把256bit的AESKEY。所有bootload image可以任意指定8把中的任意1把key,甚至所有bootload image都共用其中1把key。

    2.6. Security boot system flow介绍

    下图为从ROM到Linux Kernel的Security Boot Flow结构,其中Signature为签章数据部分,每个Flow的Signature均会嵌入到相应bin文件的最后,每个Flow均包含Get Key和Authenticate的动作直到Linux Kernel,部分Flow支持解密(是否开启解密取决于需求)。


    图6 Boot Flow结构
    1. Authenticate IPL by OTP Key-RSA

      该流程为ROM code从OTP中读取RSA Public Key后,对IPL进行签章的验证。由于OTP的RSA Public Key可以进行Write Lock动作(后面章节会详细提及),阻止再次被写和被读取,所以OTP的RSA Public Key可以做到不被替换,从而保证了IPL不会被篡改。如果开启加密机制,ROM code根据OTP_ROM_SEL_AESKEY继续从OTP中读取AES key对IPL进行解密。

    2. Authenticate TF-A by IPL's CUST Key-RSA

      该流程为IPL读取事先嵌在IPL的CUST RSA Public Key后,对TF-A进行签章的验证。如果开启加密机制,IPL根据TF-A镜像里的append data里的IV和aes_keynum信息继续从OTP中读取AES key对TF-A进行解密。

    3. Authenticate OP-TEE by IPL's CUST Key-RSA

      该流程为IPL读取事先嵌在IPL的CUST RSA Public Key后,对OP-TEE进行签章的验证。如果开启加密机制,IPL根据OP-TEE镜像里的append data里的IV和aes_keynum信息继续从OTP中读取AES key对OP-TEE进行解密。

    4. Authenticate IPL_CUST by IPL's CUST Key-RSA

      该流程为IPL读取事先嵌在IPL的CUST RSA Public Key后,对IPL_CUST进行签章的验证。由于IPL不会被篡改,所以保证了嵌在IPL的CUST RSA Public Key不会被篡改,从而保证了IPL_CUST也不会被篡改。IPL_CUST不支持加密。

    5. Authenticate U-Boot by IPL_CUST's Image Key-RSA

      该流程为IPL_CUST读取事先嵌在IPL_CUST的Image RSA Public Key后,对U-Boot进行签章的验证。如果开启加密机制,IPL_CUST根据U-Boot镜像里的append data里的IV和aes_keynum信息继续从OTP中读取AES key对U-Boot进行解密。

    6. Authenticate Kernel/ramdiskfs by IPL_CUST's Image Key-RSA

      该流程为U-Boot bootcmd读取事先嵌在IPL_CUST的Image RSA Public Key后,对kernel/ramdiskfs进行签章的验证。如果开启加密机制,bootcmd根据kernel/ramdiskfs镜像里的append data里的IV和aes_keynum信息继续从OTP中读取AES key对kernel/ramdiskfs进行解密。


    3. Anti-rollback原理介绍


    防回滚机制,其目的是为了防止IPL/IPL_CUST/TF-A/OPTEE/UBOOT/KERNEL 降级到以前的版本。各个阶段的boot code通过检查下一阶段的boot code(IPL/IPL_CUST/TF-A/OPTEE/UBOOT/KERNEL) image信息里的Image Version,与保存在OTP里对应的OTP Version 进行对比,如果:

    Image Version >= OTP Version ==> 正常加载并启动下一阶段的boot code image

    Image Version < OTP Version ==> 提示系统卡住,不启动下一阶段的boot code image

    以此来保证IPL/IPL_CUST/TF-A/OPTEE/UBOOT/KERNEL 的版本为最新。

    以下是各个Image的可用进版数(otp version烧录详见《OTP栏位介绍》)。

    Name 最多可进版次数 otp name otp cmd offset range
    IPL 64 OTP_VERSION_CTL 0x0 ~ 0x100
    IPL_CUST 16 OTP_VERSION2_CTL 0x0 ~ 0x40
    tfa 24 OTP_VERSION2_CTL 0x40 ~ 0xA0
    optee 24 OTP_VERSION2_CTL 0xA0 ~ 0x100
    uboot 24 OTP_VERSION2_CTL 0x100 ~ 0x160
    kernel 24 OTP_VERSION2_CTL 0x160 ~ 0x1C0

    注意:

    • 在OTP Version中,用4 bytes表示进阶一次版本。以IPL为例,当IPL OTP Version 从0进版到1,需要使用OTP_VERSION_CTL命令将0x0-0x4刻录成0xFFFF FFFF; 当IPL OTP Version需要再次进版到2,需要使用OTP_VERSION_CTL命令将0x4-0x8刻录成0xFFFF FFFF;
    • Image Version为当前image的版本号,对于IPL和IPL_CUST,Image Version是保存在header data里;对于TF-A/OPTEE/UBOOT/KERNEL,Image Version是保存在appended data里; 除此之外的其他image(VMM/RTOS/PM_RTOS/ROOTFS)虽然也会追加appended data,但不支持anti-rollback功能。
    • otp version可具有自动更新功能(默认关闭)。当header version大于otp version时,会更新otp version与header version一致。

    3.1. Append data说明

    只要使用securityboot功能,目前除了IPL/IPL_CUST,security_boot_tools会用同样的方式处理其余每个Image(UBOOT/TF-A/VMM/KERNEL/OPTEE/RTOS等):先在尾部追加 32byte appended data,再追加256/512 byte signature data。


    图7 appended data结构

    以下是 32byte appended data的说明:

    Member Description
    magic 检索的标志,固定为“SSTARSBT”
    pend_version Secure append的软件版本
    sstar_pend_size Secure append的长度,固定为32Byte
    aes_msg bit 0 - decrypt_enable。bit [1:2] - 00:ecb; 01: ctr; 10:cbc
    AntiRollback_version 除IPL,IPL_CUST之外的其他image的版本号
    IV1&IV2 CBC/CTR解密需要传入的IV值
    aes_keynum 0000 ==> 没有经过AES加密
    0100 ==> AES256 with {Key1[127:0], Key2[127:0]
    0101 ==> AES256 with {Key3[127:0], Key4[127:0]
    0110 ==> AES256 with {Key5[127:0], Key6[127:0]
    0111 ==> AES256 with {Key7[127:0], Key8[127:0]
    1000 ==> AES128 with Key1[127:0]
    1001 ==> AES128 with Key2[127:0]
    1010 ==> AES128 with Key3[127:0]
    1011 ==> AES128 with Key4[127:0]
    1100 ==> AES128 with Key5[127:0]
    1101 ==> AES128 with Key6[127:0]
    1110 ==> AES128 with Key7[127:0]
    1111 ==> AES128 with Key8[127:0]

    可以看出,镜像信息:如anti-rollback功能的Image Version、Image是否经过AES加密、使用哪种类型AES(CBC/CTR/ECB、128/256)加密、加密使用的IV值、使用OTP里哪一把AES key,都是保存在这32字节的appended data里。系统启动过程中,每一个阶段的boot code就是根据下一阶段的boot code image里的appended data,对其进行相应的version check和解密镜像。


    4. 防止错误注入和信号分析原理介绍


    防止错误注入和信号分析的功能,如Multiple Round、SCA、key2sha1。该功能默认关闭,需要通过配置OTP打开,(详见《OTP栏位介绍》)。

    • Multiple Round,表示AES内部加解密需要做N(1~4)次,N次结果一致再输出。

      硬件增加Multiple Rounds的功能,如果开启此功能,硬件在做完一次AES加解密之后,将会记录此次结果,在内部再重新做1/ 2/ 3次AES加解密(取决于Register的设定),并对比N次结果,如果有一次结果不一致,则判定为结果出错,AESDMA Engine不输出结果,从而防止黑客攻击。实测该功能开启后,aes加密速率会有略微下降,通过配置OTP开启。

    • SCA是在aes加解密中加入random num打乱aes时序,防止SCA攻击。

      旁路攻击(Side Channel Analysis,SCA)是一种新型密码分析方法,其突破了传统密码分析的思维模式,利用芯片密码运算过程中泄露的各种物理信息(如功耗、电磁辐射、声音、可见光等)与加解密操作的相关性来破解密码系统。

      AESDMA Engine可在做AES加解密时,通过加入冗余操作,增加AES加解密的复杂程度,使得攻击者无法根据AES加解密原理借助工具推断分析出加解密的轮数。该功能对软件透明,通过配置OTP开启。

    • key2sha1

      该方案的HW Flow及原理如下:

      1. 在烧写AESKEY/RSAKEY/PASSWORD 的OTP时,用户需要将AESKEY/RSAKEY/PASSWORD 分别计算出 SHA1,并将SHA1 result进行XOR成32Bit的数据写入OTP_KeyX_chk/OTP_RSA_KEY_N_CHK/OTP_PassWord_chk中。

      2. 系统启动过程HW将AESKEY Auto Load到AESDMA Engine中,RSAKey Auto Load到RSA_ENG的SRAM中,再开始AES/RSA运算。如果打开了OTP_RSA_KEY_N_CHK_ENABLE/OTP_OTP_KEY_CHK_ENABLE/OTP_PASSWORD_CHK_ENABLE,ROM code将会对rsakey/aeskey/pwd 做sha1&xor的动作,得出的结果与用户保存在OTP里的SHA1&XOR' 结果对比一致,则证明Key未被修改。

      ROM code具体行为如图:


      图6 key2sha1原理图

      1. OTP_PROTECT_ENABLE是总开关,子开关 RSA_N_CHK_ENABLE,AES_CHK_ENABLE,PWD_CHK_ENABLE
      2. 在前置开关满足的情况下,ROM code对PWD/AESKEY/RSAKEY做一次SHA1运算,再将sha1运算的结果(160bit)做5组异或操作,得到最终结果为32bit的数据。
      3. 步骤2的32bit将和OTP中存储的值做对比,如果一致,则认为校验pass,否则将Halt。

    5. Security_boot_tools工具使用介绍


    使用Security_boot_tools对alkaid image进行签章的步骤主要有以下几步:

    1. 先编译打包,生成未签章的完整镜像烧录包。
    2. 手动制作RSA key和aes Key,替换Security_boot_tools工具目录下默认的RSA key和aes Key。
    3. 编译配置文件sign_image.config,指定各阶段的boot Image的Image version/rsa key/aes key/aes加密模式(CBC/CTR/ECB)/aes IV值等信息。
    4. 执行Security_boot_tools即可根据配置信息,自动完成对完整镜像烧录包的拆包、签名、嵌入CUST Key、嵌入appended data、打包、压缩等工作,输出已签章的完整镜像烧录包。

    5.1. 制作RSA key和aes Key

    5.1.1 制作RSA Key

    制作方式适用于OTP Key/CUST Key/Image Key中的RSA Key,可依据客户需求,多个Image使用同一把Key或多个Image使用不同的RSA Key。出于安全性考虑,建议使用多把不同的RSA key。

    请使用openssl命令来生成Private.bin和Public.bin。openssl是Linux系统中常用的开源加密库与命令行工具集,核心作用是提供安全通信、数据加密/解密、数字签名、证书管理等功能。推荐使用3.0.17以上版本。

    通过以下命令生成的E key值默认为0x10001,security boot flow不支持自定义E key值。

    RSA2048:

    1. 生成RSA私钥

      openssl genrsa -out private.pem 2048
      
    2. 生成RSA公钥

      openssl rsa -in private.pem -out public.pem -outform PEM -pubout
      

    RSA4096:

    1. 生成RSA私钥

      openssl genrsa -out private.pem 4096
      
    2. 生成RSA公钥

      openssl rsa -in private.pem -out public.pem -outform PEM -pubout
      

    将上述生成的n对RSA key,替换project/image/security_boot_tools/下的rsa2048 或者 rsa4096 目录下对应的需要用到的key binary文件即可。

    key type Description
    private-otp.pem 被security_boot_tools用来签章IPL
    public-otp.pem 需要人为烧录到OTP里,用于启动过程ROM code验签IPL
    private-cust.pem 被security_boot_tools用来签章IPL_CUST/TF_A/OPTEE
    public-cust.pem 被security_boot_tools嵌入到IPL里,用于启动过程IPL验签IPL_CUST/TF_A/OPTEE
    private-image.pem 被security_boot_tools用来签章除了IPL/IPL_CUST/TF_A/OPTEE的其他Image
    public-image.pem 被security_boot_tools嵌入到IPL_CUST里,用于启动过程IPL_CUST验签除了IPL/IPL_CUST/TF_A/OPTEE的其他Image

    5.1.2. 制作AES Key

    这边通过xxd tool(Linux中预装的命令行二进制文件分析工具,此处的功能是将十六进制还原为二进制文件)来生成AES key binary file,制作方式适用于OTP里的8把 aes-128 key或者4把aes-256 key。可依据客户需要求,多个Image使用同一把aes Key或者多个Image使用不同的aes Key。出于安全性考虑,建议使用多把不同的aes key。

    1. AES-128 Key

      echo '00102030405060708090A0B0C0D0E0FF' | xxd -r -ps > aesKey_128.bin
      
    2. AES-256 Key

      echo '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F' | xxd -r -ps > aesKey_256.bin
      
    3. IV

      echo '303132333435363738393A3B3C3D3E3F' | xxd -r -ps > IV.bin
      

    将上述生成的n把AES key,替换project/image/security_boot_tools/下的aesKey目录下对应的需要用到的key binary文件即可。


    5.2. 配置文件sign_image.config

    进入project/image/security_boot_tools/下,修改sign_image.config文件。

    sign_image.config文件中参数说明:

    Name Description
    rsalen rsalen的值为 2048 或 4096,各阶段boot code都由该参数指定RSA2048 or RSA4096
    ipl_abk IPL的image version版本号,anti-rollback func used,当ipl_abk=0时表示不使用antirollback
    ipl_aeskeynum IPL加密功能。aeskey目录下有8把aes128和4把aes256,可以选择使用4把aes256和8把aes128中的一把,和aeskeylen搭配使用,当ipl_aeskeynum=0时表示不使用aes加密。以ipl_aeskeylen=128&&ipl_aeskeynum=1为例,说明IPL将使用security_boot_tools/aeskey/aesKey128_1.bin作为aes-key进行加密
    ipl_aeskeylen IPL加密功能。aeskey目录下有8把aes128和4把aes256,aeskeylen的值为128 或者256。当ipl_aeskeylen=0时表示不使用aes加密,和ipl_aeskeynum搭配使用。
    ipl_IV IPL加密方式一定是cbc。如果加密的话,此项填入IV的binary的名字
    sw_debug 测试时代替OTP_Secure_boot使用,调试模式
    ipl_cust_abk IPL_CUST的版本号, antirollback func used
    add_sbot_header sboot可选是否增加Image Header,默认关闭
    tf_a_abk TF_A的版本号,antirollback func used
    tf_a_aes_type tf_a的加密方式(支持ecb cbc ctr),若选CBC or CTR,则需要IV值
    tf_a_aeskeylen aeskeylen的值为128 或者256。当tf_a_aeskeylen=0时表示不使用aes加密,和tf_a_aeskeynum搭配使用
    tf_a_aeskeynum aeskeylen=128下aeskeynum有效范围为[1-8]。
    aeskeylen=256下aeskeynum有效范围为[1-4],当tf_a_aeskeynum=0时表示不使用aes加密
    tf_a_IV CBC or CTR所需要的IV值file name
    tf_a_enable 是否使能以上参数,若为0,则默认使用image的参数
    optee_abk OPTEE的版本号,antirollback func used
    optee_aes_type optee的加密方式(支持ecb cbc ctr),若选CBC or CTR,则需要IV值
    optee_aeskeylen aeskeylen的值为128 或者256。 当optee_aeskeylen=0时表示不使用aes加密,和optee_aeskeynum搭配使用
    optee_aeskeynum aeskeylen=128下aeskeynum有效范围为[1-8]。
    aeskeylen=256下aeskeynum有效范围为[1-4],当optee_aeskeynum=0时表示不使用aes加密
    optee_IV CBC or CTR所需要的IV值filename
    optee_enable 是否使能以上参数,若为0,则默认使用image的参数

    Name Description
    vmm_abk VMM的版本号, antirollback func used,暂不支持版本控制
    vmm_aes_type 加密方式(支持ecb cbc ctr),若选CBC or CTR,则需要IV值
    vmm_aes_enable VMM是否使用AES加密,若为0表示不适用aes加密
    vmm_aeskeylen aeskeylen的值为128 或者256。当vmm_aeskeylen=0时表示不使用aes加密,和vmm_aeskeynum搭配使用
    vmm_aeskeynum aeskeylen=128下aeskeynum有效范围为[1-8]。
    aeskeylen=256下aeskeynum有效范围为[1-4],当vmm_aeskeynum=0时表示不使用aes加密
    vmm_IV CBC or CTR所需要的IV值file name
    vmm_enable 是否使能以上参数,若为0,则默认使用image的参数
    uboot_abk uboot的版本号,antirollback func used
    uboot_aes_type 加密方式(支持ecb cbc ctr),若选CBC or CTR,则需要IV值
    uboot_aeskeylen aeskeylen的值为128 或者256。 当uboot_aeskeylen=0时表示不使用aes加密,和uboot_aeskeynum搭配使用
    uboot_aeskeynum aeskeylen=128下aeskeynum有效范围为[1-8]。
    aeskeylen=256下aeskeynum有效范围为[1-4],当uboot_aeskeynum=0时表示不使用aes加密
    uboot_IV CBC or CTR所需要的IV值file name
    uboot_enable 是否使能以上参数,若为0,则默认使用image的参数
    kernel_abk kernel的版本号,antirollback func used
    kernel_aes_type 加密方式(支持ecb cbc ctr),若选CBC or CTR,则需要IV值
    kernel_aeskeylen aeskeylen的值为128 或者256。 当kernel_aeskeylen=0时表示不使用aes加密,和kernel_aeskeynum搭配使用
    kernel_aeskeynum aeskeylen=128下aeskeynum有效范围为[1-8]。
    aeskeylen=256下aeskeynum有效范围为[1-4],当kernel_aeskeynum=0时表示不使用aes加密
    kernel_IV CBC or CTR所需要的IV值file name
    kernel_enable 是否使能以上参数,若为0,则默认使用image的参数

    Name Description
    rtos_abk RTOS的版本号, antirollback func used,暂不支持版本控制
    rtos_aes_type 加密方式(支持ecb cbc ctr),若选CBC or CTR,则需要IV值
    rtos_aeskeylen aeskeylen的值为128 或者256。 当rtos_aeskeylen=0时表示不使用aes加密,和rtos_aeskeynum搭配使用
    rtos_aeskeynum aeskeylen=128下aeskeynum有效范围为[1-8]。
    aeskeylen=256下aeskeynum有效范围为[1-4],当rtos_aeskeynum=0时表示不使用aes加密
    rtos_IV CBC or CTR所需要的IV值file name
    rtos_enable 是否使能以上参数,若为0,则默认使用image的参数
    image_aes_type 加密方式(支持ecb cbc ctr),若选CBC or CTR,则需要IV值
    image_aeskeylen aeskeylen的值为128 或者256。 当image_aeskeylen=0时表示不使用aes加密,和image_aeskeynum搭配使用
    image_aeskeynum aeskeylen=128下aeskeynum有效范围为[1-8]。
    aeskeylen=256下aeskeynum有效范围为[1-4],当image_aeskeynum=0时表示不使用aes加密
    image_IV CBC or CTR所需要的IV值file name
    image_abk 预保留,若使用anti rollback功能,填写在对应image的abk

    5.3. 运行Security_boot_tools

    实际操作步骤如下:

    1. 进入project目录,make xxx_defconfig; make clean -j32; make image -j32;

    2. 进入project/image/security_boot_tools/下,make clean;make;即可生成security_boot_tools/image_secure目录(目录下Image已签章)

      如果签章的动作需要在别的目录下做或者需要在不同电脑上签章,Step2中请执行make image_prepare,并把security_boot_tools完整copy到另一个位置,再执行make即可。

    注:security_boot_tools生成的image,estar会自动配置bootcmd来验签(或者解密+验签)kernel。默认rootfs会加签,但bootcmd不会验签(或者解密+验签)rootfs。如需验签rootfs,请手动修改bootcmd,增加signature 验签rootfs步骤。


    5.4. signature cmd介绍

    在Uboot阶段需要修改环境变量bootcmd来对Linux Kernel/rtos/vmm/ramdiskfs等binary进行验证,其原理是通过sigauth命令来对Binary进行验签和解密:

    sigauth <Binary_Addr> <KEY_Addr> [--aes]
    <Binary_Addr>:  需要验签(或者加密)的binary在ddr里的加载地址。
    <KEY_Addr>:    IPL_CUST在ddr里的加载地址,sigauth cmd会根据IPL_CUST头部信息找到IPL_CUST内部的public N key。一般在启动过程IPL_CUST固定被加载在0x21000000位置。
    [--aes]:        可选项,表示验签前是否先对binary进行aes解密。sigauth cmd会自动根据binary的appended data找到指定的OTP AES key和指定的AES解密模式。
    

    U-boot启动pure linux,验签前:

    EX:
    setenv bootcmd ' dcache on; loados nand 0x23000000 KERNEL ${kernel_file_size}; bootm 0x23000000; dcache on; loados nand 0x23000000 RECOVERY ${recovery_file_size}; bootm 0x23000000;
    

    U-boot启动pure linux,验签后:

    EX:
    setenv bootcmd ' dcache on; loados nand 0x23000000 KERNEL ${kernel_file_size}; sigauth 23000000 0x21000000 ; bootm 0x23000000; dcache on; loados nand 0x23000000 RECOVERY ${recovery_file_size}; bootm 0x23000000;
    

    如果镜像使用了加密,请在对应的启动方式上的sigauth命令的尾部加上 --aes。

    U-boot启动dualos,验签前:

    EX:
    setenv bootcmd ' loados nand by_header MISC by_header; loados nand by_header RTOS by_header;bootm start ${loados_addr};bootm loados;bootm prep;wakeupcpu 3 s 0x2ef08000; loados nand by_header RAMDISK by_header; loados nand by_header KERNEL by_header;dcache off;bootm ${loados_addr};
    

    U-boot启动dualos,验签后:

    EX:
    setenv bootcmd ' loados nand by_header MISC by_header; loados nand by_header RTOS by_header;sigauth ${loados_addr} 0x21000000;bootm start ${loados_addr};bootm loados;bootm prep;wakeupcpu 3 s 0x2ef08000; loados nand by_header RAMDISK by_header;sigauth ${loados_addr} 0x21000000; loados nand by_header KERNEL by_header;sigauth ${loados_addr} 0x21000000;dcache off;bootm ${loados_addr};
    

    在ENV中设定rootfs_size的大小:

    rootfs_size <rootfs_sieze>; saveenv;
    EX:
    rootfs_size 1af100; saveenv;
    

    在对应的存储介质读取rootfs后加上:

    dcache off;sigauth <Binary_Addr> <KEY_Addr> [--aes];dcache on;
    EX:
    setenv bootcmd ' dcache off; loados nand 0x22000000 roofs 0x600000; sigauth 22000000 0x21000000 ; loados nand 0x23000000 KERNEL ${kernel_file_size};sigauth 23000000 0x21000000; dcache on; bootm 0x23000000; loados nand 0x23000000 RECOVERY ${recovery_file_size}; bootm 0x23000000;
    

    6. Security BOOT部署步骤


    OTP只能烧写一次,一旦烧写则无法清除和重烧。为了防止误操作导致系统无法启动甚至IC作废,一般建议调试流程PASS以后,才能进行正式OTP流程。即先烧录部分OTP进行测试,确认调试流程PASS,以后再补充烧录剩余OTP。

    调试模式下,Security_boot_tools会将IPL header里的AUTH栏位置1,rom code加载IPL、IPL加载IPL_CUST/TF-A/OPTEE、IPL_CUST加载VMM/RTOS/LINUX会根据AUTH标记决定走验签启动流程。

    OTP正式模式下,rom code加载IPL、IPL加载IPL_CUST/TF-A/OPTEE、IPL_CUST加载VMM/RTOS/LINUX会根据OTP是否烧录 OTP_SECURITY_BOOT 标记决定走验签启动流程。

    6.1. Security Boot调试流程

    第一步:用户自行生成三组RSA public/private key,替换security_boot_tools/aes/和rsa2048或者rsa4096/目录下的key文件。详见5.1. 制作RSA key和aes Key

    第二步:使用U-Boot Command otpctrl 烧录RSA Public NKey/Ekey(或AES Key),详见《OTP栏位介绍》。

    • 调试阶段建议只烧录 OTP_RSA_N / OTP_RSA_E / OTP_RSA_KEY_LEN / OTP_KEY1~8。
    • 不建议烧录 OTP_SECURITY_BOOT 栏位,即使在调试阶段错误烧录了OTP内容,该芯片board无法启动签章image,但依然可以用来启动未签章image。
    • 不建议烧录 所有 OTP LOCK & BLOCK 栏位,即使调试阶段错误烧录了OTP内容,还有机会检查和修改OTP内容。
    • 不建议烧录 OTP_ROM_SELECT_AES_KEY,即使调试阶段错误烧录了OTP AES-key 内容,ROM code依然可以启动未加密签章的IPL。

    第三步:根据客户需要配置security_boot_tools配置文件sign_image.config,但在调试阶段以下配置需要注意:

    sw_debug=1        #即使OTP没有烧录 OTP_SECURITY_BOOT 栏位,系统启动过程也会走security boot验签和解密流程。
    ipl_aeskeynum=0   #因为OTP没有烧录 OTP_ROM_SELECT_AES_KEY,系统启动过程不会对IPL进行解密,因此不使用security_boot_tools对IPL进行加密。
    ipl_aeskeylen=0
    

    第四步: 检查系统打印

    检查系统打印确认ROM->IPL->IPL_CUST->U-Boot已进行到SecurityBoot的flow。

    1. ROM->IPL确认是否走SecurityBoot的方式

      ROM验签IPL成功不会有任何log,但验签失败则会打印AUTH ERR(波特率可能需要调为38400或57600,否则乱码)。

    2. IPL->IPL_CUST->U-Boot确认是否走SecurityBoot的方式

      查看log即可,一般带有Authenticate image关键字,若开启解密流程则还会有AES ECB关键字。

      举例如下:

    3. U-Boot -> kernel确认是否走SecurityBoot的方式

      直接查看bootcmd是否有验签signature。详见5.4. signature cmd介绍


    6.2. Security Boot正式流程

    调试模式能正常走Secruty boot启动后,说明调试阶段烧录的OTP RSA N/E KEY、AES KEY的步骤是可靠的,后续芯片可以直接复制调试模式总结下来的OTP烧录命令。

    正式流程只需要补充烧录部分OTP栏位即可。

    第一步:使用U-Boot Command otpctrl 烧录 OTP_SECURITY_BOOT、 RSA KEY的LOCK和BLOCK、OTP_ROM_SELECT_AES_KEY等。

    第二步:配置security_boot_tools配置文件sign_image.config:

    sw_debug = 0
    ipl_aeskeynum = 1   #举例使用第一把AES-128 KEY
    ipl_aeskeylen = 128
    

    第三步: 检查系统打印

    • 烧录后同样按照6.1的方法确认ROM->IPL->IPL_CUST->U-Boot->Kernel有走到SecurityBoot并能启动到U-Boot,到此ROM->IPL->IPL_CUST->U-Boot->Kernel的SecurityBoot flow和OTP相关验证已经PASS。