[Cryptech-Commits] [core/rosc_entropy] 01/01: Adding a new core for ring oscillator based entropy.

git at cryptech.is git at cryptech.is
Thu Sep 18 16:40:01 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/rosc_entropy.

commit 2f468f182027217e72c08e684d32e4450917f5a4
Author: Joachim Strömbergson <joachim at secworks.se>
Date:   Thu Sep 18 18:39:54 2014 +0200

    Adding a new core for ring oscillator based entropy.
---
 src/rtl/rosc.v              | 109 ++++++++++++++++++
 src/rtl/rosc_entropy.v      | 261 +++++++++++++++++++++++++++++++++++++++++++
 src/rtl/rosc_entropy_core.v | 265 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 635 insertions(+)

diff --git a/src/rtl/rosc.v b/src/rtl/rosc.v
new file mode 100644
index 0000000..afcc9bf
--- /dev/null
+++ b/src/rtl/rosc.v
@@ -0,0 +1,109 @@
+//======================================================================
+//
+// rosc.v
+// ------
+// Digital ring oscillator used as entropy source. Based on the
+// idea of using carry chain in adders as inverter by Bernd Paysan.
+//
+//
+//
+// 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 rosc #(parameter WIDTH = 2)
+             (
+              input wire                   clk,
+              input wire                   reset_n,
+
+              input wire                   we,
+
+              input wire [(WIDTH - 1) : 0] opa,
+              input wire [(WIDTH - 1) : 0] opb,
+
+              output wire                  dout
+             );
+
+  //----------------------------------------------------------------
+  // Registers.
+  //----------------------------------------------------------------
+  reg dout_reg;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg [WIDTH : 0] sum;
+  reg 	          cin;
+
+
+  //----------------------------------------------------------------
+  // Concurrent assignment.
+  //----------------------------------------------------------------
+  assign dout = dout_reg;
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //----------------------------------------------------------------
+     always @ (posedge clk or negedge reset_n)
+       begin
+         if (!reset_n)
+           begin
+             dout_reg <= 1'b0;
+           end
+         else
+           begin
+             if (we)
+               begin
+                 dout_reg <= cin;
+               end
+           end
+       end
+
+
+  //----------------------------------------------------------------
+  // adder_osc
+  //
+  // Adder logic that generates the oscillator.
+  //
+  // NOTE: This logic contains a combinational loop and does
+  // not play well with an event driven simulator.
+  //----------------------------------------------------------------
+  always @*
+    begin: adder_osc
+      cin = ~sum[WIDTH];
+      sum = opa + opb + cin;
+    end
+endmodule // rosc
+
+//======================================================================
+// EOF rosc.v
+//======================================================================
diff --git a/src/rtl/rosc_entropy.v b/src/rtl/rosc_entropy.v
new file mode 100644
index 0000000..b407f3b
--- /dev/null
+++ b/src/rtl/rosc_entropy.v
@@ -0,0 +1,261 @@
+//======================================================================
+//
+// rosc_entropy.v
+// --------------
+// Top level wrapper for the ring oscillator entropy core.
+//
+//
+// 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 rosc_entropy(
+                    input wire           clk,
+                    input wire           reset_n,
+
+                    output wire [7 : 0]  debug,
+                    input wire           debug_update,
+
+                    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
+                   );
+
+
+  //----------------------------------------------------------------
+  // Parameters.
+  //----------------------------------------------------------------
+  parameter ADDR_CTRL            = 8'h00;
+  parameter CTRL_ENABLE_BIT      = 0;
+
+  parameter ADDR_STATUS          = 8'h01;
+  parameter STATUS_RND_VALID_BIT = 0;
+
+  parameter ADDR_OPA             = 8'h08;
+  parameter ADDR_OPB             = 8'h09;
+
+  parameter ADDR_ENTROPY         = 8'h10;
+  parameter ADDR_RND             = 8'h20;
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg          en_reg;
+  reg          en_new;
+  reg          en_we;
+
+  reg [31 : 0] op_a_reg;
+  reg [31 : 0] op_a_new;
+  reg          op_a_we;
+
+  reg [31 : 0] op_b_reg;
+  reg [31 : 0] op_b_new;
+  reg          op_b_we;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  wire [31 : 0] entropy;
+
+  wire [31 : 0] rnd_data;
+  wire          rnd_valid;
+  reg           rnd_ack;
+
+  reg [31 : 0]  tmp_read_data;
+  reg           tmp_error;
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign read_data = tmp_read_data;
+  assign error     = tmp_error;
+
+
+  //----------------------------------------------------------------
+  // module instantiations.
+  //----------------------------------------------------------------
+  rosc_entropy_core core(
+                         .clk(clk),
+                         .reset_n(reset_n),
+
+                         .enable(en_reg),
+
+                         .opa(op_a_reg),
+                         .opb(op_b_reg),
+
+                         .entropy(entropy),
+
+                         .rnd_data(rnd_data),
+                         .rnd_valid(rnd_valid),
+                         .rnd_ack(rnd_ack),
+
+                         .debug(debug),
+                         .debug_update(debug_update)
+                        );
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //
+  // Update functionality for all registers in the core.
+  // All registers are positive edge triggered with asynchronous
+  // active low reset.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin
+      if (!reset_n)
+        begin
+          en_reg   <= 1;
+          op_a_reg <= 32'h01010101;
+          op_a_reg <= 32'h10101010;
+        end
+      else
+        begin
+          if (en_we)
+            begin
+              en_reg <= en_new;
+            end
+
+          if (op_a_we)
+            begin
+              op_a_reg <= op_a_new;
+            end
+
+          if (op_b_we)
+            begin
+              op_b_reg <= op_b_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
+      en_new        = 0;
+      en_we         = 0;
+      op_a_new      = 0;
+      op_a_we       = 0;
+      op_b_new      = 0;
+      op_b_we       = 0;
+      rnd_ack       = 0;
+      tmp_read_data = 32'h00000000;
+      tmp_error     = 0;
+
+      if (cs)
+        begin
+          if (we)
+            begin
+              case (address)
+                // Write operations.
+                ADDR_CTRL:
+                  begin
+                    en_new = write_data[CTRL_ENABLE_BIT];
+                    en_we  = 1;
+                  end
+
+                ADDR_OPA:
+                  begin
+                    op_a_new = write_data;
+                    op_a_we  = 1;
+                  end
+
+                ADDR_OPB:
+                  begin
+                    op_b_new = write_data;
+                    op_b_we  = 1;
+                  end
+
+                default:
+                  begin
+                    tmp_error = 1;
+                  end
+              endcase // case (address)
+            end
+          else
+            begin
+              case (address)
+                ADDR_CTRL:
+                  begin
+                    tmp_read_data[CTRL_ENABLE_BIT] = en_reg;
+                  end
+
+                ADDR_STATUS:
+                  begin
+                    tmp_read_data[STATUS_RND_VALID_BIT] = rnd_valid;
+                  end
+
+              ADDR_OPA:
+                begin
+                  tmp_read_data = op_a_reg;
+                end
+
+              ADDR_OPB:
+                begin
+                  tmp_read_data = op_b_reg;
+                end
+
+                ADDR_ENTROPY:
+                  begin
+                    tmp_read_data = entropy;
+                  end
+
+                ADDR_RND:
+                  begin
+                    tmp_read_data = rnd_data;
+                    rnd_ack       = 1;
+                  end
+
+                default:
+                  begin
+                    tmp_error = 1;
+                  end
+              endcase // case (address)
+            end
+        end
+    end
+
+endmodule // rosc_entropy_core
+
+//======================================================================
+// EOF rosc_entropy_core.v
+//======================================================================
diff --git a/src/rtl/rosc_entropy_core.v b/src/rtl/rosc_entropy_core.v
new file mode 100644
index 0000000..5b4b8c4
--- /dev/null
+++ b/src/rtl/rosc_entropy_core.v
@@ -0,0 +1,265 @@
+//======================================================================
+//
+// rosc_entropy_core.v
+// -------------------
+// Digitial ring oscillator based entropy generation core.
+//
+//
+// 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 rosc_entropy_core(
+                         input wire           clk,
+                         input wire           reset_n,
+
+                         input wire           enable,
+
+                         input wire [31 : 0]  opa,
+                         input wire [31 : 0]  opb,
+
+                         output [31 : 0]      entropy,
+
+                         output wire [31 : 0] rnd_data,
+                         output wire          rnd_valid,
+                         input wire           rnd_ack,
+
+                         output wire [7 : 0]  debug,
+                         input wire           debug_update
+                        );
+
+
+  //----------------------------------------------------------------
+  // Parameters.
+  //----------------------------------------------------------------
+  parameter NUM_SHIFT_BITS    = 8'h20;
+  parameter SAMPLE_CLK_CYCLES = 8'hff;
+
+
+  //----------------------------------------------------------------
+  // Registers including update variables and write enable.
+  //----------------------------------------------------------------
+  reg [31 : 0] ent_shift_reg;
+  reg [31 : 0] ent_shift_new;
+
+  reg          ent_shift_we_reg;
+  reg          ent_shift_we_new;
+
+  reg [31 : 0] rnd_reg;
+  reg          rnd_we;
+
+  reg          rnd_valid_reg;
+  reg          rnd_valid_new;
+  reg          rnd_valid_we;
+
+  reg          bit_we_reg;
+  reg          bit_we_new;
+
+  reg [7 : 0]  bit_ctr_reg;
+  reg [7 : 0]  bit_ctr_new;
+  reg          bit_ctr_inc;
+  reg          bit_ctr_we;
+
+  reg [7 : 0]  sample_ctr_reg;
+  reg [7 : 0]  sample_ctr_new;
+
+  reg [7 : 0]  debug_reg;
+  reg          debug_update_reg;
+
+
+  //----------------------------------------------------------------
+  // Wires.
+  //----------------------------------------------------------------
+  reg           rosc_we;
+  wire [31 : 0] rosc_dout;
+
+
+  //----------------------------------------------------------------
+  // Concurrent connectivity for ports etc.
+  //----------------------------------------------------------------
+  assign entropy   = ent_shift_reg;
+  assign rnd_data  = rnd_reg;
+  assign rnd_valid = rnd_valid_reg;
+  assign debug     = debug_reg;
+
+
+  //----------------------------------------------------------------
+  // module instantiations.
+  //
+  // 32 1-bit wide oscillators. We want them to run as fast as
+  // possible to maximize differences over time.
+  //----------------------------------------------------------------
+  genvar i;
+  generate
+    for(i = 0 ; i < 32 ; i = i + 1)
+      begin: oscillators
+        rosc #(.WIDTH(1)) osc_array(.clk(clk),
+                                    .we(rosc_we),
+                                    .reset_n(reset_n),
+                                    .opa(opa),
+                                    .opb(opb),
+                                    .dout(rosc_dout[i])
+                                   );
+      end
+  endgenerate
+
+
+  //----------------------------------------------------------------
+  // reg_update
+  //
+  // Update functionality for all registers in the core.
+  // All registers are positive edge triggered with asynchronous
+  // active low reset.
+  //----------------------------------------------------------------
+  always @ (posedge clk or negedge reset_n)
+    begin
+      if (!reset_n)
+        begin
+          ent_shift_reg    <= 32'h00000000;
+          ent_shift_we_reg <= 0;
+          rnd_reg          <= 32'h00000000;
+          rnd_valid_reg    <= 0;
+          bit_ctr_reg      <= 8'h00;
+          sample_ctr_reg   <= 8'h00;
+          debug_reg        <= 8'h00;
+          debug_update_reg <= 0;
+        end
+      else
+        begin
+          sample_ctr_reg   <= sample_ctr_new;
+          ent_shift_we_reg <= ent_shift_we_new;
+          debug_update_reg <= debug_update;
+
+          if (ent_shift_we_reg)
+            begin
+              ent_shift_reg <= ent_shift_new;
+            end
+
+          if (bit_ctr_we)
+            begin
+              bit_ctr_reg <= bit_ctr_new;
+            end
+
+          if (rnd_we)
+            begin
+              rnd_reg <= ent_shift_reg;
+            end
+
+          if (rnd_valid_we)
+            begin
+              rnd_valid_reg <= rnd_valid_new;
+            end
+
+          if (debug_update_reg)
+            begin
+              debug_reg <= rnd_reg[7 : 0];
+            end
+         end
+    end // reg_update
+
+
+  //----------------------------------------------------------------
+  // rnd_out
+  //
+  // Logic that implements the random output control. If we have
+  // added more than NUM_SHIFT_BITS we raise the rnd_valid flag.
+  // When we detect and ACK, the valid flag is dropped.
+  //----------------------------------------------------------------
+  always @*
+    begin : rnd_out
+      bit_ctr_new   = 8'h00;
+      bit_ctr_we    = 0;
+      rnd_we        = 0;
+      rnd_valid_new = 0;
+      rnd_valid_we  = 0;
+
+      if (bit_ctr_inc)
+        begin
+
+          if (bit_ctr_reg < NUM_SHIFT_BITS)
+            begin
+              bit_ctr_new = bit_ctr_reg + 1'b1;
+              bit_ctr_we  = 1;
+            end
+          else
+            begin
+              rnd_we        = 1;
+              rnd_valid_new = 1;
+              rnd_valid_we  = 1;
+            end
+        end
+
+      if (rnd_ack)
+        begin
+          bit_ctr_new   = 8'h00;
+          bit_ctr_we    = 1;
+          rnd_valid_new = 0;
+          rnd_valid_we  = 1;
+        end
+    end
+
+
+  //----------------------------------------------------------------
+  // rnd_gen
+  //
+  // Logic that implements the actual random bit value generator
+  // by XOR mixing the oscillator outputs. These outputs are
+  // sampled once every SAMPLE_CLK_CYCLES.
+  //
+  // Note that the update of the shift register is delayed
+  // one cycle to allow the outputs from the oscillators
+  // to be updated.
+  //----------------------------------------------------------------
+  always @*
+    begin : rnd_gen
+      reg ent_bit;
+
+      bit_ctr_inc      = 0;
+      rosc_we          = 0;
+      ent_shift_we_new = 0;
+
+      ent_bit        = ^rosc_dout;
+      ent_shift_new  = {ent_shift_reg[30 : 0], ent_bit};
+
+      sample_ctr_new = sample_ctr_reg + 1'b1;
+
+      if (enable && (sample_ctr_reg == SAMPLE_CLK_CYCLES))
+        begin
+          sample_ctr_new   = 8'h00;
+          bit_ctr_inc      = 1;
+          rosc_we          = 1;
+          ent_shift_we_new = 1;
+        end
+    end
+endmodule // rosc_entropy_core
+
+//======================================================================
+// EOF rosc_entropy_core.v
+//======================================================================



More information about the Commits mailing list