3、FPGA比特流结构与安全风险:比特流格式解析、未加密比特流的脆弱性、Xilinx/Intel的加密方案概览
好,咱们进入第三章。这一章我打算聊聊比特流——这个FPGA的“灵魂文件”。
你想想看,FPGA上电后啥也不干,就等着加载这个文件。它决定了你的逻辑电路怎么连、跑多快、甚至有没有后门。所以,理解比特流的结构,是搞安全的第一步。
我个人习惯把比特流比作一张“电路蓝图”。只不过这张蓝图是用二进制写的,而且里面藏着不少秘密。
3.1 比特流格式解析
先说格式。不同厂家的比特流格式不一样,但核心思路差不多。
以Xilinx为例,它的比特流文件(.bit)开头是一段固定头。这段头里包含了设计名称、器件型号、生成时间等信息。我当年刚入行时,还傻乎乎地以为这些信息只是给用户看的。后来才发现,这些头信息在安全校验时也会被用到。
头之后,就是真正的配置数据了。这部分是压缩过的,按帧(Frame)组织。每一帧对应FPGA内部的一列逻辑资源。说白了,就是告诉你哪个LUT该连哪个线,哪个BRAM存什么数据。
Intel(原Altera)的格式也类似,但它的帧结构更复杂一些。我记得有一次调试一个Intel的板子,死活加载不上,最后发现是帧对齐出了问题。嗯,这里要注意:不同系列的器件,帧长度可能不一样。
下面是一个简化的比特流结构示意:
+------------------+
| 同步头 (Sync) | // 固定值,用于识别
+------------------+
| 器件ID (IDCODE) | // 校验器件型号
+------------------+
| 配置命令 (CMD) | // 如写配置、读状态
+------------------+
| 配置数据 (Data) | // 真正的比特流内容
| (帧序列) |
+------------------+
| 循环冗余校验(CRC) | // 完整性校验
+------------------+
| 结束标志 (Done) | // 配置完成
+------------------+
你可能会问:为什么要有CRC?其实,CRC最初是为了检测传输错误。但在安全场景下,它也能防止比特流被篡改。不过,如果CRC算法是公开的,攻击者完全可以重新计算。所以,光靠CRC是不够的。
3.2 未加密比特流的脆弱性
这一节我要重点讲。未加密的比特流,说白了就是“裸奔”。
我在项目中遇到过一件事:客户的产品被抄板了,对方直接把比特流从SPI Flash里读出来,然后烧到自己的板子上。为什么能这么干?因为比特流没加密,读出来就是明文。
未加密比特流的脆弱性主要体现在三个方面:
- 窃取:通过JTAG、SPI接口或逻辑分析仪,直接抓取比特流数据。你想想看,只要物理接触到了板子,这几乎是防不住的。
- 逆向:比特流虽然是人眼看不懂的二进制,但工具可以反编译。Xilinx有bitgen,社区也有开源工具。我曾经见过有人把别人的比特流反编译成网表,然后改几个LUT,就变成了自己的设计。
- 篡改:更可怕的是,攻击者可以在比特流里插入恶意逻辑。比如,在某个状态机里加一个“后门触发条件”。一旦满足条件,系统就失控了。
为什么会这样?因为FPGA的配置过程本质上是“明文传输”。上电后,FPGA从外部存储器读取配置数据,然后加载到内部SRAM。这个过程中,数据是暴露在总线上的。只要有人监听总线,就能拿到完整的比特流。
我曾经帮一个客户做过安全审计。他们的板子上,SPI Flash到FPGA的走线长达5厘米。我用一个简单的近场探头,就能在5厘米外读到完整的比特流。嗯,这其实是个物理安全问题。
3.3 Xilinx/Intel的加密方案概览
既然明文不行,那就加密。两大厂都有自己的方案。
3.3.1 Xilinx的加密方案
Xilinx的方案叫“比特流加密”,主要用AES-256。我记得从7系列开始,就支持了。
流程是这样的:
- 在Vivado里生成加密比特流时,需要指定一个密钥文件(.nky)。
- 这个密钥会被烧录到FPGA内部的eFUSE或BBRAM(电池备份RAM)里。
- 上电后,FPGA先从外部读取加密的比特流,然后用内部密钥解密,再加载。
这里有个关键点:密钥存储在哪里?
- eFUSE:一次性编程,不可逆。适合量产场景。但一旦烧错,芯片就废了。我有个同事就干过这事,烧错了密钥,整批芯片报废。
- BBRAM:可多次写入,但断电后需要电池保持。适合开发调试。不过电池会没电,所以产品里我一般不建议用。
Xilinx还支持“HMAC认证”。说白了,就是在加密的基础上再加一层校验。防止有人篡改加密后的比特流。我建议,只要条件允许,就把HMAC打开。多一层保护,多一分安全。
3.3.2 Intel的加密方案
Intel的方案叫“配置安全特性”,也是用AES-256。但它的实现方式有点不一样。
Intel的FPGA内部有一个“安全处理器”,专门负责解密和认证。这个处理器是独立的,不占用用户逻辑。所以,即使你的设计跑飞了,安全处理器还在正常工作。
Intel支持两种密钥存储方式:
| 存储方式 | 特点 | 适用场景 |
|---|---|---|
| 熔丝(Fuse) | 一次性编程,不可逆 | 量产产品 |
| 安全RAM | 可多次写入,断电丢失 | 开发调试 |
我个人觉得,Intel的“安全处理器”设计更合理。因为它把加解密任务从主配置逻辑里分离出来了。这样,即使攻击者破解了配置协议,也拿不到密钥。
3.4 避坑指南
最后,分享几个我踩过的坑:
- 不要用默认密钥:Xilinx和Intel的参考设计里,有时会带一个测试密钥。有人直接拿去量产。结果呢?所有用这个密钥的板子,都能被同一个比特流启动。这跟没加密一样。
- 注意密钥备份:eFUSE烧一次就没了。如果密钥丢了,芯片就变砖。我建议,在烧录前,至少做三次备份:一个存保险柜,一个存密码管理器,一个存离线硬盘。
- 小心JTAG后门:加密了比特流,但JTAG接口可能还是开放的。攻击者可以通过JTAG直接读取内部状态。所以,量产时一定要禁用JTAG,或者设置密码。
好了,这一章就到这里。下一章我会讲“密钥管理与分发”,那是整个安全体系的基石。咱们到时候见。