From e4b4ae51cd1e2ae076de3f5ee75c16f1409f269d Mon Sep 17 00:00:00 2001 From: Pirmin Vogel Date: Thu, 7 Nov 2024 22:08:55 +0100 Subject: [PATCH] WIP Signed-off-by: Pirmin Vogel --- hw/ip/aes/rtl/aes_ghash.sv | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/hw/ip/aes/rtl/aes_ghash.sv b/hw/ip/aes/rtl/aes_ghash.sv index ed17a07107f101..296c2e295af60a 100644 --- a/hw/ip/aes/rtl/aes_ghash.sv +++ b/hw/ip/aes/rtl/aes_ghash.sv @@ -136,6 +136,7 @@ module aes_ghash logic [GCMDegree-1:0] s_d [NumSharesLocal]; logic [GCMDegree-1:0] s_q [NumSharesLocal]; sp2v_e s_we; + sp2v_e s1_we; logic [15:0][7:0] ghash_in; logic [15:0][7:0] ghash_in_valid; ghash_in_sel_e ghash_in_sel; @@ -176,11 +177,35 @@ module aes_ghash // S = AES_K(J_0) // //////////////////// // The initial counter block J_0 encrypted using the encryption key K. For the unmasked - // implementation this is only used at the very end. For the masked implementaion, it is used - // multiple times and in various forms throughout the computation of the authentication tag. + // implementation this is only used at the very end. + // + // For the masked implementaion, it is used multiple times in the form of correction terms + // throughout the computation of the authentication tag. After loading S and the hash subkey, + // the GHASH state is initialized with S and the computation of the correction terms is + // triggered. The correction terms are then stored back into these registers. After this point, + // only Share 1 of S is used again in it's original form at the very end. We thus store it in a + // dedicated register. // // This register can be cleared with pseudo-random data by loading the output of the cipher // core after having cleared the internal state of the cipher core. + if (SecMasking) begin : gen_s1_reg + logic [GCMDegree-1:0] s1_d; + logic [GCMDegree-1:0] s1_q; + + assign s1_d = cipher_state_done[1]; + always_ff @(posedge clk_i or negedge rst_ni) begin : s1_reg + if (!rst_ni) begin + s1_q <= '0; + end else if (s1_we == SP2V_HIGH) begin + s1_q <= s1_d; + end + end + end else begin : gen_no_s1_reg + // Tie-off unused signals. + sp2v_e unused_s1_we; + assign unused_s1_we = s1_we; + end + assign s_d = cipher_state_done; always_ff @(posedge clk_i or negedge rst_ni) begin : s_reg if (!rst_ni) begin @@ -223,10 +248,11 @@ module aes_ghash end end + // We initialize the state with S (masked implementation) or with zero (unmasked implementation). always_comb begin : ghash_state_mux unique case (ghash_state_sel) GHASH_STATE_RESTORE: ghash_state_d = cipher_state_init; - GHASH_STATE_INIT: ghash_state_d = '{default: '0}; + GHASH_STATE_INIT: ghash_state_d = SecMasking ? s_q : '{default: '0}; GHASH_STATE_ADD: ghash_state_d = ghash_state_add; GHASH_STATE_MULT: ghash_state_d = ghash_state_mult; default: ghash_state_d = ghash_state_add; @@ -292,7 +318,8 @@ module aes_ghash out_valid_o = SP2V_LOW; // Data path - s_we = SP2V_LOW; + s_we = SP2V_LOW; + s1_we = SP2V_LOW; ghash_in_sel = GHASH_IN_DATA_OUT; @@ -316,6 +343,7 @@ module aes_ghash if (clear_i) begin // Clearing has highest priority. s_we = SP2V_HIGH; + s1_we = SP2V_HIGH; ghash_state_we = SP2V_HIGH; hash_subkey_we = SP2V_HIGH; @@ -328,6 +356,7 @@ module aes_ghash // Load S and initialize the state. s_we = SP2V_HIGH; + s1_we = SP2V_HIGH; ghash_state_sel = GHASH_STATE_INIT; ghash_state_we = SP2V_HIGH; end @@ -391,6 +420,7 @@ module aes_ghash out_valid_o = SP2V_HIGH; if (out_ready_i == SP2V_HIGH) begin s_we = SP2V_HIGH; + s1_we = SP2V_HIGH; ghash_state_we = SP2V_HIGH; hash_subkey_we = SP2V_HIGH; aes_ghash_ns = GHASH_IDLE;