MTK 平台 Secure Boot 配置过程

一、生成root key用于cert1的签名和验证

1.1 生成private key

1
2
3
4
5
#生成root_prvk.pem
openssl genrsa -out cert_chain/root_prvk.pem 2048
cp cert_chain/root_prvk.pem vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/key/root_prvk.pem
#将root_prvk.pem转换为root_prvk.der
python der_extractor/pem_to_der.py cert_chain/root_prvk.pem cert_chain/root_prvk.der

1.2 生成public key

1
2
3
4
#生成root_pubk.pem
openssl rsa -in cert_chain/root_prvk.pem -pubout > cert_chain/root_pubk.pem
#将root_pubk.pem转换为root_pubk.der
python der_extractor/pem_to_der.py cert_chain/root_pubk.pem cert_chain/root_pubk.der

1.3 生成oemkey.h

1
2
3
4
5
6
chmod 777 der_extractor/der_extractor
#将root_pubk.der拷贝到oemkey.h中
./der_extractor/der_extractor cert_chain/root_pubk.der cert_chain/oemkey.h ANDROID_SBC
cp cert_chain/oemkey.h Customization_Kit_buildspec/Raphael-da/custom/$PLATFORM/oemkey.h
cp cert_chain/oemkey.h vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/inc/oemkey.h
cp cert_chain/oemkey.h vendor/mediatek/proprietary/bootable/bootloader/lk/target/$PROJECT/inc/oemkey.h

1.4 生成dakey.h

1
2
3
4
5
#将root_pubk.der拷贝到dakey.h中
./der_extractor/der_extractor cert_chain/root_pubk.der cert_chain/dakey.h ANDROID_SBC
#将dakey.h中'OEM'替换成'DA'
sed -i 's/OEM/DA/g' cert_chain/dakey.h
cp cert_chain/dakey.h vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/inc/dakey.h

二、生成img key用于cert2的签名和验证

2.1 生成img private key

1
2
3
4
5
#生成img_prvk.pem
openssl genrsa -out cert_chain/img_prvk.pem 2048
cp cert_chain/img_prvk.pem vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/key/img_prvk.pem
#将img_prvk.pem转换为img_prvk.der
python der_extractor/pem_to_der.py cert_chain/img_prvk.pem cert_chain/img_prvk.der

2.2 生成img public key

1
2
3
4
#生成img_pubk.pem
openssl rsa -in cert_chain/img_prvk.pem -pubout > cert_chain/img_pubk.pem
#将img_pubk.pem转换为img_pubk.der
python der_extractor/pem_to_der.py cert_chain/img_pubk.pem cert_chain/img_pubk.der

三、打开Secure Boot相关功能宏

3.1 preloader部分

1
2
#vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/$project.mk
MTK_SECURITY_SW_SUPPORT=yes

(1)sw root of trust:不烧efuse,实现secure boot/security download

1
2
MTK_SEC_BOOT=ATTR_SBOOT_ENABLE
MTK_SEC_USBDL=ATTR_SUSBDL_ENABLE

(2)hw root of trust:烧efuse,实现secure boot/security download

1
2
3
4
5
MTK_SEC_BOOT=ATTR_SBOOT_ENABLE
MTK_SEC_USBDL=ATTR_SUSBDL_ENABLE
#或
MTK_SEC_BOOT=ATTR_SBOOT_ONLY_ENABLE_ON_SCHIP
MTK_SEC_USBDL=ATTR_SUSBDL_ONLY_ENABLE_ON_SCHIP

3.2 lk部分

1
2
#vendor/mediatek/proprietary/bootable/bootloader/lk/target/$PROJECT/$project.mk
MTK_SECURITY_SW_SUPPORT=yes

(1)支持fastboot指令

1
MTK_SEC_FASTBOOT_UNLOCK_SUPPORT=yes

(2)支持fastboot指令同时需要key的校验

1
MTK_SEC_FASTBOOT_UNLOCK_KEY_SUPPORT=yes

