i.MX93 作为 NXP 新一代高性能 MCU,其加密启动在安全启动基础上新增镜像加密功能,通过对外部存储(Flash/EMMC)中的启动程序和数据进行混淆加密,防止非授权访问与克隆。该方案核心依赖 AHAB(Authenticated High Assurance Boot)安全机制、ELE(Embedded Security Element)硬件安全模块,以及 DEK BLOB(Data Encryption Key BLOB)的加密封装,实现 “硬件级信任锚定 + 软件级数据加密” 的双重防护。本文详解从环境准备到启动验证的全流程,帮助开发者快速落地加密启动功能。
资料获取:i.MX93加密启动
1. 核心概念与安全原理
1.1 关键术语解析
- AHAB:i.MX93 的安全启动核心机制,负责验证镜像签名与解密授权,依赖 PKI 信任链实现硬件级可信启动;
- DEK(Data Encryption Key):镜像加密的会话密钥,用于加密 bootloader 等核心镜像,需通过设备唯一的 OPTMK(One-Time Programmable Master Key)封装为 DEK BLOB;
- DEK BLOB:OPTMK 加密后的 DEK 存储格式,大小固定 72 字节,需嵌入镜像签名块,确保仅目标设备可解密;
- CST(Code Signing Tool):NXP 官方签名工具,用于生成 PKI 树、SRK(Super Root Key)表及加密镜像;
- CSF(Command Sequence File):命令序列文件,定义 AHAB 的验证逻辑、SRK 配置及密钥安装规则。
1.2 加密启动核心流程
- 构建 PKI 信任链:生成 SRK 表与证书,烧录 SRK 哈希至芯片 fuse 作为信任根;
- 编译支持加密启动的 bootloader:启用 AHAB 与 DEK 封装相关配置;
- 编写 CSF 文件:定义镜像认证与密钥安装规则;
- 加密镜像:通过 CST 工具结合 CSF 文件生成加密镜像,记录 DEK BLOB 插入偏移;
- 生成 DEK BLOB:利用 i.MX93 的 OPTMK 封装 DEK,生成仅本设备可解密的 DEK BLOB;
- 插入 DEK BLOB:将 DEK BLOB 写入加密镜像指定偏移;
- 烧录验证:烧录加密镜像,通过 AHAB 状态验证启动结果。
2. 环境准备与前置条件
2.1 软硬件环境
- 硬件:i.MX93 11x11 EVK 开发板、EMMC/Flash 存储设备、USB 调试线;
- 软件:Ubuntu 20.04 主机、NXP Linux BSP(6.1-mickledore)、CST 工具(v3.4.0+)、imx-mkimage 工具、uuu 烧录工具;
- 依赖包:交叉编译工具链(armv8a-poky-linux)、OpenSSL(生成密钥)、fatfs 工具(文件系统操作)。
2.2 工具下载与配置
- CST 工具:从 NXP 官网搜索 “IMX_CST_TOOL_NEW” 下载,解压后获取
cst可执行文件; - imx-mkimage 工具:用于构建 i.MX93 镜像容器,从 NXP GitHub 仓库克隆:
git clone https://github.com/nxp-imx/imx-mkimage.git; - 交叉编译环境:加载 NXP 官方 SDK 环境变量:
source /opt/fsl-imx-wayland/6.1-mickledore/environment-setup-armv8a-poky-linux。
3. 分步实现流程
步骤 1:构建 PKI 信任链(生成 SRK 与证书)
(1)生成 PKI 树与 SRK 表
- 进入 CST 工具的 keys 目录,执行 PKI 树生成脚本(以 RSA 2048 位密钥为例):
cd cst-3.4.0/keys ./hab4_pki_tree.sh - 按提示配置参数:
- 选择密钥类型:rsa;
- 密钥长度:2048;
- 有效期:10 年;
- SRK 数量:4;
- CA flag:y(生成带 CA 标记的 SRK 证书);
- 生成文件:
- SRK 表:
SRK_1_2_3_4_table.bin(存储 4 个 SRK 公钥参数); - 公钥证书:
SRK1_sha256_2048_65537_v3_ca_crt.pem(SRK1 公钥证书); - 私钥文件:
SRK1_sha256_2048_65537_v3_ca_key.pem(用于镜像签名)。
- SRK 表:
(2)烧录 SRK 哈希至 Fuse(可选,增强安全性)
将 SRK 表的哈希值烧录至芯片 fuse,使 AHAB 仅信任该 PKI 树:
# 生成fuse烧录文件
srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c SRK1_sha256_2048_65537_v3_ca_crt.pem,SRK2_sha256_2048_65537_v3_ca_crt.pem,SRK3_sha256_2048_65537_v3_ca_crt.pem,SRK4_sha256_2048_65537_v3_ca_crt.pem
# 通过uuu工具烧录fuse
uuu -b fuse SRK_1_2_3_4_fuse.bin
步骤 2:编译支持加密启动的 bootloader
(1)配置 uboot 编译选项
- 编辑 i.MX93 EVK 配置文件:
vim configs/imx93_11x11_evk_defconfig - 启用以下核心配置:
CONFIG_AHAB_BOOT=y # 启用AHAB安全启动 CONFIG_CMD_DEKBLOB=y # 启用DEK BLOB生成命令 CONFIG_IMX_ELE_DEK_ENCAP=y # 启用ELE的DEK封装功能 CONFIG_FAT_WRITE=y # 支持FAT分区写入(用于DEK BLOB操作)
(2)编译 uboot 并构建镜像容器
# 配置编译环境
export ARCH=arm64
make imx93_11x11_evk_defconfig
make -j8
# 复制编译产物到imx-mkimage
cp u-boot.bin ../imx-mkimage/iMX9/
cp spl/u-boot-spl.bin ../imx-mkimage/iMX9/
# 构建镜像容器,记录偏移信息
cd ../imx-mkimage
make SOC=iMX93 REV=A1 flash_singleboot
- 关键输出:记录容器偏移(如
Offsets = 0x400 0x490),用于后续 CSF 文件配置。
步骤 3:编写 CSF 文件
CSF 文件定义 AHAB 的验证逻辑,需针对第 2、3 个容器分别编写(示例如下):
(1)csf_boot_image.txt(第 2 个容器加密配置)
[Header]
Target = AHAB
Version = 1.0
[Install SRK]
File = "./release/crts/SRK_1_2_3_4_table.bin" # SRK表路径
Source = "./release/crts/SRK1_sha256_2048_65537_v3_ca_crt.pem" # SRK1公钥证书
Source index = 0 # SRK表中的索引(0-3)
Source set = OEM # SRK类型(OEM/NXP)
Revocations = 0x0 # 吊销SRK掩码(0表示无吊销)
[Authenticate Data]
File = "flash.bin" # 待加密镜像
Offsets = 0x400 0x490 # 容器头与签名块偏移(来自imx-mkimage输出)
Key = "dek_2.bin" # DEK文件路径
Key Length = 128 # DEK长度(单位:位)
Key Identifier = 0x1234CAFE # 密钥标识(自定义)
Image Indexes = 0xFFFFFFFE
[Install Secret Key]
(2)csf_3rd_image.txt(第 3 个容器加密配置)
[Header]
Target = AHAB
Version = 1.0
[Install SRK]
File = "../crts/SRK_1_2_3_4_table.bin"
Source = "../crts/SRK1_sha256_2048_65537_v3_ca_crt.pem"
Source index = 0
Source set = OEM
Revocations = 0x0
[Authenticate Data]
File = "enc_2nd_cntnr_flash.bin" # 上一步生成的加密镜像
Offsets = 0x4F000 0x4F110 # 第3个容器偏移(来自imx-mkimage输出)
Key = "dek_3.bin" # 第3个容器的DEK文件
Key Length = 128
Key Identifier = 0x1234CAFE
Image Indexes = 0xFFFFFFFE
[Install Secret Key]
步骤 4:加密镜像生成
使用 CST 工具结合 CSF 文件生成加密镜像,记录 DEK BLOB 插入偏移:
# 加密第2个容器
cst-3.4.0/linux64/bin/cst -i csf_boot_image.txt -o enc_2nd_cntnr_flash.bin
# 关键输出:DEK BLOB插入偏移(如0x6c0)
# 加密第3个容器
cst-3.4.0/linux64/bin/cst -i csf_3rd_image.txt -o encrypted-flash.bin
# 关键输出:DEK BLOB插入偏移(如0x4f340)
- 注意:记录两次执行输出的 “DEK BLOB must be inserted at offset” 值,用于后续 DEK BLOB 插入。
步骤 5:生成 DEK BLOB
DEK 需通过 i.MX93 的 OPTMK 封装为 DEK BLOB,确保仅目标设备可解密:
(1)准备 DEK 文件
创建 128 位 DEK 文件(dek_2.bin、dek_3.bin),示例:
# 生成随机128位DEK(16字节)
openssl rand -out dek_2.bin 16
openssl rand -out dek_3.bin 16
(2)通过 uboot 生成 DEK BLOB
- 烧录未加密的 flash.bin 到开发板,启动后停在 uboot 命令行;
- 挂载 EMMC FAT 分区,复制 DEK 文件到开发板:
# 开发板端:启用USB Mass Storage模式 uboot=> ums 0 mmc 0 # 主机端:复制DEK文件到EMMC FAT分区 cp dek_2.bin /media/xxx/EMMC/ cp dek_3.bin /media/xxx/EMMC/ - 开发板端封装 DEK BLOB:
# 加载dek_2.bin并封装 uboot=> fatload mmc 0:1 0x90000000 dek_2.bin uboot=> dek_blob 0x90000000 0x90001000 128 # 128为DEK长度(位) uboot=> fatwrite mmc 0:1 0x90001000 dek_blob2.bin 0x48 # 0x48=72字节 # 加载dek_3.bin并封装 uboot=> fatload mmc 0:1 0x90000000 dek_3.bin uboot=> dek_blob 0x90000000 0x90001000 128 uboot=> fatwrite mmc 0:1 0x90001000 dek_blob3.bin 0x48 - 主机端复制 DEK BLOB:通过 UMS 模式将
dek_blob2.bin、dek_blob3.bin复制到主机。
步骤 6:插入 DEK BLOB 到加密镜像
使用
dd命令将 DEK BLOB 写入加密镜像的指定偏移:# 插入dek_blob2.bin(偏移0x6c0)
dd if=dek_blob2.bin of=encrypted-flash.bin bs=1 seek=$((0x6c0)) conv=notrunc
# 插入dek_blob3.bin(偏移0x4f340)
dd if=dek_blob3.bin of=encrypted-flash.bin bs=1 seek=$((0x4f340)) conv=notrunc
步骤 7:烧录与启动验证
(1)烧录加密镜像
使用 uuu 工具将
encrypted-flash.bin烧录到 EMMC:uuu -b emmc encrypted-flash.bin
(2)验证加密启动
- 开发板设置为 EMMC 启动,重启后停在 uboot 命令行;
- 执行
ahab status命令验证:uboot=> ahab status Lifecycle: 0x00000008, OEM Open No Events Found!
- 关键判断:无错误事件(No Events Found)表示加密镜像已成功启动,AHAB 解密验证通过。
4. 关键避坑事项
- SRK 配置一致性:CSF 文件中的 SRK 表路径、索引需与 PKI 树生成结果一致,否则 AHAB 验证失败;
- DEK BLOB 偏移准确性:插入偏移必须严格遵循 CST 工具输出,偏移错误会导致镜像无法解密;
- 编译配置完整性:uboot 必须启用
CONFIG_AHAB_BOOT等核心配置,否则不支持 DEK BLOB 生成与解密; - 密钥安全管理:DEK 文件与 SRK 私钥需严格保密,避免泄露导致加密失效;
- 工具版本兼容性:CST 工具需使用 v3.4.0 及以上版本,确保支持 i.MX93 的 AHAB v4 机制。
阅读全文
129