RSIP 数据流

RSIP(Runtime Secure Image Protection)通过 AES 硬件加密技术防止 Flash 中的固件被非法读取和克隆。 在介绍 RSIP 之前,需先理解 Flash 的访问机制。SPIC (SPI Controller) 控制器有两种操作 Flash 的模式:自动模式和用户模式。

  • 用户模式(读/写/擦除):软件需要按照 Flash 芯片数据手册的要求,通过配置 SPIC 的控制寄存器组成串行命令,对 Flash 执行读、写或擦除操作。

  • 自动模式(只读):CPU、DMA 等主设备可以通过总线地址直接读取 Flash 中数据。整个数据读取过程由硬件自动完成无需软件干预,支持 Flash OTF 实时解密。SPIC 会将总线的读取命令自动转化为符合 Flash 芯片手册的串行读命令。RSIP 在取得原始数据后,根据访问地址选择密钥和 IV,执行自动解密。

RSIP 仅在自动模式下工作。这是因为 CPU 执行指令时必须通过总线地址读取 Flash,而 RSIP 模块位于总线访问路径上,才能在数据返回给 CPU 之前自动完成解密操作。 用户模式则是直接操作 Flash 控制器,因此无法触发 RSIP 的解密功能。

../../_images/rsip_brife.svg

RSIP 数据示意图

备注

RSIP 模块本身不提供加密或写入数据的功能,它仅支持在自动读取模式下的实时解密。若需进行数据加密,请使用专用硬件: 对称硬件加密引擎

工作原理

在理解 Flash 两种操作模式的基础上,本节介绍 RSIP 的工作原理,以及如何通过 Entry 实现分区保护。 RSIP 包含多个独立的通道(称为 Entry),每个 Entry 可保护 Flash 中一块独立的内存区域。 其典型应用场景是为不同的固件分区配置独立的加密通道。不同固件分区可以使用不同的加密参数和方法,实现风险隔离。例如:

  • Entry 0:使用 IV0 保护 Bootloader 固件;

  • Entry 1:使用 IV1 保护 APP 应用程序固件;

  • Entry 2~N:保护其他固件分区或保留。

RSIP Entry 工作原理如下:

../../_images/rsip_entry.svg

RSIP Entry 工作原理图

  • 独立配置:每个 Entry 都拥有自己独立的密钥、初始化向量(IV)、加密算法配置(CTR/XTS/GCM)以及启用(Enable)控制位。

  • 独立使能:只有已启用的 Entry 区域才会进行解密;未启用的区域,数据直接透传。

  • OTF 解密:当 CPU 访问固件时,RSIP 根据访问地址计算 IV 的低 64 位(IV 的高 64 位是用户配置),从 Flash 读取密文并使用 OTP 密钥自动解密。

默认的 SDK 已为所有固件提供了 RSIP 加密的配置选项,每个固件占用一个独立的 Entry。 您可以根据安全需求,通过修改配置文件决定是否启用此保护。

RSIP Entry 实现了多通道解密的硬件架构,但其所需的密钥和控制位需预先存储在芯片的 OTP 区域中。下节介绍 RSIP OTP 配置。

OTP 配置

OTP 是芯片内部的一次性可编程存储器,具有非易失性和不可篡改性。 RSIP 密钥和控制位需要预先存储在芯片的 OTP 区域中。启动时硬件自动将密钥加载进 RSIP 引擎。Boot ROM 代码从 OTP 读取模式及使能信息,并配置 RSIP 控制寄存器。

RSIP 支持多种 AES 加密模式以满足不同安全等级需求。XTS 模式使用双密钥提供更高的加密安全性,是推荐的默认选择。 不同芯片的 OTP 配置地址和方法不同,请根据实际使用的芯片型号查阅下表:

RTL8721Dx:

名称

地址

大小(比特)

默认值

描述

RSIP Enable

逻辑映射

0x003 bit[3]

1

0

RSIP 是否启用(研发测试阶段使用,可以关闭)

  • 1:RSIP 启用

  • 0:RSIP 禁用

RSIP Enable

物理映射

0x368 bit[2]

1

1

RSIP 是否启用(量产阶段使用,永久开启)

  • 0:RSIP 启用

  • 1:RSIP 禁用

RSIP Key 1

物理映射

0x2C0 ~ 0x2DF

256

每个字节 0xFF

RSIP 密钥存储在安全区 OTP 区域,并在启动时自动加载到 RSIP

