Firmware Encryption 开发指南¶
1 概述¶
PAN108x SoC 提供了一个名为 Firmware Encryption 的固件加密机制,用于通过固件加密、硬件解密的付出保护 SoC Flash 中的关键代码。
2 在 App 工程中使能固件加密¶
任意 App 工程均可通过如下的简单配置使能固件加密功能,并编译生成加密固件,本文以 fw_encryption 例程为例进行说明。
2.1 在 prj.conf 文件中开启加密相关配置¶
在 App 工程的 prj.conf 中配置以下宏开关以使能固件加密机制:
# Enable Firmware Encryption Feature
CONFIG_FIRMWARE_ENCRYPTION=y
# Set the Encrypt Information File Name for Search
CONFIG_ENCRYPT_INFO_FILE_NAME="encrypt_info.yaml"
# Set the spetial flash area for encrypted code in
CONFIG_ENCRYPT_FLASH_OFFSET=0x303
其中:
CONFIG_FIRMWARE_ENCRYPTION
:使能加密模块CONFIG_ENCRYPT_INFO_FILE_NAME
:指定加密配置文件的名称,默认为 encrypt_info.yamlCONFIG_ENCRYPT_FLASH_OFFSET
:指定加密代码位于 Flash 的位置,以 Flash Page(256B)为单位;例如上述例程中此项配置为 0x303,即对应 Flash 地址为 0x30300注意:
此配置需要与加密配置文件 encrypt_info.yaml 中的
encrypt_flash_offset
项保持一致!若无特殊需要,(在使能 Bootloader 的情况下)建议在实际项目中将加密 Flash 地址配置为与本例程中保持一致(即
CONFIG_ENCRYPT_FLASH_OFFSET=0x303
),这样对 Flash 的利用率最高。
2.2 在 encrypt_info.yaml 文件中指定加密相关参数¶
在前述 App 工程的 prj.conf 文件中,通过 CONFIG_ENCRYPT_INFO_FILE_NAME="encrypt_info.yaml"
指定了一个名为 encrypt_info.yaml 的加密配置文件,其内容如下:
encrypt_info:
secure_enable: true
anti_injection_enable: true
encrypt_flash_offset: 0x303 # The 303rd page of flash (or say absolute flash address 0x30300)
encrypt_key: '4c68384139f574d836bcf34e9dfb01bf' # AES-128 key in hexadecimal string format
image_info:
expected_start_addr: 0x30000 # For encrypt tool to validate input hex image file
其中各个 item 解释如下:
secure_enable: true
:使能固件加密功能anti_injection_enable: true
:使能防注入保护功能,与固件加密功能结合使用,作用是防止通过 SWD Debug 的方式获取到加密 Flash 区域的明文信息encrypt_flash_offset: 0x303
:配置加密 Flash 的第几个 Page(大小 256 字节),如 0x303 表示加密 Flash 的第 303 个 Page,对应 Flash 绝对地址为 0x30300;注意此处配置的值一定要与 App 功能 prj.conf 中的配置 CONFIG_ENCRYPT_FLASH_OFFSET 值相同!encrypt_key: '4c68384139f574d836bcf34e9dfb01bf'
:配置加密秘钥(AES-128)expected_start_addr: 0x30000
:配置当前 Image 固件的起始地址为 0x30000,用于编译过程中 Encrypt Tool 交叉验证输入 Image 的地址是否有效
警告
本文件中包含明文的加密秘钥(encrypt_key),一定要妥善保管,不可随意外传,以防密钥泄露!
在编译过程中,Post Build 流程会基于本文件生成一个二次加密后的
encrypt_info_enc.bin
文件,此文件中会对秘钥添加扰码,因此在后续 PanLink 载入加密信息的过程中建议使用此文件,而不是明文的 yaml 文件。
2.3 在 App 程序中编写待保护的加密函数¶
PAN108x SoC 加密区域大小为 256 字节,因此项目中应选取一个重要且简短的函数作为加密函数段。
代码中只需在期望加密的函数前,添加一个指示加密的特殊语法标记 __in_section_unique(encrypted_section)
即可:
#ifdef CONFIG_FIRMWARE_ENCRYPTION
__in_section_unique(encrypted_section)
#endif
void encrypted_test_function(uint32_t *calculation)
{
/* Do some secret operations/calculations here */
*calculation = *(uint32_t *)((uint32_t)(&encrypted_test_function) & 0xFFFFFFFE);
printk("Hello from %s!\n", __func__);
}
上述代码即实现了将 encrypted_test_function()
函数编译到 Flash 加密区域的效果。
2.4 编译生成加密固件¶
App 工程经过上述修改后,编译即可生成加密后的固件:
zephyr_enc.bin
:编译输出的加密后的二进制格式 App Imagezephyr_enc.hex
:编译输出的加密后的十六进制文本格式 App Imagezephyr_enc.signed.bin
:加密并签名后的二进制格式的 App Image,可用于 DFU/OTAzephyr_enc.signed.hex
:加密并签名后的十六进制文本格式的 App ImagezImageMerged.bin
:合并了 Bootloader 和 加密签名后 App Image 的二进制格式 ImagezImageMerged.hex
:合并了 Bootloader 和 加密签名后 App Image 的十六进制文本格式 Image
3 使用 PANLINK 制作加密芯片¶
除了按照前述步骤编译生成加密固件外,为使其能够正常运行,还需通过特殊处理将芯片制作成加密芯片(使用 PanLink 工具烧录芯片 eFuse 中的加密相关区域,以使能芯片加密功能)。
将 PanLink 连接至芯片(若使用 EVB,则需将 EVB 核心板从 EVB 底板取下),打开 PanLink 上位机工具,使能 “加密信息配置”,并同时选择载入以下两个文件:
App 工程生成的加密配置信息文件
encrypt_info_enc.bin
或encrypt_info.yaml
(位于 01_SDK\zephyr\samples_panchip\basic\fw_encryption 目录)App 工程生成的加密固件
zImageMerged.bin
或zImageMerged.hex
(位于 01_SDK\build\fw_encryption_prj_pan108xxxx_evb\zephyr 目录)
PanLink 成功载入加密配置信息文件和加密固件¶
具体操作步骤请参考 PanLink 上位机工具文档。
点击 “下载” 按钮,即可将本工程的加密配置信息(包括加密使能开关、防注入保护使能开关、加密 Flash 区域配置、加密秘钥等)和加密固件分别烧录到芯片 eFuse 和 Flash 中:
PanLink 成功烧录加密配置信息文件和加密固件¶
完成后,断开芯片与 PANLink 的连接,重新给芯片上电执行其中的加密程序,即可看到其中的加密程序成功执行,具体可参考 fw_encryption 例程。