Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rtl] Add LFSR permutation option #1420

Merged
merged 1 commit into from
Aug 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions doc/02_user/integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 (),
Expand Down Expand Up @@ -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 |
Expand Down
1 change: 1 addition & 0 deletions doc/03_reference/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
4 changes: 4 additions & 0 deletions rtl/ibex_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 ),
Expand Down
12 changes: 9 additions & 3 deletions rtl/ibex_dummy_instr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 ),
Expand Down
7 changes: 6 additions & 1 deletion rtl/ibex_if_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 ),
Expand Down
4 changes: 4 additions & 0 deletions rtl/ibex_lockstep.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 ),
Expand Down
10 changes: 10 additions & 0 deletions rtl/ibex_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -558,4 +558,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
50 changes: 27 additions & 23 deletions rtl/ibex_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -199,6 +199,8 @@ module ibex_top #(
.DbgHwBreakNum ( DbgHwBreakNum ),
.WritebackStage ( WritebackStage ),
.ResetAll ( ResetAll ),
.RndCnstLfsrSeed ( RndCnstLfsrSeed ),
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
.SecureIbex ( SecureIbex ),
.DummyInstructions ( DummyInstructions ),
.RegFileECC ( RegFileECC ),
Expand Down Expand Up @@ -648,6 +650,8 @@ module ibex_top #(
.DbgHwBreakNum ( DbgHwBreakNum ),
.WritebackStage ( WritebackStage ),
.ResetAll ( ResetAll ),
.RndCnstLfsrSeed ( RndCnstLfsrSeed ),
.RndCnstLfsrPerm ( RndCnstLfsrPerm ),
.SecureIbex ( SecureIbex ),
.DummyInstructions ( DummyInstructions ),
.RegFileECC ( RegFileECC ),
Expand Down
46 changes: 23 additions & 23 deletions rtl/ibex_top_tracing.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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.");
Expand Down