安全启动
本章节主要介绍基于 WQ SDK 的安全启动流程,安全固件的构建方式和烧录方式。
概述
芯片安全启动(Secure Boot)是一种确保设备仅运行经过授权和可信代码的安全机制,其主要目标是防止未经授权的软件加载,保护设备免受潜在的安全威胁。
本文档的目标是帮助开发人员理解和实现芯片的安全启动功能。通过介绍相关概念、技术细节和实现步骤,开发人员可以正确配置和使用安全启动功能,确保设备的启动过程安全可靠。
本文档的结构如下:
背景与需求:解释安全启动的目标和实现意义。
技术概览:描述安全启动的关键概念和常见实现方案。
安全启动流程描述:详细描述硬件初始化、引导加载程序阶段和操作系统加载等关键步骤。
流程实现细节:提供实现安全启动功能所需的硬件和软件支持。
背景与需求
- 安全启动的目标
确保设备仅运行经过认证和可信任的软件。
防止恶意代码或未经授权的软件加载。
提供设备启动过程的完整性和保密性验证。
建立可信的设备运行环境,增强系统安全性。
技术概览
摘要算法:用于生成数据的唯一指纹,确保数据的完整性。当前使用的是 SHA-256 算法,其具有较高的安全性和广泛的应用。 SHA-256 的哈希碰撞概率极低,输出为 256 位的固定长度散列值,其碰撞概率在理想条件下为 ,这意味着尝试产生两个相同散列值的成功率几乎为零。这种高安全性使 SHA-256 在关键安全应用中广泛采用,确保数据在传输和存储过程中的完整性和防篡改能力。
RSA: 一种广泛应用的非对称加密算法,使用公钥和私钥对进行数据加密和解密。其主要应用包括数字签名、密钥交换和数据加密。数字签名用于验证数据的来源和完整性,而密钥交换则用于在不安全的网络环境中安全地传输加密密钥。RSA-2048 和 RSA-3072 是常用的密钥长度,提供较高的安全性,适用于嵌入式设备和安全启动过程中的关键数据保护。
OTP(一次性可编程存储器):OTP存储器的一个重要特点是数据一旦写入后无法再更改。与可擦写存储器(如 EEPROM 或 Flash)不同, OTP 存储器不支持擦除或修改操作,在嵌入式系统中, OTP 可以用于存储加密密钥或其他身份验证信息。由于它只能编程一次,这样的数据无法被修改或篡改,从而增加了安全性。
安全启动流程
- 一级引导 (由ROM引导至SBL)
验证公钥,读取 OTP 中存储的公钥的 hash 值,与需要被引导的固件所携带的公钥计算出的hash值进行比较,如果相同,则认为公钥合法。
验证固件,使用公钥解密公钥的签名,与固件的hash值进行对比,如果相同则认为固件合法,加载并运行固件。
- 二级引导 (由SBL启动APP)
验证公钥,与一级验证相同的方式验证app携带的公钥的合法性。
验证app,与一级引导相同的方式验证app固件的合法性,若验证通过则加载并启动。
- 链式启动 (由app加载其他固件)
链式启动中app再次加载其他固件时,可由app自行添加相应的验证方式,或直接使用与一级/二级引导相同的验证方式。
链式启动中的每一级启动都应验证固件的合法性。
graph TB
subgraph 安全启动流程
direction TB
subgraph 存储区域
subgraph OTP/EFUSE
style OTP/EFUSE fill:#f99
pubhash[公钥 hash值]
end
subgraph Flash
subgraph SBL
style SBL fill:#88F
sblbin[SBL固件]
pubkey[公钥]
sblsign[签名]
end
end
end
subgraph 签名服务器
style 签名服务器 fill:#cce
prikey[私钥]
sign[[对固件进行签名]]
pubkey <--公私钥对--> prikey
prikey --> sign
sblbin --> sign
sign --> sblsign
end
A[开始] --> B[计算公钥HASH值]
pubkey --> B
pubhash --> C
B --> C{与OTP公钥哈希值比对}
C -->|不相等| G[公钥非法,中止流程]
style G fill:#C22
C -->|相等| D[计算固件哈希值A]
style D fill:#282
sblbin --> D
D --> E[解密签名得到哈希值B]
pubkey --> E
sblsign --> E
E --> F{哈希值A和B比对}
F -->|相同| H[验签成功,正常启动]
style H fill:#282
F -->|不同| I[验签失败]
style I fill:#C22
end
安全启动流程图
安全固件的配置和构建
- 配置
在项目目录使用
scons --menuconfig打开配置开启 enable build secure package 选项
在 Select signature type 中选择要使用的签名算法
按需开启各个固件的签名 Enable ?CORE image secure
在 Command to sign the image 中配置在编译机器中可以运行的用来对固件进行签名的命令 [1]
- 构建
执行常规编译命令
scons
- 安全固件构建流程
flowchart TD subgraph 编译服务器 style 编译服务器 fill:#FFFACD build[编译] pack[打包] burn[烧录] firmware([固件.wpk]) build --> binfile1([固件1.bin]) build --> binfile2([固件2.bin]) build --> binfile3([固件3.bin]) binfile1 --> pack binfile2 --> pack binfile3 --> pack subgraph 签名脚本 style 签名脚本 fill:#87cefA upload[上传] download[下载] upload --> sign signfile --> download subgraph 签名服务器 style 签名服务器 fill:#FF69B4 sign[签名] prikey[私钥] prikey --> sign sign --> signfile([签名文件]) end end binfile1 --> upload binfile2 --> upload binfile3 --> upload download --> signfilea1([签名1.sign]) download --> signfilea2([签名2.sign]) download --> signfilea3([签名3.sign]) download --> pubkey[公钥] signfilea1 --> pack signfilea2 --> pack signfilea3 --> pack pubkey --> pack pack --> firmware --> burn end安全启动流程图
安全固件的下载和安全启动的开启
- 已开启了安全启动的芯片,后续下载
使用工具加载正确的固件包 [4]
取消勾选 开启安全启动 选项
取消勾选 开启安全下载 选项
点击开始烧录
- 使用安全固件包,但不使用开启和使用安全启动 [5]
使用工具加载固件包
点击开始烧录
此选项会向OTP中写入公钥的摘要信息,后续仅授权固件可以在此芯片运行
此选项会向OTP中写入公钥的摘要信息,后续仅授权的固件可以进行烧录
确保此固件包与芯片内部保存的加密信息相符
仅支持在未开启安全启动的芯片上使用此方式