| @ -0,0 +1,133 @@ | |||
| -- ====================================================================== | |||
| -- CBC-MAC-DES | |||
| -- Copyright (C) 2015 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.des_pkg.all; | |||
| entity cbcmac_des is | |||
| port ( | |||
| reset_i : in std_logic; -- low active async reset | |||
| clk_i : in std_logic; -- clock | |||
| start_i : in std_logic; -- start cbc | |||
| key_i : in std_logic_vector(0 to 63); -- key input | |||
| data_i : in std_logic_vector(0 to 63); -- 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 63); -- data output | |||
| valid_o : out std_logic; -- output data valid flag | |||
| accept_i : in std_logic | |||
| ); | |||
| end entity cbcmac_des; | |||
| architecture rtl of cbcmac_des is | |||
| component des is | |||
| generic ( | |||
| design_type : string := "ITER" | |||
| ); | |||
| port ( | |||
| reset_i : in std_logic; | |||
| clk_i : IN std_logic; | |||
| mode_i : IN std_logic; | |||
| key_i : IN std_logic_vector(0 to 63); | |||
| data_i : IN std_logic_vector(0 to 63); | |||
| valid_i : IN std_logic; | |||
| accept_o : out std_logic; | |||
| data_o : out std_logic_vector(0 to 63); | |||
| valid_o : out std_logic; | |||
| accept_i : in std_logic | |||
| ); | |||
| end component des; | |||
| -- CBCMAC must have fix IV for security reasons | |||
| constant C_IV : std_logic_vector(0 to 63) := (others => '0'); | |||
| signal s_des_datain : std_logic_vector(0 to 63); | |||
| signal s_des_dataout : std_logic_vector(0 to 63); | |||
| signal s_des_dataout_d : std_logic_vector(0 to 63); | |||
| signal s_des_key : std_logic_vector(0 to 63); | |||
| signal s_key : std_logic_vector(0 to 63); | |||
| signal s_des_accept : std_logic; | |||
| signal s_des_validout : std_logic; | |||
| begin | |||
| s_des_datain <= C_IV xor data_i when start_i = '1' else | |||
| s_des_dataout_d xor data_i when start_i = '0'; | |||
| data_o <= s_des_dataout; | |||
| s_des_key <= key_i when start_i = '1' else s_key; | |||
| accept_o <= s_des_accept; | |||
| valid_o <= s_des_validout; | |||
| inputregister : process(clk_i, reset_i) is | |||
| begin | |||
| if(reset_i = '0') then | |||
| s_key <= (others => '0'); | |||
| elsif(rising_edge(clk_i)) then | |||
| if(valid_i = '1' and s_des_accept = '1' and start_i = '1') then | |||
| s_key <= key_i; | |||
| end if; | |||
| end if; | |||
| end process inputregister; | |||
| outputregister : process(clk_i, reset_i) is | |||
| begin | |||
| if(reset_i = '0') then | |||
| s_des_dataout_d <= (others => '0'); | |||
| elsif(rising_edge(clk_i)) then | |||
| if(s_des_validout = '1') then | |||
| s_des_dataout_d <= s_des_dataout; | |||
| end if; | |||
| end if; | |||
| end process outputregister; | |||
| i_des : des | |||
| generic map ( | |||
| design_type => "ITER" | |||
| ) | |||
| port map ( | |||
| reset_i => reset_i, | |||
| clk_i => clk_i, | |||
| mode_i => '0', | |||
| key_i => s_des_key, | |||
| data_i => s_des_datain, | |||
| valid_i => valid_i, | |||
| accept_o => s_des_accept, | |||
| data_o => s_des_dataout, | |||
| valid_o => s_des_validout, | |||
| accept_i => accept_i | |||
| ); | |||
| end architecture rtl; | |||
| @ -0,0 +1,44 @@ | |||
| # ====================================================================== | |||
| # DES encryption/decryption | |||
| # algorithm according to FIPS 46-3 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 | |||
| # ====================================================================== | |||
| DESIGN=cbcmac_des | |||
| TESTBENCH=tb_${DESIGN} | |||
| DES=../../../des/rtl/vhdl | |||
| all : sim wave | |||
| sim : ${TESTBENCH}.ghw | |||
| tb_cbcmac_des.ghw : ${DES}/*.vhd ../../rtl/vhdl/${DESIGN}.vhd ${TESTBENCH}.vhd | |||
| ghdl -a ${DES}/des_pkg.vhd ${DES}/des.vhd ../../rtl/vhdl/${DESIGN}.vhd ${TESTBENCH}.vhd | |||
| ghdl -e ${TESTBENCH} | |||
| ghdl -r ${TESTBENCH} --wave=${TESTBENCH}.ghw --assert-level=error --stop-time=2us | |||
| wave : ${TESTBENCH}.ghw | |||
| gtkwave -S ${TESTBENCH}.tcl ${TESTBENCH}.ghw | |||
| clean : | |||
| echo "# cleaning simulation files" | |||
| rm -f *.o | |||
| rm -f ${TESTBENCH}.ghw | |||
| rm -f ${TESTBENCH} | |||
| rm -f work*.cf | |||
| @ -0,0 +1,12 @@ | |||
| set signals [list] | |||
| lappend signals "top.tb_cbcmac_des.s_reset" | |||
| lappend signals "top.tb_cbcmac_des.s_clk" | |||
| lappend signals "top.tb_cbcmac_des.s_validin" | |||
| lappend signals "top.tb_cbcmac_des.s_acceptout" | |||
| lappend signals "top.tb_cbcmac_des.s_start" | |||
| lappend signals "top.tb_cbcmac_des.s_key" | |||
| lappend signals "top.tb_cbcmac_des.s_datain" | |||
| lappend signals "top.tb_cbcmac_des.s_validout" | |||
| lappend signals "top.tb_cbcmac_des.s_acceptin" | |||
| lappend signals "top.tb_cbcmac_des.s_dataout" | |||
| set num_added [ gtkwave::addSignalsFromList $signals ] | |||
| @ -0,0 +1,141 @@ | |||
| -- ====================================================================== | |||
| -- CBC-MAC-DES testbench | |||
| -- Copyright (C) 2015 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; | |||
| entity tb_cbcmac_des is | |||
| end entity tb_cbcmac_des; | |||
| architecture sim of tb_cbcmac_des is | |||
| type t_array is array (natural range <>) of std_logic_vector(0 to 63); | |||
| signal s_reset : std_logic := '0'; | |||
| signal s_clk : std_logic := '0'; | |||
| signal s_start : std_logic := '0'; | |||
| signal s_key : std_logic_vector(0 to 63) := (others => '0'); | |||
| signal s_datain : std_logic_vector(0 to 63) := (others => '0'); | |||
| signal s_validin : std_logic := '0'; | |||
| signal s_acceptout : std_logic; | |||
| signal s_dataout : std_logic_vector(0 to 63); | |||
| signal s_validout : std_logic; | |||
| signal s_acceptin : std_logic; | |||
| component cbcmac_des is | |||
| port ( | |||
| reset_i : in std_logic; | |||
| clk_i : in std_logic; | |||
| start_i : in std_logic; | |||
| key_i : in std_logic_vector(0 to 63); | |||
| data_i : in std_logic_vector(0 to 63); | |||
| valid_i : in std_logic; | |||
| accept_o : out std_logic; | |||
| data_o : out std_logic_vector(0 to 63); | |||
| valid_o : out std_logic; | |||
| accept_i : in std_logic | |||
| ); | |||
| end component cbcmac_des; | |||
| -- key, plain & crypto stimuli values | |||
| -- taken from NIST website: | |||
| -- http://csrc.nist.gov/publications/fips/fips113/fips113.html | |||
| constant C_KEY : std_logic_vector(0 to 63) := x"0123456789abcdef"; | |||
| constant C_PLAIN : t_array := ( | |||
| x"3736353433323120", x"4e6f772069732074", | |||
| x"68652074696d6520", x"666f722000000000"); | |||
| constant C_CRYPT : t_array := ( | |||
| x"21fb193693a16c28", x"6c463f0cb7167a6f", | |||
| x"956ee891e889d91e", x"f1d30f6849312ca4"); | |||
| begin | |||
| s_clk <= not(s_clk) after 10 ns; | |||
| s_reset <= '1' after 100 ns; | |||
| StimuliP : process is | |||
| begin | |||
| s_start <= '0'; | |||
| s_key <= (others => '0'); | |||
| s_datain <= (others => '0'); | |||
| s_validin <= '0'; | |||
| wait until s_reset = '1'; | |||
| s_start <= '1'; | |||
| for i in C_PLAIN'range loop | |||
| wait until rising_edge(s_clk); | |||
| s_validin <= '1'; | |||
| s_key <= C_KEY; | |||
| s_datain <= C_PLAIN(i); | |||
| wait until rising_edge(s_clk) and s_acceptout = '1'; | |||
| s_start <= '0'; | |||
| s_validin <= '0'; | |||
| end loop; | |||
| wait; | |||
| end process StimuliP; | |||
| CheckerP : process is | |||
| begin | |||
| s_acceptin <= '0'; | |||
| wait until s_reset = '1'; | |||
| for i in C_CRYPT'range loop | |||
| wait until rising_edge(s_clk); | |||
| s_acceptin <= '1'; | |||
| wait until rising_edge(s_clk) and s_validout = '1'; | |||
| assert s_dataout = C_CRYPT(i) | |||
| report "Encryption error" | |||
| severity failure; | |||
| s_acceptin <= '0'; | |||
| end loop; | |||
| report "CBCMAC test successful :)"; | |||
| wait; | |||
| end process CheckerP; | |||
| i_cbcmac_des : cbcmac_des | |||
| port map ( | |||
| reset_i => s_reset, | |||
| clk_i => s_clk, | |||
| start_i => s_start, | |||
| 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 | |||
| ); | |||
| end architecture sim; | |||