mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
[rtl] Add LFSR permutation option
Random constants are sent through the hierarchy as parameters in-line with other OpenTitan modules. Further detail on this mechanism can be found in lowrisc/opentitan#2229 Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
parent
dbc2b6f5dc
commit
65bf9c94f9
9 changed files with 108 additions and 66 deletions
|
@ -15,22 +15,24 @@ Instantiation Template
|
|||
.. code-block:: verilog
|
||||
|
||||
ibex_top #(
|
||||
.PMPEnable ( 0 ),
|
||||
.PMPGranularity ( 0 ),
|
||||
.PMPNumRegions ( 4 ),
|
||||
.MHPMCounterNum ( 0 ),
|
||||
.MHPMCounterWidth ( 40 ),
|
||||
.RV32E ( 0 ),
|
||||
.RV32M ( ibex_pkg::RV32MFast ),
|
||||
.RV32B ( ibex_pkg::RV32BNone ),
|
||||
.RegFile ( ibex_pkg::RegFileFF ),
|
||||
.ICache ( 0 ),
|
||||
.ICacheECC ( 0 ),
|
||||
.BranchPrediction ( 0 ),
|
||||
.SecureIbex ( 0 ),
|
||||
.DbgTriggerEn ( 0 ),
|
||||
.DmHaltAddr ( 32'h1A110800 ),
|
||||
.DmExceptionAddr ( 32'h1A110808 )
|
||||
.PMPEnable ( 0 ),
|
||||
.PMPGranularity ( 0 ),
|
||||
.PMPNumRegions ( 4 ),
|
||||
.MHPMCounterNum ( 0 ),
|
||||
.MHPMCounterWidth ( 40 ),
|
||||
.RV32E ( 0 ),
|
||||
.RV32M ( ibex_pkg::RV32MFast ),
|
||||
.RV32B ( ibex_pkg::RV32BNone ),
|
||||
.RegFile ( ibex_pkg::RegFileFF ),
|
||||
.ICache ( 0 ),
|
||||
.ICacheECC ( 0 ),
|
||||
.BranchPrediction ( 0 ),
|
||||
.SecureIbex ( 0 ),
|
||||
.RndCnstLfsrSeed ( ibex_pkg::RndCnstLfsrSeedDefault ),
|
||||
.RndCnstLfsrPerm ( ibex_pkg::RndCnstLfsrPermDefault ),
|
||||
.DbgTriggerEn ( 0 ),
|
||||
.DmHaltAddr ( 32'h1A110800 ),
|
||||
.DmExceptionAddr ( 32'h1A110808 )
|
||||
) u_top (
|
||||
// Clock and reset
|
||||
.clk_i (),
|
||||
|
@ -132,6 +134,12 @@ Parameters
|
|||
| | | | secure code execution. Note: SecureIbex == 1'b1 and |
|
||||
| | | | RV32M == ibex_pkg::RV32MNone is an illegal combination. |
|
||||
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
|
||||
| ``RndCnstLfsrSeed`` | lfsr_seed_t | see above | Set the starting seed of the LFSR used to generate dummy instructions |
|
||||
| | | | (only relevant when SecureIbex == 1'b1) |
|
||||
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
|
||||
| ``RndCnstLfsrPerm`` | lfsr_perm_t | see above | Set the permutation applied to the output of the LFSR used to |
|
||||
| | | | generate dummy instructions (only relevant when SecureIbex == 1'b1) |
|
||||
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
|
||||
| ``DbgTriggerEn`` | bit | 0 | Enable debug trigger support (one trigger only) |
|
||||
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
|
||||
| ``DmHaltAddr`` | int | 0x1A110800 | Address to jump to when entering Debug Mode |
|
||||
|
|
|
@ -50,6 +50,7 @@ The frequency of injected instructions can be tuned via the **dummy_instr_mask**
|
|||
Other values of **dummy_instr_mask** are legal, but will have a less predictable impact.
|
||||
|
||||
The interval between instruction insertion is randomized in the core using an LFSR.
|
||||
The initial seed and output permutation for this LFSR can be set using parameters from the top-level of Ibex.
|
||||
Sofware can periodically re-seed this LFSR with true random numbers (if available) via the **secureseed** CSR.
|
||||
This will make the insertion interval of dummy instructions much harder for an attacker to predict.
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
|
||||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter bit DummyInstructions = 1'b0,
|
||||
parameter bit RegFileECC = 1'b0,
|
||||
|
@ -398,6 +400,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
.LineSizeECC ( LineSizeECC ),
|
||||
.PCIncrCheck ( PCIncrCheck ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.RndCnstLfsrSeed ( RndCnstLfsrSeed ),
|
||||
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
|
||||
.BranchPredictor ( BranchPredictor )
|
||||
) if_stage_i (
|
||||
.clk_i ( clk_i ),
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
* Provides pseudo-randomly inserted fake instructions for secure code obfuscation
|
||||
*/
|
||||
|
||||
module ibex_dummy_instr (
|
||||
module ibex_dummy_instr import ibex_pkg::*; #(
|
||||
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
|
||||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault
|
||||
) (
|
||||
// Clock and reset
|
||||
input logic clk_i,
|
||||
input logic rst_ni,
|
||||
|
@ -70,8 +73,11 @@ module ibex_dummy_instr (
|
|||
end
|
||||
|
||||
prim_lfsr #(
|
||||
.LfsrDw ( 32 ),
|
||||
.StateOutDw ( LFSR_OUT_W )
|
||||
.LfsrDw ( LfsrWidth ),
|
||||
.StateOutDw ( LFSR_OUT_W ),
|
||||
.DefaultSeed ( RndCnstLfsrSeed ),
|
||||
.StatePermEn ( 1'b1 ),
|
||||
.StatePerm ( RndCnstLfsrPerm )
|
||||
) lfsr_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
|
|
|
@ -23,6 +23,8 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
parameter int unsigned LineSizeECC = IC_LINE_SIZE,
|
||||
parameter bit PCIncrCheck = 1'b0,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
|
||||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
|
||||
parameter bit BranchPredictor = 1'b0
|
||||
) (
|
||||
input logic clk_i,
|
||||
|
@ -330,7 +332,10 @@ module ibex_if_stage import ibex_pkg::*; #(
|
|||
logic insert_dummy_instr;
|
||||
logic [31:0] dummy_instr_data;
|
||||
|
||||
ibex_dummy_instr dummy_instr_i (
|
||||
ibex_dummy_instr #(
|
||||
.RndCnstLfsrSeed (RndCnstLfsrSeed),
|
||||
.RndCnstLfsrPerm (RndCnstLfsrPerm)
|
||||
) dummy_instr_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.dummy_instr_en_i ( dummy_instr_en_i ),
|
||||
|
|
|
@ -27,6 +27,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit ResetAll = 1'b0,
|
||||
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
|
||||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter bit DummyInstructions = 1'b0,
|
||||
parameter bit RegFileECC = 1'b0,
|
||||
|
@ -292,6 +294,8 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
.DbgHwBreakNum ( DbgHwBreakNum ),
|
||||
.WritebackStage ( WritebackStage ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.RndCnstLfsrSeed ( RndCnstLfsrSeed ),
|
||||
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
|
||||
.SecureIbex ( SecureIbex ),
|
||||
.DummyInstructions ( DummyInstructions ),
|
||||
.RegFileECC ( RegFileECC ),
|
||||
|
|
|
@ -559,4 +559,14 @@ parameter int unsigned CSR_MSECCFG_MML_BIT = 0;
|
|||
parameter int unsigned CSR_MSECCFG_MMWP_BIT = 1;
|
||||
parameter int unsigned CSR_MSECCFG_RLB_BIT = 2;
|
||||
|
||||
// These LFSR parameters have been generated with
|
||||
// $ opentitan/util/design/gen-lfsr-seed.py --width 32 --seed 2480124384 --prefix ""
|
||||
parameter int LfsrWidth = 32;
|
||||
typedef logic [LfsrWidth-1:0] lfsr_seed_t;
|
||||
typedef logic [LfsrWidth-1:0][$clog2(LfsrWidth)-1:0] lfsr_perm_t;
|
||||
parameter lfsr_seed_t RndCnstLfsrSeedDefault = 32'hac533bf4;
|
||||
parameter lfsr_perm_t RndCnstLfsrPermDefault = {
|
||||
160'h1e35ecba467fd1b12e958152c04fa43878a8daed
|
||||
};
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -12,26 +12,28 @@
|
|||
/**
|
||||
* Top level module of the ibex RISC-V core
|
||||
*/
|
||||
module ibex_top #(
|
||||
parameter bit PMPEnable = 1'b0,
|
||||
parameter int unsigned PMPGranularity = 0,
|
||||
parameter int unsigned PMPNumRegions = 4,
|
||||
parameter int unsigned MHPMCounterNum = 0,
|
||||
parameter int unsigned MHPMCounterWidth = 40,
|
||||
parameter bit RV32E = 1'b0,
|
||||
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast,
|
||||
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
|
||||
parameter ibex_pkg::regfile_e RegFile = ibex_pkg::RegFileFF,
|
||||
parameter bit BranchTargetALU = 1'b0,
|
||||
parameter bit WritebackStage = 1'b0,
|
||||
parameter bit ICache = 1'b0,
|
||||
parameter bit ICacheECC = 1'b0,
|
||||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808
|
||||
module ibex_top import ibex_pkg::*; #(
|
||||
parameter bit PMPEnable = 1'b0,
|
||||
parameter int unsigned PMPGranularity = 0,
|
||||
parameter int unsigned PMPNumRegions = 4,
|
||||
parameter int unsigned MHPMCounterNum = 0,
|
||||
parameter int unsigned MHPMCounterWidth = 40,
|
||||
parameter bit RV32E = 1'b0,
|
||||
parameter rv32m_e RV32M = RV32MFast,
|
||||
parameter rv32b_e RV32B = RV32BNone,
|
||||
parameter regfile_e RegFile = RegFileFF,
|
||||
parameter bit BranchTargetALU = 1'b0,
|
||||
parameter bit WritebackStage = 1'b0,
|
||||
parameter bit ICache = 1'b0,
|
||||
parameter bit ICacheECC = 1'b0,
|
||||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
|
||||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -71,7 +73,7 @@ module ibex_top #(
|
|||
|
||||
// Debug Interface
|
||||
input logic debug_req_i,
|
||||
output ibex_pkg::crash_dump_t crash_dump_o,
|
||||
output crash_dump_t crash_dump_o,
|
||||
|
||||
// RISC-V Formal Interface
|
||||
// Does not comply with the coding standards of _i/_o suffixes, but follows
|
||||
|
@ -112,8 +114,6 @@ module ibex_top #(
|
|||
input logic scan_rst_ni
|
||||
);
|
||||
|
||||
import ibex_pkg::*;
|
||||
|
||||
localparam bit Lockstep = SecureIbex;
|
||||
localparam bit ResetAll = Lockstep;
|
||||
localparam bit DummyInstructions = SecureIbex;
|
||||
|
@ -199,6 +199,8 @@ module ibex_top #(
|
|||
.DbgHwBreakNum ( DbgHwBreakNum ),
|
||||
.WritebackStage ( WritebackStage ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.RndCnstLfsrSeed ( RndCnstLfsrSeed ),
|
||||
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
|
||||
.SecureIbex ( SecureIbex ),
|
||||
.DummyInstructions ( DummyInstructions ),
|
||||
.RegFileECC ( RegFileECC ),
|
||||
|
@ -648,6 +650,8 @@ module ibex_top #(
|
|||
.DbgHwBreakNum ( DbgHwBreakNum ),
|
||||
.WritebackStage ( WritebackStage ),
|
||||
.ResetAll ( ResetAll ),
|
||||
.RndCnstLfsrSeed ( RndCnstLfsrSeed ),
|
||||
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
|
||||
.SecureIbex ( SecureIbex ),
|
||||
.DummyInstructions ( DummyInstructions ),
|
||||
.RegFileECC ( RegFileECC ),
|
||||
|
|
|
@ -6,26 +6,28 @@
|
|||
* Top level module of the ibex RISC-V core with tracing enabled
|
||||
*/
|
||||
|
||||
module ibex_top_tracing #(
|
||||
parameter bit PMPEnable = 1'b0,
|
||||
parameter int unsigned PMPGranularity = 0,
|
||||
parameter int unsigned PMPNumRegions = 4,
|
||||
parameter int unsigned MHPMCounterNum = 0,
|
||||
parameter int unsigned MHPMCounterWidth = 40,
|
||||
parameter bit RV32E = 1'b0,
|
||||
parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast,
|
||||
parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone,
|
||||
parameter ibex_pkg::regfile_e RegFile = ibex_pkg::RegFileFF,
|
||||
parameter bit BranchTargetALU = 1'b0,
|
||||
parameter bit WritebackStage = 1'b0,
|
||||
parameter bit ICache = 1'b0,
|
||||
parameter bit ICacheECC = 1'b0,
|
||||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808
|
||||
module ibex_top_tracing import ibex_pkg::*; #(
|
||||
parameter bit PMPEnable = 1'b0,
|
||||
parameter int unsigned PMPGranularity = 0,
|
||||
parameter int unsigned PMPNumRegions = 4,
|
||||
parameter int unsigned MHPMCounterNum = 0,
|
||||
parameter int unsigned MHPMCounterWidth = 40,
|
||||
parameter bit RV32E = 1'b0,
|
||||
parameter rv32m_e RV32M = RV32MFast,
|
||||
parameter rv32b_e RV32B = RV32BNone,
|
||||
parameter regfile_e RegFile = RegFileFF,
|
||||
parameter bit BranchTargetALU = 1'b0,
|
||||
parameter bit WritebackStage = 1'b0,
|
||||
parameter bit ICache = 1'b0,
|
||||
parameter bit ICacheECC = 1'b0,
|
||||
parameter bit BranchPredictor = 1'b0,
|
||||
parameter bit DbgTriggerEn = 1'b0,
|
||||
parameter int unsigned DbgHwBreakNum = 1,
|
||||
parameter bit SecureIbex = 1'b0,
|
||||
parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault,
|
||||
parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault,
|
||||
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
||||
parameter int unsigned DmExceptionAddr = 32'h1A110808
|
||||
) (
|
||||
// Clock and Reset
|
||||
input logic clk_i,
|
||||
|
@ -67,7 +69,7 @@ module ibex_top_tracing #(
|
|||
|
||||
// Debug Interface
|
||||
input logic debug_req_i,
|
||||
output ibex_pkg::crash_dump_t crash_dump_o,
|
||||
output crash_dump_t crash_dump_o,
|
||||
|
||||
// CPU Control Signals
|
||||
input logic fetch_enable_i,
|
||||
|
@ -77,8 +79,6 @@ module ibex_top_tracing #(
|
|||
|
||||
);
|
||||
|
||||
import ibex_pkg::*;
|
||||
|
||||
// ibex_tracer relies on the signals from the RISC-V Formal Interface
|
||||
`ifndef RVFI
|
||||
$fatal("Fatal error: RVFI needs to be defined globally.");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue