第四章:物理安全防护——给FPGA穿上“防弹衣”
大家好,我是你们的FPGA安全讲师。今天咱们聊点硬核的——物理安全防护。
你想想看,金融交易系统里,FPGA跑着最核心的算法,处理着最敏感的数据。如果攻击者直接拿探针去戳芯片引脚,或者用激光照射芯片内部,会发生什么?嗯,后果不堪设想。
我做过一个项目,客户是某交易所。他们最担心的不是网络攻击,而是有人物理接触到设备。说白了,物理安全是最后一道防线。今天我就把我在这个领域踩过的坑、总结的经验,一次性讲清楚。
4.1 防篡改检测电路设计
防篡改检测,说白了就是给FPGA装个“防盗报警器”。一旦有人试图物理入侵,系统立刻响应。
核心思路:用一组传感器网络覆盖整个PCB和芯片封装。任何异常——比如钻孔、切割、探针接触——都会触发报警。
我常用的传感器类型:
- 网格传感器:在PCB顶层和底层走细密的蛇形线,一旦某条线被切断,电阻变化立刻被检测到。
- 电容传感器:监测芯片表面电容变化。有人靠近时,电容值会变。
- 光传感器:封装内部放光电二极管。一旦封装被打开,光线进入,立刻触发。
关键设计原则:检测电路必须独立于主系统供电。我曾经见过一个设计,检测电路和主系统共用电源——结果攻击者先切断电源,检测电路直接失效。血的教训。
来看一个简单的防篡改检测电路Verilog代码示例:
// 防篡改检测模块
module tamper_detector (
input wire clk,
input wire rst_n,
input wire [7:0] sensor_in, // 8路传感器输入
output reg tamper_alarm // 报警输出
);
reg [7:0] sensor_prev;
reg [31:0] debounce_cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
sensor_prev <= 8'h00;
tamper_alarm <= 1'b0;
debounce_cnt <= 32'h0;
end else begin
// 检测传感器状态变化
if (sensor_in != sensor_prev) begin
debounce_cnt <= debounce_cnt + 1;
if (debounce_cnt > 1000) begin // 消抖处理
tamper_alarm <= 1'b1;
end
end else begin
debounce_cnt <= 32'h0;
end
sensor_prev <= sensor_in;
end
end
endmodule
这段代码很简单,但有个细节要注意:消抖计数器。我遇到过误报的情况——因为电源噪声导致传感器信号抖动,结果系统频繁报警。加个消抖,世界清净了。
4.2 电压/温度/频率异常监测
攻击者有时候不会直接物理破坏,而是通过改变工作环境来诱导芯片出错。比如:
- 降低电压,让芯片进入亚稳态
- 升高温度,加速老化或触发热逃逸
- 改变时钟频率,导致时序违规
这些攻击手段,我统称为“环境攻击”。应对方法就是——实时监测,超标即报警。
监测参数及阈值:
| 参数 | 正常范围 | 报警阈值 | 响应动作 |
|---|---|---|---|
| 核心电压 | 0.95V - 1.05V | <0.90V 或 >1.10V | 触发安全销毁 |
| 芯片温度 | -40°C - 85°C | >100°C | 降频+报警 |
| 时钟频率 | 100MHz ± 1% | 偏差 > 5% | 切换备用时钟 |
我的经验:阈值不能设得太死。有一次在数据中心做测试,空调故障导致温度飙升到95°C,但芯片其实还能正常工作。如果阈值设在85°C,就会误触发。建议留10%的余量。
实现上,我习惯用FPGA内部的ADC(如果有的话)或者外挂专用监测芯片。Xilinx的7系列FPGA内部有XADC,可以直接读取电压和温度,非常方便。
4.3 主动屏蔽层技术
主动屏蔽层,这是物理防护的“天花板”技术。简单说,就是在芯片顶层金属上走一层密集的、随机化的导线网络。这些导线传输着伪随机序列。如果有人试图用聚焦离子束(FIB)修改芯片,或者用探针接触内部信号,屏蔽层会被破坏,伪随机序列中断,系统立刻报警。
设计要点:
- 随机化布线:屏蔽层的走线不能是规则的网格,否则攻击者可以预测并绕过。我一般用LFSR(线性反馈移位寄存器)生成随机路径。
- 多层屏蔽:至少两层,上下交错。单层屏蔽容易被FIB从侧面切入。
- 动态密钥:屏蔽层传输的序列要定期更换。我见过一个设计,序列固定不变——结果攻击者录下序列后,用信号发生器模拟,轻松绕过。
注意:主动屏蔽层会增加芯片面积和功耗。在金融交易系统中,我们通常只对存放密钥和核心算法的区域做屏蔽。全芯片屏蔽?成本太高,不现实。
下面是一个简单的屏蔽层监测逻辑:
// 主动屏蔽层监测
module shield_monitor (
input wire clk,
input wire shield_data_in, // 从屏蔽层读回的序列
output reg shield_ok // 屏蔽层状态
);
reg [31:0] lfsr;
wire expected_data;
// LFSR生成期望序列
always @(posedge clk) begin
if (!rst_n) begin
lfsr <= 32'hACE1; // 初始种子
end else begin
lfsr <= {lfsr[30:0], lfsr[31] ^ lfsr[21] ^ lfsr[1] ^ lfsr[0]};
end
end
assign expected_data = lfsr[31];
// 比较实际数据和期望数据
always @(posedge clk) begin
if (shield_data_in != expected_data) begin
shield_ok <= 1'b0; // 屏蔽层被破坏
end else begin
shield_ok <= 1'b1;
end
end
endmodule
这段代码里,LFSR的种子(ACE1)是随机选的。实际项目中,种子应该从物理不可克隆函数(PUF)中派生,这样每个芯片的序列都不同。
4.4 安全销毁机制
最后,也是最极端的手段——安全销毁。当检测到不可逆的物理攻击时,系统必须能在极短时间内销毁所有敏感数据。
销毁方式对比:
| 方式 | 销毁时间 | 可恢复性 | 适用场景 |
|---|---|---|---|
| 密钥覆写 | <1ms | 不可恢复 | 所有场景 |
| 熔断保险丝 | <10ms | 不可恢复 | 一次性编程器件 |
| 化学腐蚀 | 几分钟 | 不可恢复 | 极端安全需求 |
| 物理粉碎 | 几秒 | 不可恢复 | 军用级 |
在金融交易系统中,我们最常用的是密钥覆写。具体做法:
- 将密钥存储在易失性存储器(如BRAM)中
- 检测到攻击时,立即切断BRAM的供电
- 同时用伪随机数反复覆写BRAM内容
关键点:销毁动作必须由独立硬件触发,不能依赖软件。我见过一个设计,销毁逻辑跑在CPU上——结果攻击者先冻结CPU,销毁指令根本没发出去。从那以后,我所有销毁逻辑都用纯硬件状态机实现。
下面是一个安全销毁状态机的简化版:
// 安全销毁状态机
module secure_wipe (
input wire clk,
input wire wipe_trigger, // 来自检测电路的触发信号
output reg [7:0] addr, // BRAM地址
output reg [31:0] data, // 覆写数据
output reg wipe_done // 销毁完成标志
);
typedef enum {IDLE, WIPE, DONE} state_t;
state_t state;
always @(posedge clk) begin
case (state)
IDLE: begin
if (wipe_trigger) begin
state <= WIPE;
addr <= 8'h00;
end
end
WIPE: begin
if (addr == 8'hFF) begin
state <= DONE;
wipe_done <= 1'b1;
end else begin
data <= $random; // 伪随机数覆写
addr <= addr + 1;
end
end
DONE: begin
// 保持完成状态,直到系统复位
end
endcase
end
endmodule
这段代码里,我用$random生成伪随机数。实际项目中,我会用真随机数发生器(TRNG)来生成覆写数据,确保不可预测。
知识体系总览
说了这么多,我画了一张图来总结本章的核心逻辑。你看完应该能对物理安全防护有个整体认识。
这张图把四个防护手段串起来了。你看,它们不是孤立的,而是层层递进的关系。防篡改检测是第一道门,环境监测是第二道,主动屏蔽是第三道,安全销毁是最后的手段。
我的建议:在实际项目中,不要试图把所有防护手段都用上。根据你的威胁模型来选择。比如,如果设备部署在安全机房,物理接触风险低,那么主动屏蔽层可以省略。但如果设备暴露在公共场所,那所有手段都得用上。
好了,物理安全防护就讲到这里。下一章我们会聊逻辑安全防护——如何在FPGA内部防止逻辑攻击。嗯,那又是另一个故事了。
公众号:蓝海资料掘金营,微信deep3321