去年接了一个轨道交通闸机控制器的安全改造项目,客户在需求里明确写了两条:一是必须采用 PCIe/104 形态的单板计算机,二是板载 TPM-2.0 安全芯片并支持安全启动。我最初有点不以为然,觉得工控场景加一颗 TPM 芯片无非是应付合规。直到把样机拿到手,发现这块标称 OneBank 的 PCIe/104 SBC 在 BIOS、内核、应用三层都在围绕 TPM 做文章,我才意识到,这种小尺寸板卡已经把“硬件信任根”做成了默认配置。这篇文章就把我从选型评估到实测、再到现场部署的全部记录整理出来,给正在评估 TPM-2.0 安全 SBC 的工程同行一点参考。
1. 先搞懂这块板的底子:PCIe/104 和 OneBank 形态意味着什么
1.1 PCIe/104 不是老 PC/104 换个名字
在嵌入式领域,PC/104 是极有历史的紧凑规格,名字来自 104 个引脚,标准板卡尺寸是 90×96 mm,通过四角的安装孔可以直接层叠,省掉了传统背板和机箱。PCIe/104 则是在这个物理外形框架下,用 PCI Express 串行总线替代传统 PCI/ISA 并行总线的新一代标准。
注意,PCIe/104 不是一个笼统的“老标准升级版”,它底下还分了好几个子规格,最常见的是 PCI/104-Express 和 PCIe/104。区别在于:PCI/104-Express 上同时保留了传统 PCI 和 PCIe 信号,方便兼容旧模块;PCIe/104 则更激进,主要保留 PCIe 信号,走纯串行路线。普通用户很容易把这两个名字混用,但选型时如果搞混,很可能会导致后续堆叠模块插不上,或者信号线定义不一致,板卡插上去点不亮。
从工程角度看,PCIe/104 最大的改进是带宽和信号数量。PCIe x1 链路的单向速率是 2.5 GT/s,x4、x16 更高,而且差分信号比并行总线抗干扰能力强得多。这对于机器视觉、多路网络采集这类数据量大的场景是实打实的提升。同时,PCIe/104 的堆叠方式决定了它天然适合可扩展、可维护性要求高的工业设备:哪个模块坏了就换哪个,不用动整个机箱。我们在轨道交通项目中选它,就是看中这个特性。
1.2 OneBank 单通道内存设计:稳定优先还是性能妥协?
OneBank 这个词,在 PCIe/104 SBC 上通常指内存子系统采用单通道设计,或者只保留一条 SO-DIMM 插槽。在内存颗粒层面,Bank 是 Memory Controller 寻址的一个逻辑组织,单 Bank 意味着数据通路只有一条 64-bit 通道。很多板厂把它做成产品线命名规则,我是认同的:它传达的第一优先级不是跑分,而是“简化”。
为什么工业板卡要刻意把内存做成单通道?第一是信号完整性更好。单通道布线短、串扰少,内存控制器和颗粒之间的时序更容易收敛,这对长时间 7×24 小时运行非常重要。第二是功耗可控。多通道意味着多组供电和更复杂的电源拓扑,单通道可以把待机功耗压得更低。第三是故障率。少一组通道、少一个插槽,就少一个故障点。工业现场的振动、温湿度变化都可能导致 SO-DIMM 接触不良,板载单通道颗粒方案反而更稳。
我在实际测试这块 8 GB DDR4 单通道板卡时,跑 Modbus 网关、边缘协议解析和本地 SQLite 读写,内存带宽基本不是瓶颈。真正吃内存带宽的场景是多路网口同时抓包,这种情况单通道确实有上限。所以,OneBank 不是低端的代名词,而是把产品定义聚焦在稳定、低功耗、长生命周期上。选型的人要先想清楚自己的应用负载是带宽型还是事务型。
1.3 为什么这块板要搭配 TPM-2.0 而不是 1.2
TPM 1.2 时代的芯片,主要作用就是给 BitLocker 做平台验证,算法固定为 RSA-2048 和 SHA-1,PCR 只有 16 个,厂商策略差异也大。TPM 2.0 是 TCG 在 2014 年发布的规范,最大变化是算法可扩展:支持 SHA-256、SM3、SHA3-256,支持 RSA 和 ECC,PCR 数量增加到最多 24 个,还引入了更灵活的授权策略和 NV 索引机制。
对工业设备来说,TPM 2.0 真正值钱的地方在于“硬件信任根”。设备上的加密证书、通信密钥、软件更新签名公钥都可以放到 TPM 里,即使攻击者拿到文件系统,也无法把密钥复制到另一台机器上使用。加上 Windows 11 把 TPM 2.0 列为强制要求,这两年几乎所有新设计的工控板卡都把 TPM 2.0 变成标配。PCIe/104 板卡跟着走,实际上是顺应了整个产业链的安全基线提升。
2. TPM 2.0 的安全机制拆解:信任根、密钥与测量启动
2.1 TPM 在硬件上是什么
从主板设计角度看,TPM 是一颗被动安全微控制器,它不主动执行代码,而是等 CPU 通过总线发起指令后响应。在 PCIe/104 SBC 上,TPM 通常通过 SPI 或 LPC 总线与 SoC 连接。SPI 更常见,原因很简单:引脚少、速率高,还能和其他 SPI 设备共用一个控制器,只要片选信号分开就行。
市面上常见的独立 TPM 芯片有英飞凌 SLB 系列、Nuvoton NPCT 系列、Microchip ATTPM 系列等。选型时除了看芯片是否通过 TCG 认证,还要确认它是 discrete TPM 还是 fTPM。Intel/AMD 平台上的 fTPM 是固件模拟的,虽然功能兼容,但在工业高安全场景下,我更信任独立封装芯片,因为它的物理隔离性更好,也更难被固件级攻击绕过。
TPM 芯片内部有非易失性存储,通常几十 KB,用来存 EK、SRK、NV 索引和 PCR 数据;还有自己的真随机数生成器和哈希、非对称加密引擎。这些能力决定它不只是“存一个密码”,而是能在芯片内部完成密钥生成、签名、加解密操作,私钥全程不离开芯片。
2.2 EK、SRK、PCR:必须理解的三个概念
三个概念想清楚,TPM 的用法就懂了一半。
EK 是背书密钥,每颗 TPM 出厂时生成,唯一标识这颗芯片。EK 绝不能导出,主机软件也不能直接用 EK 做普通加解密,它只用于平台身份认证。比如通过 EK 证书向验证服务器证明“我是这台有正规 TPM 的设备”。
SRK 是存储根密钥,通常由 TPM 的种子结合平台参数生成。用户创建的所有密钥都会被 SRK 保护,所以这些密钥导出到外部时是密文,只能在当前 TPM 内部解密后使用。TPM 2.0 里 SRK 的算法和策略是可配置的,常用 RSA-2048 或 ECC P-256。
PCR 是平台配置寄存器。它的计算方式是:新值 = HASH(旧值 || 度量值),一旦写入就无法逆推,也不能直接清零,只能通过重启重置。TPM 本身不负责度量,它只记录系统各阶段组件的哈希值。常见分配:PCR0 是平台固件代码,PCR1 是平台固件配置,PCR4 是引导加载程序,PCR7 是安全启动状态。系统每次启动,PCR 都会重置并重新累计,所以通过对比 PCR 值就能判断平台是否被篡改。
2.3 安全启动和测量启动的区别
这个区别非常关键。Secure Boot(安全启动)是 UEFI 在加载每个阶段前做签名验证,验证失败就拒绝执行。Measured Boot(测量启动)则是把每个阶段的实际哈希值算出来记入 PCR,不阻止启动,但留痕。两者结合,Secure Boot 保证“坏东西进不来”,TPM 保证“就算进来也一定会留下痕迹,并且让敏感密钥在异常状态下无法使用”。
这里就引出 TPM 最实用的能力:基于策略的密钥密封。比如我想把设备的根证书私钥密封在 TPM 中,解封条件是“PCR7 等于安全启动启用状态,且 PCR4 等于一个已知的 bootloader 哈希”。如果攻击者替换了带后门的 bootloader,PCR4 变化,即使私钥被读出来,TPM 也不会解密。
这个机制在 BitLocker、LUKS2、systemd 加密凭证和 Android 的 dm-verity 里都有落地。理解它,你才能真正用活 TPM,而不是只把它当成一个合规贴纸。
3. 从固件到操作系统:实测 TPM 的完整过程
3.1 BIOS/UEFI 设置注意点
拿到 PCIe/104 OneBank 板卡后,先把 BIOS 里的 TPM 菜单确认清楚。不同厂家路径不太一样,常见位置在 Security 或 Trusted Computing 下面。关键在于看清状态:Enabled、Disabled、Deactivated 三者的区别。如果板子上确实装了 TPM 芯片,但 BIOS 里找不到菜单,大概率是固件版本太老,ACPI 表没生成完整,这时不要自己猜,直接找原厂要新版 BIOS。
开启 TPM 时,把 PCR bank 的首选算法设为 SHA-256。SHA-1 在很多新系统里已经默认不启用,如果只保留 SHA-1,后续在 Linux 下读取 PCR 会少很多有用的值。还有一个容易踩的坑:Fast Boot 开启状态下,首次激活 TPM 后重启可能卡在 POST,尤其是那些对 TPM 初始化时序要求严格的 BIOS。遇到这种问题,先做一次 CMOS 清除,然后关闭 Fast Boot 再试。
3.2 Linux 下用 tpm2-tools 实测
进入 Ubuntu 22.04 后,先用 dmesg 确认内核识别了 TPM:
dmesg | grep -i tpm正常情况下能看到 tpm0 设备节点。如果看不到,确认内核配置 CONFIG_TCG_TPM 和 CONFIG_TCG_TIS_SPI 是否开启。然后安装工具:
sudo apt install tpm2-tools注意,Ubuntu 22.04 自带的是 tpm2-tools 5.x,命令行参数和 3.x 差很多。比如指定父对象用的是-C,创建对象时-c表示要加载的上下文文件,新手很容易抄错老命令直接报错。
先读 PCR:
tpm2_pcrread可以看到 sha1、sha256 两套 PCR 值。再创建一个受 SRK 保护的主密钥:
tpm2_createprimary -C e -g sha256 -G rsa2048 -c primary.ctx这里-C e表示父对象是 EK handle,可能部分芯片需要先用tpm2_createek生成 EK 证书,具体因固件而异。接下来做一次带 PCR 策略的密钥创建:
tpm2_startauthsession -S session.ctx --policy-session tpm2_policypcr -S session.ctx -l sha256:7 tpm2_create -C primary.ctx -g sha256 -G rsa2048 -u pub.pem -r priv.bin -L policy.dat -a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth" tpm2_flushcontext session.ctx这套命令的含义是:把密钥的私钥绑定到 PCR7 当前状态。属性里的fixedtpm表示私钥只能在当前 TPM 上使用,sensitivedataorigin表示密钥材料由 TPM 自行随机生成,外部导入时则不需要这个属性。
创建完后可以加载进行实际加密测试:
tpm2_load -C primary.ctx -u pub.pem -r priv.bin -c key.ctx echo "secret data" > secret.txt tpm2_encryptdecrypt -c key.ctx -G aes -i secret.txt -o secret.enc如果之前用了 PCR 策略,直接用tpm2_encryptdecrypt会报策略不匹配。需要重新开启 policy session 并执行tpm2_policypcr后才能解密。我实际测试时故意关闭 Secure Boot 再解封,命令立即报 0x9010 错误,恢复后又能正常使用。这个行为就是平台绑定的价值所在。
3.3 Windows 端的 BitLocker 和 Win11 验证
Windows 下打开 tpm.msc 就能看到 TPM 状态。显示“TPM 已准备好使用”是正常状态;如果显示“已就绪,但未完成初始化”,点“初始化 TPM”并重启即可。我测试的这块板卡,在 BIOS 里开启了 UEFI 和 TPM 后,Windows 11 安装检测直接通过。
BitLocker 开启后,默认会用 TPM 进行启动完整性验证。这里有一个常见误区:很多运维看到 BitLocker 进入恢复模式就以为是加密坏了,其实可以通过manage-bde -protectors -get C:命令找回恢复密钥 ID。只要你有 48 位恢复密钥,即使 TPM 芯片损坏,也能在另一台机器上挂载原有数据。
我建议每个项目交付前都做一次“TPM 损坏模拟”演练:备份恢复密钥,在 tpm.msc 里清除 TPM,重启后观察系统进入恢复模式,输入恢复密钥确认系统能正常引导。这个演练能提前发现恢复密钥备份和交接流程中的漏洞。
4. 工程化和部署阶段那些容易翻车的地方
4.1 断电、电池和 TPM 不可恢复状态
有些工业板卡上的 TPM 不需要外部电池供电,它的非易失性存储是内置的,但这不代表你可以随意断电。TPM 在写 NVRAM 时存在一个很小的持久化窗口,如果恰好在这个窗口掉电,轻则 PCR 数值不一致,重则 NV 索引损坏,导致 TPM 状态异常。
我在实验室里遇到过一次典型问题:反复调试 TPM 清除流程时,某次清完 TPM 后设备重启直接卡在 BIOS 自检。最后通过串口看门狗才发现,BIOS 在检测到 TPM 被清除后,要求完成一次“物理在场确认”,需要再次进入 BIOS 手工确认。这类问题对远程运维是致命的,所以如果设备要部署到无人值守的站点,必须和硬件厂家确认清楚:板卡的 BIOS 是否支持远程 TPM 状态确认,或者有对应的管理接口,否则清 TPM 这个动作只能现场执行。
4.2 堆叠其他 PCIe/104 模块时的中断与引脚冲突
PCIe/104 的卖点是堆叠,但堆叠模块多了以后,总线负载和信号质量的风险会明显上升。TPM 通常走 SPI 总线,而 SPI 总线上往往同时挂着 BIOS Flash、管理控制器等设备。只要任何一块扩展模块复用了 SPI 片选,就可能和 TPM 冲突。
我见过一个实际案例:客户加装了一块自定义 SPI 通讯模块后,系统每隔几次启动就会出现一次 TPM 报错。最后分析发现,扩展模块的 SPI 片选和 TPM 使用同一路 GPIO,占用了同一个片选编号。解决办法是改模块上的跳线,把片选映射到空闲引脚,但这类问题最好在选型阶段就向板卡原厂要完整的 SPI 资源分配表,提前规避。
另外,堆叠导致的散热问题常被忽略。我在测试时把两个热电偶分别贴到底层 SBC 和中间层扩展模块上,发现夹层里的实际 PCB 温度比环境温度高 10~15°C。如果现场机柜温度已经 50°C,TPM 芯片表面可能接近 70°C,虽然没超工业级标称上限,但长期可靠性肯定受影响。机箱设计时一定要给堆叠模块上方留出至少 10 mm 的散热空间。
4.3 兼容性坑:某些 BIOS 版本对 TPM 打开状态的处理不一致
同一块 PCIe/104 板,BIOS 版本不同,TCG ACPI 表的行为可能完全不同。我实测过一块板子的 v1.1 固件:开启 TPM 后 Linux 能看到 /dev/tpm0,但执行tpm2_pcrread报 0x146 错误,内核日志里出现 tpm 命令超时。升级到 v1.4 后问题消失。这种问题不用花太多时间调试内核,第一时间还是应该联系原厂要新版固件。
同时,建议把 TPM 固件版本也一并记录下来,用tpm2_getcap properties-fixed可以查看 TPM 厂商、固件版本等信息。把主板 BIOS 版本和 TPM 固件版本一起纳入出厂验收记录。项目上遇到过两台外观完全一样的设备,因为出厂固件批次不同,TPM 策略调用行为有细微差异,导致一台能正常解封,另一台怎么都失败。这种问题光凭代码比对是看不出来的,只有靠基线记录。
5. 选型、验收和风险控制:我的检查清单与实测建议
5.1 硬件选型清单
我在项目里把验收项做成了一张表,下单前发给供应商确认,到货后逐项核对。
| 检查项 | 验收要求 | 备注 |
|---|---|---|
| 外形规范 | 90×96 mm,符合 PCIe/104 标准 | 确认具体子规格,PCI/104-Express 与 PCIe/104 不能混用 |
| 内存配置 | OneBank 单通道,明确容量和颗粒 | 板载颗粒或 SO-DIMM 插槽,确认是否支持 ECC |
| TPM 形态 | 独立封装芯片,TCG 认证 | 不接受 fTPM 或未认证型号 |
| TPM 算法 | 支持 SHA-256,PCR bank 数不少于 20 | 确认 RSA/ECC 支持情况 |
| 总线接口 | SPI 接口,独立片选 | 确认不与 SPI Flash、管理控制器冲突 |
| 工作温度 | 工业级 -40~85°C | 实测堆叠后夹层热点温度 |
| 电源 | 单 5V 或 12V 供电 | 确认待机状态下 TPM 是否继续供电 |
| 认证 | 固件、TPM 均为最新版本 | 要求提供出厂基线报告 |
5.2 固件/系统启用清单
硬件确认完以后,固件和系统侧的清单也很关键,每一步都有对应的验证动作:
- 把 BIOS 固件升到厂家最新版本,更新后重新检查 TPM 菜单是否完整。
- 开启 UEFI 模式和安全启动,关闭 CSM/Legacy 模块。
- 在 BIOS 中启用 TPM,设置 SHA-256 为 PCR bank 首选算法,确认状态为“已就绪”。
- 进入操作系统,用 dmesg 确认 TPM 设备节点正常,Linux 内核开启 CONFIG_TCG_TPM、CONFIG_TCG_TIS_SPI。
- Windows 系统下打开 tpm.msc 确认状态正常,初始化并重启。
5.3 完整安全验证流程
我建议项目验收时至少完整跑一遍下面的流程,这套流程看着简单,但能提前暴露 70% 的现场安全问题:
- 读取 PCR0/4/7,保存为基准哈希值。
- 用 tpm2-tools 生成 SRK 和一个应用密钥。
- 创建绑定到 PCR7 的数据密封策略,把配置文件加密保存。
- 在正常启动状态下执行解封,确认成功。
- 在 BIOS 中关闭安全启动,引导系统后再次执行解封,确认失败。
- 恢复安全启动,再次执行解封,确认成功。
- 备份 BitLocker 恢复密钥或 TPM 主密钥,清除 TPM,验证系统恢复过程。
- 记录每次操作的关键日志,形成出厂基线报告。
这套流程我通常安排在新设备到货后的第二天做,一块板子大概需要半天时间。做完以后,板卡状态、密钥策略、恢复流程都明确记录在案,后续不管设备发到哪个现场,运维都有一份可依赖的参考。
我在实际项目里踩过不少坑,最后总结下来的体会是:TPM-2.0 不是买回来开个 BIOS 开关就完事的。一定要在出样机前把 PCR 基线、密钥备份、状态恢复流程都跑一遍,尤其是对于部署在外场的设备,一次误清 TPM 可能就意味着一张现场车票。把这些前置工作做扎实,TPM 才能真正成为你系统的安全底座,而不是一个添乱的合规组件。