3.3 kernel部分

1
2
3
#kernel-4.9/arch/arm64/configs/$project_defconfig
#kernel-4.9/arch/arm64/configs/$project_debug_defconfig
CONFIG_MTK_SECURITY_SW_SUPPORT=y

四、签名配置

4.1 给preloader签名的流程

(1)将root key(root_prvk.pem及img_prvk.pem)拷贝至 vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/key/目录

(2)在vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/key/pl_key.ini中配置’rootkey’及’imgkey’路径

1
2
rootkey="root_prvk.pem"
imgkey="img_prvk.pem"

(3)在vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/key/pl_content.ini中配置’imgkey’路径

1
2
imgkey="img_prvk.pem"
#sw_ver需同pl_key.ini中保持一致,以保证preloader最终支持回滚

(4)vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/gfh/pl_gfh_config_cert_chain.ini配置

1
2
3
4
5
flash_dev="emmc"
sig_type="CERT_CHAIN"
pad_type="pss"
max_size="0x00040000"
sig_ver="2"

(5)python tool配置(存在即支持preloader的证书链格式签名)

vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/cfg/PBP_BY_SUPPORT

(6)padding type配置(存在即支持preloader的证书链格式签名)

vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_config/s/cfg/PADDING_TYPE.ini cert_chain

(7)build resign

secure_chip_tools=./vendor/mediatek/proprietary/scrips/secure_chip_tools/
将preloader.bin放到$secure_chip_tools/prebuilts/pbp目录下;

1
cp out/target/product/$PROJECT/preloader.bin ./vendor/mediatek/proprietary/scrips/secure_chip_tools/

将上述配置的pl_key.ini、pl_content.ini、pl_gfh_config_cert_chain.ini拷贝到$secure_chip_tools/settings/pbp目录下;
将vendor/mediatek/proprietary/scripts/sign-image_v2/cert_chain/中root_prvk.pem和img_prvk.pem拷贝到vendor/mediatek/proprietary/scrips/secure_chip_tools/keys/pbp目录中。
执行命令:

1
2
cd secure_chip_tools/
python pbp.py -i settings/pbp/pl_key.ini -k out/pbp/key_cert.bin -g settings/pbp/pl_gfh_config_cert_chain.ini -c settings/pbp/pl_content.ini -func sign -o out/pbp/preloader-signed.bin prebuilt/pbp/preloader.bin

检查out目录会生成key_cert.bin、signed.bin及sig_size.txt文件;
由于img private key不包含root private key,所以key_cert.bin需要通过上述指令用root private key来生成。
将生成的key_cert.bin放置到prebuilt/pbp路径下,执行指令:

1
2
cp out/pbp/key_cert.bin prebuilt/pbp/key_cert.bin
python pbp.py -k prebuilt/pbp/key_cert.bin -g settings/pbp/pl_gfh_config_cert_chain.ini -c settings/pbp/pl_content.ini -func sign -o out/pbp/preloader-signed.bin prebuilt/pbp/preloader.bin

4.2 给img签名的流程

(1)生成cert1和cert2 key

(2)检查vendor/mediatek/proprietary/scrips/sign-image_v2/img_key_deploy.py文件中是否包含以下内容:

1
2
3
4
5
6
7
8
9
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"])
...
if (os.path.isfile(mdBin)):
+ if (argDict["root_key_padding"]):
+ 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)+"root_key_padding="+str(argDict["root_key_padding"])

(3)执行指令生成cert1和cert2:

(Android O是SecureGen.py,Android P是img_key_deploy.py)

1
./vendor/mediatek/proprietary/scripts/sign-image_v2/img_key_deploy.py $PLATFORM 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=./vendor/mediatek/proprietary/scripts/sign-image_v2/cert_chain)

(4)检查cert1及cert2:

vendor/mediatek/proprietary/custom/$PLATFORM/security/cert_config/cer1_key
vendor/mediatek/proprietary/custom/$PLATFORM/security/cert_config/cer2_key

