Security Boot使用参考¶
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | 07/20/2023 | |
| 1.1 | 01/04/2024 | |
| 1.2 | 01/31/2024 | |
| 1.3 | 02/02/2024 | |
| 1.4 | 05/26/2025 | |
| 1.5 | 08/18/2025 | |
| 1.6 | 10/10/2025 | |
| 1.7 | 10/11/2025 |
1. Security Boot概述¶
为防止用户产品的固件被抄板或者刷机,SGS固件在启动过程自动进行验签(或验签+解密),验签即签章的验证,防止软件加载的镜像内容被恶意篡改。其中加密和解密为可选,一般情况下镜像加密是为了防止镜像中的信息被泄露,而镜像验章是为了防止镜像的信息被篡改,用户可根据自身需求取舍。使用Security Boot的核心工作有两步:人为将镜像文件进行签章(或加密+签章),以及将签章使用到的对应key通过烧录保存在芯片OTP中。
烧录芯片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中。
SGS芯片内部还提供了防止错误注入和信号分析的硬件设计(Multiple Round、SCA、key2sha1),防止新型密码分析方法对芯片加解密过程进行干扰或者分析,有效地增加系统破解难度,(详见4. 防止错误注入和信号分析原理介绍章节),用户可根据自身需求使用。开启(Multiple Round、SCA、key2sha1)功能与镜像本身无关,核心工作只有一步:烧录OTP使能指定功能。
Security Boot支持的签章验签算法有:RSA2048/RSA4096, 国密SM2算法,ECC256/ECC384/ECC512算法。由于SM2与ECC算法原理类似,下面的描述会将SM2算法归为ECC系列算法。
mhera平台Secureboot支持RSA2048/RSA4096/SM2/ECC256/ECC384 算法, 不支持其他算法
2. Security Boot原理介绍¶
2.1. 开启Security Boot¶
当烧录完OTP Key后,真正启动Security Boot需要烧录OTP里的OTP_Secure_Boot相应的栏位(OTP烧录方法详见6.2 security boot相关的OTP栏位章节),将该栏位烧录为0xFFFFFFFF,则会启动OTP的SecurityBoot(注:开启后无法关闭,每次启动都将会强制走Security Boot flow)。
2.2. 单个镜像签章和Security Boot流程¶
Generate Signature一般是在local端执行security_boot_tools脚本完成,流程如下:
- security_boot_tools对Image file进行SHA-256的计算,生成Digest
- 通过RSA2048做签章动作,生成256Bytes的signature; RSA4096生成512Byte的 signature; ECC256/SM2生成64Byte的signature; ECC384生成96Byte的signature; ECC512生成128Byte的signature;
- 将signature嵌入至Image尾端
- 将Image烧录到系统存储器中启动。
Verify Signature是在固件boot flow中执行,流程如下:
- 各阶段的boot code会对下一段的Image进行SHA-256计算,生成Digest
- 根据header信息取出嵌入在尾部的signature来做RSA2048/RSA4096的解密生成Digest'
- 对比Digest和Digest',若对比一致,则Verify success,否则Verify fail。
如果走ECC验签流程无上述步骤,会直接对下一段Image中的signature进行验签,并直接给出校验结果。

图2.1 RSA2048/RSA4096签章验签流程

图2.2 ECC系列签章验签流程
2.3. 单个镜像签章+加密和Security Boot流程¶
对于RSA2048 or RSA4096流程:
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,对Signature做RSA-2048的解密后,生成Digest',最后对比Digest和Digest'。如对比成功,则对Cipher file进行AES解密的动作,最后解密为能开机的image。
对于ECC系列流程:
Generate Signature一般是在local端执行security_boot_tools脚本完成:security_boot_tools先对Image通过AES加密成Cipher file,再通过ECC系列算法做加密动作,生成signature数据,再将signature嵌入至Image后端,最后将Image烧录把系统存储器中启动。
Verify Signature是在boot flow中,各阶段的boot code会根据下一段Image的header信息来取出嵌入在末尾的Signature,再对Signature做对应的ECC系列验签。如果验签通过,则对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. 密钥介绍¶
从密钥使用的角度看,同一个image签章和验签必须使用一对RSA/ECC Private Key和RSA/ECC Public Key,加密和解密使用同一把AES Key。
2.4.1. RSA/ECC Public Key¶
验签流程中所用的RSA/ECC 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文件内容的指定位置。
第三把为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文件内容的指定位置。
如果走的是ECC系列流程,Key的位置与上面描述相同,不同的是Public Key的size不一样。
ECC256/SM2的Public Key是64Byte;ECC384的Public Key是96Byte;ECC512的Public Key是128Byte;
2.4.2. AES KEY¶
解密流程中所用的AES Key最多为8把。
在SGS固件在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.5. Security boot system flow介绍¶
下图为从ROM到Linux Kernel的Security Boot Flow结构,其中Signature为签章数据部分,每个Flow的Signature均会嵌入到相应bin文件的最后,每个Flow均包含Get Key和Authenticate的动作直到Linux Kernel,部分Flow支持解密(是否开启解密取决于需求)。

