HARDWARE SECURITY

AES-128 RTL 初學者圖解

從 128-bit 資料流、Round 運算到控制 FSM,用圖解建立一套可以開始寫 RTL 的完整心智模型。

AES-128 RTL 初學者圖解

本文件用圖解說明 AES-128 加密器的資料流、各個 sub-block 的功能、模組連接方式,以及 RTL 控制流程。

1. 先認識 AES-128

AES-128 每次處理:

  • 一組 128-bit 明文(Plaintext)
  • 一把 128-bit 金鑰(Cipher Key)
  • 產生一組 128-bit 密文(Ciphertext)
  • 總共執行 10 個 rounds
AES-128 教學圖 1
教學圖 1 · 點圖可開啟原尺寸

AES-128 不是把 128 bits 當成一個大數字計算,而是先切成 16 個 bytes。

128 bits = 16 bytes

Plaintext = 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
              |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
             B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10...........B15

2. 初學者版 Top-Level 架構

AES-128 教學圖 2
教學圖 2 · 點圖可開啟原尺寸

Top-Level IO

訊號方向寬度功能
clkInput1系統時脈
rst_nInput1Active-low synchronous reset
key_validInput1表示 key_data 有效
key_readyOutput1核心可以接收新金鑰
key_dataInput128AES-128 cipher key
in_validInput1表示 in_data 有效
in_readyOutput1核心可以接收明文
in_dataInput128128-bit plaintext
out_validOutput1表示 out_data 有效
out_readyInput1下游可以接收密文
out_dataOutput128128-bit ciphertext
busyOutput1AES 正在運算

資料只有在 valid=1ready=1 的 clock edge 才真正被接收。

3. 完整 AES-128 加密流程

AES-128 教學圖 3
教學圖 3 · 點圖可開啟原尺寸

初學者只要先記住:

Round 0     = AddRoundKey
Round 1~9   = SubBytes + ShiftRows + MixColumns + AddRoundKey
Round 10    = SubBytes + ShiftRows + AddRoundKey

Final Round 不做 MixColumns

4. AES State 的 4 x 4 Byte 排列

AES 把 16 bytes 排成 4 rows x 4 columns,而且採用 column-major 排列。

128-bit input bytes:

 B0  B1  B2  B3  B4  B5  B6  B7  B8  B9 B10 B11 B12 B13 B14 B15

放入 AES State 後:

             Column 0   Column 1   Column 2   Column 3
Row 0           B0         B4         B8        B12
Row 1           B1         B5         B9        B13
Row 2           B2         B6        B10        B14
Row 3           B3         B7        B11        B15

對應 RTL bit mapping:

B0  = state[127:120]       B8  = state[63:56]
B1  = state[119:112]       B9  = state[55:48]
B2  = state[111:104]       B10 = state[47:40]
B3  = state[103:96]        B11 = state[39:32]
B4  = state[95:88]         B12 = state[31:24]
B5  = state[87:80]         B13 = state[23:16]
B6  = state[79:72]         B14 = state[15:8]
B7  = state[71:64]         B15 = state[7:0]

這個排列方式必須先固定,否則 ShiftRowsMixColumns 很容易接錯 byte。

5. 一個 Normal Round 的模組連接

AES-128 教學圖 4
教學圖 4 · 點圖可開啟原尺寸

aes_encrypt_round IO

module aes_encrypt_round (
    input  logic [127:0] state_i,
    input  logic [127:0] round_key_i,
    output logic [127:0] state_o
);

此模組是 combinational logic。輸入一個 state 和 round key,輸出完成一個 normal round 的新 state。

6. SubBytes:每個 Byte 查 S-box

AES-128 教學圖 5
教學圖 5 · 點圖可開啟原尺寸

功能

  • 將 128-bit state 分成 16 個 8-bit bytes。
  • 每個 byte 獨立通過同一張 AES S-box 查表。
  • 16 個 bytes 的位置不改變。
  • 16 個 S-box 可以平行運算。

