ESP32-C3 手动启用 Secure Boot V2 与 Flash 加密流程

news2024/9/28 13:16:06

ESP-IDF 中 flash 加密可以在 bootloader 阶段自动启用,但是这需要设备自加密后重启一次,为了节省这次重启的步骤,你可以选择通过一些脚本工具在外部启用 flash 加密。

本篇文档用于介绍 ESP32-C3 手动启用 Secure Boot V2Flash 加密的操作流程。其中,Flash 加密使用发布模式(Release Mode),使用主机生成的密钥对数据进行加密。Secure Boot 方案所需的公钥的 SHA-256 哈希摘要和和 Flash 加密方案需要的 Flash 加密秘钥均为外部生成(bootloader 阶段自动启用的方式为设备内自动计算并写入相关的 efuse)。其他相关的 efuse 也通过脚本工具进行烧录,更多信息请参考乐鑫官方文档 基于主机的安全工作流程。本篇文档可以看做官方文档的一次实践,仅做参考。

1 测试环境

  • 硬件:ESP32-C3
  • IDF 版本:esp-idf v5.0.2
  • 测试例程:examples/system/ota/simple_ota_example

2 通过 menuconfig 使能

2.1 调整分区表偏移量

使能 Flash 加密以及 Secure Boot V2 后,生成的 bootloader bin 会变大,可以通过调整分区表偏移量增大 bootloader 分区大小,本例中将分区表偏移量从默认的 0x8000 调整到 0xF000,这样 bootloader 分区的大小为 0xF000 - 0x1000 = 0xE000 (0x0 为 bootloader bin 烧录地址),可以参考引导加载程序大小。
在这里插入图片描述

需要注意的是,开启 Flash 加密会默认使能 NVS 加密,需要在分区表中定义 NVS Key 分区,否则运行会出现错误。参考 NVS Key Partition。如果不需要 NVS 加密,可以通过 menuconfig 禁用该功能,配置路径: (Top) -> Component config -> NVS -> [ ] Enable NVS encryption,这样无需在分区表中定义 NVS Key 分区。

2.2 安全特征配置

在这里插入图片描述
Flash 加密 release 模式默认的 UART ROM download modePermanently switch to Secure mode (recommended),在开发过程中,为了避出现意外无法使设备恢复正常,暂且使能 UART ROM 下载模式,后面可以通过烧录 ENABLE_SECURITY_DOWNLOAD 使用安全下载模式。

3 测试流程

3.1 生成 Secure Boot V2 签名秘钥并烧录到对应 efuse

  • 可使用如下指令生成签名秘钥:
python $IDF_PATH/components/esptool_py/esptool/espsecure.py generate_signing_key --version 2 secure_boot_signing_key.pem
  • 生成 secure_boot_digest.bin,该文件为 secure boot 公钥的 SHA-256 摘要:
python $IDF_PATH/components/esptool_py/esptool/espsecure.py digest_sbv2_public_key --keyfile secure_boot_signing_key.pem --output secure_boot_digest.bin
  • 烧录 secure_boot_digest.bin
python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_key BLOCK_KEY0 secure_boot_digest.bin SECURE_BOOT_DIGEST0
  • 烧录 SECURE_BOOT_EN
python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse SECURE_BOOT_EN 1

3.2 Flash 加密密钥生成与烧录

python $IDF_PATH/components/esptool_py/esptool/espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_key BLOCK_KEY1 my_flash_encryption_key.bin XTS_AES_128_KEY
  • Flash 加密相关安全 eFuses:
    • DIS_DOWNLOAD_ICACHE: Disable UART cache
    • DIS_DIRECT_BOOT: Disable direct boot (legacy SPI boot mode)
    • DIS_USB_JTAG: Disable USB switch to JTAG
    • DIS_PAD_JTAG: Disable JTAG permanently
    • DIS_DOWNLOAD_MANUAL_ENCRYPT: Disable UART bootloader encryption access
      此处先不烧录 DIS_DOWNLOAD_MANUAL_ENCRYPT,如果不禁用这个 efuse,那么仍可通过 idf.py encrypted-app-flash/idf.py encrypted-flash (参考 Re-flashing Updated Partitions)或者 esptool.py write_flash --encrypt 这两种方式边写边加密明文固件。
python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse DIS_DOWNLOAD_ICACHE 1 DIS_PAD_JTAG 1 DIS_USB_JTAG 1 DIS_DIRECT_BOOT 1 
  • Flash 加密模式下 SPI_BOOT_CRYPT_CNT 需要设置为 7,此时 Flash 加密无法关闭。
python $IDF_PATH/components/esptool_py/esptool/espefuse.py burn_efuse SPI_BOOT_CRYPT_CNT 7

3.3 编译 bootloader

