ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

S32K3xx HSE安全启动实战:SMR分区、密钥烧录与多核协同

S32K3xx HSE安全启动实战:SMR分区、密钥烧录与多核协同 1. 从一次量产固件被篡改说起HSE安全启动到底在防什么前两年帮一家做车身域控制器的团队排查过一个挺典型的问题他们基于S32K344做的BCM样机在实验室跑了大半年都正常结果小批量装车之后有台设备在售后被刷入了非授权固件功能逻辑被改得面目全非。事后复盘发现问题不在应用层而是整条启动链路上没有任何一道校验关卡——Bootloader拿到什么就跳什么HSEHardware Security Engine虽然硬件上摆在那里但SMRSecure Memory Region一个都没配等于把保险柜买回来当储物箱用。这件事之后我把S32K3xx的HSE安全启动从头到尾捋了一遍从SMR分区规划、密钥烧录、SBAFSecure Boot Assist Flash配置一直到多核场景下各核的启动顺序协同。这篇就把这套流程完整拆开讲重点放在SMR怎么划、HSE固件怎么装、多核怎么配合这三件事上。适合正在用S32K3系列做量产项目、需要过信息安全要求、或者单纯想把HSE用起来的嵌入式工程师。如果你只是跑个点灯Demo这篇可能有点重但只要涉及OTA、Bootloader、功能安全HSE这套东西迟早绕不过去。先说清楚一个前提S32K3xx的HSE不是软件库它是一块独立的硬件安全子系统内部有自己的Cortex-M0核、专用RAM、加密加速器和密钥存储区。主核Cortex-M7想让它干活只能通过MUMessaging Unit发消息走的是IPC那套机制。理解这一点很关键后面所有配置逻辑都建立在这个主从消息的模型上。2. SMR分区规划安全启动的地基怎么打2.1 SMR的本质是一组带权限的内存窗口SMR全称Secure Memory Region直译就是安全内存区域。很多人第一次看手册会以为它是个加密开关其实不是。SMR干的事情是把Flash和RAM切成若干个窗口每个窗口声明谁可以读、谁可以写、谁可以执行、要不要做完整性校验。HSE在启动阶段会逐个检查这些窗口任何一条规则不满足启动就停在SBAF阶段主核根本拿不到控制权。S32K3xx的SMR数量是有限的具体几个取决于芯片型号和HSE固件版本常见配置下大概能划8到16个区间。这个数量看着不少但真到项目里你会发现根本不够用——Bootloader一个、应用一个、标定数据一个、密钥区一个、配置区一个再留几个给OTA的A/B分区很快就见底了。所以SMR规划的核心不是能划几个而是哪些必须划、哪些可以合并。我的经验是分三层来考虑第一层是启动必需区SBAF本身、HSE固件区、IVTImage Vector Table这些是HSE自己管的通常不需要你手动划SMR但你要知道它们占了哪些地址别去碰。第二层是可信执行区Bootloader和它的配置数据。这块必须配SMR而且校验方式要选最严的——通常用CMAC或者ECDSA签名校验不能只做CRC。第三层是应用与数据区Application、标定参数、故障码存储。应用区一般也要签名校验数据区可以放宽到只做写保护。2.2 地址对齐和粒度踩过的最多的坑SMR的地址必须按粒度对齐S32K3xx上这个粒度通常是1KB或者4KB具体看HSE配置。我见过有同事把SMR起始地址写成0x00401200这种非对齐值结果HSE直接返回配置错误而且错误码很含糊查半天查不出来。提示规划SMR之前先把链接脚本linker script里的段地址全部列出来确认每个段的起止地址都落在对齐边界上。如果某个段跨了两个SMR窗口要么调整段大小要么把两个窗口合并成一个。举个实际例子一个典型的S32K344项目内存布局大概是这样区域起始地址大小SMR策略SBAF0x0040000032KBHSE自管勿动Bootloader0x0040800064KB签名校验只读可执行Bootloader配置0x004180004KBCMAC校验只读Application0x00420000512KB签名校验只读可执行标定数据0x004A000032KB只读允许HSE更新密钥存储0x004B00008KB仅HSE可访问这张表不是拍脑袋来的每一行都对应一个SMR条目。注意密钥存储区那一行它的访问权限要设成仅HSE主核连读都不允许——这是防止密钥被dump出来的关键。有些团队图省事把密钥和应用放一个区等于把钥匙和锁放一个抽屉里安全启动就白做了。2.3 校验方式的选择CRC、CMAC还是签名SMR支持几种完整性校验方式从弱到强依次是无校验、CRC、CMAC、ECDSA/ RSA签名。选哪种不是越强越好要看启动时间预算。CRC最快但只能防意外损坏防不了恶意篡改——攻击者改了数据重算一遍CRC就行。CMAC用对称密钥速度快能防篡改但密钥在设备里理论上可以被提取虽然S32K3xx的密钥区有保护。ECDSA签名用非对称密钥私钥在服务器上设备里只有公钥安全性最高但验签耗时明显更长。实测数据供参考在S32K344上64KB的Bootloader做CMAC校验大概几毫秒做ECDSA P-256验签要几十毫秒。如果启动时间要求严格比如CAN唤醒后100ms内要能响应Bootloader用CMAC、Application用签名是比较务实的折中。当然如果项目对安全等级要求高全签名也不是不行就是得接受启动慢一点。3. HSE固件安装与密钥烧录一次性但不可逆的操作3.1 HSE固件不是出厂就有的这一点新手最容易误解。S32K3xx出厂时HSE区域是空的需要你通过SBAF把HSE固件一个加密的二进制文件NXP会随芯片提供或者从官网下载对应版本装进去。这个过程叫HSE Firmware Installation只能做一次做完之后HSE才真正活过来。安装流程大致是主核通过MU向HSE发送安装命令把固件数据分块传过去HSE自己解密、校验、写入内部Flash。整个过程不可中断中途断电芯片可能就废了。所以第一次装HSE固件务必保证供电稳定最好用稳压电源而不是USB供电。注意HSE固件版本要和芯片型号、你用的RTDReal-Time Drivers版本匹配。我遇到过用错版本导致HSE起不来、MU通信超时的情况排查了很久才发现是固件版本对不上。装之前先确认三件事芯片具体型号S32K344还是S32K358、HSE固件版本号、RTD版本。3.2 密钥烧录的层级关系HSE的密钥体系是分层的理解这个层级比记命令重要得多最底层是设备密钥Device Key出厂固化或者首次配置时生成不可更改。往上是密钥加密密钥KEK用来加密其他密钥。再往上是各种功能密钥签名验证公钥、CMAC密钥、AES密钥等。烧录密钥时敏感密钥比如CMAC密钥要用KEK加密后再传不能明文传。HSE提供了一套密钥目录Key Catalog机制每个密钥有个ID应用里通过ID引用不直接接触密钥内容。这个设计很聪明——即使应用被反编译也拿不到密钥本身。实际操作中密钥烧录通常通过HSE的密钥管理服务Key Management Services来做流程是先创建密钥目录再导入密钥最后激活。每一步都有对应的MU消息格式NXP的RTD里封装了API但底层消息结构建议还是了解一下出问题时能自己抓MU日志分析。3.3 一个容易忽略的点密钥的持久化密钥烧进去之后存在哪S32K3xx的HSE有专门的密钥存储区Key Store掉电不丢。但要注意某些密钥比如会话密钥是易失的重启就没了需要重新协商。做安全启动时用到的验证公钥属于持久密钥烧一次就行。还有个坑密钥存储区的擦写次数是有限的。如果你在调试阶段反复烧密钥可能把某个扇区写坏。建议调试时用HSE的模拟模式或者先在RAM里验证逻辑确认没问题再真正烧录。4. 多核协同谁先启动、谁等谁4.1 S32K3xx的多核启动拓扑S32K3系列里S32K344是单核M7S32K358是双核M7加一个M0HSE自己的核不算。多核场景下安全启动的复杂度直接翻倍因为你要回答一个问题HSE校验完之前从核能不能启动答案是不能。HSE的校验是全局的它检查的是整个启动镜像包括从核的代码。所以正确的顺序是主核先启动跑SBAFHSE校验通过后主核再释放从核。如果从核抢跑HSE会认为启动流程异常可能直接锁死。4.2 核间同步的两种做法实际项目里主核释放从核有两种常见做法第一种是硬件信号量。S32K3xx有SEMA42模块主核校验通过后置一个信号量从核在启动早期轮询这个信号量拿到才继续往下跑。这种做法简单可靠但要注意信号量的初始状态和超时处理——如果主核校验失败从核不能无限等下去要有超时复位机制。第二种是MU消息。主核通过MU给从核发一条启动许可消息从核在MU中断里收到才继续。这种做法更灵活可以传递参数但依赖MU驱动先初始化好。我一般推荐第一种因为安全启动阶段MU可能还没完全配好用信号量更稳妥。等系统跑起来之后核间通信再切到MU。4.3 从核代码的SMR配置从核的代码通常和主核放在同一个镜像里但如果你把从核代码单独放一个区就要单独配SMR。这里有个细节从核的SMR校验方式要和主核一致否则HSE校验时会出现部分通过部分失败的诡异现象。另外从核的栈和堆如果放在共享RAM里那块RAM也要配SMR至少要做写保护防止从核跑飞了踩到主核的数据。5. 调试阶段最折磨人的几个问题5.1 HSE起不来MU通信超时这是最高频的问题。现象是主核发MU消息后一直等不到响应超时返回。原因通常有三个HSE固件没装、固件版本不匹配、MU时钟没使能。排查顺序建议从时钟开始——MU挂在哪个时钟域、有没有使能这个用调试器看寄存器最快。时钟没问题再确认HSE固件状态HSE有个状态寄存器能读出当前是未安装已安装未启动还是运行中。5.2 SMR配置报错但错误码看不懂HSE返回的错误码是分层的高字节是模块低字节是具体错误。手册里有完整列表但实际排查时更有效的方法是把SMR配置逐条简化先配一个最简单的只读区跑通了再往上加。我遇到过地址对齐问题、权限位冲突、SMR数量超限都是靠这种二分法定位的。5.3 签名校验通过但启动还是失败这种情况往往是校验范围不对。签名是对整个镜像算的如果SMR划定的范围和签名覆盖的范围不一致HSE会认为镜像被篡改。解决办法是确保签名工具和SMR配置用的是同一份地址描述文件别一个用链接脚本、一个用手写的地址表。5.4 多核场景下从核卡死从核卡死最常见的原因是信号量没等到或者等到了错误的信号量。调试时可以在从核启动早期加一个GPIO翻转用示波器看从核到底跑到哪一步了。另外确认从核的向量表地址对不对——多核系统里每个核有自己的向量表配错了从核会跳到错误的中断处理里。6. 一套可复用的配置流程把上面这些串起来一个完整的HSE安全启动配置流程大概是这样确认硬件和软件版本芯片型号、HSE固件版本、RTD版本三者匹配。安装HSE固件稳定供电一次性完成不可中断。规划内存布局列出所有段地址确认对齐划分SMR。配置SMR从简到繁逐条验证注意权限和校验方式。烧录密钥用KEK加密敏感密钥通过密钥目录管理。配置SBAF设置启动模式、校验策略、失败处理复位还是锁定。多核协同主核先跑校验通过后用信号量释放从核。签名与验证用签名工具对镜像签名确保签名范围和SMR一致。调试与验证故意篡改一个字节确认HSE能检测到并阻止启动。这套流程我在两个量产项目上跑过第二个项目基本没踩新坑说明流程本身是收敛的。真正花时间的不是配置本身而是前期把内存布局和密钥体系想清楚。7. 几个只有实际做过才知道的细节最后分享几个文档里不太会写、但实际会遇到的点。第一HSE固件安装后建议先做一次完整的自检。HSE提供自检服务能验证内部加密引擎、密钥存储、随机数发生器是否正常。这一步在量产前做一次能提前发现硬件问题。第二SMR的配置是可以增量更新的但更新SMR本身也需要授权。如果你在量产之后想改SMR需要重新签名配置数据通过安全通道下发。所以前期规划尽量留余量别把SMR数量用满。第三调试口在安全启动启用后会被限制。这是设计使然不是bug。量产版本要关闭调试口调试版本要保留这中间需要一个开发模式和量产模式的切换机制通常通过生命周期Life Cycle状态来控制。第四启动时间要实测。签名校验、SMR检查、密钥加载都耗时叠加起来可能超出预期。建议在项目早期就用示波器测一下从上电到应用跑起来的总时间别等到后期才发现启动太慢。第五多核的启动顺序在复位类型不同时可能不一样。冷启动和看门狗复位、软件复位的启动路径可能有差异测试时要把各种复位场景都覆盖到。这套东西说到底HSE安全启动不是一个配一下就行的功能它是一套需要从内存规划阶段就介入的系统工程。SMR划得好不好、密钥体系设计得合不合理直接决定了后面调试顺不顺、量产稳不稳。我个人的体会是前期多花两天把地址表和密钥层级画清楚后面能省两周的调试时间。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进