(5)签名image

1
2
3
4
python vendor/mediatek/proprietary/scripts/sign-image_v2/sign_flow.py $PLATFORM $PROJECT | tee sign_flow.log
./vendor/mediatek/proprietary/scripts/sign-image/sign_image.sh
export BOARD_AVB_ENABLE=$(BOARD_AVB_ENABLE)
python vendor/mediatek/proprietary/scripts/sign-image_v2/sign_flow.py -env_cfg vendor/mediatek/proprietary/scripts/sign-image_v2/env.cfg $PLATFORM $PROJECT

4.3 com port设置

(1)disable brom com port

./vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/$PROJECT/security/chip_configs/s/gfh/pl_ghf_config_cert_chain.ini
./vendor/mediatek/proprietary/scripts/secure_chip_tools/settings/pbp/pl_ghf_config_cert_chain.ini

1
brom_magic_cmd_mode_permanent_dis = "1"

(2)disable preloader com port

./vendor/mediatek/proprietary/bootable/bootloader/preloader/$PLATFORM/default.mak

1
2
CFG_USB_TOOL_HANDSHAKE := 0
CFG_UART_TOOL_HANDSHAKE := 0

五、DA配置

5.1 环境配置

1
2
3
4
gcc_path: http://launchpad.ent/gcc-arm-embendded/+download
gcc_version: gcc-arm-none-eabi-4_9-20150306-win32.zip
gcc_install_path: Customization_Kit_buildspec\Raphael-da\make\base.mk
~GCCDIR := C://progra~1/GCC/arm-2015q1/bin

5.2 编译DA

(1)DA_BR:MTK_AllInOne_DA.bin

1
make BBCHIP=$PLATFORM

(2)DA_PL:DA_PL.bin

1
make BBCHIP=$PLATFORM DA_PL=yes

5.3 签名DA

(1)oemkey.h

Customization_Kit_buildspec/Raphael-da/custom/$PLATFORM/oemkey.h

(2)da_prvk.pem同epp_prvk.pem一样

(3)da_prvk.pem需与preloader的dakey.h中key匹配,另外还需与authfile中的DAA key匹配

(4)bbchip_pss.ini配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#从下载日志中获取chip相关信息:
hw_code=0x6799
hw_sub_code=0x8a00

hw_ver=0xca00
sw_ver=0x0:

#配置key路径
load_region0_sigtype=epp
load_region0_sigpad=pss
load_region0_key=keys/resignda/epp_prvk.pem
load_region1_sigtype=da
load_region1_sigpad=pss
load_region1_key=keys/resignda/da_prvk.pem
load_region2_sigtype=da
load_region2_sigpad=pss
load_region2_key=keys/resignda/da_prvk.pem

(5)将需要签名的DA放入prebuilt/resignda目录下,执行指令:

1
python resign_da.py prebuilt/resignda/MTK_AllInOne_DA.bin $PLATFORM settings/resignda/bbchip_pss.ini all out/resignda/MTK_AllInOne_DA.bin-resign

六、efuse.xml配置

配置key-type栏位
cert_chain格式preload对应的key_type是”pss”,Pub-key-e需设置为01001
(key-type设置不同则key hash也会不同)

1
2
3
4
<sbc-pub-key>
<key-type>pss</key-type>
<pub-key-e>01001</pub-key-e>
<pub-key-n>

七、AuthFile

7.1 authfile key的配置

在vendor/mediatek/proprietary/scrips/secure_chip_tools/settings/toolauth/toolauth_key.ini中配置rootkey的路径

1
2
3
sw_ver="1"
rootkey="keys/toolauth/root_prvk.pem"
img_key="keys/toolauth/img_prvk.pem"

7.2 daa和sla prvk的配置(RSA2048)

vendor/mediatek/proprietary/scrips/secure_chip_tools/keys/toolauth

