搞车规 MCU 信息安全的人,这两年应该都绕不开一个词——HSM。尤其是当你拿到英飞凌 AURIX TC3xx 这类芯片,打开用户手册,翻到系统架构图,你会发现在一群 TriCore 主核旁边,还藏着一个“独立小系统”,这就是 HSM(Hardware Security Module,硬件安全模块)。
很多朋友第一次接触它的时候,脑子里全是问号:这不是已经有 TriCore 内核了吗,为什么还要单独塞一个核进去?它到底能干哪些事,又能替主核分担多少活?开发的时候要怎么跟它打交道?这些问题是绕不过去的,因为现在车厂对信息安全的要求已经不是“未来考虑”,而是量产准入级别的硬指标。不论你是做 BMS、域控制器还是 VDC,只要芯片选了 AURIX,HSM 这块内容迟早要啃。
这篇文章我打算做个系列,第一篇先把概念彻底讲透:HSM 到底是什么,它在 AURIX TC3xx 里是怎么搭出来的,软件侧的形态长什么样,以及它跟主核之间是怎么分工配合的。我自己在项目里调试安全启动时踩过不少坑,比如 HSM 启动后主核一直挂死、通信超时这类问题,这些实操细节后面单独开一篇说,这篇先把地基打好。
1. 为什么汽车电子需要一个“安全岛”
1.1 一个容易被忽略的现实:功能安全不等于信息安全
我在跟很多做嵌入式开发的朋友聊天时发现一个思维定式:大家习惯了把“可靠性”理解为信息安全。比如程序跑飞了有看门狗拉回来,数据出错了有 ECC 纠错,SRAM 有问题有 SafetyLib 做自检。这些确实是车规芯片非常核心的能力,AURIX 在这方面做得也确实稳。但信息安全是另一码事——它要防的不是随机故障,而是有目的的恶意攻击。
举个例子,假设你的 Bootloader 只做了 CRC 校验就放行应用程序。这个设计从功能安全角度看是合格的,因为 CRC 能检测出数据在存储或传输过程中的随机位翻转。但从信息安全角度看,这个校验形同虚设——攻击者完全可以自己算好 CRC,往固件里嵌入恶意代码,再把校验值一并改掉。更极端的情况是,攻击者通过调试接口直接把 MPCU(Memory Protection Unit)的配置寄存器改了,那你在应用层做的所有安全保护就成了摆设。
所以汽车行业逐渐达成了一个共识:安全必须有一个独立于主系统之外的硬件锚点。这个锚点不能跟主核共享内存空间,不能有公共的调试入口,也不能被应用层软件随意访问。它必须是一个物理上隔离的计算环境。
1.2 HSM 与“安全岛”理念的对应关系
HSM 就是这套理念的一个具体落地形态。在 AURIX TC3xx 里面,HSM 是一个独立的子系统,它有自己的 CPU、自己的 ROM、自己的 RAM、自己的密码学加速引擎。它不像普通外设那样挂在系统总线上等主核来访问,而是更像一个独立的“安全协处理器”,跟主系统之间的边界是硬件级的。
你可以把这个结构类比成一个银行网点:主核是营业大厅,处理日常存取款业务,效率高、吞吐量大;HSM 是金库,有独立的人脸识别门禁系统、独立的监控网络,就算营业大厅被人抢了,金库的门也不是靠抢柜台就能打开的。在汽车上,这个“金库”负责管密钥、管固件签名验证、管安全通信会话,都是最敏感的数据和操作。
说句题外话,TC3xx 一共有 6 个 TriCore 1.6.2P 主核(不同型号数量有差异),而 HSM 子系统内部还有一颗单核的 TriCore 1.6.2P,主频大概 100 MHz 左右。这颗小核平时你几乎感觉不到它的存在,但它承担的工作量一点都不轻。在 TC3xx 的安全启动流程中,这颗小核从上电那一刻就开始干活了。
2. TC3xx 里 HSM 的硬件架构初探
2.1 HSM 内部有哪些“家当”
翻看 AURIX TC3xx 用户手册,在 System Architecture 那一章能看到 HSM 子系统的大致组成。我按自己的理解整理了一张清单,方便大家对照手册看:
| 模块 | 说明 |
|---|---|
| CPU | 单核 TriCore 1.6.2P,主频约 100 MHz,架构与主核一致 |
| ROM | HSM 专用 ROM,存放出厂 Bootloader,上电优先执行 |
| RAM | HSM 专用 RAM(HSM RAM),主核不可直接访问 |
| Crypto Engine | 硬件密码学加速模块,支持 AES、RSA、ECC、SHA 等算法 |
| TRNG | 真随机数发生器,为密钥派生提供熵源 |
| DMA | 独立 DMA 控制器,处理密码运算时的数据搬移 |
| Mailbox | 与主系统通信的信箱机制,支持命令/响应交互 |
| Bridge | 连接主系统总线与 HSM 内部总线的桥接模块 |
2.2 这颗“迷你 TriCore”跑的是什么代码
很多第一次接触 HSM 的同学最容易产生的困惑是:HSM 里的 CPU 跟我用的主核是同一个架构,那我能不能直接在 HSM 上跑裸机程序?答案是能,但没人会这么干,也几乎没必要。因为 HSM 的编程模型跟主核完全不同。
HSM 的软件栈通常被划分为两个层次。第一层是固件层,由英飞凌提供,也叫 HSM Firmware,它实现了安全启动、密钥管理、加解密服务调用等功能。这一层对用户是半封闭的,它提供了 API 接口,但内部实现细节不公开。第二层则是用户扩展层,在英飞凌提供的框架之上用 SHE/EvitaFull 协议实现自定义的安全逻辑。但在量产项目里,绝大多数人其实并不需要在 HSM 里写业务代码,直接用英飞凌提供的固件接口就够了。
我自己刚开始接触时,总想着“既然 HSM 是个核,我是不是可以像写主核一样写个中断处理函数?”后来发现思路错了。HSM 更像一个专门执行密码学操作的服务单元,主核往它的 Mailbox 里丢一条指令,它算完再把结果放回来,本质是“计算委托”关系,而不是主核的“伙伴 CPU”。
3. HSM 的通信机制与启动流程
3.1 数据门卫:Mailbox 与共享内存的配合
主核与 HSM 之间怎么交换数据,是开发时必须面对的第一个问题。TC3xx 为 HSM 设计了一套独立的通信接口,通常是通过寄存器映射的 Mailbox 来传递控制消息,同时用有限的共享内存来搬运数据块。这里有个关键点:HSM 的信箱和共享内存地址在系统地址映射中是固定区域,主核能访问,但 HSM 内部的完整内存空间主核是看不见的。
如果你的应用要往 HSM 发送一段待加密数据,一般流程是:先把数据放到双方约定的共享内存区域,然后在 Mailbox 里写一条命令,告诉 HSM“数据准备好了,算法是 AES-128-CBC,密钥 ID 是多少”。HSM 拿到命令后,自己通过内部的 DMA 把数据搬到自己私有的 RAM 里,计算完再把结果写回共享区。
在实际项目里,这套机制还需要考虑 Cache 一致性问题——主核写完共享内存后,一定记得做数据同步操作,否则 HSM 可能读到陈旧数据。这个坑我真见人踩过,现象是加解密结果偶发性出错,排查了半天最后发现是 Cache 没刷。
3.2 上电后到底谁先跑
AURIX 的启动过程跟普通 MCU 有一个显著差异:主核并不是上电后立刻运行用户代码的。完整流程大概是这样:芯片复位后,主核处于等待状态,和主核紧密耦合的 HSM 核心开始从它的 ROM 区域执行启动代码,完成内部初始化,读取保存在 Flash 中的安全元数据(比如固件镜像的签名值、密钥版本号),然后开始安全验证。
主核在这段时间里不是完全闲着,它也会执行一小段 BootROM 代码。但真正的“放行”指令要等 HSM 验证通过后才会下发。这个设计初看可能让人觉得启动变慢了,但却是抵御“改一个字节固件就能刷进去”这类攻击的关键手段。
有的朋友可能会问:“如果 HSM 验证不过,主核会怎样?”答案是:主核会一直停在等待状态,或者根据配置进入一个错误处理流程。因为芯片本身被锁住了,你想通过 debugger 去连、去改 Flash 里的内容,都会被 HSM 拦截。这时候你才会明白,为什么说 HSM 是“防别人也防自己”的——所以量产阶段一定要预留好安全更新通道,否则自己也会被锁在外面。
4. 安全启动的完整链路拆解
4.1 从信任根到应用校验的关键路径
安全启动(Secure Boot)是 HSM 在车规项目里最核心、也是最先落地的一个功能。它的实现逻辑并不复杂,可以用一句话概括:从复位向量开始,每一级加载下一级代码之前,都必须验证下一级代码的身份和完整性。
具体到 AURIX 上,链路大致是:HSM ROM 就是信任根(Root of Trust),它验证 Bootloader 的数字签名;Bootloader 里调 HSM 固件的安全服务,再由 HSM 验证 Application 的签名;Application 启动后,后续的安全通信、安全更新都基于 HSM 提供的会话密钥来保护。
假设攻击者把 Application 区域的固件整体替换了,HSM 在验证时会发现摘要对不上或者签名不合法,随即中止启动流程。这就是“信任链”传导。要注意的是,这条链路上每一环都必须可信,如果某个环节用了不安全的哈希算法或弱密钥,那整个安全体系就会被拖垮。
4.2 数字签名的原理在安全启动中如何体现
数字签名用的是非对称密码算法。通俗地说,签名方用私钥对固件摘要进行加密,验证方用公钥解密并比对摘要。AURIX HSM 支持 RSA 和 ECC,对 4096 位 RSA 的验证性能也足够日常项目使用。
我在一个量产项目里实际遇到过一个问题:Bootloader 验证 Application 通过后,Application 启动时如果又去做了一遍完整签名校验,整个启动时间增加了不少。后来我们调整了策略:Bootloader 阶段做完整签名验证,Application 阶段只做关键内存区的完整性检查,启动时间才压回到设计要求以内。这个优化思路供大家参考。
4.3 密钥是如何保存在 HSM 内部的
传统 MCU 如果把密钥明文存在 Flash 里,攻击者通过调试接口或者芯片开盖就能提取。而 HSM 的做法是:把密钥放在只有 HSM 自己能访问的存储区域,或者用 HSM 内部的主密钥加密后存储在外部 Flash 中。
这里涉及一个概念叫“密钥封装”。比如你有一个用于固件签名的私钥,它不能明文出现在 Flash 里,而是用 HSM 内部不可读的主密钥加密成密文,在需要使用时由 HSM 在内部解密,主核全程接触不到明文密钥。TC3xx 里其实也有专门的 NVM 区域给 HSM 使用,但这块区域受保护,普通代码无法直接读取。
我见过一些项目图省事,把 HSM 密钥的编程过程简化成“直接写 Flash”,结果后续升级时发现密钥区被意外改写导致安全验证全盘失败,只能返工。密钥编程必须通过 HSM 提供的安全服务来做,绝不能绕过它。
5. HSM 的典型应用场景,远不止一个安全启动
5.1 固件安全更新:OTA 时代的基本盘
这几年车载 OTA 越来越普及,整个回滚和防篡改机制就成了安全重灾区。如果升级包在传输或者存储过程中被篡改,轻则 ECU 变砖,重则被植入恶意代码。HSM 在 OTA 链路里承担的是“验签+解密”两个核心动作:下载完成后的升级包先由 HSM 验证数字签名,如果升级包做了加密,再由 HSM 解密后才写入 Flash。
基于我自己的调测经验,固件升级时最需要注意的是版本回滚保护和失败恢复机制。如果新固件验证失败,Bootloader 必须能回退到上一版可用固件,而这一判断逻辑需要放在 HSM 或受 HSM 保护的代码里,不能依赖主核应用层——因为应用层本身可能已经被篡改了。
5.2 安全通信:SecOC 与 MAC 计算
现在整车通信越来越强调 Authenticity(真实性)和 Integrity(完整性)。AUTOSAR 里常见的 SecOC(Secure Onboard Communication)机制,就是对 CAN/以太网报文做 MAC 计算与验证。如果让主核软件算 MAC,不仅 CPU 开销大,而且密钥就暴露在应用层了。
把 MAC 计算放到 HSM 之后,有两点很关键:一是 CPU 负载压力大幅下降,实测中 AES-128 的 MAC 计算由硬件引擎完成后,主核几乎零负担;二是密钥不出 HSM,攻击者在应用层拿不到任何密钥材料。有些平台直接把报文收发路径和 HSM 的 MAC 计算做成一条硬件流水线,这个对实时性敏感的 ECU 来说非常友好。
5.3 安全调试与生命周期管理
芯片调试接口是攻击者最爱的入口之一。AURIX 提供了不同级别的调试访问控制,配合 HSM 可以实现“封板”效果:量产阶段关掉不必要的调试通道,或者只有通过安全认证流程才能解锁调试权限。这对防止调试接口被滥用非常重要。
生命周期管理也是 HSM 的一项硬能力。芯片从开发到量产再到售后维修,状态是分阶段的,比如 Customer Delivery、In Field 等。HSM 可以管理这些状态之间的切换,而且状态通常只能单向推进,防止有人把量产态回滚成开发态来开启调试功能。
6. 开发者视角:我该怎么开始用 HSM?
6.1 不要从零造轮子,先用英飞凌的框架
很多人第一次接触 HSM 就想自己写底层驱动,我劝你先把英飞凌官方提供的 HSM 固件和相关库用起来。不同芯片系列的 HSM 软件栈是有差异的,AURIX TC2xx 和 TC3xx 的 HSM 设计就不完全一样。如果你用 TC3xx,先从官方的 MCAL 和 Crypto Driver 入手,它们是 AUTOSAR 标准接口,上层软件可以直接调用,不需要自己对接底层密码引擎。
英飞凌的 Crypto Driver 有几种操作模式:同步模式、异步模式和中断模式,实际项目中我一般倾向用异步模式,因为密码运算毕竟是一个耗时操作,同步模式会阻塞主核的任务调度。异步模式下,主核发起请求后可以继续执行其他任务,等 HSM 算完通过回调通知结果,CPU 利用率能高不少。
6.2 开发调试时容易踩的坑
第一,HSM 的调试与主核不同。主核可以用主流的调试器直接连接,但如果 HSM 已经锁死或进入了 Secure 状态,调试器连接可能会被拒绝。我建议在开发阶段不要过早把 HSM 置于生产安全状态,先保留调试通道,等所有逻辑验证完成后再封闭。
第二,HSM 固件的升级要格外谨慎。有一类应用场景是 HSM 固件本身需要更新,这时老的 HSM 固件需要允许新固件更新自己。这套更新流程必须非常小心,因为一旦中途断电,HSM 可能会进入一个不可恢复的砖头状态。英飞凌的机制通常要求双备份区域,但我仍建议所有量产项目在做 HSM 固件更新时增加掉电检测和紧急恢复流程。
第三,主核与 HSM 的通信超时问题。这个我在项目里反复遇到,HSM 忙的时候,主核发送的请求可能排大队,如果主核代码里等响应超时时间设得太短,就会误报失败。建议所有通信都采用状态机驱动,不要用阻塞式死等,至少给自己的业务逻辑留足余量。
6.3 性能上的几个参考数据
很多人担心 HSM 会不会变成性能瓶颈。以 TC3xx 的 HSM 子系统为例,它内置的硬件加密引擎在算 AES-128(加解密)时吞吐量可以达到几十 MB/s 级别,对常见的车载通信报文来说完全够用。RSA 这种非对称运算相对慢一些,但一次 2048 位 RSA 验签大概也只需要几十毫秒,而这个动作通常只发生在启动或升级场景,对实时性要求不高。
真正需要关注的性能瓶颈常常不在算法本身,而在数据搬运路径。主核往共享内存里写数据、HSM 用 DMA 搬数据、算完再搬回来,这三个环节如果设计不好,会产生不少额外延迟。建议在数据量大的场景下,优先用 DMA 而不是 CPU 搬运。
7. 写在最后的一点实践体会
我自己的感觉是,HSM 跟普通 MCU 外设最大的不同在于:它带来的是一整套新的开发思维。过去我们更多的是在“用寄存器”,而 HSM 更像是“与一个安全协处理器协作”。如果你是从传统单片机直接跳到 AURIX,这个思维转变需要一点时间来适应。
这篇文章里我没有贴太多寄存器级的细节,因为对于刚接触 HSM 的人来说,先建立整体框架比直接陷入寄存器更有价值。到了真正做安全启动或者密钥管理方案时,再回头去查具体寄存器和 API,会顺畅很多。
下一篇我准备写 HSM 固件的具体使能流程,以及在 AURIX 开发环境中如何一步一步跑通 HSM 的安全通信示例。如果你正准备在项目里落地 SecOC 或者安全启动,可以先把手上的 TC3xx 开发板翻出来,照着官方示例熟悉一下 Crypto Driver 的接口,等下一篇出来正好能衔接上。