Linux · 2023年8月9日

SECURE BOOT 如何使能 【高通】

1. 创建临时目录

cd common

mkdir tmp

cd tmp

2. 复制opensslroot.cfg和v3.ext到tmp目录

cp ../sectools/resources/data_prov_assets/General_Assets/Signing/openssl/opensslroot.cfg .

cp ../sectools/resources/data_prov_assets/General_Assets/Signing/openssl/v3.ext

3. 生成证书并计算Hash

3.1 GENERATE Root KEY and CERT

3.1.1 generate root key

openssl genrsa -out oem_rootca.key -3 2048

3.1.2 generate root cert

openssl req -new -key oem_rootca.key -x509 -out oem_rootca.crt -subj /C=”US”/ST=”CA”/L=”SANDIEGO”/O=”OEM”/OU=”General OEM rootca”/CN=”OEM ROOT CA” -days 7300 -set_serial 1 -config opensslroot.cfg

3.2 GENERATE ATTEST CA KEY and CSR (证书请求文件) and CERT

3.2.1 generate attestCA key

openssl genrsa -out oem_attestca.key -3 2048

3.2.2 generate attestCA CSR

openssl req -new -key oem_attestca.key -out oem_attestca.csr -subj /C=”US”/ST=”CA”/L=”SANDIEGO”/O=”OEM”/OU=”General OEM attestation CA”/CN=”OEM attestation CA” -days 7300 -config opensslroot.cfg

3.2.3 generate attestCA CERT

openssl x509 -req -in oem_attestca.csr -CA oem_rootca.crt -CAkey oem_rootca.key -out oem_attestca.crt -set_serial 5 -days 7300 -extfile v3.ext

3.2.4

openssl x509 -in oem_rootca.crt -inform PEM -out oem_rootca.cer -outform DER

openssl x509 -in oem_attestca.crt -inform PEM -out oem_attestca.cer -outform DER

3.2.5

mv oem_rootca.key qpsa_rootca.key

mv oem_attestca.key qpsa_attestca.key

mv oem_rootca.cer qpsa_rootca.cer

mv oem_attestca.cer qpsa_attestca.cer

3.2.6

将生成的qpsa_rootca.key,qpsa_attestca.key,qpsa_rootca.cer,qpsa_attestca.cer复制到common/sectools/resources/data_prov_assets/Signing/Local/qc_presigned_certs-key2048_exp3/ 目录