7.3 toolauth_gfh_config_pss.ini的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[CHIP]
version="mt6799"
[GFH_FILE_INFO]
version="1"
file_type="5"
start_addr="0x00201000"
flash_dev="ufs"
sig_type="SINGLE"
pad_type="pss"
max_size="0x0040000"
[CFH_TOOL_AUTH]
version="1"
cust_name="MTK"
attr="0x0"
sla_public_key="key/toolauth/sla_prvk.pem"
sla_pad_type="pkcs1"
daa_public_key="key/toolauth/daa_prvk.pem"
daa_pad_type="pss"

(sla_pad_type需同sla_challenge.dll中pad type一致,daa_pad_type需与签名DA配置的padding type一致)

7.4 生成authfile指令

1
python toolauth.py -i settings/toolauth/toolauth_key.ini -g settings/toolauth/toolauth_gfh_config_pss.ini out/toolauth/auth_sv5.auth_sv5

八、ScertFile

8.1 Scertfile key的配置

生成primary_dbg_prvk及secondary_dbg.prvk(RSA2048)
vendor/mediatek/proprietary/scrips/secure_chip_tools/keys/sctrlcert

8.2 ini的配置

(1)settings/sctrlcert/scc_key.ini

1
2
3
4
5
[KEY]
sw_ver="1"
rootkey="keys/sctrlcert/root_prvk.pem"
imgkey="keys/sctrlcert/primary_dbg_prvk.pem"
ac_key="0X112233445566778899aabbccddeeff"

(2)settings/sctrlcert/scc_gfh_config_cert_chain.ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[CHIP]
version="mt6799"
[CFH_FILE_INFO]
version="1"
file_type="4"
start_addr="0x00201000"
flash_dev="emmc"
sig_type="CERT_CHAIN"
pad_type="pss"
max_size="0x00040000"
sig_ver="5"
arrt="0"
[GFH_SCTRL_CERT]
version="2"
cust_name="MTK"
attr="0x00000001"

(3)settings/sctrlcert/scc_primary_dbg.ini

1
2
3
4
5
6
7
8
[PRIMARY_DBG]
primary_dbg_prvk="keys/sctrlcert/primary_dbg_prvk.pem"
secondary_dbg_prvk="keys/sctrlcert/secondary_dbg_prvk.pem"
dbg_cap0="0x0"
dbg_cap1="0x0"
sla_dis="yes"
daa_dis="yes"
sbc_dis="yes"

(4)settings/sctrlcert/scc_secondary_dbg.ini

1
2
3
4
5
6
7
secondary_dbg_prvk="keys/sctrlcert/secondary_dbg_prvk.pem"
soc_id="70 61 3c 50 6f d2 4e c0 82 a6 62 5d c3 16 70 9b db 50 56 ea 96 8b 75 22 f1 56 b6 9d f4 63 a1 25"
dbg_cap0="0x0"
dbg_cap1="0x0"
sla_dis="yes"
daa_dis="yes"
sbc_dis="yes"

(用flashtool进行BROM下载,从GLB.log中搜索soc_id)

8.3 生成cert_chain格式的scertFile

(1)root private key owner:将配置的ini放到settings/sctrlcert目录下执行指令:

1
python sctrlcert.py -i settings/sctrlcert/scc_key.ini -k out/sctrlcert/key_cert.bin -g settings/sctrlcert/scc_gfh_config_cert_chain.ini -q settings/sctrlcert/scc_primary_dbg.ini -p out/sctrlcert/primary_dbg_cert.bin -s settings/sctrlcert/scc_secondary_dbg.ini out/sctrlcert/scc_sv5.cert

(2)service center:将key_cert.bin和primary_dbg_cert.bin放到prebuilt/sctrlcert目录下执行指令:

1
python sctrlcert.py -k prebuilt/sctrlcert/key_cert.bin -g settings/sctrlcert/scc_gfh_config_cert_chain.ini -p prebuilt/sctrlcert/primary_dbg_cert.bin -s settings/sctrlcert/scc_secondary_dbg.ini out/sctrlcert/scc_sv5.cert