阶段五实战项目 — AES-GCM 是 TLS 1.3 的核心 AEAD 方案。它结合 AES-CTR 加密和 GHASH 认证,提供同时保密和完整性保护。
GCM(Galois/Counter Mode)提供认证加密:
其中 H = AES_K(0¹²⁸) 是哈希子密钥。
GHASH 在 GF(2¹²⁸) 上运算,使用多项式 x¹²⁸ + x⁷ + x² + x + 1:
// ghash.v - GHASH 乘法模块
module ghash_mul (
input wire [127:0] x,
input wire [127:0] h,
output wire [127:0] y
);
// GF(2^128) 乘法,多项式 x^128 + x^7 + x^2 + x + 1
// 使用移位+条件约减法
reg [255:0] product;
reg [127:0] result;
integer i;
// 简化实现:先做 128 位乘法,再模约减
always @(*) begin
product = 256'h0;
for (i = 0; i < 128; i = i + 1) begin
if (x[i])
product = product ^ (h << i);
end
// 模约减:x^128 = x^7 + x^2 + x + 1
result = product[127:0];
for (i = 255; i >= 128; i = i - 1) begin
if (product[i]) begin
result[i-128] = result[i-128] ^ 1'b1;
result[i-128+7] = result[i-128+7] ^ 1'b1;
result[i-128+2] = result[i-128+2] ^ 1'b1;
result[i-128+1] = result[i-128+1] ^ 1'b1;
end
end
end
assign y = result;
endmodule
// aes_gcm.v - AES-GCM 引擎(简化版)
module aes_gcm (
input wire clk,
input wire rst_n,
input wire start,
input wire [127:0] key,
input wire [95:0] iv, // 96位初始向量
input wire [127:0] plaintext,
input wire [127:0] aad, // 附加认证数据
input wire last_block,
output reg [127:0] ciphertext,
output reg [127:0] auth_tag,
output reg tag_valid
);
// 状态机
localparam S_IDLE=0, S_INIT=1, S_ENCRYPT=2, S_HASH=3, S_TAG=4;
reg [2:0] state;
// 计数器
reg [31:0] ctr;
// GHASH 累积器
reg [127:0] ghash_state;
reg [127:0] hash_key; // H = AES_K(0)
// AES 加密实例(简化)
reg aes_start;
reg [127:0] aes_pt, aes_key;
wire [127:0] aes_ct;
wire aes_valid;
aes128_enc u_aes (
.clk(clk), .rst_n(rst_n), .start(aes_start),
.plaintext(aes_pt), .key(aes_key),
.ciphertext(aes_ct), .valid(aes_valid), .busy()
);
// GHASH 乘法实例
wire [127:0] ghash_out;
ghash_mul u_ghash (.x(ghash_state), .h(hash_key), .y(ghash_out));
// 密钥流
reg [127:0] key_stream;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= S_IDLE; ctr <= 0;
ghash_state <= 0; hash_key <= 0;
ciphertext <= 0; auth_tag <= 0; tag_valid <= 0;
aes_start <= 0; key_stream <= 0;
end else begin
aes_start <= 0;
tag_valid <= 0;
case (state)
S_IDLE: if (start) begin
// 计算 H = AES_K(0^128)
aes_pt <= 128'h0; aes_key <= key;
aes_start <= 1;
ctr <= 32'd1; // 计数器从1开始
state <= S_INIT;
end
S_INIT: if (aes_valid) begin
hash_key <= aes_ct; // H
// 计算初始密钥流
aes_pt <= {iv, 32'd1}; // J0
aes_key <= key;
aes_start <= 1;
ghash_state <= 0;
state <= S_ENCRYPT;
end
S_ENCRYPT: if (aes_valid) begin
key_stream <= aes_ct;
ciphertext <= plaintext ^ aes_ct;
// GHASH: 处理密文块
ghash_state <= ghash_out ^ ciphertext;
if (last_block) begin
// 处理 AAD 的 GHASH(简化:假设只有一块 AAD)
state <= S_HASH;
end else begin
ctr <= ctr + 1;
aes_pt <= {iv, ctr + 1};
aes_key <= key;
aes_start <= 1;
end
end
S_HASH: begin
// 包含长度信息的最终 GHASH
ghash_state <= ghash_out ^ {64'h0, 64'd128}; // 简化
state <= S_TAG;
end
S_TAG: begin
// 认证标签 = GHASH ⊕ AES_K(J0)
auth_tag <= ghash_out ^ key_stream;
tag_valid <= 1;
state <= S_IDLE;
end
endcase
end
end
endmodule
1. 验证 AES-GCM 的 NIST 测试向量(Test Case 1-4)。
2. 优化 GF(2¹²⁸) 乘法:实现 Karatsuba 分解,减少关键路径延迟。
3. 实现完整的 AES-GCM 解密和验证:解密后重新计算标签并比较。
4. 安全分析:如果 IV 重复使用,AES-GCM 的安全性如何被破坏?
你已实现 AES-GCM 认证加密引擎,掌握 GHASH 和 GF(2¹²⁸) 乘法。AES-GCM 是现代网络安全的核心协议!
获得徽章:🔐 AEAD_PIONEER
推荐使用以下工具链进行课程实践:
# 安装 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 偏重面积和能效,服务器偏重吞吐量。