Skip to content

Commit

Permalink
Change final handling to FSM
Browse files Browse the repository at this point in the history
Signed-off-by: Joachim Strömbergson <[email protected]>
  • Loading branch information
secworks committed May 31, 2024
1 parent b9d309c commit 356b37a
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 73 deletions.
177 changes: 119 additions & 58 deletions src/rtl/sha256_final_padding.v
Original file line number Diff line number Diff line change
Expand Up @@ -54,47 +54,61 @@ module sha256_final_padding(

output wire init_out,
output wire next_out,
output wire ready_out,
output wire [511 : 0] block_out
);


//----------------------------------------------------------------
// 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;


//----------------------------------------------------------------
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
assign init_out = init_in;
assign next_out = tmp_next_out;
assign ready_out = tmp_ready_out;
assign block_out = tmp_block_out;


Expand All @@ -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
Expand All @@ -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


Expand All @@ -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;

Expand All @@ -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

Expand Down
69 changes: 54 additions & 15 deletions src/tb/tb_sha256_final_padding.v
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -351,7 +389,7 @@ module tb_sha256_final_padding();
$display("TC%2d completed", tc_ctr);
$display();
end
endtask // tc2
endtask // tc3


//----------------------------------------------------------------
Expand All @@ -367,6 +405,7 @@ module tb_sha256_final_padding();
reset_dut();
tc1();
tc2();
tc3();

display_test_result();

Expand Down

0 comments on commit 356b37a

Please sign in to comment.