1 |
2 |
arif_endro |
-- ------------------------------------------------------------------------
|
2 |
|
|
-- Copyright (C) 2010 Arif Endro Nugroho
|
3 |
|
|
-- All rights reserved.
|
4 |
|
|
--
|
5 |
|
|
-- Redistribution and use in source and binary forms, with or without
|
6 |
|
|
-- modification, are permitted provided that the following conditions
|
7 |
|
|
-- are met:
|
8 |
|
|
--
|
9 |
|
|
-- 1. Redistributions of source code must retain the above copyright
|
10 |
|
|
-- notice, this list of conditions and the following disclaimer.
|
11 |
|
|
-- 2. Redistributions in binary form must reproduce the above copyright
|
12 |
|
|
-- notice, this list of conditions and the following disclaimer in the
|
13 |
|
|
-- documentation and/or other materials provided with the distribution.
|
14 |
|
|
--
|
15 |
|
|
-- THIS SOFTWARE IS PROVIDED BY ARIF ENDRO NUGROHO "AS IS" AND ANY EXPRESS
|
16 |
|
|
-- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17 |
|
|
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18 |
|
|
-- DISCLAIMED. IN NO EVENT SHALL ARIF ENDRO NUGROHO BE LIABLE FOR ANY
|
19 |
|
|
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20 |
|
|
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
21 |
|
|
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
22 |
|
|
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
23 |
|
|
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
24 |
|
|
-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
25 |
|
|
-- POSSIBILITY OF SUCH DAMAGE.
|
26 |
|
|
--
|
27 |
|
|
-- End Of License.
|
28 |
|
|
-- ------------------------------------------------------------------------
|
29 |
|
|
--
|
30 |
|
|
-- KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk)
|
31 |
|
|
-- begin
|
32 |
|
|
-- word temp
|
33 |
|
|
-- i = 0
|
34 |
|
|
-- while (i < Nk)
|
35 |
|
|
-- w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3])
|
36 |
|
|
-- i = i + 1
|
37 |
|
|
-- end while
|
38 |
|
|
-- i = Nk
|
39 |
|
|
-- while (i < Nb * (Nr+1))
|
40 |
|
|
-- temp = w[i-1]
|
41 |
|
|
-- if (i mod Nk = 0)
|
42 |
|
|
-- temp = SubWord(RotWord(temp)) xor Rcon[i/Nk]
|
43 |
|
|
-- else if (Nk > 6 and i mod Nk = 4)
|
44 |
|
|
-- temp = SubWord(temp)
|
45 |
|
|
-- end if
|
46 |
|
|
-- w[i] = w[i-Nk] xor temp
|
47 |
|
|
-- i = i + 1
|
48 |
|
|
-- end while
|
49 |
|
|
-- end
|
50 |
|
|
-- Nk (Number of Key), Nb (Number of Block), Nr (Number of Round)
|
51 |
|
|
|
52 |
|
|
library ieee;
|
53 |
|
|
use ieee.std_logic_1164.all;
|
54 |
|
|
use ieee.std_logic_unsigned.all;
|
55 |
|
|
|
56 |
|
|
entity keyexpansion is
|
57 |
|
|
port (
|
58 |
|
|
key : in bit_vector (31 downto 00); -- source key
|
59 |
|
|
w : out bit_vector (31 downto 00); -- expanded keys
|
60 |
|
|
Nk : in bit_vector (03 downto 00); -- 128,192,256 => 4,6,8 (0100,0110,1000)
|
61 |
|
|
ld : in bit; -- 'ld' must active for Nk clock to load keys.
|
62 |
|
|
v : out bit; -- output valid signal
|
63 |
|
|
clk : in bit; -- clock signal
|
64 |
|
|
rst : in bit -- reset signal, its wise to reset before any action.
|
65 |
|
|
);
|
66 |
|
|
end keyexpansion;
|
67 |
|
|
|
68 |
|
|
architecture phy of keyexpansion is
|
69 |
|
|
|
70 |
|
|
constant Rc : bit_vector (79 downto 00) := ( X"01020408_10204080_1B36");
|
71 |
|
|
signal Rcs : bit_vector (79 downto 00) := ( X"01020408_10204080_1B36");
|
72 |
|
|
signal int : bit_vector (255 downto 0); -- 256 bit internal register
|
73 |
|
|
signal cnt : bit_vector (03 downto 00); -- 4 bit counter start from 1 not 0
|
74 |
|
|
signal cnts : bit_vector (05 downto 00); -- 6 bit counter start from 1 not 0
|
75 |
|
|
signal Rcon : bit_vector (07 downto 00); -- round constant
|
76 |
|
|
signal rot : bit; -- RotWord signal
|
77 |
|
|
signal crst : bit; -- reset counter
|
78 |
|
|
signal rsts : bit; -- reset state counter
|
79 |
|
|
signal mod4 : bit; -- modulo 4 (used in case of 256bit key)
|
80 |
|
|
signal Nk8s : bit; -- Nk 8 signal
|
81 |
|
|
signal ldi1 : bit; -- delayed load signal
|
82 |
|
|
signal ldrs : bit; -- reset signal from load
|
83 |
|
|
signal vld : bit; -- valid signal
|
84 |
|
|
signal vrst1 : bit; -- reset valid signal for 128bit key
|
85 |
|
|
signal vrst2 : bit; -- reset valid signal for 192bit key
|
86 |
|
|
signal vrst3 : bit; -- reset valid signal for 256bit key
|
87 |
|
|
signal rstsc : bit; -- reset state counter from reset valid signal
|
88 |
|
|
signal sai : bit_vector (07 downto 00); -- SubWord input signal
|
89 |
|
|
signal sbi : bit_vector (07 downto 00); -- SubWord input signal
|
90 |
|
|
signal sci : bit_vector (07 downto 00); -- SubWord input signal
|
91 |
|
|
signal sdi : bit_vector (07 downto 00); -- SubWord input signal
|
92 |
|
|
signal sao : bit_vector (07 downto 00); -- SubWord output signal
|
93 |
|
|
signal sbo : bit_vector (07 downto 00); -- SubWord output signal
|
94 |
|
|
signal sco : bit_vector (07 downto 00); -- SubWord output signal
|
95 |
|
|
signal sdo : bit_vector (07 downto 00); -- SubWord output signal
|
96 |
|
|
signal wi1 : bit_vector (31 downto 00); -- w[i] state signal
|
97 |
|
|
signal wiNk : bit_vector (31 downto 00); -- w[i-Nk] state signal
|
98 |
|
|
signal temp : bit_vector (31 downto 00); -- SubWord,RotWord,Rcon signal
|
99 |
|
|
signal tmp : bit_vector (31 downto 00); -- SubWord,RotWord,Rcon signal
|
100 |
|
|
|
101 |
|
|
--For SubWord
|
102 |
|
|
component sbox
|
103 |
|
|
port (
|
104 |
|
|
di : in bit_vector (07 downto 00);
|
105 |
|
|
do : out bit_vector (07 downto 00)
|
106 |
|
|
);
|
107 |
|
|
end component;
|
108 |
|
|
--For each round counter
|
109 |
|
|
component c4b
|
110 |
|
|
port (
|
111 |
|
|
cnt : out bit_vector (03 downto 00);
|
112 |
|
|
clk : in bit;
|
113 |
|
|
rst : in bit
|
114 |
|
|
);
|
115 |
|
|
end component;
|
116 |
|
|
--For all iteration in keyexpansion
|
117 |
|
|
component c6b
|
118 |
|
|
port (
|
119 |
|
|
cnt : out bit_vector (05 downto 00);
|
120 |
|
|
clk : in bit;
|
121 |
|
|
rst : in bit
|
122 |
|
|
);
|
123 |
|
|
end component;
|
124 |
|
|
|
125 |
|
|
begin
|
126 |
|
|
|
127 |
|
|
sboxa : sbox
|
128 |
|
|
port map (
|
129 |
|
|
di => sai,
|
130 |
|
|
do => sao
|
131 |
|
|
);
|
132 |
|
|
sboxb : sbox
|
133 |
|
|
port map (
|
134 |
|
|
di => sbi,
|
135 |
|
|
do => sbo
|
136 |
|
|
);
|
137 |
|
|
sboxc : sbox
|
138 |
|
|
port map (
|
139 |
|
|
di => sci,
|
140 |
|
|
do => sco
|
141 |
|
|
);
|
142 |
|
|
sboxd : sbox
|
143 |
|
|
port map (
|
144 |
|
|
di => sdi,
|
145 |
|
|
do => sdo
|
146 |
|
|
);
|
147 |
|
|
ctr1 : c4b
|
148 |
|
|
port map (
|
149 |
|
|
cnt => cnt,
|
150 |
|
|
clk => clk,
|
151 |
|
|
rst => crst
|
152 |
|
|
);
|
153 |
|
|
ctr2 : c6b
|
154 |
|
|
port map (
|
155 |
|
|
cnt => cnts,
|
156 |
|
|
clk => clk,
|
157 |
|
|
rst => rsts
|
158 |
|
|
);
|
159 |
|
|
|
160 |
|
|
--Special cases for Nk=8
|
161 |
|
|
mod4 <= not(cnt(3) or not(cnt(2)) or cnt(1) or cnt(0));
|
162 |
|
|
Nk8s <= mod4 and not(not(Nk(3)) or Nk(2) or Nk(1) or Nk(0));
|
163 |
|
|
|
164 |
|
|
--RotWord detection
|
165 |
|
|
rot <= not( (Nk(3) xor cnt(3)) or (Nk(2) xor cnt(2)) or
|
166 |
|
|
(Nk(1) xor cnt(1)) or (Nk(0) xor cnt(0)) );
|
167 |
|
|
|
168 |
|
|
process (clk)
|
169 |
|
|
begin
|
170 |
|
|
if ((clk = '1') and clk'event) then
|
171 |
|
|
ldi1 <= ld;
|
172 |
|
|
end if;
|
173 |
|
|
end process;
|
174 |
|
|
ldrs <= ld xor ldi1; -- reset signal from load
|
175 |
|
|
|
176 |
|
|
--Keyexpansion need 4*(Nr+1) clock to do all calculation with
|
177 |
|
|
--Nr = 10 when Nk = 4 (128 bit) this would generate 44(101100) 32bit keys
|
178 |
|
|
--Nr = 12 when Nk = 6 (192 bit) this would generate 52(110100) 32bit keys
|
179 |
|
|
--Nr = 14 when Nk = 8 (256 bit) this would generate 60(111100) 32bit keys
|
180 |
|
|
|
181 |
|
|
vrst1 <= not( not(cnts(5)) or cnts(4) or not(cnts(3)) or not(cnts(2)) or cnts(1) or cnts(0)); -- 44(101100)
|
182 |
|
|
vrst2 <= not( not(cnts(5)) or not(cnts(4)) or cnts(3) or not(cnts(2)) or cnts(1) or cnts(0)); -- 52(110100)
|
183 |
|
|
vrst3 <= not( not(cnts(5)) or not(cnts(4)) or not(cnts(3)) or not(cnts(2)) or cnts(1) or cnts(0));-- 60(111100)
|
184 |
|
|
|
185 |
|
|
with Nk(03 downto 00) select
|
186 |
|
|
rstsc <= vrst1 when B"0100", -- Nk 4(0100)
|
187 |
|
|
vrst2 when B"0110", -- Nk 6(0110)
|
188 |
|
|
vrst3 when B"1000", -- Nk 8(1000)
|
189 |
|
|
vrst1 when others; -- default
|
190 |
|
|
|
191 |
|
|
--Setting up counter inline with Nk periode.
|
192 |
|
|
--For each round
|
193 |
|
|
crst <= rst or rot or ldrs;
|
194 |
|
|
--For the state
|
195 |
|
|
rsts <= rst or (ldrs and ld) or rstsc;
|
196 |
|
|
|
197 |
|
|
process (clk)
|
198 |
|
|
begin
|
199 |
|
|
if ((clk = '1') and clk'event) then
|
200 |
|
|
if (rst = '1') then
|
201 |
|
|
vld <= '0';
|
202 |
|
|
elsif (((ldrs and ld) or (rstsc and vld)) = '1') then -- (ldrs and ld) is start signal (rstsc and vld) is end signal
|
203 |
|
|
vld <= not(vld);
|
204 |
|
|
end if;
|
205 |
|
|
end if;
|
206 |
|
|
end process;
|
207 |
|
|
|
208 |
|
|
v <= vld; -- valid key expansion output signal
|
209 |
|
|
|
210 |
|
|
--Round constant calculation
|
211 |
|
|
--Rcon sequence: 01 02 04 08 10 20 40 80 1b 36
|
212 |
|
|
Rcon(07 downto 00)<= Rcs (79 downto 72);
|
213 |
|
|
process (clk)
|
214 |
|
|
begin
|
215 |
|
|
if ((clk = '1') and clk'event) then
|
216 |
|
|
if (rst = '1') then -- default reset
|
217 |
|
|
Rcs <= Rc;
|
218 |
|
|
elsif (rot = '1') then -- shift one byte
|
219 |
|
|
Rcs (79 downto 08)<= Rcs (71 downto 00);
|
220 |
|
|
Rcs (07 downto 00)<= (others => '0');
|
221 |
|
|
end if;
|
222 |
|
|
end if;
|
223 |
|
|
end process;
|
224 |
|
|
|
225 |
|
|
with Nk(03 downto 00) select
|
226 |
|
|
wiNk <= int(127 downto 96) when B"0100", -- Nk 4(0100)
|
227 |
|
|
int(191 downto 160) when B"0110", -- Nk 6(0110)
|
228 |
|
|
int(255 downto 224) when B"1000", -- Nk 8(1000)
|
229 |
|
|
int(127 downto 96) when others; -- default
|
230 |
|
|
|
231 |
|
|
process (clk)
|
232 |
|
|
begin
|
233 |
|
|
if ((clk = '1') and clk'event) then
|
234 |
|
|
if (rst = '1') then
|
235 |
|
|
int(255 downto 00) <= (others => '0');
|
236 |
|
|
elsif (ld = '1') then
|
237 |
|
|
int(255 downto 00) <= int(223 downto 00) & key(31 downto 00);
|
238 |
|
|
else
|
239 |
|
|
int(255 downto 00) <= int(223 downto 00) & (wiNk xor temp);
|
240 |
|
|
end if;
|
241 |
|
|
end if;
|
242 |
|
|
end process;
|
243 |
|
|
|
244 |
|
|
wi1( 31 downto 00) <= int( 31 downto 00); -- first fifo
|
245 |
|
|
|
246 |
|
|
sai(07 downto 00)<= wi1(31 downto 24); -- SubWord
|
247 |
|
|
sbi(07 downto 00)<= wi1(23 downto 16); -- SubWord
|
248 |
|
|
sci(07 downto 00)<= wi1(15 downto 08); -- SubWord
|
249 |
|
|
sdi(07 downto 00)<= wi1(07 downto 00); -- SubWord
|
250 |
|
|
|
251 |
|
|
tmp <= sao & sbo & sco & sdo when Nk8s='1' else -- special cases for Nk 8
|
252 |
|
|
(sbo xor Rcon ) & sco & sdo & sao; -- others do: RotWord xor Rcon
|
253 |
|
|
|
254 |
|
|
temp <= tmp when (rot='1' or Nk8s='1') else wi1;
|
255 |
|
|
|
256 |
|
|
w ( 31 downto 00) <= int( 31 downto 00) when vld = '1' else (others => '0'); -- key expansion result
|
257 |
|
|
|
258 |
|
|
end phy;
|