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系列开始,就支持了。

流程是这样的:

  1. 在Vivado里生成加密比特流时,需要指定一个密钥文件(.nky)。
  2. 这个密钥会被烧录到FPGA内部的eFUSE或BBRAM(电池备份RAM)里。
  3. 上电后,FPGA先从外部读取加密的比特流,然后用内部密钥解密,再加载。

这里有个关键点:密钥存储在哪里?

  • eFUSE:一次性编程,不可逆。适合量产场景。但一旦烧错,芯片就废了。我有个同事就干过这事,烧错了密钥,整批芯片报废。
  • BBRAM:可多次写入,但断电后需要电池保持。适合开发调试。不过电池会没电,所以产品里我一般不建议用。

Xilinx还支持“HMAC认证”。说白了,就是在加密的基础上再加一层校验。防止有人篡改加密后的比特流。我建议,只要条件允许,就把HMAC打开。多一层保护,多一分安全。

3.3.2 Intel的加密方案

Intel的方案叫“配置安全特性”,也是用AES-256。但它的实现方式有点不一样。

Intel的FPGA内部有一个“安全处理器”,专门负责解密和认证。这个处理器是独立的,不占用用户逻辑。所以,即使你的设计跑飞了,安全处理器还在正常工作。

Intel支持两种密钥存储方式:

存储方式 特点 适用场景
熔丝(Fuse) 一次性编程,不可逆 量产产品
安全RAM 可多次写入,断电丢失 开发调试

我个人觉得,Intel的“安全处理器”设计更合理。因为它把加解密任务从主配置逻辑里分离出来了。这样,即使攻击者破解了配置协议,也拿不到密钥。

提示: 无论用哪家的方案,密钥管理都是最头疼的。我见过很多公司,密钥就写在代码注释里,或者存在SVN上。这等于把钥匙挂在门上。建议使用专门的密钥管理芯片,或者至少把密钥分散存储。

3.4 避坑指南

最后,分享几个我踩过的坑:

  • 不要用默认密钥:Xilinx和Intel的参考设计里,有时会带一个测试密钥。有人直接拿去量产。结果呢?所有用这个密钥的板子,都能被同一个比特流启动。这跟没加密一样。
  • 注意密钥备份:eFUSE烧一次就没了。如果密钥丢了,芯片就变砖。我建议,在烧录前,至少做三次备份:一个存保险柜,一个存密码管理器,一个存离线硬盘。
  • 小心JTAG后门:加密了比特流,但JTAG接口可能还是开放的。攻击者可以通过JTAG直接读取内部状态。所以,量产时一定要禁用JTAG,或者设置密码。

好了,这一章就到这里。下一章我会讲“密钥管理与分发”,那是整个安全体系的基石。咱们到时候见。