1 |
11 |
ruschi |
-------------------------------------------------------------------------------
|
2 |
|
|
-- This file is part of the project avs_aes
|
3 |
|
|
-- see: http://opencores.org/project,avs_aes
|
4 |
|
|
--
|
5 |
|
|
-- description:
|
6 |
|
|
-- Central file for definition of types and global functions for handling of
|
7 |
|
|
-- datatypes and generics. All components are defined here.
|
8 |
|
|
--
|
9 |
|
|
-- Author(s):
|
10 |
|
|
-- Thomas Ruschival -- ruschi@opencores.org (www.ruschival.de)
|
11 |
|
|
--
|
12 |
|
|
--------------------------------------------------------------------------------
|
13 |
|
|
-- Copyright (c) 2009, Thomas Ruschival
|
14 |
|
|
-- All rights reserved.
|
15 |
|
|
--
|
16 |
|
|
-- Redistribution and use in source and binary forms, with or without modification,
|
17 |
|
|
-- are permitted provided that the following conditions are met:
|
18 |
|
|
-- * Redistributions of source code must retain the above copyright notice,
|
19 |
|
|
-- this list of conditions and the following disclaimer.
|
20 |
|
|
-- * Redistributions in binary form must reproduce the above copyright notice,
|
21 |
|
|
-- this list of conditions and the following disclaimer in the documentation
|
22 |
|
|
-- and/or other materials provided with the distribution.
|
23 |
|
|
-- * Neither the name of the nor the names of its contributors
|
24 |
|
|
-- may be used to endorse or promote products derived from this software without
|
25 |
|
|
-- specific prior written permission.
|
26 |
|
|
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
27 |
|
|
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
28 |
|
|
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29 |
|
|
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
30 |
|
|
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
31 |
|
|
-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
32 |
|
|
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
33 |
|
|
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
34 |
|
|
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35 |
|
|
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
36 |
|
|
-- THE POSSIBILITY OF SUCH DAMAGE
|
37 |
|
|
-------------------------------------------------------------------------------
|
38 |
|
|
-- version management:
|
39 |
20 |
ruschi |
-- $Author:: $
|
40 |
|
|
-- $Date:: $
|
41 |
|
|
-- $Revision:: $
|
42 |
11 |
ruschi |
-------------------------------------------------------------------------------
|
43 |
|
|
|
44 |
|
|
|
45 |
|
|
library ieee;
|
46 |
|
|
use ieee.std_logic_1164.all;
|
47 |
|
|
use ieee.numeric_std.all;
|
48 |
|
|
|
49 |
|
|
package avs_aes_pkg is
|
50 |
|
|
-- tiny 4 bit value
|
51 |
|
|
constant NIBBLE_WIDTH : NATURAL := 4;
|
52 |
|
|
subtype NIBBLE_RANGE is NATURAL range NIBBLE_WIDTH-1 downto 0;
|
53 |
|
|
subtype NIBBLE is STD_LOGIC_VECTOR(NIBBLE_RANGE);
|
54 |
|
|
|
55 |
|
|
-- type definition byte: 8 bit = byte (cell of the
|
56 |
|
|
-- state)
|
57 |
|
|
constant BYTE_WIDTH : NATURAL := 8;
|
58 |
|
|
subtype BYTE_RANGE is NATURAL range BYTE_WIDTH-1 downto 0;
|
59 |
|
|
subtype BYTE is STD_LOGIC_VECTOR(BYTE_RANGE);
|
60 |
|
|
|
61 |
|
|
-- Type definition word: 16 bit = word
|
62 |
|
|
constant WORD_WIDTH : NATURAL := 16;
|
63 |
|
|
subtype WORD_RANGE is NATURAL range WORD_WIDTH-1 downto 0;
|
64 |
|
|
subtype WORD is STD_LOGIC_VECTOR(WORD_RANGE); -- storage type "word"
|
65 |
|
|
|
66 |
|
|
-- type definition Dword: 32 bit = dword
|
67 |
|
|
constant DWORD_WIDTH : NATURAL := 32;
|
68 |
|
|
subtype DWORD_RANGE is NATURAL range DWORD_WIDTH-1 downto 0;
|
69 |
|
|
subtype DWORD is STD_LOGIC_VECTOR(DWORD_RANGE);
|
70 |
|
|
|
71 |
|
|
-- type definition Qword: 64 bit = qword
|
72 |
|
|
constant QWORD_WIDTH : NATURAL := 64;
|
73 |
|
|
subtype QWORD_RANGE is NATURAL range QWORD_WIDTH-1 downto 0;
|
74 |
|
|
subtype QWORD is STD_LOGIC_VECTOR(QWORD_RANGE);
|
75 |
|
|
|
76 |
|
|
|
77 |
|
|
---------------------------------------------------------------------------
|
78 |
|
|
-- aggregates of Signals
|
79 |
|
|
---------------------------------------------------------------------------
|
80 |
|
|
-- array of 64 bit words
|
81 |
|
|
type QWORDARRAY is array (NATURAL range <>) of QWORD;
|
82 |
|
|
-- array of 32 bit words
|
83 |
|
|
type DWORDARRAY is array (NATURAL range <>) of DWORD;
|
84 |
|
|
-- array of 16 bit words
|
85 |
|
|
type WORDARRAY is array (NATURAL range <>) of WORD;
|
86 |
|
|
-- array of 8 bit words
|
87 |
|
|
type BYTEARRAY is array (NATURAL range <>) of BYTE;
|
88 |
|
|
-- array of NATURALS
|
89 |
|
|
type NATURALARRAY is array (NATURAL range <>) of NATURAL;
|
90 |
|
|
-- array of integers
|
91 |
|
|
type INTEGERARRAY is array (NATURAL range <>) of INTEGER;
|
92 |
|
|
|
93 |
|
|
-- Byte Matrix
|
94 |
|
|
type BYTEMATRIX is array (NATURAL range <>, NATURAL range <>) of BYTE;
|
95 |
|
|
|
96 |
|
|
|
97 |
|
|
|
98 |
|
|
---------------------------------------------------------------------------
|
99 |
|
|
-- types for signal mnemonics
|
100 |
|
|
---------------------------------------------------------------------------
|
101 |
|
|
type ACCESS_MODE is (W , R); -- Modes how memory can be accessed
|
102 |
|
|
type CRYPTODIRECTION is (encrypt, decrypt); -- Switch to encrypt or decrypt
|
103 |
|
|
|
104 |
|
|
---------------------------------------------------------------------------
|
105 |
|
|
-- constants for convienience
|
106 |
|
|
---------------------------------------------------------------------------
|
107 |
|
|
constant NULL_QWORD : QWORD := (others => '0'); -- Qword to clear memory
|
108 |
|
|
constant NULL_DWORD : DWORD := (others => '0'); -- Dword to clear memory
|
109 |
|
|
constant NULL_WORD : WORD := (others => '0'); -- word to clear memory
|
110 |
|
|
constant NULL_BYTE : BYTE := (others => '0'); -- byte to clear memory
|
111 |
|
|
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
|
115 |
|
|
|
116 |
|
|
-- The state type is the matrix unfolded into a linear representation
|
117 |
|
|
-- the length of a column is always fixed so every 32 Bit of this vector
|
118 |
|
|
-- represents a column of the state
|
119 |
|
|
--
|
120 |
|
|
-- once and for all: THE COLUMNS STAND WITH THE MSB (Bit 31) AT THE TOP!!
|
121 |
|
|
-- => cell0, cell4, cell8... are byte0 of the column
|
122 |
|
|
--
|
123 |
|
|
-- state: ==> BYTEARRAY (0 to (BLOCKLENGTH/8)-1);
|
124 |
|
|
-- cell0 cell4 ...
|
125 |
|
|
-- cell1 cell5 ... ==> cell0,cell1,cell2,cell3,cell4,cell5....
|
126 |
|
|
-- cell2 cell6 ... ^ ^-bit[8]
|
127 |
|
|
-- cell3 ... ... ^-bit[0]
|
128 |
|
|
subtype STATE is DWORDARRAY (0 to 3);
|
129 |
|
|
-- alias KEYBLOCK is STATE;
|
130 |
|
|
-- DUMB xilinx compiler does not know aliases for subtypes.....
|
131 |
|
|
subtype KEYBLOCK is DWORDARRAY (0 to 3);
|
132 |
|
|
|
133 |
|
|
|
134 |
|
|
-- Round constants for XOR in Keygenerator
|
135 |
|
|
constant ROUNDCONSTANTS : BYTEARRAY(0 to 15) := (X"00", X"01", X"02", X"04", X"08", X"10", X"20", X"40",
|
136 |
|
|
X"80", X"1B", X"36", X"6C", X"D8", X"AB", X"4D", X"9A");
|
137 |
|
|
|
138 |
|
|
-------------------------------------------------------------------------------
|
139 |
|
|
-- General (useful) Components
|
140 |
|
|
-------------------------------------------------------------------------------
|
141 |
|
|
---------------------------------------------------------------------------
|
142 |
|
|
-- register word with variable width
|
143 |
|
|
---------------------------------------------------------------------------
|
144 |
|
|
component memory_word
|
145 |
|
|
generic (
|
146 |
|
|
IOwidth : POSITIVE := 1 -- width of register
|
147 |
|
|
);
|
148 |
|
|
port (
|
149 |
|
|
data_in : in STD_LOGIC_VECTOR (IOwidth-1 downto 0); -- input
|
150 |
|
|
data_out : out STD_LOGIC_VECTOR (IOwidth-1 downto 0); -- output
|
151 |
|
|
res_n : in STD_LOGIC; -- system reset active low
|
152 |
|
|
ena : in STD_LOGIC; -- enable write
|
153 |
|
|
clk : in STD_LOGIC -- system clock
|
154 |
|
|
);
|
155 |
|
|
end component;
|
156 |
|
|
|
157 |
|
|
|
158 |
|
|
---------------------------------------------------------------------------
|
159 |
|
|
-- 2:1 STD_LOGIC_VECTOR multiplexer
|
160 |
|
|
---------------------------------------------------------------------------
|
161 |
|
|
component mux2
|
162 |
|
|
generic (
|
163 |
|
|
IOwidth : POSITIVE := 1 -- width of I/O ports
|
164 |
|
|
);
|
165 |
|
|
port (
|
166 |
|
|
inport_a : in STD_LOGIC_VECTOR (IOwidth-1 downto 0); -- port 1
|
167 |
|
|
inport_b : in STD_LOGIC_VECTOR (IOwidth-1 downto 0); -- port 2
|
168 |
|
|
selector : in STD_LOGIC; -- switch TO select ports
|
169 |
|
|
outport : out STD_LOGIC_VECTOR (IOwidth-1 downto 0) -- output
|
170 |
|
|
);
|
171 |
|
|
end component;
|
172 |
|
|
|
173 |
|
|
---------------------------------------------------------------------------
|
174 |
|
|
-- 3:1 multiplexer
|
175 |
|
|
---------------------------------------------------------------------------
|
176 |
|
|
component mux3
|
177 |
|
|
generic (
|
178 |
|
|
IOwidth : POSITIVE := 1 -- width of I/O ports
|
179 |
|
|
);
|
180 |
|
|
port (
|
181 |
|
|
inport_a : in STD_LOGIC_VECTOR (IOwidth-1 downto 0); -- port 1
|
182 |
|
|
inport_b : in STD_LOGIC_VECTOR (IOwidth-1 downto 0); -- port 2
|
183 |
|
|
inport_c : in STD_LOGIC_VECTOR (IOwidth-1 downto 0); -- port 3
|
184 |
|
|
selector : in STD_LOGIC_VECTOR(1 downto 0); -- switch TO select ports
|
185 |
|
|
outport : out STD_LOGIC_VECTOR (IOwidth-1 downto 0) -- output
|
186 |
|
|
);
|
187 |
|
|
end component;
|
188 |
|
|
|
189 |
|
|
|
190 |
|
|
---------------------------------------------------------------------------
|
191 |
|
|
-- Components relevant for AVS_AES
|
192 |
|
|
---------------------------------------------------------------------------
|
193 |
|
|
component AddRoundKey
|
194 |
|
|
port (
|
195 |
|
|
roundkey : in KEYBLOCK; -- Roundkey
|
196 |
|
|
cypherblock : in STATE; -- State for this round
|
197 |
|
|
result : out STATE
|
198 |
|
|
);
|
199 |
|
|
end component;
|
200 |
|
|
|
201 |
|
|
---------------------------------------------------------------------------
|
202 |
|
|
-- FSM that controls the dataflow of AES_ECB encryption
|
203 |
|
|
---------------------------------------------------------------------------
|
204 |
|
|
component AES_FSM_ENCRYPT is
|
205 |
|
|
generic (
|
206 |
|
|
NO_ROUNDS : NATURAL := 10); -- number of rounds
|
207 |
|
|
port (
|
208 |
|
|
clk : in STD_LOGIC; -- System clock
|
209 |
|
|
data_stable : in STD_LOGIC; -- flag valid data/activate the process
|
210 |
|
|
-- interface for keygenerator
|
211 |
|
|
key_ready : in STD_LOGIC; -- flag valid roundkeys
|
212 |
|
|
round_index_out : out NIBBLE; -- address for roundkeys memory
|
213 |
|
|
-- Result of Process
|
214 |
|
|
finished : out STD_LOGIC; -- flag valid result
|
215 |
|
|
-- Control ports for the Core
|
216 |
|
|
round_type_sel : out STD_LOGIC_VECTOR(1 downto 0) -- selector for mux around mixcols
|
217 |
|
|
);
|
218 |
|
|
end component;
|
219 |
|
|
|
220 |
|
|
---------------------------------------------------------------------------
|
221 |
|
|
-- FSM that controls the dataflow of AES_ECB decryption
|
222 |
|
|
---------------------------------------------------------------------------
|
223 |
|
|
component AES_FSM_DECRYPT is
|
224 |
|
|
generic (
|
225 |
|
|
NO_ROUNDS : NATURAL := 10); -- number of rounds
|
226 |
|
|
port (
|
227 |
|
|
clk : in STD_LOGIC; -- System clock
|
228 |
|
|
data_stable : in STD_LOGIC; -- flag valid data/activate the process
|
229 |
|
|
-- interface for keygenerator
|
230 |
|
|
key_ready : in STD_LOGIC; -- flag valid roundkeys
|
231 |
|
|
round_index_out : out NIBBLE; -- address for roundkeys memory
|
232 |
|
|
-- Result of Process
|
233 |
|
|
finished : out STD_LOGIC; -- flag valid result
|
234 |
|
|
-- Control ports for the Core
|
235 |
|
|
round_type_sel : out STD_LOGIC_VECTOR(1 downto 0) -- selector for mux around mixcols
|
236 |
|
|
);
|
237 |
|
|
end component;
|
238 |
|
|
|
239 |
|
|
|
240 |
|
|
---------------------------------------------------------------------------
|
241 |
|
|
-- Mixcolumn component
|
242 |
|
|
-- (has 2 architectures inverse and forward)
|
243 |
|
|
---------------------------------------------------------------------------
|
244 |
|
|
component Mixcol is
|
245 |
|
|
port (
|
246 |
|
|
col_in : in DWORD; -- one column of the state
|
247 |
|
|
col_out : out DWORD); -- output column
|
248 |
|
|
end component Mixcol;
|
249 |
|
|
|
250 |
|
|
---------------------------------------------------------------------------
|
251 |
|
|
-- Sbox component
|
252 |
|
|
-- The interface is 2x8Bit because Altera megafunction is supposed to be at max
|
253 |
|
|
-- 8Bit dual port ROM (and I relied on a altera quartus generated component
|
254 |
|
|
-- before) see architecture m4k
|
255 |
|
|
-------------------------------------------------------------------------------
|
256 |
|
|
component sbox is
|
257 |
|
|
generic (
|
258 |
|
|
INVERSE : BOOLEAN); -- is this the inverse or the forward
|
259 |
|
|
-- lookup table.
|
260 |
|
|
-- TRUE -> inverse sbox
|
261 |
|
|
-- FALSE -> forward sbox
|
262 |
|
|
port (
|
263 |
|
|
clk : in STD_LOGIC; -- system clock
|
264 |
|
|
address_a : in STD_LOGIC_VECTOR (7 downto 0); -- 1st byte
|
265 |
|
|
address_b : in STD_LOGIC_VECTOR (7 downto 0); -- 2nd byte
|
266 |
|
|
q_a : out STD_LOGIC_VECTOR (7 downto 0); -- substituted 1st byte
|
267 |
|
|
q_b : out STD_LOGIC_VECTOR (7 downto 0)); -- substituted 2nd byte
|
268 |
|
|
end component sbox;
|
269 |
|
|
|
270 |
|
|
|
271 |
|
|
---------------------------------------------------------------------------
|
272 |
|
|
-- Encrypt version of Shiftrow component
|
273 |
|
|
-- (has 2 architectures inverse and forward)
|
274 |
|
|
---------------------------------------------------------------------------
|
275 |
|
|
component Shiftrow
|
276 |
|
|
port (
|
277 |
|
|
state_in : in STATE; -- Raw input data TO be shifted
|
278 |
|
|
state_out : out STATE -- shifted result
|
279 |
|
|
);
|
280 |
|
|
end component;
|
281 |
|
|
|
282 |
|
|
---------------------------------------------------------------------------
|
283 |
|
|
-- Keykenerator for roundkeys
|
284 |
|
|
---------------------------------------------------------------------------
|
285 |
|
|
component keyexpansionV2 is
|
286 |
|
|
generic (
|
287 |
|
|
KEYLENGTH : NATURAL); -- Size of keyblock (128, 192, 256 Bits)
|
288 |
|
|
port (
|
289 |
|
|
clk : in STD_LOGIC; -- system clock
|
290 |
|
|
keyword : in DWORD; -- word of original userkey
|
291 |
|
|
keywordaddr : in STD_LOGIC_VECTOR(2 downto 0); -- keyword register address
|
292 |
|
|
w_ena_keyword : in STD_LOGIC; -- write enable of keyword to wordaddr
|
293 |
|
|
key_stable : in STD_LOGIC; -- key is completa and valid, start expansion
|
294 |
|
|
roundkey_idx : in NIBBLE; -- index for selecting roundkey
|
295 |
|
|
roundkey : out KEYBLOCK; -- key for each round
|
296 |
|
|
ready : out STD_LOGIC); -- expansion done, roundkeys ready
|
297 |
|
|
end component keyexpansionV2;
|
298 |
|
|
|
299 |
|
|
|
300 |
|
|
---------------------------------------------------------------------------
|
301 |
|
|
-- Keykenerator for roundkeys
|
302 |
|
|
---------------------------------------------------------------------------
|
303 |
|
|
component keygenerator is
|
304 |
|
|
generic (
|
305 |
|
|
KEYLENGTH : NATURAL := 128; -- Size of keyblock (128, 192, 256 Bits)
|
306 |
|
|
NO_ROUNDS : NATURAL := 10 -- how many rounds
|
307 |
|
|
);
|
308 |
|
|
port (
|
309 |
|
|
clk : in STD_LOGIC; -- system clock
|
310 |
|
|
initialkey : in KEYBLOCK; -- original userkey
|
311 |
|
|
key_stable : in STD_LOGIC; -- signal for enabling write of initial
|
312 |
|
|
-- key and signal valid key
|
313 |
|
|
-- ena=0->blank_key
|
314 |
|
|
round : in NIBBLE; -- index for selecting roundkey
|
315 |
|
|
roundkey : out KEYBLOCK; -- key for each round
|
316 |
|
|
ready : out STD_LOGIC
|
317 |
|
|
);
|
318 |
|
|
end component;
|
319 |
|
|
|
320 |
|
|
|
321 |
|
|
|
322 |
|
|
---------------------------------------------------------------------------
|
323 |
|
|
-- Complete Core implementation
|
324 |
|
|
---------------------------------------------------------------------------
|
325 |
|
|
component AES_CORE is
|
326 |
|
|
generic (
|
327 |
|
|
KEYLENGTH : NATURAL; -- Size of keyblock (128, 192, 256 Bits)
|
328 |
|
|
DECRYPTION : BOOLEAN); -- include decrypt datapath
|
329 |
|
|
port (
|
330 |
|
|
clk : in STD_LOGIC; -- system clock
|
331 |
|
|
data_in : in STATE; -- payload to encrypt
|
332 |
|
|
data_stable : in STD_LOGIC; -- flag valid payload
|
333 |
|
|
keyword : in DWORD; -- word of original userkey
|
334 |
|
|
keywordaddr : in STD_LOGIC_VECTOR(2 downto 0); -- keyword register address
|
335 |
|
|
w_ena_keyword : in STD_LOGIC; -- write enable of keyword to wordaddr
|
336 |
|
|
key_stable : in STD_LOGIC; -- key is complete and valid, start expansion
|
337 |
|
|
decrypt_mode : in STD_LOGIC; -- decrypt='1',encrypt='0'
|
338 |
|
|
keyexp_done : out STD_LOGIC; -- keyprocessing is done
|
339 |
|
|
result : out STATE; -- output
|
340 |
|
|
finished : out STD_LOGIC); -- output valid
|
341 |
|
|
end component AES_CORE;
|
342 |
|
|
---------------------------------------------------------------------------
|
343 |
|
|
-- function to calculate number of rounds based on keylength, returns
|
344 |
|
|
-- either 10,12 or 14
|
345 |
|
|
---------------------------------------------------------------------------
|
346 |
|
|
function lookupRounds (keylen : in NATURAL) return NATURAL;
|
347 |
|
|
|
348 |
|
|
---------------------------------------------------------------------------
|
349 |
|
|
-- Functions for convinience
|
350 |
|
|
---------------------------------------------------------------------------
|
351 |
|
|
-- modulo additon DWORD+DWORD=DWORD
|
352 |
|
|
function "+" (left, right : in DWORD) return DWORD;
|
353 |
|
|
|
354 |
|
|
end package avs_aes_pkg;
|
355 |
|
|
|
356 |
|
|
package body avs_aes_pkg is
|
357 |
|
|
|
358 |
|
|
---------------------------------------------------------------------------
|
359 |
|
|
-- function to calculate number of rounds based on keylength, returns
|
360 |
|
|
-- either 10,12 or 14
|
361 |
|
|
---------------------------------------------------------------------------
|
362 |
|
|
function lookupRounds(keylen : in NATURAL) return NATURAL is
|
363 |
|
|
begin
|
364 |
|
|
assert (keylen = 128 or keylen = 192 or keylen = 256)
|
365 |
|
|
report "Wrong KEYLENGTH parameter" severity failure;
|
366 |
|
|
if keylen = 128 then
|
367 |
|
|
return 10;
|
368 |
|
|
elsif keylen = 192 then
|
369 |
|
|
return 12;
|
370 |
|
|
elsif keylen = 256 then
|
371 |
|
|
return 14;
|
372 |
|
|
else
|
373 |
|
|
return 0;
|
374 |
|
|
end if;
|
375 |
|
|
end;
|
376 |
|
|
|
377 |
|
|
-- modulo additon DWORD+DWORD=DWORD
|
378 |
|
|
function "+" (left, right : in DWORD) return DWORD
|
379 |
|
|
is
|
380 |
|
|
variable result : UNSIGNED(DWORD_RANGE);
|
381 |
|
|
begin
|
382 |
|
|
result := UNSIGNED(left) + UNSIGNED(right);
|
383 |
|
|
return STD_LOGIC_VECTOR(result);
|
384 |
|
|
end function;
|
385 |
|
|
|
386 |
|
|
end package body avs_aes_pkg;
|