阶段五实战项目 — 安全启动链确保设备从上电到运行可信 OS 的每一步都经过验证。它是硬件信任根到软件信任链的桥梁。
安全启动的核心是信任链:
每一步验证下一步的完整性和真实性,形成不可断裂的信任链。
// secure_boot.v - 安全启动控制器
module secure_boot #(
parameter HASH_WIDTH = 256,
parameter SIG_WIDTH = 256
)(
input wire clk,
input wire rst_n,
input wire boot_start,
// 固件接口
input wire [31:0] fw_data,
input wire [31:0] fw_addr,
input wire fw_valid,
input wire fw_last,
// 签名接口
input wire [SIG_WIDTH-1:0] signature,
input wire sig_valid,
// 公钥哈希(存储在 eFuse 中)
input wire [HASH_WIDTH-1:0] root_key_hash,
// 输出
output reg boot_ok,
output reg boot_fail,
output reg [HASH_WIDTH-1:0] computed_hash,
output reg [31:0] fw_version,
output reg [31:0] min_version // 反回滚计数器
);
localparam S_IDLE=0, S_HASH=1, S_VERIFY=2, S_VERSION=3, S_DONE=4, S_FAIL=5;
reg [2:0] state;
reg [HASH_WIDTH-1:0] hash_acc;
// SHA-256 实例
reg sha_start, sha_block_valid, sha_last;
reg [511:0] sha_block;
wire [HASH_WIDTH-1:0] sha_digest;
wire sha_valid;
sha256_engine u_sha (
.clk(clk), .rst_n(rst_n), .start(sha_start),
.block(sha_block), .block_valid(sha_block_valid),
.last_block(sha_last),
.digest(sha_digest), .digest_valid(sha_valid)
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= S_IDLE; boot_ok <= 0; boot_fail <= 0;
computed_hash <= 0; hash_acc <= 0;
fw_version <= 0;
end else begin
case (state)
S_IDLE: if (boot_start) begin
boot_ok <= 0; boot_fail <= 0;
hash_acc <= 0;
sha_start <= 1;
state <= S_HASH;
end
S_HASH: begin
sha_start <= 0;
if (fw_valid) begin
sha_block <= {fw_data, 480'h0}; // 填充
sha_block_valid <= 1;
sha_last <= fw_last;
end else begin
sha_block_valid <= 0;
sha_last <= 0;
end
if (sha_valid) begin
hash_acc <= sha_digest;
computed_hash <= sha_digest;
state <= S_VERIFY;
end
end
S_VERIFY: begin
// 简化:比较哈希值与预期值
// 实际需要 RSA/ECC 签名验证
if (sig_valid) begin
state <= S_VERSION;
end
end
S_VERSION: begin
// 反回滚检查
if (fw_version >= min_version) begin
min_version <= fw_version + 1;
boot_ok <= 1;
state <= S_DONE;
end else begin
boot_fail <= 1;
state <= S_FAIL;
end
end
S_DONE: begin
// 启动成功
end
S_FAIL: begin
// 启动失败,系统停机
end
endcase
end
end
endmodule
反回滚使用单调计数器(one-time programmable eFuse 或安全存储器)记录最低允许版本:
// anti_rollback.v - 反回滚计数器
module anti_rollback #(
parameter VERSION_WIDTH = 32
)(
input wire clk,
input wire rst_n,
input wire update_en,
input wire [VERSION_WIDTH-1:0] new_version,
output reg [VERSION_WIDTH-1:0] current_min,
output wire rollback_detected
);
// 单调计数器:只能递增
assign rollback_detected = (new_version < current_min) && update_en;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
current_min <= 0;
end else if (update_en && !rollback_detected) begin
if (new_version > current_min)
current_min <= new_version;
end
end
endmodule
1. 实现完整的 RSA 签名验证模块:SHA-256 哈希 → RSA 公钥验证。
2. 设计多级启动链:BootROM → SPL → U-Boot → Linux,每级验证下一级。
3. 实现固件回滚恢复:如果更新失败,自动回退到上一个已知好的版本。
4. 安全分析:如果 Boot ROM 中硬编码的根公钥被攻破,如何恢复信任?
你已设计安全启动控制器,实现固件验证和反回滚保护。安全启动是设备安全的根基!
获得徽章:⛓️ TRUST_CHAIN
推荐使用以下工具链进行课程实践:
# 安装 Verilator
sudo apt install verilator
# 安装 Icarus Verilog(可选)
sudo apt install iverilog
# 安装 GTKWave(波形查看器)
sudo apt install gtkwave
# 验证安装
verilator --lint-only --version
iverilog -V
密码学硬件实现的关键性能指标:
这些指标之间通常存在 trade-off,设计时需根据应用场景权衡。
本课涉及的核心概念和技术关系:
Verilog 仿真调试的常用方法:
// 调试示例
initial begin
$dumpfile("sim.vcd");
$dumpvars(0, uut);
end
// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
else $error("Invalid data when valid!");
# 1. 语法检查
verilator --lint-only module.v
# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
Vmodule* top = new Vmodule;
top->clk = 0; top->rst_n = 0;
top->eval();
top->rst_n = 1;
for (int i = 0; i < 100; i++) {
top->clk = !top->clk;
top->eval();
}
delete top;
return 0;
}
EOF
# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk
# 4. 运行
./obj_dir/Vmodule
密码硬件的性能评估维度:
| 指标 | 单位 | 说明 |
|---|---|---|
| 面积 | GE / LUT | 等效门数或查找表数量 |
| 频率 | MHz | 最大时钟频率 |
| 吞吐量 | Gbps | 每秒处理的数据量 |
| 延迟 | 周期数 | 从输入到输出的周期 |
| 能效 | pJ/bit | 每比特能耗 |
| 面积效率 | Gbps/GE | 单位面积吞吐量 |
不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。
本课涉及的核心概念和技术关系:
Verilog 仿真调试的常用方法:
// 调试示例
initial begin
$dumpfile("sim.vcd");
$dumpvars(0, uut);
end
// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
else $error("Invalid data when valid!");
# 1. 语法检查
verilator --lint-only module.v
# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
Vmodule* top = new Vmodule;
top->clk = 0; top->rst_n = 0;
top->eval();
top->rst_n = 1;
for (int i = 0; i < 100; i++) {
top->clk = !top->clk;
top->eval();
}
delete top;
return 0;
}
EOF
# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk
# 4. 运行
./obj_dir/Vmodule
密码硬件的性能评估维度:
| 指标 | 单位 | 说明 |
|---|---|---|
| 面积 | GE / LUT | 等效门数或查找表数量 |
| 频率 | MHz | 最大时钟频率 |
| 吞吐量 | Gbps | 每秒处理的数据量 |
| 延迟 | 周期数 | 从输入到输出的周期 |
| 能效 | pJ/bit | 每比特能耗 |
| 面积效率 | Gbps/GE | 单位面积吞吐量 |
不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。