From 67df839c956e2a829a4213d95f965c9ce0b40e9d Mon Sep 17 00:00:00 2001 From: tmeissner Date: Sun, 22 Mar 2015 23:05:56 +0100 Subject: [PATCH] add implementation & testbench of CBCMAC with DES algorithm --- cbcmac_des/rtl/vhdl/cbcmac_des.vhd | 133 ++++++++++++++++++++++++ cbcmac_des/sim/vhdl/makefile | 44 ++++++++ cbcmac_des/sim/vhdl/tb_cbcmac_des.tcl | 12 +++ cbcmac_des/sim/vhdl/tb_cbcmac_des.vhd | 141 ++++++++++++++++++++++++++ 4 files changed, 330 insertions(+) create mode 100644 cbcmac_des/rtl/vhdl/cbcmac_des.vhd create mode 100644 cbcmac_des/sim/vhdl/makefile create mode 100644 cbcmac_des/sim/vhdl/tb_cbcmac_des.tcl create mode 100644 cbcmac_des/sim/vhdl/tb_cbcmac_des.vhd diff --git a/cbcmac_des/rtl/vhdl/cbcmac_des.vhd b/cbcmac_des/rtl/vhdl/cbcmac_des.vhd new file mode 100644 index 0000000..601ab87 --- /dev/null +++ b/cbcmac_des/rtl/vhdl/cbcmac_des.vhd @@ -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; \ No newline at end of file diff --git a/cbcmac_des/sim/vhdl/makefile b/cbcmac_des/sim/vhdl/makefile new file mode 100644 index 0000000..f291a8b --- /dev/null +++ b/cbcmac_des/sim/vhdl/makefile @@ -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 diff --git a/cbcmac_des/sim/vhdl/tb_cbcmac_des.tcl b/cbcmac_des/sim/vhdl/tb_cbcmac_des.tcl new file mode 100644 index 0000000..b021b34 --- /dev/null +++ b/cbcmac_des/sim/vhdl/tb_cbcmac_des.tcl @@ -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 ] diff --git a/cbcmac_des/sim/vhdl/tb_cbcmac_des.vhd b/cbcmac_des/sim/vhdl/tb_cbcmac_des.vhd new file mode 100644 index 0000000..96d8ad6 --- /dev/null +++ b/cbcmac_des/sim/vhdl/tb_cbcmac_des.vhd @@ -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;