aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoachim StroĢˆmbergson <joachim@secworks.se>2016-05-31 14:00:00 +0200
committerJoachim StroĢˆmbergson <joachim@secworks.se>2016-05-31 14:00:00 +0200
commitdc47fffe47a1fc49ad79e4201f219c8a697b7ae5 (patch)
tree581058cea1d58978871636e66e48787f545e38cc
parent0e90cfa1f076b8660610dfd3930ef1b37a1fb41e (diff)
Adding functionality to support both SHA224 and SHA256 digest modes. Note: This update changes the ADDR_CTRL API register since it adds a mode bit. The version major number has been bumped to reflect this API change. The top level testbench contains tests for SHA224 as well as old tests for SHA256. The core level tb still only tests SHA256.
-rw-r--r--src/rtl/sha256.v23
-rw-r--r--src/rtl/sha256_core.v101
-rw-r--r--src/tb/tb_sha256.v142
-rw-r--r--src/tb/tb_sha256_core.v3
4 files changed, 204 insertions, 65 deletions
diff --git a/src/rtl/sha256.v b/src/rtl/sha256.v
index 1f9e75e..17fcd84 100644
--- a/src/rtl/sha256.v
+++ b/src/rtl/sha256.v
@@ -64,6 +64,7 @@ module sha256(
localparam ADDR_CTRL = 8'h08;
localparam CTRL_INIT_BIT = 0;
localparam CTRL_NEXT_BIT = 1;
+ localparam CTRL_MODE_BIT = 2;
localparam ADDR_STATUS = 8'h09;
localparam STATUS_READY_BIT = 0;
@@ -97,7 +98,10 @@ module sha256(
localparam CORE_NAME0 = 32'h73686132; // "sha2"
localparam CORE_NAME1 = 32'h2d323536; // "-256"
- localparam CORE_VERSION = 32'h302e3831; // "0.81"
+ localparam CORE_VERSION = 32'h312e3830; // "1.80"
+
+ localparam MODE_SHA_224 = 1'h0;
+ localparam MODE_SHA_256 = 1'h1;
//----------------------------------------------------------------
@@ -113,6 +117,10 @@ module sha256(
reg next_we;
reg next_set;
+ reg mode_reg;
+ reg mode_new;
+ reg mode_we;
+
reg ready_reg;
reg [31 : 0] block0_reg;
@@ -201,6 +209,7 @@ module sha256(
.init(core_init),
.next(core_next),
+ .mode(mode_reg),
.block(core_block),
@@ -235,6 +244,7 @@ module sha256(
begin
init_reg <= 0;
next_reg <= 0;
+ mode_reg <= MODE_SHA_256;
ready_reg <= 0;
digest_reg <= 256'h0;
digest_valid_reg <= 0;
@@ -270,6 +280,9 @@ module sha256(
next_reg <= next_new;
end
+ if (mode_we)
+ mode_reg <= mode_new;
+
if (core_digest_valid)
begin
digest_reg <= core_digest;
@@ -405,6 +418,8 @@ module sha256(
begin : api_logic
init_set = 0;
next_set = 0;
+ mode_new = 0;
+ mode_we = 0;
block0_we = 0;
block1_we = 0;
block2_we = 0;
@@ -443,6 +458,8 @@ module sha256(
begin
init_set = write_data[CTRL_INIT_BIT];
next_set = write_data[CTRL_NEXT_BIT];
+ mode_new = write_data[CTRL_MODE_BIT];
+ mode_we = 1;
end
ADDR_BLOCK0:
@@ -538,10 +555,10 @@ module sha256(
tmp_read_data = CORE_VERSION;
ADDR_CTRL:
- tmp_read_data = {28'h0000000, 2'b00, next_reg, init_reg};
+ tmp_read_data = {29'h0, mode_reg, next_reg, init_reg};
ADDR_STATUS:
- tmp_read_data = {28'h0000000, 2'b00, digest_valid_reg, ready_reg};
+ tmp_read_data = {30'h0, digest_valid_reg, ready_reg};
ADDR_BLOCK0:
tmp_read_data = block0_reg;
diff --git a/src/rtl/sha256_core.v b/src/rtl/sha256_core.v
index 448dfe6..6553aab 100644
--- a/src/rtl/sha256_core.v
+++ b/src/rtl/sha256_core.v
@@ -44,6 +44,7 @@ module sha256_core(
input wire init,
input wire next,
+ input wire mode,
input wire [511 : 0] block,
@@ -68,20 +69,29 @@ module sha256_core(
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
- parameter H0_0 = 32'h6a09e667;
- parameter H0_1 = 32'hbb67ae85;
- parameter H0_2 = 32'h3c6ef372;
- parameter H0_3 = 32'ha54ff53a;
- parameter H0_4 = 32'h510e527f;
- parameter H0_5 = 32'h9b05688c;
- parameter H0_6 = 32'h1f83d9ab;
- parameter H0_7 = 32'h5be0cd19;
-
- parameter SHA256_ROUNDS = 63;
-
- parameter CTRL_IDLE = 0;
- parameter CTRL_ROUNDS = 1;
- parameter CTRL_DONE = 2;
+ localparam SHA224_H0_0 = 32'hc1059ed8;
+ localparam SHA224_H0_1 = 32'h367cd507;
+ localparam SHA224_H0_2 = 32'h3070dd17;
+ localparam SHA224_H0_3 = 32'hf70e5939;
+ localparam SHA224_H0_4 = 32'hffc00b31;
+ localparam SHA224_H0_5 = 32'h68581511;
+ localparam SHA224_H0_6 = 32'h64f98fa7;
+ localparam SHA224_H0_7 = 32'hbefa4fa4;
+
+ localparam SHA256_H0_0 = 32'h6a09e667;
+ localparam SHA256_H0_1 = 32'hbb67ae85;
+ localparam SHA256_H0_2 = 32'h3c6ef372;
+ localparam SHA256_H0_3 = 32'ha54ff53a;
+ localparam SHA256_H0_4 = 32'h510e527f;
+ localparam SHA256_H0_5 = 32'h9b05688c;
+ localparam SHA256_H0_6 = 32'h1f83d9ab;
+ localparam SHA256_H0_7 = 32'h5be0cd19;
+
+ localparam SHA256_ROUNDS = 63;
+
+ localparam CTRL_IDLE = 0;
+ localparam CTRL_ROUNDS = 1;
+ localparam CTRL_DONE = 2;
//----------------------------------------------------------------
@@ -311,15 +321,29 @@ module sha256_core(
if (digest_init)
begin
- H0_new = H0_0;
- H1_new = H0_1;
- H2_new = H0_2;
- H3_new = H0_3;
- H4_new = H0_4;
- H5_new = H0_5;
- H6_new = H0_6;
- H7_new = H0_7;
H_we = 1;
+ if (mode)
+ begin
+ H0_new = SHA256_H0_0;
+ H1_new = SHA256_H0_1;
+ H2_new = SHA256_H0_2;
+ H3_new = SHA256_H0_3;
+ H4_new = SHA256_H0_4;
+ H5_new = SHA256_H0_5;
+ H6_new = SHA256_H0_6;
+ H7_new = SHA256_H0_7;
+ end
+ else
+ begin
+ H0_new = SHA224_H0_0;
+ H1_new = SHA224_H0_1;
+ H2_new = SHA224_H0_2;
+ H3_new = SHA224_H0_3;
+ H4_new = SHA224_H0_4;
+ H5_new = SHA224_H0_5;
+ H6_new = SHA224_H0_6;
+ H7_new = SHA224_H0_7;
+ end
end
if (digest_update)
@@ -397,17 +421,31 @@ module sha256_core(
if (state_init)
begin
+ a_h_we = 1;
if (first_block)
begin
- a_new = H0_0;
- b_new = H0_1;
- c_new = H0_2;
- d_new = H0_3;
- e_new = H0_4;
- f_new = H0_5;
- g_new = H0_6;
- h_new = H0_7;
- a_h_we = 1;
+ if (mode)
+ begin
+ a_new = SHA256_H0_0;
+ b_new = SHA256_H0_1;
+ c_new = SHA256_H0_2;
+ d_new = SHA256_H0_3;
+ e_new = SHA256_H0_4;
+ f_new = SHA256_H0_5;
+ g_new = SHA256_H0_6;
+ h_new = SHA256_H0_7;
+ end
+ else
+ begin
+ a_new = SHA224_H0_0;
+ b_new = SHA224_H0_1;
+ c_new = SHA224_H0_2;
+ d_new = SHA224_H0_3;
+ e_new = SHA224_H0_4;
+ f_new = SHA224_H0_5;
+ g_new = SHA224_H0_6;
+ h_new = SHA224_H0_7;
+ end
end
else
begin
@@ -419,7 +457,6 @@ module sha256_core(
f_new = H5_reg;
g_new = H6_reg;
h_new = H7_reg;
- a_h_we = 1;
end
end
diff --git a/src/tb/tb_sha256.v b/src/tb/tb_sha256.v
index d881dae..6377688 100644
--- a/src/tb/tb_sha256.v
+++ b/src/tb/tb_sha256.v
@@ -60,6 +60,7 @@ module tb_sha256();
parameter ADDR_NAME0 = 8'h00;
parameter ADDR_NAME1 = 8'h01;
parameter ADDR_VERSION = 8'h02;
+ parameter CTRL_MODE_VALUE = 8'h04;
parameter ADDR_CTRL = 8'h08;
parameter CTRL_INIT_VALUE = 8'h01;
@@ -95,6 +96,9 @@ module tb_sha256();
parameter ADDR_DIGEST6 = 8'h26;
parameter ADDR_DIGEST7 = 8'h27;
+ parameter SHA224_MODE = 0;
+ parameter SHA256_MODE = 1;
+
//----------------------------------------------------------------
// Register and Wire declarations.
@@ -435,17 +439,27 @@ module tb_sha256();
//
// Perform test of a single block digest.
//----------------------------------------------------------------
- task single_block_test(input [511 : 0] block,
+ task single_block_test(input mode,
+ input [511 : 0] block,
input [255 : 0] expected);
begin
$display("*** TC%01d - Single block test started.", tc_ctr);
write_block(block);
- write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
+ if (mode)
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));
+ else
+ write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
#(CLK_PERIOD);
wait_ready();
read_digest();
+ // We need to ignore the LSW in SHA224 mode.
+ if (mode == SHA224_MODE)
+ digest_data[31 : 0] = 32'h0;
+
if (digest_data == expected)
begin
$display("TC%01d: OK.", tc_ctr);
@@ -470,7 +484,8 @@ module tb_sha256();
// Perform test of a double block digest. Note that we check
// the digests for both the first and final block.
//----------------------------------------------------------------
- task double_block_test(input [511 : 0] block0,
+ task double_block_test(input mode,
+ input [511 : 0] block0,
input [255 : 0] expected0,
input [511 : 0] block1,
input [255 : 0] expected1
@@ -480,11 +495,20 @@ module tb_sha256();
// First block
write_block(block0);
- write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
+ if (mode)
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_INIT_VALUE));
+ else
+ write_word(ADDR_CTRL, CTRL_INIT_VALUE);
+
#(CLK_PERIOD);
wait_ready();
read_digest();
+ // We need to ignore the LSW in SHA224 mode.
+ if (mode == SHA224_MODE)
+ digest_data[31 : 0] = 32'h0;
+
if (digest_data == expected0)
begin
$display("TC%01d first block: OK.", tc_ctr);
@@ -499,11 +523,20 @@ module tb_sha256();
// Final block
write_block(block1);
- write_word(ADDR_CTRL, CTRL_NEXT_VALUE);
+
+ if (mode)
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));
+ else
+ write_word(ADDR_CTRL, CTRL_NEXT_VALUE);
+
#(CLK_PERIOD);
wait_ready();
read_digest();
+ // We need to ignore the LSW in SHA224 mode.
+ if (mode == SHA224_MODE)
+ digest_data[31 : 0] = 32'h0;
+
if (digest_data == expected1)
begin
$display("TC%01d final block: OK.", tc_ctr);
@@ -525,15 +558,19 @@ module tb_sha256();
//----------------------------------------------------------------
// restore_state_test()
//
- //
// Perform test of a double block digest. Note that we check
// the digests for both the first and final block.
//----------------------------------------------------------------
- task restore_state_test(input [255 : 0] state,
- input [511 : 0] block,
- input [255 : 0] expected
- );
- begin
+ task restore_state_test;
+ begin : restore_state
+ reg [255 : 0] state;
+ reg [511 : 0] block;
+ reg [255 : 0] expected;
+
+ state = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;
+ block = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;
+ expected = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;
+
$display("*** TC%01d - Restore state test started.", tc_ctr);
// Write state.
@@ -548,7 +585,7 @@ module tb_sha256();
// Process block.
write_block(block);
- write_word(ADDR_CTRL, CTRL_NEXT_VALUE);
+ write_word(ADDR_CTRL, (CTRL_MODE_VALUE + CTRL_NEXT_VALUE));
#(CLK_PERIOD);
wait_ready();
read_digest();
@@ -572,14 +609,14 @@ module tb_sha256();
//----------------------------------------------------------------
- // sha256_test
- // The main test functionality.
+ // sha224_tests()
//
+ // Run test cases for sha224.
// Test cases taken from:
- // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf
+ // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf
//----------------------------------------------------------------
- initial
- begin : sha256_test
+ task sha224_tests;
+ begin : sha224_tests_block
reg [511 : 0] tc0;
reg [255 : 0] res0;
@@ -588,35 +625,80 @@ module tb_sha256();
reg [511 : 0] tc1_1;
reg [255 : 0] res1_1;
- $display(" -- Testbench for sha256 started --");
+ $display("*** Testcases for sha224 functionality started.");
- init_sim();
- reset_dut();
- check_name_version();
+ tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;
- // dump_dut_state();
- // write_word(ADDR_BLOCK0, 32'hdeadbeef);
- // dump_dut_state();
- // read_word(ADDR_BLOCK0);
- // dump_dut_state();
+ res0 = 256'h23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA700000000;
+ single_block_test(SHA224_MODE, tc0, res0);
+
+ tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;
+ res1_0 = 256'h8250e65dbcf62f8466659c3333e5e91a10c8b7b0953927691f1419c200000000;
+ tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;
+ res1_1 = 256'h75388b16512776cc5dba5da1fd890150b0c6455cb4f58b195252252500000000;
+ double_block_test(SHA224_MODE, tc1_0, res1_0, tc1_1, res1_1);
+
+ $display("*** Testcases for sha224 functionality completed.");
+ end
+ endtask // sha224_tests
+
+
+ //----------------------------------------------------------------
+ // sha256_tests()
+ //
+ // Run test cases for sha256.
+ // Test cases taken from:
+ // http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA256.pdf
+ //----------------------------------------------------------------
+ task sha256_tests;
+ begin : sha256_tests_block
+ reg [511 : 0] tc0;
+ reg [255 : 0] res0;
+
+ reg [511 : 0] tc1_0;
+ reg [255 : 0] res1_0;
+ reg [511 : 0] tc1_1;
+ reg [255 : 0] res1_1;
+
+ $display("*** Testcases for sha256 functionality started.");
tc0 = 512'h61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018;
res0 = 256'hBA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD;
- single_block_test(tc0, res0);
+ single_block_test(SHA256_MODE, tc0, res0);
tc1_0 = 512'h6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F70718000000000000000;
res1_0 = 256'h85E655D6417A17953363376A624CDE5C76E09589CAC5F811CC4B32C1F20E533A;
tc1_1 = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C0;
res1_1 = 256'h248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1;
- double_block_test(tc1_0, res1_0, tc1_1, res1_1);
+ double_block_test(SHA256_MODE, tc1_0, res1_0, tc1_1, res1_1);
- restore_state_test(res1_0, tc1_1, res1_1);
+ $display("*** Testcases for sha256 functionality completed.");
+ end
+ endtask // sha256_tests
+
+
+ //----------------------------------------------------------------
+ // sha256_top_test
+ // The main test functionality.
+ //----------------------------------------------------------------
+ initial
+ begin : sha256_top_test
+ $display(" -- Testbench for sha256 started --");
+
+ init_sim();
+ reset_dut();
+
+ check_name_version();
+ sha224_tests();
+ sha256_tests();
+ restore_state_test();
display_test_result();
$display(" -- Testbench for sha256 done. --");
$finish;
- end // sha256_test
+ end // sha256_top_test
+
endmodule // tb_sha256
//======================================================================
diff --git a/src/tb/tb_sha256_core.v b/src/tb/tb_sha256_core.v
index 07e2334..981351c 100644
--- a/src/tb/tb_sha256_core.v
+++ b/src/tb/tb_sha256_core.v
@@ -68,6 +68,7 @@ module tb_sha256_core();
reg tb_reset_n;
reg tb_init;
reg tb_next;
+ reg tb_mode;
reg [511 : 0] tb_block;
reg [31 : 0] tb_state_wr_data;
reg tb_state0_we;
@@ -92,6 +93,7 @@ module tb_sha256_core();
.init(tb_init),
.next(tb_next),
+ .mode(tb_mode),
.block(tb_block),
@@ -244,6 +246,7 @@ module tb_sha256_core();
tb_init = 0;
tb_next = 0;
+ tb_mode = 1;
tb_block = 512'h0;
tb_state_wr_data = 32'h0;
tb_state0_we = 0;