Secure Boot 功能概述

方案概述

所用资源

执行过程

  1. 编译 bootloader image 时发现 menuconfig 中使能了 secure boot,于是根据 menuconfig 中指定的公钥/秘钥文件路径将公钥编译到 bootloader image 中,bootloader 被编译成支持 secure boot

  2. 编译 partition table 和 app images 时使用秘钥计算出签名,将签名编译到相应的二进制文件中

  3. 芯片第一次 boot 时,软件 bootloader 根据一下步骤使能 secure boot:

    • 硬件产生一个 secure boot key,将这个 key 保存在 efuse 中,利用这个 key、一个随机数 IV 和 bootloader image 计算出 secure digest
    • secure digest 与随机数 IV 保存在 flash 的 0x0 地址,用于在后续 boot 时验证 bootloader image 是否被篡改
    • 若 menuconfig 中选择了禁止 JTAG 中断和 ROM BASIC 中断,bootloader 会将 efuse 中的一些标志位设置为禁止这些中断(强烈建议禁止这些中断)
    • bootloader 通过烧写 efuse 中的 ABS_DONE_0 永久使能 secure boot
  4. 芯片在后面的 boot 中,ROM bootloader 发现 efuse 中的 ABS_DONE_0 被烧写,于是从 flash 的地址 0x0 读取第一次 boot 时保存的 secure digest 和随机数 IV,硬件使用 efuse 中的 secure boot key 、随机数 IV 与当前的 bootloader image 计算当前的 secure digest,若与 flash 中的 secure digest 不同,则 boot 不会继续,否则就执行软件 bootloader。

  5. 软件 bootloader 使用 bootloader image 中保存的公钥对 flash 中的 partition table 和 app images 签字进行验证,验证成功之后才会 boot 到 app 代码中

使用步骤

  1. make menuconfig 选择 "enable secure boot in bootloader"
  2. make menuconfig 设置保存公钥/秘钥对的文件
  3. 生成公钥和秘钥,先执行 "make" 命令,此时由于还没有公钥/秘钥对,所以命令行中会提示生成公钥/秘钥对的命令,按提示执行命令即可。但在产品级使用中,建议使用 openssl 或者其他工业级加密程序生成公钥/秘钥对。例如使用 openssl:“openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key.pem”(若使用现有的公钥/秘钥对文件,可以跳过此步)
  4. 运行命令 "make bootloader" 产生一个使能 secure boot 的 bootloader image
  5. 执行完4后命令行会提示下一步烧写 bootloader image 的命令,按提示烧写即可
  6. 运行命令 "make flash" 编译并烧写 partition table 和 app images
  7. 重启芯片,软件 bootloader 会使能 secure boot ,查看串口打印确保 secure boot 成功启用。

注意事项

可重复烧写 bootloader

Flash Encryption

方案概述

使用步骤

  1. make menuconfig 中选择 "Security features"->"Enable flash encryption on boot"
  2. 按通常操作编译出 bootloader, partition table 和 app image 并烧写到 flash 中
  3. 第一次 boot 时 flash 中被指定加密的数据被加密(大的 partition 加密过程可能需要花费超过1分钟) ,之后就可以正常使用被加密的 flash 数据

加密过程(第一次 boot 时进行)

  1. bootloader 读取到 efuse 中的 FLASH_CRYPT_CNT 为0,于是利用硬件随机数生成器产生加密用的 key ,此 key 被保存在 efuse 中,对于软件是读写保护的
  2. bootloader 对所有需要被加密的 partition 在 flash 中原处加密
  3. 默认情况下 efuse 中的 DISABLE_DL_ENCRYPT, DISABLE_DL_DECRYPT 和 DISABLE_DL_CACHE 会被烧写为1,这样 UART bootloader 时就不能读取到解密后的 flash 数据
  4. efuse 中的 FLASH_CRYPT_CONFIG 被烧写成 0xf,此标志用于决定加密 key 的多少位被用于计算每一个 flash 块(32字节)对应的秘钥,设置为 0xf 时使用所有256位
  5. efuse 中的 FLASH_CRYPT_CNT 被烧写成 0x01,此标志用于 flash 烧写次数限制以及加密控制,详见“FLASH_CRYPT_CNT”一节
  6. bootloader 将自己重启,从加密的 flash 执行软件 bootloader

串口重烧 flash (3次重烧机会)

FLASH_CRYPT_CNT

被加密的数据

哪些方式读到解密后的数据(真实数据)

哪些方式读到不解密的数据(无法使用的脏数据)

软件写入加密数据

Secure Boot 与 Flash Encryption 流程图

Windows平台的下载工具

ITEMFunctiondefault
debug_enable是否开启debug模式,在debug模式下,工具会根据pem文件产生相同密钥,否则随机生成密钥True
debug_pem_path设置证书地址,用于生成可重复烧写的密钥,尽在debug模式下有效 
SECURE BOOT  
secure_boot_en开启secure boot功能False
burn_secure_boot_key使能secure boot key烧写False
secure_boot_force_write是否不检查secure boot key block,强制烧写keyFalse
secure_boot_rw_protect开启secure boot key区域的读写保护False
FLASH ENCRYPTION  
flash_encryption_en开启flash加密功能False
burn_flash_encryption_key使能flash encrypt key烧写False
flash_encrypt_force_write是否不检查flash encrypt key block,强制烧写keyFalse
flash_encrypt_rw_protect开启flash encrypt key区域的读写保护False
AES KEYNot used yet 
DISABLE FUNC  
jtag_disable是否关闭JTAG调试功能False
dl_encrypt_disable是否关闭下载模式下flash加密功能False
dl_decrypt_disable是否关闭下载模式下flash解密功能False
dl_cache_disable是否关闭下载模式下的flash cache功能False

启用Secure Boot 与 Flash Encryption 的生产方案

准备工作

方案1: 通过bootloader完成security特性初始化

方案2: 通过下载工具初始化security特性

开发阶段使用可重复烧写 flash 的 Secure Boot 与 Flash encryption

  1. make menuconfig 中使能 secure boot 和 flash encrypt,“Secure bootloader mode”选择“Reflashable”,并设置你的公钥/私钥.pem文件路径

  2. 编译 bootloader 并生成 secure boot key:

  3. 使用 key 和 bootloader 计算带 digest 的 bootloader

  4. 编译 partition_table 与 app

  5. 加密三个 bin 文件

  6. 烧写三个加密后的 bin 文件

  7. 将 flash_encryption_key 烧入 efuse (仅在第一次boot前烧写):

  8. 将 secure boot key 烧入efuse(仅在第一次boot前烧写):

  9. 烧写 efuse 中的控制标志(仅在第一次boot前烧写)