3. 物理不可克隆函数(PUF):芯片的“指纹”
各位同学,今天我们来聊聊物理不可克隆函数,简称 PUF。这玩意儿,说白了就是给每颗芯片一个独一无二的“身份证”。你想想看,传统密钥是存在 Flash 或 eFuse 里的,一旦被物理探针或者侧信道攻击挖出来,整个系统就裸奔了。PUF 的思路完全不同——它不存密钥,而是“制造”密钥。
我记得 2015 年帮一家 IoT 公司做安全评估时,他们用的就是外挂安全芯片,密钥存 EEPROM。结果呢?我们用聚焦离子束(FIB)切开芯片顶层,直接用微探针读出了密钥。从那以后,我但凡做安全方案,第一反应就是:能不能用 PUF?
3.1 PUF 的核心原理
PUF 的物理基础,是芯片制造过程中不可避免的工艺偏差。同一片晶圆上,哪怕相邻的两个晶体管,其阈值电压、栅氧厚度、沟道长度都会有细微差异。这些差异是随机的、不可控的,而且一旦芯片封装完毕,就基本固定了。
PUF 做的事情很简单:把这种物理偏差映射成二进制响应。你给它一个“挑战”(Challenge),它返回一个“响应”(Response)。这个 Challenge-Response Pair(CRP)就是芯片的身份凭证。
核心特性:
- 不可克隆:即使拿到同一套光罩、同一套工艺参数,也无法造出第二颗 CRP 完全相同的芯片。
- 物理绑定:PUF 响应与芯片物理实体绑定,芯片被破坏,响应即消失。
- 防篡改:任何物理探测都会改变 PUF 的物理结构,导致响应变化。
嗯,这里要注意:PUF 不是完美的。它的响应会有噪声——同一个挑战,在不同温度、电压下,可能返回略有差异的响应。所以后面我们会讲怎么用纠错码(ECC)来稳定它。
3.2 PUF 的主要类型
PUF 家族成员不少,我按实现方式分成三大类:模拟型、数字型和存储型。下面这个表格帮你快速对比:
| 类型 | 典型结构 | 面积开销 | 稳定性 | 典型应用 |
|---|---|---|---|---|
| 模拟型 | 环形振荡器 PUF (RO-PUF) | 中 | 中(受温度影响大) | 密钥生成 |
| 数字型 | 仲裁器 PUF (Arbiter PUF) | 小 | 低(易受建模攻击) | 轻量级认证 |
| 存储型 | SRAM PUF | 大(需 SRAM 阵列) | 高(上电即稳定) | 密钥存储、设备ID |
3.2.1 环形振荡器 PUF(RO-PUF)
这是我个人用得最多的一种。原理很简单:在 FPGA 或 ASIC 里放 N 个结构完全相同的环形振荡器,每个 RO 由奇数个反相器组成。由于工艺偏差,每个 RO 的振荡频率都不一样。我们比较两个 RO 的频率,谁快谁慢,输出 0 或 1。
我曾经在一个 28nm 的项目里,用 RO-PUF 做密钥生成。踩过一个坑:RO 的布局布线必须极度对称。如果两个 RO 的走线长度差了 1 微米,频率偏差就会被布线偏差主导,PUF 的随机性就没了。所以我的习惯是:用 Common Centroid 布局,加 dummy RO 做边界匹配。
避坑指南: RO-PUF 对温度敏感。我曾经在 -40°C 下测试通过的 CRP,到 85°C 时误码率飙升到 15%。解决方案是:用差分比较(比如 3 个 RO 取中位数),或者加片上温度传感器做动态补偿。
3.2.2 仲裁器 PUF(Arbiter PUF)
仲裁器 PUF 是另一种经典结构。它由两条对称的延迟路径组成,路径上有一系列开关单元。挑战信号控制每个开关的交叉/直通状态。最终,两条路径的信号到达仲裁器(一个 D 触发器)的时间差,决定了输出是 0 还是 1。
这种 PUF 的优点是面积小、CRP 数量多(理论上 2^N 个挑战)。但缺点也很致命:容易被机器学习建模攻击。我记得 2018 年看过一篇论文,用几千个 CRP 训练一个神经网络,就能以 95% 以上的精度预测未知挑战的响应。所以,仲裁器 PUF 现在主要用于轻量级认证场景,而且必须配合 CRP 混淆或哈希使用。
警告: 不要在生产环境中直接暴露仲裁器 PUF 的原始 CRP!攻击者可以通过侧信道(比如功耗分析)获取 CRP,然后建模。我建议至少加一层 HMAC 对响应做后处理。
3.2.3 SRAM PUF
SRAM PUF 是我个人最喜欢的类型,因为它“零成本”——利用芯片上已有的 SRAM 单元。SRAM 单元在上电瞬间,由于两个交叉耦合反相器的工艺失配,会随机稳定到 0 或 1 状态。这个初始状态就是 PUF 响应。
SRAM PUF 的稳定性很好,因为 SRAM 单元本身设计就是双稳态的。但要注意:不是所有 SRAM 都适合做 PUF。比如低功耗 SRAM 用了高阈值电压晶体管,上电状态可能受噪声影响。我一般建议用标准 6T SRAM,而且上电前要确保所有位线预充电到 VDD/2。
实际项目中,我常用 SRAM PUF 做设备唯一 ID。比如在 MCU 里,芯片启动时读一段 SRAM 的上电初始值,经过纠错和哈希,生成 128 位设备密钥。整个过程不需要额外硬件,爽得很。
3.3 PUF 的典型应用场景
PUF 不是万能的,但在以下几个场景里,它比传统方案靠谱得多:
- 安全密钥存储:密钥不落 Flash,只在需要时由 PUF 实时生成。芯片被物理破解,密钥自动消失。
- 设备身份认证:服务器存 CRP 数据库,设备每次认证时,服务器发随机挑战,设备返回 PUF 响应。防克隆、防重放。
- IP 保护:防止芯片被过度制造或克隆。比如在 FPGA Bitstream 里绑定 PUF 响应,Bitstream 只能在特定芯片上运行。
- 真随机数生成:PUF 响应的随机性可以提取出来做 TRNG 种子。我做过一个方案,用 RO-PUF 的抖动(Jitter)直接生成随机数,通过了 NIST SP 800-22 测试。
一个真实案例: 某汽车 T-Box 项目,要求 OTA 升级时验证服务器身份。传统方案用预置证书,但证书私钥存在 Flash 里,被 JTAG 调试接口读出来了。后来改用 SRAM PUF 生成设备私钥,配合 ECDSA 签名,彻底堵死了密钥提取路径。
3.4 PUF 系统架构图
下面这张图展示了一个典型的 PUF 密钥生成系统架构。我建议你仔细看看数据流,尤其是纠错和哈希这两个模块——它们是 PUF 从“实验室玩具”变成“工业级方案”的关键。
3.5 工程实现中的关键问题
最后,我结合自己的项目经验,给你列几个 PUF 落地的关键问题:
- 稳定性 vs. 随机性:两者是 trade-off。纠错码加得越多,稳定性越好,但随机性可能下降(因为纠错码会引入确定性)。我一般用 BCH 码,纠错能力选 t=3 或 t=4,够用又不至于过度修正。
- 老化效应:芯片用久了,PUF 响应会漂移。尤其是 RO-PUF,NBTI 效应会让 PMOS 阈值电压漂移。我的做法是:在注册阶段留 20% 的冗余位,用于后期动态替换漂移严重的位。
- 攻击防护:PUF 本身抗物理探测,但它的接口(比如挑战寄存器、响应输出)可能被攻击。我习惯在 PUF 模块周围加 active shield,检测到异常探测就清零所有寄存器。
一个小技巧: 如果你用 SRAM PUF,上电后不要马上读。等 1-2 微秒,让 SRAM 单元充分稳定。我见过一个项目,上电后 100ns 就读,结果 10% 的单元还在亚稳态,响应全是乱的。