注意不同的高通基线/SDK,此路径可能有区别(和生成key用的参数为-3 2048对应,目标目录为*key2048_exp3

cp qpsa_rootca.key qpsa_attestca.key qpsa_rootca.cer qpsa_attestca.cer ../sectools/resources/data_prov_assets/Signing/Local/qc_presigned_certs-key2048_exp3/

3.3 生成Hash值

openssl dgst -sha256 qpsa_rootca.cer

这个命令产生的哈希值在后面会用到:SHA256(qpsa_rootca.cer)= 1063f1ba7a0290861834a482fc415600b4fd8c3f2d3f5b56edab0e74d26c6ad5

4. 修改common/sectools/config/9607目录下的 xml 文件

4.1 9607_fuseblower_USER.xml

4.1.1 root_cert_hash配置成以上生成qpsa_rootca.cer的hash值

<module id=”SECURITY_CONTROL_CORE”>

<entry ignore=”false”>

<description>contains the OEM public key hash as set by OEM</description> <name>root_cert_hash</name> – <value>0000000000000000000000000000000000000000000000000000000000000000</value> + <value>1063f1ba7a0290861834a482fc415600b4fd8c3f2d3f5b56edab0e74d26c6ad5</value>
</entry>  

4.1.2 配置hash in fuse

确保以下配置为true

<entry ignore=”false”>

<description>PK Hash is in Fuse for SEC_BOOT1 : Apps</description> <name>SEC_BOOT1_PK_Hash_in_Fuse</name>

– <value>false</value>

+ <value>true</value>

</entry> …

<entry ignore=”false”>

<description>PK Hash is in Fuse for SEC_BOOT2 : MBA</description> <name>SEC_BOOT2_PK_Hash_in_Fuse</name>

– <value>false</value>

+ <value>true</value> </entry>

<entry ignore=”false”>

<description>PK Hash is in Fuse for SEC_BOOT3 : MPSS</description> <name>SEC_BOOT3_PK_Hash_in_Fuse</name>

– <value>false</value>

+ <value>true</value>

</entry>

4.1.3 配置OEM ID

配置为qcom分配给OEM的ID,qcom没给我们分,此处为默认的0x0000

<entry ignore=”false”>

<description>The OEM hardware ID</description>

<name>oem_hw_id</name>

<value>0x0000</value>

</entry>

4.1.3 配置产品ID

配置为本产品的ID, 此ID为OEM自定义的用于区分不同产品的ID

<entry ignore=”false”>

<description>The OEM product ID</description>

<name>oem_product_id</name>

<value>0x0000</value>

</entry>

4.2 9607_secimage.xml

4.2.1 根据实际情况修改

和生成key用的参数为-3 2048对应,如下key_size为2048,exponent为3

<general_properties>

<selected_signer>local</selected_signer>

<selected_encryptor></selected_encryptor> <selected_cert_config>qc_presigned_certs</selected_cert_config> <cass_capability>secboot_sha2_root</cass_capability>  

<key_size>2048</key_size>

<exponent>3</exponent>

以上配置会决定证书的路径,例如如上配置会使用common/sectools/resources/data_prov_assets/Signing/Local/qc_presigned_certs-key2048_exp3目录的证书

<msm_part>0x000480E1</msm_part>

<oem_id>0x0000</oem_id>

<model_id>0x0000</model_id>

<debug>0x0000000000000002</debug>  

<max_cert_size>2048</max_cert_size>

<num_certs_in_certchain>3</num_certs_in_certchain>

  • msm_part为JTAG ID,不同的芯片比如,9207和9307不一样,可以通过devmem 0x000A607C命令读取
  • oem_id,必须保证与 9607_fuseblower_USER.xml 的 oem_hw_id 一致
  • model_id,产品ID 必须保证与 9607_fuseblower_USER.xml 的 oem_product_id 一致

4.2.2 prog_nand_firehose_9x07.mbn

需要添加对prog_nand_firehose_9x07.mbn进行签名,否则工厂烧录工具会失败

<image sign_id=”prog_nand_firehose” name=”prog_nand_firehose_9x07.mbn” image_type=”elf_has_ht”> <general_properties_overrides>

<sw_id>0x0000000000000003</sw_id>

</general_properties_overrides>

<meta_build_location>$(FILE_TYPE:device_programmer_vip)</meta_build_location>

</image>

4.3 9607_fuseblower_OEM.xml

一般不需要修改,某些项目的特别需求,比如airtel禁用短接进9008,需要如下修改

详细参考:80-p1511-97_c_mdm9x07_mdm8207_mdm9628_mdm9206_qfprom_programming_reference_spreadsheet.xlsm

<fuse_region id=”QFPROM_RAW_OEM_CONFIG”>

<description></description>

<fuse ignore=”false” n=”0″> <address>0x000a0150</address>

<operation>BLOW</operation>

+ <field id=”FORCE_DLOAD_DISABLE”>

+ <description></description>

+ <owner>QC</owner>

+ <value>0x1</value>

+ <bits>3</bits>

+ </field>

4.4 9607_fuseblower_QC.xml

目前不需要修改编辑

5. 生成和验证sec.dat文件

5.1 生成

cd common/sectools python sectools.py fuseblower -e config/9607/9607_fuseblower_OEM.xml -q config/9607/9607_fuseblower_QC.xml -u config/9607/9607_fuseblower_USER.xml -g verbose -vvv

5.2 验证

验证一个 sec.dat与配置文件是否匹配cd common/sectools python sectools.py fuseblower –oem_config_path=config/9607/9607_fuseblower_OEM.xml –qc_config_path=config/9607/9607_fuseblower_QC.xml –user_config_path=config/9607/9607_fuseblower_USER.xml –secdat=common_output/v1/sec.dat –validate

5.3 结果

  • log 位于 fuseblower_output 目录
  • sec.dat位于common/sectools/fuseblower_output/v1/sec.dat目录

6. 签名

python sectools.py secimage -i $FILE -c config/9607/9607_secimage.xml -sa

所有在 9607_secimage.xml 列出来的所有image都需要签名, 参考9x07_rjil_M3的common/build/ww_sign.sh实现。

7. 使能secure boot

确保DUT分区里面有sec分区

common/config目录下:partition_nand_*.xml <partition> <name length=”16″ type=”string”>0:sec</name> <size_kb length=”4″>16</size_kb> <pad_kb length=”4″>10</pad_kb> <which_flash>0</which_flash> <attr>0xFF</attr> <attr>0x01</attr> <attr>0x00</attr> <attr>0xFF</attr> </partition> </xml>   将签名完毕的image下载到DUT,检查是否能够开机。   如果能够开机下载sec.dat到手机熔丝并重启   <code bash> fastboot flash sec sec.dat fastboot reboot

 注意

  • 烧录sec.dat之后,下次启动CPU就熔断了,这时候再烧录未签名的版本会启动不了(启动到哪一步具体看哪个包未签名)
  • 如果要换CPU,记得一定要把flash也换掉(或者把sec.dat去掉),因为flash已经有sec.dat文件,启动又会导致CPU熔断。
  • CPU熔断后,CPU的信息会被改变,这时候存在efs分区的qcn的信息(safe目录))和CPU不对应,会导致上不了网,需要重新烧录efs.mbn。