RSIP Key 2

物理映射

0x2E0 ~ 0x2FF

256

每个字节 0xFF

RSIP 密钥存储在安全区 OTP 区域,并在启动时自动加载到 RSIP

RSIP Mode

物理映射

0x369 bit[1:0]

2

0x3

RSIP 加密算法模式

  • 00/11b:XTS 模式

  • 01/10b:CTR 模式

RSIP Key1 Read Protection

物理映射

0x366 bit[7]

1

1

  • 0:启用 RSIP 密钥1 的读取保护,防止被读出

  • 1:禁用 RSIP 密钥1 的读取保护

RSIP Key1 Write Protection

物理映射

0x367 bit[0]

1

1

  • 0:启用 RSIP 密钥1 的写入保护,防止被黑客全写0

  • 1:禁用 RSIP 密钥1 的写入保护

RSIP Key2 Read Protection

物理映射

0x367 bit[1]

1

1

  • 0:启用 RSIP 密钥2 的读取保护,防止被读出

  • 1:禁用 RSIP 密钥2 的读取保护

RSIP Key2 Write Protection

物理映射

0x367 bit[2]

1

1

  • 0:启用 RSIP 密钥2 的写入保护,防止被黑客全写0

  • 1:禁用 RSIP 密钥2 的写入保护

RSIP Mode Write Protection

物理映射

0x367 bit[3]

1

1

  • 0:启用 RSIP 模式的写入保护,防止被黑客篡改

  • 1:禁用 RSIP 模式的写入保护

使用方法

RSIP 的完整配置流程涵盖开发与生产两个阶段:开发阶段生成密钥和加密固件,生产阶段烧录 OTP 和加密固件。 各步骤按顺序介绍如下:

1. 生成密钥和 IV(开发阶段)

密钥和初始化向量(IV)是 AES 加密算法的核心配置项,直接决定了固件加密的安全性。密钥用于加密和解密数据,IV 用于确保相同的明文在不同位置产生不同的密文,防止模式分析攻击。 密钥长度为 32 字节(256 位),由用户随机生成且必须保密。IV 总长度为 128 位,其中高 64 位需要用户随机生成,低 64 位在系统运行时由 RSIP 根据固件访问地址自动计算生成,无需用户指定。

密钥和 IV 生成后,需要在 Manifest 配置文件中设置 RSIP 参数,以便编译生成加密固件。

2. 配置 Manifest 生成加密固件(开发阶段)

Manifest 配置用于指定后处理脚本如何对固件进行加密,密文固件将与 OTP 中的密钥对应。 在 <SDK>/component/soc/amebaxxx/project/manifest.json5 配置文件中设置 rsip_enable: true,根据生成的密钥和 IV 配置 rsip_modersip_keyrsip_iv。 配置文件中, image1 段对应 Bootloader, image2 段对应用户的应用程序固件。推荐使用安全性更高的 XTS 模式。

不同芯片的配置示例请参照下表:

RTL8721Dx:

支持一组 RSIP 密钥。使用 XTS 模式加密的示例配置如下:

{
   version: 1,
   image1: {
   rsip_iv: "7ba46d14d709872a",
   },
   ...
   image2: {
   rsip_iv: "fcadc141386b60c5",
   },
   ...

   /* ================================ RSIP globle settings =============================== */
   rsip_enable: true,
   /* rsip_mode valid option: 1 (XTS), 0 (CTR) */
   rsip_mode: 1,
   /* rsip_key_group valid option: "rsip_xts_g0", "rsip_ctr_g0" */
   rsip_key_group: "rsip_xts_g0",
   /* rsip key group define, uses do not modify */
   rsip_xts_g0: ["otp_key_0x2C0", "otp_key_0x2E0"],
   /* ctr mode not recommend */
   rsip_ctr_g0: ["otp_key_0x2E0"],

   /* =================================== OTP key value =================================== */
   otp_key_0x2C0: "E2A0D6500BBF1DD8DC212098C230EB731ECE3A81AA11D0E6E538FA36BBA4FF6E",
   otp_key_0x2E0: "6AA34203018334474B25A0600996CA0968AA6228B886FF234B4EB9628B703C0A",
   ...
}

配置完成后,执行 ameba.py build 指令重新编译工程,即可生成加密后的固件文件。 加密固件生成后,开发阶段的工作已全部完成。

3. 烧录 OTP(生产阶段)