idf.py bootloader

3.4 编译 app/partition bin

idf.py build
Project build complete. To flash, run this command:
/home/mali/.espressif/python_env/idf5.0_py3.8_env/bin/python ../../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after no_reset --chip esp32c3 --no-stub write_flash --flash_mode dio --flash_size keep --flash_freq 80m 0xf000 build/partition_table/partition-table.bin 0x14000 build/ota_data_initial.bin 0x20000 build/simple_ota.bin
or run 'idf.py -p (PORT) flash'

由于使能了 Sign binaries during build, 会在构建过程中对 bootloaderapp bin 进行签名,此时,生成的 bootloader.binapp.bin 为签过名的明文固件。

  • 获取分区表信息:
$ idf.py partition-table
Executing action: partition-table
Running ninja in directory /home/mali/esp/esp32/rel_50/examples/system/ota/simple_ota_example/build
Executing "ninja partition-table"...
[1/2] cd /home/mali/esp/esp32/rel_50/examples/system/ota/simple_ota_example/build/esp-idf/partition_table && /home/mali/.e...sif/tools/cmake/3.24.0/bin/cmake -E echo "*******************************************************************************"Partition table binary generated. Contents:
*******************************************************************************
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x10000,16K,
otadata,data,ota,0x14000,8K,
phy_init,data,phy,0x16000,4K,
ota_0,app,ota_0,0x20000,1536K,
ota_1,app,ota_1,0x1a0000,1536K,
nvs_key,data,nvs_keys,0x320000,4K,encrypted
*******************************************************************************
[2/2] Running utility command for partition-tablePartition table built:

Partition Table build complete. To flash, run this command:
/home/mali/.espressif/python_env/idf5.0_py3.8_env/bin/python ../../../../components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after no_reset --chip esp32c3 --no-stub write_flash 0xf000 build/partition_table/partition-table.bin
or run 'idf.py -p (PORT) partition-table-flash'

3.5 使用 Flash 加密密钥对签名后的 bin 文件进行加密

使用 Flash 加密密钥对 bin 文件加密时,需要指定 bin 文件的地址,这个地址可从 idf.py build 结束后输出的烧录指令中获取,在本例中,共有四个 bin 文件需要被加密。

0x0 build/bootloader/bootloader.bin (ESP32-C3 的 bootloader bin 的烧录地址是一个确定值,为 0x0)
0xf000 build/partition_table/partition-table.bin
0x14000 build/ota_data_initial.bin 
0x20000 build/simple_ota.bin
python $IDF_PATH/components/esptool_py/esptool/espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x20000 --output simple_ota_enc.bin build/simple_ota.bin
python $IDF_PATH/components/esptool_py/esptool/espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0xf000 --output partition-table_enc.bin build/partition_table/partition-table.bin
python $IDF_PATH/components/esptool_py/esptool/espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x0 --output bootloader_enc.bin build/bootloader/bootloader.bin
python $IDF_PATH/components/esptool_py/esptool/espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x14000 --output ota_data_initial_enc.bin build/ota_data_initial.bin

3.6 烧录加密后的 bin 文件

  • 烧录前建议擦除 Flash 一次。
python $IDF_PATH/components/esptool_py/esptool/esptool.py -b 921600 --before default_reset --after no_reset --chip esp32c3 --no-stub write_flash --force --flash_mode dio --flash_size keep --flash_freq 80m 0x0 bootloader_enc.bin 0xf000 partition-table_enc.bin 0x14000 ota_data_initial_enc.bin 0x20000 simple_ota_enc.bin
  • 烧录完成后,检查设备是否可以正常启动。如果可以正常启动,从 log 中应该可以看到类似下面的日志:
E (1171) flash_encrypt: Flash encryption settings error: app is configured for RELEASE but efuses are set for DEVELOPMENT
E (1181) flash_encrypt: Mismatch found in security options in bootloader menuconfig and efuse settings. Device is not secure.

flash_encrypt 报错的的原因是当前烧录的 efuse 和 Flash 加密 release 模式不匹配,这是因为前面没有烧录 DIS_DOWNLOAD_MANUAL_ENCRYPT,release 模式下需要保证这个 efuse 烧录,此时,无法再可通过 idf.py encrypted-app-flash/idf.py encrypted-flash (参考 Re-flashing Updated Partitions)或者 esptool.py write_flash --encrypt 这两种方式边写边加密明文固件,需要先使用 Flash 加密秘钥对明文固件进行加密,然后直接烧录密文固件。

espefuse.py burn_efuse DIS_DOWNLOAD_MANUAL_ENCRYPT
  • 前面在 menuconfig 中使能 UART ROM 下载模式,Flash release 模式建议使用安全下载模式,该模式下,仍可烧录固件但是无法读取固件。
