mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2024-12-20 21:34:28 -05:00
Replace FiGaRO based TRNG with new ROSC based TRNG
This commit is contained in:
parent
af36a40f3e
commit
7e0692b150
@ -275,9 +275,8 @@ Assigned core prefixes:
|
||||
|
||||
| *name* | *fw* | *app | *size* | *type* | *content* | *description* |
|
||||
|--------------------|------|------------|--------|---------|-----------|--------------------------------------------------------|
|
||||
| `TRNG_STATUS` | r | r | | | | TBD |
|
||||
| `TRNG_SAMPLE_RATE` | | r | | | | TBD |
|
||||
| `TRNG_ENTROPY` | | | | | | TBD |
|
||||
| `TRNG_STATUS` | r | r | | | | Non-zero when an entropy word is available. |
|
||||
| `TRNG_ENTROPY` | r | r | | | | Entropy word. Reading a word will clear status. |
|
||||
| `TIMER_CTRL` | | | | | | TBD |
|
||||
| `TIMER_STATUS` | r | | | | | TBD |
|
||||
| `TIMER_PRESCALER` | | r/w | | | | TBD |
|
||||
|
@ -63,10 +63,7 @@ VERILOG_SRCS = \
|
||||
$(P)/core/uart/rtl/uart_core.v \
|
||||
$(P)/core/uart/rtl/uart_fifo.v \
|
||||
$(P)/core/uart/rtl/uart.v \
|
||||
$(P)/core/trng/rtl/firo.v \
|
||||
$(P)/core/trng/rtl/garo.v \
|
||||
$(P)/core/trng/rtl/figaro_core.v \
|
||||
$(P)/core/trng/rtl/figaro.v
|
||||
$(P)/core/trng/rtl/rosc.v
|
||||
|
||||
FIRMWARE_DEPS = \
|
||||
$(P)/fw/mta1_mkdf_mem.h \
|
||||
|
@ -1,204 +0,0 @@
|
||||
//======================================================================
|
||||
//
|
||||
// figaro_core.v
|
||||
// -----------
|
||||
// FiGaRO based FIGARO for iCE40 device.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module figaro_core(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire set_sample_rate,
|
||||
input wire [23 : 0] sample_rate,
|
||||
|
||||
input wire read_entropy,
|
||||
output wire [31 : 0] entropy,
|
||||
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Local parameters.
|
||||
//---------------------------------------------------------------
|
||||
localparam DEFAULT_SAMPLE_RATE = 24'h010000;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Registers.
|
||||
//---------------------------------------------------------------
|
||||
reg [23 : 0] sample_rate_ctr_reg;
|
||||
reg [23 : 0] sample_rate_ctr_new;
|
||||
|
||||
reg [23 : 0] sample_rate_reg;
|
||||
reg sample_rate_we;
|
||||
|
||||
reg [5 : 0] bit_ctr_reg;
|
||||
reg [5 : 0] bit_ctr_new;
|
||||
reg bit_ctr_rst;
|
||||
reg bit_ctr_inc;
|
||||
reg bit_ctr_we;
|
||||
|
||||
reg [31 : 0] entropy_reg;
|
||||
reg [31 : 0] entropy_new;
|
||||
reg entropy_we;
|
||||
|
||||
reg ready_reg;
|
||||
reg ready_new;
|
||||
reg ready_we;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Firo oscillator instances and XOR combined result.
|
||||
//---------------------------------------------------------------
|
||||
wire firo_ent[3 : 0];
|
||||
wire firo_entropy;
|
||||
|
||||
firo #(.POLY(10'b1111110111)) firo0(.clk(clk), .entropy(firo_ent[0]));
|
||||
firo #(.POLY(10'b1011111001)) firo1(.clk(clk), .entropy(firo_ent[1]));
|
||||
firo #(.POLY(10'b1100000001)) firo2(.clk(clk), .entropy(firo_ent[2]));
|
||||
firo #(.POLY(10'b1011111111)) firo3(.clk(clk), .entropy(firo_ent[3]));
|
||||
|
||||
assign firo_entropy = firo_ent[0] ^ firo_ent[1] ^
|
||||
firo_ent[2] ^ firo_ent[3];
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// garo oscillator instances and XOR combined result.
|
||||
//---------------------------------------------------------------
|
||||
wire garo_ent[3 : 0];
|
||||
wire garo_entropy;
|
||||
|
||||
garo #(.POLY(11'b11111101111)) garo0(.clk(clk), .entropy(garo_ent[0]));
|
||||
garo #(.POLY(11'b10111110011)) garo1(.clk(clk), .entropy(garo_ent[1]));
|
||||
garo #(.POLY(11'b11000000011)) garo2(.clk(clk), .entropy(garo_ent[2]));
|
||||
garo #(.POLY(11'b10111111111)) garo3(.clk(clk), .entropy(garo_ent[3]));
|
||||
|
||||
assign garo_entropy = garo_ent[0] ^ garo_ent[1] ^
|
||||
garo_ent[2] ^ garo_ent[3];
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Assignments.
|
||||
//---------------------------------------------------------------
|
||||
assign ready = ready_reg;
|
||||
assign entropy = entropy_reg;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// reg_update
|
||||
//---------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
sample_rate_reg <= DEFAULT_SAMPLE_RATE;
|
||||
sample_rate_ctr_reg <= 24'h0;
|
||||
bit_ctr_reg <= 6'h0;
|
||||
entropy_reg <= 32'h0;
|
||||
ready_reg <= 1'h0;
|
||||
end
|
||||
else begin
|
||||
sample_rate_ctr_reg <= sample_rate_ctr_new;
|
||||
|
||||
if (sample_rate_we) begin
|
||||
sample_rate_reg <= sample_rate;
|
||||
end
|
||||
|
||||
if (bit_ctr_we) begin
|
||||
bit_ctr_reg <= bit_ctr_new;
|
||||
end
|
||||
|
||||
if (entropy_we) begin
|
||||
entropy_reg <= entropy_new;
|
||||
end
|
||||
|
||||
if (ready_we) begin
|
||||
ready_reg <= ready_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// ready_logic
|
||||
//
|
||||
// After an entropy word has been read we wait 32 bits before
|
||||
// setting ready again, indicating that a new word is ready.
|
||||
//---------------------------------------------------------------
|
||||
always @*
|
||||
begin : ready_logic;
|
||||
bit_ctr_new = 6'h0;
|
||||
bit_ctr_we = 1'h0;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h0;
|
||||
|
||||
if (bit_ctr_reg >= 6'h20) begin
|
||||
ready_new = 1'h1;
|
||||
ready_we = 1'h1;
|
||||
end
|
||||
|
||||
if (bit_ctr_rst) begin
|
||||
bit_ctr_new = 6'h0;
|
||||
bit_ctr_we = 1'h1;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h1;
|
||||
end
|
||||
|
||||
else if (bit_ctr_inc) begin
|
||||
if (bit_ctr_reg < 6'h24) begin
|
||||
bit_ctr_new = bit_ctr_reg + 1'h1;
|
||||
bit_ctr_we = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// figaro_sample_logic
|
||||
//
|
||||
// Wait sample_rate_reg number of cycles between sampling a bit
|
||||
// from the entropy source.
|
||||
//---------------------------------------------------------------
|
||||
always @*
|
||||
begin : figaro_sample_logic
|
||||
sample_rate_we = 1'h0;
|
||||
bit_ctr_rst = 1'h0;
|
||||
bit_ctr_inc = 1'h0;
|
||||
entropy_we = 1'h0;
|
||||
|
||||
entropy_new = {entropy_reg[30 : 0], firo_entropy ^ garo_entropy};
|
||||
|
||||
if (read_entropy) begin
|
||||
bit_ctr_rst = 1'h1;
|
||||
sample_rate_ctr_new = 24'h0;
|
||||
end
|
||||
|
||||
else if (set_sample_rate) begin
|
||||
bit_ctr_rst = 1'h1;
|
||||
sample_rate_we = 1'h1;
|
||||
sample_rate_ctr_new = 24'h0;
|
||||
end
|
||||
|
||||
else if (sample_rate_ctr_reg == sample_rate_reg) begin
|
||||
sample_rate_ctr_new = 24'h0;
|
||||
entropy_we = 1'h1;
|
||||
bit_ctr_inc = 1'h1;
|
||||
end
|
||||
|
||||
else begin
|
||||
sample_rate_ctr_new = sample_rate_ctr_reg + 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // figaro_core
|
||||
|
||||
//======================================================================
|
||||
// EOF figaro_core.v
|
||||
//======================================================================
|
@ -1,80 +0,0 @@
|
||||
//======================================================================
|
||||
//
|
||||
// firo.v
|
||||
// ------
|
||||
// Fibonacci Ring Oscillator with state sampling.
|
||||
// The Fibonacci depth is 10 bits, and the bits are always sampled.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module firo(
|
||||
input wire clk,
|
||||
output wire entropy
|
||||
);
|
||||
|
||||
parameter POLY = 10'b1111111111;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers and wires.
|
||||
//----------------------------------------------------------------
|
||||
reg entropy_reg;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
wire [10 : 0] f;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Combinational loop inverters.
|
||||
//---------------------------------------------------------------
|
||||
/* verilator lint_off PINMISSING */
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv1 (.I0(f[0]), .O(f[1]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv2 (.I0(f[1]), .O(f[2]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv3 (.I0(f[2]), .O(f[3]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv4 (.I0(f[3]), .O(f[4]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv5 (.I0(f[4]), .O(f[5]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv6 (.I0(f[5]), .O(f[6]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv7 (.I0(f[6]), .O(f[7]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv8 (.I0(f[7]), .O(f[8]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv9 (.I0(f[8]), .O(f[9]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv10 (.I0(f[9]), .O(f[10]));
|
||||
/* verilator lint_on PINMISSING */
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// parameterized feedback logic.
|
||||
//---------------------------------------------------------------
|
||||
assign f[0] = (POLY[0] & f[1]) ^ (POLY[1] & f[2]) ^
|
||||
(POLY[2] & f[3]) ^ (POLY[3] & f[4]) ^
|
||||
(POLY[4] & f[5]) ^ (POLY[5] & f[6]) ^
|
||||
(POLY[6] & f[7]) ^ (POLY[7] & f[8]) ^
|
||||
(POLY[8] & f[9]) ^ (POLY[9] & f[10]);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign entropy = entropy_reg;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// reg_update
|
||||
//---------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
entropy_reg <= ^f;
|
||||
end
|
||||
|
||||
endmodule // firo
|
||||
|
||||
//======================================================================
|
||||
// EOF firo.v
|
||||
//======================================================================
|
@ -1,90 +0,0 @@
|
||||
//======================================================================
|
||||
//
|
||||
// garo.v
|
||||
// ------
|
||||
// GaloisRing Oscillator with state sampling.
|
||||
// The Galois depth is 11 bits, and the bits are always sampled.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module garo(
|
||||
input wire clk,
|
||||
output wire entropy
|
||||
);
|
||||
|
||||
parameter POLY = 11'b11111111111;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers and wires.
|
||||
//----------------------------------------------------------------
|
||||
reg entropy_reg;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
wire [11 : 0] g;
|
||||
wire [11 : 0] gp;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Combinational loop inverters.
|
||||
//---------------------------------------------------------------
|
||||
/* verilator lint_off PINMISSING */
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv1 (.I0(g[0]), .O(gp[0]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv2 (.I0(g[1]), .O(gp[1]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv3 (.I0(g[2]), .O(gp[2]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv4 (.I0(g[3]), .O(gp[3]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv5 (.I0(g[4]), .O(gp[4]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv6 (.I0(g[5]), .O(gp[5]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv7 (.I0(g[6]), .O(gp[6]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv8 (.I0(g[7]), .O(gp[7]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv9 (.I0(g[8]), .O(gp[8]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv10 (.I0(g[9]), .O(gp[9]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv11 (.I0(g[10]), .O(gp[10]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(16'h1)) osc_inv12 (.I0(g[11]), .O(gp[11]));
|
||||
/* verilator lint_on PINMISSING */
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// parameterized feedback logic.
|
||||
//---------------------------------------------------------------
|
||||
assign g[11] = gp[0];
|
||||
assign g[10] = gp[11] ^ (POLY[10] & gp[0]);
|
||||
assign g[9] = gp[10] ^ (POLY[9] & gp[0]);
|
||||
assign g[8] = gp[9] ^ (POLY[8] & gp[0]);
|
||||
assign g[7] = gp[8] ^ (POLY[7] & gp[0]);
|
||||
assign g[6] = gp[7] ^ (POLY[6] & gp[0]);
|
||||
assign g[5] = gp[6] ^ (POLY[5] & gp[0]);
|
||||
assign g[4] = gp[5] ^ (POLY[4] & gp[0]);
|
||||
assign g[3] = gp[4] ^ (POLY[3] & gp[0]);
|
||||
assign g[2] = gp[3] ^ (POLY[2] & gp[0]);
|
||||
assign g[1] = gp[2] ^ (POLY[1] & gp[0]);
|
||||
assign g[0] = gp[1] ^ (POLY[0] & gp[0]);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign entropy = entropy_reg;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// reg_update
|
||||
//---------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
entropy_reg <= ^g;
|
||||
end
|
||||
|
||||
endmodule // garo
|
||||
|
||||
//======================================================================
|
||||
// EOF garo.v
|
||||
//======================================================================
|
@ -1,8 +1,11 @@
|
||||
//======================================================================
|
||||
//
|
||||
// figaro.v
|
||||
// --------
|
||||
// Top level wrapper for the figaro core.
|
||||
// rosc.v
|
||||
// ------
|
||||
// Digital ring oscillator based entropy generator.
|
||||
// Use this as a source of entropy, for example as seeds.
|
||||
// Do **NOT** use directly as random number in any security
|
||||
// related use cases.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
@ -13,19 +16,19 @@
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module figaro(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
module rosc(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
input wire [7 : 0] address,
|
||||
/* verilator lint_off UNUSED */
|
||||
input wire [31 : 0] write_data,
|
||||
/* verilator lint_on UNUSED */
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
input wire cs,
|
||||
input wire we,
|
||||
input wire [7 : 0] address,
|
||||
/* verilator lint_off UNUSED */
|
||||
input wire [31 : 0] write_data,
|
||||
/* verilator lint_on UNUSED */
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@ -298,8 +301,8 @@ module figaro(
|
||||
endcase // case (rosc_ctrl_reg)
|
||||
end
|
||||
|
||||
endmodule // figaro
|
||||
endmodule // rosc
|
||||
|
||||
//======================================================================
|
||||
// EOF figaro.v
|
||||
// EOF rosc.v
|
||||
//======================================================================
|
@ -39,7 +39,6 @@ enum {
|
||||
|
||||
MTA1_MKDF_MMIO_TRNG_STATUS = MTA1_MKDF_MMIO_TRNG_BASE | 0x24,
|
||||
MTA1_MKDF_MMIO_TRNG_STATUS_READY_BIT = 0,
|
||||
MTA1_MKDF_MMIO_TRNG_SAMPLE_RATE = MTA1_MKDF_MMIO_TRNG_BASE | 0x40,
|
||||
MTA1_MKDF_MMIO_TRNG_ENTROPY = MTA1_MKDF_MMIO_TRNG_BASE | 0x80,
|
||||
|
||||
MTA1_MKDF_MMIO_TIMER_CTRL = MTA1_MKDF_MMIO_TIMER_BASE | 0x20,
|
||||
|
@ -217,7 +217,7 @@ module application_fpga(
|
||||
);
|
||||
|
||||
|
||||
figaro trng_inst(
|
||||
rosc trng_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.cs(trng_cs),
|
||||
|
Loading…
Reference in New Issue
Block a user