图6 Boot Flow结构
-
Authenticate IPL by OTP Key-RSA
该流程为ROM code从OTP中读取RSA/ECC Public Key后,对IPL进行签章的验证。由于OTP的RSA/ECC Public Key可以进行Write Lock动作(后面章节会详细提及),阻止再次被写和被读取,所以OTP的RSA/ECC Public Key可以做到不被替换,从而保证了IPL不会被篡改。如果开启加密机制,ROM code根据OTP_ROM_SEL_AESKEY继续从OTP中读取AES key对IPL进行解密。
-
Authenticate TF-A by IPL's CUST Key-RSA
该流程为IPL读取事先嵌在IPL的CUST RSA/ECC Public Key后,对TF-A进行签章的验证。如果开启加密机制,IPL根据TF-A镜像里的append data里的IV和aes_keynum信息继续从OTP中读取AES key对TF-A进行解密。
-
Authenticate OP-TEE by IPL's CUST Key-RSA
该流程为IPL读取事先嵌在IPL的CUST RSA/ECC Public Key后,对OP-TEE进行签章的验证。如果开启加密机制,IPL根据OP-TEE镜像里的append data里的IV和aes_keynum信息继续从OTP中读取AES key对OP-TEE进行解密。
-
Authenticate IPL_CUST by IPL's CUST Key-RSA
该流程为IPL读取事先嵌在IPL的CUST RSA/ECC Public Key后,对IPL_CUST进行签章的验证。由于IPL不会被篡改,所以保证了嵌在IPL的CUST RSA/ECC Public Key不会被篡改,从而保证了IPL_CUST也不会被篡改。IPL_CUST不支持加密。
-
Authenticate U-Boot by IPL_CUST's Image Key-RSA
该流程为IPL_CUST读取事先嵌在IPL_CUST的Image RSA/ECC Public Key后,对U-Boot进行签章的验证。如果开启加密机制,IPL_CUST根据U-Boot镜像里的append data里的IV和aes_keynum信息继续从OTP中读取AES key对U-Boot进行解密。
-
Authenticate Kernel/ramdiskfs by IPL_CUST's Image Key-RSA
该流程为U-Boot bootcmd读取事先嵌在IPL_CUST的Image RSA/ECC 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。
以下是 32byte appended data的说明:
| Member | Description |
|---|---|
| magic | 检索的标志 |
| pend_version | Secure append的软件版本 |
| pend_size | Secure append的长度,固定为32Byte |
| aes_msg | bit 0 - decrypt_enable。 bit [1:2] - 00:ecb; 01: ctr; 10:cbc。 bit [3] - 0:aes; 1:sm4 |
| AntiRollback_version | uImage的版本号 |
| 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及原理如下:
-
在烧写AESKEY/RSAKEY/PASSWORD 的OTP时,用户需要将AESKEY/RSAKEY/PASSWORD 分别计算出 SHA1,并将SHA1 result进行XOR成32Bit的数据写入OTP_KeyX_chk/OTP_RSA_KEY_N_CHK/OTP_PassWord_chk中。
-
系统启动过程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原理图- OTP_PROTECT_ENABLE是总开关,子开关 RSA_N_CHK_ENABLE,AES_CHK_ENABLE,PWD_CHK_ENABLE
- 在前置开关满足的情况下,ROM code对PWD/AESKEY/RSAKEY做一次SHA1运算,再将sha1运算的结果(160bit)做5组异或操作,得到最终结果为32bit的数据。
- 步骤2的32bit将和OTP中存储的值做对比,如果一致,则认为校验pass,否则将Halt。
5. Security_boot_tools工具使用介绍¶
使用Security_boot_tools对alkaid image进行签章的步骤主要有以下几步:
- 先编译打包,生成未签章的完整镜像烧录包。
- 手动制作RSA/ECC key和aes Key,替换Security_boot_tools工具目录下默认的RSA/ECC key和aes Key。
- 编译配置文件sign_image.config,指定各阶段的boot Image的Image version/rsa key/aes key/aes加密模式(CBC/CTR/ECB)/aes IV值等信息。
- 执行Security_boot_tools即可根据配置信息,自动完成对完整镜像烧录包的拆包、签名、嵌入CUST Key、嵌入appended data、打包、压缩等工作,输出已签章的完整镜像烧录包。
5.1. 制作RSA/ECC key和aes Key¶
5.1.1 制作RSA/ECC Key¶
制作方式适用于OTP Key/CUST Key/Image Key中的RSA/ECC Key,可依据客户需求,多个Image使用同一把Key或多个Image使用不同的RSA/ECC Key。出于安全性考虑,建议使用多把不同的RSA/ECC key。
使用RSA2048/4096算法,需要生成RSA private.pem和public.pem
使用SM2/ECC256/ECC384/ECC512算法,需要生成ECC private.der和public.der
请使用以下命令来生成RSA private.pem和public.pem
通过以下命令生成的E key值默认为0x10001,security boot flow不支持自定义E key值。
RSA2048 :
-
生成 RSA2048 私钥
openssl genrsa -out private.pem 2048 -
生成 RSA2048 公钥
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
RSA4096 :
-
生成 RSA4096 私钥
openssl genrsa -out private.pem 4096 -
生成 RSA4096 公钥
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
请使用以下命令来生成ECC private.der和public.der
SM2 :
-
生成 SM2 私钥并转化为der格式
openssl ecparam -genkey -name SM2 -out private.pem openssl ec -in private.pem -outform DER -out private.der -
生成 SM2 公钥并转化为der格式
openssl ec -in private.pem -pubout -out public.pem openssl ec -in public.pem -pubin -outform DER -out public.der
ECC256 :
-
生成 ECC256 私钥并转化为der格式
openssl ecparam -genkey -name prime256v1 -out private.pem openssl ec -in private.pem -outform DER -out private.der -
生成 ECC256 公钥并转化为der格式
openssl ec -in private.pem -pubout -out public.pem openssl ec -in public.pem -pubin -outform DER -out public.der
ECC384 :
-
生成 ECC384 私钥并转化为der格式
openssl ecparam -genkey -name secp384r1 -out private.pem openssl ec -in private.pem -outform DER -out private.der -
生成 ECC384 公钥并转化为der格式
openssl ec -in private.pem -pubout -out public.pem openssl ec -in public.pem -pubin -outform DER -out public.der
ECC512 :
-
生成 ECC512 私钥并转化为der格式
openssl ecparam -genkey -name brainpoolP512r1 -out private.pem openssl ec -in private.pem -outform DER -out private.der -
生成 ECC512 公钥并转化为der格式
openssl ec -in private.pem -pubout -out public.pem openssl ec -in public.pem -pubin -outform DER -out public.der
将上述生成的n对RSA/ECC key,替换project/image/security_boot_tools/下的rsa2048/rsa4096/sm2/ecc256/ecc384/ecc512 对应目录下需要用到的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。-
AES-128 Key
echo '00102030405060708090A0B0C0D0E0FF' | xxd -r -ps > aesKey_128.bin -
AES-256 Key
echo '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F' | xxd -r -ps > aesKey_256.bin -
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 sign_alg sign_alg的值为 rsa 或 ecc 或 sm2,各阶段boot code都由该参数指定使用RSA2048/RSA4096 or ECC系列算法进行签章验签 sign_len 如果sign_alg选择rsa, 则sign_len的值为 2048 或 4096,即整个Secureboot流程中都使用RSA2048 or RSA4096进行签章验签; 如果sign_alg选择ecc, 则sign_len的值为256/384/512,即整个Secureboot流程中都使用ecc256/ecc384/ecc512进行签章验签; 如果sign_alg选择sm2, 则sign_len的值填非0值即可, 即整个Secureboot流程中都使用sm2算法进行签章验签 padding_type padding_type 值为 pkcs 或 pss, 指定用于rsa签名过程中的填充方式。 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加密,目前仅支持aeskey128_1解密image_IV CBC or CTR所需要的IV值file name image_abk 预保留,若使用anti rollback功能,填写在对应image的abk
5.3. 运行Security_boot_tools¶
实际操作步骤如下:
-
进入project目录,make xxx_defconfig; make clean -j32; make image -j32;
-
进入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> <Binary_Addr>: 需要验签(或者加密)的binary在ddr里的加载地址。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 0x23000000 ; bootm 0x23000000; dcache on; loados nand 0x23000000 RECOVERY ${recovery_file_size}; bootm 0x23000000;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};bootm start ${loados_addr};bootm loados;bootm prep;wakeupcpu 3 s 0x2ef08000; loados nand by_header RAMDISK by_header;sigauth ${loados_addr}; loados nand by_header KERNEL by_header;sigauth ${loados_addr};dcache off;bootm ${loados_addr};
6. OTP 栏位介绍¶
如果要在uboot下使用otpctrl功能,需要确保uboot开启CONFIG_ARM_SMCCC!
在编译uboot时需要选择的配置如下:
ARM architecture--> [*] Support for ARM SMC Calling Convention(SMCCC)OTP各个bit只能烧写一次,一旦置1后不可置0,请在确认需要的场合下执行烧写动作!
OTP相同位置烧写相同数据的动作可能会导致OTP内容损坏,不允许有重复写相同数据的动作
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执行许可证
支持在uboot下使用otpfactor指令进行自动烧录,详见6.6. otpfactor指令自动烧录OTP章节
6.2. security boot相关的OTP栏位¶
如果客户使用security boot功能,需要关注OTP以下内容:
OTP command ID length(byte) Description OTP_RSA_N 0X00 512 保存用于验签IPL的RSA public key的 N 值。走ecc256流程时,保存Public Key值 OTP_RSA_E 0X01 4 保存用于验签IPL的RSA public key的 E 值。走ecc256流程时,不能烧录值 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 使用RSA2048签章,不用烧录,使用其它签章方式需要烧录 OTP_PSS_PKCS_SELECT 0X52 1(bit) 使用rsa签章时,选择PSS填充方式需要烧录,选择PKCS填充方式不需要烧录 各个OTP栏位的烧录方法举例说明如下。
6.2.1. OTP_RSA_N (0x0) / OTP_RSA_E (0x1)¶
走rsa2048 or rsa4096流程:
对于生成的rsa public.pem文件,需要先将pem格式转化成可以用于烧录的格式。使用以下cmd生成rsaKey.txt,rsaKey.txt中的command在UBOOT下烧写OTP。
./key_proc.py --exportkey_reverse --rsa=private.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次执行。
如果走ECC系列算法的签章验签流程:
对于生成的pem格式的ecc密钥,需要先使用如下指令将密钥转化为der格式
openssl ec -in private.pem -outform DER -out private.der再使用如下指令将der格式转化成可以用于烧录的格式,执行后会生成rsaKey.txt,使用rsaKey.txt中的command在UBOOT下烧写OTP。
SM2算法:
./key_proc.py --exportkey_ecc --ec=private-otp.der --curves=SM2ECC256算法:
./key_proc.py --exportkey_ecc --ec=private-otp.der --curves=secp256r1ECC384算法:
./key_proc.py --exportkey_ecc --ec=private-otp.der --curves=secp384r1ECC512算法:
./key_proc.py --exportkey_ecc --ec=private-otp.der --curves=brainpoolP512r1举例使用现成的ecc256 pem文件转化后的rsaKey.txt内容如下,直接复制粘贴到uboot 菜单命令行下执行即可:
####### ECC PX ######## otpctrl -w 0x0 0x0 0xb73a3460;otpctrl -w 0x0 0x4 0x0eb47647;otpctrl -w 0x0 0x8 0x4c9d7ce7;otpctrl -w 0x0 0xc 0x681eb04d;otpctrl -w 0x0 0x10 0xd7d5f581;otpctrl -w 0x0 0x14 0x4be74af8;otpctrl -w 0x0 0x18 0x4acf2678;otpctrl -w 0x0 0x1c 0x4cdaae72; ####### ECC PY ######## otpctrl -w 0x0 0x20 0x74b17388;otpctrl -w 0x0 0x24 0x699da51e;otpctrl -w 0x0 0x28 0x839b3a07;otpctrl -w 0x0 0x2c 0xf57cca01;otpctrl -w 0x0 0x30 0x0da38989;otpctrl -w 0x0 0x34 0xc5eb0a46;otpctrl -w 0x0 0x38 0x1cd03251;otpctrl -w 0x0 0x3c 0xc63407cf;检查rsa/ecc key是否成功写入:
6.2.2. OTP_SECURE_BOOT (0x2)¶
确认RSA/AES key都烧录后,启动security boot功能(下次启动才会生效):
检查security boot功能是否已开启:
结果为 0xFFFFFFFF 表示开启,重启后生效
6.2.3. OTP_RSA_KEY_LOCK (0x3) / OTP_RSA_KEY_BLOCK (0x4)¶
非必要操作,客户可根据需求使用。
确认LOCK和BLOCK rsa key(下次启动才会生效):
检查LOCK和BLOCK是否已开启:
结果为 0xFFFFFFFF 表示开启,重启后生效
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中可以存放有8把AES128 KEY,一把key占有16-Bytes的OTP位置。在设置完该Command后,须于下次启动才会生效。
ALL AESKEY WRITE COMMAND:
-
KEY1
WRITE COMMAND:
otpctrl -w 0x5 offset writedataREAD COMMAND:
otpctrl -r 0x5Example:
制作AES KEY: echo '000102030405060708090A0B0C0D0E0F' | xxd -r -ps > aesKey1.bin otpctrl -w 0x5 0x0 0x03020100 otpctrl -w 0x5 0x4 0x07060504 otpctrl -w 0x5 0x8 0x0B0A0908 otpctrl -w 0x5 0xC 0x0F0E0D0C -
KEY2
WRITE COMMAND:
otpctrl -w 0x6 offset writedataREAD COMMAND:
otpctrl -r 0x6Example:
制作AES KEY: echo '00112233445566778899AABBCCDDEEFF' | xxd -r -ps > aesKey2.bin otpctrl -w 0x6 0x0 0x33221100 otpctrl -w 0x6 0x4 0x77665544 otpctrl -w 0x6 0x8 0xBBAA9988 otpctrl -w 0x6 0xC 0xFFEEDDCC -
KEY3
WRITE COMMAND:
otpctrl -w 0x7 offset writedataREAD COMMAND:
otpctrl -r 0x7Example:
制作AES KEY: echo '030102030405060708090A0B0C0D0E0F' | xxd -r -ps > aesKey3.bin otpctrl -w 0x7 0x0 0x03020103 otpctrl -w 0x7 0x4 0x07060504 otpctrl -w 0x7 0x8 0x0B0A0908 otpctrl -w 0x7 0xC 0x0F0E0D0C -
KEY4
WRITE COMMAND:
otpctrl -w 0x8 offset writedataREAD COMMAND:
otpctrl -r 0x8Example:
制作AES KEY: echo '04112233445566778899AABBCCDDEEFF' | xxd -r -ps > aesKey4.bin otpctrl -w 0x8 0x0 0x33221104 otpctrl -w 0x8 0x4 0x77665544 otpctrl -w 0x8 0x8 0xBBAA9988 otpctrl -w 0x8 0xC 0xFFEEDDCC -
KEY5
WRITE COMMAND:
otpctrl -w 0x9 offset writedataREAD COMMAND:
otpctrl -r 0x9Example:
制作AES KEY: echo '05112233445566778899AABBCCDDEEFF' | xxd -r -ps > aesKey5.bin otpctrl -w 0x9 0x0 0x33221105 otpctrl -w 0x9 0x4 0x77665544 otpctrl -w 0x9 0x8 0xBBAA9988 otpctrl -w 0x9 0xC 0xFFEEDDCC -
KEY6
WRITE COMMAND:
otpctrl -w 0xA offset writedataREAD COMMAND:
otpctrl -r 0xAExample:
制作AES KEY: echo '06112233445566778899AABBCCDDEEFF' | xxd -r -ps > aesKey6.bin otpctrl -w 0xA 0x0 0x33221106 otpctrl -w 0xA 0x4 0x77665544 otpctrl -w 0xA 0x8 0xBBAA9988 otpctrl -w 0xA 0xC 0xFFEEDDCC -
KEY7
WRITE COMMAND:
otpctrl -w 0xB offset writedataREAD COMMAND:
otpctrl -r 0xBExample:
制作AES KEY: echo '07112233445566778899AABBCCDDEEFF' | xxd -r -ps > aesKey7.bin otpctrl -w 0xB 0x0 0x33221107 otpctrl -w 0xB 0x4 0x77665544 otpctrl -w 0xB 0x8 0xBBAA9988 otpctrl -w 0xB 0xC 0xFFEEDDCC -
KEY8
WRITE COMMAND:
otpctrl -w 0xC offset writedataREAD COMMAND:
otpctrl -r 0xCExample:
制作AES KEY: echo '08112233445566778899AABBCCDDEEFF' | xxd -r -ps > aesKey8.bin otpctrl -w 0xC 0x0 0x33221108 otpctrl -w 0xC 0x4 0x77665544 otpctrl -w 0xC 0x8 0xBBAA9988 otpctrl -w 0xC 0xC 0xFFEEDDCC -
KEY256_1
WRITE COMMAND:
otpctrl -w 0x5 offset writedata otpctrl -w 0x6 offset writedataREAD COMMAND:
otpctrl -r 0x5 otpctrl -r 0x6Example:
制作AES KEY: echo '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F' | xxd -r -ps > aesKey256_1.bin 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
KEY256_2/KEY256_3/KEY256_4 烧录方法与KEY256_1类似
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(下次启动才会生效):
第一把AES128 key检查LOCK和BLOCK是否已开启:
确认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是否已开启:
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。
Read cmd:
otpctrl -r 0x24Example:
-
选择 AESKEY128_1
otpctrl -w 0x24 0x0 0xFF000000读到数据为 0xFF000000 表示成功写入
-
选择 AESKEY128_2
otpctrl -w 0x24 0x0 0xFF0000FF读到数据为 0xFF0000FF 表示成功写入
-
选择 AESKEY128_3
otpctrl -w 0x24 0x0 0xFF00FF00读到数据为 0xFF00FF00 表示成功写入
-
选择 AESKEY128_4
otpctrl -w 0x24 0x0 0xFF00FFFF读到数据为 0xFF00FFFF 表示成功写入
-
选择 AESKEY128_5
otpctrl -w 0x24 0x0 0xFFFF0000读到数据为 0xFFFF0000 表示成功写入
-
选择 AESKEY128_6
otpctrl -w 0x24 0x0 0xFFFF00FF读到数据为 0xFFFF00FF 表示成功写入
-
选择 AESKEY128_7
otpctrl -w 0x24 0x0 0xFFFFFF00读到数据为 0xFFFFFF00 表示成功写入
-
选择 AESKEY128_8
otpctrl -w 0x24 0x0 0xFFFFFFFF读到数据为 0xFFFFFFFF 表示成功写入
另外IPL可以使用AES256解密,OTP中AESKEY256实际上是由OTP中两把AES128组合而成,组合和设置方式举例如下:
-
选择 AESKEY256_1(Composition mode: AES128key1 + AES128key2)
otpctrl -w 0x24 0x0 0x00FF0000读到数据为 0x00FF0000 表示成功写入
-
选择 AESKEY256_2(Composition mode: AES128key3 + AES128key4)
otpctrl -w 0x24 0x0 0x00FF00FF读到数据为 0x00FF00FF 表示成功写入
-
选择 AESKEY256_3(Composition mode: AES128key5 + AES128key6)
otpctrl -w 0x24 0x0 0x00FFFF00读到数据为 0x00FFFF00 表示成功写入
-
选择 AESKEY256_4(Composition mode: AES128key7 + AES128key8)
otpctrl -w 0x24 0x0 0x00FFFFFF读到数据为 0x00FFFFFF 表示成功写入
6.2.7. OTP_ROM_SEL_AESKEY_LOCK (0x25)¶
非必要操作,客户可根据需求使用。
确认LOCK和BLOCK OTP_ROM_SEL_AESKEY里的内容(下次启动才会生效):
检查LOCK和BLOCK是否已开启:
结果为 0xFFFFFFFF 表示开启,重启后生效
6.2.8. OTP_RSA_KEY_LEN(0x2F)¶
该Command被使用来配置RSA_KEY的长度,默认长度为2048bit。
在设置完该Command后,须于下次启动才会生效。
若想设置为RSA4096验签,请烧此OTP
WRITE COMMAND:
READ COMMAND:
读到 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 表示烧录成功
若想设置为ECC256验签,请烧此OTP
WRITE COMMAND:
READ COMMAND:
读到 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 表示烧录成功
若想设置为ECC384验签,请烧此OTP
WRITE COMMAND:
READ COMMAND:
读到 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 表示烧录成功
若想设置为SM2验签,请烧此OTP
WRITE COMMAND:
READ COMMAND:
读到 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 表示烧录成功
6.2.9. OTP_PSS_PKCS_SELECT(0x52)¶
使用rsa签章方式时,默认使用PKCS填充方式,如果选择PSS填充方式烧录此OTP:
检查是否烧写成功:
读到0x08, 0x00, 0x00, 0x00,表示烧录成功(最低位字节的BIT3为1),重启后生效
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,每4bytes表示一次进阶版本,最多可进版64次 OTP_IPL_CUST_ANTI_ROLLBACK 0x2C 64 保存IPL_CUST的OTP version,每4bytes表示一次进阶版本,最多可进版16次 OTP_TF_A_ANTI_ROLLBACK 0x2C 64 保存TF_A的OTP version,每4bytes表示一次进阶版本,最多可进版16次 OTP_OPTEE_ANTI_ROLLBACK 0x2C 64 保存OPTEE的OTP version,每4bytes表示一次进阶版本,最多可进版16次 OTP_VMM_ANTI_ROLLBACK 0x2C 64 保存VMM的OTP version,每4bytes表示一次进阶版本,最多可进版16次 OTP_UBOOT_ANTI_ROLLBACK 0x2C 64 保存BOOT的OTP version,每4bytes表示一次进阶版本,最多可进版16次 OTP_KERNEL_ANTI_ROLLBACK 0x2C 64 保存KERNEL的OTP version,每4bytes表示一次进阶版本,最多可进版16次 OTP_RTOS_ANTI_ROLLBACK 0x2C 64 保存RTOS的OTP version,每4bytes表示一次进阶版本,最多可进版16次 各个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
IPL OTP Version = 2
IPL OTP Version = 3
以此类推。
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
IPL_CUST OTP Version = 2
IPL_CUST OTP Version = 3
以此类推。
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
TF_A OTP Version = 2
TF_A OTP Version = 3
以此类推。
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
OPTEE OTP Version = 2
OPTEE OTP Version = 3
以此类推。
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
UBOOT OTP Version = 2
UBOOT OTP Version = 3
以此类推。
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
KERNEL OTP Version = 2
KERNEL OTP Version = 3
以此类推。
6.4. 防止错误注入和信号分析功能相关的OTP栏位¶
如果客户使用防止错误注入和信号分析功能(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的总开关,烧录后须于下次启动才会生效。
检查总开关是否已开启:
结果为 0xFFFFFFFF 表示开启,重启后生效
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内容如下:

再启动rsa2sha1的子开关:
读到结果为 0xFFFFFFFF 表示开启,重启后生效
如果使用ecc系列算法流程,对于ecc public.der 文件,制作key-SHA1的方法如下:
SM2:
./key_proc.py --key2sha1 -f public-otp.der --curves SM2ECC256:
./key_proc.py --key2sha1 -f public-otp.der --curves secp256r1ECC384:
./key_proc.py --key2sha1 -f public-otp.der --curves secp384r1ECC512:
./key_proc.py --key2sha1 -f public-otp.der --curves brainpoolP512r1 ------------------------------------------------------>public-otp.der_sha1.txt其他烧录部分与上面相同
6.4.3. OTP_PASSWORD_CHK_ENABLE(0x32) / OTP_PASSWORD_CHK¶
非必要操作,客户可根据需求使用。注意开启 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内容如下:

再启动pwd2sha1的子开关:
读到结果为 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_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第1把,则烧录bin_sha1.txt内容到OTP_KEY1_CHK
如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第2把,则烧录bin_sha1.txt内容到OTP_KEY2_CHK
如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第3把,则烧录bin_sha1.txt内容到OTP_KEY3_CHK
以此类推。
再启动aes2sha1的子开关:
读到结果为 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:
读到结果为 0xFFFFFFFF 表示开启,重启后生效
6.5. 用户自定义数据相关的OTP栏位¶
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:
以此类推。
最后4byte WRITE COMMAND:
CUSTOMER_AREA读取:
6.5.2. OTP_CUSTOMER_AREA_LOCK(0xA1~0xA8)¶
LOCK 0k~1K bits数据(下次启动才会生效):
LOCK 1k~2K bits数据(下次启动才会生效):
LOCK 2k~3K bits数据(下次启动才会生效):
LOCK 3k~4K bits数据(下次启动才会生效):
LOCK 4k~5K bits数据(下次启动才会生效):
LOCK 5k~6K bits数据(下次启动才会生效):
LOCK 6k~7K bits数据(下次启动才会生效):
LOCK 7k~8K bits数据(下次启动才会生效):
6.6. otpfactor指令自动烧录OTP¶
在uboot下支持使用otpfactor指令自动烧录secureboot相关的OTP栏位,需要自行修改uboot otpctrl.c中定义的数据,修改为需要烧录到OTP中的数据。
在otpfator的执行函数do_otpfactor()中,会先查看芯片中的Secureboot enable是否烧录,如果没有烧录,才会往下执行其他数据的烧录。如果不需要该逻辑,可自行修改注释。

6.6.1. 烧录RSA/ECC Key¶
由于OTP对烧录的密钥顺序有特殊要求,需要使用下面方法定义需要烧录的数据。
RSA2048/RSA4096
./key_proc.py --exportkey_reverse --rsa=private.pemSM2算法:
./key_proc.py --exportkey_ecc --ec=private.der --curves=SM2ECC256算法:
./key_proc.py --exportkey_ecc --ec=private.der --curves=secp256r1ECC384算法:
./key_proc.py --exportkey_ecc --ec=private.der --curves=secp384r1ECC512算法:
./key_proc.py --exportkey_ecc --ec=private.der --curves=brainpoolP512r1执行对应指令后会生成rsaKey_c_array.txt文件,该文件存放的是Public key的C语言数据的格式。将文件中的内容替换到otpctrl.c中已定义的rsa2048[256]/rsa4096[512]/sm2_key[64]/ecc256[64]/ecc384[96]/ecc512[128]数组中。如下图
RSA2048:

RSA4096:

SM2:

ECC256:

ECC384:

ECC512:

将 OTP_SIGN_ALG 宏修改为需要使用的对应算法

SIGN ALG ALG MICRO RSA2048 SIGN_ALG_RSA2048 RSA4096 SIGN_ALG_RSA4096 SM2 SIGN_ALG_SM2 ECC256 SIGN_ALG_ECC256 ECC384 SIGN_ALG_ECC384 ECC512 SIGN_ALG_ECC512 do_otpfactor()中会执行对应密钥的自动烧录,如下图代码。

另外,RSA key的锁读和锁写位的烧录如下代码,可自行开启。

6.6.2. 烧录AES Key¶
修改aeskey1~8数组中的数据:

将 OTP_ROM_SELECT_AES 宏修改为需要使用的对应的AES KEY

AES KEY AES KEY MICRO AES128_1 ROM_SELECT_AES128_KEY1 AES128_2 ROM_SELECT_AES128_KEY2 AES128_3 ROM_SELECT_AES128_KEY3 AES128_4 ROM_SELECT_AES128_KEY4 AES128_5 ROM_SELECT_AES128_KEY5 AES128_6 ROM_SELECT_AES128_KEY6 AES128_7 ROM_SELECT_AES128_KEY7 AES128_8 ROM_SELECT_AES128_KEY8 AES256_1 ROM_SELECT_AES256_KEY1 AES256_2 ROM_SELECT_AES256_KEY2 AES256_3 ROM_SELECT_AES256_KEY3 AES256_4 ROM_SELECT_AES256_KEY4 do_otpfactor()中会执行对应ROM SELECT AESKEY的自动烧录,并烧录8把aeskey,如下图代码。如不需要烧录8把aeskey,可自行注释相关代码行。

另外,aeskey的锁读和锁写位的烧录如下代码,可自行开启。

6.6.3. 烧录Secureboot enable¶
do_otpfactor()的最后会烧录Secureboot enable

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/ECC public/private key,替换security_boot_tools/aes/和rsa2048/rsa4096/sm2/ecc256/ecc384/ecc512目录下的key文件。详见5.1. 制作RSA/ECC key和aes Key。
第二步:使用U-Boot Command otpctrl 烧录RSA/ECC 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。
-
ROM->IPL确认是否走SecurityBoot的方式
ROM验签IPL成功不会有任何log,但验签失败则会打印AUTH ERR(波特率可能需要调为115200,否则乱码)。
-
IPL->IPL_CUST->U-Boot确认是否走SecurityBoot的方式
查看log即可,一般带有Authenticate image关键字,若开启解密流程则还会有AES ECB关键字。
举例如下:

-
U-Boot -> kernel确认是否走SecurityBoot的方式
直接查看bootcmd是否有验签signature。详见5.4. signature cmd介绍。
7.2. Security Boot正式流程¶
调试模式能正常走Security 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。
-