[aes, pre_sca] Enable formal verification of more than a single S-Box
This commit enables the formal verification of either the full SubBytes,
i.e., the 16 S-Boxes in the data path, and even a reduced AES round
containing also ShiftRows and MixColumns. This is useful as formal
verification of the entire AES cipher core is currently out of scope
from a tool run time point of view whereas SCA leakage outside the
reduced AES round is unlikely.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/hw/ip/aes/rtl/aes_reduced_round.sv b/hw/ip/aes/rtl/aes_reduced_round.sv
new file mode 100644
index 0000000..3e9b79a
--- /dev/null
+++ b/hw/ip/aes/rtl/aes_reduced_round.sv
@@ -0,0 +1,80 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// AES reduced round data path
+// This module is useful for formal masking verification using e.g. Alma.
+// For details, see hw/ip/aes/pre_sca/alma/README.md .
+
+module aes_reduced_round import aes_pkg::*;
+#(
+ parameter sbox_impl_e SBoxImpl = SBoxImplLut
+) (
+ input logic clk_i,
+ input logic rst_ni,
+ input sp2v_e en_i,
+ output sp2v_e out_req_o,
+ input sp2v_e out_ack_i,
+ input ciph_op_e op_i,
+ input logic [3:0][3:0][7:0] data_i,
+ input logic [3:0][3:0][7:0] mask_i,
+ input logic [3:0][3:0][WidthPRDSBox-1:0] prd_i,
+ output logic [3:0][3:0][7:0] data_o,
+ output logic [3:0][3:0][7:0] mask_o,
+ output logic err_o
+);
+
+ localparam int NumShares = 2;
+
+ // Signals
+ logic [3:0][3:0][7:0] sub_bytes_out;
+ logic [3:0][3:0][7:0] sb_out_mask;
+ logic [3:0][3:0][7:0] shift_rows_in [NumShares];
+ logic [3:0][3:0][7:0] shift_rows_out [NumShares];
+ logic [3:0][3:0][7:0] mix_columns_out [NumShares];
+
+ // A single reduced (no AddKey) round of the cipher data path
+ aes_sub_bytes #(
+ .SBoxImpl ( SBoxImpl )
+ ) u_aes_sub_bytes (
+ .clk_i ( clk_i ),
+ .rst_ni ( rst_ni ),
+ .en_i ( en_i ),
+ .out_req_o ( out_req_o ),
+ .out_ack_i ( out_ack_i ),
+ .op_i ( op_i ),
+ .data_i ( data_i ),
+ .mask_i ( mask_i ),
+ .prd_i ( prd_i ),
+ .data_o ( sub_bytes_out ),
+ .mask_o ( sb_out_mask ),
+ .err_o ( err_o )
+ );
+
+ for (genvar s = 0; s < NumShares; s++) begin : gen_shares_shift_mix
+ if (s == 0) begin : gen_shift_in_data
+ // The (masked) data share
+ assign shift_rows_in[s] = sub_bytes_out;
+ end else begin : gen_shift_in_mask
+ // The mask share
+ assign shift_rows_in[s] = sb_out_mask;
+ end
+
+ aes_shift_rows u_aes_shift_rows (
+ .op_i ( op_i ),
+ .data_i ( shift_rows_in[s] ),
+ .data_o ( shift_rows_out[s] )
+ );
+
+ aes_mix_columns u_aes_mix_columns (
+ .op_i ( op_i ),
+ .data_i ( shift_rows_out[s] ),
+ .data_o ( mix_columns_out[s] )
+ );
+ end
+
+ // Outputs
+ assign data_o = mix_columns_out[0];
+ assign mask_o = mix_columns_out[1];
+
+endmodule