Browse Source

First working version of AES enc & dec

* Split enc & dec in separate units aes_enc & aes_dec
* Add component declarations to aes_pkg
* Key schedule isn't implemented yet
* Fixed round keys at the moment until key schedule is implemented
* Simple test of enc & dec
* New aes top level unit (empty at the moment)
* Renamed makefile to Makefile
master
T. Meissner 2 years ago
parent
commit
735c411ff8
6 changed files with 387 additions and 41 deletions
  1. +0
    -5
      aes/rtl/vhdl/aes.vhd
  2. +139
    -0
      aes/rtl/vhdl/aes_dec.vhd
  3. +139
    -0
      aes/rtl/vhdl/aes_enc.vhd
  4. +38
    -1
      aes/rtl/vhdl/aes_pkg.vhd
  5. +2
    -2
      aes/sim/vhdl/Makefile
  6. +69
    -33
      aes/sim/vhdl/tb_aes.vhd

+ 0
- 5
aes/rtl/vhdl/aes.vhd View File

@ -53,12 +53,7 @@ architecture rtl of aes is
begin
PipeG : if design_type = "PIPE" generate
begin
end generate PipeG;
end architecture rtl;

+ 139
- 0
aes/rtl/vhdl/aes_dec.vhd View File

@ -0,0 +1,139 @@
-- ======================================================================
-- AES decryption
-- algorithm according to FIPS 197 specification
-- Copyright (C) 2011 Torsten Meissner
-------------------------------------------------------------------------
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-- ======================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.aes_pkg.all;
entity aes_dec is
generic (
design_type : string := "ITER"
);
port (
reset_i : in std_logic; -- async reset
clk_i : in std_logic; -- clock
key_i : in std_logic_vector(0 TO 127); -- key input
data_i : in std_logic_vector(0 TO 127); -- data input
valid_i : in std_logic; -- input key/data valid flag
accept_o : out std_logic;
data_o : out std_logic_vector(0 TO 127); -- data output
valid_o : out std_logic; -- output data valid flag
accept_i : in std_logic
);
end entity aes_dec;
architecture rtl of aes_dec is
-- Fixed round keys for verification until key schedule is implemented
type t_key_array is array (11 downto 1) of t_key;
constant c_round_keys : t_key_array := (
(x"2b7e1516", x"28aed2a6", x"abf71588", x"09cf4f3c"),
(x"a0fafe17", x"88542cb1", x"23a33939", x"2a6c7605"),
(x"f2c295f2", x"7a96b943", x"5935807a", x"7359f67f"),
(x"3d80477d", x"4716fe3e", x"1e237e44", x"6d7a883b"),
(x"ef44a541", x"a8525b7f", x"b671253b", x"db0bad00"),
(x"d4d1c6f8", x"7c839d87", x"caf2b8bc", x"11f915bc"),
(x"6d88a37a", x"110b3efd", x"dbf98641", x"ca0093fd"),
(x"4e54f70e", x"5f5fc9f3", x"84a64fb2", x"4ea6dc4f"),
(x"ead27321", x"b58dbad2", x"312bf560", x"7f8d292f"),
(x"ac7766f3", x"19fadc21", x"28d12941", x"575c006e"),
(x"d014f9a8", x"c9ee2589", x"e13f0cc8", x"b6630ca6")
);
signal s_round_key : t_key := (others => (others => '0'));
begin
IterG : if design_type = "ITER" generate
signal s_round : natural range t_rounds'low to t_rounds'high+1;
begin
s_round_key <= c_round_keys(s_round) when s_round >= 1 and s_round <= 11 else
(others => (others => '0'));
DeCryptP : process (reset_i, clk_i) is
variable v_state : t_datatable2d;
begin
if (reset_i = '0') then
v_state := (others => (others => (others => '0')));
s_round <= 0;
accept_o <= '0';
data_o <= (others => '0');
valid_o <= '0';
elsif (rising_edge(clk_i)) then
case s_round is
when 0 =>
accept_o <= '1';
if (accept_o = '1' and valid_i = '1') then
accept_o <= '0';
v_state := set_state(data_i);
s_round <= s_round + 1;
end if;
when 1 =>
v_state := addroundkey(v_state, s_round_key);
s_round <= s_round + 1;
when t_rounds'high =>
v_state := invshiftrow(v_state);
v_state := invsubbytes(v_state);
v_state := addroundkey(v_state, s_round_key);
s_round <= s_round + 1;
when t_rounds'high+1 =>
valid_o <= '1';
data_o <= get_state(v_state);
if (valid_o = '1' and accept_i = '1') then
valid_o <= '0';
data_o <= (others => '0');
s_round <= 0;
end if;
when others =>
v_state := invshiftrow(v_state);
v_state := invsubbytes(v_state);
v_state := addroundkey(v_state, s_round_key);
v_state := invmixcolumns(v_state);
s_round <= s_round + 1;
end case;
end if;
end process DeCryptP;
end generate IterG;
end architecture rtl;