IO

module aes_sub_bytes (
    input  logic [127:0] state_i,
    output logic [127:0] state_o
);

module aes_sbox (
    input  logic [7:0] data_i,
    output logic [7:0] data_o
);

小例子

S-box(8'h53) = 8'hED

輸入 byte  53
             |
          AES S-box
             |
輸出 byte  ED

7. ShiftRows:移動位置,不改變 Byte 數值

ShiftRows 前                          ShiftRows 後

 B0   B4   B8  B12                   B0   B4   B8  B12
 B1   B5   B9  B13       --->        B5   B9  B13   B1
 B2   B6  B10  B14                   B10 B14   B2   B6
 B3   B7  B11  B15                   B15  B3   B7  B11

 Row 0:左移 0 格
 Row 1:循環左移 1 格
 Row 2:循環左移 2 格
 Row 3:循環左移 3 格

RTL 接線觀念

AES-128 教學圖 6
教學圖 6 · 點圖可開啟原尺寸

IO

module aes_shift_rows (
    input  logic [127:0] state_i,
    output logic [127:0] state_o
);

ShiftRows 只需要重新接線,不需要 S-box、加法器、乘法器或 register。

8. MixColumns:每次混合一個 Column

MixColumns 將每個 column 內的 4 個 bytes 混合。四個 columns 彼此獨立,可以平行運算。

AES-128 教學圖 7
教學圖 7 · 點圖可開啟原尺寸

單一 Column 內部連接

輸入 Column                         輸出 Column

 a0 ---- x2 --+                    y0 = 2*a0 ^ 3*a1 ^ a2   ^ a3
 a1 ---- x3 --+--> XOR --> y0      y1 = a0   ^ 2*a1 ^ 3*a2 ^ a3
 a2 --------- +                    y2 = a0   ^ a1   ^ 2*a2 ^ 3*a3
 a3 --------- +                    y3 = 3*a0 ^ a1   ^ a2   ^ 2*a3

這裡的乘 2、乘 3是在有限體 GF(2^8) 中運算,不是一般整數乘法。

mul2(x) = xtime(x)
mul3(x) = xtime(x) XOR x

IO

module aes_mix_columns (
    input  logic [127:0] state_i,
    output logic [127:0] state_o
);

module aes_mix_one_column (
    input  logic [31:0] column_i,
    output logic [31:0] column_o
);

初學者記憶方式

  • ShiftRows:bytes 在不同 columns 之間移動。
  • MixColumns:把同一 column 內的 4 個 bytes 混合。
  • AES 標準沒有 MixRows 這個步驟。

9. AddRoundKey:State 與 Round Key 做 XOR

AES-128 教學圖 8
教學圖 8 · 點圖可開啟原尺寸

功能

state_o[127:0] = state_i[127:0] XOR round_key_i[127:0]

Byte 例子

State byte = 8'h53 = 0101_0011
Key byte   = 8'hCA = 1100_1010
                       ---------
Result     = 8'h99 = 1001_1001

IO

module aes_add_round_key (
    input  logic [127:0] state_i,
    input  logic [127:0] round_key_i,
    output logic [127:0] state_o
);

10. Final Round 的連接

AES-128 教學圖 9
教學圖 9 · 點圖可開啟原尺寸

Final Round 與 Normal Round 的唯一主要差別:

Normal Round:有 MixColumns
Final Round :沒有 MixColumns

11. AES-128 Key Expansion

原始 128-bit key 會被展開成 11 把 128-bit round keys。

AES-128 教學圖 10
教學圖 10 · 點圖可開啟原尺寸

一次 Key Expansion Step

將一把 128-bit key 分成四個 32-bit words:

key_i[127:0] = { w0, w1, w2, w3 }
AES-128 教學圖 11
教學圖 11 · 點圖可開啟原尺寸

計算式:

temp = SubWord(RotWord(w3)) XOR Rcon(round)

w4 = w0 XOR temp
w5 = w1 XOR w4
w6 = w2 XOR w5
w7 = w3 XOR w6

next_round_key = {w4, w5, w6, w7}

Key Expansion IO

module aes128_key_expand_step (
    input  logic [127:0] key_i,
    input  logic [3:0]   round_i,
    output logic [127:0] key_o
);

round_i 的有效範圍是 1 到 10。

12. Iterative RTL Datapath

為了讓初版面積較小,可以只放一套 AES Round 硬體,每個 clock 重複使用一次。

AES-128 教學圖 12
教學圖 12 · 點圖可開啟原尺寸

每個 Clock 做什麼

Clock 階段State Register 更新內容使用的 Key
接收輸入plaintext
Round 0plaintext XOR original_keyRound Key 0
Round 1Normal Round 結果Round Key 1
Round 2Normal Round 結果Round Key 2
Round 9Normal Round 結果Round Key 9
Round 10Final Round 結果Round Key 10
Output保持結果直到被接收

13. Controller FSM

AES-128 教學圖 13
教學圖 13 · 點圖可開啟原尺寸

狀態功能

FSM State功能
NO_KEY等待載入 128-bit key
READY已有 key,等待 plaintext
ROUND_0執行 initial AddRoundKey
NORMAL_ROUND依序執行 rounds 1 到 9
FINAL_ROUND執行 round 10,不做 MixColumns
OUTPUT_HOLDout_valid=1,保持密文直到 out_ready=1

14. Valid/Ready 握手圖

Clock       1       2       3       4       5
            |       |       |       |       |
in_valid    0_______/‾‾‾‾‾‾‾\_______________
in_ready    0_______/‾‾‾‾‾‾‾\_______________
                    ^
                    在此 clock edge 接收 plaintext


Clock       N      N+1     N+2     N+3
            |       |       |       |
out_valid   0_______/‾‾‾‾‾‾‾‾‾‾‾‾‾\____
out_ready   0_______________/‾‾‾‾‾\____
                            ^
                            在此 clock edge 傳送 ciphertext

out_valid=1out_ready=0

  • out_valid 必須保持為 1。
  • out_data 必須保持不變。
  • 核心停在 OUTPUT_HOLD

15. 建議的 RTL Module Hierarchy

AES-128 教學圖 14
教學圖 14 · 點圖可開啟原尺寸

在 RTL 中 aes_sub_bytes 可以由 normal round 和 final round 共用同一套 combinational logic;上圖主要用來表達功能階層。

16. 建議教學順序

  1. 先用一張圖說明 plaintext + key 產生 ciphertext。
  2. 解釋 128 bits 如何拆成 16 bytes 和 4 x 4 state。
  3. 只介紹四個基本積木:SubBytes、ShiftRows、MixColumns、AddRoundKey。
  4. 組合出 normal round。
  5. 說明 final round 少了 MixColumns。
  6. 再加入 key expansion。
  7. 最後才解釋 register、round counter、FSM 和 valid/ready。

17. 最小實作檢查表

  • State byte mapping 已明確定義。
  • SubBytes 有 16 個 byte substitutions。
  • ShiftRows 只做 byte permutation。
  • MixColumns 對 4 個 columns 分別運算。
  • AddRoundKey 是 128-bit XOR。
  • Key Expansion 能產生 Round Keys 1 到 10。
  • Rounds 1 到 9 有 MixColumns。
  • Round 10 沒有 MixColumns。
  • out_valid && !out_ready 時輸出保持不變。
  • 通過 FIPS-197 標準測試向量。

標準測試向量:

Key        = 000102030405060708090A0B0C0D0E0F
Plaintext  = 00112233445566778899AABBCCDDEEFF
Ciphertext = 69C4E0D86A7B0430D8CDB78070B4C55A