第四章:物理安全防护——给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物理安全防护体系 物理安全防护 防篡改检测电路 电压/温度/频率监测 主动屏蔽层技术 安全销毁机制 网格传感器 电容传感器 光传感器 电压监测 温度监测 频率监测 随机化布线 多层屏蔽 动态密钥 密钥覆写 熔断保险丝 化学腐蚀 核心设计原则 独立供电 | 硬件触发 | 冗余检测 | 不可恢复

这张图把四个防护手段串起来了。你看,它们不是孤立的,而是层层递进的关系。防篡改检测是第一道门,环境监测是第二道,主动屏蔽是第三道,安全销毁是最后的手段。

我的建议:在实际项目中,不要试图把所有防护手段都用上。根据你的威胁模型来选择。比如,如果设备部署在安全机房,物理接触风险低,那么主动屏蔽层可以省略。但如果设备暴露在公共场所,那所有手段都得用上。

好了,物理安全防护就讲到这里。下一章我们会聊逻辑安全防护——如何在FPGA内部防止逻辑攻击。嗯,那又是另一个故事了。


公众号:蓝海资料掘金营,微信deep3321