aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoachim StroĢˆmbergson <joachim@secworks.se>2015-05-22 10:34:50 +0200
committerJoachim StroĢˆmbergson <joachim@secworks.se>2015-05-22 10:34:50 +0200
commitd5974ed0d389f8953b23d98bb69b1576adad27b8 (patch)
treee604e1ade476afbb3e312d3d923d1ec62fcf2913
parent92790f3b539f275a060ca6bd4e2d91a9e5b13718 (diff)
(1) Added a cipher block statistics counter. (2) Cleaned up the csprng code and connected discard for fast restart of trng. (3) Added addresses for allowing API to write a known seed to allow test mode. (3) Fixed a number of minor issues during linting. (4) Fixed the csprng testbench to actually generate data as well as displaying the block stat counter.
-rw-r--r--src/rtl/trng_csprng.v107
-rw-r--r--src/rtl/trng_csprng_fifo.v2
-rw-r--r--src/tb/fake_modules/avalanche_entropy.v4
-rw-r--r--src/tb/fake_modules/rosc_entropy.v6
-rw-r--r--src/tb/tb_csprng.v67
5 files changed, 117 insertions, 69 deletions
diff --git a/src/rtl/trng_csprng.v b/src/rtl/trng_csprng.v
index eda9eea..ce5c89c 100644
--- a/src/rtl/trng_csprng.v
+++ b/src/rtl/trng_csprng.v
@@ -76,12 +76,32 @@ module trng_csprng(
localparam ADDR_STATUS = 8'h11;
localparam STATUS_RND_VALID_BIT = 0;
+ localparam ADDR_STAT_BLOCKS_LOW = 8'h14;
+ localparam ADDR_STAT_BLOCKS_HIGH = 8'h15;
+
localparam ADDR_RND_DATA = 8'h20;
localparam ADDR_NUM_ROUNDS = 8'h40;
localparam ADDR_NUM_BLOCKS_LOW = 8'h41;
localparam ADDR_NUM_BLOCKS_HIGH = 8'h42;
+ localparam ADDR_TEST_SEED_W00 = 8'h80;
+ localparam ADDR_TEST_SEED_W01 = 8'h81;
+ localparam ADDR_TEST_SEED_W02 = 8'h82;
+ localparam ADDR_TEST_SEED_W03 = 8'h83;
+ localparam ADDR_TEST_SEED_W04 = 8'h84;
+ localparam ADDR_TEST_SEED_W05 = 8'h85;
+ localparam ADDR_TEST_SEED_W06 = 8'h86;
+ localparam ADDR_TEST_SEED_W07 = 8'h87;
+ localparam ADDR_TEST_SEED_W08 = 8'h88;
+ localparam ADDR_TEST_SEED_W09 = 8'h89;
+ localparam ADDR_TEST_SEED_W10 = 8'h8a;
+ localparam ADDR_TEST_SEED_W11 = 8'h8b;
+ localparam ADDR_TEST_SEED_W12 = 8'h8c;
+ localparam ADDR_TEST_SEED_W13 = 8'h8d;
+ localparam ADDR_TEST_SEED_W14 = 8'h8e;
+ localparam ADDR_TEST_SEED_W15 = 8'h8f;
+
localparam CIPHER_KEYLEN256 = 1'b1; // 256 bit key.
localparam CIPHER_MAX_BLOCKS = 64'h1000000000000000;
@@ -130,6 +150,9 @@ module trng_csprng(
reg block_ctr_we;
reg block_ctr_max;
+ reg [63 : 0] block_stat_ctr_reg;
+ reg [63 : 0] block_stat_ctr_new;
+
reg ready_reg;
reg ready_new;
reg ready_we;
@@ -185,8 +208,6 @@ module trng_csprng(
reg rnd_ack;
reg fifo_cipher_data_valid;
- wire [63 : 0] num_blocks;
-
wire muxed_rnd_ack;
@@ -199,8 +220,6 @@ module trng_csprng(
assign more_seed = more_seed_reg;
assign debug = rnd_data[7 : 0];
assign security_error = 0;
-
- assign num_blocks = {num_blocks_high_reg, num_blocks_low_reg};
assign muxed_rnd_ack = rnd_ack | debug_update;
@@ -259,6 +278,7 @@ module trng_csprng(
cipher_ctr_reg <= {2{32'h00000000}};
cipher_block_reg <= {16{32'h00000000}};
block_ctr_reg <= {2{32'h00000000}};
+ block_stat_ctr_reg <= {2{32'h00000000}};
more_seed_reg <= 0;
seed_ack_reg <= 0;
ready_reg <= 0;
@@ -291,7 +311,10 @@ module trng_csprng(
cipher_block_reg <= cipher_block_new;
if (block_ctr_we)
- block_ctr_reg <= block_ctr_new;
+ begin
+ block_ctr_reg <= block_ctr_new;
+ block_stat_ctr_reg <= block_stat_ctr_new;
+ end
if (ready_we)
ready_reg <= ready_new;
@@ -378,50 +401,40 @@ module trng_csprng(
case (address)
// Read operations.
ADDR_NAME0:
- begin
tmp_read_data = CORE_NAME0;
- end
ADDR_NAME1:
- begin
tmp_read_data = CORE_NAME1;
- end
ADDR_VERSION:
- begin
tmp_read_data = CORE_VERSION;
- end
ADDR_CTRL:
- begin
tmp_read_data = {30'h00000000, seed_reg, enable_reg};
- end
ADDR_STATUS:
- begin
tmp_read_data = {30'h00000000, ready_reg, rnd_syn};
- end
+
+ ADDR_STAT_BLOCKS_LOW:
+ tmp_read_data = block_stat_ctr_reg[31 : 0];
+
+ ADDR_STAT_BLOCKS_HIGH:
+ tmp_read_data = block_stat_ctr_reg[63 : 32];
ADDR_RND_DATA:
begin
tmp_read_data = rnd_data;
- rnd_ack = 1;
+ rnd_ack = 1;
end
ADDR_NUM_ROUNDS:
- begin
tmp_read_data = {27'h0000000, num_rounds_reg};
- end
ADDR_NUM_BLOCKS_LOW:
- begin
tmp_read_data = num_blocks_low_reg;
- end
ADDR_NUM_BLOCKS_HIGH:
- begin
tmp_read_data = num_blocks_high_reg;
- end
default:
begin
@@ -440,28 +453,36 @@ module trng_csprng(
// ability to detect that maximum allowed number of blocks
// has been reached. Either as defined by the application
// or the hard coded CIPHER_MAX_BLOCKS value.
+
+ // The stat counter is a sepatate block counter updated in
+ // sync with the block counter. It is only used to track the
+ // number of blocks generated from the cipher as a metric
+ // provided to the system. The stat counter is never reset.
//----------------------------------------------------------------
always @*
begin : block_ctr
- block_ctr_new = 64'h0000000000000000;
- block_ctr_we = 0;
- block_ctr_max = 0;
+ block_ctr_new = {2{32'h00000000}};
+ block_ctr_we = 1'b0;
+ block_ctr_max = 1'b0;
+ block_stat_ctr_new = {2{32'h00000000}};
if (block_ctr_rst)
begin
- block_ctr_new = 64'h0000000000000000;
- block_ctr_we = 1;
+ block_ctr_new = {2{32'h00000000}};
+ block_ctr_we = 1'b1;
end
if (block_ctr_inc)
begin
- block_ctr_new = block_ctr_reg + 1'b1;
- block_ctr_we = 1;
+ block_ctr_new = block_ctr_reg + 1'b1;
+ block_stat_ctr_new = block_stat_ctr_reg + 1'b1;
+ block_ctr_we = 1;
end
- if ((block_ctr_reg == num_blocks) || (block_ctr_reg == CIPHER_MAX_BLOCKS))
+ if ((block_ctr_reg == {num_blocks_high_reg, num_blocks_low_reg}) ||
+ (block_ctr_reg == CIPHER_MAX_BLOCKS))
begin
- block_ctr_max = 1;
+ block_ctr_max = 1'b1;
end
end // block_ctr
@@ -497,7 +518,7 @@ module trng_csprng(
case (csprng_ctrl_reg)
CTRL_IDLE:
begin
- if (!enable_reg)
+ if (!enable_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -512,7 +533,7 @@ module trng_csprng(
CTRL_SEED0:
begin
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -529,7 +550,7 @@ module trng_csprng(
CTRL_NSYN:
begin
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -544,7 +565,7 @@ module trng_csprng(
CTRL_SEED1:
begin
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -569,7 +590,7 @@ module trng_csprng(
CTRL_INIT0:
begin
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -585,7 +606,7 @@ module trng_csprng(
CTRL_INIT1:
begin
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -599,7 +620,7 @@ module trng_csprng(
CTRL_NEXT0:
begin
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -613,12 +634,12 @@ module trng_csprng(
end
CTRL_NEXT1:
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
end
- else if (cipher_ready)
+ else if (cipher_ready && cipher_data_out_valid)
begin
block_ctr_inc = 1;
fifo_cipher_data_valid = 1;
@@ -628,7 +649,7 @@ module trng_csprng(
CTRL_MORE:
begin
- if ((!enable_reg) || (seed_reg))
+ if ((!enable_reg) || seed_reg || discard)
begin
csprng_ctrl_new = CTRL_CANCEL;
csprng_ctrl_we = 1;
@@ -665,6 +686,10 @@ module trng_csprng(
csprng_ctrl_we = 1;
end
+ default:
+ begin
+ end
+
endcase // case (cspng_ctrl_reg)
end // csprng_ctrl_fsm
diff --git a/src/rtl/trng_csprng_fifo.v b/src/rtl/trng_csprng_fifo.v
index 9c52ef5..1f91802 100644
--- a/src/rtl/trng_csprng_fifo.v
+++ b/src/rtl/trng_csprng_fifo.v
@@ -447,7 +447,7 @@ module trng_csprng_fifo(
begin
if (!fifo_full)
begin
- more_data_new = 1;
+ more_data_new = 1'b1;
end
if (csprng_data_valid)
diff --git a/src/tb/fake_modules/avalanche_entropy.v b/src/tb/fake_modules/avalanche_entropy.v
index 857926c..2caf743 100644
--- a/src/tb/fake_modules/avalanche_entropy.v
+++ b/src/tb/fake_modules/avalanche_entropy.v
@@ -80,9 +80,9 @@ module avalanche_entropy(
.clk(clk),
.reset_n(reset_n),
- .enable(1),
+ .enable(1'b1),
- .raw_entropy(noise),
+ .raw_entropy(),
.stats(),
.enabled(entropy_enabled),
diff --git a/src/tb/fake_modules/rosc_entropy.v b/src/tb/fake_modules/rosc_entropy.v
index b66bd90..add8b7a 100644
--- a/src/tb/fake_modules/rosc_entropy.v
+++ b/src/tb/fake_modules/rosc_entropy.v
@@ -41,8 +41,6 @@ module rosc_entropy(
input wire clk,
input wire reset_n,
- input wire noise,
-
input wire cs,
input wire we,
input wire [7 : 0] address,
@@ -80,9 +78,9 @@ module rosc_entropy(
.clk(clk),
.reset_n(reset_n),
- .enable(1),
+ .enable(1'b1),
- .raw_entropy(noise),
+ .raw_entropy(),
.stats(),
.enabled(entropy_enabled),
diff --git a/src/tb/tb_csprng.v b/src/tb/tb_csprng.v
index f860258..0404b56 100644
--- a/src/tb/tb_csprng.v
+++ b/src/tb/tb_csprng.v
@@ -55,6 +55,25 @@ module tb_csprng();
parameter CLK_HALF_PERIOD = 1;
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
+ localparam ADDR_NAME0 = 8'h00;
+ localparam ADDR_NAME1 = 8'h01;
+ localparam ADDR_VERSION = 8'h02;
+
+ localparam ADDR_CTRL = 8'h10;
+ localparam CTRL_ENABLE_BIT = 0;
+ localparam CTRL_SEED_BIT = 1;
+
+ localparam ADDR_STATUS = 8'h11;
+ localparam STATUS_RND_VALID_BIT = 0;
+
+ localparam ADDR_STAT_BLOCKS_LOW = 8'h14;
+ localparam ADDR_STAT_BLOCKS_HIGH = 8'h15;
+
+ localparam ADDR_RND_DATA = 8'h20;
+
+ localparam ADDR_NUM_ROUNDS = 8'h40;
+ localparam ADDR_NUM_BLOCKS_LOW = 8'h41;
+ localparam ADDR_NUM_BLOCKS_HIGH = 8'h42;
//----------------------------------------------------------------
// Register and Wire declarations.
@@ -166,17 +185,19 @@ module tb_csprng();
$display("test_mode = 0x%01x, seed = 0x%01x, enable = 0x%01x",
dut.test_mode, dut.seed_reg, dut.enable_reg);
$display("num_rounds = 0x%02x, num_blocks = 0x%016x",
- dut.num_rounds_reg, dut.num_blocks);
+ dut.num_rounds_reg, {dut.num_blocks_high_reg,
+ dut.num_blocks_low_reg});
$display("seed_syn = 0x%01x, seed_ack = 0x%01x, seed_data = 0x%064x",
dut.seed_syn, dut.seed_ack, dut.seed_data);
$display("");
$display("Internal states:");
- $display("cipher_key = 0x%032x", dut.cipher_key_reg);
- $display("cipher_iv = 0x%08x, cipher_ctr = 0x%08x",
+ $display("cipher_key = 0x%032x", dut.cipher_key_reg);
+ $display("cipher_iv = 0x%08x, cipher_ctr = 0x%08x",
dut.cipher_iv_reg, dut.cipher_ctr_reg);
- $display("cipher_block = 0x%064x", dut.cipher_block_reg);
- $display("csprng_ctrl = 0x%02x", dut.csprng_ctrl_reg);
+ $display("cipher_block = 0x%064x", dut.cipher_block_reg);
+ $display("csprng_blocks = 0x%016x", dut.block_stat_ctr_reg);
+ $display("csprng_ctrl = 0x%02x", dut.csprng_ctrl_reg);
$display("");
$display("Cipher states:");
@@ -192,7 +213,7 @@ module tb_csprng();
$display("Outputs:");
$display("rnd_syn = 0x%01x, rnd_ack = 0x%01x, rnd_data = 0x%08x",
- dut.rnd_syn, dut.rnd_ack, dut.rnd_data);
+ dut.rnd_syn, dut.rnd_ack, tb_read_data);
$display("");
end
endtask // dump_dut_state
@@ -203,7 +224,7 @@ module tb_csprng();
//
// Write the given word to the DUT using the DUT interface.
//----------------------------------------------------------------
- task write_word(input [11 : 0] address,
+ task write_word(input [11 : 0] address,
input [31 : 0] word);
begin
if (DEBUG)
@@ -317,25 +338,30 @@ module tb_csprng();
//----------------------------------------------------------------
- // tc1_test_init_cipher()
+ // tc1_init_csprng()
//
// TC1: Test that the DUT automatically starts initialize when
- // enable is set.
+ // enable is set. We also starts pulling random data from the
+ // csprng to see that it actually emits data as expected.
//----------------------------------------------------------------
- task tc1_test_init_cipher();
+ task tc1_init_csprng();
begin
- $display("*** TC1: Test automatic init of cipher started.");
- // tb_num_blocks = 64'h0000000000000004;
- tb_seed_data = {8{64'haaaaaaaa55555555}};
- // tb_num_rounds = 5'h08;
- tb_rnd_ack = 1;
+ tc_ctr = tc_ctr + 1;
+
+ $display("*** TC1: Test automatic init of csprng started.");
+
+ tb_seed_data = {8{64'haaaaaaaa55555555}};
+ tb_seed_syn = 1'b1;
- #(2000 * CLK_PERIOD);
+ tb_cs = 1'b1;
+ tb_we = 1'b0;
+ tb_address = ADDR_RND_DATA;
- $display("*** TC1: Test automatic init of cipher done.");
+ #(200 * CLK_PERIOD);
+ $display("*** TC1: Test automatic init of csprng done.");
end
- endtask // tc1_test_init_cipher
+ endtask // tc1_init_csprng
//----------------------------------------------------------------
@@ -355,13 +381,12 @@ module tb_csprng();
reset_dut();
dump_dut_state();
- // Test code goes here.
- tc1_test_init_cipher();
+ tc1_init_csprng();
display_test_results();
$display("");
- $display("*** CSPRNG simulation done. ***");
+ $display("*** csprng simulation done. ***");
$finish;
end // csprng_test
endmodule // tb_csprng