前言
由于项目key是放在服务器上的,本地代码在编译时候获取不到,所以security开发需要考虑到工程师本地编译和服务器编译兼容。
MTK平台Security模块需求
- Secure boot:安全启动验证,打开secure boot的宏控后必须签名。
- Efuse烧写:Efuse依赖于open secboot,写入方式有两种,一般选择a。
a)通过flash tool加载配置efuse.xml使用DA烧写;
b)配置Preloader/LK,让手机第一次开机自烧写。 - Google key:打开Android key写入权限,依赖open TEE。
开发任务
生成Key:root keys,image keys(Cert1 and Cert2 ),OEM and DA keys
SW配置:TEE,RPMB,secure boot,google key
签名:sign Image,sign Preloader,sign DA
1 Keys Generation
1.1 root key
生成一对用于Cert1签名和验证的根密钥(私钥和公钥)。使用pem_to_der.py将密钥的格式转换为der。
path: vendor/mediatek/proprietary/scripts/sign-image_v2/der_extractor/
1.Generate private key command:
openssl genrsa -out root_prvk.pem 2048 python pem_to_der.py root_prvk.pem root_prvk.der
2.Generate public key command:
openssl rsa -in root_prvk.pem -pubout > root_pubk.pem python pem_to_der.py root_pubk.pem root_pubk.der
用同样的方法生成其他image key(img_prvk_pem/img_pubk_pem),会被用来签名和认证Cert2。
1.2 oemkey.h
导出root key(root_pubk.der),通过der_extractor生成oemkey.h。
der_extractor path:
vendor/mediatek/proprietary/scripts/sign-image_v2/cert_chain/cert_gen/
or vendor/mediatek/proprietary/scripts/sign-image_v2/der_extractor/
执行该命令前需要给der_extractor 权限:chmod 777 der_extractor
命令: ./der_extractor root_pubk.der oemkey.h ANDROID_SBC
将生成的oemkey.h放入以下路径:
[PL]
P
L
/
c
u
s
t
o
m
/
{PL}/custom/
PL/custom/{PROJECT}/inc/oemkey.h
[LK]
L
K
/
t
a
r
g
e
t
/
{LK}/target/
LK/target/{PROJECT}/inc/oemkey.h
[DA]
D
A
K
i
t
/
R
a
p
h
a
e
l
−
d
a
/
c
u
s
t
o
m
/
{DA_Kit}/Raphael-da/custom/
DAKit/Raphael−da/custom/{PLATFORM}/oemkey.h
DA的oemkey.h不在项目代码,位于生成DA文件的源代码中,区分win和linux环境,详情参考MTK文档:
https://online.mediatek.com/FAQ#/SW/FAQ16649
1.3 dakey.h
dakey.h包含DA_PL公钥,用于preloader验证DA_PL.bin。DA_PL.bin由其相关的私钥签名。首先,生成一个DA_PL密钥对,并使用以下命令生成dakey.h。
./der_extractor da_pubk.der dakey.h ANDROID_SBC
命令中的da_pubk.der可使用生成oemkey.h的root_pubk.der,在生成dakey.h后需要将dakey.h中的OEM字样替换成DA,否则会编译报错。
将生成的dakey.h放入以下路径:
[PL]
P
L
/
c
u
s
t
o
m
/
{PL}/custom/
PL/custom/{PROJECT}/inc/dakey.h
1.4 Image key
使用root_prvk.Pem和img_prvk.pem生成cert2和cert1 keys。
Execute the command:
python $ {python_PATH} /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
or
Python ${python_PATH}/img_key_deploy.py mt67xx $ {PROJECT} cert1_key_path=$ {KEY_PATH}/root_prvk.pem cert2_key_path=$ {KEY_PATH}/img_prvk.pem root_key_padding=pss | tee SecureGen.log
执行该脚本时必须在项目的根目录下执行该命令,不能在sign-image_v2下执行。PATH为绝对路径。“tee”是执行命令时打印和记录日志的命令。
cert1 and cert2生成的所有文件在:
vendor/mediatek/proprietary/custom/${PROJECT}/security/cert_config/
执行完脚本后可以检查该两个路径下文件是否更新来判断是否执行成功。
2 SW配置
2.1 Open TEE
可信执行环境(TEE)是一个安全的计算环境,它能够保护运行在其中的代码和数据免受外部攻击,包括来自操作系统、硬件和其他应用程序的攻击。TEE通过在处理器内部创建一个隔离的执行环境来实现这一目标,这个环境被称为“保护容器”(secure container)或“信任区”(trust zone)。通常用于运行关键的操作:(1)、移动支付:指纹验证、PIN码输入等;(2)、机密数据:私钥、证书等的安全存储;(3)、内容包括:DRM(数字版权保护)等。
Trustonic TEE:https://online.mediatek.com/faq#/SW/FAQ24581
Set TEE size:https://online.mediatek.com/FAQ#/SW/FAQ27123
2.2 RPMB
RPMB全称Replay Protected Memory Block,重放保护存储块,用于存放一些重要的安全信息,eMMC和UFS都有这一区域。
目前在mtk平台, rpmb key的生成规则有两种, 一是common key, 另一种是per device key。使用哪一种规则, 取决于是否开启宏RPMB_PER_DEVICE_KEY。
MTK RPMB介绍:https://online.mediatek.com/FAQ#/SW/FAQ20629
2.3 Secure boot
2.3.1 Prelaoder setting
1.vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/${PROJECT}/<project.mk>
MTK_SECURITY_SW_SUPPORT=yes
2.vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/${PROJECT}/<project.mk>
采用信任软件根(without blowing efuse),强制打开安全引导和安全下载。请按以下方式配置:
MTK_SEC_BOOT=ATTR_SBOOT_ENABLE
MTK_SEC_USBDL=ATTR_SUSBDL_ENABLE
如果硬件根信任(with blowing efuse),请按以下方式配置:
MTK_SEC_BOOT=ATTR_SBOOT_ENABLE
MTK_SEC_USBDL=ATTR_SUSBDL_ENABLE
or
MTK_SEC_BOOT=ATTR_SBOOT_ONLY_ENABLE_ON_SCHIP
MTK_SEC_USBDL=ATTR_SUSBDL_ONLY_ENABLE_ON_SCHIP
ONLY_ENABLE_ON_SCHIP意思是仅在熔断(blowing efuse)后启用安全启动和安全下载。
2.3.2 lk settings
1.vendor/mediatek/proprietary/bootable/bootloader/lk/${PROJECT}/<project.mk>
MTK_SECURITY_SW_SUPPORT=yes
若不配置,该宏默认打开。
2.vendor/mediatek/proprietary/bootable/bootloader/lk/${PROJECT}/<project.mk> 是否使能fastboot单刷的宏控
MTK_SEC_FASTBOOT_UNLOCK_SUPPORT
MTK_SEC_FASTBOOT_UNLOCK_KEY_SUPPORT
2.3.3 kernel settings
检查MTK_SECURITY_SW_SUPPORT=yes
3 Sign
3.1Sign img
执行shell脚本在lunch后对img进行签名:
./vendor/mediatek/proprietary/scripts/sign-image/sign_image.sh
做OTA升级签名单个镜像:
python sign_flow.py -env_cfg env.cfg -target lk.img { Platform_Name } { Project_name } | tee sign_lk.log
3.2Sign preloader
1.将生成的root key(包含root_prvk.pem,img_prvk.pem)Copy在下面的路径:
vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/${PROJECT}/security/chip_config/s/key
2.配置root key和image key的路径放在pl_key.ini,这两个私钥是用来签名preloader的。
[KEY]
sw_ver = “0”
rootkey = “root_prvk.pem”
imgkey = “img_prvk.pem”
ac_key = “0x112233445566778899aabbccddeeff”
3.配置imgkey的路径放在pl_content.ini文件中
[CONTENT]
sw_ver = “0”
imgkey = “img_prvk.pem”
注意:pl_key.ini和pl_content.ini文件中的sw_ver应该保持一致.
4.pl_gfh_config_cert_chain.ini文件配置。路径:
vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/${PROJECT}/security/chip_config/s/gfh/pl_gfh_config_cert_chain.ini
5.以下文件不需要配置,检查这两个文件或内容即可,只有这两个文件存在preloader才会支持cert chain 格式的签名:
vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/security/chip_config/s/cfg下的PBP_BY_SUPPORT是否存在,不存在重新同步或者向MTK索要。
/vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/security/chip_config/s/cfg的PADDING_TYPE.ini中是否有该设置:
Cert_chain /代表生成preloader的格式是以cert_chain格式的/
6.Build preloader。只在首次编译才会sign preloader,所以如果直接build需要make clean 或者new build。在调试中,需要快速确认preloader签名成功与否,可以使用resign preloader。
4 Comport Setting
对于MTK平台,有两个阶段可以使用工具实现握手。一个是BROM,另一个是预装载阶段。如果您不希望最终用户通过BORM或预加载程序连接设备或flash映像,请禁用BROM或预加载程序。除特殊要求,一般不用disable。
4.1Disable BROM Comport
-Go to
{PL}/custom/${PROJECT}/security/chip_config/s/gfh/pl_gfh_config_cert_chain.ini
[CFH_BROM_SEC_CFG]选项下添加:
brom_magic_cmd_mode_permanent_dis=“1”
4.2Disable Preloader Comport
- Go to
1./vendor/mediatek/proprietary/bootable/bootloader/preloader/${PLATFORM}/default.mak - Set CFG_USB_TOOL_HANDSHAKE := 0
- Set CFG_UART_TOOL_HANDSHAKE := 0
5 Efuse 烧写机制
MTK平台Efuse烧写有两种方式:
1.通过flash tool加载配置efuse.xml使用DA烧写。
2.配置Preloader/LK,让手机第一次开机自烧写。
5.1 Flash tool
5.1.1 生成DA
DA编译环境安装MTK文档:https://online.mediatek.com/FAQ#/SW/FAQ16649
5.1.2 Sign DA
在DA签名之前,确保oemkey.h在项目源码和DA编译源码中已替换。
1.将da_prvk.pem和epp_prvk.pem放置在目录下,因为生成oemkey.h和dakey.h用的是root_prvk.pem,所以将root_prvk.pem改名成再替换即可。
vendor/mediatek/proprietary/scripts/secure_chip_tools/keys/resignda/
2.将编译生成的DA文件放在该路径下:
vendor/mediatek/proprietary/scripts/secure_chip_tools/prebuilt/resignda
3.使用命令:
Python resign_da.py prebuilt/resignda/DA.bin MT67xx settings/resignda/bbchips_pss.ini all out/resignda/DA_Signed.bin
签完名的DA生成在secure_chip_tools/out/resignda下。
5.1.3 烧写efuse
1.进入生成root key的目录,生成 CHIP_TEST_KEY.ini。
./der_extractor root_prvk.der CHIP_TEST_KEY.ini SV5_SIGN
2.从CHIP_TEST_KEY.ini中提取public_key_n,配置到efuse.xml文件中。
3.用命令行打开 Flash tool,执行efuse烧写命令:
flash_tool -i efuse.xml -d DA.bin -s MTXXXX_Android_scatter.txt -o -r >> log
5.2Efuse self blowmagic-key
5.2.1配置input.xml
1.magic-key
EFUSE_BLOW_KEY1 0x90b1e2f6
EFUSE_BLOW_KEY2 0x73d5a8c9
key1= EFUSE_BLOW_KEY1 高低位反转 f6e2b190
key2= EFUSE_BLOW_KEY2 高低位反转 c9a8d573
2.sbc-pub-key
key-type pss
pub-key-e 010001
public_key_n将public_key_n配置于此
5.2.2 修改preloader/lk宏开关
MTK_EFUSE_WRITER_SUPPORT = yes
cust_bldr.mak
lk/project/
p
r
o
j
e
c
t
n
a
m
e
.
m
k
d
e
v
i
c
e
/
t
i
n
n
o
/
project_name.mk device/tinno/
projectname.mkdevice/tinno/project_name/ProjectConfig.mk
5.2.3 生成efuse.img
PBP_TOOL := tools/pbp/pbp.py
BIN_TO_TXT_TOOL := tools/pbp/bin2txt.py
python $(PBP_TOOL) -j $(KEY_PATH)/root_prvk.pem -func keyhash_pss -o $(D_BIN)/keyhash.bin
python $(BIN_TO_TXT_TOOL) $(D_BIN)/keyhash.bin $(D_BIN)/keyhash.txt
python tools/efuse/efuse_bingen_v2.py -f …/…/…/custom/c210/security/efuse/input.xml -d tools/efuse/MT67xx/efuse_definition.xml -k /local/c210/android/out/target/product/c210/obj/PRELOADER_OBJ/bin/keyhash.txt -o ~/efuse.img -l ~/efuse_gen.log