From 735c411ff8247f1616abf3f4a2214de87dcf62ac Mon Sep 17 00:00:00 2001 From: tmeissner Date: Thu, 28 Feb 2019 22:55:01 +0100 Subject: [PATCH] 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 --- aes/rtl/vhdl/aes.vhd | 5 - aes/rtl/vhdl/aes_dec.vhd | 139 ++++++++++++++++++++++++++++ aes/rtl/vhdl/aes_enc.vhd | 139 ++++++++++++++++++++++++++++ aes/rtl/vhdl/aes_pkg.vhd | 39 +++++++- aes/sim/vhdl/{makefile => Makefile} | 4 +- aes/sim/vhdl/tb_aes.vhd | 102 +++++++++++++------- 6 files changed, 387 insertions(+), 41 deletions(-) create mode 100644 aes/rtl/vhdl/aes_dec.vhd create mode 100644 aes/rtl/vhdl/aes_enc.vhd rename aes/sim/vhdl/{makefile => Makefile} (94%) diff --git a/aes/rtl/vhdl/aes.vhd b/aes/rtl/vhdl/aes.vhd index 3386328..8faaac3 100644 --- a/aes/rtl/vhdl/aes.vhd +++ b/aes/rtl/vhdl/aes.vhd @@ -53,12 +53,7 @@ architecture rtl of aes is begin - PipeG : if design_type = "PIPE" generate - begin - - - end generate PipeG; end architecture rtl; diff --git a/aes/rtl/vhdl/aes_dec.vhd b/aes/rtl/vhdl/aes_dec.vhd new file mode 100644 index 0000000..53e221c --- /dev/null +++ b/aes/rtl/vhdl/aes_dec.vhd @@ -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; diff --git a/aes/rtl/vhdl/aes_enc.vhd b/aes/rtl/vhdl/aes_enc.vhd new file mode 100644 index 0000000..3198787 --- /dev/null +++ b/aes/rtl/vhdl/aes_enc.vhd @@ -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; diff --git a/aes/rtl/vhdl/aes_pkg.vhd b/aes/rtl/vhdl/aes_pkg.vhd index 4cd872f..5524dd7 100644 --- a/aes/rtl/vhdl/aes_pkg.vhd +++ b/aes/rtl/vhdl/aes_pkg.vhd @@ -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; diff --git a/aes/sim/vhdl/makefile b/aes/sim/vhdl/Makefile similarity index 94% rename from aes/sim/vhdl/makefile rename to aes/sim/vhdl/Makefile index 88025ab..4369ad7 100644 --- a/aes/sim/vhdl/makefile +++ b/aes/sim/vhdl/Makefile @@ -19,12 +19,12 @@ # ====================================================================== -all : sim wave +all : sim sim : tb_aes.ghw compile : ../../rtl/vhdl/*.vhd tb_aes.vhd - ghdl -a --std=08 ../../rtl/vhdl/aes_pkg.vhd ../../rtl/vhdl/aes.vhd tb_aes.vhd + ghdl -a --std=08 ../../rtl/vhdl/aes_pkg.vhd ../../rtl/vhdl/aes.vhd ../../rtl/vhdl/aes_enc.vhd ../../rtl/vhdl/aes_dec.vhd tb_aes.vhd ghdl -e --std=08 tb_aes tb_aes.ghw : compile diff --git a/aes/sim/vhdl/tb_aes.vhd b/aes/sim/vhdl/tb_aes.vhd index 8d100af..8e32803 100644 --- a/aes/sim/vhdl/tb_aes.vhd +++ b/aes/sim/vhdl/tb_aes.vhd @@ -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;