@@ -113,7 +113,7 @@ module otbn_core
113113 logic [31 : 0 ] insn_fetch_resp_data;
114114 logic insn_fetch_resp_clear;
115115 logic insn_fetch_err;
116- logic insn_addr_err;
116+ logic insn_addr_err_d, insn_addr_err;
117117
118118 rf_predec_bignum_t rf_predec_bignum;
119119 alu_predec_bignum_t alu_predec_bignum;
@@ -156,7 +156,7 @@ module otbn_core
156156 logic rf_base_rd_commit;
157157 logic rf_base_call_stack_sw_err;
158158 logic rf_base_call_stack_hw_err;
159- logic rf_base_intg_err;
159+ logic rf_base_intg_err_d, rf_base_intg_err;
160160 logic rf_base_spurious_we_err;
161161 logic rf_base_sec_wipe_err;
162162
@@ -175,7 +175,7 @@ module otbn_core
175175
176176 logic [BaseIntgWidth- 1 : 0 ] lsu_base_rdata;
177177 logic [ExtWLEN- 1 : 0 ] lsu_bignum_rdata;
178- logic lsu_rdata_err;
178+ logic lsu_rdata_err_d, lsu_rdata_err;
179179
180180 logic [WdrAw- 1 : 0 ] rf_bignum_wr_addr;
181181 logic [WdrAw- 1 : 0 ] rf_bignum_wr_addr_ctrl;
@@ -241,7 +241,7 @@ module otbn_core
241241 logic urnd_advance;
242242 logic urnd_advance_start_stop_control;
243243 logic [WLEN - 1 : 0 ] urnd_data;
244- logic urnd_all_zero;
244+ logic urnd_all_zero_d, urnd_all_zero;
245245
246246 logic controller_start;
247247
@@ -281,7 +281,7 @@ module otbn_core
281281 logic start_stop_fatal_error;
282282 logic rf_bignum_predec_error, alu_bignum_predec_error, ispr_predec_error, mac_bignum_predec_error;
283283 logic controller_predec_error;
284- logic rd_predec_error, predec_error;
284+ logic rd_predec_error, predec_error_d, predec_error;
285285
286286 logic req_sec_wipe_urnd_keys_q;
287287
@@ -361,7 +361,7 @@ module otbn_core
361361 .insn_fetch_resp_data_o (insn_fetch_resp_data),
362362 .insn_fetch_resp_clear_i (insn_fetch_resp_clear),
363363 .insn_fetch_err_o (insn_fetch_err),
364- .insn_addr_err_o (insn_addr_err ),
364+ .insn_addr_err_o (insn_addr_err_d ),
365365
366366 .rf_predec_bignum_o (rf_predec_bignum),
367367 .alu_predec_bignum_o (alu_predec_bignum),
@@ -416,7 +416,7 @@ module otbn_core
416416 rf_predec_bignum.rf_ren_b,
417417 ispr_predec_bignum.ispr_rd_en} & ~ insn_valid;
418418
419- assign predec_error =
419+ assign predec_error_d =
420420 ((alu_bignum_predec_error | mac_bignum_predec_error | controller_predec_error) & insn_valid) |
421421 rf_bignum_predec_error |
422422 ispr_predec_error |
@@ -589,10 +589,100 @@ module otbn_core
589589 controller_err_bits.bad_internal_state,
590590 controller_err_bits.reg_intg_violation} ;
591591
592- logic non_controller_reg_intg_violation;
593- assign non_controller_reg_intg_violation =
594- |{ alu_bignum_reg_intg_violation_err, mac_bignum_reg_intg_violation_err, rf_base_intg_err} ;
595-
592+ logic non_controller_reg_intg_violation_d, non_controller_reg_intg_violation;
593+ assign non_controller_reg_intg_violation_d =
594+ |{ alu_bignum_reg_intg_violation_err, mac_bignum_reg_intg_violation_err, rf_base_intg_err_d} ;
595+
596+ // //////////////////////////////////////////////////////////////
597+ // Register local escalation signals for timinig optimization //
598+ // //////////////////////////////////////////////////////////////
599+ // Signals contributing to the local controller escalation signal directly factor into the
600+ // insn_executing signal inside the otbn_controller.sv. This then drives various commit signals
601+ // as well as the DMEM request signal (lsu_load_req_o). By cutting these escalation signals,
602+ // these paths are shortened which results in better timing/area results. Signals contributing to
603+ // the start/stop escalation are also cut to synchronize the escalation such that transitioning
604+ // into LOCKED and the start of wiping activities happen at the same time. The error bits are
605+ // also updated delayed to have the same behaviour as without a cut.
606+ //
607+ // Registered signals:
608+ // - urnd_all_zero: Is high when the local PRNG is all zero and locks up.
609+ // Potentially timing critical.
610+ // - predec_error: Generated by checking all the registered, predecoded signals with decoded
611+ // signals and combining these.
612+ // Potentially timing critical.
613+ // - lsu_rdata_err: DMEM ECC errors of data read from DMEM.
614+ // Timing critical because source is in memory.
615+ // - insn_addr_err: Depends on insn_fetch_req_addr_o from the controller which factors in
616+ // lots of combinatorial signals.
617+ // Likely timing critical.
618+ // - rf_base_intg_err: ECC errors triggered with in the base register file. The control signals
619+ // for the base register file are not predecoded.
620+ // So this is likely timing critical.
621+ // - non_controller_reg_intg_violation: Based on alu_bignum_reg_intg_violation_err,
622+ // mac_bignum_reg_intg_violation_err and rf_base_intg_err.
623+ // The former two are generated by checking the ECC of the
624+ // MOD / ACC values. The checks depends on the actual
625+ // ALU / MAC datapath outputs.
626+ // **Highly** timing critical.
627+ //
628+ // Not registered signals:
629+ // - escalate_en_i: This must NOT be not cut. It stems from the system wide escalation
630+ // control mechanism and such a global escalation must be as fast as
631+ // possible.
632+ // - start_stop_fatal_error: The error signal of the start stop FSM. Based on EDN urnd ack
633+ // signal and internal state checking. This error is not cut to
634+ // synchronize the escalation of the controller and start/stop
635+ // control.
636+ // - controller_fatal_err: The error signal of the controller towards the start/stop logic.
637+ // This error is not cut to synchronize the escalation of the
638+ // controller and start/stop control.
639+ // - rf_base_spurious_we_err: This error is already registered at the source.
640+ // - insn_fetch_err: IMEM ECC errors, not computed on the IMEM output but on a flopped
641+ // signal.
642+ //
643+ // Security considerations:
644+ // With the registering, the reaction to escalation sources is delayed by one cycle. Any faulty
645+ // instruction therefore still commits and updates registers or the memory. This does not affect
646+ // security because:
647+ // - While executing a program, the IMEM and DMEM are locked and cannot be read by Ibex.
648+ // - They become readable once the execution finishes without a fatal error. In addition, only a
649+ // part of the DMEM is readable by Ibex.
650+ // - If a fatal error occurs OTBN locks up and none of the memories become readable again.
651+ // - SCA and FI combined attacks are out of scope. As of this, any leakage due to FI attacks is
652+ // considered unusable because the OpenTitan chip scraps itself when too many FI attacks were
653+ // detected.
654+ // - When escalating, OTBN asserts locking_o and therefore any memory reads are killed
655+ // immediately. This handles the case where the final instruction is targeted. An error during
656+ // the final instruction does not prevent the OTBN of going into IDLE and thus the memories are
657+ // theoretically unlocked for one cycle. However, OTBN will escalate immediately and also kill
658+ // any read requests. The memories are therefore never readable except maybe some glitching
659+ // activities on the port. However, assuming a single fault per execution, when targeting the
660+ // last instruction, any program should have run correctly up to this point and thus should not
661+ // expose any secrets in the readable DMEM section. Additionally, converting the ECALL
662+ // instruction into a meaningful memory instruction is infeasible with only 1 fault. Also, a
663+ // BN.SID instruction takes two cycles to execute and therefore only a SW instruction could
664+ // be performed.
665+
666+ // TODO: Does this need a prim_flop or is a regular flop sufficient?
667+ // We drop the _q suffix for the registered signals such that DV and tracing can stay the same
668+ // whether there is a cut or not.
669+ always_ff @ (posedge clk_i or negedge rst_ni) begin
670+ if (! rst_ni) begin
671+ urnd_all_zero <= '0 ;
672+ predec_error <= '0 ;
673+ rf_base_intg_err <= '0 ;
674+ lsu_rdata_err <= '0 ;
675+ non_controller_reg_intg_violation <= '0 ;
676+ insn_addr_err <= '0 ;
677+ end else begin
678+ urnd_all_zero <= urnd_all_zero_d;
679+ predec_error <= predec_error_d;
680+ rf_base_intg_err <= rf_base_intg_err_d;
681+ lsu_rdata_err <= lsu_rdata_err_d;
682+ non_controller_reg_intg_violation <= non_controller_reg_intg_violation_d;
683+ insn_addr_err <= insn_addr_err_d;
684+ end
685+ end
596686
597687 // Generate an err_bits output by combining errors from all the blocks in otbn_core
598688 assign err_bits_d = '{
@@ -633,11 +723,12 @@ module otbn_core
633723
634724 // Pass an "escalation" signal down to the controller by ORing in error signals from the other
635725 // modules in otbn_core. Note that each error signal except escalate_en_i that appears here also
636- // appears somewhere in err_bits_o above (checked in ErrBitsIfControllerEscalate_A)
726+ // appears somewhere in err_bits_o above (checked in ErrBitsIfControllerEscalate_A).
727+ // The error rf_base_intg_err is already factored into non_controller_reg_intg_violation.
637728 assign controller_fatal_escalate_en =
638729 mubi4_or_hi (escalate_en_i,
639730 mubi4_bool_to_mubi (|{ start_stop_fatal_error, urnd_all_zero, predec_error,
640- rf_base_intg_err, rf_base_spurious_we_err, lsu_rdata_err,
731+ rf_base_spurious_we_err, lsu_rdata_err,
641732 insn_fetch_err, non_controller_reg_intg_violation,
642733 insn_addr_err} ));
643734
@@ -684,7 +775,7 @@ module otbn_core
684775
685776 .lsu_base_rdata_o (lsu_base_rdata),
686777 .lsu_bignum_rdata_o (lsu_bignum_rdata),
687- .lsu_rdata_err_o (lsu_rdata_err )
778+ .lsu_rdata_err_o (lsu_rdata_err_d )
688779 );
689780
690781 // Base Instruction Subset =======================================================================
@@ -716,7 +807,7 @@ module otbn_core
716807
717808 .call_stack_sw_err_o (rf_base_call_stack_sw_err),
718809 .call_stack_hw_err_o (rf_base_call_stack_hw_err),
719- .intg_err_o (rf_base_intg_err ),
810+ .intg_err_o (rf_base_intg_err_d ),
720811 .spurious_we_err_o (rf_base_spurious_we_err),
721812 .sec_wipe_err_o (rf_base_sec_wipe_err)
722813 );
@@ -910,7 +1001,7 @@ module otbn_core
9101001 .urnd_reseed_ack_o (urnd_reseed_ack),
9111002 .urnd_advance_i (urnd_advance),
9121003 .urnd_data_o (urnd_data),
913- .urnd_all_zero_o (urnd_all_zero ),
1004+ .urnd_all_zero_o (urnd_all_zero_d ),
9141005
9151006 .edn_rnd_req_o,
9161007 .edn_rnd_ack_i,
0 commit comments