+ 139
- 0
aes/rtl/vhdl/aes_enc.vhd View File

@ -0,0 +1,139 @@
-- ======================================================================
-- AES encryption/decryption
-- algorithm according to FIPS 197 specification
-- Copyright (C) 2011 Torsten Meissner
-------------------------------------------------------------------------
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-- ======================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.aes_pkg.all;
entity aes_enc is
generic (
design_type : string := "ITER"
);
port (
reset_i : in std_logic; -- async reset
clk_i : in std_logic; -- clock
key_i : in std_logic_vector(0 TO 127); -- key input
data_i : in std_logic_vector(0 TO 127); -- data input
valid_i : in std_logic; -- input key/data valid flag
accept_o : out std_logic;
data_o : out std_logic_vector(0 TO 127); -- data output
valid_o : out std_logic; -- output data valid flag
accept_i : in std_logic
);
end entity aes_enc;
architecture rtl of aes_enc is
-- Fixed round keys for verification until key schedule is implemented
type t_key_array is array (1 to 11) of t_key;
constant c_round_keys : t_key_array := (
(x"2b7e1516", x"28aed2a6", x"abf71588", x"09cf4f3c"),
(x"a0fafe17", x"88542cb1", x"23a33939", x"2a6c7605"),
(x"f2c295f2", x"7a96b943", x"5935807a", x"7359f67f"),
(x"3d80477d", x"4716fe3e", x"1e237e44", x"6d7a883b"),
(x"ef44a541", x"a8525b7f", x"b671253b", x"db0bad00"),
(x"d4d1c6f8", x"7c839d87", x"caf2b8bc", x"11f915bc"),
(x"6d88a37a", x"110b3efd", x"dbf98641", x"ca0093fd"),
(x"4e54f70e", x"5f5fc9f3", x"84a64fb2", x"4ea6dc4f"),
(x"ead27321", x"b58dbad2", x"312bf560", x"7f8d292f"),
(x"ac7766f3", x"19fadc21", x"28d12941", x"575c006e"),
(x"d014f9a8", x"c9ee2589", x"e13f0cc8", x"b6630ca6")
);
signal s_round_key : t_key := (others => (others => '0'));
begin
IterG : if design_type = "ITER" generate
signal s_round : natural range t_rounds'low to t_rounds'high+1;
begin
s_round_key <= c_round_keys(s_round) when s_round >= 1 and s_round <= 11 else
(others => (others => '0'));
CryptP : process (reset_i, clk_i) is
variable v_state : t_datatable2d;
begin
if (reset_i = '0') then
v_state := (others => (others => (others => '0')));
s_round <= 0;
accept_o <= '0';
data_o <= (others => '0');
valid_o <= '0';
elsif (rising_edge(clk_i)) then
case s_round is
when 0 =>
accept_o <= '1';
if (accept_o = '1' and valid_i = '1') then
accept_o <= '0';
v_state := set_state(data_i);
s_round <= s_round + 1;
end if;
when 1 =>
v_state := addroundkey(v_state, s_round_key);
s_round <= s_round + 1;
when t_rounds'high =>
v_state := subbytes(v_state);
v_state := shiftrow(v_state);
v_state := addroundkey(v_state, s_round_key);
s_round <= s_round + 1;
when t_rounds'high+1 =>
valid_o <= '1';
data_o <= get_state(v_state);
if (valid_o = '1' and accept_i = '1') then
valid_o <= '0';
data_o <= (others => '0');
s_round <= 0;
end if;
when others =>
v_state := subbytes(v_state);
v_state := shiftrow(v_state);
v_state := mixcolumns(v_state);
v_state := addroundkey(v_state, s_round_key);
s_round <= s_round + 1;
end case;
end if;
end process CryptP;
end generate IterG;
end architecture rtl;

+ 38
- 1
aes/rtl/vhdl/aes_pkg.vhd View File

@ -33,6 +33,43 @@ library ieee;
package aes_pkg is
-- components
component aes_enc is
generic (
design_type : string := "ITER"
);
port (
reset_i : in std_logic;
clk_i : in std_logic;
key_i : in std_logic_vector(0 to 127);
data_i : in std_logic_vector(0 to 127);
valid_i : in std_logic;
accept_o : out std_logic;
data_o : out std_logic_vector(0 to 127);
valid_o : out std_logic;
accept_i : in std_logic
);
end component aes_enc;
component aes_dec is
generic (
design_type : string := "ITER"
);
port (
reset_i : in std_logic;
clk_i : in std_logic;
key_i : in std_logic_vector(0 to 127);
data_i : in std_logic_vector(0 to 127);
valid_i : in std_logic;
accept_o : out std_logic;
data_o : out std_logic_vector(0 to 127);
valid_o : out std_logic;
accept_i : in std_logic
);
end component aes_dec;
-- constants for AES128
constant c_nk : natural := 4; -- key size
constant c_nb : natural := 4; -- number of bytes
@ -318,7 +355,7 @@ package body aes_pkg is
function rotword (input : in t_datatable1d) return t_datatable1d is
begin
return(input(2), input(1), input(0), input(3));
return(input(1), input(2), input(3), input(0));
end function rotword;


aes/sim/vhdl/makefile → aes/sim/vhdl/Makefile View File


+ 69
- 33
aes/sim/vhdl/tb_aes.vhd View File

@ -38,32 +38,21 @@ end entity tb_aes;
architecture rtl of tb_aes is
signal s_reset : std_logic := '0';
signal s_clk : std_logic := '0';
signal s_mode : std_logic := '0';
signal s_key : std_logic_vector(0 to 127) := (others => '0');
signal s_datain : std_logic_vector(0 to 127) := (others => '0');
signal s_validin : std_logic := '0';
signal s_acceptout : std_logic;
signal s_dataout : std_logic_vector(0 to 127);
signal s_validout : std_logic;
signal s_acceptin : std_logic;
component aes is
port (
reset_i : in std_logic;
clk_i : in std_logic;
mode_i : in std_logic;
key_i : in std_logic_vector(0 TO 127);
data_i : in std_logic_vector(0 TO 127);
valid_i : in std_logic;
accept_o : out std_logic;
data_o : out std_logic_vector(0 TO 127);
valid_o : out std_logic;
accept_i : in std_logic
);
end component aes;
signal s_reset : std_logic := '0';
signal s_clk : std_logic := '0';
signal s_mode : std_logic := '0';
signal s_key : std_logic_vector(0 to 127) := (others => '0');
signal s_datain : std_logic_vector(0 to 127) := (others => '0');
signal s_validin_enc : std_logic := '0';
signal s_acceptout_enc : std_logic;
signal s_dataout_enc : std_logic_vector(0 to 127);
signal s_validout_enc : std_logic;
signal s_acceptin_enc : std_logic := '0';
signal s_validin_dec : std_logic := '0';
signal s_acceptout_dec : std_logic;
signal s_dataout_dec : std_logic_vector(0 to 127);
signal s_validout_dec : std_logic;
signal s_acceptin_dec : std_logic := '0';
begin
@ -73,19 +62,66 @@ begin
s_reset <= '1' after 100 ns;
i_aes : aes
i_aes_enc : aes_enc
port map (
reset_i => s_reset,
clk_i => s_clk,
mode_i => s_mode,
key_i => s_key,
data_i => s_datain,
valid_i => s_validin,
accept_o => s_acceptout,
data_o => s_dataout,
valid_o => s_validout,
accept_i => s_acceptin
valid_i => s_validin_enc,
accept_o => s_acceptout_enc,
data_o => s_dataout_enc,
valid_o => s_validout_enc,
accept_i => s_acceptin_enc
);
i_aes_dec : aes_dec
port map (
reset_i => s_reset,
clk_i => s_clk,
key_i => s_key,
data_i => s_datain,
valid_i => s_validin_dec,
accept_o => s_acceptout_dec,
data_o => s_dataout_dec,
valid_o => s_validout_dec,
accept_i => s_acceptin_dec
);
process is
begin
wait until s_reset = '1';
-- ENCRYPTION TEST
wait until rising_edge(s_clk);
s_validin_enc <= '1';
s_datain <= x"3243f6a8885a308d313198a2e0370734";
wait until s_acceptout_enc = '1' and rising_edge(s_clk);
s_validin_enc <= '0';
wait until s_validout_enc = '1' and rising_edge(s_clk);
s_acceptin_enc <= '1';
assert s_dataout_enc = x"3925841D02DC09FBDC118597196A0B32"
report "Encryption error"
severity failure;
s_datain <= s_dataout_enc;
wait until rising_edge(s_clk);
s_acceptin_enc <= '0';
-- DECRYPTION TEST
wait until rising_edge(s_clk);
s_validin_dec <= '1';
wait until s_acceptout_dec = '1' and rising_edge(s_clk);
s_validin_dec <= '0';
wait until s_validout_dec = '1' and rising_edge(s_clk);
s_acceptin_dec <= '1';
assert s_dataout_dec = x"3243f6a8885a308d313198a2e0370734"
report "Decryption error"
severity failure;
wait until rising_edge(s_clk);
s_acceptin_dec <= '0';
wait for 100 ns;
finish(0);
end process;
end architecture rtl;

Loading…
Cancel
Save