../src/lowrisc_ip_aes_0.6/rtl/aes_cipher_core.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4: //
5: // AES cipher core implementation
6: //
7: // This module contains the AES cipher core including, state register, full key and decryption key
8: // registers as well as key expand module and control unit.
9:
10: `include "prim_assert.sv"
11:
12: module aes_cipher_core #(
13: parameter bit AES192Enable = 1,
14: parameter SBoxImpl = "lut"
15: ) (
16: input logic clk_i,
17: input logic rst_ni,
18:
19: // Input handshake signals
20: input logic in_valid_i,
21: output logic in_ready_o,
22:
23: // Output handshake signals
24: output logic out_valid_o,
25: input logic out_ready_i,
26:
27: // Control and sync signals
28: input aes_pkg::ciph_op_e op_i,
29: input aes_pkg::key_len_e key_len_i,
30: input logic crypt_i,
31: output logic crypt_o,
32: input logic dec_key_gen_i,
33: output logic dec_key_gen_o,
34: input logic key_clear_i,
35: output logic key_clear_o,
36: input logic data_out_clear_i, // Re-use the cipher core muxes.
37: output logic data_out_clear_o,
38:
39: // Pseudo-random data
40: input logic [63:0] prng_data_i,
41:
42: // I/O data & initial key
43: input logic [3:0][3:0][7:0] state_init_i,
44: input logic [7:0][31:0] key_init_i,
45: output logic [3:0][3:0][7:0] state_o
46: );
47:
48: import aes_pkg::*;
49:
50: // Signals
51: logic [3:0][3:0][7:0] state_d;
52: logic [3:0][3:0][7:0] state_q;
53: logic state_we;
54: state_sel_e state_sel;
55:
56: logic [3:0][3:0][7:0] sub_bytes_out;
57: logic [3:0][3:0][7:0] shift_rows_out;
58: logic [3:0][3:0][7:0] mix_columns_out;
59: logic [3:0][3:0][7:0] add_round_key_in;
60: logic [3:0][3:0][7:0] add_round_key_out;
61: add_rk_sel_e add_round_key_in_sel;
62:
63: logic [7:0][31:0] key_full_d;
64: logic [7:0][31:0] key_full_q;
65: logic key_full_we;
66: key_full_sel_e key_full_sel;
67: logic [7:0][31:0] key_dec_d;
68: logic [7:0][31:0] key_dec_q;
69: logic key_dec_we;
70: key_dec_sel_e key_dec_sel;
71: logic [7:0][31:0] key_expand_out;
72: ciph_op_e key_expand_op;
73: logic key_expand_step;
74: logic key_expand_clear;
75: logic [3:0] key_expand_round;
76: key_words_sel_e key_words_sel;
77: logic [3:0][31:0] key_words;
78: logic [3:0][3:0][7:0] key_bytes;
79: logic [3:0][3:0][7:0] key_mix_columns_out;
80: logic [3:0][3:0][7:0] round_key;
81: round_key_sel_e round_key_sel;
82:
83: //////////
84: // Data //
85: //////////
86:
87: // State registers
88: always_comb begin : state_mux
89: unique case (state_sel)
90: STATE_INIT: state_d = state_init_i;
91: STATE_ROUND: state_d = add_round_key_out;
92: STATE_CLEAR: state_d = {prng_data_i, prng_data_i};
93: default: state_d = {prng_data_i, prng_data_i};
94: endcase
95: end
96:
97: always_ff @(posedge clk_i) begin : state_reg
98: if (state_we) begin
99: state_q <= state_d;
100: end
101: end
102:
103: // Cipher data path
104: aes_sub_bytes #(
105: .SBoxImpl ( SBoxImpl )
106: ) aes_sub_bytes (
107: .op_i ( op_i ),
108: .data_i ( state_q ),
109: .data_o ( sub_bytes_out )
110: );
111:
112: aes_shift_rows aes_shift_rows (
113: .op_i ( op_i ),
114: .data_i ( sub_bytes_out ),
115: .data_o ( shift_rows_out )
116: );
117:
118: aes_mix_columns aes_mix_columns (
119: .op_i ( op_i ),
120: .data_i ( shift_rows_out ),
121: .data_o ( mix_columns_out )
122: );
123:
124: always_comb begin : add_round_key_in_mux
125: unique case (add_round_key_in_sel)
126: ADD_RK_INIT: add_round_key_in = state_q;
127: ADD_RK_ROUND: add_round_key_in = mix_columns_out;
128: ADD_RK_FINAL: add_round_key_in = shift_rows_out;
129: default: add_round_key_in = state_q;
130: endcase
131: end
132:
133: assign add_round_key_out = add_round_key_in ^ round_key;
134:
135: /////////
136: // Key //
137: /////////
138:
139: // Full Key registers
140: always_comb begin : key_full_mux
141: unique case (key_full_sel)
142: KEY_FULL_ENC_INIT: key_full_d = key_init_i;
143: KEY_FULL_DEC_INIT: key_full_d = key_dec_q;
144: KEY_FULL_ROUND: key_full_d = key_expand_out;
145: KEY_FULL_CLEAR: key_full_d = {prng_data_i, prng_data_i, prng_data_i, prng_data_i};
146: default: key_full_d = {prng_data_i, prng_data_i, prng_data_i, prng_data_i};
147: endcase
148: end
149:
150: always_ff @(posedge clk_i) begin : key_full_reg
151: if (key_full_we) begin
152: key_full_q <= key_full_d;
153: end
154: end
155:
156: // Decryption Key registers
157: always_comb begin : key_dec_mux
158: unique case (key_dec_sel)
159: KEY_DEC_EXPAND: key_dec_d = key_expand_out;
160: KEY_DEC_CLEAR: key_dec_d = {prng_data_i, prng_data_i, prng_data_i, prng_data_i};
161: default: key_dec_d = {prng_data_i, prng_data_i, prng_data_i, prng_data_i};
162: endcase
163: end
164:
165: always_ff @(posedge clk_i) begin : key_dec_reg
166: if (key_dec_we) begin
167: key_dec_q <= key_dec_d;
168: end
169: end
170:
171: // Key expand data path
172: aes_key_expand #(
173: .AES192Enable ( AES192Enable ),
174: .SBoxImpl ( SBoxImpl )
175: ) aes_key_expand (
176: .clk_i ( clk_i ),
177: .rst_ni ( rst_ni ),
178: .op_i ( key_expand_op ),
179: .step_i ( key_expand_step ),
180: .clear_i ( key_expand_clear ),
181: .round_i ( key_expand_round ),
182: .key_len_i ( key_len_i ),
183: .key_i ( key_full_q ),
184: .key_o ( key_expand_out )
185: );
186:
187: always_comb begin : key_words_mux
188: unique case (key_words_sel)
189: KEY_WORDS_0123: key_words = key_full_q[3:0];
190: KEY_WORDS_2345: key_words = AES192Enable ? key_full_q[5:2] : '0;
191: KEY_WORDS_4567: key_words = key_full_q[7:4];
192: KEY_WORDS_ZERO: key_words = '0;
193: default: key_words = '0;
194: endcase
195: end
196:
197: // Convert words to bytes (every key word contains one column)
198: assign key_bytes = aes_transpose(key_words);
199:
200: aes_mix_columns aes_key_mix_columns (
201: .op_i ( CIPH_INV ),
202: .data_i ( key_bytes ),
203: .data_o ( key_mix_columns_out )
204: );
205:
206: always_comb begin : round_key_mux
207: unique case (round_key_sel)
208: ROUND_KEY_DIRECT: round_key = key_bytes;
209: ROUND_KEY_MIXED: round_key = key_mix_columns_out;
210: default: round_key = key_bytes;
211: endcase
212: end
213:
214: /////////////
215: // Control //
216: /////////////
217:
218: // Control
219: aes_cipher_control aes_cipher_control (
220: .clk_i ( clk_i ),
221: .rst_ni ( rst_ni ),
222:
223: .in_valid_i ( in_valid_i ),
224: .in_ready_o ( in_ready_o ),
225: .out_valid_o ( out_valid_o ),
226: .out_ready_i ( out_ready_i ),
227: .op_i ( op_i ),
228: .key_len_i ( key_len_i ),
229: .crypt_i ( crypt_i ),
230: .crypt_o ( crypt_o ),
231: .dec_key_gen_i ( dec_key_gen_i ),
232: .dec_key_gen_o ( dec_key_gen_o ),
233: .key_clear_i ( key_clear_i ),
234: .key_clear_o ( key_clear_o ),
235: .data_out_clear_i ( data_out_clear_i ),
236: .data_out_clear_o ( data_out_clear_o ),
237:
238: .state_sel_o ( state_sel ),
239: .state_we_o ( state_we ),
240: .add_rk_sel_o ( add_round_key_in_sel ),
241: .key_expand_op_o ( key_expand_op ),
242: .key_full_sel_o ( key_full_sel ),
243: .key_full_we_o ( key_full_we ),
244: .key_dec_sel_o ( key_dec_sel ),
245: .key_dec_we_o ( key_dec_we ),
246: .key_expand_step_o ( key_expand_step ),
247: .key_expand_clear_o ( key_expand_clear ),
248: .key_expand_round_o ( key_expand_round ),
249: .key_words_sel_o ( key_words_sel ),
250: .round_key_sel_o ( round_key_sel )
251: );
252:
253: /////////////
254: // Outputs //
255: /////////////
256:
257: // The output of the last round is not stored into the state register but forwarded directly.
258: assign state_o = add_round_key_out;
259:
260: ////////////////
261: // Assertions //
262: ////////////////
263:
264: // Selectors must be known/valid
265: `ASSERT(AesStateSelValid, state_sel inside {
266: STATE_INIT,
267: STATE_ROUND,
268: STATE_CLEAR
269: })
270: `ASSERT(AesAddRKSelValid, add_round_key_in_sel inside {
271: ADD_RK_INIT,
272: ADD_RK_ROUND,
273: ADD_RK_FINAL
274: })
275: `ASSERT_KNOWN(AesKeyFullSelKnown, key_full_sel)
276: `ASSERT_KNOWN(AesKeyDecSelKnown, key_dec_sel)
277: `ASSERT_KNOWN(AesKeyWordsSelKnown, key_words_sel)
278: `ASSERT_KNOWN(AesRoundKeySelKnown, round_key_sel)
279:
280: endmodule
281: