MTK Secure Boot 2.1詳細配置方案-終極版

 

1. 目的/背景

此文檔使用了secure boot 2.1方案的配置,如有其他版本的secure方案,本文檔僅作參考,secure boot方案可在security MTK文檔中查到,也可以諮詢MTK,此文檔適配於:MTK6739等平臺。

2. 前述

Secure boot & Efuse方案和硬件強相關,在開始調試之前切記以下要點:

1.            確保所有的keys都是一次性生成的,keys、證書、hash一定要匹配,如果不確定,請全部重新生成一次

2.            生成keys之後謹慎保存,如無必要,儘量不做修改(尤其是root_key),修改之後,以前efuse的芯片便無法再使用。

3.            再所有方案double 驗證OK之前,不要上傳secure boot的開關宏,以免造成大面積芯片廢棄

3. 可參考文檔

Secure_2.1_Configuration_SOP.pdf

Efuse_self_blow_user_guide_v1.3.pdf

4. 詳細配置方案

生成keys

利用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

以上操作如下面演示:

 

 

產生oemkey.h和dakey.h

用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

Secure boot配置部分

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

 

Preloader簽名:

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時沒有參照依據。

 

產生簽名的image

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

 

build DA

提供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匹配

Noteepp_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確認。、

efuse.xml配置指導:

 

<?xml version="1.0" encoding="UTF-8" ?>

<flashtool-config version="2.0">

  <general>

   <chip-name>MT6779</chip-name> //平臺信息,對應項目的xml該項應該是匹配的,如果不匹配請確認xml來源

....

        preloader_¥project.bin //在此preloader中校驗

...

    <connection

      type="BromUSB" //下載端口需要對應

...

    <efuse>

      <magic-key                            /*需要和efuse.h中定義的key匹配,注意倒敘

        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" />

      <sbc-pub-key>//security2.1preloader默認是cert_chain格式,對應此項配置是key_type爲pss,pub-key-e必須設置爲010001,如不確定,向MTK諮詢

           <key-type>pss</key-type>

        <pub-key-e>010001</pub-key-e>

        <pub-key-n>//security 2.1,此處的keys值可以直接從root中獲取,這裏不需要配置

        </pub-key-n>

      </sbc-pub-key>

 

      <common-lock

        com_ctrl_lock="false"  //ctrl定製位鎖

        usb_id_lock="false"/>

      <secure-lock

       sec_msc_lock="false"

       sec_attr_lock="false"

        ackey_lock="false"

       sbc_pubk_hash_lock="false" /> //efuse hash的鎖,字面理解,但有個疑問,既然是EFUSE,應該寫入後熔斷,爲什麼需要上鎖呢?脫了褲子放個屁?

...

      <sec_msc

        md1_sbc_en="true"/>  //區別於SecureBoot和AVB,這是MTK自己的modem簽名驗證功能

 

      <c_ctrlm

       disable_self_blow="false" /> //是否允許自燒寫

 

 

Auth生成:

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流程能正常運行完成

5.    共基線secure boot開發策略

在共基線開發多個項目時,由於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文件夾,其中存放cert1cert2_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文件夾,其中存放cert1cert2_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/"

6.    驗證結果

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.      將未簽名的鏡像刷入,手機無法開機,然後再將鏡像簽名刷入,可開機。說明已經efuse

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章