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 验签和解密总体流程

    烧录芯片OTP的常用方式是使用uboot下的otpctrl cmd,(详见6. 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烧录方法详见6.2 security boot相关的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烧录详见6.3. anti-rollback相关的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打开,(详见6.4. 防止错误注入和信号分析功能相关的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。

    请使用以下命令来生成Private.bin和Public.bin。

    通过以下命令生成的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来生成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
    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. OTP 栏位介绍


    OTP各个bit只能烧写一次,一旦置1后不可置0,请在确认需要的场合下执行烧写动作!

    6.1. OTP Command Format

    烧录芯片的OTP栏位一般是在uboot下使用otpctrl进行烧录操作。烧录完OTP后,一般需要下次启动才会生效。 如下图,列出在UBOOT下执行OTP烧录的两个COMMAND,分别能对OTP进行读写的动作。

    WRITE COMMAND:

    READ COMMAND:

    ERROR CODE:

    FF01: 无效的COMMAND

    FF02: 无效的OTP地址

    FF03: 无效的OTP执行许可证


    6.2. security boot相关的OTP栏位

    对于Souffle系统芯片,如果客户使用security boot功能,需要关注OTP以下内容:

    OTP command ID length(byte) Description
    OTP_RSA_N 0X00 512 保存用于验签IPL的RSA public key的 N 值
    OTP_RSA_E 0X01 4 保存用于验签IPL的RSA public key的 E 值
    OTP_SECURITY_BOOT 0X02 4 启动security boot功能开关,需要在确认正确烧录完RSA/AES key才开启
    OTP_RSA_KEY_LOCK 0X03 4 对OTP内的RSA Public Key栏位进行LOCK的动作,LOCK后不可再修改,客户可根据需求使用
    OTP_RSA_KEY_BLOCK 0X04 4 对OTP内的RSA Public Key栏位进行BLOCK的动作,BLOCK后CPU无法读出OTP内的RSA Public Key,客户可根据需求使用
    OTP_KEY1 0X05 16 第1把AES128 key
    OTP_KEY2 0X06 16 第2把AES128 key,也可以和OTP_KEY1组合成第1把AES256 key
    OTP_KEY3 0X07 16 第3把AES128 key
    OTP_KEY4 0X08 16 第4把AES128 key,也可以和OTP_KEY3组合成第2把AES256 key
    OTP_KEY5 0X09 16 第5把AES128 key
    OTP_KEY6 0X0A 16 第6把AES128 key,也可以和OTP_KEY5组合成第3把AES256 key
    OTP_KEY7 0X0B 16 第7把AES128 key
    OTP_KEY8 0X0C 16 第8把AES128 key,也可以和OTP_KEY7组合成第4把AES256 key
    OTP_AES_KEY1_LOCK 0X0D 4 LOCK后不可再修改即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY1_BLOCK 0X0E 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_AES_KEY2_LOCK 0X0F 4 LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY2_BLOCK 0X10 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_AES_KEY3_LOCK 0X11 4 LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY3_BLOCK 0X12 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_AES_KEY4_LOCK 0X13 4 LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY4_BLOCK 0X14 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_AES_KEY5_LOCK 0X15 4 LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY5_BLOCK 0X16 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_AES_KEY6_LOCK 0X17 4 LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY6_BLOCK 0X18 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_AES_KEY7_LOCK 0X19 4 LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY7_BLOCK 0X1A 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_AES_KEY8_LOCK 0X1B 4 LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用
    OTP_AES_KEY8_BLOCK 0X1C 4 BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用
    OTP_ROM_SELECT_AES_KEY 0X24 4 选择OTP中哪一把AESKey对IPL进行解密,一旦写入此OTP,IPL必须使用CBC加密
    OTP_ROM_SELECT_AES_KEY_LOCK 0X25 4 LOCK后OTP_ROM_SELECT_AES_KEY不可再修改。
    OTP_RSA_KEY_LEN 0X2F 4 使用RSA4096签章时,必须烧录。如果使用RSA2048签章,不用烧录。

    各个OTP栏位的烧录方法举例说明如下。

    6.2.1. OTP_RSA_N (0x0) / OTP_RSA_E (0x1)

    对于现成的需要rsa-public.pem文件,需要先将pem格式转化成可以用于烧录的格式。使用以下cmd生成rsaKey.txt,rsaKey.txt中的command在UBOOT下烧写OTP。

    ./key_proc.py --exportkey_reverse --rsa=public.pem
    

    举例使用现成的pem文件转化后的rsaKey.txt内容如下,直接复制粘贴到uboot 菜单命令行下执行即可:

    ####### RSA N-Key ########
    otpctrl -w 0x0 0x0 0x58653431;otpctrl -w 0x0 0x4 0x06ba8f4a;otpctrl -w 0x0 0x8 0x5caee61a;otpctrl -w 0x0 0xc 0x1912648d;otpctrl -w 0x0 0x10 0xb3b77f1c;otpctrl -w 0x0 0x14 0xd116e973;otpctrl -w 0x0 0x18 0x74f82967;otpctrl -w 0x0 0x1c 0xf85d78e8;otpctrl -w 0x0 0x20 0x55a92d7a;otpctrl -w 0x0 0x24 0xf807ef92;otpctrl -w 0x0 0x28 0xeaca7ab8;otpctrl -w 0x0 0x2c 0x2d33149a;otpctrl -w 0x0 0x30 0xc47f6cfb;otpctrl -w 0x0 0x34 0x99d0fb2b;otpctrl -w 0x0 0x38 0xb94e529f;otpctrl -w 0x0 0x3c 0x09d1e66a;
    otpctrl -w 0x0 0x40 0x93614b62;otpctrl -w 0x0 0x44 0x40db5115;otpctrl -w 0x0 0x48 0x4d37ec4c;otpctrl -w 0x0 0x4c 0xd7ac36da;otpctrl -w 0x0 0x50 0x8bbef7bb;otpctrl -w 0x0 0x54 0x459ffe82;otpctrl -w 0x0 0x58 0xea5aa7ed;otpctrl -w 0x0 0x5c 0x979ac988;otpctrl -w 0x0 0x60 0xd9ad7843;otpctrl -w 0x0 0x64 0xb086c544;otpctrl -w 0x0 0x68 0x75248853;otpctrl -w 0x0 0x6c 0xd0c61f34;otpctrl -w 0x0 0x70 0xd4fd028a;otpctrl -w 0x0 0x74 0x93037bd3;otpctrl -w 0x0 0x78 0x2b3cd0e2;otpctrl -w 0x0 0x7c 0x12b49f2d;
    otpctrl -w 0x0 0x80 0x72fc0405;otpctrl -w 0x0 0x84 0xc1fb6cfd;otpctrl -w 0x0 0x88 0xb42fb860;otpctrl -w 0x0 0x8c 0xa06e8c6e;otpctrl -w 0x0 0x90 0x43870bc3;otpctrl -w 0x0 0x94 0xb97ebe88;otpctrl -w 0x0 0x98 0x45113bd1;otpctrl -w 0x0 0x9c 0xb7974436;otpctrl -w 0x0 0xa0 0x47c3d001;otpctrl -w 0x0 0xa4 0x3611716d;otpctrl -w 0x0 0xa8 0x67abc2d5;otpctrl -w 0x0 0xac 0x773ac1cd;otpctrl -w 0x0 0xb0 0x7d1ee609;otpctrl -w 0x0 0xb4 0xc72e97ee;otpctrl -w 0x0 0xb8 0x91af8bd5;otpctrl -w 0x0 0xbc 0xd516243d;
    otpctrl -w 0x0 0xc0 0x949b2522;otpctrl -w 0x0 0xc4 0x3d73c4d7;otpctrl -w 0x0 0xc8 0xcf2fde53;otpctrl -w 0x0 0xcc 0xbd35d242;otpctrl -w 0x0 0xd0 0x2362de0f;otpctrl -w 0x0 0xd4 0x8d9f7418;otpctrl -w 0x0 0xd8 0x861f69d5;otpctrl -w 0x0 0xdc 0x0736f5ff;otpctrl -w 0x0 0xe0 0x7655b44e;otpctrl -w 0x0 0xe4 0x06198429;otpctrl -w 0x0 0xe8 0xe0975a88;otpctrl -w 0x0 0xec 0x6fcec320;otpctrl -w 0x0 0xf0 0x49480b57;otpctrl -w 0x0 0xf4 0xea4a5ee3;otpctrl -w 0x0 0xf8 0x6502ddee;otpctrl -w 0x0 0xfc 0xd6d17ae2;
    ####### RSA E-Key ########
    otpctrl -w 0x1 0x0 0x00010001
    

    注意:因为uboot 菜单命令行的buf缓存长度有限制,不可直接将64条otpctrl命令当成一次复制粘贴回车运行。建议至少分成4次执行。


    6.2.2. OTP_SECURE_BOOT (0x2)

    确认RSA/AES key都烧录后,启动security boot功能(下次启动才会生效):

    otpctrl -w 0x2 0x0 0xFFFFFFFF
    

    检查security boot功能是否已开启:

    otpctrl  -r 0x2
    

    6.2.3. OTP_RSA_KEY_LOCK (0x3) / OTP_RSA_KEY_BLOCK (0x4)

    非必要操作,客户可根据需求使用。

    确认LOCK和BLOCK rsa key(下次启动才会生效):

    otpctrl -w 0x3 0x0 0xFFFFFFFF
    otpctrl -w 0x4 0x0 0xFFFFFFFF
    

    检查LOCK和BLOCK是否已开启:

    otpctrl -r 0x3
    otpctrl -r 0x4
    

    6.2.4. OTP_AES128_KEY (0x5~0xC)

    如果客户使用security boot的签章+加密功能,烧录AES KEY是必要操作。

    如果是制作AES128 KEY:

    echo '000102030405060708090A0B0C0D0E0F' | xxd -r -ps > aesKey128_1.bin
    

    烧录AES key到 OTP_KEY1位置:

    otpctrl -w 0x5 0x0 0x03020100
    otpctrl -w 0x5 0x4 0x07060504
    otpctrl -w 0x5 0x8 0x0B0A0908
    otpctrl -w 0x5 0xC 0x0F0E0D0C
    

    如果是制作AES256 KEY:

    echo '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F' | xxd -r -ps > aesKey256_1.bin
    

    烧录AES key到 OTP_KEY1和OTP_KEY2位置:

    otpctrl -w 0x5 0x0 0x03020100
    otpctrl -w 0x5 0x4 0x07060504
    otpctrl -w 0x5 0x8 0x0B0A0908
    otpctrl -w 0x5 0xC 0x0F0E0D0C
    otpctrl -w 0x6 0x0 0x13121110
    otpctrl -w 0x6 0x4 0x17161514
    otpctrl -w 0x6 0x8 0x1B1A1918
    otpctrl -w 0x6 0xC 0x1F1E1D1C
    

    烧录8把AES128 key或者4把AES256 key的操作同理。

    6.2.5. OTP_AES128_KEY1~8_LOCK (0xD,0xF,0x11,0x13,0x15,0x17,0x19,0x1B) / OTP_AES128_KEY1~8_BLOCK (0xE,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C)

    非必要操作,客户可根据需求使用。

    确认LOCK和BLOCK 第一把AES128 key(下次启动才会生效):

    otpctrl -w 0xD 0x0 0xFFFFFFFF
    otpctrl -w 0xE 0x0 0xFFFFFFFF
    

    第一把AES128 key检查LOCK和BLOCK是否已开启:

    otpctrl -r 0xD
    otpctrl -r 0xE
    

    确认LOCK和BLOCK 第一把AES256 key(下次启动才会生效):

    otpctrl -w 0xD 0x0 0xFFFFFFFF
    otpctrl -w 0xF 0x0 0xFFFFFFFF
    otpctrl -w 0xE 0x0 0xFFFFFFFF
    otpctrl -w 0x10 0x0 0xFFFFFFFF
    

    第一把AES256 key检查LOCK和BLOCK是否已开启:

    otpctrl -r 0xD
    otpctrl -r 0xF
    otpctrl -r 0xE
    otpctrl -r 0x10
    

    LOCK和BLOCK8把AES128 key或者4把AES256 key的操作同理。

    6.2.6. OTP_ROM_SEL_AESKEY (0x24)

    如果客户使用security boot的签章+加密功能,烧录OTP_ROM_SEL_AESKEY用来选择OTP中哪一把AESKey对IPL进行解密是必要操作。

    如果客户只使用security boot的签章,不可烧录OTP_ROM_SEL_AESKEY。

    Example:

    • 选择 AESKEY128_1

      otpctrl -w 0x24 0x0 0xFF000000
      
    • 选择 AESKEY128_2

      otpctrl  -w 0x24 0x0 0xFF0000FF
      
    • 选择 AESKEY128_3

      otpctrl  -w 0x24 0x0 0xFF00FF00
      
    • 选择 AESKEY128_4

      otpctrl  -w 0x24 0x0 0xFF00FFFF
      
    • 选择 AESKEY128_5

      otpctrl  -w 0x24 0x0 0xFFFF0000
      
    • 选择 AESKEY128_6

      otpctrl  -w 0x24 0x0 0xFFFF00FF
      
    • 选择 AESKEY128_7

      otpctrl  -w 0x24 0x0 0xFFFFFF00
      
    • 选择 AESKEY128_8

      otpctrl  -w 0x24 0x0 0xFFFFFFFF
      

    另外IPL可以使用AES256解密,OTP中AESKEY256实际上是由OTP中两把AES128组合而成,组合和设置方式举例如下:

    • 选择 AESKEY256_1(Composition mode: AES128key1 + AES128key2)

      otpctrl  -w 0x24 0x0 0x00FF0000
      
    • 选择 AESKEY256_2(Composition mode: AES128key3 + AES128key4)

      otpctrl  -w 0x24 0x0 0x00FF00FF
      
    • 选择 AESKEY256_3(Composition mode: AES128key5 + AES128key6)

      otpctrl  -w 0x24 0x0 0x00FFFF00
      
    • 选择 AESKEY256_4(Composition mode: AES128key7 + AES128key8)

      otpctrl  -w 0x24 0x0 0x00FFFFFF
      

    6.2.7. OTP_ROM_SEL_AESKEY_LOCK (0x25)

    非必要操作,客户可根据需求使用。 确认LOCK和BLOCK OTP_ROM_SEL_AESKEY里的内容(下次启动才会生效):

    otpctrl -w 0x25 0x0 0xFFFFFFFF
    

    检查LOCK和BLOCK是否已开启:

    otpctrl  -r 0x25
    

    6.2.8. OTP_RSA_KEY_LEN (0x2F)

    如果客户使用rsa4096来签章,必须烧录此OTP栏位,使用rsa2048则无需关注。

    otpctrl -w 0x2F 0x0 0xFFFFFFFF
    

    6.3. anti-rollback相关的OTP栏位

    如果客户不使用anti-rollback功能,将security_boot_tools/sign_image.config里的所有Image version默认保持为0即可。

    如果客户使用anti-rollback功能,才需要关注OTP以下内容:

    OTP command ID length(byte) Description
    OTP_IPL_ANTI_ROLLBACK 0x2B 256 保存IPL的OTP version,每4个bytes表示一次进阶版本,IPL最多可进版64次
    OTP_IPL_CUST_ANTI_ROLLBACK 0x2C 64 保存IPL_CUST的OTP version,每4个bytes表示一次进阶版本,IPL最多可进版16次
    OTP_TF_A_ANTI_ROLLBACK 0x2C 96 保存TF_A的OTP version,每4个bytes表示一次进阶版本,IPL最多可进版24次
    OTP_OPTEE_ANTI_ROLLBACK 0x2C 96 保存OPTEE的OTP version,每4个bytes表示一次进阶版本,IPL最多可进版24次
    OTP_UBOOT_ANTI_ROLLBACK 0x2C 96 保存BOOT的OTP version,每4个bytes表示一次进阶版本,IPL最多可进版24次
    OTP_KERNEL_ANTI_ROLLBACK 0x2C 96 保存KERNEL的OTP version,每4个bytes表示一次进阶版本,IPL最多可进版24次

    各个OTP栏位的烧录方法举例说明如下。

    6.3.1. OTP_IPL_ANTI_ROLLBACK (0x2B)

    IPL 的 Image version 在security_boot_tools/sign_image.config通过修改参数 'ipl_abk'指定。需要确认 Image version 大于烧录的 OTP Version。

    烧录 IPL 的 OTP Version 举例:

    IPL OTP Version = 1

    otpctrl  -w 0x2B 0x0 0xFFFFFFFF
    

    IPL OTP Version = 2

    otpctrl  -w 0x2B 0x0 0xFFFFFFFF
    otpctrl  -w 0x2B 0x4 0xFFFFFFFF
    

    IPL OTP Version = 3

    otpctrl  -w 0x2B 0x0 0xFFFFFFFF
    otpctrl  -w 0x2B 0x4 0xFFFFFFFF
    otpctrl  -w 0x2B 0x8 0xFFFFFFFF
    

    以此类推。

    6.3.2 OTP_IPL_CUST_ANTI_ROLLBACK (0x2C,OFFSET 0X0~0X40)

    IPL_CUST 的 Image version 在security_boot_tools/sign_image.config通过修改参数 'ipl_cust_abk'指定。需要确认 Image version 大于烧录的 OTP Version。

    烧录 IPL_CUST 的 OTP Version 举例:

    IPL_CUST OTP Version = 1

    otpctrl  -w 0x2C 0x0 0xFFFFFFFF
    

    IPL_CUST OTP Version = 2

    otpctrl  -w 0x2C 0x0 0xFFFFFFFF
    otpctrl  -w 0x2C 0x4 0xFFFFFFFF
    

    IPL_CUST OTP Version = 3

    otpctrl  -w 0x2C 0x0 0xFFFFFFFF
    otpctrl  -w 0x2C 0x4 0xFFFFFFFF
    otpctrl  -w 0x2C 0x8 0xFFFFFFFF
    

    以此类推。

    6.3.3 OTP_TF_A_ANTI_ROLLBACK (0x2C,OFFSET 0X40~0XA0)

    TF_A 的 Image version 在security_boot_tools/sign_image.config通过修改参数 'tf_a_abk'指定。需要确认 Image version 大于烧录的 OTP Version。

    烧录 TF_A 的 OTP Version 举例:

    TF_A OTP Version = 1

    otpctrl  -w 0x2C 0x40 0xFFFFFFFF
    

    TF_A OTP Version = 2

    otpctrl  -w 0x2C 0x40 0xFFFFFFFF
    otpctrl  -w 0x2C 0x44 0xFFFFFFFF
    

    TF_A OTP Version = 3

    otpctrl  -w 0x2C 0x40 0xFFFFFFFF
    otpctrl  -w 0x2C 0x44 0xFFFFFFFF
    otpctrl  -w 0x2C 0x48 0xFFFFFFFF
    

    以此类推。

    6.3.4 OTP_OPTEE_ANTI_ROLLBACK (0x2C,OFFSET 0XA0~0X100)

    OPTEE 的 Image version 在security_boot_tools/sign_image.config通过修改参数 'optee_abk'指定。需要确认 Image version 大于烧录的 OTP Version。

    烧录 OPTEE 的 OTP Version 举例:

    OPTEE OTP Version = 1

    otpctrl  -w 0x2C 0xA0 0xFFFFFFFF
    

    OPTEE OTP Version = 2

    otpctrl  -w 0x2C 0xA0 0xFFFFFFFF
    otpctrl  -w 0x2C 0xA4 0xFFFFFFFF
    

    OPTEE OTP Version = 3

    otpctrl  -w 0x2C 0xA0 0xFFFFFFFF
    otpctrl  -w 0x2C 0xA4 0xFFFFFFFF
    otpctrl  -w 0x2C 0xA8 0xFFFFFFFF
    

    以此类推。

    6.3.5 OTP_UBOOT_ANTI_ROLLBACK (0x2C,OFFSET 0X100~0X160)

    UBOOT 的 Image version 在security_boot_tools/sign_image.config通过修改参数 'uboot_abk'指定。需要确认 Image version 大于烧录的 OTP Version。

    烧录 UBOOT 的 OTP Version 举例:

    UBOOT OTP Version = 1

    otpctrl  -w 0x2C 0x100 0xFFFFFFFF
    

    UBOOT OTP Version = 2

    otpctrl  -w 0x2C 0x100 0xFFFFFFFF
    otpctrl  -w 0x2C 0x104 0xFFFFFFFF
    

    UBOOT OTP Version = 3

    otpctrl  -w 0x2C 0x100 0xFFFFFFFF
    otpctrl  -w 0x2C 0x104 0xFFFFFFFF
    otpctrl  -w 0x2C 0x108 0xFFFFFFFF
    

    以此类推。

    6.3.6 OTP_KERNEL_ANTI_ROLLBACK (0x2C,OFFSET 0X160~0X1C0)

    KERNEL 的 Image version 在security_boot_tools/sign_image.config通过修改参数 'kernel_abk'指定。需要确认 Image version 大于烧录的 OTP Version。

    烧录 KERNEL 的 OTP Version 举例:

    KERNEL OTP Version = 1

    otpctrl  -w 0x2C 0x160 0xFFFFFFFF
    

    KERNEL OTP Version = 2

    otpctrl  -w 0x2C 0x160 0xFFFFFFFF
    otpctrl  -w 0x2C 0x164 0xFFFFFFFF
    

    KERNEL OTP Version = 3

    otpctrl  -w 0x2C 0x160 0xFFFFFFFF
    otpctrl  -w 0x2C 0x164 0xFFFFFFFF
    otpctrl  -w 0x2C 0x168 0xFFFFFFFF
    

    以此类推。


    6.4. 防止错误注入和信号分析功能相关的OTP栏位

    对于Souffle系统芯片,如果客户使用防止错误注入和信号分析功能(Multiple Round、SCA、key2sha1),才需要关注OTP以下内容:

    OTP command ID length(byte) Description
    OTP_PROTECT_ENABLE 0x30 4 rsa2sha1和pwd2sha1和aes2sha1的总开关
    OTP_RSA_KEY_N_CHK_ENABLE 0x31 4 启动rsa2sha1的子开关,表示启动rsa public key的check功能
    OTP_PASSWORD_CHK_ENABLE 0x32 4 启动pwd2sha1的子开关,表示启动password的check功能
    OTP_OTP_KEY_CHK_ENABLE 0x33 4 启动aes2sha1的子开关,表示启动AES key的check功能
    OTP_AES_MULTIPLE_NUM 0x34 8 启动aes multiple num的开关,表示AES内部加解密需要做N(1~4)次,N次结果一致再输出
    OTP_SCA_PROTECT_ENABLE 0x35 4 启动SCA PROTECT的开关,表示每次HW aes加解密中加入random num打乱aes时序,防止信号分析
    OTP_PassWord_chk 0x36 4 保存PASSWORD的 SHA1&XOR运算值,用于启动过程校验OTP PASSWORD可靠性
    OTP_Key1_chk 0x37 4 保存第1把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_Key2_chk 0x38 4 保存第2把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_Key3_chk 0x39 4 保存第3把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_Key4_chk 0x3A 4 保存第4把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_Key5_chk 0x3B 4 保存第5把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_Key6_chk 0x3C 4 保存第6把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_Key7_chk 0x3D 4 保存第7把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_Key8_chk 0x3E 4 保存第8把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性
    OTP_RSA_KEY_N_CHK 0x3F 4 保存RSA public N key的 SHA1&XOR运算值,用于启动过程校验OTP RSAKEY可靠性

    各个OTP栏位的烧录方法举例说明如下。

    6.4.1. OTP_PROTECT_ENABLE(0x30)

    启动aes2sha1 pwd2sha1 rsa2sha1 check的总开关,烧录后须于下次启动才会生效。

    otpctrl -w 0x30 0x0 0xFFFFFFFF
    

    检查总开关是否已开启:

    otpctrl -r 0x30
    

    6.4.2. OTP_RSA_KEY_N_CHK_ENABLE(0x31) / OTP_RSA_KEY_N_CHK(0x3F)

    非必要操作,客户可根据需求使用。注意开启 OTP_RSA_KEY_N_CHK_ENABLE 需要搭配烧录OTP_RSA_KEY_N_CHK。

    对于现成的rsa-public.pem文件,制作key-SHA1方法如下:

    ./key_proc.py --key2sha1 -f rsa2048/public-otp.pem
    ------------------------------------------------------>public-otp.pem_sha1.txt
    

    举例使用现成的pem文件转化后的pem_sha1.txt内容如下:

    otp-sca-protect-enable

        otpctrl -w 0x3F 0x0 0xa44a2887
    

    再启动rsa2sha1的子开关:

        otpctrl -w 0x31 0x0 0xFFFFFFFF
    

    6.4.3. OTP_PASSWORD_CHK_ENABLE(0x32) / OTP_PassWord_chk(0x36)

    非必要操作,客户可根据需求使用。注意开启 OTP_PASSWORD_CHK_ENABLE 需要搭配烧录OTP_PassWord_chk。

    对于现成的需要pwd.bin文件,制作key-SHA1方法如下:

    ./key_proc.py --pwd2sha1 -f pwd.bin
    ------------------------------------------------------>pwd.bin_sha1.txt
    

    举例使用现成的pwd.bin文件转化后的bin_sha1.txt内容如下:

    otp-sca-protect-enable

        otpctrl -w 0x36 0x0 0xa6a938d1
    

    再启动pwd2sha1的子开关:

        otpctrl -w 0x32 0x0 0xFFFFFFFF
    

    6.4.4. OTP_OTP_KEY_CHK_ENABLE(0x33) / OTP_Key1~8_chk (0x37-0x3E)

    非必要操作,客户可根据需求使用。注意开启 OTP_OTP_KEY_CHK_ENABLE 需要搭配烧录由OTP_ROM_SELECT_AES_KEY 指定的第n把AES key对应的OTP_Key_chk。

    对于现成的需要aesKey.bin文件,制作key-SHA1方法如下:

    ./key_proc.py --key2sha1 -f aeskey/aesKey1.bin
    ------------------------------------------------------>aesKey1.bin_sha1.txt
    

    举例使用现成的aesKey.bin文件转化后的bin_sha1.txt内容如下:

    otp-sca-protect-enable

    如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第1把,则烧录bin_sha1.txt内容到OTP_Key1_chk

    otpctrl -w 0x37 0x0  0x35f0f5d7
    

    如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第2把,则烧录bin_sha1.txt内容到OTP_Key2_chk

    otpctrl -w 0x38 0x0  0x35f0f5d7
    

    如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第3把,则烧录bin_sha1.txt内容到OTP_Key3_chk

    otpctrl -w 0x39 0x0  0x35f0f5d7
    

    以此类推。

    再启动aes2sha1的子开关:

        otpctrl -w 0x33 0x0 0xFFFFFFFF
    

    6.4.5. OTP_AES_MULTIPLE_NUM(0x34)

    非必要操作,客户可根据需求使用。表示AES内部加解密需要做N(1~4)次,N次结果一致再输出。在设置完该Command后,须于下次启动才会生效。

    Example:

    MULTIPLE_NUM=1:
    otpctrl -w 0x34 0x0 0x00000000
    otpctrl -w 0x34 0x4 0x00000000
    
    MULTIPLE_NUM=2:
    otpctrl -w 0x34 0x0 0xFFFFFFFF
    otpctrl -w 0x34 0x4 0x00000000
    
    MULTIPLE_NUM=3:
    otpctrl -w 0x34 0x0 0x00000000
    otpctrl -w 0x34 0x4 0xFFFFFFFF
    
    MULTIPLE_NUM=4:
    otpctrl -w 0x34 0x0 0xFFFFFFFF
    otpctrl -w 0x34 0x4 0xFFFFFFFF
    

    6.4.6. OTP_SCA_PROTECT_ENABLE(0x35)

    非必要操作,客户可根据需求使用。表示启动SCA PROTECT。SCA是在aes加解密中加入random num打乱aes时序,防止信号分析,在设置完该Command后,须于下次启动才会生效。

    Example:

    WRITE COMMAND: otpctrl -w 0x35 0x0 0xFFFFFFFF
    

    6.5. 用户自定义数据相关的OTP栏位

    对于Souffle系统芯片,OTP区域有8K bit开放给客户使用保存自定义数据。

    OTP command ID length(byte) Description
    OTP_CUSTOMER_AREA 0XA0 1024 可用于用户自由烧录自定义数据
    OTP_CUSTOMER_AREA_LOCK0 0XA1 4 LOCK后,0-127Bytes 自定义数据不可再修改
    OTP_CUSTOMER_AREA_LOCK1 0XA2 4 LOCK后,128-255Bytes 自定义数据不可再修改
    OTP_CUSTOMER_AREA_LOCK2 0XA3 4 LOCK后,256-383Bytes 自定义数据不可再修改
    OTP_CUSTOMER_AREA_LOCK3 0XA4 4 LOCK后,384-511Bytes 自定义数据不可再修改
    OTP_CUSTOMER_AREA_LOCK4 0XA5 4 LOCK后,512-639Bytes 自定义数据不可再修改
    OTP_CUSTOMER_AREA_LOCK5 0XA6 4 LOCK后,640-767Bytes 自定义数据不可再修改
    OTP_CUSTOMER_AREA_LOCK6 0XA7 4 LOCK后,768-895Bytes 自定义数据不可再修改
    OTP_CUSTOMER_AREA_LOCK7 0XA8 4 LOCK后,896-1023Bytes 自定义数据不可再修改

    各个OTP栏位的烧录方法举例说明如下。

    6.5.1. OTP_CUSTOMER_AREA (0xA0)

    每次只能写4byte。offset从0x0 - 0x3FF。

    Example:

    otpctrl -w 0xA0 0x0 0x12345678
    otpctrl  -w 0xA0 0x4 0x09ABCDEF
    otpctrl  -w 0xA0 0x8 0x33445566
    

    以此类推。

    最后4byte WRITE COMMAND:

    otpctrl  -w 0xA0 0x3fC 0xAA778899
    

    CUSTOMER_AREA读取:

    otpctrl  -r 0xA0
    

    6.5.2. OTP_CUSTOMER_AREA_LOCK(0xA1~0xA8)

    LOCK 0k~1K bits数据(下次启动才会生效):

    otpctrl -w 0xA1 0x0 0xFFFFFFFF
    

    LOCK 1k~2K bits数据(下次启动才会生效):

    otpctrl -w 0xA2 0x0 0xFFFFFFFF
    

    LOCK 2k~3K bits数据(下次启动才会生效):

    otpctrl -w 0xA3 0x0 0xFFFFFFFF
    

    LOCK 3k~4K bits数据(下次启动才会生效):

    otpctrl -w 0xA4 0x0 0xFFFFFFFF
    

    LOCK 4k~5K bits数据(下次启动才会生效):

    otpctrl -w 0xA5 0x0 0xFFFFFFFF
    

    LOCK 5k~6K bits数据(下次启动才会生效):

    otpctrl -w 0xA6 0x0 0xFFFFFFFF
    

    LOCK 6k~7K bits数据(下次启动才会生效):

    otpctrl -w 0xA7 0x0 0xFFFFFFFF
    

    LOCK 7k~8K bits数据(下次启动才会生效):

    otpctrl -w 0xA8 0x0 0xFFFFFFFF
    

    7. 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 标记决定走验签启动流程。

    7.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),详见6.2. security boot相关的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介绍


    7.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
    

    第三步: 检查系统打印

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