生成量产固件
按照本节流程编译加密的量产固件。
配置 BootLoader
- 进入 SDK
根目录:
cd <SDK_ROOT>
- 在 SDK
根目录中执行下列命令:
scons --apply-def=d12x_demo68-nor_baremetal_bootloader_defconfig
-
打开 BootLoader 的 menuconfig 菜单:
scons --menuconfig
-
在配置界面,勾选或确认已勾选下列参数:
AIC_USING_SPIENC AIC_SPIENC_BYPASS_IN_UPGMODE
参数对应的配置界面如下:Board options ---> [*] Using Spienc [*] Enc qspi0 (0) set qspi0 tweak [*] Using Efuse/SID SID Parameter ---> (64) set efuse max word Bootloader options ---> [*] Upgrading ---> [*] Secure transfer firmware and burn
注:编译量产固件时,需将编译烧录 eFuse 程序时的代码修改还原。
-
在正式发布的固件中,建议将下列参数选项去掉,防止攻击者通过控制台读出 Flash 中的数据,否则可跳过:
AIC_BOOTLOADER_CMD_MTD AIC_MTD_BARE_TEST
参数对应的功能配置界面如下:BootLoader options ---> Commands ---> [ ] mtd read/write Drivers options ---> Drivers examples ---> [ ] Enable MTD driver test command
配置应用程序
- 进入 SDK
根目录:
cd <SDK_ROOT>
- 在 SDK
根目录,执行下列命令:
scons --apply-def=d12x_demo68-nor_baremetal_bootloader_defconfig
-
打开 Application 的 menuconfig 菜单:
scons --menuconfig
-
勾选或确认已勾选下列选项:
AIC_USING_SPIENC
对应的配置界面如下:Board options ---> [*] Using Spienc [*] Enc qspi0 (0) set qspi0 tweak
-
在正式版本的固件中,建议删除 bsp/examples/test-spinor/test_sfud.c bsp/examples/test-spinor/test_fal.c bsp/examples/test-spinand/test_mtd.c 文件中的 sf、 fal 和 mtd_nand 命令命令,防攻击者通过控制台读出 Flash 中的数据,否则可跳过此步。
固件签名加密
在 SDK/target/<SoC>/<board>/pack/image_cfg.json 文件中配置并生成签名加密固件,例如 SDK/target/d12x/demo68-nor/pack/image_cfg.json。
-
对组件进行加密
在 image_cfg.json 的 “temporary” 或 “pre-process” 对象的最后,添加 “data_crypt” 对象配置。
此处使用的 AES 加密密钥,即为SDK/target/<soc>/<board>/pack/keys/ 文件目录中生成的密钥。
在下列示例中,配置了一组需要使用 “data_crypt” 工具进行加密的组件,其中生成 bootloader.aic.enc 组件的配置参数为:-
algo: 加密的算法
-
file: 加密的源文件,此处为前面生成的 bootloader.aic 文件
-
key: 使用的加密密钥
-
tweak: 该值不需要配置,保持为 0 即可
{ "spi-nor": { ... }, "image": { ... }, "info": { // Header information about image ... }, "updater": { // Image writer which is downloaded to RAM by USB/UART ... }, "target": { // Image components which will be burn to device's partitions ... }, "pre-process": { // before v1.0.6 is the name "temporary" "data_crypt": { "bootloader.aic.enc": { //加密 bootloader 分区 "algo": "spienc-aes-128-ecb", "file": "bootloader.aic", // File to be encrypted "key": "keys/spi_aes.key", // Keys the same in eFuse "tweak": "0", }, "env.bin.enc": { //加密 env 分区,备份分区使用同一个组件 "algo": "spienc-aes-128-ecb", "file": "env.bin", // File to be encrypted "key": "keys/spi_aes.key", // Keys the same in eFuse "tweak": "0", }, "d12x_os.itb.enc": { //加密 os 分区 "algo": "spienc-aes-128-ecb", "file": "d12x_os.itb", // File to be encrypted "key": "keys/spi_aes.key", // Keys the same in eFuse "tweak": "0", }, "rodata.fatfs.enc": { //加密 rodata 分区 "algo": "spienc-aes-128-ecb", "file": rodata.fatfs", // File to be encrypted "key": "keys/spi_aes.key", // Keys the same in eFuse "tweak": "0", }, "data.lfs.enc": { //加密 data 分区 "algo": "spienc-aes-128-ecb", "file": "data.lfs.itb", // File to be encrypted "key": "keys/spi_aes.key", // Keys the same in eFuse "tweak": "0", }, ... }, }, }
对于一个或者多个需要进行加密的组件,都应按照上述方式进行配置。
mk_image.py 工具在读取 image_cfg.json 文件时,逐个处理放在 “data_crypt” 中的配置,生成对应的加密组件,然后再进行打包。
重要:“data_crypt” 字段应放在 “temporary”/”pre-process” 的最后,因为处理 “data_crypt” 时,可能需要依赖前面配置生成的文件,比如 ”aicimage”。
-
-
配置烧录加密组件
在 image_cfg.json 中配置下列参数,打包加密组件,以适配烧录加密固件的要求:
-
updater 中打包的程序,应为非加密程序
updater 中配置的参数,都不是 .enc 结尾的组件
-
target 中打包的程序和数据,应为加密后的程序
target 中配置的参数,都是 .enc 结尾的组件
这是因为:-
SD 卡启动时,首先运行 updater 中的程序,进入烧录模式。此时由于数据是从 SD 卡加载的,不能为加密程序,否则无法正常执行
-
target 中打包的程序是要烧录到 Flash 的数据,如果不加密,则无法起到保护的作用,因此需要打包加密后的组件
{ "image": { ... }, "info": { // Header information about image ... }, "updater": { // Image writer which is downloaded to RAM by USB/UART "ddr": { "file": "usbupg-ddr-init.aic", "attr": ["required", "run"], "ram": "0x00103000" }, "spl": { "file": "bootloader.aic", "attr": ["required", "run"], "ram": "0x41000000" }, }, "target": { // Image components which will be burn to device's partitions "spl": { "file": "bootloader.aic.enc", //使用 enc 结尾的加密组件 "attr": ["mtd", "required"], "part": ["spl"] }, "os": { "file": "d21x_os.itb.enc", //使用 enc 结尾的加密组件 "attr": ["mtd", "required"], "part": ["os"] }, "rodata": { "file": "rodata.fatfs.enc", //使用 enc 结尾的加密组件 "attr": ["mtd", "optional"], "part": ["rodata"] }, "data": { "file": "data.fatfs.enc", //使用 enc 结尾的加密组件 "attr": ["mtd", "optional"], "part": ["data"] }, }, "pre-process": { // before v1.0.6 is the name "temporary" ... }, }
-
UART 烧录
直接使用编译生成的 img 文件进行量产烧录即可。
SD 卡量产
-
标准方式
编译生成下列文件后,将其复制到 SD 卡 FAT32 文件系统的根目录中,等待平台重新上电即可进入烧录:
-
bootcfg.txt
-
打包后的 img 文件,例如 d12x_demo68-nor_v1.0.0.img
-
-
Direct Mode
修改 bootcfg.txt,并且将 bootcfg.txt 和使用到的组件复制到 SD 卡 FAT32 文件系统的根目录,等待平台重新上电即可进入烧录模式。
bootcfg.txt 示例:
boot0=bootloader.aic writetype=spi-nand writeintf=0 write0=bootloader.aic.enc write1=d21x_os.itb.enc,0x40000 write2=rodata.fatfs.enc,0x240000 write3=data.fatfs.enc,0x840000
重要:在修改 bootcfg.txt 文件后,确保使用 UNIX 格式的换行符,而非 DOS 格式的换行符,即 ‘n’ 换行,而非 ‘rn’ 换行。