本步骤进入生产阶段。将密钥烧录至芯片的 OTP 区域,使芯片能够解密并运行该加密固件。 密钥写入 OTP 并使能 RSIP 后,该芯片只能从特定的加密固件启动。

警告

  • AT+SEC 命令前提:需在 menuconfig 中使能 CONFIG_ATCMD_SECURE``(默认关闭),路径: ``CONFIG SHELL Enable ATCMD SECURE 。未使能时 AT+SEC 命令不可用。

  • OTP 烧录前提:设备 Flash 中需已存在一个可正常启动的固件,以便通过串口发送 AT 命令。下面命令中的密钥字符串仅作为示例,勿用于生产。

  • OTP 区域只能写入一次,无法擦除或撤销。请在执行写入命令前,仔细核对地址和数据。

  • 量产阶段建议先在少量样机上验证通过后,再进行批量操作。

  • 特别注意 OTP 地址是逻辑区还是物理区。具体的 OTP 操作方法请参考 OTP 串口编程章节

根据芯片型号,参照 RSIP OTP 表格,烧录密钥并配置相关控制位。下面是配置示例:

  1. 烧录 RSIP 密钥至 OTP 物理区。使用以下命令烧录 RSIP 密钥,命令中的密钥为 manifest 配置示例 中的 XTS 模式密钥:

    RTL8721Dx:

    仅支持一组密钥(grp0)。XTS 模式使用两步命令序列。首先发送 ECB 密钥:

    AT+SEC=RSIP_KEY,grp0,xts,E2A0D6500BBF1DD8DC212098C230EB731ECE3A81AA11D0E6E538FA36BBA4FF6E
    

    命令返回 KEY1 OK 后,发送 CTR 密钥:

    AT+SEC=RSIP_KEY2,6AA34203018334474B25A0600996CA0968AA6228B886FF234B4EB9628B703C0A
    

    CTR 模式仅需一段 32 字节密钥:AT+SEC=RSIP_KEY,grp0,ctr,<hex>

    发送第二把密钥后,两把密钥和 RSIP 模式统一写入 OTP 并自动回读校验。若校验失败会返回错误信息。 注意:发送第一把密钥后,在提供第二把密钥之前,仅接受 RSIP_KEY2 命令。复位设备可取消待提交状态。 烧录密钥时注意字节顺序:密钥的最高有效字节(MSB)存储在最高的 OTP 地址。例如上面命令中的第一段密钥(ECB)会将 0xE2 烧录至 OTP 地址 0x2C00xA0 烧录至 0x2C1,依此类推。第二段密钥(CTR)烧录至 0x2E0 起始地址。

  2. 选择和启用 RSIP 模式。根据使用场景选择以下配置方式:

开发阶段临时启用:

逻辑区 OTP 配置可修改,开发阶段可关闭 RSIP 保护,方便调试。 默认 OTP 值已配置为 XTS 模式,只需启用 RSIP 功能:

AT+SEC=RSIP_EN,temp

关闭上述临时使能(若已通过 perm 永久使能,则此命令无效):

AT+SEC=RSIP_EN,temp_off

完成 OTP 烧录后,将加密固件烧录到 Flash 中,随后复位开发板进行验证。

4. 烧录加密固件(生产阶段)

使用 ImageTool 或其他烧录工具,将开发阶段生成的加密固件烧录到芯片的 Flash 存储器中。 此时 Flash 中存储的是加密后的密文固件,即使攻击者通过物理手段读取 Flash,也只能获得无法解密的密文数据。

5. 复位运行(测试阶段)

固件烧录完成后,复位开发板进行验证。如果 RSIP 加密固件成功加载,您将在启动日志中看到 OTF EN 的打印信息,这表明 RSIP 实时解密功能已正常启用。 不同芯片的启动日志示例请参照下表:

