------------------------------------------------------------ -- Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich -- http://www.iis.ee.ethz.ch/~sha3 ------------------------------------------------------------ library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; use work.shavitepkg.all; entity expansion is port ( ClkxCI : in std_logic; RstxRBI : in std_logic; InputEnxEI : in std_logic; DataBlkxDI : in wordmat512; BitCntxDI : in wordmat64; SubKeyxDO : out wordmat128); end expansion; architecture rtl of expansion is component aes port ( ClkxCI : in std_logic; RstxRBI : in std_logic; PlainxDI : in wordmat128; OutxDO : out wordmat128); end component; signal AESInxD, AESOutxD, AESXorxD : wordmat128; signal StatexDP, StatexDN : unsigned(5 downto 0); --cycle counter: -- 0 = input fetch/AES, mod8=4 = XOR signal StateMatxDP, StateMatxDN : wordmat512; begin -- rtl u_aes : aes port map ( ClkxCI => ClkxCI, RstxRBI => RstxRBI, PlainxDI => AESInxD, OutxDO => AESOutxD); -- Output output : for i in 3 downto 0 generate SubKeyxDO(i) <= StateMatxDP(i) when InputEnxEI = '0' else DataBlkxDI(i); end generate output; -- purpose: Control the expansion function -- type : combinational -- inputs : AESOutxD, AESXorxD, BitCntxDI, DataBlkxDI, InputEnxEI, StateMatxDP, StatexDP -- outputs: AESInxD, AESXorxD, StateMatxDN, StatexDN p_fsm : process (AESOutxD, AESXorxD, BitCntxDI, DataBlkxDI, InputEnxEI, StateMatxDP, StatexDP) begin -- process p_fsm -- default assignments AESInxD(2) <= StateMatxDP(3); AESInxD(1) <= StateMatxDP(2); AESInxD(0) <= StateMatxDP(1); AESInxD(3) <= StateMatxDP(0); for i in 3 downto 0 loop AESXorxD(i) <= AESOutxD(i) xor StateMatxDP(12+i); end loop; -- i StateMatxDN <= StateMatxDP; StatexDN <= StatexDP+1; -- Walk through states 0...35 StatexDN <= StatexDP+1; if to_integer(StatexDP) = 35 or (to_integer(StatexDP) = 0 and InputEnxEI = '0') then StatexDN <= (others => '0'); end if; -- main operations: AES round, XOR of previous values if to_integer(StatexDP) mod 8 < 4 then --AES for i in 0 to 3 loop StateMatxDN(i+12) <= AESXorxD(i); end loop; -- i else --XOR for i in 0 to 2 loop StateMatxDN(i+12) <= StateMatxDP(i) xor StateMatxDP(i+13); end loop; StateMatxDN(15) <= StateMatxDP(3) xor StateMatxDP(0) xor StateMatxDP(13); end if; -- Shift the state matrix for i in 11 downto 0 loop StateMatxDN(i) <= StateMatxDP(i+4); end loop; -- i -- special cases case to_integer(StatexDP) is when 0 => AESInxD(2) <= DataBlkxDI(3); AESInxD(1) <= DataBlkxDI(2); AESInxD(0) <= DataBlkxDI(1); AESInxD(3) <= DataBlkxDI(0); AESXorxD(0) <= AESOutxD(0) xor DataBlkxDI(12) xor BitCntxDI(0); AESXorxD(1) <= AESOutxD(1) xor DataBlkxDI(13) xor (not BitCntxDI(1)); AESXorxD(2) <= AESOutxD(2) xor DataBlkxDI(14); AESXorxD(3) <= AESOutxD(3) xor DataBlkxDI(15); for i in 11 downto 0 loop StateMatxDN(i) <= DataBlkxDI(i+4); end loop; -- i when 10 => AESXorxD(0) <= AESOutxD(0) xor StateMatxDP(12); AESXorxD(1) <= AESOutxD(1) xor StateMatxDP(13) xor BitCntxDI(1); AESXorxD(2) <= AESOutxD(2) xor StateMatxDP(14) xor (not BitCntxDI(0)); AESXorxD(3) <= AESOutxD(3) xor StateMatxDP(15); when 17 => AESXorxD(0) <= AESOutxD(0) xor StateMatxDP(12); AESXorxD(1) <= AESOutxD(1) xor StateMatxDP(13); AESXorxD(2) <= AESOutxD(2) xor StateMatxDP(14) xor BitCntxDI(1); AESXorxD(3) <= AESOutxD(3) xor StateMatxDP(15) xor (not BitCntxDI(0)); when 27 => AESXorxD(0) <= AESOutxD(0) xor StateMatxDP(12) xor BitCntxDI(0); AESXorxD(1) <= AESOutxD(1) xor StateMatxDP(13); AESXorxD(2) <= AESOutxD(2) xor StateMatxDP(14); AESXorxD(3) <= AESOutxD(3) xor StateMatxDP(15) xor (not BitCntxDI(1)); when others => null; end case; end process; p_mem : process (ClkxCI, RstxRBI) begin -- process p_mem if RstxRBI = '0' then -- asynchronous reset (active low) StatexDP <= (others => '0'); StateMatxDP <= (others => (others => '0')); elsif ClkxCI'event and ClkxCI = '1' then -- rising clock edge StatexDP <= StatexDN; StateMatxDP <= StateMatxDN; end if; end process p_mem; end rtl;