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. Security Boot概述¶
为防止用户产品的固件被抄板或者刷机,Sigmastar固件在启动过程自动进行验签(或验签+解密),验签即签章的验证,防止软件加载的镜像内容被恶意篡改。其中加密和解密为可选,一般情况下镜像加密是为了防止镜像中的信息被泄露,而镜像验章是为了防止镜像的信息被篡改,用户可根据自身需求取舍。使用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中。
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脚本完成,流程如下:
- security_boot_tools对Image 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',若对比一致,则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变化¶
需要注意:
- 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 Key
和RSA 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文件内容的指定位置。
第三把为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文件内容的指定位置。
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支持解密(是否开启解密取决于需求)。
-
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进行解密。
-
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进行解密。
-
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进行解密。
-
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不支持加密。
-
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进行解密。
-
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。
以下是 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及原理如下:
-
在烧写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 key和aes Key,替换Security_boot_tools工具目录下默认的RSA 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 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:
-
生成RSA私钥
openssl genrsa -out private.pem 2048
-
生成RSA公钥
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
RSA4096:
-
生成RSA私钥
openssl genrsa -out private.pem 4096
-
生成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。-
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 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¶
实际操作步骤如下:
-
进入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> <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内容如下:
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内容如下:
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_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。
-
ROM->IPL确认是否走SecurityBoot的方式
ROM验签IPL成功不会有任何log,但验签失败则会打印AUTH ERR(波特率可能需要调为38400或57600,否则乱码)。
-
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正式流程¶
调试模式能正常走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。
-