此文档使用了secure boot 2.1方案的配置,如有其他版本的secure方案,本文档仅作参考,secure boot方案可在security MTK文档中查到,也可以咨询MTK,此文档适配于:MTK6739等平台。
Secure boot & Efuse方案和硬件强相关,在开始调试之前切记以下要点:
1. 确保所有的keys都是一次性生成的,keys、证书、hash一定要匹配,如果不确定,请全部重新生成一次
2. 生成keys之后谨慎保存,如无必要,尽量不做修改(尤其是root_key),修改之后,以前efuse的芯片便无法再使用。
3. 再所有方案double 验证OK之前,不要上传secure boot的开关宏,以免造成大面积芯片废弃
Secure_2.1_Configuration_SOP.pdf
Efuse_self_blow_user_guide_v1.3.pdf
利用openssl生成private key和publickey,并用pem_to_der.pyiaoben转换key的格式为pem
生成private key:
opensslgenrsa -out root_prvk.pem 2048
/*rsa是格式,2048是长度,目前在MTK都保持这样的格式*/
转换格式:
pythonpem_to_der.py root_prvk.pem root_prvk.der
生成public key
opensslrsa -in root_prvk.pem -pubout > root_pubk.pem
转换格式:
pythonpem_to_der.py root_pubk.pem root_pubk.der
生成img key,用来签名和校验img
openssl genrsa -out image_prvk.pem 2048
以上操作如下面演示:
用der_extractor脚本将root key(root_pubk.der)导出生成oemkey.h,然后放到下面三个目录
生成命令:
./der_extractor root_pubk.der oemkey.h ANDROID_SBC
生成方式如图:
【DA】DA的生成交给Tool team,SW只需要提供oemkey.h给工具组即可
【PL】:$PL/custom/$project/inc/oemkey.h
【LK】:$LK/target/$project/inc/oemkey.h
同样的方式将root_pubk.der导出生成dakey.h
功能:dakey.h中包含的DA_PLpublic key public key用于preloader校验DA_PL.bin,所以在签名DA_PL.bin时需要拿这个key对应的private key对DA_Pluo签名
Note:值得注意的是,由于DA_PL下载权限很低,所以通常我们的DA都使用DA_BROM的方式去做下载,但是推荐此处同样配置OK。
dakey和oemkey都是用同样的pubk key生成的,所以生成出来的dakey和oemkey都是相同的,但是在dakey中需要修改部分内容,否则会导致编译报错:
Dakey.h生成后存放位置:
【PL】:$PL/custom/$project/int/dakey.h
Preloader配置:
vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$project/$project.mk
MTK_SECURITY_SW_SUPPORT=yes
MTK_SEC_BOOT=
MTK_SEC_USBDL=
Note:上述两个BOOT和USBDL宏如果是SW root of trust,意味着,硬件上不实现efuse,但sw上要强制打开secure boot和securitydownload,那么需要如下配置:
MTK_SEC_BOOT=ATTR_SBOOT_ENABLE
MTK_SEC_USBDL=ATTR_SUSBFL_ENABLE
如果是hw root of trust,意味着会烧写efuse,并在efuse后打开secure boot和secure download,需要如下配置(默认)
MTK_SEC_BOOT=ATTR_SBOOT_ONLY_ENABLE_ON_SHIP
MTK_SEC_USBDL=ATTR_SUSBDL_ONLY_ENABLE_ON_SHIP
vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$project_name/cust_bldr.mk
MTK_EFUSE_WRITER_SUPPORT :=yes/*注意定义的格式*/
MTK_EFUSE_WRITER_RESERVE_CODESIZE := yes
CFG_USB_AUTO_DETECT := 1 //注意这个宏,此宏定义生效,下载阶段强制枚举BROM端口,DA和AUTH将在这里校验,如果该宏没有定义,会导致端口错误
~/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mtxxxx/src/security/inc/sec_efuse.h
#define EFUSE_BLOW_KEY1 0x90b1e2f6 //此为MTK默认值,建议修改定制
#define EFUSE_BLOW_KEY2 0x73d5a8c9
该项和input.xml中的magic key对应,在input.xml中详细解释配置方法
Lk配置
vendor/mediatek/proprietary/bootable/bootloader/lk/project/$project.mk
MTK_SECURITY_SW_SUPPORT=yes
MTK_EFUSE_WRITER_SUPPORT :=yes
Note:此处有两个宏是可选的,如需支持fastbootunlock的命令,可以将此处打开,但目前和MTK沟通,此功能开发尚未完全,需要自行定制,建议在调试该功能时先关闭。否则通过fastboot刷机会有风险。
MTK_SEC_FASTBOOT_UNLOCK_SUPPORT
MTK_SEC_FASTBOOT_UNLOCK_KEY_SUPPORT
Kernel配置:
根据project选项defconfig配置,需要确定是用arm32还是arm64:
kernel-4.x/arch/arm/configs/
在所有项目的defcofnig和def_debug_cofnig中添加:
MTK_SECURITY_SW_SUPPORT=yes
DEVICE配置
Device/mediatek/$project/ProjectConfig.mk
MTK_EFUSE_WRITER_SUPPORT=yes
Build cert_chain格式的preloader是在build的过程中sign的,那么签名的配置是使用cert_chain签名格式:
1.将生成的root key(包括root_prvk.pem , img_prvk.pem)cp到以下路径:
~/vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/security/chip_config/s/key/
配置宏配置sign preloader的pem路径:
Pl_content.ini 中配置imgkey路径:
Note:上述两个ini中sw_ver版本号需要一致
Pl_gfh_config_cert_chain.ini配置
注意:里面的version等其他信息,请不要随意更改
使用python形式的sign tool配置
先确定该路径:~/vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/security/chip_config/s/cfg下的PBP_BY_SUPPORT文件是否存在,如果遇到不存在的,请重新同步或者向MTK索要
Padding type的配置
确定同样路径下:
/vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/security/chip_config/s/cfg/
的PADDING_TYPE.ini中是否有设置:
Cert_chain /*代表生成preloader的格式是以cert_chain格式的*/
Resign preloader,secure 2.1支持在build的过程中去签名preloader,也支持对已签名的镜像进行re-sign
产生cert1和cert2
用security2.1生成的root_prvk.pem和image_prvk.pem产生cert1和cert2_key
检查SecureGen.py脚本中几个关键点,如果没有需要自己添加:
/vendor/mediatek/proprietary/scripts/sign-image_v2/SecureGen.py
def genCert1(binList)
....
if ( isMD == 0):
if(argDict["root_key_padding"]):
sh_command= "python "+ resign_tool_path+ " type=cert1 privk="+argDict["cert1_key_path"] +"pubk="+cert2_pubk_path+" ver="+str(img_ver)+"group="+str(img_group)+" root_key_padding="+str(argDict["root_key_padding"])
else:
sh_command= "python "+ resign_tool_path+ " type=cert1 privk="+argDict["cert1_key_path"] +"pubk="+cert2_pubk_path+" ver="+str(img_ver)+" group="+str(img_group)
tmp_out_path= out_cert1_path
else:
mdBin =os.path.join(out, part_name+".img")
if(os.path.isfile(mdBin) ):
printmdBin+" exist"
if(argDict["root_key_padding"]):
sh_command= "python "+ resign_tool_path+ " type=cert1mdimg="+mdBin+" privk="+argDict["cert1_key_path"]+" pubk="+cert2_pubk_path+" ver="+str(img_ver)+"group="+str(img_group)+" root_key_padding="+str(argDict["root_key_padding"])
else:
sh_command= "python "+ resign_tool_path+ " type=cert1md img="+mdBin+"privk="+argDict["cert1_key_path"] +"pubk="+cert2_pubk_path+" ver="+str(img_ver)+"group="+str(img_group)
tmp_out_path= out_cert1md_path
else:
printmdBin+" Not exist"
print"Bypassmd image cert1 Gen!"
执行以下命令
./ vendor/mediatek/proprietary/scripts/sign-image_v2/SecureGen.py mt67xx cert1_key_path=${KEY_PATH}/root_prvk.pem cert2_key_path=${KEY_PATH}/img_prvk.pem root_key_padding=pss | tee securegen.log
以上KEY_PATH=指存放root_prvk.pem和img_prvk.prm的路径
说明:
请在codebase的根目录下使用该脚本,包括签名脚本,否则无法加载到环境参数
根据cert1_key_path的key,生成所有的img的cert1到
/vendor/mediatek/proprietary/custom/security/cert_config/cert1
根据cert2_key_path的key,生成所有的image的cert2到:
/vendor/mediatek/proprietary/custom/security/cert_config/cert2_key/
执行完secureGen.py后,请检查上面目录文件是否更新
建议保留gen的log,以防doubleconfirm时没有参照依据。
Cert2和cert2的key正确产生之后,就可以执行签名脚本,产生xx-verified.bin/img了,执行如下命令进行签名:
./vendor/mediatek/proprietary/scripts/sign-image_v2/SignFlow.py $platform $project | tee sign.log
或者
vendor/mediatek/proprietary/scripts/sign-image/sign_image.sh
提供oemkey.h生成DA_BR.bin,详细生成DA的情况在window下进行,详细请参考文档
SignDA的配置
Security2.1的DA需要使用python脚本进行签名
Key的配置:
所有对DA签名,生成auth和secrtfile的keys都放在:
~/vendor/mediatek/proprietary/scripts/secure_chip_tools/keys/下,如下:
drwxr-xr-x 2 keli cdgroup 4096 Dec 19 11:30 hsm/
drwxr-xr-x 2 keli cdgroup 4096 Dec 19 11:30 pbp/
drwxr-xr-x 2 keli cdgroup 4096 Dec 19 17:29 resignda/————对应DA
drwxr-xr-x 2 keli cdgroup 4096 Dec 19 11:33 sctrlcert/————对应secrtfile
drwxr-xr-x 2 keli cdgroup 4096 Dec 21 09:56 toolaut—————对应auth
而针对auth,da等的配置文件都存放于:
vendor/mediatek/proprietary/scripts/secure_chip_tools/settings/
drwxr-xr-x 6 keli cdgroup 4096 Dec 19 11:30 ./
drwxr-xr-x 8 keli cdgroup 4096 Dec 20 15:41 ../
drwxr-xr-x 2 keli cdgroup 4096 Dec 19 11:30 pbp/
drwxr-xr-x 2 keli cdgroup 4096 Dec 21 09:50 resignda/————对应DA
drwxr-xr-x 2 keli cdgroup 4096 Dec 20 15:13 sctrlcert/————对应secrtfile
drwxr-xr-x 2 keli cdgroup 4096 Dec 21 09:50 toolauth/—————对应auth
DA的keys:
其中da_prvk.pem和epp_prvk.pem都是RSA2048格式
-rw-r--r-- 1 keli cdgroup 1679 Nov 28 17:11 da_prvk.pem
-rw-r--r-- 1 keli cdgroup 1679 Nov 28 17:11 epp_prvk.pem
-rw-r--r-- 1 keli cdgroup 451 Nov 3009:32 PUBKda_prvk.pem
其中da_prvk可以openssl生成一份,也可以直接使用root_prvk去 rename。
签名DA_BR时,da_prvk.pem需要和auth中的DAA key匹配
签名DA_PL时要和dakey.h中的key匹配
Note:epp_prvk.pem可使用与da_prvk.pem一样的keys,epp_prvk,MTK说是为了兼容以前框架所用。
在settings的配置文件中:
bbchips_pss.ini中有如下配置需要double check
然后将需要签名的DA放在prebuilt/resignda/路径下,以psspadding的方式去执行DA的签名命令:
python resign_da.py prebuilt/resignda/newMTK_AllInOne_DA.bin ¥platform settings/resignda/bbchips_pss.ini all out/resignda/newMTK_DA.bin-resign
Efuse.xml的配置
Note:
Security 2.1 EFUSE烧录的efuse.xml文件需要配置key-type位,key-type值有legacy和pss两种,如果不配置,默认是legacy。值得注意的是,efuxe.xml需要联系MTK获取,不要自行修改或者混用。
Note!!!:相同的一组SBC Key,key-type设置不同则生成的key hash也不同,因此烧入refuse后无法更正,请确保key-type的配置是否正确,如果不确定,可以与MTK ACS support确认。、
....
preloader_¥project.bin //在此preloader中校验
...
type="BromUSB" //下载端口需要对应 ... key1="f6e2b190" key2="c9a8d573" /> /* 比如在code中的值如下 4#defineEFUSE_BLOW_KEY1 0x90b1e2f6 5#defineEFUSE_BLOW_KEY2 0x73d5a8c9 则efuse.xml中必须为 key1="f6e2b190" key2="c9a8d573"/> */ ... Disable_DBGPORT_LOCK="false" Enable_SW_JTAG_CON="true" Enable_ACC="false" Enable_ACK="false" Enable_SLA="true"//校验AUTH文件的SLA Enable_DAA="true"//校验DA,项目初调试,可以先开启DA,验证DA通过后,再开启AUTH验证,这样有助于定位问题 Enable_SBC="true"//校验SBC Disable_JTAG="false" /> com_ctrl_lock="false" //ctrl定制位锁 usb_id_lock="false"/> sec_msc_lock="false" sec_attr_lock="false" ackey_lock="false" sbc_pubk_hash_lock="false" /> //efuse hash的锁,字面理解,但有个疑问,既然是EFUSE,应该写入后熔断,为什么需要上锁呢?脱了裤子放个屁? ... md1_sbc_en="true"/> //区别于SecureBoot和AVB,这是MTK自己的modem签名验证功能 disable_self_blow="false" /> //是否允许自烧写 Efuse烧写了DAA or SLA,在下载的时候,需要用到auth file和scertfile,需要使用python脚本生成 Auth key配置: Auth的keys Auth的配置改动和MTK文档不同,auth处请详细参考该文档 da_pubk.pem*//da_prvk和sla_prvk:这里找了下逻辑,最终会根据prvk去拿pubk,所以可以直接用公钥,而prvk可以保存起来不开放。 epp_prvk.pem*//epp_prvk:和MTK确认过,是为了兼容之前的架构,可以不管,不会用到 root_pubk.pem sla_pubk.pem //这个由OEM同一使用,开发一般只能拿到pubk 在auth的settings配置中,先确定toolath_key.ini中 确认rootkey的路径是否OK 确认tooauth_gfh_config_pss.ini配置: 注意: 此处于上图差异部分: sla_pad_type与开启SLA功能客制化的sla_challenge.dll 使用的pad type一直,daa_pad_type_pad_type与sign DA使用的padding type一致 Auth生成命令: python toolauth.py -i settings/toolauth/toolauth_key.ini -gsettings/toolauth/toolauth_gfh_config_pss.ini out/toolauth/authXX.auth 一切配置OK,请做最后的double confirm(针对MTK6799,6767,6758,6739等新平台) 检查SBC_PUBK_HASH Key config: preloader/custom/$peoject/security/chip_config/s/key/pl_key.ini 检查自己的keys: 确定该路径下的prvk是自己本次配置的,如果不是,请覆盖root_prvk.pem 对于efuseself-blow,这些SBC_PUBK_HASH是由这里去获取,而不是配置在input.xml中 以上是security2.1 secure boot完全配置方案 Note: 在刷机前要确定efuse.img是否选中,并且分区中是否有对应的分区表信息 Effuse手机,需要电池电压高于3.7V(可以参考自己项目电池电量) 并且开机后,开机过程不要关机,确保efuse流程能正常运行完成 在共基线开发多个项目时,由于secure 2.1方案存在证书和密钥的路径是在平台路径下,没有区分项目,所以这块的策略需要处理: 1. vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/$platrm/src/security/inc/sec_efuse.h 该文件中定义了两个magic key,会在efuse.xml中对magickey进行匹配校验,所以对于这里的key需要做项目区分,当然也可以用同一个keys,这样efuse.xml中magickey也保持相同 2. ~/vendor/mediatek/proprietary/custom/$project/security/cert_config下存放了cert和keys 共基线策略: drwxr-xr-x 4 keli cdgroup 4096 Dec 27 16:32 XXX1/———新添加的项目X1文件夹,其中存放cert1和cert2_key drwxr-xr-x 2 keli cdgroup 4096 Dec 21 11:07 cert1/——通用的,可保持默认 drwxr-xr-x 2 keli cdgroup 4096 Dec 21 11:07 cert2_key/ -rw-r--r-- 1 keli cdgroup 311 Dec 2111:07 img_list.txt——签名镜像信息,设置签名镜像列表 -rw-r--r-- 1 keli cdgroup 886 Dec 2111:07 img_ver.txt——版本信息,确定每个签名版本的一些配置情况,使用默认即可 drwxr-xr-x 4 keli cdgroup 4096 Dec 27 17:21 XXX2/-------新添加的项目X2文件夹,其中存放cert1和cert2_key 以上项目名注意与环境变量中的项目名对应 3. 签名脚本 Cert_config是在签名的时候调用,所以也需要修改签名时候获取的路径: --- a/sign-image_v2/SignFlow.py +++ b/sign-image_v2/SignFlow.py @@ -41,9 +41,9 @@ def setPath(): if (project =="X1"): cert1_dir = cert_dir+"/XXX1/cert1/" cert2_key_dir = cert_dir+"/XXX1/cert2_key/" elif (project =="X2"): cert1_dir = cert_dir+"/XXX2/cert1/" cert2_key_dir =cert_dir+"/XXX2/cert2_key/" else: cert1_dir =cert_dir+"/cert1/" cert2_key_dir =cert_dir+"/cert2_key/" Efuse后,需要验证手机是否已经置于efuse状态,验证方法如下: 1. 开机在lk界面时:左下角会显示logo: Efuse blow:seccuesful 2. 开完成后,读取出efuse.img,查看里面内容,开头出现大量aaaaa内容即成功,如下: 怎么导出efuse分区: 在adbshell下/dev/block/platform/bootable/by-name/下,查找efuse对应的分区号:e.g. mmcblk0p17 然后remount后将分区导出 adb pull /dev/block/mmcblk0p17 然后查看分区数据:hd mmcblk0p17 00000000 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| * 00000200 1c 00 00 00 28 01 0000 ff 02 00 00 ff 02 00 00 |....(...........| 00000210 ff 02 00 00 ff 02 0000 29 01 00 00 00 00 00 00 |........).......| 00000220 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 |................| * 00080000 @test 3. 将未签名的镜像刷入,手机无法开机,然后再将镜像签名刷入,可开机。说明已经efuseAuth生成:
结束检查:
5. 共基线secure boot开发策略
6. 验证结果