1 |
2 |
ruschi |
-------------------------------------------------------------------------------
|
2 |
10 |
ruschi |
-- This file is part of the project avs_aes
|
3 |
|
|
-- see: http://opencores.org/project,avs_aes
|
4 |
2 |
ruschi |
--
|
5 |
|
|
-- description:
|
6 |
|
|
-- Complete structural description of the AES core. No processes or protocol
|
7 |
|
|
-- handling is done at this level. This component is entirely depending on the
|
8 |
|
|
-- underlying elements.
|
9 |
|
|
--
|
10 |
|
|
-- Author(s):
|
11 |
|
|
-- Thomas Ruschival -- ruschi@opencores.org (www.ruschival.de)
|
12 |
|
|
--
|
13 |
|
|
--------------------------------------------------------------------------------
|
14 |
|
|
-- Copyright (c) 2009, Thomas Ruschival
|
15 |
|
|
-- All rights reserved.
|
16 |
|
|
--
|
17 |
|
|
-- Redistribution and use in source and binary forms, with or without modification,
|
18 |
|
|
-- are permitted provided that the following conditions are met:
|
19 |
|
|
-- * Redistributions of source code must retain the above copyright notice,
|
20 |
|
|
-- this list of conditions and the following disclaimer.
|
21 |
|
|
-- * Redistributions in binary form must reproduce the above copyright notice,
|
22 |
|
|
-- this list of conditions and the following disclaimer in the documentation
|
23 |
|
|
-- and/or other materials provided with the distribution.
|
24 |
|
|
-- * Neither the name of the nor the names of its contributors
|
25 |
|
|
-- may be used to endorse or promote products derived from this software without
|
26 |
|
|
-- specific prior written permission.
|
27 |
|
|
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
28 |
|
|
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
29 |
|
|
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
30 |
|
|
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
31 |
|
|
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
32 |
|
|
-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
33 |
|
|
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
34 |
|
|
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
35 |
|
|
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
36 |
|
|
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
37 |
|
|
-- THE POSSIBILITY OF SUCH DAMAGE
|
38 |
|
|
-------------------------------------------------------------------------------
|
39 |
|
|
-- version management:
|
40 |
|
|
-- $Author$
|
41 |
|
|
-- $Date$
|
42 |
|
|
-- $Revision$
|
43 |
|
|
-------------------------------------------------------------------------------
|
44 |
|
|
|
45 |
|
|
library ieee;
|
46 |
|
|
use ieee.std_logic_1164.all;
|
47 |
|
|
use ieee.numeric_std.all;
|
48 |
|
|
|
49 |
11 |
ruschi |
library avs_aes_lib;
|
50 |
|
|
use avs_aes_lib.avs_aes_pkg.all;
|
51 |
2 |
ruschi |
|
52 |
|
|
entity AES_CORE is
|
53 |
|
|
generic (
|
54 |
|
|
KEYLENGTH : NATURAL := 128; -- Size of keyblock (128, 192, 256 Bits)
|
55 |
|
|
DECRYPTION : BOOLEAN := false -- include decrypt datapath
|
56 |
|
|
);
|
57 |
|
|
port(
|
58 |
|
|
clk : in STD_LOGIC; -- system clock
|
59 |
|
|
data_in : in STATE; -- payload to encrypt
|
60 |
|
|
data_stable : in STD_LOGIC; -- flag valid payload
|
61 |
|
|
keyword : in DWORD; -- word of original userkey
|
62 |
|
|
keywordaddr : in STD_LOGIC_VECTOR(2 downto 0); -- keyword register address
|
63 |
|
|
w_ena_keyword : in STD_LOGIC; -- write enable of keyword to wordaddr
|
64 |
|
|
key_stable : in STD_LOGIC; -- key is complete and valid, start expansion
|
65 |
|
|
decrypt_mode : in STD_LOGIC; -- decrypt='1',encrypt='0'
|
66 |
|
|
keyexp_done : out STD_LOGIC; -- keyprocessing is done
|
67 |
|
|
result : out STATE; -- output
|
68 |
|
|
finished : out STD_LOGIC -- output valid
|
69 |
|
|
);
|
70 |
|
|
-- number of rounds 10, 12 or 14, needed for looping
|
71 |
|
|
constant NO_ROUNDS : NATURAL := lookupRounds(KEYLENGTH);
|
72 |
|
|
end AES_CORE;
|
73 |
|
|
|
74 |
|
|
|
75 |
|
|
architecture arch1 of AES_CORE is
|
76 |
|
|
---------------------------------------------------------------------------
|
77 |
|
|
-- signal for encrypt datapath
|
78 |
|
|
---------------------------------------------------------------------------
|
79 |
|
|
signal addkey_in_enc : STATE; -- State for this round
|
80 |
|
|
signal mixcol_out_enc : STATE; -- State with mixed Colums
|
81 |
|
|
signal sbox_out_enc : STATE; -- 4 columns output form ROM
|
82 |
|
|
signal shiftrow_out_enc : STATE; -- shifted state
|
83 |
|
|
signal addkey_out_enc : STATE; -- result of add key
|
84 |
|
|
-- control signals
|
85 |
|
|
signal roundkey_idx_enc : NIBBLE; -- index for selecting roundkey
|
86 |
|
|
signal round_type_enc : STD_LOGIC_VECTOR(1 downto 0); -- switch to select ports
|
87 |
|
|
signal finished_enc : STD_LOGIC; -- encryption has terminated
|
88 |
|
|
signal ena_encrypt : STD_LOGIC; -- enable encryption fsm only if not
|
89 |
|
|
-- decryption is running
|
90 |
|
|
-- (data_stable AND not decrypt_mode='1')
|
91 |
|
|
---------------------------------------------------------------------------
|
92 |
|
|
-- Signals for decrypt datapath
|
93 |
|
|
---------------------------------------------------------------------------
|
94 |
|
|
signal addkey_in_dec : STATE; -- input for addkey
|
95 |
|
|
signal addkey_out_dec : STATE; -- output of addkey
|
96 |
|
|
signal mixcol_out_dec : STATE; -- State with mixed Colums
|
97 |
|
|
signal sbox_out_dec : STATE; -- 4 columns output form ROM
|
98 |
|
|
signal shiftrow_in_dec : STATE; -- multiplexer output for shiftrow
|
99 |
|
|
signal shiftrow_out_dec : STATE; -- shifted state
|
100 |
|
|
-- control signals
|
101 |
|
|
signal round_type_dec : STD_LOGIC_VECTOR(1 downto 0); -- switch to select ports
|
102 |
|
|
signal roundkey_idx_dec : NIBBLE; -- index for selecting roundkey
|
103 |
|
|
signal finished_dec : STD_LOGIC; -- decryption has terminated
|
104 |
|
|
signal ena_decrypt : STD_LOGIC; -- enable encryption fsm only if not
|
105 |
|
|
-- decryption is running
|
106 |
|
|
-- (data_stable AND decrypt_mode='1')
|
107 |
|
|
---------------------------------------------------------------------------
|
108 |
|
|
-- Common signals encrypt and decrypt
|
109 |
|
|
---------------------------------------------------------------------------
|
110 |
|
|
signal roundkey_idx : NIBBLE; -- multiplexed round index
|
111 |
|
|
signal key_ready : STD_LOGIC; -- ouput of keyexpansion
|
112 |
|
|
signal roundkey : KEYBLOCK; -- Roundkey
|
113 |
|
|
|
114 |
|
|
begin -- architecture arch1
|
115 |
|
|
---------------------------------------------------------------------------
|
116 |
|
|
-- Multiplexers for switching encrypt and decrypt controller
|
117 |
|
|
-- only needed if decryption datapath is enabled
|
118 |
|
|
---------------------------------------------------------------------------
|
119 |
|
|
decryption_result_mux : if DECRYPTION generate
|
120 |
|
|
-- Multiplexed result port
|
121 |
|
|
ResultMux : for i in 0 to 3 generate
|
122 |
|
|
Multiplex : mux2
|
123 |
|
|
generic map (
|
124 |
|
|
IOwidth => DWORD_WIDTH)
|
125 |
|
|
port map (
|
126 |
|
|
inport_a => addkey_out_enc(i),
|
127 |
|
|
inport_b => addkey_out_dec(i),
|
128 |
|
|
selector => decrypt_mode, -- decrypt='1',encrypt='0'
|
129 |
|
|
outport => Result(i));
|
130 |
|
|
end generate ResultMux;
|
131 |
|
|
|
132 |
|
|
-- Multiplexed control over key index
|
133 |
|
|
keyindexMux : mux2
|
134 |
|
|
generic map (
|
135 |
|
|
IOwidth => NIBBLE_WIDTH)
|
136 |
|
|
port map (
|
137 |
|
|
inport_a => roundkey_idx_enc,
|
138 |
|
|
inport_b => roundkey_idx_dec,
|
139 |
|
|
selector => decrypt_mode, -- decrypt='1',encrypt='0'
|
140 |
|
|
outport => roundkey_idx);
|
141 |
|
|
|
142 |
|
|
-- Multiplexed finished signal
|
143 |
|
|
finished <= finished_enc when decrypt_mode = '0' else finished_dec;
|
144 |
|
|
end generate decryption_result_mux;
|
145 |
|
|
|
146 |
|
|
---------------------------------------------------------------------------
|
147 |
|
|
-- No DECRYPTION MODE --> multiplexers not needed
|
148 |
|
|
---------------------------------------------------------------------------
|
149 |
|
|
ecryption_only : if not DECRYPTION generate
|
150 |
|
|
-- result:
|
151 |
|
|
result <= addkey_out_enc;
|
152 |
|
|
--finished flag
|
153 |
|
|
finished <= finished_enc;
|
154 |
|
|
-- key index:
|
155 |
|
|
roundkey_idx <= roundkey_idx_enc;
|
156 |
|
|
end generate ecryption_only;
|
157 |
|
|
|
158 |
|
|
|
159 |
|
|
---------------------------------------------------------------------------
|
160 |
|
|
-- Key generator for roundkeys (decrypt and encrypt)
|
161 |
|
|
---------------------------------------------------------------------------
|
162 |
|
|
roundkey_generator : keyexpansionV2
|
163 |
|
|
generic map (
|
164 |
|
|
KEYLENGTH => KEYLENGTH) -- Size of keyblock (128, 192, 256 Bits)
|
165 |
|
|
port map (
|
166 |
|
|
clk => clk, -- system clock
|
167 |
|
|
keyword => keyword, -- word of original userkey
|
168 |
|
|
keywordaddr => keywordaddr, -- keyword register address
|
169 |
|
|
w_ena_keyword => w_ena_keyword, -- write enable of keyword to wordaddr
|
170 |
|
|
key_stable => key_stable, -- key is completa and valid, start expansion
|
171 |
|
|
roundkey_idx => roundkey_idx, -- index for selecting roundkey
|
172 |
|
|
roundkey => roundkey, -- key for each round
|
173 |
|
|
ready => key_ready); -- expansion done, roundkeys ready
|
174 |
|
|
|
175 |
|
|
-- Signal to the top level instance for availability of key
|
176 |
|
|
-- maybe used to create avalon waitrequests if key is written to keyaddress
|
177 |
|
|
-- range while other key is still in processing
|
178 |
|
|
keyexp_done <= key_ready;
|
179 |
|
|
|
180 |
|
|
-------------------------------------------------------------------------------
|
181 |
|
|
-- Encrypt datapath (always included)
|
182 |
|
|
-------------------------------------------------------------------------------
|
183 |
|
|
|
184 |
|
|
---------------------------------------------------------------------------
|
185 |
|
|
-- encryption FSM is always needed
|
186 |
|
|
---------------------------------------------------------------------------
|
187 |
|
|
ena_encrypt <= data_stable and not decrypt_mode;
|
188 |
|
|
|
189 |
|
|
-- Controller for encrypt
|
190 |
|
|
FSM_ENC : AES_FSM_ENCRYPT
|
191 |
|
|
generic map (
|
192 |
|
|
NO_ROUNDS => NO_ROUNDS)
|
193 |
|
|
port map (
|
194 |
|
|
clk => clk,
|
195 |
|
|
data_stable => ena_encrypt,
|
196 |
|
|
key_ready => key_ready,
|
197 |
|
|
round_index_out => roundkey_idx_enc,
|
198 |
|
|
finished => finished_enc,
|
199 |
|
|
round_type_sel => round_type_enc
|
200 |
|
|
);
|
201 |
|
|
|
202 |
|
|
---------------------------------------------------------------------------
|
203 |
|
|
-- 4 SboxBlocks of 2 SboxM4K each for the single columns
|
204 |
|
|
---------------------------------------------------------------------------
|
205 |
|
|
sboxROMs_enc : for i in 0 to 3 generate
|
206 |
|
|
HighWord : sbox
|
207 |
|
|
generic map (
|
208 |
|
|
INVERSE => false)
|
209 |
|
|
port map (
|
210 |
|
|
clk => clk,
|
211 |
|
|
address_a => addkey_out_enc(i)(31 downto 24),
|
212 |
|
|
address_b => addkey_out_enc(i)(23 downto 16),
|
213 |
|
|
q_a => sbox_out_enc(i)(31 downto 24),
|
214 |
|
|
q_b => sbox_out_enc(i)(23 downto 16));
|
215 |
|
|
LowWord : sbox
|
216 |
|
|
generic map (
|
217 |
|
|
INVERSE => false)
|
218 |
|
|
port map (
|
219 |
|
|
clk => clk,
|
220 |
|
|
address_a => addkey_out_enc(i)(15 downto 8),
|
221 |
|
|
address_b => addkey_out_enc(i)(7 downto 0),
|
222 |
|
|
q_a => sbox_out_enc(i)(15 downto 8),
|
223 |
|
|
q_b => sbox_out_enc(i)(7 downto 0));
|
224 |
|
|
end generate sboxROMs_enc;
|
225 |
|
|
|
226 |
|
|
|
227 |
|
|
---------------------------------------------------------------------------
|
228 |
|
|
-- Shiftrow step (encryption datapath)
|
229 |
|
|
---------------------------------------------------------------------------
|
230 |
11 |
ruschi |
shiftrow_enc : entity avs_aes_lib.Shiftrow(fwd)
|
231 |
2 |
ruschi |
port map (
|
232 |
|
|
state_in => sbox_out_enc,
|
233 |
|
|
state_out => shiftrow_out_enc
|
234 |
|
|
);
|
235 |
|
|
|
236 |
|
|
---------------------------------------------------------------------------
|
237 |
|
|
-- mix column step
|
238 |
|
|
---------------------------------------------------------------------------
|
239 |
|
|
MixColArray_enc : for i in 0 to 3 generate
|
240 |
11 |
ruschi |
mix_column_enc : entity avs_aes_lib.Mixcol(fwd)
|
241 |
2 |
ruschi |
port map (
|
242 |
|
|
col_in => shiftrow_out_enc(i),
|
243 |
|
|
col_out => mixcol_out_enc(i));
|
244 |
|
|
end generate MixColArray_enc;
|
245 |
|
|
|
246 |
|
|
---------------------------------------------------------------------------
|
247 |
|
|
-- Multiplexer for input to AddRoundKey, depending on round_type
|
248 |
|
|
-- Initial round "00": directly feed data_in (data block)
|
249 |
|
|
-- regular round "01": feed result from mix_column
|
250 |
|
|
-- final round "10": skip mixcolumn and feed result from shiftrow
|
251 |
|
|
---------------------------------------------------------------------------
|
252 |
|
|
AddKeyMuxArray_enc : for i in 0 to 3 generate
|
253 |
|
|
AddKeyMux : mux3
|
254 |
|
|
generic map (
|
255 |
|
|
IOwidth => DWORD_WIDTH)
|
256 |
|
|
port map (
|
257 |
|
|
inport_a => data_in(i),
|
258 |
|
|
inport_b => mixcol_out_enc(i),
|
259 |
|
|
inport_c => shiftrow_out_enc(i),
|
260 |
|
|
selector => round_type_enc,
|
261 |
|
|
outport => addkey_in_enc(i));
|
262 |
|
|
end generate AddKeyMuxArray_enc;
|
263 |
|
|
|
264 |
|
|
---------------------------------------------------------------------------
|
265 |
|
|
-- key addition (encrypt datapath)
|
266 |
|
|
---------------------------------------------------------------------------
|
267 |
|
|
Keyadder_enc : AddRoundKey
|
268 |
|
|
port map (
|
269 |
|
|
roundkey => roundkey,
|
270 |
|
|
cypherblock => addkey_in_enc,
|
271 |
|
|
result => addkey_out_enc
|
272 |
|
|
);
|
273 |
|
|
|
274 |
|
|
---------------------------------------------------------------------------
|
275 |
|
|
-- Decrypt datapath
|
276 |
|
|
---------------------------------------------------------------------------
|
277 |
|
|
decrypt_datapath : if DECRYPTION generate
|
278 |
|
|
---------------------------------------------------------------------------
|
279 |
|
|
-- Decryption FSM
|
280 |
|
|
---------------------------------------------------------------------------
|
281 |
|
|
ena_decrypt <= data_stable and decrypt_mode;
|
282 |
|
|
|
283 |
|
|
FSM_DEC : AES_FSM_DECRYPT
|
284 |
|
|
generic map (
|
285 |
|
|
NO_ROUNDS => NO_ROUNDS)
|
286 |
|
|
port map (
|
287 |
|
|
clk => clk,
|
288 |
|
|
data_stable => ena_decrypt,
|
289 |
|
|
key_ready => key_ready,
|
290 |
|
|
round_index_out => roundkey_idx_dec,
|
291 |
|
|
finished => finished_dec,
|
292 |
|
|
round_type_sel => round_type_dec
|
293 |
|
|
);
|
294 |
|
|
|
295 |
|
|
---------------------------------------------------------------------------
|
296 |
|
|
-- key addition (Decrypt datapath)
|
297 |
|
|
-- Multiplexed input on addkey (data_in or feedback)
|
298 |
|
|
---------------------------------------------------------------------------
|
299 |
|
|
AKinputMux : for i in 0 to 3 generate
|
300 |
|
|
mux : Mux2
|
301 |
|
|
generic map (
|
302 |
|
|
IOwidth => DWORD_WIDTH)
|
303 |
|
|
port map (
|
304 |
|
|
inport_a => data_in(i),
|
305 |
|
|
inport_b => sbox_out_dec(i),
|
306 |
|
|
selector => round_type_dec(0),
|
307 |
|
|
outport => addkey_in_dec(i));
|
308 |
|
|
end generate AKinputMux;
|
309 |
|
|
|
310 |
|
|
Keyadder_dec : AddRoundKey
|
311 |
|
|
port map (
|
312 |
|
|
roundkey => roundkey,
|
313 |
|
|
cypherblock => addkey_in_dec,
|
314 |
|
|
result => addkey_out_dec
|
315 |
|
|
);
|
316 |
|
|
---------------------------------------------------------------------------
|
317 |
|
|
-- Inverse mixcolumn
|
318 |
|
|
---------------------------------------------------------------------------
|
319 |
|
|
InverseMixCol : for i in 0 to 3 generate
|
320 |
11 |
ruschi |
mix_column_dec : entity avs_aes_lib.Mixcol(inv)
|
321 |
2 |
ruschi |
port map (
|
322 |
|
|
col_in => addkey_out_dec(i),
|
323 |
|
|
col_out => mixcol_out_dec(i));
|
324 |
|
|
end generate InverseMixCol;
|
325 |
|
|
|
326 |
|
|
---------------------------------------------------------------------------
|
327 |
|
|
-- Inverse Shiftrow
|
328 |
|
|
-- multiplexed input form either addkey_out_dec during loop or mixcol_out_dec
|
329 |
|
|
-- when exiting loop
|
330 |
|
|
---------------------------------------------------------------------------
|
331 |
|
|
SRinputMux : for i in 0 to 3 generate
|
332 |
|
|
mux : Mux2
|
333 |
|
|
generic map (
|
334 |
|
|
IOwidth => 32)
|
335 |
|
|
port map (
|
336 |
|
|
inport_a => addkey_out_dec(i),
|
337 |
|
|
inport_b => mixcol_out_dec(i),
|
338 |
|
|
selector => round_type_dec(0),
|
339 |
|
|
outport => shiftrow_in_dec(i));
|
340 |
|
|
end generate SRinputMux;
|
341 |
|
|
|
342 |
11 |
ruschi |
Shiftrow_dec : entity avs_aes_lib.Shiftrow(inv)
|
343 |
2 |
ruschi |
port map (
|
344 |
|
|
state_in => shiftrow_in_dec,
|
345 |
|
|
state_out => shiftrow_out_dec
|
346 |
|
|
);
|
347 |
|
|
|
348 |
|
|
---------------------------------------------------------------------------
|
349 |
|
|
-- 4 INVERSE SboxBlocks of 2 SboxM4K each for the single columns
|
350 |
|
|
---------------------------------------------------------------------------
|
351 |
|
|
sboxROMs_dec : for i in 0 to 3 generate
|
352 |
|
|
HighWord : sbox
|
353 |
|
|
generic map (
|
354 |
|
|
INVERSE => true)
|
355 |
|
|
port map (
|
356 |
|
|
clk => clk,
|
357 |
|
|
address_a => shiftrow_out_dec(i)(31 downto 24),
|
358 |
|
|
address_b => shiftrow_out_dec(i)(23 downto 16),
|
359 |
|
|
q_a => sbox_out_dec(i)(31 downto 24),
|
360 |
|
|
q_b => sbox_out_dec(i)(23 downto 16));
|
361 |
|
|
LowWord : sbox
|
362 |
|
|
generic map (
|
363 |
|
|
INVERSE => true)
|
364 |
|
|
port map (
|
365 |
|
|
clk => clk,
|
366 |
|
|
address_a => shiftrow_out_dec(i)(15 downto 8),
|
367 |
|
|
address_b => shiftrow_out_dec(i)(7 downto 0),
|
368 |
|
|
q_a => sbox_out_dec(i)(15 downto 8),
|
369 |
|
|
q_b => sbox_out_dec(i)(7 downto 0));
|
370 |
|
|
end generate sboxROMs_dec;
|
371 |
|
|
end generate decrypt_datapath;
|
372 |
|
|
|
373 |
|
|
end architecture arch1;
|