3、网表基础知识回顾:综合网表结构、标准单元库、网表文件格式
各位同学,咱们今天聊网表。说实话,网表这东西,在硬件安全领域就是个“照妖镜”。你设计的RTL代码再花哨,综合成网表之后,所有逻辑都摊在台面上了。后门检测,说白了就是在这张“摊开的牌”里找猫腻。
我个人习惯把网表比作芯片的“骨架”。RTL是设计意图,网表就是具体实现。你想想看,一个后门要是藏在RTL里,可能还能用代码风格掩饰一下。但到了网表层面,每个门、每条连线都清清楚楚,想藏东西?难度大得多。
3.1 综合网表结构
综合网表,就是EDA工具把RTL代码“翻译”成标准单元库里的元件后,生成的连接关系描述。它长什么样?我直接给你看个例子。
module top (clk, rst, data_in, data_out);
input clk, rst;
input [7:0] data_in;
output [7:0] data_out;
wire [7:0] n1, n2;
wire n3;
DFFRQX1 \reg_out_reg[0] (.D(n2[0]), .CK(clk), .RN(rst), .Q(data_out[0]));
DFFRQX1 \reg_out_reg[1] (.D(n2[1]), .CK(clk), .RN(rst), .Q(data_out[1]));
// ... 省略中间连线
AND2X1 U1 (.A(data_in[0]), .B(n3), .Y(n1[0]));
INVX1 U2 (.A(n1[0]), .Y(n2[0]));
endmodule
看到了吗?这就是综合后的网表。它由三部分组成:端口声明、内部连线(wire)、实例化单元。每个实例化单元,比如DFFRQX1、AND2X1,都是标准单元库里的“积木块”。
核心要点:网表结构是层次化的。顶层模块调用底层模块,底层模块再调用标准单元。后门检测时,我们重点关注的是那些“不该出现的连线”或“异常的逻辑锥”。
我在项目中遇到过一种情况:攻击者在网表里偷偷加了一个“额外”的触发器,平时不工作,只在特定温度或电压下才激活。这种后门,光看RTL根本发现不了,但网表里多出来的那个DFF,就是铁证。
3.2 标准单元库
标准单元库,说白了就是芯片设计的“乐高积木”。里面有与门、或门、非门、触发器、锁存器等等。每个单元都有固定的功能、面积、功耗、时序参数。
为什么后门检测要懂标准单元库?因为攻击者可能会篡改标准单元本身。比如,把一个正常的“与门”改成“与或门”,或者给触发器加一个“隐藏的置位端”。
| 单元类型 | 常见名称 | 功能描述 | 后门风险 |
|---|---|---|---|
| 组合逻辑 | AND2X1, OR2X1, INVX1 | 基本布尔运算 | 功能被篡改(如AND变OR) |
| 时序逻辑 | DFFRQX1, DFFSQX2 | 带复位/置位的触发器 | 增加隐藏复位或时钟门控 |
| 特殊单元 | TIEH, TIEL, DELAY | 固定电平、延迟单元 | 用于构造“时间炸弹”后门 |
我的经验:检查标准单元库时,我习惯先看“非常用单元”。比如,一个设计里突然出现了大量DELAY单元,或者TIEH/TIEL的使用方式很奇怪,那就要警惕了。我曾经在一个项目里发现,攻击者用TIEH和AND2X1组合,构造了一个“永远为真”的条件,从而绕过了关键的安全校验。
3.3 网表文件格式
网表文件格式有好几种,咱们做后门检测,至少得认识三种:Verilog网表、EDIF、Liberty。每种格式的“脾气”不一样,解析方法也不同。
3.3.1 Verilog网表
这个最常见。就是上面代码示例那种格式。可读性好,适合人工审查。但缺点是文件体积大,尤其是几百万门的芯片,打开一个网表文件,电脑都能卡半天。
Verilog网表里,我特别关注assign语句和always块。正常情况下,综合工具生成的网表里,assign应该很少,always块更是几乎绝迹。如果看到大量always块,那八成是有人手动修改过网表。
3.3.2 EDIF格式
EDIF(Electronic Design Interchange Format)是一种中间格式。说白了,它是为了不同EDA工具之间交换数据用的。EDIF文件长这样:
(edif top
(edifVersion 2 0 0)
(cell top
(cellType GENERIC)
(view netlist
(viewType NETLIST)
(interface
(port clk (direction INPUT))
(port rst (direction INPUT))
(port data_in (direction INPUT))
(port data_out (direction OUTPUT))
)
(contents
(instance reg_out_reg_0
(cellRef DFFRQX1)
)
(net n1
(joined
(portRef data_in)
(portRef A (instanceRef U1))
)
)
)
)
)
)
EDIF的优点是标准化程度高,缺点是“啰嗦”。同样的逻辑,Verilog可能一行搞定,EDIF要写十几行。解析EDIF时,我建议用专门的解析库,别自己手写正则,容易出bug。
避坑指南:我曾经手写过一个EDIF解析器,结果被一个嵌套了8层的括号结构搞崩溃了。后来老老实实用了开源库。记住:不要重复造轮子,除非你想体验“括号地狱”。
3.3.3 Liberty格式
Liberty(.lib)文件不是网表,而是标准单元库的时序和功耗描述文件。它告诉EDA工具:每个单元在不同输入转换时间、输出负载下的延迟是多少,功耗是多少。
为什么后门检测要懂Liberty?因为攻击者可能会修改Liberty文件里的时序参数。比如,把一个关键路径上的单元延迟改小,让静态时序分析(STA)误以为时序满足要求,但实际上芯片流片后根本跑不到目标频率。
cell (AND2X1) {
area : 5.6;
pin (A) {
direction : input;
capacitance : 0.002;
}
pin (Y) {
direction : output;
function : "A & B";
timing () {
related_pin : "A";
timing_type : combinational;
cell_rise (delay_template_7x7) {
index_1 ("0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3");
index_2 ("0.01, 0.02, 0.05, 0.1, 0.2, 0.4, 0.8");
values ( \
"0.05, 0.08, 0.12, 0.18, 0.25, 0.35, 0.50", \
"0.06, 0.09, 0.13, 0.19, 0.26, 0.36, 0.51", \
// ... 省略
);
}
}
}
}
你看,Liberty文件里每个单元的延迟都是一个二维查找表。攻击者要是把某个cell_rise值改小0.1ns,在几百万门的芯片上,STA根本查不出来。但实际芯片可能就因为这条路径的时序违规,导致功能异常。
3.4 知识体系总览
为了让你更直观地理解这三者的关系,我画了一张图。你可以把它当作本章的“思维导图”。
这张图把本章的三个核心知识点串起来了。你记住:综合网表结构是“骨架”,标准单元库是“血肉”,网表文件格式是“皮囊”。后门检测,就是透过皮囊看血肉,再通过血肉分析骨架,最终找出那些“不该存在的东西”。
嗯,今天就先聊到这儿。网表这块内容多,但都是基础。基础不牢,地动山摇。后面咱们讲后门检测的具体方法时,你会频繁用到今天这些知识。