嵌入式设备安全实战:从安全左移到安全启动与SBOM管理
1. 项目概述嵌入式安全设计的时代挑战与应对在工业4.0、智能汽车和万物互联的时代嵌入式设备早已不是孤立的“黑盒子”。它们连接着工厂的生产线、家庭的智能中枢、行驶中的汽车网络甚至关键基础设施。随之而来的是攻击面的急剧扩大。恶意代码注入、固件篡改、数据窃取、乃至通过一个边缘设备渗透进整个核心网络这些威胁正变得日益真实和普遍。过去安全或许是某些“高精尖”产品的附加项今天它已成为所有联网嵌入式设备从设计之初就必须内置的“生存项”。更关键的是游戏规则正在改变。以欧盟《网络弹性法案》为代表全球范围内的法规正将安全责任明确地、不可推卸地压向设备制造商。这意味着安全不再是“最好有”而是“必须有”并且你需要证明你有。从产品设计、生产到停产的整个生命周期你都需要为设备的安全负责否则将面临严厉的处罚。这种从“用户责任”到“制造商责任”的范式转移迫使我们必须从根本上重新审视嵌入式开发流程。面对这种局面许多团队感到无从下手安全涉及面太广从硬件、启动、存储、通信到软件更新每个环节似乎都需要专业知识。但根据我在工业控制和汽车电子领域十多年的实战经验与其试图一次性构建铜墙铁壁不如抓住几个最核心、最有效的杠杆点。本文将聚焦三个经过验证的、能立即着手实施的策略安全设计左移、构建硬件信任根安全启动、以及管理软件物料清单。我会结合德州仪器处理器的具体实现拆解其背后的原理、实操步骤并分享那些数据手册里不会写的“踩坑”心得。无论你使用的是TI的AM62x、AM64x系列还是其他架构的处理器这里面的设计思路和实战要点都具有普适的参考价值。2. 安全设计左移将安全融入开发DNA2.1 传统开发流程的安全缺陷我们熟悉的嵌入式开发流程通常是“构思-评估-设计-编码-调试-测试-量产”。安全活动比如渗透测试、漏洞扫描往往被安排在开发末期甚至产品发布之后。这就好比房子盖好了才想起来检查地基的钢筋够不够发现问题时成本已呈指数级增长。一个典型的现象是项目前期疯狂赶功能后期拼命补安全漏洞导致工期延误甚至为了“达标”而引入不优雅、不稳定的临时方案。这种“安全后置”模式的核心问题在于它把安全视为一个独立的、可附加的模块。但实际上安全是一种属性必须内生于系统的架构和每一个设计决策中。在嵌入式领域一个在应用层看似微小的漏洞可能因为缺乏硬件隔离或安全的启动链演变成对整个设备的完全控制。2.2 “安全左移”的具体实践框架“安全左移”不是一句空话它需要具体的方法和工具落地。关键在于将安全活动嵌入到开发流程的每一个阶段需求与设计阶段这是成本最低、收益最高的介入点。威胁建模在画第一张架构图之前就组织一次威胁建模会议。使用STRIDE欺骗、篡改、否认、信息泄露、拒绝服务、权限提升等方法系统地识别系统资产如加密密钥、传感器数据、控制指令、信任边界以及可能的攻击路径。例如对于一块工业网关资产可能是PLC控制协议、设备私钥威胁可能是通过未加密的调试接口篡改固件。安全需求定义基于威胁模型导出具体的安全需求。例如“设备启动代码必须经过ECDSA签名验证”、“存储在Flash中的敏感配置数据必须使用设备唯一密钥进行加密”、“所有网络通信必须使用TLS 1.2或以上”。这些需求应像功能需求一样被写入需求文档并进行追踪。安全架构设计选择能够支撑安全需求的硬件和软件架构。例如决定使用带有硬件安全模块和TrustZone的处理器规划安全世界与非安全世界的内存分区设计安全的OTA更新流程。实现与验证阶段安全编码规范为团队制定并强制执行安全编码规范特别是针对C/C这类嵌入式常用语言。重点防范缓冲区溢出、整数溢出、格式化字符串漏洞等。使用静态代码分析工具作为代码审查的补充。依赖项安全审查任何第三方库、开源组件的引入都必须经过安全审查。记录其版本、已知漏洞通过CVE数据库查询和许可证。这直接为后续的SBOM管理打下基础。早期安全测试在单元测试和集成测试阶段就引入针对安全需求的测试用例。例如编写测试验证非法签名固件是否被拒绝启动或尝试通过非法内存访问来测试防火墙规则是否生效。注意威胁建模很容易流于形式。我的经验是找一个真实的、已发生的安全事件案例作为引子能极大提升团队的参与度和产出质量。不要试图一次覆盖所有聚焦在最核心的2-3个高危场景进行深入分析。2.3 贯穿生命周期的安全维护设备出厂只是开始而非结束。法规要求制造商在声明的生命周期内可能是5年、10年甚至更长持续维护设备安全。这意味着开发流程必须形成一个包含“更新”的闭环。你需要建立一个软件更新安全流程它与主开发流程并行。这个流程需要定义如何安全地生成更新包签名、加密如何安全地将包分发到设备设备如何验证和安装更新回滚机制、断电恢复以及如何确认更新成功。这个流程必须和初始的“安全启动”、“安全存储”等机制无缝衔接。定义清晰的设备生命周期状态至关重要。通常包括开发调试、量产部署、现场运行、静默更新、服务终止。每个状态对应不同的安全策略。例如在“开发调试”状态JTAG调试口可能是开放的而一旦进入“量产部署”状态就必须通过烧写efuse等方式永久关闭或严格限制JTAG访问。TI处理器中的“HS-FS”和“HS-SE”设备类型正是为此设计我们会在下一章详细讨论。3. 构建硬件信任根深入解析安全启动3.1 安全启动的核心价值与原理安全启动是所有后续安全机制的基石它的目标是建立一个不可篡改的硬件信任根。简单类比就像你只信任从银行金库直接运出的钞票硬件根并通过验钞机密码学验证来确认每一张流通钞票的真伪从而杜绝假币。其核心原理是密码学签名链。芯片在出厂时会在一片一次性可编程存储器中烧入一个或多个公钥的哈希值即“根公钥”。设备上电后固化在ROM中的第一段引导代码会使用这个根公钥去验证下一阶段引导加载程序的数字签名。如果验证通过说明代码完整且来自可信方才会执行它。这个引导加载程序可以继续用自身的密钥验证操作系统内核内核再验证应用从而形成一条“信任链”。它的技术价值在于保证真实性运行的代码确实来自你制造商而非攻击者。保证完整性代码在存储和加载过程中未被篡改。防止回滚通过版本号签名可以防止设备被恶意降级到有漏洞的旧版本。3.2 TI处理器安全启动的实操分解以TI的AM62x/A系列等Cortex-A处理器为例其安全启动流程高度依赖其安全控制器和可编程efuse。下面我拆解从零开始实现安全启动的五个关键步骤并附上关键决策点的思考。步骤一理解设备安全状态与模式转换TI的高安全性处理器通常有两种关键状态HS-FS现场可安全化。这是出厂和开发板默认状态。此时安全功能未激活JTAG对安全控制器以外部分开放方便你开发和调试所有功能。这是一个关键窗口期你可以尽情测试硬件和基础软件。HS-SE安全强制启用。这是量产状态。一旦通过烧写efuse将设备转为HS-SE安全启动将被强制启用JTAG可能被完全关闭设备将只运行经过签名的代码。这个转换是不可逆的。决策点你必须在开发流程中明确划分“FS阶段”和“SE阶段”。通常在工厂量产烧录时才执行从FS到SE的最终转换。之前的所有测试包括OTA更新流程测试都应在FS状态的设备或模拟环境下完成。步骤二生成和管理密钥对这是整个体系安全性的源头。你需要一对非对称密钥如RSA 2048/3072或ECC NIST P-256。生成环境绝对不要在联网的普通开发机上生成量产密钥。应使用硬件安全模块或一台完全离线的、物理隔离的机器。私钥一旦生成就永远不应以明文形式出现在HSM之外。密钥存储私钥保存在HSM或离线安全存储中。公钥则需准备用于烧录到设备efuse中。TI的方案通常要求你提供一个X.509证书其中包含公钥然后工具会计算证书的哈希值并烧录这个哈希。密钥轮换策略考虑支持双根密钥。在efuse中预烧两个根密钥哈希Key0, Key1。初始使用Key0。当需要轮换如密钥泄露时可以用Key0签名授权启用Key1的新固件。这为现场密钥更新提供了可能。步骤三构建可签名镜像你的引导加载程序需要被编译和打包成符合TI安全引导格式的镜像。这通常意味着镜像布局镜像文件需要包含证书元数据、引导加载程序代码本身、以及签名块。TI的ti-image-gen等工具能帮助生成这种格式。多阶段引导ROM Code验证并加载你的初始引导加载程序。你的引导加载程序需要继续验证下一阶段如ATF、OP-TEE、U-Boot SPL。你需要为每一阶段准备相应的签名密钥可以是同一把密钥也可以是不同的密钥形成链式信任。步骤四签名与烧录流程这是将软件与硬件绑定的核心操作。签名操作使用你的私钥在HSM内对步骤三生成的镜像进行签名。命令类似sign_ti_image --key my_private_key.pem --input tiboot3.bin --output tiboot3-signed.bin。这个过程会在镜像中添加签名信息。烧录公钥哈希使用TI的烧录工具将你的公钥证书哈希值写入目标设备的efuse特定区域。警告此操作可能不可逆地改变设备状态如从FS转为SE。务必先在测试板上验证整个流程。烧录签名镜像将签名后的镜像烧录到设备的启动介质如QSPI Flash, eMMC中。步骤五验证与测试正向测试设备上电应能正常引导。负向测试这是关键尝试烧录一个未签名的镜像或使用错误密钥签名的镜像设备必须拒绝启动并进入安全错误状态。测试JTAG访问在SE状态下是否已被正确禁用。回滚测试如果你实现了防回滚机制测试用旧版本签名镜像启动是否会被拒绝。实操心得最容易出错的环节是“镜像格式”和“efuse烧写顺序”。TI不同处理器系列AM335x, AM62x, AM64x的引导格式和工具链可能有细微差别。强烈建议在项目早期就建立一个自动化的签名和烧录脚本并记录所有工具链的版本号。另一个坑是调试一旦启用安全启动并关闭JTAG传统的调试手段几乎失效。因此必须提前规划好SE状态下的调试方法例如通过UART输出丰富的日志或利用安全控制器内预留的调试接口。3.3 超越引导信任链的延伸安全启动建立了对引导加载程序的信任。一个健壮的系统需要将这条信任链延伸到整个软件栈操作系统内核由引导加载程序验证其签名后再加载。安全世界软件如果使用TrustZone安全世界的可信应用同样需要被验证。关键应用对于汽车或工业中安全等级最高的应用可能需要对其实时进行完整性度量。这通常需要一个安全软件架构的支持如OP-TEE Linux其中U-Boot作为第一阶段验证者验证Linux内核和OP-TEE然后由OP-TEE管理安全侧应用的生命周期。4. 管理软件物料清单应对供应链安全与合规4.1 SBOM是什么为什么它现在如此重要软件物料清单顾名思义就是你产品中所有软件成分的“清单”。它详细列出了使用的所有开源和第三方软件组件、库、框架及其精确版本、许可证信息以及它们之间的依赖关系。它的重要性在当下凸显源于两个驱动力漏洞管理的迫切需要现代嵌入式系统严重依赖开源软件。当一个像Log4j这样的通用库爆出高危漏洞时你需要立刻知道我的产品用了没有用在哪个版本哪些设备受影响没有SBOM你就如同在黑暗中摸索只能进行耗时且易出错的全盘排查。法规合规的硬性要求欧盟CRA等法规明确要求产品必须提供证明其安全性的文档SBOM是其中关键一环。它提供了软件供应链的透明度是证明你已履行“尽职调查”责任的重要证据。4.2 如何为嵌入式系统生成有效的SBOM生成SBOM不是简单列个清单它需要融入构建流程。以下是两种主要方法方法一在构建时生成这是最准确、最推荐的方式。利用构建系统在编译过程中自然知晓所有依赖项的特性。包管理器集成如果你的项目使用Yocto/OpenEmbedded, Buildroot它们本身就有强大的包管理能力。例如在Yocto中bitbake命令可以生成包含所有配方、源码版本和许可证的清单。# 在Yocto构建后生成SPDX格式的SBOM bitbake image-name -c create-spdx编译脚本钩子在Makefile或CMakeLists.txt中集成SBOM生成工具。例如在编译每个库时将其名称和版本信息自动追加到一个清单文件中。SBOM格式行业标准格式如SPDX和CycloneDX是首选。它们机器可读便于自动化工具进行漏洞扫描。TI的一些SDK也开始提供实验性的SPDX生成支持。方法二对二进制/文件系统进行扫描当无法获得源码或构建系统时可以对最终生成的固件镜像或根文件系统进行扫描。工具扫描使用像syft、trivy这样的软件组成分析工具直接扫描文件系统中的二进制文件识别其中包含的已知开源组件及其版本。这对于识别从二进制分发版引入的依赖项特别有用。# 使用syft扫描一个根文件系统目录 syft dir:/path/to/rootfs -o spdx-json sbom.json局限性此方法可能无法识别深度修改的组件或版本信息不明确的二进制文件准确性低于构建时生成。嵌入式SBOM的特殊考量层级化SBOM一个设备可能包含多个逻辑部件MCU固件、Linux系统、FPGA比特流、配置数据。为每个部件生成子SBOM再组合成设备级总SBOM会更清晰。版本标识嵌入式软件常使用自定义版本号或Git提交哈希。在SBOM中除了组件版本务必记录你所用代码仓库的具体提交ID这是实现可追溯性的关键。许可证兼容性SBOM也是进行许可证合规审查的基础。确保所有组件的许可证与你产品的分发方式兼容避免法律风险。4.3 利用SBOM进行漏洞管理与合规响应生成了SBOM只是第一步更重要的是利用它来驱动安全运营。建立漏洞响应流程自动化扫描将SBOM最好是SPDX格式导入漏洞管理平台或使用trivy等CLI工具定期或持续地对所有组件进行CVE匹配扫描。风险评估不是所有CVE都需要立即处理。结合CVSS评分、你的组件在系统中的使用方式是否暴露于网络、是否处理敏感数据以及利用条件进行风险评估确定修复优先级。修复与更新对于高危漏洞需要制定修复计划是升级组件版本还是应用补丁这反过来会触发你的软件构建和更新流程。应对合规审计当监管机构或客户要求你证明产品安全性时一份详细、准确的SBOM是你“安全尽职调查”的核心证据。它展示了你对软件成分的掌控力以及当漏洞出现时你快速定位影响范围的能力。常见问题很多团队开始做SBOM后会被海量的、中低危的CVE报告淹没导致“警报疲劳”。我的建议是不要追求零CVE而要追求风险可控。建立一个清晰的策略对于开发中的产品定期扫描并修复所有中高危漏洞对于已部署的产品重点关注远程可利用、无需用户交互的高危漏洞。同时在SBOM中记录每个已知漏洞的评估状态和处置决定这本身就是一种负责任的体现。5. 实战整合从设计到部署的安全闭环5.1 一个整合的安全开发流程示例让我们将一个工业物联网网关项目作为案例串联起上述三大策略概念阶段进行威胁建模。识别出“通过未加密的OTA通道植入恶意固件”为高风险。设计阶段导出安全需求“固件更新包必须使用ECC P-256签名验证”“设备必须启用安全启动根密钥由HSM管理”。选型选择TI AM62x处理器因其具备硬件安全模块、HS-FS/HS-SE支持以及丰富的加密加速器。开发阶段安全编码使用MISRA C规范并集成静态分析工具。依赖管理所有使用的Yocto层、开源库版本均记录在manifest文件中。在每次构建时自动调用bitbake -c create-spdx生成SBOM草案。安全功能实现 a. 在HS-FS开发板上开发并测试U-Boot的安全启动插件验证签名逻辑。 b. 在隔离环境中使用HSM生成ECC密钥对。 c. 编写自动化脚本在CI/CD流水线中调用HSM对构建出的tiboot3.bin等镜像进行签名。 d. 实现一个安全的OTA客户端负责下载、验证签名、并安全地切换启动分区。测试与验证阶段功能测试验证签名正确的固件能正常启动和更新。渗透测试尝试注入非法签名包、中间人攻击OTA过程、尝试访问已关闭的JTAG接口。验证安全机制是否有效。SBOM验证对最终发布的固件镜像进行二进制扫描与构建时生成的SBOM交叉核对确保一致性。量产与部署阶段在产线使用预配置的工装将唯一的设备证书包含公钥哈希值烧录到每颗处理器的efuse中并将设备状态从HS-FS转为HS-SE。烧录已签名的量产固件。为每台设备记录其最终的SBOM和烧录的密钥标识符。运维阶段当某个第三方库爆出漏洞时利用SBOM在1小时内确定受影响的产品批次和版本。使用预留的更新密钥制作并签名修复漏洞的新固件包通过安全OTA通道推送。更新设备SBOM记录。5.2 关键决策与避坑指南密钥管理是重中之重私钥泄露意味着整个安全体系崩塌。务必使用HSM并严格遵循密钥访问的“双人原则”和操作审计。考虑使用专业的密钥管理服务。平衡安全与调试便利性在SE状态下调试极其困难。因此必须在FS阶段进行充分测试。可以设计一种“工程模式”通过特定的安全签名指令临时开启有限的调试功能但这需要非常谨慎的设计。性能考量安全启动的签名验证、运行时的加解密都会消耗CPU资源和时间。在资源受限的MCU上需要仔细评估引导时间增量。TI的加密硬件加速器可以极大缓解此问题。处理安全启动失败设备如何优雅地处理签名验证失败是永久变砖还是进入一个受限的恢复模式必须设计好这个流程避免因OTA失败导致大规模设备故障。SBOM的维护是持续过程不要把它当成一次性的交付物。每次构建、每次版本更新SBOM都应随之更新并归档。将其纳入你的产品版本管理体系中。嵌入式系统安全是一场马拉松而非冲刺。从“安全左移”的设计思维到“安全启动”的硬件基石再到“SBOM”的供应链管理工具这三者构成了一个从内到外、从开发到运维的立体防御体系。开始实践时可能会觉得繁琐但一旦流程跑通它就会成为你开发过程中自然而然的肌肉记忆。最危险的往往不是复杂的攻击而是我们对自己系统中潜藏风险的未知。通过实施这些策略你至少能将“未知”变为“已知”将“失控”变为“可控”从而在日益严峻的网络安全环境和法规要求下构建出真正值得信赖的嵌入式产品。