7.1 如何确定板子是否使能了secure boot

7.1.1 修改lk代码

参考代码修改参考9x07_rjil_M3 分支的改动

7.1.2 查看

/var/volatile/tmp # cat /proc/cmdline noinitrd rw console=ttyHSL0,115200,n8 androidboot.hardware=qcom ehci-hcd.park=3 msm_rtb.filter=0x37 lpm_levels.sleep_disabled=1 earlycon=msm_hsl_uart,0x78b3000 androidboot.serialno=3a02417 ww_hw_type=3 ww_chipset_info=0,490e1 androidboot.authorized_kernel=true androidboot.baseband=msm rootfstype=ubifs rootflags=bulk_read root=ubi0:rootfs ubi.mtd=17

  • no blown: ww_chipset_info=0x0,chipsetid=0x490e1
  • blown: ww_chipset_info=0x303030,chipsetid=0x490e1

8. 在版本添加sec.dat的烧录

修改:boot_images/core/storage/tools/nandbootmbn/nand_mbn_generator.py elif user_partition_entries[i][“label”] == “0:EFS2”: elem.attrib[“filename”] = “efs.mbn” elif user_partition_entries[i][“label”] == “0:data”: elem.attrib[“filename”] = “ww_data.ubi” elif user_partition_entries[i][“label”] == “0:bata”: elem.attrib[“filename”] = “ww_data.ubi” + elif user_partition_entries[i][“label”] == “0:sec”: + elem.attrib[“filename”] = “sec.dat” else: elem.attrib[“filename”] = user_partition_entries[i][“filename”]

如果不希望烧录sec.dat熔断CPU,则这里不要添加。

添加后会在factory目录的rawprogram_nand_p2K_b128K.xml文件体现

9. 如何在使能secury boot的板子上dump log

使能了secury boot的板子正常是无法用QPST导出log的

使能需要修改common/sectools/config/9607/9607_secimage.xml文件两处地方:<!– <debug>0x0000000000000002</debug> –> <debug>0xcb279f5600000003</debug> <!– high 32 bits: serialno low 32 bits: 3 –><image sign_id=”sbl1_nand” name=”sbl1.mbn” image_type=”elf_preamble”> <general_properties_overrides> <sw_id>0x0000000000000000</sw_id> <crash_dump>0xcb279f5600000001</crash_dump> <!– high 32 bits: serialno low 32 bits: 1 –> </general_properties_overrides> <meta_build_location>$(FILE_TYPE:download_file, ATTR:cmm_file_var, VAR:BOOT_BINARY)</meta_build_location> </image>

其中高32位都是当前板子的serial num,从/proc/cmdline读取的androidboot.serialno=3a02417 可以得到,每个使能了secury boot的板子都不一样。不足8个前面要补0。

修改之后重新签名sbl.mbn,再单独烧录这个特殊的sbl.mbn即可。

参考资料

  • 80-p2200-39_c_enabling_secure_boot_on_mdm9x07_mdm8207_mdm9628_mdm9206_asics.pdf
  • 80-p1511-97_c_mdm9x07_mdm8207_mdm9628_mdm9206_qfprom_programming_reference_spreadsheet.xlsm
  • 80_NM248_1_T_SECTOOLS__SECIMAGE_TOOL_USER_GUIDE.pdf
  • 80_P7202_7_A_HOW_TO_ENABLE_SECURE_BOOT_STEP_BY_STE.pdf
  • enable_secure_boot.docx
打赏作者