Edit online

固件加密-SPIENC

3 Mar 2025
Read time: 4 minute(s)

本节以 D13x 系列芯片为例,演示固件加密的具体流程。关于 eFuse 烧录区域,可参考对应用户手册。

完成本节所有操作后,编译镜像直接使用 AiBurn 工具进行烧录即可。

配置 BROM 中的 SPI_ENC_EN 比特位

使能 BROM 中 SPI_ENC 功能,在开发板平台命令行执行下列命令,烧录下列 eFuse 信息中的 SPI_ENC_EN 比特位:

efuse writehex 0x38 00000800
上述命令会在地址 0x38 处设置 SPI_ENC_EN 比特位为 1。

用途

位数

地址

禁止位

禁写

禁读

归属

备注

SECURE

64

38~3F

14~15

V

-

CSTM

安全和调试功能开关

SECURE 区域定义

比特位

名称

描述

31:25

-

-

24

PBP_ENC_EN

BROM 读取使用,使能 PBP 程序加密功能

23:20

-

-

19

SPI_ENC_EN

BROM 读取使用,使能 SPI 总线数据加密功能

18

-

-

17

ENCRYPT_BOOT_EN

BROM 读取使用,使能固件加密启动功能

16

SECURE_BOOT_EN

BROM 读取使用,使能安全启动功能

15:1

-

-

0

JTAG_LOCK

逻辑组合后连接到 CPU 屏蔽 TDO,关闭 JTAG 调试功能,在安全方案中烧录为 1

具体 eFuse 区域的地址,请参考芯片的数据手册。

在 BootLoader 中启用 SPIENC 驱动

  1. Luban-Lite 根目录下执行 bm,进入 BootLoader 的 menuconfig 功能配置界面。
    bm
  2. 进入 menuconfig 功能配置界面,按如下选择启用 QSPI0 的加密功能,配置只打开了 QSPI0 的加密使能作为示例:
    Board options  --->
        [*] Using Spienc
            [*]   Enc qspi0
  3. 如果需要,进入 menuconfig 功能配置界面设置 Tweak 值,否则可略过。

    SPIENC 中的 Tweak 可以影响 COUNTER 的生成,进而改变加密的结果。 如果需要让在不同的产品对相同的数据有不同的加密结果,则可以进入 menuconfig 的功能配置界面调整该值。

    Board options  --->
        [*] Using spienc  --->
            (0)     set qspi0 tweak

    完成以上配置之后, BootLoader SPI_ENC 驱动将被使能, SPI NOR / SPI NAND 驱动在数据访问时将自动进行数据加解密。

在 RTOS 中启用 SPIENC 驱动

  1. Luban-Lite 根目录下执行以下命令,进入 RTOS 的 menuconfig 功能配置界面:
    scons --menuconfig
  2. 在功能配置界面,按如下选择启用 QSPI0 的加密功能,配置只打开了 QSPI0 的加密使能作为示例:
    Board options  --->
        [*] Using Spienc
            [*]   Enc qspi0
    
  3. 如果需要,进入 menuconfig 功能配置界面设置 Tweak 值,否则可略过。

    SPIENC 中的 Tweak 可以影响 COUNTER 的生成,进而改变加密的结果。 如果需要让在不同的产品对相同的数据有不同的加密结果,则可以进入 menuconfig 的功能配置界面调整该值。

    Board options  --->
        [*] Using spienc  --->
            (0)     set qspi0 tweak
    

    完成以上配置之后, RTOS SPI_ENC 驱动将被使能, SPI NOR/ SPI NAND 驱动在数据访问时将自动进行数据加解密。

配置密钥及所需的 KEY 和 COUNTER 值

SPI_ENC 模块使用 AES-128-CTR 算法对 SPI 总线数据进行加解密,该算法在计算时的密钥有两部分:
  • 128 bit AES 密钥(KEY)

  • 128 bit 数据块的 COUNTER 值

其中 KEY 直接使用 eFuse 中的 SPI_ENC_KEY ,COUNTER 值则由几部分共同产生:
  • eFuse 中的 SPI_ENC_NONCE

  • memuconfig 中配置的 tweak

  • 访问数据所在的地址 address


spienc_counter_value1

1. COUNTER 值的生成
因此在使用 SPI_ENC 时,需要设置以下的 eFuse 信息:
1.

用途

位数

地址

禁止位

禁写

禁读

归属

备注

DIS RD

64

0~7

0~1

V

-

CSTM

eFuse 读禁止配置区域

DIS WR

64

8~F

2~3

-

-

-

eFuse 写禁止配置区域

SPI ENC KEY

128

A0~AF

40~43

V

V

CSTM

安全,连接到 SPI ENC,对称密钥

SPI ENC NONCE

64

B0~B7

44~45

V

V

CSTM

安全,连接到 SPI ENC,随机数

具体 eFuse 区域的地址,请参考芯片的数据手册。

烧写 SPI_ENC KEY

到 eFuse 中
  1. 主机端执行 opensslrand-hex16 生成 SPI_ENC KEY。
    52e0ef932d755b69f7a93dd7485748d8
  2. 在开发板平台命令行执行下列命令,烧录 SPI_ENC KEY 到 eFuse 中。
    efuse writehex 0xA0 52e0ef932d755b69f7a93dd7485748d8
  3. 禁止 SPI_ENC KEY 读写

    efuse writehex 0x04 000f0000
    efuse writehex 0x0c 000f0000

烧写 SPI_ENC NONCE 到 eFuse 中

  1. 主机端执行 opensslrand-hex8 生成 SPI_ENC NONCE。
    bb99eb4ababc43dc
  2. 在开发板平台命令行执行下列命令,烧录 SPI_ENC NONCE 到 eFuse 中。
    efuse writehex 0xB0 bb99eb4ababc43dc
  3. 禁止 SPI_ENC NONCE 读写

    efuse writehex 0x04 00300000
    efuse writehex 0x0c 00300000