RTL8721Dx:
ROM:[V1.0]
FLASH RATE:1, Pinmux:1
OTF EN
IMG1(OTA1) VALID, ret: 0
IMG1 ENTRY[3000ad39:0]
[KM4] [MODULE_BOOT-LEVEL_INFO]:IMG1 ENTER MSP:[30009fe4]
[KM4] [MODULE_BOOT-LEVEL_INFO]:IMG1 SECURE STATE: 1
[KM4] [MODULE_BOOT-LEVEL_INFO]:Flash ID: c8-65-17
[KM4] [MODULE_BOOT-LEVEL_INFO]:Flash Read 4IO
[KM4] FLASH HandShake[0x1 OK]
[KM4] IMG2 OTF EN
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM0 XIP IMG[0c000000:5020]
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM0 SRAM[20040000:da0]
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM0 PSRAM[0c005dc0:20]
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM0 BOOT[20004d00:40]
[KM4] IMG2 OTF EN
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 XIP IMG[0e000000:6d60]
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 SRAM[20010000:60]
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 PSRAM[0e006dc0:20]
[KM4] [MODULE_BOOT-LEVEL_INFO]:IMG2 BOOT from OTA 1
[KM4] [MODULE_BOOT-LEVEL_INFO]:Start NonSecure @ 0xe000115 ...
[KM0] [MODULE_BOOT-LEVEL_INFO]:KM0 BOOT UP
[KM4] [MODULE_BOOT-LEVEL_INFO]:VTOR: 20005000, VTOR_NS:0
[KM0] [MODULE_BOOT-LEVEL_INFO]:KM0 APP_START
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 APP START
[KM0] [MODULE_BOOT-LEVEL_INFO]:KM0 CPU CLK: 40000000 Hz
[KM4] [MODULE_BOOT-LEVEL_INFO]:IMG2 SECURE STATE: 0
[KM0] [MODULE_BOOT-LEVEL_INFO]:KM0 VTOR:0x20000000
[KM4] [MODULE_BOOT-LEVEL_INFO]:KM4 BOOT REASON: 0

备注

量产指导

本节介绍基于双分区机制的 RSIP 量产配置方案。

Bootloader(image1) 和 APP(image2) 固件均采用双分区设计:OTA1 存储未加密的量产工具固件,OTA2 存储加密的产品固件。

该方案的优势在于整个量产过程只烧录一次 Flash,即未加密的量产工具固件(第一分区)和加密的产品固件(第二分区)一次性烧录,避免了传统方案需要先烧录未加密固件配置 OTP、再重新烧录加密固件的两步操作,简化了量产流程。

../../_images/rsip_mp_flow.svg

RSIP 量产使能流程

上述流程利用双分区机制实现固件切换:首次启动时由于第二分区地址未配置,系统从第一分区启动;通过第一分区固件完成 OTP 配置并使能 RSIP。复位后第一分区(明文固件)无法正确执行,系统自动尝试从第二分区运行加密固件,确保了加密固件的唯一可执行性。

具体实施步骤如下:

1. 固件准备与烧录

准备两份固件并在量产时一次性烧录至芯片 Flash。第一分区为未加密的量产工具固件,第二分区为加密产品固件。

烧录后,由于 OTP 中尚未配置第二分区地址,芯片将从第一分区启动。

2. 通过第一分区固件烧录 OTP

第一分区固件启动后,通过串口发送 AT 命令依次完成以下配置:

  1. 配置第二分区地址:将固件的 Flash 地址写入 OTP,使能产品固件。详细的地址配置方法和计算公式请参考 BOOT OTAFlash 布局修改

  2. 配置 RSIP 密钥和使能:按照 使用方法步骤 3 的量产阶段永久启用流程完成 RSIP 配置,包括烧录密钥、配置密钥读/写保护、锁定加密模式并启用模式写保护、烧录物理使能位。

    警告

    OTP 只能写入一次,烧录前请务必核对地址和数据。建议先在样机上验证后再批量操作。

3. 复位切换至加密固件

完成 OTP 配置后复位系统。此时第二分区地址已配置,RSIP 已启用并配置了正确的密钥,第一分区(明文固件)无法正确执行,系统将自动尝试从第二分区的加密固件启动。 启动日志中应显示 OTF EN,表明 RSIP 实时解密功能已正常工作。

问题排查

若在启用 RSIP 后遇到问题,请参考下表进行排查:

问题现象

可能原因

解决方案

使能 RSIP 后复位启动失败

RSIP 功能未成功启用

检查 OTP 配置,确认 RSIP Enable 位已正确置位。

RSIP 密钥烧录失败

密钥烧录后命令会自动回读校验。若校验失败,请检查 OTP 中烧录的密钥是否与 manifest.json5 中配置的密钥一致。

烧录的固件未加密

确认已正确配置 manifest.json5 并重新编译生成加密固件。

启动日志未显示 “OTF EN”

RSIP 功能未启用或配置未生效

检查 OTP 逻辑或者物理使能位,确保 RSIP 功能已启用,并确认已进行系统复位。