aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoachim StroĢˆmbergson <joachim@secworks.se>2018-05-22 11:18:35 +0200
committerJoachim StroĢˆmbergson <joachim@secworks.se>2018-05-22 11:18:35 +0200
commita689dccc34edcc6b955c9b522bb141e32c871add (patch)
tree13a0554d23fdea8d0edd5c552144ff7e7ddb6431
parentea98bf78abd32420b803ba2f67e264c89ee98077 (diff)
Combined all AES round operations into a single operation for a round.
-rw-r--r--README.md11
-rw-r--r--src/rtl/aes_decipher_block.v102
-rw-r--r--src/rtl/aes_encipher_block.v99
-rw-r--r--src/tb/tb_aes.v1
-rw-r--r--src/tb/tb_aes_decipher_block.v5
-rw-r--r--src/tb/tb_aes_encipher_block.v9
6 files changed, 61 insertions, 166 deletions
diff --git a/README.md b/README.md
index 6ce5f4b..aa2e14e 100644
--- a/README.md
+++ b/README.md
@@ -40,10 +40,11 @@ the total number of S-boxes is 20.
## Performance comparison
Number of cycles for the old Cryptech AES core:
- AES-128 Encipher one block with key expansion: 57
-
+- AES-256 Decipher one block with key expansion: 77
Number of cycles for the Cryptech AES speed core:
-- AES-128 Encipher with key expansion: 27
+- AES-128 Encipher one block with key expansion: 17
+- AES-255 Decipher one block with key expansion: 21
## Implementation comparison
@@ -56,8 +57,6 @@ Old Cryptech AES core:
Cryptec AES speed core:
-- 2019 slices
+- 2076 slices
- 2984 regs
-- 131 MHz. (7.58ns)
-
-Surprisingly, the number of slices actually decreases.
+- 117 MHz. (8.54ns)
diff --git a/src/rtl/aes_decipher_block.v b/src/rtl/aes_decipher_block.v
index c2304d6..ce34cc8 100644
--- a/src/rtl/aes_decipher_block.v
+++ b/src/rtl/aes_decipher_block.v
@@ -72,9 +72,8 @@ module aes_decipher_block(
localparam CTRL_IDLE = 3'h0;
localparam CTRL_INIT = 3'h1;
- localparam CTRL_SBOX = 3'h2;
- localparam CTRL_MAIN = 3'h3;
- localparam CTRL_FINAL = 3'h4;
+ localparam CTRL_MAIN = 3'h2;
+ localparam CTRL_FINAL = 3'h3;
//----------------------------------------------------------------
@@ -192,22 +191,16 @@ module aes_decipher_block(
//----------------------------------------------------------------
// Registers including update variables and write enable.
//----------------------------------------------------------------
+ reg [127 : 0] block_reg;
+ reg [127 : 0] block_new;
+ reg block_we;
+
reg [3 : 0] round_ctr_reg;
reg [3 : 0] round_ctr_new;
reg round_ctr_we;
reg round_ctr_set;
reg round_ctr_dec;
- reg [127 : 0] block_new;
- reg [31 : 0] block_w0_reg;
- reg [31 : 0] block_w1_reg;
- reg [31 : 0] block_w2_reg;
- reg [31 : 0] block_w3_reg;
- reg block_w0_we;
- reg block_w1_we;
- reg block_w2_we;
- reg block_w3_we;
-
reg ready_reg;
reg ready_new;
reg ready_we;
@@ -243,8 +236,8 @@ module aes_decipher_block(
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
+ assign new_block = block_reg;
assign round = round_ctr_reg;
- assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
assign ready = ready_reg;
@@ -259,27 +252,15 @@ module aes_decipher_block(
begin: reg_update
if (!reset_n)
begin
- block_w0_reg <= 32'h0;
- block_w1_reg <= 32'h0;
- block_w2_reg <= 32'h0;
- block_w3_reg <= 32'h0;
+ block_reg <= 128'h0;
round_ctr_reg <= 4'h0;
ready_reg <= 1'b1;
dec_ctrl_reg <= CTRL_IDLE;
end
else
begin
- if (block_w0_we)
- block_w0_reg <= block_new[127 : 096];
-
- if (block_w1_we)
- block_w1_reg <= block_new[095 : 064];
-
- if (block_w2_we)
- block_w2_reg <= block_new[063 : 032];
-
- if (block_w3_we)
- block_w3_reg <= block_new[031 : 000];
+ if (block_we)
+ block_reg <= block_new;
if (round_ctr_we)
round_ctr_reg <= round_ctr_new;
@@ -300,68 +281,43 @@ module aes_decipher_block(
//----------------------------------------------------------------
always @*
begin : round_logic
- reg [127 : 0] old_block, inv_shiftrows_block, inv_mixcolumns_block;
+ reg [127 : 0] subbytes_block, inv_shiftrows_block, inv_mixcolumns_block;
reg [127 : 0] addkey_block;
inv_shiftrows_block = 128'h0;
inv_mixcolumns_block = 128'h0;
addkey_block = 128'h0;
block_new = 128'h0;
- block_w0_we = 1'b0;
- block_w1_we = 1'b0;
- block_w2_we = 1'b0;
- block_w3_we = 1'b0;
+ block_we = 1'b0;
- sboxw0 = block_w0_reg;
- sboxw1 = block_w1_reg;
- sboxw2 = block_w2_reg;
- sboxw3 = block_w3_reg;
+ sboxw0 = block_reg[127 : 96];
+ sboxw1 = block_reg[95 : 64];
+ sboxw2 = block_reg[63 : 32];
+ sboxw3 = block_reg[31 : 0];
+ subbytes_block = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3};
- old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
-
- // Update based on update type.
case (update_type)
- // InitRound
INIT_UPDATE:
begin
- old_block = block;
- addkey_block = addroundkey(old_block, round_key);
+ addkey_block = addroundkey(block, round_key);
inv_shiftrows_block = inv_shiftrows(addkey_block);
block_new = inv_shiftrows_block;
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
- end
-
- SBOX_UPDATE:
- begin
- block_new = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3};
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
+ block_we = 1'b1;
end
MAIN_UPDATE:
begin
- addkey_block = addroundkey(old_block, round_key);
+ addkey_block = addroundkey(subbytes_block, round_key);
inv_mixcolumns_block = inv_mixcolumns(addkey_block);
inv_shiftrows_block = inv_shiftrows(inv_mixcolumns_block);
block_new = inv_shiftrows_block;
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
+ block_we = 1'b1;
end
FINAL_UPDATE:
begin
- block_new = addroundkey(old_block, round_key);
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
+ block_new = addroundkey(subbytes_block, round_key);
+ block_we = 1'b1;
end
default:
@@ -431,15 +387,8 @@ module aes_decipher_block(
CTRL_INIT:
begin
- update_type = INIT_UPDATE;
- dec_ctrl_new = CTRL_SBOX;
- dec_ctrl_we = 1'b1;
- end
-
- CTRL_SBOX:
- begin
- update_type = SBOX_UPDATE;
round_ctr_dec = 1'b1;
+ update_type = INIT_UPDATE;
dec_ctrl_new = CTRL_MAIN;
dec_ctrl_we = 1'b1;
end
@@ -448,9 +397,8 @@ module aes_decipher_block(
begin
if (round_ctr_reg > 0)
begin
+ round_ctr_dec = 1'b1;
update_type = MAIN_UPDATE;
- dec_ctrl_new = CTRL_SBOX;
- dec_ctrl_we = 1'b1;
end
else
begin
diff --git a/src/rtl/aes_encipher_block.v b/src/rtl/aes_encipher_block.v
index f0e42f9..8cac95f 100644
--- a/src/rtl/aes_encipher_block.v
+++ b/src/rtl/aes_encipher_block.v
@@ -66,9 +66,8 @@ module aes_encipher_block(
localparam NO_UPDATE = 3'h0;
localparam INIT_UPDATE = 3'h1;
- localparam SBOX_UPDATE = 3'h2;
- localparam MAIN_UPDATE = 3'h3;
- localparam FINAL_UPDATE = 3'h4;
+ localparam MAIN_UPDATE = 3'h2;
+ localparam FINAL_UPDATE = 3'h3;
localparam CTRL_IDLE = 3'h0;
localparam CTRL_INIT = 3'h1;
@@ -156,22 +155,16 @@ module aes_encipher_block(
//----------------------------------------------------------------
// Registers including update variables and write enable.
//----------------------------------------------------------------
+ reg [127 : 0] block_reg;
+ reg [127 : 0] block_new;
+ reg block_we;
+
reg [3 : 0] round_ctr_reg;
reg [3 : 0] round_ctr_new;
reg round_ctr_we;
reg round_ctr_rst;
reg round_ctr_inc;
- reg [127 : 0] block_new;
- reg [31 : 0] block_w0_reg;
- reg [31 : 0] block_w1_reg;
- reg [31 : 0] block_w2_reg;
- reg [31 : 0] block_w3_reg;
- reg block_w0_we;
- reg block_w1_we;
- reg block_w2_we;
- reg block_w3_we;
-
reg ready_reg;
reg ready_new;
reg ready_we;
@@ -199,8 +192,8 @@ module aes_encipher_block(
//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
+ assign new_block = block_reg;
assign round = round_ctr_reg;
- assign new_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
assign ready = ready_reg;
@@ -224,27 +217,15 @@ module aes_encipher_block(
begin: reg_update
if (!reset_n)
begin
- block_w0_reg <= 32'h0;
- block_w1_reg <= 32'h0;
- block_w2_reg <= 32'h0;
- block_w3_reg <= 32'h0;
+ block_reg <= 128'h0;
round_ctr_reg <= 4'h0;
ready_reg <= 1'b1;
enc_ctrl_reg <= CTRL_IDLE;
end
else
begin
- if (block_w0_we)
- block_w0_reg <= block_new[127 : 096];
-
- if (block_w1_we)
- block_w1_reg <= block_new[095 : 064];
-
- if (block_w2_we)
- block_w2_reg <= block_new[063 : 032];
-
- if (block_w3_we)
- block_w3_reg <= block_new[031 : 000];
+ if (block_we)
+ block_reg <= block_new;
if (round_ctr_we)
round_ctr_reg <= round_ctr_new;
@@ -265,22 +246,19 @@ module aes_encipher_block(
//----------------------------------------------------------------
always @*
begin : round_logic
- reg [127 : 0] old_block, shiftrows_block, mixcolumns_block;
+ reg [127 : 0] subbytes_block, shiftrows_block, mixcolumns_block;
reg [127 : 0] addkey_init_block, addkey_main_block, addkey_final_block;
- block_new = 128'h0;
- block_w0_we = 1'b0;
- block_w1_we = 1'b0;
- block_w2_we = 1'b0;
- block_w3_we = 1'b0;
+ block_new = 128'h0;
+ block_we = 1'b0;
- sboxw0 = block_w0_reg;
- sboxw1 = block_w1_reg;
- sboxw2 = block_w2_reg;
- sboxw3 = block_w3_reg;
+ sboxw0 = block_reg[127 : 96];
+ sboxw1 = block_reg[95 : 64];
+ sboxw2 = block_reg[63 : 32];
+ sboxw3 = block_reg[31 : 0];
- old_block = {block_w0_reg, block_w1_reg, block_w2_reg, block_w3_reg};
- shiftrows_block = shiftrows(old_block);
+ subbytes_block = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3};
+ shiftrows_block = shiftrows(subbytes_block);
mixcolumns_block = mixcolumns(shiftrows_block);
addkey_init_block = addroundkey(block, round_key);
addkey_main_block = addroundkey(mixcolumns_block, round_key);
@@ -289,38 +267,20 @@ module aes_encipher_block(
case (update_type)
INIT_UPDATE:
begin
- block_new = addkey_init_block;
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
- end
-
- SBOX_UPDATE:
- begin
- block_new = {new_sboxw0, new_sboxw1, new_sboxw2, new_sboxw3};
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
+ block_new = addkey_init_block;
+ block_we = 1'b1;
end
MAIN_UPDATE:
begin
- block_new = addkey_main_block;
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
+ block_new = addkey_main_block;
+ block_we = 1'b1;
end
FINAL_UPDATE:
begin
- block_new = addkey_final_block;
- block_w0_we = 1'b1;
- block_w1_we = 1'b1;
- block_w2_we = 1'b1;
- block_w3_we = 1'b1;
+ block_new = addkey_final_block;
+ block_we = 1'b1;
end
default:
@@ -392,13 +352,6 @@ module aes_encipher_block(
begin
round_ctr_inc = 1'b1;
update_type = INIT_UPDATE;
- enc_ctrl_new = CTRL_SBOX;
- enc_ctrl_we = 1'b1;
- end
-
- CTRL_SBOX:
- begin
- update_type = SBOX_UPDATE;
enc_ctrl_new = CTRL_MAIN;
enc_ctrl_we = 1'b1;
end
@@ -409,8 +362,6 @@ module aes_encipher_block(
if (round_ctr_reg < num_rounds)
begin
update_type = MAIN_UPDATE;
- enc_ctrl_new = CTRL_SBOX;
- enc_ctrl_we = 1'b1;
end
else
begin
diff --git a/src/tb/tb_aes.v b/src/tb/tb_aes.v
index bd51ec8..35fc1d9 100644
--- a/src/tb/tb_aes.v
+++ b/src/tb/tb_aes.v
@@ -305,6 +305,7 @@ module tb_aes();
end
endtask // read_word
+
//----------------------------------------------------------------
// wait_ready
//
diff --git a/src/tb/tb_aes_decipher_block.v b/src/tb/tb_aes_decipher_block.v
index 0475cf5..13b9949 100644
--- a/src/tb/tb_aes_decipher_block.v
+++ b/src/tb/tb_aes_decipher_block.v
@@ -158,10 +158,9 @@ module tb_aes_decipher_block();
$display("Internal data values");
$display("round_key = 0x%016x", dut.round_key);
- $display("block_w0_reg = 0x%08x, block_w1_reg = 0x%08x, block_w2_reg = 0x%08x, block_w3_reg = 0x%08x",
- dut.block_w0_reg, dut.block_w1_reg, dut.block_w2_reg, dut.block_w3_reg);
+ $display("block_reg = 0x%016x", dut.block_reg);
$display("");
- $display("old_block = 0x%08x", dut.round_logic.old_block);
+ $display("subbytes_block = 0x%08x", dut.round_logic.subbytes_block);
$display("inv_shiftrows_block = 0x%08x", dut.round_logic.inv_shiftrows_block);
$display("inv_mixcolumns_block = 0x%08x", dut.round_logic.inv_mixcolumns_block);
$display("addkey_block = 0x%08x", dut.round_logic.addkey_block);
diff --git a/src/tb/tb_aes_encipher_block.v b/src/tb/tb_aes_encipher_block.v
index 87bab2c..0606d95 100644
--- a/src/tb/tb_aes_encipher_block.v
+++ b/src/tb/tb_aes_encipher_block.v
@@ -159,18 +159,15 @@ module tb_aes_encipher_block();
$display("Internal data values");
$display("round_key = 0x%016x", dut.round_key);
- $display("block_w0_reg = 0x%08x, block_w1_reg = 0x%08x, block_w2_reg = 0x%08x, block_w3_reg = 0x%08x",
- dut.block_w0_reg, dut.block_w1_reg, dut.block_w2_reg, dut.block_w3_reg);
+ $display("block_reg = 0x%016x", dut.block_reg);
$display("");
- $display("old_block = 0x%08x", dut.round_logic.old_block);
+ $display("subbytes_block = 0x%08x", dut.round_logic.subbytes_block);
$display("shiftrows_block = 0x%08x", dut.round_logic.shiftrows_block);
$display("mixcolumns_block = 0x%08x", dut.round_logic.mixcolumns_block);
$display("addkey_init_block = 0x%08x", dut.round_logic.addkey_init_block);
$display("addkey_main_block = 0x%08x", dut.round_logic.addkey_main_block);
$display("addkey_final_block = 0x%08x", dut.round_logic.addkey_final_block);
- $display("block_w0_new = 0x%08x, block_w1_new = 0x%08x, block_w2_new = 0x%08x, block_w3_new = 0x%08x",
- dut.block_new[127 : 096], dut.block_new[095 : 064],
- dut.block_new[063 : 032], dut.block_new[031 : 000]);
+ $display("block_new = 0x%08x", dut.block_new);
$display("");
end
endtask // dump_dut_state