From 356b37a1a601351a75794ed56fb3c708ab1b2792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Stro=CC=88mbergson?= Date: Fri, 31 May 2024 16:01:00 +0200 Subject: [PATCH] Change final handling to FSM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Joachim StroĢˆmbergson --- src/rtl/sha256_final_padding.v | 177 +++++++++++++++++++++---------- src/tb/tb_sha256_final_padding.v | 69 +++++++++--- 2 files changed, 173 insertions(+), 73 deletions(-) diff --git a/src/rtl/sha256_final_padding.v b/src/rtl/sha256_final_padding.v index 0776486..f0e1aec 100644 --- a/src/rtl/sha256_final_padding.v +++ b/src/rtl/sha256_final_padding.v @@ -54,6 +54,7 @@ module sha256_final_padding( output wire init_out, output wire next_out, + output wire ready_out, output wire [511 : 0] block_out ); @@ -61,33 +62,45 @@ module sha256_final_padding( //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - localparam CTRL_IDLE = 1'h0; - localparam CTRL_FINAL = 1'h1; + localparam CTRL_IDLE = 3'h0; + localparam CTRL_FINAL = 3'h1; + localparam CTRL_NEXT1 = 3'h2; + localparam CTRL_READY1 = 3'h3; + localparam CTRL_NEXT2 = 3'h4; + localparam CTRL_READY2 = 3'h5; + + localparam NO_INC = 2'h0; + localparam BLOCK_INC = 2'h1; + localparam FINAL_INC = 2'h2; //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- - reg [8 : 0] final_len_reg; - reg [8 : 0] final_len_we; + reg [511 : 0] block_out_reg; + reg [511 : 0] block_out_new; + reg block_out_we; + + reg [8 : 0] final_len_reg; + reg final_len_we; reg [63 : 0] bit_ctr_reg; reg [63 : 0] bit_ctr_new; reg bit_ctr_rst; - reg bit_ctr_block_inc; + reg [1 : 0] bit_ctr_inc; reg bit_ctr_we; - reg sha256_final_padding_ctrl_reg; - reg sha256_final_padding_ctrl_new; - reg sha256_final_padding_ctrl_we; + reg [2 : 0] sha256_final_padding_ctrl_reg; + reg [2 : 0] sha256_final_padding_ctrl_new; + reg [2 : 0] sha256_final_padding_ctrl_we; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- - reg [1 : 0] block_out_mux_ctrl; reg [511 : 0] tmp_block_out; reg tmp_next_out; + reg tmp_ready_out; //---------------------------------------------------------------- @@ -95,6 +108,7 @@ module sha256_final_padding( //---------------------------------------------------------------- assign init_out = init_in; assign next_out = tmp_next_out; + assign ready_out = tmp_ready_out; assign block_out = tmp_block_out; @@ -106,14 +120,19 @@ module sha256_final_padding( integer i; if (!reset_n) begin + block_out_reg <= 512'h0; final_len_reg <= 9'h0; bit_ctr_reg <= 64'h0; sha256_final_padding_ctrl_reg <= CTRL_IDLE; end else begin + if (block_out_we) begin + block_out_reg <= block_out_new; + end + if (final_len_we) begin - final_len_reg <= final_len; + final_len_reg = final_len; end if (bit_ctr_we) begin @@ -140,10 +159,15 @@ module sha256_final_padding( bit_ctr_we = 1'h1; end - if (bit_ctr_block_inc) begin + if (bit_ctr_inc == BLOCK_INC) begin bit_ctr_new = bit_ctr_reg + 9'h100; bit_ctr_we = 1'h1; end + + if (bit_ctr_inc == FINAL_INC) begin + bit_ctr_new = bit_ctr_reg + final_len; + bit_ctr_we = 1'h1; + end end @@ -153,14 +177,14 @@ module sha256_final_padding( //---------------------------------------------------------------- always @* begin : sha256_final_padding_ctrl - reg [63 : 0] msg_len; - - bit_ctr_rst = 1'h0; - bit_ctr_block_inc = 1'h0; + block_out_new = 512'h0; + block_out_we = 1'h0; final_len_we = 1'h0; - tmp_block_out = 512'h0; - tmp_next_out = 1'h0; - msg_len = 64'h0; + bit_ctr_rst = 1'h0; + bit_ctr_inc = NO_INC; + tmp_block_out = block_in; + tmp_next_out = next_in; + tmp_ready_out = core_ready; sha256_final_padding_ctrl_new = CTRL_IDLE; sha256_final_padding_ctrl_we = 1'h0; @@ -171,59 +195,96 @@ module sha256_final_padding( end if (next_in) begin - bit_ctr_block_inc = 1'h1; - tmp_block_out = block_in; - tmp_next_out = 1'h1; + bit_ctr_inc = BLOCK_INC; end if (final_in) begin - msg_len = bit_ctr_reg + final_len; - - if (final_len < 448) begin - // We fit in the final block. - tmp_next_out = 1'h1; - tmp_block_out = block_in; - tmp_block_out[(511 - final_len)] = 1'h1; - tmp_block_out[63 : 0] = msg_len; - end + tmp_next_out = 1'h0; + tmp_ready_out = 1'h0; + final_len_we = 1'h1; + block_out_new = block_in; + block_out_we = 1'h1; + bit_ctr_inc = FINAL_INC; + sha256_final_padding_ctrl_new = CTRL_FINAL; + sha256_final_padding_ctrl_we = 1'h1; + end + end - else if (final_len < 512) begin - // We fit the one, but not the counter. - // We will need another block. - final_len_we = 1'h1; - tmp_next_out = 1'h1; - tmp_block_out = block_in; - tmp_block_out[(511 - final_len)] = 1'h1; - sha256_final_padding_ctrl_new = CTRL_FINAL; - sha256_final_padding_ctrl_we = 1'h1; - end + CTRL_FINAL: begin + tmp_next_out = 1'h0; + tmp_ready_out = 1'h0; - else begin - // The whole block is filled. - // We will need another block. - final_len_we = 1'h1; - tmp_next_out = 1'h1; - tmp_block_out = block_in; - sha256_final_padding_ctrl_new = CTRL_FINAL; - sha256_final_padding_ctrl_we = 1'h1; - end + if (final_len_reg < 448) begin + block_out_new = block_in; + block_out_new[(511 - final_len_reg)] = 1'h1; + block_out_new[63 : 0] = bit_ctr_reg; + block_out_we = 1'h1; + + sha256_final_padding_ctrl_new = CTRL_NEXT2; + sha256_final_padding_ctrl_we = 1'h1; end - end + else if ((final_len >= 448) && (final_len < 511)) begin + block_out_new = block_in; + block_out_new[(511 - final_len_reg)] = 1'h1; + block_out_we = 1'h1; - CTRL_FINAL: begin - msg_len = bit_ctr_reg + final_len_reg; - sha256_final_padding_ctrl_new = CTRL_IDLE; + sha256_final_padding_ctrl_new = CTRL_NEXT1; + sha256_final_padding_ctrl_we = 1'h1; + end + + else begin + block_out_new = block_in; + block_out_we = 1'h1; + + sha256_final_padding_ctrl_new = CTRL_NEXT1; + sha256_final_padding_ctrl_we = 1'h1; + end + end + + CTRL_NEXT1: begin + tmp_next_out = 1'h1; + tmp_ready_out = 1'h0; + tmp_block_out = block_out_reg; + sha256_final_padding_ctrl_new = CTRL_READY1; sha256_final_padding_ctrl_we = 1'h1; + end + + + CTRL_READY1: begin + tmp_next_out = 1'h0; + tmp_ready_out = 1'h0; if (core_ready) begin + block_out_new[63 : 0] = bit_ctr_reg;; + block_out_we = 1'h1; + if (final_len_reg < 512) begin - tmp_block_out[63 : 0] = msg_len; - end - else begin - tmp_block_out[511] = 1'h1; - tmp_block_out[63 : 0] = msg_len; + block_out_new[511] = 1'h1; end + + sha256_final_padding_ctrl_new = CTRL_NEXT2; + sha256_final_padding_ctrl_we = 1'h1; + end + end + + + CTRL_NEXT2: begin + tmp_next_out = 1'h1; + tmp_ready_out = 1'h0; + tmp_block_out = block_out_reg; + sha256_final_padding_ctrl_new = CTRL_READY2; + sha256_final_padding_ctrl_we = 1'h1; + end + + + CTRL_READY2: begin + tmp_next_out = 1'h0; + tmp_ready_out = 1'h0; + + if (core_ready) begin + sha256_final_padding_ctrl_new = CTRL_IDLE; + sha256_final_padding_ctrl_we = 1'h1; end end diff --git a/src/tb/tb_sha256_final_padding.v b/src/tb/tb_sha256_final_padding.v index c33ea04..3b141cd 100644 --- a/src/tb/tb_sha256_final_padding.v +++ b/src/tb/tb_sha256_final_padding.v @@ -298,39 +298,77 @@ module tb_sha256_final_padding(); //---------------------------------------------------------------- // tc2 - // Test that triggers a the second type od padding where the - // padding does not fit and we get a single one block - // and a second block with the length at the end. + // Test that extends the FIPS 180-4 padding example in chapter + // 5.1.1 with a few more chars. //---------------------------------------------------------------- task tc2; begin : tc2 - reg tc2_error; - tc2_error = 0; tc_ctr = tc_ctr + 1; - $display("TC%2d started: Padding that does not fit in the block.", tc_ctr); + $display("TC%2d started: Extended NIST FIPS 180-4 padding example.", tc_ctr); tb_init_in = 1'h1; #(CLK_PERIOD); tb_init_in = 1'h0; #(CLK_PERIOD); - tb_block_in[511 : 0] = {{15{32'hdeadbeef}}, 32'h0}; - tb_final_len = 9'h1e0; + tb_block_in = 512'h0; + tb_block_in[511 : 440] = 72'h616263616263616263; + tb_final_len = 9'h048; tb_final_in = 1'h1; #(CLK_PERIOD); tb_final_in = 1'h0; - if (tb_block_out == {{15{32'hdeadbeef}}, 1'h1, 31'h0}) begin - $display("Correct first block: 0x%064x", tb_block_out); + if (tb_block_out == {72'h616263616263616263, 8'h80, 368'h0,64'h00000048}) begin + $display("Correct block: 0x%064x", tb_block_out); end else begin - $display("Incorrect first block: 0x%064x", tb_block_out); - $display("Expected first block: 0x%064x", {{15{32'hdeadbeef}}, 1'h1, 31'h0}); - tc2_error = 1; + $display("Incorrect block: 0x%064x", tb_block_out); + $display("Expected block: 0x%064x", {72'h616263616263616263, 8'h80, 368'h0,64'h00000048}); + error_ctr = error_ctr + 1; end + + $display("TC%2d completed", tc_ctr); $display(); + end + endtask // tc2 - #(2 * CLK_PERIOD); + + //---------------------------------------------------------------- + // tc3 + // Test that triggers a the second type od padding where the + // padding does not fit and we get a single one block + // and a second block with the length at the end. + //---------------------------------------------------------------- + task tc3; + begin : tc3 + reg tc2_error; + tc2_error = 0; + tc_ctr = tc_ctr + 1; + $display("TC%2d started: Padding that does not fit in the final block.", tc_ctr); + + tb_init_in = 1'h1; + #(CLK_PERIOD); + tb_init_in = 1'h0; + + #(CLK_PERIOD); + tb_block_in[511 : 0] = {{15{32'h13371337}}, 32'h0}; + tb_final_len = 9'h1e0; + tb_final_in = 1'h1; + + if (tb_next_out == 1'h1) begin + if (tb_block_out == {{15{32'h13371337}}, 1'h1, 31'h0}) begin + $display("Correct first block: 0x%064x", tb_block_out); + end + else begin + $display("Incorrect first block: 0x%064x", tb_block_out); + $display("Expected first block: 0x%064x", {{15{32'h13371337}}, 1'h1, 31'h0}); + tc2_error = 1; + end + end + + tb_final_in = 1'h0; + + #(10 * CLK_PERIOD); tb_core_ready = 1'h1; #(CLK_PERIOD); tb_core_ready = 1'h0; @@ -351,7 +389,7 @@ module tb_sha256_final_padding(); $display("TC%2d completed", tc_ctr); $display(); end - endtask // tc2 + endtask // tc3 //---------------------------------------------------------------- @@ -367,6 +405,7 @@ module tb_sha256_final_padding(); reset_dut(); tc1(); tc2(); + tc3(); display_test_result();