第28课:安全启动链

阶段五实战项目 — 安全启动链确保设备从上电到运行可信 OS 的每一步都经过验证。它是硬件信任根到软件信任链的桥梁。

1. 安全启动链的信任模型

安全启动的核心是信任链

Boot ROM → BL1 → BL2 → BL3 → OS → Application

每一步验证下一步的完整性和真实性,形成不可断裂的信任链。

2. 安全启动的组件

3. 安全启动控制器

✅Verilator验证通过
// 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

4. 反回滚保护

反回滚使用单调计数器(one-time programmable eFuse 或安全存储器)记录最低允许版本:

✅Verilator验证通过
// 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!");

🔧 Verilator 编译仿真完整流程

# 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!");

🔧 Verilator 编译仿真完整流程

# 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 偏重面积和能效,服务器偏重吞吐量。