深入解析CC35xx HSM寄存器与安全启动:从硬件隔离到信任链构建 1. 项目概述与HSM核心价值在嵌入式系统尤其是物联网设备的设计中安全不再是“锦上添花”的可选项而是关乎产品生命线和用户信任的基石。想象一下一个智能门锁的固件被恶意替换或者一个工业传感器的通信密钥被窃取其后果不堪设想。硬件安全模块HSM正是为解决这类问题而生的“安全堡垒”。它不是一段运行在主处理器上的普通代码而是一个物理上隔离的、具备独立执行和存储能力的硬件子系统专门负责执行最敏感的操作如密钥管理、加密解密和可信启动验证。以德州仪器TI的CC35xx系列无线MCU为例其内置的HSM模块就是我们今天要深入剖析的核心。这个模块的设计精妙之处在于它将安全功能从主应用处理器Cortex-M33中剥离出来交由一个独立的协处理器Cortex-M3来执行。这种硬件隔离架构使得即使主处理器被攻破攻击者也无法直接触及HSM内部保护的密钥和加密引擎从而在硬件层面构建了第一道防线。对于开发者而言理解并正确配置HSM的寄存器是激活这套安全机制、实现从芯片上电第一刻就开始的“信任链”传递的关键。这不仅仅是阅读数据手册更是掌握如何与这个“安全协警”对话指挥它何时“上岗”使能时钟、如何“执勤”执行加密、以及在异常时如何“干预”中止操作。接下来我们将从最基础的寄存器操作入手逐步揭开CC35xx安全启动与运行的神秘面纱。2. HSM寄存器详解从非安全到安全域的控制逻辑HSM的寄存器空间被清晰地划分为非安全HSM_NON_SEC和安全HSM_SEC两个域。这种划分并非随意而是基于ARM TrustZone或类似安全扩展架构的思想。非安全域通常由主应用处理器或调试接口访问提供了一些基础的状态监控和控制功能而更深层次、更敏感的控制则被放在安全域只有处于安全状态或通过特定安全服务才能访问。这种设计确保了关键的安全配置不会被非特权代码意外或恶意修改。2.1 HSM_NON_SEC寄存器组状态监控与基础控制非安全寄存器组是主处理器与HSM交互的第一个窗口。它允许主处理器在不进入安全世界的情况下了解HSM的工作状态并进行一些必要的控制。我们逐一解析几个关键寄存器。2.1.1 CLK_MEM_CTRL模块时钟的门卫时钟是数字电路的脉搏对于HSM这样一个独立模块其时钟的开启与关闭需要精细控制以达到功耗与性能的平衡。CLK_MEM_CTRL寄存器偏移地址0h就是这个控制中心。这个寄存器包含多组控制位其设计体现了层次化的时钟管理思想MEM_CLK_GO/MEM_CLK_GO_M3(位0和位3)这是模块主时钟的总开关。MEM_CLK_GO位通常由系统级电源管理单元控制而MEM_CLK_GO_M3则专门留给HSM内部的M3协处理器控制。这种双控机制提供了灵活性例如系统进入深度睡眠时可通过MEM_CLK_GO关闭时钟以省电而M3在执行安全任务时可通过MEM_CLK_GO_M3确保自身时钟稳定。MEM_SLV_CLK_GO/MEM_SLV_CLK_GO_M3(位1和位4)控制主机接口Host Interface的时钟。主机接口是HSM与外部如主处理器DMA进行数据交换的通道。在不需要数据传输时关闭其时钟可以有效降低动态功耗。MEM_CTR_CLK_GO/MEM_CTR_CLK_GO_M3(位2和位5)控制计数器Counter模块的时钟。该计数器可能用于真随机数生成器TRNG等需要独立时钟源的子模块。实操要点与避坑指南使能顺序在初始化HSM时建议先使能模块主时钟MEM_CLK_GO等待稳定后再根据需要使能主机接口或计数器时钟。直接同时使能所有时钟在理论上可行但分步操作更符合稳健性设计原则。状态查询在尝试关闭某个时钟域前务必先检查对应的*_CLK_BUSY状态位如CLK_BUSY、SLV_CLK_BUSY、CTR_CLK_BUSY。只有当BUSY位为0时才表示该模块空闲可以安全关闭时钟。强行关闭一个繁忙模块的时钟可能导致数据丢失或状态机卡死。M3控制位优先级注意*_GO_M3位和*_GO位最终是“或”逻辑关系。只要其中任何一个为1对应时钟域就会被使能。在调试时如果发现时钟无法关闭需要检查这两组位是否都被正确清零。2.1.2 PKA_ABORT_CTRL紧急制动按钮公钥加速器PKA是HSM中执行非对称加密如ECC、RSA运算的核心硬件。这些运算可能非常耗时。PKA_ABORT_CTRL寄存器偏移地址4h提供了一个紧急中止机制。MEM_PKA_ABORT_NS(位0)向此位写1即可请求中止正在进行的PKA操作。这是一个非常直接的控制位。为什么需要中止机制超时处理如果PKA运算因某种原因如错误的输入参数陷入死循环或远超预期时间主处理器可以通过此寄存器强制中止防止系统被挂起。任务优先级变更在高安全性的实时系统中可能发生更高优先级的加密任务需要立即执行。此时可以中止当前的低优先级PKA任务当然需要妥善保存上下文或明确该任务可被丢弃。安全擦除在即将进入安全睡眠或复位前中止所有未完成的加密操作确保没有残留的中间状态是良好的安全实践。注意事项非瞬时性写入中止请求后PKA操作不会立即停止。软件需要轮询PKA的状态寄存器通常在其他地方确认操作已真正进入中止或空闲状态后才能进行下一步操作如复位PKA模块或开始新任务。数据一致性被中止的运算其输出结果是无效的。调用者必须能够处理这种“运算被中断”的异常情况并可能需要进行清理或重试。2.1.3 HSM_STA_REGHSM的健康状态仪表盘HSM_STA_REG寄存器偏移地址8h是一个只读寄存器提供了HSM核心文中提到的EIP130可能是一个安全IP核的代号的实时状态信息。FIPS_MODE/NON_FIPS_MODE(位0和位1)这两个位指示HSM当前运行在哪种模式下。FIPSFederal Information Processing Standards模式通常意味着模块按照更严格、经过认证的算法和流程运行可能禁用了一些非标准的或强度较低的算法。这对于需要满足特定行业合规性如金融、政府的应用至关重要。这两个位是互斥的同一时间只有一个为1。FATAL_ERROR(位2)这是一个需要高度警惕的标志位。当它被置1时表明HSM内部检测到了不可恢复的致命错误例如固件ROM的CRC校验失败或启动自检Selftest失败。一旦发生致命错误HSM通常会停止所有安全操作。此时系统软件应触发安全警报并将设备置于一个安全的故障状态可能需要整个芯片的硬复位才能恢复。POWER_MODE(位3)指示HSM的电源模式。1表示睡眠模式0表示活跃模式。在管理设备功耗时查询此位可以确认HSM是否已成功进入低功耗状态。关键点数据手册特别强调访问此寄存器必须使用最小32位的写宽度。这意味着即使你只想读取某个位也必须发起一个32位的读操作。使用8位或16位访问可能导致总线错误或读取到错误数据。在C代码中应确保将指向该寄存器的指针定义为volatile uint32_t*类型并通过该指针进行访问2.1.4 RAM_CLR_STA安全擦除的完成指示灯安全设备在复位释放时一个关键操作是自动清除存储在易失性存储器如RAM和一次性可编程存储器OTP中的敏感资产如临时密钥。RAM_CLR_STA寄存器偏移地址Ch就是用来报告这个自动清除过程的状态。OTP_CLR_DONE(位0)置1表示OTP区域的自动清除已完成。DATARAM_CLR_DONE(位1)置1表示数据RAM的自动清除已完成。这个状态为什么重要启动安全性主处理器或安全启动代码在HSM复位后需要等待这两个标志位都变为1才能确认HSM内部的敏感残留数据已被清理可以安全地加载新的固件或密钥。如果未完成就进行交互可能存在数据泄露的风险。故障诊断如果设备复位后HSM功能异常检查这两个标志位可以判断是否在最初的清理阶段就发生了问题。同样访问此寄存器也必须使用32位宽度。2.2 HSM_SEC寄存器组安全域内的深度控制安全寄存器只能由处于安全状态的代码如运行在安全世界下的安全固件访问它们提供了对HSM更底层、更关键的控制能力。2.2.1 CLKCTL安全侧的时钟精细管理CLKCTL寄存器偏移地址0h的功能与CLK_MEM_CTRL类似但位于安全域。这意味着对HSM时钟的最终控制权掌握在安全代码手中。CLKGO,HIFCLKGO,CNTCLKGO分别对应模块主时钟、主机接口时钟和计数器时钟的使能位功能同非安全侧。CLKDISREQ(位3)这是一个重要的安全特性。向此位写1可以请求禁用所有时钟源。这通常用于在即将进入某种深度安全睡眠状态或确认HSM被彻底攻破需要完全关闭时由安全固件发起。与非安全侧的控制位不同这是一个更高级别的、可能不可逆的关闭请求。CLKBUSY,HIFCLKBUSY,CTLCLKBUSY对应的忙状态指示位。安全设计考量安全域的存在使得非安全世界的软件甚至是恶意软件无法通过胡乱操作时钟控制位来导致HSM宕机或产生不可预测的行为从而保证了安全核心的稳定性。2.2.2 SRSTCTL软件复位与状态机SRSTCTL寄存器偏移地址4h提供了对HSM的软件复位控制其状态机设计值得仔细品味。ABORTREQ(位0)软件通过写1来请求发起一次软复位Abort Request。这是一个“写1清零”或“自动清零”的位意味着写操作后硬件会自动将其清0或者软件需要写0来清除请求。ABORTACK(位1)只读位。当HSM内部的EIP可能指加密引擎确认收到了复位请求并开始执行复位操作时此位会被硬件置1。FRCACK(位2)写1可以强制确认复位而无需等待EIP的ABORTACK。这用于处理EIP无响应等异常情况属于强制干预手段。STA(位3)只读位。当软复位真正被施加到模块时此位置1。STATE(位[6:4])一个3位的状态字段清晰地展示了软复位流程的状态机0h: 软复位未请求。1h: 软复位已请求ABORTREQ已写。2h: 软复位已得到确认ABORTACK置起。3h: 软复位可以被断言可能意味着所有前置条件已满足。4h: 软复位已设置STA置起复位生效。实操流程一个标准的软复位操作应该是1) 写ABORTREQ1发起请求2) 轮询ABORTACK或等待中断直到确认为13) 观察STATE状态变迁和STA位确认复位生效。使用FRCACK是特殊情况下的备选方案。2.2.3 PKACTL安全侧的中止与屏蔽PKACTL寄存器偏移地址8h是安全域内对PKA操作的中止控制。ABORT(位0)写1以中止PKA操作功能类似非安全侧的MEM_PKA_ABORT_NS。NSMASKREQ(位1)这是一个关键的安全策略控制位。将其置1可以屏蔽来自非安全控制器Non-Secure Controller的PKA中止请求。也就是说当此位置位后非安全世界写PKA_ABORT_CTRL寄存器将失效。这可以防止非安全世界的恶意代码或故障代码干扰安全世界正在执行的关键加密操作。2.2.4 SLPCTL睡眠模式控制SLPCTL寄存器偏移地址18h控制HSM的睡眠模式。OVRVAL(位0)固件FW可以写入的覆盖值。例如在冷启动后安全固件可以将其设为1来手动控制power_mode_in信号。SRCVAL(位1)电源模式输入源选择。0表示power_mode_in来自逻辑可能是硬件自动管理1表示来自mem_slp_ovr_val可能是内存中的某个覆盖值。这个位允许安全固件选择睡眠控制的信号源。应用场景在实现高级电源管理策略时安全固件可以根据系统整体状态通过配置这两个位来决定HSM是跟随系统进入睡眠还是保持唤醒以处理可能的安全任务如安全网络心跳。3. CC35xx安全启动流程深度解析理解了HSM的寄存器是“术”而理解安全启动流程则是“道”。CC35xx的安全启动是一个精心设计的、多阶段的“信任链”传递过程确保设备从芯片出厂到最终用户手中运行的代码始终是可信的。3.1 信任链的基石两级引导加载程序CC35xx的启动流程核心是两级引导加载程序BootloaderBL1第一阶段引导这是固化在芯片ROM中的代码由TI编写且不可更改。它的唯一使命就是验证并加载BL2。它使用TI内置的不可变公钥来验证BL2的数字签名。ROM代码是信任的根源。BL2第二阶段引导这是一个可更新的引导程序通常存储在外部Flash中。它由TI签发但可以被更新修复漏洞、增加功能。BL2被BL1验证后就继承了信任。它的核心职责是验证并加载最终的供应商应用镜像BL3.x。这种“ROM验证可更新引导程序可更新引导程序验证用户应用”的链条就是“信任链”。每一环都验证下一环的完整性和真实性将信任从硬件根ROM一直传递到最终的应用软件。3.2 五大启动流程详解数据手册中详细描述了五种启动流程对应设备生命周期的不同阶段。3.2.1 应用执行启动流程默认流程这是设备出厂后终端用户正常上电所经历的流程目标是运行一个经过认证的供应商应用。上电复位芯片从ROMBL1开始执行。BL1运行BL1从外部Flash或调试接口加载BL2镜像并使用TI的根公钥验证其签名。验证通过后将控制权交给BL2并在隔离的M3协处理器上运行。BL2运行在M3上验证供应商镜像BL2读取外部Flash中的供应商镜像BL3.x该镜像由供应商私钥签名。BL2使用设备OTP中预先烧录的供应商公钥哈希ROT来验证此签名。强制执行系统配置BL2解析镜像中携带的、经过签名的初始系统配置如时钟、电源、安全策略并予以强制执行。这确保了设备在应用启动前就处于一个已知的安全状态。处理调试请求如果通过调试接口收到了一个经过签名的调试请求BL2也会验证它并在验证通过后按请求开放调试接口。BL3.x运行在M33上验证通过后BL2将控制权跳转到已验证的供应商镜像入口点该镜像在M33主处理器上执行。至此一个可信的应用环境建立完成。关键点整个验证过程BL1-BL2-BL3.x中涉及密码学运算如哈希、签名验证的核心部分极有可能就是由我们前面分析的HSM模块来完成的。BL2运行在隔离的M3上也增强了其自身的安全性。3.2.2 设备激活流程一次性这是设备从TI转移到供应商手中的“所有权交接”仪式。在此流程之前设备是“TI锁定”状态无法编程供应商代码。触发通过调试接口发起一个特殊的复位。BL1 BL2加载BL1从调试接口加载并验证一个特殊的BL2用于激活。所有权转移BL2检查设备未激活然后验证通过调试接口发送的、由供应商提供的“激活指令”包。验证通过后BL2将指令包中包含的供应商根公钥的哈希值ROT烧录到芯片的OTP熔丝中。这是一个一次性、不可逆的操作。完成烧录成功后设备就与该供应商的公钥绑定。从此只有用对应私钥签名的镜像才能在该设备上通过BL2的验证。3.2.3 初始编程流程对于已激活的空白设备或需要重新初始化的设备此流程用于首次将完整的镜像集BL2、无线固件、供应商应用写入外部Flash。触发通过调试接口发起特殊复位。BL1 BL2加载同上。请求验证BL2识别到这是一个已激活设备发来的“签名编程请求”。它使用OTP中存储的供应商ROT哈希来验证请求包的签名。擦写Flash验证通过后BL2根据请求中的指令先配置外部Flash然后通过调试接口接收来自主机的各个镜像TI签名的BL2、TI签名的无线连接固件、供应商签名的应用镜像并将其写入Flash的指定位置。报告结果编程完成后BL2通过调试接口报告成功或失败。3.2.4 重新编程流程这是开发阶段最常用的流程用于更新已部署设备上的供应商应用镜像。触发与验证与初始编程流程类似通过调试接口触发BL2验证签名编程请求。更新镜像验证通过后BL2接收新的、已签名的供应商镜像并将其写入Flash覆盖旧版本。注意此流程通常只更新供应商应用镜像TI的BL2和无线固件一般不变。版本回滚保护MCUboot通常支持版本号检查防止被旧版本可能存在漏洞的镜像替换新版本这是安全启动的一个重要特性。3.2.5 无线连接测试工具流程此流程跳过了所有供应商相关的部分直接由BL1从调试接口加载并验证一个由TI签名的专用无线测试固件到M3协处理器上运行用于生产线或研发阶段的射频性能测试。3.3 信任链的全景图与安全启示纵观整个流程信任的传递清晰可见TI的不可变信任根ROM BL1验证 -TI的可更新BL2。TI的BL2使用 -供应商在OTP中的ROT公钥哈希验证 -供应商的镜像BL3.x。可选TI的BL2使用 -供应商的调试ROT验证 -来自调试接口的签名请求。给开发者的核心启示私钥安全是命脉供应商的签名私钥必须得到最高级别的保护。一旦泄露攻击者就可以为任意恶意固件签名从而攻破整个信任链。激活是关键一步生产线上必须安全地完成设备激活将正确的供应商ROT烧录进OTP。这是一个不可逆的单向过程。调试接口的双刃剑调试接口是强大的开发工具也是潜在的攻击入口。通过签名验证来有条件地开放调试权限是CC35xx提供的一项重要安全特性。HSM是幕后功臣上述所有签名验证、哈希计算、乃至OTP的读写保护其底层硬件执行者很可能就是HSM模块。正确配置HSM寄存器是这些高级安全流程能够可靠运行的基础。4. 工程实践HSM初始化与安全启动配置示例理论最终要服务于实践。下面我们以一个典型的CC35xx安全应用启动场景为例勾勒出HSM初始化和参与安全启动的关键代码逻辑框架。请注意以下代码为概念性伪代码具体寄存器地址和位定义需参考最新的设备数据手册。4.1 HSM基础初始化流程在安全启动的BL2阶段或安全应用早期需要对HSM进行初始化。// 假设寄存器基址定义 #define HSM_NON_SEC_BASE 0x40080000 #define HSM_SEC_BASE 0x50080000 typedef volatile struct { uint32_t CLK_MEM_CTRL; // 偏移 0x0 uint32_t PKA_ABORT_CTRL; // 偏移 0x4 uint32_t HSM_STA_REG; // 偏移 0x8 uint32_t RAM_CLR_STA; // 偏移 0xC // ... 其他寄存器 } HSM_NonSec_Regs; typedef volatile struct { uint32_t CLKCTL; // 偏移 0x0 uint32_t SRSTCTL; // 偏移 0x4 uint32_t PKACTL; // 偏移 0x8 uint32_t RESERVED; // 偏移 0xC uint32_t SLPCTL; // 偏移 0x18 // ... 其他寄存器 } HSM_Sec_Regs; HSM_NonSec_Regs* pHSM_NonSec (HSM_NonSec_Regs*)HSM_NON_SEC_BASE; HSM_Sec_Regs* pHSM_Sec (HSM_Sec_Regs*)HSM_SEC_BASE; // 注意此地址需在安全态下访问 void hsm_init(void) { // 1. 等待HSM自检及内存清除完成 (通过非安全寄存器查询) // 必须使用32位访问 while (((pHSM_NonSec-RAM_CLR_STA 0x3) ! 0x3)) { // OTP_CLR_DONE 和 DATARAM_CLR_DONE 都应为1 // 实际可能需要超时处理 } // 2. 检查HSM状态确认无致命错误 uint32_t status pHSM_NonSec-HSM_STA_REG; // 32位读取 if (status (1 2)) { // 检查FATAL_ERROR位 // 处理致命错误可能需要进行系统级复位或报警 handle_fatal_error(); return; } // 3. 使能HSM基础时钟 (通过非安全或安全寄存器此处以非安全为例) // 先确保模块不忙 while (pHSM_NonSec-CLK_MEM_CTRL (1 6)) { // 检查CLK_BUSY // 等待 } // 使能模块主时钟 pHSM_NonSec-CLK_MEM_CTRL | (1 0); // 置位MEM_CLK_GO // 可选使能主机接口时钟如果需要与HSM进行数据交换 // pHSM_NonSec-CLK_MEM_CTRL | (1 1); // 置位MEM_SLV_CLK_GO // 4. (在安全环境中) 可进行更深入的配置例如屏蔽非安全侧的中断请求 // secure_configure_hsm(); // 此函数需在安全态下执行 } void secure_configure_hsm(void) { // 此函数假设在安全世界如TrustZone安全区调用 // 5. 屏蔽非安全世界对PKA的中止请求确保安全运算不被干扰 pHSM_Sec-PKACTL | (1 1); // 置位NSMASKREQ // 6. 根据需要配置睡眠控制等 // pHSM_Sec-SLPCTL ...; }4.2 安全启动过程中HSM的潜在角色在BL2验证供应商镜像签名时具体的密码学操作如ECC签名验证很可能由HSM内的PKA公钥加速器完成。流程可能如下int verify_vendor_image_signature(const uint8_t* image, uint32_t image_len, const uint8_t* signature) { // 1. 准备验证数据通常包括镜像的哈希值、签名、公钥等 prepare_verification_data(image, image_len, signature); // 2. 配置HSM/PKA模块进行运算此处为概念性步骤 // - 将公钥、签名、哈希值等数据通过主机接口HIF或特定内存区域送入HSM。 // - 配置PKA相关寄存器可能不在HSM_NON_SEC/SEC寄存器组而在PKA专属寄存器中启动ECC验证命令。 // 3. 等待运算完成或处理中止 // 轮询状态寄存器或等待HSM中断。 // 在等待期间如果需要超时处理可能会用到PKA_ABORT_CTRL寄存器。 // uint32_t timeout MAX_TIMEOUT; // while (!is_pka_operation_done() timeout--) { // delay(); // } // if (timeout 0) { // pHSM_NonSec-PKA_ABORT_CTRL 0x1; // 请求中止 // return VERIFICATION_TIMEOUT; // } // 4. 获取验证结果 // 从HSM指定位置读取验证结果成功/失败。 // 5. 根据结果决定启动流程 // if (verification_successful) { // return JUMP_TO_IMAGE; // } else { // return HALT_OR_ENTER_RECOVERY; // } return 0; }4.3 常见问题与调试技巧HSM初始化失败卡在等待RAM_CLR_STA可能原因芯片上电不稳定或HSM硬件故障。排查检查电源和复位信号是否满足时序要求。测量HSM相关电源引脚电压。如果持续失败考虑芯片硬件问题。应急处理在开发初期可以尝试增加一个较长的延时后再检查但量产代码必须确保此状态完成。PKA运算超时中止无效可能原因HSM时钟未正确使能PKA模块处于异常锁定状态安全侧NSMASKREQ被置位导致非安全中止请求被屏蔽。排查确认CLK_MEM_CTRL或CLKCTL中相关时钟使能位已设置且*_CLK_BUSY状态正确。检查HSM_STA_REG是否有致命错误。如果是在非安全世界调用中止确认安全世界的PKACTL.NSMASKREQ位是否为0。终极手段尝试通过安全软件触发对HSM的软复位操作SRSTCTL寄存器但要注意这会重置HSM状态可能影响其他正在进行的任务。安全启动时镜像验证失败可能原因镜像签名错误私钥不匹配或签名过程出错。设备OTP中的ROT哈希值与镜像公钥哈希不匹配激活过程出错或用了错误的设备。镜像本身损坏Flash读写错误。HSM在计算哈希或验证签名时发生内部错误。排查在开发主机上用相同的工具和密钥对镜像重新签名并对比哈希。确认目标设备的激活记录核对烧录的ROT哈希值。使用调试器读取Flash中镜像的特定区域如签名头与原始文件对比。检查HSM_STA_REG寄存器看是否有FATAL_ERROR或模式异常。无法进入调试模式可能原因设备未激活或激活后未提供有效的签名调试请求。排查确认设备已执行激活流程。通过调试接口发送的调试请求包必须使用与设备ROT对应的私钥进行签名。检查BL2的调试认证流程是否启用并配置正确。最后一点个人体会处理HSM和安全启动最重要的心态是“敬畏”和“细致”。任何一个寄存器位的误写、一个流程顺序的错乱都可能把设备变成“砖头”。务必在开发板上充分测试每一行与HSM交互的代码并利用好芯片提供的状态寄存器进行充分的错误检查和超时处理。安全无小事代码的每一处都必须经得起推敲。

本周精选

本月热点