| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // AES SBox |
| |
| `include "prim_assert.sv" |
| |
| module aes_sbox import aes_pkg::*; |
| #( |
| parameter sbox_impl_e SecSBoxImpl = SBoxImplLut |
| ) ( |
| input logic clk_i, |
| input logic rst_ni, |
| input logic en_i, |
| output logic out_req_o, |
| input logic out_ack_i, |
| input ciph_op_e op_i, |
| input logic [7:0] data_i, |
| input logic [7:0] mask_i, |
| input logic [WidthPRDSBox+19:0] prd_i, |
| output logic [7:0] data_o, |
| output logic [7:0] mask_o, |
| output logic [19:0] prd_o |
| ); |
| |
| // Create a lint error to reduce the risk of accidentally using a less secure SBox |
| // implementation. |
| `ASSERT_STATIC_LINT_ERROR(AesSBoxSecSBoxImplNonDefault, SecSBoxImpl == SBoxImplDom) |
| |
| localparam bit SBoxMasked = (SecSBoxImpl == SBoxImplCanrightMasked || |
| SecSBoxImpl == SBoxImplCanrightMaskedNoreuse || |
| SecSBoxImpl == SBoxImplDom) ? 1'b1 : 1'b0; |
| |
| localparam bit SBoxSingleCycle = (SecSBoxImpl == SBoxImplDom) ? 1'b0 : 1'b1; |
| |
| if (!SBoxMasked) begin : gen_sbox_unmasked |
| // Tie off unused inputs. |
| logic unused_clk; |
| logic unused_rst; |
| logic [7:0] unused_mask; |
| logic [WidthPRDSBox+19:0] unused_prd; |
| assign unused_clk = clk_i; |
| assign unused_rst = rst_ni; |
| assign unused_mask = mask_i; |
| assign unused_prd = prd_i; |
| |
| if (SecSBoxImpl == SBoxImplCanright) begin : gen_sbox_canright |
| aes_sbox_canright u_aes_sbox ( |
| .op_i ( op_i ), |
| .data_i ( data_i ), |
| .data_o ( data_o ) |
| ); |
| |
| end else begin : gen_sbox_lut // SecSBoxImpl == SBoxImplLut |
| aes_sbox_lut u_aes_sbox ( |
| .op_i ( op_i ), |
| .data_i ( data_i ), |
| .data_o ( data_o ) |
| ); |
| end |
| |
| assign mask_o = '0; |
| assign prd_o = '0; |
| |
| end else begin : gen_sbox_masked |
| |
| // SEC_CM: KEY.MASKING |
| if (SecSBoxImpl == SBoxImplDom) begin : gen_sbox_dom |
| |
| aes_sbox_dom u_aes_sbox ( |
| .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[27:0] ), |
| .data_o ( data_o ), |
| .mask_o ( mask_o ), |
| .prd_o ( prd_o ) |
| ); |
| |
| `ASSERT_INIT(AesWidthPRDSBox, WidthPRDSBox == 8) |
| |
| end else if (SecSBoxImpl == SBoxImplCanrightMaskedNoreuse) begin : |
| gen_sbox_canright_masked_noreuse |
| // Tie off unused inputs. |
| logic unused_clk; |
| logic unused_rst; |
| logic [19:0] unused_prd; |
| assign unused_clk = clk_i; |
| assign unused_rst = rst_ni; |
| assign unused_prd = prd_i[WidthPRDSBox+19:WidthPRDSBox]; |
| |
| aes_sbox_canright_masked_noreuse u_aes_sbox ( |
| .op_i ( op_i ), |
| .data_i ( data_i ), |
| .mask_i ( mask_i ), |
| .prd_i ( prd_i[17:0] ), |
| .data_o ( data_o ), |
| .mask_o ( mask_o ) |
| ); |
| |
| assign prd_o = '0; |
| |
| `ASSERT_INIT(AesWidthPRDSBox, WidthPRDSBox == 18) |
| |
| end else begin : gen_sbox_canright_masked // SecSBoxImpl == SBoxImplCanrightMasked |
| // Tie off unused inputs. |
| logic unused_clk; |
| logic unused_rst; |
| logic [19:0] unused_prd; |
| assign unused_clk = clk_i; |
| assign unused_rst = rst_ni; |
| assign unused_prd = prd_i[WidthPRDSBox+19:WidthPRDSBox]; |
| |
| aes_sbox_canright_masked u_aes_sbox ( |
| .op_i ( op_i ), |
| .data_i ( data_i ), |
| .mask_i ( mask_i ), |
| .prd_i ( prd_i[7:0] ), |
| .data_o ( data_o ), |
| .mask_o ( mask_o ) |
| ); |
| |
| assign prd_o = '0; |
| |
| `ASSERT_INIT(AesWidthPRDSBox, WidthPRDSBox == 8) |
| end |
| end |
| |
| if (SBoxSingleCycle) begin : gen_req_singlecycle |
| // Tie off unused inputs. |
| logic unused_out_ack; |
| assign unused_out_ack = out_ack_i; |
| |
| // Signal that we have valid output right away. |
| assign out_req_o = en_i; |
| end |
| |
| endmodule |