aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--README.md40
-rw-r--r--src/rtl/keywrap.v6
-rw-r--r--src/rtl/keywrap_core.v6
-rw-r--r--src/rtl/keywrap_mkmif.v2
-rw-r--r--src/tb/tb_keywrap.v444
-rw-r--r--src/tb/tb_keywrap_core.v11
7 files changed, 447 insertions, 63 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c369eb7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+toolruns/*.sim
diff --git a/README.md b/README.md
index 9873ae0..8420944 100644
--- a/README.md
+++ b/README.md
@@ -13,18 +13,26 @@ The core supports 128 and 256 bit wrapping keys.
First complete version developed. The core does work.
The core has been simulated with two different simulators and
-linted.
+linted. The core has been used on the Cryptech Alpha and verified to
+work.
-The core has been implemented for Xilinx Artix7-t200 using ISE with the
-following results:
-Regs: 2906 (1%)
-Slices: 1991 (5%)
-RamB36E: 32 (8%)
-Clock: 100+ MHz
+## API
+Objects to be processed are written in word order (MSB words). The
+caller writes the calculated magic value to the A regsisters in word
+order. The caller also needs to write the number of blocks (excluding
+magic block) into the RLEN register. Finally the caller needs to write
+the wrapping key.
+
+Due to address space limitations in the Cryptech cores (with 8-bit
+address space) the object storage is divided into banks [0 .. 127]. Each
+bank supports 128 32-bit words or 4096 bits. For objects lager than 4096
+bits, it is the callers responsibilty to switch banks when reading and
+writing to the storage.
## Implementation details
+### Key Wrap
The core implements the wrap block processing part of the AES Key Wrap
as specified in chapter 2.1.1 of RFC 3394:
@@ -45,15 +53,11 @@ perform padding as meeded.
chapter 2.2.2 of RFC 3394.)
-### API
-Objects to be processed are written in word order (MSB words). The
-caller writes the calculated magic value to the A regsisters in word
-order. The caller also needs to write the number of blocks (excluding
-magic block) into the RLEN register. Finally the caller needs to write
-the wrapping key.
+## Implementation results
+The core has been implemented for Xilinx Artix7-t200 using ISE with the
+following results:
-Due to address space limitations in the Cryptech cores (with 8-bit
-address space) the object storage is divided into banks [0 .. 127]. Each
-bank supports 128 32-bit words or 4096 bits. For objects lager than 4096
-bits, it is the callers responsibilty to switch banks when reading and
-writing to the storage.
+Regs: 2906 (1%)
+Slices: 1991 (5%)
+RamB36E: 32 (8%)
+Clock: 100+ MH
diff --git a/src/rtl/keywrap.v b/src/rtl/keywrap.v
index 53deaaf..2e9a7f6 100644
--- a/src/rtl/keywrap.v
+++ b/src/rtl/keywrap.v
@@ -48,7 +48,7 @@
//
//======================================================================
-module keywrap #(parameter ADDR_BITS = 13)
+module keywrap #(parameter ADDR_BITS = 12)
(
input wire clk,
input wire reset_n,
@@ -281,7 +281,7 @@ module keywrap #(parameter ADDR_BITS = 13)
end
if (rlen_we)
- rlen_reg <= write_data[12 : 0];
+ rlen_reg <= write_data[(RLEN_BITS - 1) : 0];
if (a0_we)
a0_reg <= write_data;
@@ -383,7 +383,7 @@ module keywrap #(parameter ADDR_BITS = 13)
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};
+ api_rd_delay_new = {{(32 - RLEN_BITS){1'h0}}, rlen_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 378a61a..3abe93c 100644
--- a/src/rtl/keywrap_core.v
+++ b/src/rtl/keywrap_core.v
@@ -4,7 +4,6 @@
// --------------
// Core that tries to implement AES KEY WRAP as specified in
// RFC 3394 and extended with padding in RFC 5649.
-// Experimental core at the moment. Does Not Work.
// The maximum wrap object size is 64 kByte.
//
//
@@ -244,7 +243,7 @@ module keywrap_core #(parameter MEM_BITS = 11)
begin
a_reg <= 64'h0;
ready_reg <= 1'h1;
- valid_reg <= 1'h1;
+ valid_reg <= 1'h0;
block_ctr_reg <= {(MEM_BITS - 1){1'h0}};
iteration_ctr_reg <= 3'h0;
keywrap_core_ctrl_reg <= CTRL_RESET;
@@ -287,7 +286,7 @@ 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)};
+ xor_val = (rlen * iteration_ctr_reg) + {53'h0, (block_ctr_reg + 1'h1)};
if (encdec)
aes_block = {a_reg, core_rd_data};
@@ -455,7 +454,6 @@ module keywrap_core #(parameter MEM_BITS = 11)
valid_new = 1'h0;
valid_we = 1'h1;
init_a = 1'h1;
-
if (encdec)
keywrap_core_ctrl_new = CTRL_NEXT_WSTART;
else
diff --git a/src/rtl/keywrap_mkmif.v b/src/rtl/keywrap_mkmif.v
index 2f7bebf..d73c5bd 100644
--- a/src/rtl/keywrap_mkmif.v
+++ b/src/rtl/keywrap_mkmif.v
@@ -357,7 +357,7 @@ module keywrap_mkmif (
mkm_read_op = 1'h1;
mkm_addr_new = MKM_KEY_BASE_WORD + {key_word_ctr_reg, 2'h0};
mkm_addr_we = 1'h1;
- keywrap_mkmif_ctrl_new = CTRL_WRITE_KEY_WAIT;
+ keywrap_mkmif_ctrl_new = CTRL_READ_KEY_WAIT;
keywrap_mkmif_ctrl_we = 1'h1;
end
else
diff --git a/src/tb/tb_keywrap.v b/src/tb/tb_keywrap.v
index 1f1dabf..fb02792 100644
--- a/src/tb/tb_keywrap.v
+++ b/src/tb/tb_keywrap.v
@@ -39,9 +39,10 @@
module tb_keywrap();
- parameter DEBUG = 0;
- parameter DUMP_TOP = 0;
- parameter DUMP_CORE = 0;
+ parameter DEBUG = 0;
+ parameter DUMP_TOP = 1;
+ parameter DUMP_CORE = 1;
+ parameter DUMP_TIMEOUT = 1;
parameter CLK_HALF_PERIOD = 1;
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
@@ -51,38 +52,42 @@ module tb_keywrap();
// API for the core.
- localparam ADDR_NAME0 = 8'h00;
- localparam ADDR_NAME1 = 8'h01;
- localparam ADDR_VERSION = 8'h02;
+ localparam ADDR_NAME0 = 8'h00;
+ localparam ADDR_NAME1 = 8'h01;
+ localparam ADDR_VERSION = 8'h02;
- localparam ADDR_CTRL = 8'h08;
- localparam CTRL_INIT_BIT = 0;
- localparam CTRL_NEXT_BIT = 1;
+ localparam ADDR_CTRL = 8'h08;
+ localparam CTRL_INIT_BIT = 0;
+ localparam CTRL_NEXT_BIT = 1;
+ localparam CTRL_ZEROISE_BIT = 2;
- localparam ADDR_STATUS = 8'h09;
- localparam STATUS_READY_BIT = 0;
- localparam STATUS_VALID_BIT = 1;
+ localparam ADDR_STATUS = 8'h09;
+ localparam STATUS_READY_BIT = 0;
+ localparam STATUS_VALID_BIT = 1;
+ localparam STATUS_LOADED_BIT = 2;
- localparam ADDR_CONFIG = 8'h0a;
- localparam CTRL_ENCDEC_BIT = 0;
- localparam CTRL_KEYLEN_BIT = 1;
+ localparam ADDR_CONFIG = 8'h0a;
+ localparam CTRL_ENCDEC_BIT = 0;
+ localparam CTRL_KEYLEN_BIT = 1;
- localparam ADDR_RLEN = 8'h0c;
- localparam ADDR_R_BANK = 8'h0d;
- localparam ADDR_A0 = 8'h0e;
- localparam ADDR_A1 = 8'h0f;
+ localparam ADDR_TIMEOUT = 8'h0b;
- localparam ADDR_KEY0 = 8'h10;
- localparam ADDR_KEY1 = 8'h11;
- localparam ADDR_KEY2 = 8'h12;
- localparam ADDR_KEY3 = 8'h13;
- localparam ADDR_KEY4 = 8'h14;
- localparam ADDR_KEY5 = 8'h15;
- localparam ADDR_KEY6 = 8'h16;
- localparam ADDR_KEY7 = 8'h17;
+ localparam ADDR_RLEN = 8'h0c;
+ localparam ADDR_R_BANK = 8'h0d;
+ localparam ADDR_A0 = 8'h0e;
+ localparam ADDR_A1 = 8'h0f;
- localparam ADDR_R_DATA0 = 8'h80;
- localparam ADDR_R_DATA127 = 8'hff;
+ localparam ADDR_KEY0 = 8'h10;
+ localparam ADDR_KEY1 = 8'h11;
+ localparam ADDR_KEY2 = 8'h12;
+ localparam ADDR_KEY3 = 8'h13;
+ localparam ADDR_KEY4 = 8'h14;
+ localparam ADDR_KEY5 = 8'h15;
+ localparam ADDR_KEY6 = 8'h16;
+ localparam ADDR_KEY7 = 8'h17;
+
+ localparam ADDR_R_DATA0 = 8'h80;
+ localparam ADDR_R_DATA127 = 8'hff;
//----------------------------------------------------------------
@@ -302,8 +307,21 @@ module tb_keywrap();
$display("keywrap_core_ctrl_reg = 0x%0x", dut.core.keywrap_core_ctrl_reg);
$display("keywrap_core_ctrl_new = 0x%0x", dut.core.keywrap_core_ctrl_new);
$display("keywrap_core_ctrl_we = 0x%0x", dut.core.keywrap_core_ctrl_we);
+ $display("");
end
+ if (DUMP_TIMEOUT)
+ begin
+ $display("timeout state:");
+ $display("api_timeout_reg = 0x%04x api_timeout_we = 0x%x", dut.timeout_reg, dut.timeout_we);
+ $display("timeout_delay = 0x%04x timeout = 0x%x ping = 0x%x zeroise = 0x%x loaded = 0x%x",
+ dut.core.timeout_delay, dut.core.timeout, dut.core.ping, dut.core.zeroise, dut.core.loaded);
+ $display("key_timeout_ctr_reg = 0x%04x key_timeout_ctr_new = 0x%04x key_timeout_ctr_we = 0x%x",
+ dut.core.key_timeout_ctr_reg, dut.core.key_timeout_ctr_new, dut.core.key_timeout_ctr_we);
+ $display("key_timeout = 0x%x key_timeout_ctr_we = 0x%x key_timeout_ctr_set = 0x%x key_timeout_ctr_dec = 0x%x",
+ dut.core.key_timeout, dut.core.key_timeout_ctr_we, dut.core.key_timeout_ctr_set, dut.core.key_timeout_ctr_dec);
+
+ end
$display("");
$display("");
end
@@ -448,16 +466,11 @@ module tb_keywrap();
write_word(ADDR_A1, 32'h0000001f);
- $display("* Dumping state and mem after data write and A words.");
+ $display("* Dumping state and mem after write of data A words, but before wrap processing.");
dump_dut_state();
dump_mem(6);
-
- $display("* Contents of memory and dut before wrap processing:");
- dump_mem(6);
-
-
// Start wrapping and wait for wrap to complete.
$display("* Trying to start processing.");
write_word(ADDR_CTRL, 32'h00000002);
@@ -1065,7 +1078,6 @@ module tb_keywrap();
endtask // test_kwp_ad_128_2
-
//----------------------------------------------------------------
// test_big_wrap_256
// Implements wrap test with a huge (16 kB+) data object
@@ -1154,6 +1166,360 @@ module tb_keywrap();
//----------------------------------------------------------------
+ // test_zeroise1
+ // Test the auto_zeroise functionality. We test that:
+ // 1. We can init a key and have it be auto zeroised.
+ //----------------------------------------------------------------
+ task test_zeroise1;
+ begin : test_zeroise1
+
+ $display("** TC test_zeroise1 START.");
+ $display("** Test of auto zeroise.");
+
+ tc_ctr = tc_ctr + 1;
+
+ // Write key and keylength, we also want to encrypt/wrap.
+ write_word(ADDR_KEY0, 32'h55aa55aa);
+ write_word(ADDR_KEY1, 32'h55aa55aa);
+ write_word(ADDR_KEY2, 32'h55aa55aa);
+ write_word(ADDR_KEY3, 32'h55aa55aa);
+ write_word(ADDR_KEY4, 32'h55aa55aa);
+ write_word(ADDR_KEY5, 32'h55aa55aa);
+ write_word(ADDR_KEY6, 32'h55aa55aa);
+ write_word(ADDR_KEY7, 32'h55aa55aa);
+ write_word(ADDR_CONFIG, 32'h00000003);
+
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+ // Set the key timeout to 0xdeadbeef cycles.
+ write_word(ADDR_TIMEOUT, 32'hdeadbeef);
+ read_word(ADDR_TIMEOUT);
+ if (read_data != 32'hdeadbeef)
+ begin
+ error_ctr = error_ctr + 1;
+ $display("Error. Timeout value = 0x%04x, expected 0xdeadbeef", read_data);
+ end
+
+ // Display contents in key expansion register 2.
+ $display("Contents in key_mem[2] before init: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ // Initialize the AES engine (to expand the key).
+ // Wait for init to complete.
+ $display("* Initializing.");
+ write_word(ADDR_CTRL, 32'h00000001);
+ #(2 * CLK_PERIOD);
+ wait_ready();
+ $display("* Init done.");
+
+ // Display contents in key expansion register 2 again.
+ $display("Contents in key_mem[2] after init: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ // Check if key is loaded, according to the loaded flag.
+ read_word(ADDR_STATUS);
+ $display("Status register: 0b%032b", read_data);
+
+ // Display the timeout counter a few times.
+ $display("Status of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Status of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Status timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Status of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+ $display("Contents of the API key registers:");
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[0], dut.key_reg[1], dut.key_reg[2], dut.key_reg[3]);
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[4], dut.key_reg[5], dut.key_reg[6], dut.key_reg[7]);
+
+ // Display contents in one of the key expansion registers
+ $display("Contents in key_mem[2]: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ // Set the key timeout to 16 cycles.
+ // Read status to perform ping.
+ $display("Setting the timeout to 0x10 cycles and checking status.");
+ write_word(ADDR_TIMEOUT, 32'h00000010);
+ read_word(ADDR_STATUS);
+ #(CLK_PERIOD);
+ read_word(ADDR_STATUS);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+
+ $display("Waiting 0x40 cycles.");
+ #(64 * CLK_PERIOD);
+
+
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+ $display("Status of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ // Display contents in key expansion register 2 again.
+ $display("Contents in key_mem[2] after timeout: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ $display("Contents of the API key registers:");
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[0], dut.key_reg[1], dut.key_reg[2], dut.key_reg[3]);
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[4], dut.key_reg[5], dut.key_reg[6], dut.key_reg[7]);
+
+ if (dut.core.aes.keymem.key_mem[2] != 128'h62636363626363636263636362636363)
+ begin
+ error_ctr = error_ctr + 1;
+ $display("Error. Contents in key_mem[2]: 0x%016x, expected 0x62636363626363636263636362636363",
+ dut.core.aes.keymem.key_mem[2]);
+ end
+
+ $display("** TC test_zeroise1 END.\n");
+ end
+ endtask // test_zeroise1
+
+
+ //----------------------------------------------------------------
+ // test_zeroise2
+ // Test the auto_zeroise functionality. We test that:
+ // 2. We can init a key and keep it alive.
+ //----------------------------------------------------------------
+ task test_zeroise2;
+ begin : test_zeroise2
+ integer i;
+ integer err;
+
+ err = 0;
+
+ $display("** TC test_zeroise2 START.");
+ $display("** Test of key keep alive..");
+
+ tc_ctr = tc_ctr + 1;
+
+ // Write key and keylength, we also want to encrypt/wrap.
+ write_word(ADDR_KEY0, 32'haa55aa55);
+ write_word(ADDR_KEY1, 32'haa55aa55);
+ write_word(ADDR_KEY2, 32'haa55aa55);
+ write_word(ADDR_KEY3, 32'haa55aa55);
+ write_word(ADDR_KEY4, 32'haa55aa55);
+ write_word(ADDR_KEY5, 32'haa55aa55);
+ write_word(ADDR_KEY6, 32'haa55aa55);
+ write_word(ADDR_KEY7, 32'haa55aa55);
+ write_word(ADDR_CONFIG, 32'h00000003);
+
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+ // Initialize the AES engine (to expand the key).
+ // Wait for init to complete.
+ // Note, not actually needed to wait. We can write R data during init.
+ $display("* Initializing.");
+ write_word(ADDR_CTRL, 32'h00000001);
+ #(2 * CLK_PERIOD);
+ wait_ready();
+ $display("* Init done.");
+
+ // Display contents in key expansion register 2 again.
+ $display("Contents of the key_mem[2] after init: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ // Check if key is loaded, according to the loaded flag.
+ read_word(ADDR_STATUS);
+ $display("Status register: 0b%032b", read_data);
+
+ // Set the key timeout to 256 cycles.
+ $display("Setting timout to 16 cycles and then we keep it alive.");
+ write_word(ADDR_TIMEOUT, 32'h00000010);
+
+ // Display the timeout counter a few times.
+ // And then read status. Which should trigger reset of timout.
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+ // Display the timeout counter a few times.
+ // And then read status. Which should trigger reset of timout.
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+ $display("Contents of the API key registers:");
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[0], dut.key_reg[1], dut.key_reg[2], dut.key_reg[3]);
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[4], dut.key_reg[5], dut.key_reg[6], dut.key_reg[7]);
+
+ $display("Contents of the key_mem[2]: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ // Display the timeout counter a few times.
+ // And then read status. Which should trigger reset of timout.
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(2 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+
+ $display("We now allow the timer to expire");
+ #(40 * CLK_PERIOD);
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+ $display("Contents of the API key registers:");
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[0], dut.key_reg[1], dut.key_reg[2], dut.key_reg[3]);
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[4], dut.key_reg[5], dut.key_reg[6], dut.key_reg[7]);
+
+ $display("Contents of the key_mem[2]: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ if (dut.core.aes.keymem.key_mem[2] != 128'h62636363626363636263636362636363)
+ begin
+ error_ctr = error_ctr + 1;
+ $display("Error. Contents in key_mem[2]: 0x%016x, expected 0x62636363626363636263636362636363",
+ dut.core.aes.keymem.key_mem[2]);
+ end
+
+ $display("** TC test_zeroise2 END.\n");
+ end
+ endtask // test_zeroise2
+
+
+ //----------------------------------------------------------------
+ // test_zeroise3
+ // Test the auto_zeroise functionality. We test that:
+ // 3. We can init a key and the force zeroisation.
+ //----------------------------------------------------------------
+ task test_zeroise3;
+ begin : test_zeroise3
+ integer i;
+ integer err;
+
+ err = 0;
+
+ $display("** TC test_zeroise3 START.");
+ $display("** Test of forceed zeroisation.");
+
+ tc_ctr = tc_ctr + 1;
+
+ // Write key and keylength, we also want to encrypt/wrap.
+ write_word(ADDR_KEY0, 32'h13371337);
+ write_word(ADDR_KEY1, 32'h13371337);
+ write_word(ADDR_KEY2, 32'h13371337);
+ write_word(ADDR_KEY3, 32'h13371337);
+ write_word(ADDR_KEY4, 32'h13371337);
+ write_word(ADDR_KEY5, 32'h13371337);
+ write_word(ADDR_KEY6, 32'h13371337);
+ write_word(ADDR_KEY7, 32'h13371337);
+ write_word(ADDR_CONFIG, 32'h13371337);
+
+ // Initialize the AES engine (to expand the key).
+ // Wait for init to complete.
+ $display("* Initializing.");
+ write_word(ADDR_CTRL, 32'h00000001);
+ #(2 * CLK_PERIOD);
+ wait_ready();
+ $display("* Init done.");
+
+ // Check if key is loaded, according to the loaded flag.
+ read_word(ADDR_STATUS);
+ $display("Status register: 0b%032b", read_data);
+
+ $display("Contents of the API key registers:");
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[0], dut.key_reg[1], dut.key_reg[2], dut.key_reg[3]);
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[4], dut.key_reg[5], dut.key_reg[6], dut.key_reg[7]);
+
+ // Display contents in key expansion register 2.
+ $display("Contents of the key_mem[2] after init: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+ #(40 * CLK_PERIOD);
+ $display("Contents of timeout counter: 0x%04x",
+ dut.core.key_timeout_ctr_reg);
+
+ $display("* Trigger zeroisation.");
+ write_word(ADDR_CTRL, 32'h00000004);
+ #(40 * CLK_PERIOD);
+ read_word(ADDR_STATUS);
+ $display("Status register: 0x%032b", read_data);
+
+ $display("Contents of the API key registers:");
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[0], dut.key_reg[1], dut.key_reg[2], dut.key_reg[3]);
+ $display("0x%04x 0x%04x 0x%04x 0x%04x",
+ dut.key_reg[4], dut.key_reg[5], dut.key_reg[6], dut.key_reg[7]);
+
+ // Display contents in key expansion register 2.
+ $display("Contents of the key_mem[2] after zeroisation: 0x%016x",
+ dut.core.aes.keymem.key_mem[2]);
+
+ if (dut.core.aes.keymem.key_mem[2] != 128'h62636363626363636263636362636363)
+ begin
+ error_ctr = error_ctr + 1;
+ $display("Error. Contents in key_mem[2]: 0x%016x, expected 0x62636363626363636263636362636363",
+ dut.core.aes.keymem.key_mem[2]);
+ end
+
+ $display("** TC test_zerois3 END.\n");
+ end
+ endtask // test_zeroise3
+
+
+ //----------------------------------------------------------------
// main
//----------------------------------------------------------------
initial
@@ -1178,9 +1544,13 @@ module tb_keywrap();
test_kwp_ad_128_1();
test_kwp_ae_128_2();
test_kwp_ad_128_2();
-
test_big_wrap_256();
+ reset_dut();
+ test_zeroise1();
+ test_zeroise2();
+ test_zeroise3();
+
display_test_results();
$display("");
diff --git a/src/tb/tb_keywrap_core.v b/src/tb/tb_keywrap_core.v
index 07777aa..b8857ea 100644
--- a/src/tb/tb_keywrap_core.v
+++ b/src/tb/tb_keywrap_core.v
@@ -71,6 +71,11 @@ module tb_keywrap_core();
reg tb_mkey_key;
wire tb_ready;
wire tb_valid;
+ wire tb_loaded;
+ reg [31 : 0] tb_timeout;
+ reg tb_ping;
+ reg tb_zeroise;
+ wire tb_dut_timeout;
reg [(RLEN_BITS - 1) : 0] tb_rlen;
reg [255 : 0] tb_key;
reg [31 : 0] tb_status;
@@ -113,6 +118,12 @@ module tb_keywrap_core();
.ready(tb_ready),
.valid(tb_valid),
+ .loaded(tb_loaded),
+
+ .timeout_delay(tb_timeout),
+ .ping(tb_ping),
+ .zeroise(tb_zeroise),
+ .timeout(tb_dut_timeout),
.rlen(tb_rlen),
.key(tb_key),