[Cryptech-Commits] [core/trng] 01/01: Adding first version of complete trng.

git at cryptech.is git at cryptech.is
Fri Sep 12 12:14:54 UTC 2014


This is an automated email from the git hooks/post-receive script.

joachim at secworks.se pushed a commit to branch master
in repository core/trng.

commit 25b6def7a26d90fd569cb8fc8c35468cf55bd9de
Author: Joachim Strömbergson <joachim at secworks.se>
Date:   Fri Sep 12 14:14:47 2014 +0200

    Adding first version of complete trng.
---
 src/rtl/trng.v | 539 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 539 insertions(+)

diff --git a/src/rtl/trng.v b/src/rtl/trng.v
new file mode 100644
index 0000000..f296ce5
--- /dev/null
+++ b/src/rtl/trng.v
@@ -0,0 +1,539 @@
+//======================================================================
+//
+// trng.v
+// --------
+// Top level wrapper for the True Random Number Generator.
+//
+//
+// Author: Joachim Strombergson
+// Copyright (c) 2014, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+//   notice, this list of conditions and the following disclaimer in the
+//   documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+//   be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module trng(
+            // Clock and reset.
+            input wire           clk,
+            input wire           reset_n,
+
+            input wire           avalanche_noise,
+
+            input wire           cs,
+            input wire           we,
+            input wire  [7 : 0]  address,
+            input wire  [31 : 0] write_data,
+            output wire [31 : 0] read_data,
+            output wire          error,
+
+            output wire          security_error
+           );
+
+
+  //----------------------------------------------------------------
+  // Internal constant and parameter definitions.
+  //----------------------------------------------------------------
+  parameter ADDR_NAME0                  = 8'h00;
+  parameter ADDR_NAME1                  = 8'h01;
+  parameter ADDR_VERSION                = 8'h02;
+
+  parameter ADDR_TRNG_CTRL              = 8'h10;
+  parameter TRNG_CTRL_ENABLE_BIT        = 0;
+  parameter TRNG_CTRL_ENT0_ENABLE_BIT   = 1;
+  parameter TRNG_CTRL_ENT1_ENABLE_BIT   = 2;
+  parameter TRNG_CTRL_ENT2_ENABLE_BIT   = 3;
+  parameter TRNG_CTRL_SEED_BIT          = 8;
+
+  parameter ADDR_TRNG_STATUS            = 8'h11;
+
+  parameter ADDR_TRNG_RND_DATA          = 8'h20;
+  parameter ADDR_TRNG_RND_DATA_VALID    = 8'h21;
+  parameter TRNG_RND_VALID_BIT          = 0;
+
+  parameter ADDR_CSPRNG_NUM_ROUNDS      = 8'h30;
+  parameter ADDR_CSPRNG_NUM_BLOCKS_LOW  = 8'h31;
+  parameter ADDR_CSPRNG_NUM_BLOCKS_HIGH = 8'h32;
+
+  parameter ADDR_ENTROPY0_RAW           = 8'h40;
+  parameter ADDR_ENTROPY0_STATS         = 8'h41;
+
+  parameter ADDR_ENTROPY1_RAW           = 8'h50;
+  parameter ADDR_ENTROPY1_STATS         = 8'h51;
+
+  parameter ADDR_ENTROPY2_RAW           = 8'h60;
+  parameter ADDR_ENTROPY2_STATS         = 8'h61;
+
+
+  parameter TRNG_NAME0   = 32'h74726e67; // "trng"
+  parameter TRNG_NAME1   = 32'h20202020; // "    "
+  parameter TRNG_VERSION = 32'h302e3031; // "0.01"
+
+
+  parameter CSPRNG_DEFAULT_NUM_ROUNDS = 5'h18;
+  parameter CSPRNG_DEFAULT_NUM_BLOCKS = 64'h1000000000000000;
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg [4 : 0] csprng_num_rounds_reg;
+  reg [4 : 0] csprng_num_rounds_new;
+  reg         csprng_num_rounds_we;
+
+  reg [31 : 0] csprng_num_blocks_low_reg;
+  reg [31 : 0] csprng_num_blocks_low_new;
+  reg          csprng_num_blocks_low_we;
+
+  reg [31 : 0] csprng_num_blocks_high_reg;
+  reg [31 : 0] csprng_num_blocks_high_new;
+  reg          csprng_num_blocks_high_we;
+
+  reg          entropy0_enable_reg;
+  reg          entropy0_enable_new;
+  reg          entropy0_enable_we;
+
+  reg          entropy1_enable_reg;
+  reg          entropy1_enable_new;
+  reg          entropy1_enable_we;
+
+  reg          entropy2_enable_reg;
+  reg          entropy2_enable_new;
+  reg          entropy2_enable_we;
+
+  reg         enable_reg;
+  reg         enable_new;
+  reg         enable_we;
+
+  reg         csprng_seed_reg;
+  reg         csprng_seed_new;
+
+  reg         csprng_rnd_ack_reg;
+  reg         csprng_rnd_ack_new;
+
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  wire           entropy0_enable;
+  wire [31 : 0]  entropy0_raw;
+  wire [31 : 0]  entropy0_stats;
+  wire           entropy0_enabled;
+  wire           entropy0_syn;
+  wire [31 : 0]  entropy0_data;
+  wire           entropy0_ack;
+
+  wire           entropy1_enable;
+  wire [31 : 0]  entropy1_raw;
+  wire [31 : 0]  entropy1_stats;
+  wire           entropy1_enabled;
+  wire           entropy1_syn;
+  wire [31 : 0]  entropy1_data;
+  wire           entropy1_ack;
+
+  wire           entropy2_enable;
+  wire [31 : 0]  entropy2_raw;
+  wire [31 : 0]  entropy2_stats;
+  wire           entropy2_enabled;
+  wire           entropy2_syn;
+  wire [31 : 0]  entropy2_data;
+  wire           entropy2_ack;
+
+  reg            mixer_enable;
+  wire [511 : 0] mixer_seed_data;
+  wire           mixer_seed_syn;
+  wire           mixer_seed_ack;
+
+  wire           csprng_enable;
+  wire           csprng_debug_mode;
+  wire [4 : 0]   csprng_num_rounds;
+  wire [63 : 0]  csprng_num_blocks;
+  wire           csprng_seed;
+  wire           csprng_more_seed;
+  wire           csprng_ready;
+  wire           csprng_error;
+  wire [31 : 0]  csprng_rnd_data;
+  wire           csprng_rnd_syn;
+
+  reg [31 : 0]   tmp_read_data;
+  reg            tmp_error;
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign read_data      = tmp_read_data;
+  assign error          = tmp_error;
+  assign security_error = 0;
+
+  assign csprng_num_blocks = {csprng_num_blocks_high_reg,
+                              csprng_num_blocks_low_reg};
+
+  assign entropy0_enable = entropy0_enable_reg;
+  assign entropy1_enable = entropy1_enable_reg;
+  assign entropy2_enable = entropy2_enable_reg;
+
+
+  //----------------------------------------------------------------
+  // core instantiations.
+  //----------------------------------------------------------------
+  trng_mixer mixer(
+                   .clk(clk),
+                   .reset_n(reset_n),
+
+                   .enable(mixer_enable),
+                   .more_seed(csprng_more_seed),
+
+                   .entropy0_enabled(entropy0_enabled),
+                   .entropy0_syn(entropy0_syn),
+                   .entropy0_data(entropy0_data),
+                   .entropy0_ack(entropy0_ack),
+
+                   .entropy1_enabled(entropy1_enabled),
+                   .entropy1_syn(entropy1_syn),
+                   .entropy1_data(entropy1_data),
+                   .entropy1_ack(entropy1_ack),
+
+                   .entropy2_enabled(entropy2_enabled),
+                   .entropy2_syn(entropy2_syn),
+                   .entropy2_data(entropy2_data),
+                   .entropy2_ack(entropy2_ack),
+
+                   .seed_data(mixer_seed_data),
+                   .seed_syn(mixer_seed_syn),
+                   .seed_ack(mixer_seed_ack)
+                  );
+
+  trng_csprng csprng(
+                     .clk(clk),
+                     .reset_n(reset_n),
+
+                     .enable(csprng_enable),
+                     .debug_mode(csprng_debug_mode),
+                     .num_rounds(csprng_num_rounds_reg),
+                     .num_blocks(csprng_num_blocks),
+                     .seed(csprng_seed),
+                     .more_seed(csprng_more_seed),
+                     .ready(csprng_ready),
+                     .error(csprng_error),
+
+                     .seed_data(mixer_seed_data),
+                     .seed_syn(mixer_seed_syn),
+                     .seed_ack(csprng_seed_ack),
+
+                     .rnd_data(csprng_rnd_data),
+                     .rnd_syn(csprng_rnd_syn),
+                     .rnd_ack(csprng_rnd_ack_reg)
+                    );
+
+  pseudo_entropy entropy0(
+                          .clk(clk),
+                          .reset_n(reset_n),
+
+                          .enable(entropy0_enable),
+
+                          .raw_entropy(entropy0_raw),
+                          .stats(entropy0_stats),
+
+                          .enabled(entropy0_enabled),
+                          .entropy_syn(entropy0_syn),
+                          .entropy_data(entropy0_data),
+                          .entropy_ack(entropy0_ack)
+                         );
+
+  avalance_entropy entropy1(
+                            .clk(clk),
+                            .reset_n(reset_n),
+
+                            .enable(entropy1_enable),
+
+                            .noise(avalanche_noise),
+
+                            .raw_entropy(entropy1_raw),
+                            .stats(entropy1_stats),
+
+                            .enabled(entropy1_enabled),
+                            .entropy_syn(entropy1_syn),
+                            .entropy_data(entropy1_data),
+                            .entropy_ack(entropy1_ack)
+                           );
+
+  ringosc_entropy entropy2(
+                           .clk(clk),
+                           .reset_n(reset_n),
+
+                           .enable(entropy2_enable),
+
+                           .raw_entropy(entropy2_raw),
+                           .stats(entropy2_stats),
+
+                           .enabled(entropy2_enabled),
+                           .entropy_syn(entropy2_syn),
+                           .entropy_data(entropy2_data),
+                           .entropy_ack(entropy2_ack)
+                          );
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //
+  // Update functionality for all registers in the core.
+  // All registers are positive edge triggered with asynchronous
+  // active low reset. All registers have write enable.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin
+      if (!reset_n)
+        begin
+          entropy0_enable_reg        <= 1;
+          entropy1_enable_reg        <= 1;
+          entropy2_enable_reg        <= 1;
+          enable_reg                 <= 1;
+          csprng_rnd_ack_reg         <= 0;
+          csprng_seed_reg            <= 0;
+          csprng_num_rounds_reg      <= CSPRNG_DEFAULT_NUM_ROUNDS;
+          csprng_num_blocks_low_reg  <= CSPRNG_DEFAULT_NUM_BLOCKS[31 : 0];
+          csprng_num_blocks_high_reg <= CSPRNG_DEFAULT_NUM_BLOCKS[63 : 32];
+        end
+
+      else
+        begin
+          csprng_rnd_ack_reg <= csprng_rnd_ack_new;
+          csprng_seed_reg    <= csprng_seed_new;
+
+          if (entropy0_enable_we)
+            begin
+              entropy0_enable_reg <= entropy0_enable_new;
+            end
+
+          if (entropy1_enable_we)
+            begin
+              entropy1_enable_reg <= entropy1_enable_new;
+            end
+
+          if (entropy2_enable_we)
+            begin
+              entropy2_enable_reg <= entropy2_enable_new;
+            end
+
+          if (enable_we)
+            begin
+              enable_reg <= enable_new;
+            end
+
+          if (csprng_num_rounds_we)
+            begin
+              csprng_num_rounds_reg <= csprng_num_rounds_new;
+            end
+
+          if (csprng_num_blocks_low_we)
+            begin
+              csprng_num_blocks_low_reg <= csprng_num_blocks_low_new;
+            end
+
+          if (csprng_num_blocks_high_we)
+            begin
+              csprng_num_blocks_high_reg <= csprng_num_blocks_high_new;
+            end
+        end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // api_logic
+  //
+  // Implementation of the api logic. If cs is enabled will either
+  // try to write to or read from the internal registers.
+  //----------------------------------------------------------------
+  always @*
+    begin : api_logic
+      entropy0_enable_new        = 0;
+      entropy0_enable_we         = 0;
+      entropy1_enable_new        = 0;
+      entropy1_enable_we         = 0;
+      entropy2_enable_new        = 0;
+      entropy2_enable_we         = 0;
+      enable_new                 = 0;
+      enable_we                  = 0;
+      csprng_seed_new            = 0;
+      csprng_rnd_ack_new         = 0;
+      csprng_seed_new            = 0;
+      csprng_num_rounds_new      = 5'h00;
+      csprng_num_rounds_we       = 0;
+      csprng_num_blocks_low_new  = 32'h00000000;
+      csprng_num_blocks_low_we   = 0;
+      csprng_num_blocks_high_new = 32'h00000000;
+      csprng_num_blocks_high_we  = 0;
+      tmp_read_data              = 32'h00000000;
+      tmp_error                  = 0;
+
+      if (cs)
+        begin
+          if (we)
+            begin
+              case (address)
+                // Write operations.
+                ADDR_TRNG_CTRL:
+                  begin
+                    enable_new          = write_data[TRNG_CTRL_ENABLE_BIT];
+                    enable_we           = 1;
+                    entropy0_enable_new = write_data[TRNG_CTRL_ENT0_ENABLE_BIT];
+                    entropy0_enable_we  = 1;
+                    entropy1_enable_new = write_data[TRNG_CTRL_ENT1_ENABLE_BIT];
+                    entropy1_enable_we  = 1;
+                    entropy2_enable_new = write_data[TRNG_CTRL_ENT2_ENABLE_BIT];
+                    entropy2_enable_we  = 1;
+                    csprng_seed_new     = write_data[TRNG_CTRL_SEED_BIT];
+                  end
+
+                ADDR_CSPRNG_NUM_ROUNDS:
+                  begin
+                    csprng_num_rounds_new = write_data[4 : 0];
+                    csprng_num_rounds_we  = 1;
+                  end
+
+                ADDR_CSPRNG_NUM_BLOCKS_LOW:
+                  begin
+                    csprng_num_blocks_low_new = write_data;
+                    csprng_num_blocks_low_we  = 1;
+                  end
+
+                ADDR_CSPRNG_NUM_BLOCKS_HIGH:
+                  begin
+                    csprng_num_blocks_high_new = write_data;
+                    csprng_num_blocks_high_we  = 1;
+                  end
+
+                default:
+                  begin
+                    tmp_error = 1;
+                  end
+              endcase // case (address)
+            end // if (we)
+
+          else
+            begin
+              case (address)
+                // Read operations.
+                ADDR_NAME0:
+                  begin
+                    tmp_read_data = TRNG_NAME0;
+                  end
+
+                ADDR_NAME1:
+                  begin
+                    tmp_read_data = TRNG_NAME1;
+                  end
+
+                ADDR_VERSION:
+                  begin
+                    tmp_read_data = TRNG_VERSION;
+                  end
+
+                ADDR_TRNG_CTRL:
+                  begin
+                    tmp_read_data[TRNG_CTRL_ENABLE_BIT]      = enable_reg;
+                    tmp_read_data[TRNG_CTRL_ENT0_ENABLE_BIT] = entropy0_enable_reg;
+                    tmp_read_data[TRNG_CTRL_ENT1_ENABLE_BIT] = entropy1_enable_reg;
+                    tmp_read_data[TRNG_CTRL_ENT2_ENABLE_BIT] = entropy2_enable_reg;
+                    tmp_read_data[TRNG_CTRL_SEED_BIT]        = csprng_seed_reg;
+                  end
+
+                ADDR_TRNG_STATUS:
+                  begin
+
+                  end
+
+                ADDR_TRNG_RND_DATA:
+                  begin
+                    csprng_rnd_ack_new = 1;
+                    tmp_read_data      = csprng_rnd_data;
+                  end
+
+                ADDR_TRNG_RND_DATA_VALID:
+                  begin
+                    tmp_read_data[TRNG_RND_VALID_BIT] = csprng_rnd_syn;
+                  end
+
+                ADDR_CSPRNG_NUM_ROUNDS:
+                  begin
+                    tmp_read_data[4 : 0] = csprng_num_rounds_reg;
+                  end
+
+                ADDR_CSPRNG_NUM_BLOCKS_LOW:
+                  begin
+                    tmp_read_data = csprng_num_blocks_low_reg;
+                  end
+
+                ADDR_CSPRNG_NUM_BLOCKS_HIGH:
+                  begin
+                    tmp_read_data = csprng_num_blocks_high_reg;
+                  end
+
+                ADDR_ENTROPY0_RAW:
+                  begin
+                    tmp_read_data = entropy0_raw;
+                  end
+
+                ADDR_ENTROPY0_STATS:
+                  begin
+                    tmp_read_data = entropy0_stats;
+                  end
+
+                ADDR_ENTROPY1_RAW:
+                  begin
+                    tmp_read_data = entropy1_raw;
+                  end
+
+                ADDR_ENTROPY1_STATS:
+                  begin
+                    tmp_read_data = entropy1_stats;
+                  end
+
+                ADDR_ENTROPY2_RAW:
+                  begin
+                    tmp_read_data = entropy2_raw;
+                  end
+
+                ADDR_ENTROPY2_STATS:
+                  begin
+                    tmp_read_data = entropy2_stats;
+                  end
+
+                default:
+                  begin
+                    tmp_error = 1;
+                  end
+              endcase // case (address)
+            end
+        end
+    end // addr_decoder
+endmodule // trng
+
+//======================================================================
+// EOF trng.v
+//======================================================================



More information about the Commits mailing list