espefuse.py burn_efuse ENABLE_SECURITY_DOWNLOAD

4 补充内容

UART ROM 三种下载模式的比较

  1. 下面是对于 UART ROM 三种下载模式的大致比较,更多信息请见 UART ROM download mode。
  • SECURE_DISABLE_ROM_DL_MODE:禁用下载模式
  • SECURE_ENABLE_SECURE_ROM_DL_MODE:安全下载模式
  • SECURE_INSECURE_ALLOW_DL_MODE:使能下载模式
禁用下载模式安全下载模式使能下载模式
是否可以下载固件
是否可以读取固件是(esptool.py --no-stub read_flash
是否可以获取 efuse 信息是(部分esptool.py --no-stub get_security_info是(全部espefuse.py summary
通过烧录 efuse 使能espefuse.py burn_efuse DIS_DOWNLOAD_MODEespefuse.py burn_efuse ENABLE_SECURITY_DOWNLOAD无需烧录 efuse
  1. 如果要对已经使能 Flash 加密和 secure boot v2 的设备进行 OTA 升级,那么 ota bin 文件需要先进行签名再放到服务器上,对于通用的 ota 例程,放在服务器上的 ota bin 应为签名后的明文固件,在写入到 ota 分区时会自动进行加密。
espsecure.py sign_data --version 2 --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE
  • 此处的 PRIVATE_SIGNING_KEY 为前面生成的 Secure Boot 签名密钥 secure_boot_signing_key.pem,更多信息可见 Signing using espsecure.py。

  • 如果担心服务器上的明文 ota.bin 被他人窃取(例如: non-TLS).,可以对 ota.bin 进行预加密,参考例程 pre_encrypted_ota。

5 参考链接

  • Security Guides
  • Enable Flash Encryption and Secure Boot V2 Externally

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/906777.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

矩阵乘法(C++ mpi 并行实现)

矩阵乘法有2种思路,我最先想到的是第一种思路,但是时间、空间复杂度都比较高。后面参考了一些资料,实现了第二种思路。 一、思路1:按行、列分块 矩阵乘法有一个很好的性质,就是结果矩阵的每个元素是不互相依赖的&…

如何批量加密PDF文件并设置不同密码 - 批量PDF加密工具使用教程

如果你正在寻找一种方法来批量加密和保护你的PDF文件,批量PDF加密工具是一个不错的选择。 它是一个体积小巧但功能强大的Windows工具软件,能够批量给多个PDF文件加密和限制,包括设置打印限制、禁止文字复制,并增加独立的打开密码。…

React实战 - React路由鉴权

目录 一、React-Router知识回顾 二、路由鉴权应用分析 三、路由鉴权配置 四、权限控制 一、React-Router知识回顾 React-router相关的文章中我已经给大家演示了最基础的应用&#xff1a; <Switch ><Route path"/products/:id" component{ProductDetai…

【Rust】Rust学习 第十七章Rust 的面向对象特性

面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;是一种模式化编程方式。对象&#xff08;Object&#xff09;来源于 20 世纪 60 年代的 Simula 编程语言。这些对象影响了 Alan Kay 的编程架构中对象之间的消息传递。他在 1967 年创造了 面向对…

Blob,File文件上传下载的内容笔记

Blob 对象表示一个不可变、原始数据的类文件对象&#xff0c;可以看做是存放二进制数据的容器 。 简单来说Blob就是一个二进制的对象&#xff0c;我们可以通过这个blob对象直接读取文件内容 Blob和Flie没什么区别&#xff0c;File继承于Blob,就是多了一个name属性&#xff0c;表…

当今职场,正在加速淘汰 “巨婴员工”

我担任过多家上市公司的技术高管职位&#xff0c;在工作中经常会遇到巨婴型员工&#xff0c;他们外在的表现是&#xff0c;不能够很好地管理自己&#xff0c;缺乏自律&#xff0c;缺乏起码的抗挫折能力和抗压能力&#xff0c;需要领导呵护着、同事们忍让着。作为一名管理者&…

科技成果鉴定测试有什么意义?专业CMA、CNAS软件测评公司

科技成果鉴定测试是指通过一系列科学的实验和检测手段&#xff0c;对科技成果进行客观评价和鉴定的过程。通过测试&#xff0c;可以对科技成果的技术优劣进行评估&#xff0c;从而为科技创新提供参考和指导。 一、科技成果鉴定测试的意义 1、帮助客户了解科技产品的性能特点和…

排序(七种排序)

1.插入排序 2.希尔排序 3.选择排序 4.堆排序 5.冒泡排序 6.快速排序 7.归并排序 1.插入排序 1.1思路 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为 止&#xff0c;得到一个新的有序序列 1.2实现 //插入排…

[计算机入门] 个性化设置系统

3.2 个性化设置系统 在Windows系统中&#xff0c;个性化设置可以让用户根据自己的喜好和需求对系统进行定制和调整&#xff0c;包括桌面背景、声音、屏幕保护程序、鼠标指针、字体等。通过个性化设置&#xff0c;用户可以创建自己的独特界面和用户体验&#xff0c;使系统更加符…

HBuilderX获取iOS证书的打包步骤

简介&#xff1a; 目前app开发&#xff0c;很多企业都用H5框架来开发&#xff0c;而uniapp又是这些h5框架里面最成熟的&#xff0c;因此hbuilderx就成为了开发者的首选。然而,打包APP是需要证书的&#xff0c;那么这个证书又是如何获得呢&#xff1f; 生成苹果证书相对复杂一些…

Hyper-V Linux服务器安装

官方文档&#xff1a;在 Windows 10 创意者更新上使用 Hyper-V 创建虚拟机 | Microsoft Learn 1 新增虚拟交换机 打开Hyper-V管理器&#xff0c;找到右侧的操作列&#xff0c;点击“虚拟交换机管理器”&#xff1a; 点击“新建虚拟网络交换机”&#xff0c;交换机类型选择“外部…

用idea解决代码合并冲突

参考文章&#xff1a; IDEA&#xff1a;idea中的Git冲突解决&#xff08;非常重要&#xff09; idea操作git时 合并分支解决冲突 一、前言 1.什么事冲突&#xff1f; 冲突是指当你在提交或者更新代码时被合并的文件与当前文件不一致。读起来有点绕&#xff0c;结合下面的案例…

16、Flink 的table api与sql之连接外部系统: 读写外部系统的连接器和格式以及FileSystem示例(1)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

Unity解决:3D开发模式第三人称视角 WASD控制角色移动旋转 使用InputSystem

Unity版本&#xff1a;2019.2.3f1 目录 安装InputSystem 1&#xff1a;创建InputHander.cs脚本 挂载到Player物体上 获取键盘输入WADS 2.创建PlayerLocomotion.cs挂载到Player物体上&#xff0c;控制物体移动转向 安装InputSystem 菜单栏/Window/Package Manager/Input Syst…

AI图片处理功能演示

例如&#xff0c;这是一张不错的图片&#xff0c;但是有3只手。 我们可以选择有问题的区域&#xff0c;然后要求 niji 进行重新绘制。 根据我们选择的区域&#xff0c;我们可以以不同的方式修复结果。 创意修复 修复并不仅限于纠正错误。我们可以要求 niji 添加额外的元素&…

MATLAB R2023a for Mac Update_5

MATLAB是一种高级的计算机编程环境和开发工具&#xff0c;主要用于数值计算、数据分析、算法开发和可视化。它由MathWorks公司开发&#xff0c;被广泛应用于科学研究、工程设计、数据分析和教育等领域。 MATLAB提供了丰富的数学和工程函数库&#xff0c;可以进行矩阵运算、信号…

跨域资源共享 (CORS) | PortSwigger(burpsuite官方靶场)【万字】

写在前面 在开始之前&#xff0c;先要看看ajax的局限性和其他跨域资源共享的方式&#xff0c;这里简单说说。 下面提到大量的origin&#xff0c;注意区分referer&#xff0c;origin只说明请求发出的域。 浏览器的同源组策略&#xff1a;如果两个 URL 的 protocol、port 和 h…

所见即所得,「Paraverse平行云」助力万间打造智能建造新图景

在城市建设行业中&#xff0c;数字化逐渐成为其主导力量。 新一代信息基础设施建设也迎来了新的里程碑。数据显示&#xff0c;截至今年&#xff0c;我国已全面推进城市信息模型&#xff08;CIM&#xff09;基础平台建设&#xff0c;为城市规划、建设管理提供了多场景应用的强大…

【Python】代理池针对ip拦截破解

代理池是一种常见的反反爬虫技术&#xff0c;通过维护一组可用的代理服务器&#xff0c;来在被反爬虫限制的情况下&#xff0c;实现数据的爬取。但是&#xff0c;代理池本身也面临着被目标网站针对ip进行拦截的风险。 本文将详细介绍代理池针对ip拦截破解的方法&#xff0c;包含…

小研究 - Android 字节码动态分析分布式框架(三)

安卓平台是个多进程同时运行的系统&#xff0c;它还缺少合适的动态分析接口。因此&#xff0c;在安卓平台上进行全面的动态分析具有高难度和挑战性。已有的研究大多是针对一些安全问题的分析方法或者框架&#xff0c;无法为实现更加灵活、通用的动态分析工具的开发提供支持。此…