aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoachim StroĢˆmbergson <joachim@secworks.se>2018-09-14 15:01:59 +0200
committerJoachim StroĢˆmbergson <joachim@secworks.se>2018-09-14 15:01:59 +0200
commitfa3ebe9f36310af061aba162713676b548555017 (patch)
tree9f0061951f9c0b8f3aface68c5129d432c647828
parent6cfcc1ec5bc0e2c944ec66bd62d58740d2b8823d (diff)
Adding support for automatic A-value and RLEN calculation. Adding support for checking that unwrapped data is valid.auto_magic
-rw-r--r--src/rtl/keywrap.v39
-rw-r--r--src/rtl/keywrap_core.v42
-rw-r--r--src/tb/tb_keywrap.v57
-rw-r--r--src/tb/tb_keywrap_core.v8
4 files changed, 72 insertions, 74 deletions
diff --git a/src/rtl/keywrap.v b/src/rtl/keywrap.v
index f8fcbd7..2d241a9 100644
--- a/src/rtl/keywrap.v
+++ b/src/rtl/keywrap.v
@@ -4,17 +4,6 @@
// --------
// Top level wrapper for the KEY WRAP core.
//
-// Since $clog2() is not supported by all tools, and constant
-// functions are not supported by some other tools we need to
-// do the size to number of bits calculation by hand.
-// 8192 bytes = 2048 32 bit words. This requires 11 bits.
-// We need additional space for control and status words. But
-// since we have filled the address space, we need another MSB
-// in the address. Thus ADDR_BITS = 12 bits.
-//
-// 0x000 - 0x7ff are for control and status.
-// 0x800 - 0xfff are for data storage
-//
//
// Author: Joachim Strombergson
// Copyright (c) 2018, NORDUnet A/S
@@ -81,7 +70,7 @@ module keywrap #(parameter ADDR_BITS = 13)
localparam CTRL_ENCDEC_BIT = 0;
localparam CTRL_KEYLEN_BIT = 1;
- localparam ADDR_RLEN = 8'h0c;
+ localparam ADDR_LENGTH = 8'h0c;
localparam ADDR_A0 = 8'h0e;
localparam ADDR_A1 = 8'h0f;
@@ -96,10 +85,10 @@ module keywrap #(parameter ADDR_BITS = 13)
localparam CORE_NAME0 = 32'h6b657920; // "key "
localparam CORE_NAME1 = 32'h77726170; // "wrap"
- localparam CORE_VERSION = 32'h302e3830; // "0.80"
+ localparam CORE_VERSION = 32'h312e3031; // "1.01"
localparam MEM_BITS = ADDR_BITS - 1;
- localparam RLEN_BITS = ADDR_BITS - 2;
+ localparam LEN_BITS = MEM_BITS + 2;
localparam PAD = ADDR_BITS - 8;
@@ -116,8 +105,8 @@ module keywrap #(parameter ADDR_BITS = 13)
reg keylen_reg;
reg config_we;
- reg [(RLEN_BITS - 1) : 0] rlen_reg;
- reg rlen_we;
+ reg [(LEN_BITS - 1) : 0] length_reg;
+ reg length_we;
reg [31 : 0] a0_reg;
reg a0_we;
@@ -180,7 +169,7 @@ module keywrap #(parameter ADDR_BITS = 13)
.ready(core_ready),
.valid(core_valid),
- .rlen(rlen_reg),
+ .length(length_reg),
.key(core_key),
.keylen(keylen_reg),
@@ -211,7 +200,7 @@ module keywrap #(parameter ADDR_BITS = 13)
next_reg <= 1'h0;
encdec_reg <= 1'h0;
keylen_reg <= 1'h0;
- rlen_reg <= {RLEN_BITS{1'h0}};
+ length_reg <= {LEN_BITS{1'h0}};
valid_reg <= 1'h0;
ready_reg <= 1'h0;
a0_reg <= 32'h0;
@@ -232,8 +221,8 @@ module keywrap #(parameter ADDR_BITS = 13)
keylen_reg <= write_data[CTRL_KEYLEN_BIT];
end
- if (rlen_we)
- rlen_reg <= write_data[12 : 0];
+ if (length_we)
+ length_reg <= write_data[(LEN_BITS - 1) : 0];
if (a0_we)
a0_reg <= write_data;
@@ -257,7 +246,7 @@ module keywrap #(parameter ADDR_BITS = 13)
init_new = 1'h0;
next_new = 1'h0;
config_we = 1'h0;
- rlen_we = 1'h0;
+ length_we = 1'h0;
key_we = 1'h0;
core_api_we = 1'h0;
a0_we = 1'h0;
@@ -285,8 +274,8 @@ module keywrap #(parameter ADDR_BITS = 13)
if (address == {{PAD{1'h0}}, ADDR_CONFIG})
config_we = 1'h1;
- if (address == {{PAD{1'h0}}, ADDR_RLEN})
- rlen_we = 1'h1;
+ if (address == {{PAD{1'h0}}, ADDR_LENGTH})
+ length_we = 1'h1;
if (address == {{PAD{1'h0}}, ADDR_A0})
a0_we = 1'h1;
@@ -319,8 +308,8 @@ module keywrap #(parameter ADDR_BITS = 13)
if (address == {{PAD{1'h0}}, ADDR_STATUS})
api_rd_delay_new = {30'h0, valid_reg, ready_reg};
- if (address == {{PAD{1'h0}}, ADDR_RLEN})
- api_rd_delay_new = {19'h0, rlen_reg};
+ if (address == {{PAD{1'h0}}, ADDR_LENGTH})
+ api_rd_delay_new = {{(32 - LEN_BITS){1'h0}}, length_reg};
if (address == {{PAD{1'h0}}, ADDR_A0})
api_rd_delay_new = core_a_result[63 : 32];
diff --git a/src/rtl/keywrap_core.v b/src/rtl/keywrap_core.v
index d1e63b0..469a238 100644
--- a/src/rtl/keywrap_core.v
+++ b/src/rtl/keywrap_core.v
@@ -52,7 +52,7 @@ module keywrap_core #(parameter MEM_BITS = 11)
output wire ready,
output wire valid,
- input wire [(MEM_BITS - 2) : 0] rlen,
+ input wire [(LEN_BITS - 1) : 0] length,
input wire [255 : 0] key,
input wire keylen,
@@ -84,6 +84,10 @@ module keywrap_core #(parameter MEM_BITS = 11)
localparam CTRL_NEXT_UCHECK = 4'h9;
localparam CTRL_NEXT_FINALIZE = 4'ha;
+ localparam LEN_BITS = MEM_BITS + 2;
+
+ localparam AIV = 32'ha65959a6;
+
//----------------------------------------------------------------
// Registers and memories including control signals.
@@ -134,6 +138,8 @@ module keywrap_core #(parameter MEM_BITS = 11)
reg update_state;
+ reg [(MEM_BITS - 1) : 0] rlen;
+
reg core_we;
reg [(MEM_BITS - 2) : 0] core_addr;
reg [63 : 0] core_wr_data;
@@ -238,7 +244,13 @@ module keywrap_core #(parameter MEM_BITS = 11)
core_addr = block_ctr_reg;
core_we = 1'h0;
- xor_val = (rlen * iteration_ctr_reg) + {51'h0, (block_ctr_reg + 1'h1)};
+ // Calculate the correct number of blocks including padding.
+ if (length[1 : 0] === 2'h0)
+ rlen = length[(LEN_BITS - 1) : 3];
+ else
+ rlen = length[(LEN_BITS - 2) : 3] + 1'b1;
+
+ xor_val = (rlen * iteration_ctr_reg) + {52'h0, (block_ctr_reg + 1'h1)};
if (encdec)
aes_block = {a_reg, core_rd_data};
@@ -249,8 +261,11 @@ module keywrap_core #(parameter MEM_BITS = 11)
if (init_a)
begin
- a_new = a_init;
a_we = 1'h1;
+ if (encdec)
+ a_new = {AIV, {{(32 - (MEM_BITS + 2)){1'b0}}, length}};
+ else
+ a_new = a_init;
end
if (update_state)
@@ -510,10 +525,23 @@ module keywrap_core #(parameter MEM_BITS = 11)
CTRL_NEXT_FINALIZE:
begin
- ready_new = 1'h1;
- ready_we = 1'h1;
- valid_new = 1'h1;
- valid_we = 1'h1;
+ ready_new = 1'h1;
+ ready_we = 1'h1;
+
+ if (encdec)
+ begin
+ valid_new = 1'h1;
+ valid_we = 1'h1;
+ end
+ else
+ begin
+ if (a_reg[63 : 32] == AIV)
+ begin
+ valid_new = 1'h1;
+ valid_we = 1'h1;
+ end
+ end
+
keywrap_core_ctrl_new = CTRL_IDLE;
keywrap_core_ctrl_we = 1'h1;
end
diff --git a/src/tb/tb_keywrap.v b/src/tb/tb_keywrap.v
index 4d1c25c..43e03ee 100644
--- a/src/tb/tb_keywrap.v
+++ b/src/tb/tb_keywrap.v
@@ -39,9 +39,9 @@
module tb_keywrap();
- parameter DEBUG = 0;
- parameter DUMP_TOP = 0;
- parameter DUMP_CORE = 0;
+ parameter DEBUG = 1;
+ parameter DUMP_TOP = 1;
+ parameter DUMP_CORE = 1;
parameter CLK_HALF_PERIOD = 1;
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
@@ -67,8 +67,7 @@ module tb_keywrap();
localparam CTRL_ENCDEC_BIT = 0;
localparam CTRL_KEYLEN_BIT = 1;
- localparam ADDR_RLEN = 8'h0c;
- localparam ADDR_R_BANK = 8'h0d;
+ localparam ADDR_LENGTH = 8'h0c;
localparam ADDR_A0 = 8'h0e;
localparam ADDR_A1 = 8'h0f;
@@ -249,10 +248,10 @@ module tb_keywrap();
if (DUMP_TOP)
begin
$display("top level state:");
- $display("init_reg = 0x%x next_reg = 0x%x", dut.init_reg, dut.next_reg);
- $display("endec_reg = 0x%x keylen_reg = 0x%x", dut.encdec_reg, dut.keylen_reg);
- $display("rlen_reg = 0x%08x", dut.rlen_reg);
- $display("a0_reg = 0x%08x a1_reg = 0x%08x", dut.a0_reg, dut.a1_reg);
+ $display("init_reg = 0x%x next_reg = 0x%x", dut.init_reg, dut.next_reg);
+ $display("endec_reg = 0x%x keylen_reg = 0x%x", dut.encdec_reg, dut.keylen_reg);
+ $display("length_reg = 0x%08x", dut.length_reg);
+ $display("a0_reg = 0x%08x a1_reg = 0x%08x", dut.a0_reg, dut.a1_reg);
$display("");
end
@@ -263,6 +262,7 @@ module tb_keywrap();
dut.core.init, dut.core.next, dut.core.ready, dut.core.valid);
$display("api_we = 0x%0x api_addr = 0x%0x api_wr_data = 0x%0x api_rd_data = 0x%0x",
dut.core.api_we, dut.core.api_addr, dut.core.api_wr_data, dut.core.api_rd_data);
+ $display("length = 0x%0x", dut.core.length);
$display("rlen = 0x%0x", dut.core.rlen);
$display("key = 0x%0x", dut.core.key);
$display("a_init = 0x%0x a_result = 0x%0x", dut.core.a_init, dut.core.a_result);
@@ -416,13 +416,6 @@ module tb_keywrap();
wait_ready();
$display("* Init should be done.");
-
- // Set the length or R in blocks.
- // Write the R bank to be written to.
- // Write the R blocks to be processed.
- write_word(ADDR_RLEN, 32'h00000004);
-
-
// Write the data to be wrapped.
write_word(MEM_BASE + 0, 32'h46f87f58);
write_word(MEM_BASE + 1, 32'hcdda4200);
@@ -433,9 +426,8 @@ module tb_keywrap();
write_word(MEM_BASE + 6, 32'h5f37a27d);
write_word(MEM_BASE + 7, 32'h45a28800);
- // Write magic words to A.
- write_word(ADDR_A0, 32'ha65959a6);
- write_word(ADDR_A1, 32'h0000001f);
+ // Set the length of the data before padding.
+ write_word(ADDR_LENGTH, 32'h0000001f);
$display("* Dumping state and mem after data write and A words.");
@@ -523,10 +515,8 @@ module tb_keywrap();
$display("* Init should be done.");
- // Set the length or R in blocks.
- // Write the R bank to be written to.
- // Write the R blocks to be processed.
- write_word(ADDR_RLEN, 32'h00000004);
+ // Set the length before paddfing.
+ write_word(ADDR_LENGTH, 32'h0000001f);
write_word(MEM_BASE + 0, 32'h59a69492);
write_word(MEM_BASE + 1, 32'hbb7e2cd0);
@@ -632,10 +622,8 @@ module tb_keywrap();
$display("* Init should be done.");
- // Set the length or R in blocks.
- // Write the R bank to be written to.
- // Write the R blocks to be processed.
- write_word(ADDR_RLEN, 32'h00000040);
+ // Set the length before padding.
+ write_word(ADDR_LENGTH, 32'h00000200);
write_word(MEM_BASE + 0, 32'h8af887c5);
write_word(MEM_BASE + 1, 32'h8dfbc38e);
@@ -766,10 +754,6 @@ module tb_keywrap();
write_word(MEM_BASE + 126, 32'he2de7f12);
write_word(MEM_BASE + 127, 32'h9b187053);
- // Write magic words to A.
- write_word(ADDR_A0, 32'ha65959a6);
- write_word(ADDR_A1, 32'h00000200);
-
$display("* Contents of memory and dut before wrap processing:");
dump_mem(65);
@@ -859,10 +843,8 @@ module tb_keywrap();
$display("* Init should be done.");
- // Set the length or R in blocks.
- // Write the R bank to be written to.
- // Write the R blocks to be processed.
- write_word(ADDR_RLEN, 32'h00000040);
+ // Set the length before padding.
+ write_word(ADDR_LENGTH, 32'h00000200);
write_word(MEM_BASE + 0, 32'h4501c1ec);
write_word(MEM_BASE + 1, 32'hadc6b5e3);
@@ -1096,7 +1078,7 @@ module tb_keywrap();
// Set the length or R in blocks.
// Write the R bank to be written to.
// Write the R blocks to be processed.
- write_word(ADDR_RLEN, 32'h000007f8);
+ write_word(ADDR_LENGTH, 32'h000007f8);
// Write the data to be wrapped.
@@ -1168,8 +1150,7 @@ module tb_keywrap();
test_kwp_ad_128_1();
test_kwp_ae_128_2();
test_kwp_ad_128_2();
-
- test_big_wrap_256();
+// test_big_wrap_256();
display_test_results();
diff --git a/src/tb/tb_keywrap_core.v b/src/tb/tb_keywrap_core.v
index 17c8f30..2b88b8c 100644
--- a/src/tb/tb_keywrap_core.v
+++ b/src/tb/tb_keywrap_core.v
@@ -48,7 +48,7 @@ module tb_keywrap_core();
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
parameter API_ADDR_BITS = 8;
- parameter RLEN_BITS = API_ADDR_BITS - 1;
+ parameter LEN_BITS = API_ADDR_BITS + 2;
parameter CORE_ADDR_BITS = API_ADDR_BITS - 1;
parameter API_ADDR_MAX = (2 ** API_ADDR_BITS) - 1;
parameter CORE_ADDR_MAX = (2 ** CORE_ADDR_BITS) - 1;
@@ -67,7 +67,7 @@ module tb_keywrap_core();
reg tb_encdec;
wire tb_ready;
wire tb_valid;
- reg [(RLEN_BITS - 1) : 0] tb_rlen;
+ reg [(LEN_BITS - 1) : 0] tb_length;
reg [255 : 0] tb_key;
reg tb_keylen;
reg [63 : 0] tb_a_init;
@@ -93,7 +93,7 @@ module tb_keywrap_core();
.ready(tb_ready),
.valid(tb_valid),
- .rlen(tb_rlen),
+ .length(tb_length),
.key(tb_key),
.keylen(tb_keylen),
@@ -150,7 +150,7 @@ module tb_keywrap_core();
tb_init = 0;
tb_next = 0;
tb_encdec = 0;
- tb_rlen = 13'h0;
+ tb_length = {LEN_BITS{1'h0}};
tb_key = 256'h0;
tb_keylen = 0;
tb_a_init = 64'h0;