Flash 加密
Flash 加密
Flash 加密功能用于加密 ESP32 连接的 SPI Flash 的内容。启用 Flash 加密后,通过物理方式读取 SPI Flash 的内容不足以恢复大多数 Flash 内容。
Flash 加密与安全启动功能是分离的,您可以使用 Flash 加密而无需启用安全启动。但是,我们建议将这两种功能一起用于安全的环境。在没有安全启动的情况下,需要执行其他配置以确保 Flash 加密的有效性。有关更多详细信息,请参阅使用无安全启动的 Flash 加密.
启用闪存加密会限制您进一步更新 ESP32 的选项。请务必阅读本文档(包括 Flash 加密限制)并了解启用闪存加密的含义。
1 背景
- 使用带有 256 位密钥的 AES 加密闪存的内容。闪存加密密钥存储在芯片内部的 efuse 中,并且(默认情况下)受软件访问保护。
- 通过 ESP32 的闪存缓存映射功能,Flash 访问是透明的 - 映射到地址空间的任何闪存区域在读取时都将被透明地解密。
- 通过使用明文数据烧录 ESP32 来应用加密,并且(如果启用了加密)引导加载程序会在首次启动时对数据进行加密。
- 并非所有闪存都是加密的。以下类型的闪存数据已加密:
-
引导程序
-
安全启动引导加载程序摘要(如果启用了安全启动)
-
分区表
-
所有 “app” 类型分区
-
分区表中标有 “encrypted” 标志的任何分区
可能希望一些数据分区保持未加密以便于访问,或者使用对于数据被加密时无效的闪存友好更新算法。由于 NVS 库与闪存加密不直接兼容,因此无法加密用于非易失性存储的 NVS 分区。有关更多详细信息,请参阅 NVS 加密。
-
- 闪存加密密钥存储在 ESP32 芯片内部的 efuse 密钥块 1 中。默认情况下,此密钥具有读写保护功能,因此软件无法访问或更改密钥。
- 默认情况下,Efuse Block 1 编码方案为 “None”,并且在该块中存储 256 位密钥。在某些 ESP32 上,编码方案设置为 3/4 编码 (CODING_SCHEME efuse 的值为 1),并且必须在该块中存储 192 位密钥。有关详细信息,请参见 《ESP32 技术参考手册》第 20.3.1.3 节 “系统参数 coding_scheme”。在所有情况下,算法都在 256 位密钥上运行,通过重复一些位(具体细节)来扩展 192 位密钥。当
esptool.py
连接到芯片或espefuse.py summary
输出时,编码方案显示在 Features 行中。 - 闪存加密算法是 AES-256,其中密钥是“调整”的,每个 32 字节闪存块的偏移地址。这意味着每个 32 字节块(两个连续的 16 字节 AES 块)使用从闪存加密密钥派生的唯一密钥进行加密。
- 虽然芯片上运行的软件可以透明地解密闪存内容,但默认情况下,当启用闪存加密时,UART 引导加载程序无法解密(或加密)数据。
- 如果可以启用闪存加密,则编写使用加密闪存的代码时,编程人员必须采取一定的预防措施。
2 Flash 加密初始化
这是默认(推荐) Flash 加密初始化过程。可以为开发或其他目的自定义此过程,有关详细信息,请参阅 Flash 加密高级功能。
在首次启动时启用闪存加密后,硬件通过串行重新闪存最多允许3次后续闪存烧录。必须遵循特殊过程(在串口烧录中记录)才能执行这些更新。
- 如果启用了安全启动,则使用纯文本数据进行物理重新刷新需要“可重新映射”的安全启动摘要(请参阅 Flash 加密和安全启动)。
- OTA 更新可用于更新 Flash 内容,而不计入此限制。
- 在开发中启用闪存加密时,请使用预生成的闪存加密密钥,以允许使用预加密数据进行无限次重新闪存。
启用闪存加密的过程:
- 必须在启用闪存加密支持的情况下编译引导加载程序。在
make menuconfig
中,导航到“安全功能”,然后选择“是”以“启动时启用闪存加密”。 - 如果同时启用安全启动,最好同时选择这些选项。首先阅读安全启动文档。
- 正常构建并刷新引导加载程序,分区表和工厂应用程序映像。这些分区最初写入未加密的闪存。
启用安全启动和闪存加密时,引导加载程序应用程序二进制
bootloader.bin
可能会变得太大。请参阅 Bootloader 大小。
- 首次启动时,引导加载程序会看到