blob: a03ae5178ea3e02708ce3a743c46e2922dfd64a4 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// AES SubBytes
module aes_sub_bytes import aes_pkg::*;
#(
parameter sbox_impl_e SecSBoxImpl = SBoxImplDom
) (
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
);
sp2v_e en;
logic en_err;
logic [3:0][3:0] out_req;
sp2v_e out_ack;
logic out_ack_err;
// Every DOM S-Box instance consumes 28 bits of randomness but itself produces 20 bits for use in
// another S-Box instance. For other S-Box implementations, only the bits corresponding to prd_i
// are used. Other bits are ignored and tied to 0.
logic [3:0][3:0][WidthPRDSBox+19:0] in_prd;
logic [3:0][3:0] [19:0] out_prd;
// SEC_CM: CTRL.SPARSE
// Check sparsely encoded signals.
logic [Sp2VWidth-1:0] en_raw;
aes_sel_buf_chk #(
.Num ( Sp2VNum ),
.Width ( Sp2VWidth ),
.EnSecBuf ( 1'b1 )
) u_aes_sb_en_buf_chk (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.sel_i ( en_i ),
.sel_o ( en_raw ),
.err_o ( en_err )
);
assign en = sp2v_e'(en_raw);
logic [Sp2VWidth-1:0] out_ack_raw;
aes_sel_buf_chk #(
.Num ( Sp2VNum ),
.Width ( Sp2VWidth ),
.EnSecBuf ( 1'b1 )
) u_aes_sb_out_ack_buf_chk (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.sel_i ( out_ack_i ),
.sel_o ( out_ack_raw ),
.err_o ( out_ack_err )
);
assign out_ack = sp2v_e'(out_ack_raw);
// Individually substitute bytes.
for (genvar j = 0; j < 4; j++) begin : gen_sbox_j
for (genvar i = 0; i < 4; i++) begin : gen_sbox_i
// Rotate the randomness produced by the S-Boxes over the columns but not across rows as
// MixColumns will operate across rows. The LSBs are taken from the masking PRNG (prd_i)
// whereas the MSBs are produced by the other S-Box instances.
assign in_prd[i][j] = {out_prd[i][aes_rot_int(j,4)], prd_i[i][j]};
aes_sbox #(
.SecSBoxImpl ( SecSBoxImpl )
) u_aes_sbox_ij (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.en_i ( en == SP2V_HIGH ),
.out_req_o ( out_req[i][j] ),
.out_ack_i ( out_ack == SP2V_HIGH ),
.op_i ( op_i ),
.data_i ( data_i[i][j] ),
.mask_i ( mask_i[i][j] ),
.prd_i ( in_prd[i][j] ),
.data_o ( data_o[i][j] ),
.mask_o ( mask_o[i][j] ),
.prd_o ( out_prd[i][j] )
);
end
end
// Collect REQ signals.
assign out_req_o = &out_req ? SP2V_HIGH : SP2V_LOW;
// Collect encoding errors.
assign err_o = en_err | out_ack_err;
endmodule