From aaffea0afc4a0cc5aa43cb10437134c00bff190d Mon Sep 17 00:00:00 2001 From: Pirmin Vogel Date: Thu, 31 Oct 2024 21:58:49 +0100 Subject: [PATCH] [aes] Add support for inc32() to the counter module In contrast to the regular CTR mode where the counter performs inc128(), the counter only performs inc32() in GCM, i.e., the counter wraps at 32 bits. Signed-off-by: Pirmin Vogel --- hw/ip/aes/rtl/aes_control.sv | 5 +++++ hw/ip/aes/rtl/aes_control_fsm.sv | 4 ++++ hw/ip/aes/rtl/aes_control_fsm_n.sv | 6 +++++ hw/ip/aes/rtl/aes_control_fsm_p.sv | 6 +++++ hw/ip/aes/rtl/aes_core.sv | 3 +++ hw/ip/aes/rtl/aes_ctr.sv | 35 +++++++++++++++++++++++++----- hw/ip/aes/rtl/aes_ctr_fsm.sv | 11 +++++++--- hw/ip/aes/rtl/aes_ctr_fsm_n.sv | 20 +++++++++++------ hw/ip/aes/rtl/aes_ctr_fsm_p.sv | 20 +++++++++++------ hw/ip/aes/rtl/aes_pkg.sv | 3 +++ 10 files changed, 91 insertions(+), 22 deletions(-) diff --git a/hw/ip/aes/rtl/aes_control.sv b/hw/ip/aes/rtl/aes_control.sv index a2426a505810af..f84f161419d72a 100644 --- a/hw/ip/aes/rtl/aes_control.sv +++ b/hw/ip/aes/rtl/aes_control.sv @@ -64,6 +64,7 @@ module aes_control output add_so_sel_e add_state_out_sel_o, // Counter + output sp2v_e ctr_inc32_o, output sp2v_e ctr_incr_o, input sp2v_e ctr_ready_i, input sp2v_e [NumSlicesCtr-1:0] ctr_we_i, @@ -174,6 +175,7 @@ module aes_control // signals to the single-rail FSMs. logic [Sp2VWidth-1:0] sp_data_out_we; logic [Sp2VWidth-1:0] sp_data_in_prev_we; + logic [Sp2VWidth-1:0] sp_ctr_inc32; logic [Sp2VWidth-1:0] sp_ctr_incr; logic [Sp2VWidth-1:0] sp_ctr_ready; logic [Sp2VWidth-1:0] sp_cipher_in_valid; @@ -315,6 +317,7 @@ module aes_control .add_state_in_sel_o ( mr_add_state_in_sel[i] ), // OR-combine .add_state_out_sel_o ( mr_add_state_out_sel[i] ), // OR-combine + .ctr_inc32_o ( sp_ctr_inc32[i] ), // Sparsified .ctr_incr_o ( sp_ctr_incr[i] ), // Sparsified .ctr_ready_i ( sp_ctr_ready[i] ), // Sparsified .ctr_we_i ( int_ctr_we[i] ), // Sparsified @@ -416,6 +419,7 @@ module aes_control .add_state_in_sel_o ( mr_add_state_in_sel[i] ), // OR-combine .add_state_out_sel_o ( mr_add_state_out_sel[i] ), // OR-combine + .ctr_inc32_no ( sp_ctr_inc32[i] ), // Sparsified .ctr_incr_no ( sp_ctr_incr[i] ), // Sparsified .ctr_ready_ni ( sp_ctr_ready[i] ), // Sparsified .ctr_we_ni ( int_ctr_we[i] ), // Sparsified @@ -475,6 +479,7 @@ module aes_control // Convert sparsified outputs to sp2v_e type. assign data_out_we_o = sp2v_e'(sp_data_out_we); assign data_in_prev_we_o = sp2v_e'(sp_data_in_prev_we); + assign ctr_inc32_o = sp2v_e'(sp_ctr_inc32); assign ctr_incr_o = sp2v_e'(sp_ctr_incr); assign cipher_in_valid_o = sp2v_e'(sp_cipher_in_valid); assign cipher_out_ready_o = sp2v_e'(sp_cipher_out_ready); diff --git a/hw/ip/aes/rtl/aes_control_fsm.sv b/hw/ip/aes/rtl/aes_control_fsm.sv index 718420128e6566..27056e92960fb4 100644 --- a/hw/ip/aes/rtl/aes_control_fsm.sv +++ b/hw/ip/aes/rtl/aes_control_fsm.sv @@ -64,6 +64,7 @@ module aes_control_fsm output add_so_sel_e add_state_out_sel_o, // Counter + output logic ctr_inc32_o, // Sparsify output logic ctr_incr_o, // Sparsify input logic ctr_ready_i, // Sparsify input logic [NumSlicesCtr-1:0] ctr_we_i, // Sparsify @@ -261,6 +262,9 @@ module aes_control_fsm // a GCM related operation. assign ghash_idle = ghash_in_ready_i & ~(start_gcm_init | start_gcm | start_gcm_tag); + // In GCM, the counter performs inc32() instead of inc128(), i.e., the counter wraps at 32 bits. + assign ctr_inc32_o = (mode_i == AES_GCM); + // If set to start manually, we just wait for the trigger. Otherwise, check common as well as // mode-specific start conditions. assign start = cfg_valid & no_alert & diff --git a/hw/ip/aes/rtl/aes_control_fsm_n.sv b/hw/ip/aes/rtl/aes_control_fsm_n.sv index d2275635ed97f0..464582cad050bc 100644 --- a/hw/ip/aes/rtl/aes_control_fsm_n.sv +++ b/hw/ip/aes/rtl/aes_control_fsm_n.sv @@ -69,6 +69,7 @@ module aes_control_fsm_n output add_so_sel_e add_state_out_sel_o, // Counter + output logic ctr_inc32_no, // Sparsify output logic ctr_incr_no, // Sparsify input logic ctr_ready_ni, // Sparsify input logic [NumSlicesCtr-1:0] ctr_we_ni, // Sparsify @@ -322,6 +323,7 @@ module aes_control_fsm_n si_sel_e state_in_sel; add_si_sel_e add_state_in_sel; add_so_sel_e add_state_out_sel; + logic ctr_inc32; logic ctr_incr; logic cipher_in_valid; logic cipher_out_ready; @@ -410,6 +412,7 @@ module aes_control_fsm_n .add_state_in_sel_o ( add_state_in_sel ), .add_state_out_sel_o ( add_state_out_sel ), + .ctr_inc32_o ( ctr_inc32 ), // Invert below for _n output. .ctr_incr_o ( ctr_incr ), // Invert below for _n output. .ctr_ready_i ( ~ctr_ready_n ), // Invert for regular FSM. .ctr_we_i ( ~ctr_we_n ), // Invert for regular FSM. @@ -480,6 +483,7 @@ module aes_control_fsm_n state_in_sel_o, add_state_in_sel_o, add_state_out_sel_o, + ctr_inc32_no, ctr_incr_no, cipher_in_valid_no, cipher_out_ready_no, @@ -530,6 +534,7 @@ module aes_control_fsm_n state_in_sel, add_state_in_sel, add_state_out_sel, + ~ctr_inc32, ~ctr_incr, ~cipher_in_valid, ~cipher_out_ready, @@ -584,6 +589,7 @@ module aes_control_fsm_n state_in_sel_o, add_state_in_sel_o, add_state_out_sel_o, + ctr_inc32_no, ctr_incr_no, cipher_in_valid_no, cipher_out_ready_no, diff --git a/hw/ip/aes/rtl/aes_control_fsm_p.sv b/hw/ip/aes/rtl/aes_control_fsm_p.sv index 534c5492b8584a..f306fd8fbede2a 100644 --- a/hw/ip/aes/rtl/aes_control_fsm_p.sv +++ b/hw/ip/aes/rtl/aes_control_fsm_p.sv @@ -65,6 +65,7 @@ module aes_control_fsm_p output add_so_sel_e add_state_out_sel_o, // Counter + output logic ctr_inc32_o, // Sparsify output logic ctr_incr_o, // Sparsify input logic ctr_ready_i, // Sparsify input logic [NumSlicesCtr-1:0] ctr_we_i, // Sparsify @@ -318,6 +319,7 @@ module aes_control_fsm_p si_sel_e state_in_sel; add_si_sel_e add_state_in_sel; add_so_sel_e add_state_out_sel; + logic ctr_inc32; logic ctr_incr; logic cipher_in_valid; logic cipher_out_ready; @@ -402,6 +404,7 @@ module aes_control_fsm_p .add_state_in_sel_o ( add_state_in_sel ), .add_state_out_sel_o ( add_state_out_sel ), + .ctr_inc32_o ( ctr_inc32 ), .ctr_incr_o ( ctr_incr ), .ctr_ready_i ( ctr_ready ), .ctr_we_i ( ctr_we ), @@ -472,6 +475,7 @@ module aes_control_fsm_p state_in_sel_o, add_state_in_sel_o, add_state_out_sel_o, + ctr_inc32_o, ctr_incr_o, cipher_in_valid_o, cipher_out_ready_o, @@ -520,6 +524,7 @@ module aes_control_fsm_p state_in_sel, add_state_in_sel, add_state_out_sel, + ctr_inc32, ctr_incr, cipher_in_valid, cipher_out_ready, @@ -574,6 +579,7 @@ module aes_control_fsm_p state_in_sel_o, add_state_in_sel_o, add_state_out_sel_o, + ctr_inc32_o, ctr_incr_o, cipher_in_valid_o, cipher_out_ready_o, diff --git a/hw/ip/aes/rtl/aes_core.sv b/hw/ip/aes/rtl/aes_core.sv index f199f1dfbf3df0..daa5e45f6bb0a7 100644 --- a/hw/ip/aes/rtl/aes_core.sv +++ b/hw/ip/aes/rtl/aes_core.sv @@ -132,6 +132,7 @@ module aes_core logic [NumSlicesCtr-1:0][SliceSizeCtr-1:0] ctr; sp2v_e [NumSlicesCtr-1:0] ctr_we; + sp2v_e ctr_inc32; sp2v_e ctr_incr; sp2v_e ctr_ready; logic ctr_alert; @@ -405,6 +406,7 @@ module aes_core .clk_i ( clk_i ), .rst_ni ( rst_ni ), + .inc32_i ( ctr_inc32 ), .incr_i ( ctr_incr ), .ready_o ( ctr_ready ), .alert_o ( ctr_alert ), @@ -769,6 +771,7 @@ module aes_core .add_state_in_sel_o ( add_state_in_sel_ctrl ), .add_state_out_sel_o ( add_state_out_sel_ctrl ), + .ctr_inc32_o ( ctr_inc32 ), .ctr_incr_o ( ctr_incr ), .ctr_ready_i ( ctr_ready ), .ctr_we_i ( ctr_we ), diff --git a/hw/ip/aes/rtl/aes_ctr.sv b/hw/ip/aes/rtl/aes_ctr.sv index 11ec79163314c6..f07b55a332bf3a 100644 --- a/hw/ip/aes/rtl/aes_ctr.sv +++ b/hw/ip/aes/rtl/aes_ctr.sv @@ -12,6 +12,7 @@ module aes_ctr import aes_pkg::*; input logic clk_i, input logic rst_ni, + input sp2v_e inc32_i, input sp2v_e incr_i, output sp2v_e ready_o, output logic alert_o, @@ -50,12 +51,16 @@ module aes_ctr import aes_pkg::*; logic [SliceSizeCtr-1:0] ctr_i_slice; logic [SliceSizeCtr-1:0] ctr_o_slice; + sp2v_e inc32; + logic inc32_err; sp2v_e incr; logic incr_err; + logic sp_enc_err; logic mr_err; // Sparsified FSM signals. These are needed for connecting the individual bits of the Sp2V // signals to the single-rail FSMs. + logic [Sp2VWidth-1:0] sp_inc32; logic [Sp2VWidth-1:0] sp_incr; logic [Sp2VWidth-1:0] sp_ready; logic [Sp2VWidth-1:0] sp_ctr_we; @@ -73,13 +78,27 @@ module aes_ctr import aes_pkg::*; assign ctr_i_rev = aes_rev_order_byte(ctr_i); // SEC_CM: CTRL.SPARSE - // Check sparsely encoded incr signal. + // Check sparsely encoded inc32 and incr signals. + logic [Sp2VWidth-1:0] inc32_raw; + aes_sel_buf_chk #( + .Num ( Sp2VNum ), + .Width ( Sp2VWidth ), + .EnSecBuf ( 1'b0 ) + ) u_aes_inc32_buf_chk ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .sel_i ( inc32_i ), + .sel_o ( inc32_raw ), + .err_o ( inc32_err ) + ); + assign inc32 = sp2v_e'(inc32_raw); + logic [Sp2VWidth-1:0] incr_raw; aes_sel_buf_chk #( .Num ( Sp2VNum ), .Width ( Sp2VWidth ), .EnSecBuf ( 1'b0 ) - ) u_aes_sb_en_buf_chk ( + ) u_aes_incr_buf_chk ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .sel_i ( incr_i ), @@ -88,6 +107,9 @@ module aes_ctr import aes_pkg::*; ); assign incr = sp2v_e'(incr_raw); + // Collect encoding errors. + assign sp_enc_err = inc32_err | incr_err; + ///////////// // Counter // ///////////// @@ -100,7 +122,8 @@ module aes_ctr import aes_pkg::*; ///////// // Convert sp2v_e signals to sparsified inputs. - assign sp_incr = {incr}; + assign sp_inc32 = {inc32}; + assign sp_incr = {incr}; // SEC_CM: CTR.FSM.REDUN // For every bit in the Sp2V signals, one separate rail is instantiated. The inputs and outputs @@ -111,9 +134,10 @@ module aes_ctr import aes_pkg::*; .clk_i ( clk_i ), .rst_ni ( rst_ni ), + .inc32_i ( sp_inc32[i] ), // Sparsified .incr_i ( sp_incr[i] ), // Sparsified .ready_o ( sp_ready[i] ), // Sparsified - .incr_err_i ( incr_err ), + .sp_enc_err_i ( sp_enc_err ), .mr_err_i ( mr_err ), .alert_o ( mr_alert[i] ), // OR-combine @@ -127,9 +151,10 @@ module aes_ctr import aes_pkg::*; .clk_i ( clk_i ), .rst_ni ( rst_ni ), + .inc32_ni ( sp_inc32[i] ), // Sparsified .incr_ni ( sp_incr[i] ), // Sparsified .ready_no ( sp_ready[i] ), // Sparsified - .incr_err_i ( incr_err ), + .sp_enc_err_i ( sp_enc_err ), .mr_err_i ( mr_err ), .alert_o ( mr_alert[i] ), // OR-combine diff --git a/hw/ip/aes/rtl/aes_ctr_fsm.sv b/hw/ip/aes/rtl/aes_ctr_fsm.sv index 13d8cdf7d29b01..26caa30d1d5195 100644 --- a/hw/ip/aes/rtl/aes_ctr_fsm.sv +++ b/hw/ip/aes/rtl/aes_ctr_fsm.sv @@ -11,9 +11,10 @@ module aes_ctr_fsm import aes_pkg::*; input logic clk_i, input logic rst_ni, + input logic inc32_i, // Sparsify using multi-rail. input logic incr_i, // Sparsify using multi-rail. output logic ready_o, // Sparsify using multi-rail. - input logic incr_err_i, + input logic sp_enc_err_i, input logic mr_err_i, output logic alert_o, @@ -26,6 +27,7 @@ module aes_ctr_fsm import aes_pkg::*; // Signals aes_ctr_e aes_ctr_ns, aes_ctr_cs; logic [SliceIdxWidth-1:0] ctr_slice_idx_d, ctr_slice_idx_q; + logic [SliceIdxWidth-1:0] ctr_slice_idx_max; logic ctr_carry_d, ctr_carry_q; logic [SliceSizeCtr:0] ctr_value; @@ -38,6 +40,9 @@ module aes_ctr_fsm import aes_pkg::*; assign ctr_value = ctr_slice_i + {{(SliceSizeCtr-1){1'b0}}, ctr_carry_q}; assign ctr_slice_o = ctr_value[SliceSizeCtr-1:0]; + // Perform either inc128() or inc32() for GCM. + assign ctr_slice_idx_max = inc32_i ? SliceIdxWidth'(SliceIdxMaxInc32) : {SliceIdxWidth{1'b1}}; + ///////////// // Control // ///////////// @@ -69,7 +74,7 @@ module aes_ctr_fsm import aes_pkg::*; CTR_INCR: begin // Increment slice index. ctr_slice_idx_d = ctr_slice_idx_q + SliceIdxWidth'(1); - ctr_carry_d = ctr_value[SliceSizeCtr]; + ctr_carry_d = ctr_slice_idx_q >= ctr_slice_idx_max ? 1'b0 : ctr_value[SliceSizeCtr]; ctr_we_o = 1'b1; if (ctr_slice_idx_q == {SliceIdxWidth{1'b1}}) begin @@ -92,7 +97,7 @@ module aes_ctr_fsm import aes_pkg::*; endcase // Unconditionally jump into the terminal error state in case an error is detected. - if (incr_err_i || mr_err_i) begin + if (sp_enc_err_i || mr_err_i) begin aes_ctr_ns = CTR_ERROR; end end diff --git a/hw/ip/aes/rtl/aes_ctr_fsm_n.sv b/hw/ip/aes/rtl/aes_ctr_fsm_n.sv index e4308cf78c894a..66547eb5bd79f7 100644 --- a/hw/ip/aes/rtl/aes_ctr_fsm_n.sv +++ b/hw/ip/aes/rtl/aes_ctr_fsm_n.sv @@ -16,9 +16,10 @@ module aes_ctr_fsm_n import aes_pkg::*; input logic clk_i, input logic rst_ni, + input logic inc32_ni, // Sparsify using multi-rail. input logic incr_ni, // Sparsify using multi-rail. output logic ready_no, // Sparsify using multi-rail. - input logic incr_err_i, + input logic sp_enc_err_i, input logic mr_err_i, output logic alert_o, @@ -33,8 +34,9 @@ module aes_ctr_fsm_n import aes_pkg::*; ///////////////////// localparam int NumInBufBits = $bits({ + inc32_ni, incr_ni, - incr_err_i, + sp_enc_err_i, mr_err_i, ctr_slice_i }); @@ -42,8 +44,9 @@ module aes_ctr_fsm_n import aes_pkg::*; logic [NumInBufBits-1:0] in, in_buf; assign in = { + inc32_ni, incr_ni, - incr_err_i, + sp_enc_err_i, mr_err_i, ctr_slice_i }; @@ -57,13 +60,15 @@ module aes_ctr_fsm_n import aes_pkg::*; .out_o(in_buf) ); + logic inc32_n; logic incr_n; - logic incr_err; + logic sp_enc_err; logic mr_err; logic [SliceSizeCtr-1:0] ctr_i_slice; - assign {incr_n, - incr_err, + assign {inc32_n, + incr_n, + sp_enc_err, mr_err, ctr_i_slice} = in_buf; @@ -86,9 +91,10 @@ module aes_ctr_fsm_n import aes_pkg::*; .clk_i ( clk_i ), .rst_ni ( rst_ni ), + .inc32_i ( ~inc32_n ), // Invert for regular FSM. .incr_i ( ~incr_n ), // Invert for regular FSM. .ready_o ( ready ), // Invert below for negated output. - .incr_err_i ( incr_err ), + .sp_enc_err_i ( sp_enc_err ), .mr_err_i ( mr_err ), .alert_o ( alert ), diff --git a/hw/ip/aes/rtl/aes_ctr_fsm_p.sv b/hw/ip/aes/rtl/aes_ctr_fsm_p.sv index 20ab23480866c7..3d83a99d53089d 100644 --- a/hw/ip/aes/rtl/aes_ctr_fsm_p.sv +++ b/hw/ip/aes/rtl/aes_ctr_fsm_p.sv @@ -12,9 +12,10 @@ module aes_ctr_fsm_p import aes_pkg::*; input logic clk_i, input logic rst_ni, + input logic inc32_i, // Sparsify input logic incr_i, // Sparsify output logic ready_o, // Sparsify - input logic incr_err_i, + input logic sp_enc_err_i, input logic mr_err_i, output logic alert_o, @@ -29,8 +30,9 @@ module aes_ctr_fsm_p import aes_pkg::*; ///////////////////// localparam int NumInBufBits = $bits({ + inc32_i, incr_i, - incr_err_i, + sp_enc_err_i, mr_err_i, ctr_slice_i }); @@ -38,8 +40,9 @@ module aes_ctr_fsm_p import aes_pkg::*; logic [NumInBufBits-1:0] in, in_buf; assign in = { + inc32_i, incr_i, - incr_err_i, + sp_enc_err_i, mr_err_i, ctr_slice_i }; @@ -53,13 +56,15 @@ module aes_ctr_fsm_p import aes_pkg::*; .out_o(in_buf) ); + logic inc32; logic incr; - logic incr_err; + logic sp_enc_err; logic mr_err; logic [SliceSizeCtr-1:0] ctr_i_slice; - assign {incr, - incr_err, + assign {inc32, + incr, + sp_enc_err, mr_err, ctr_i_slice} = in_buf; @@ -78,9 +83,10 @@ module aes_ctr_fsm_p import aes_pkg::*; .clk_i ( clk_i ), .rst_ni ( rst_ni ), + .inc32_i ( inc32 ), .incr_i ( incr ), .ready_o ( ready ), - .incr_err_i ( incr_err ), + .sp_enc_err_i ( sp_enc_err ), .mr_err_i ( mr_err ), .alert_o ( alert ), diff --git a/hw/ip/aes/rtl/aes_pkg.sv b/hw/ip/aes/rtl/aes_pkg.sv index 9c6df0df39ed6d..c97305e3b80b7b 100644 --- a/hw/ip/aes/rtl/aes_pkg.sv +++ b/hw/ip/aes/rtl/aes_pkg.sv @@ -19,6 +19,9 @@ parameter int unsigned SliceSizeCtr = 16; parameter int unsigned NumSlicesCtr = aes_reg_pkg::NumRegsIv * 32 / SliceSizeCtr; parameter int unsigned SliceIdxWidth = prim_util_pkg::vbits(NumSlicesCtr); +// In GCM, the counter performs inc32() instead of inc128(), i.e., the counter wraps at 32 bits. +parameter int unsigned SliceIdxMaxInc32 = 32 / SliceSizeCtr - 1; + // Widths of signals carrying pseudo-random data for clearing parameter int unsigned WidthPRDClearing = 64; parameter int unsigned NumChunksPRDClearing128 = 128/WidthPRDClearing;