OpenCores
URL https://opencores.org/ocsvn/nfcc/nfcc/trunk

Subversion Repositories nfcc

[/] [nfcc/] [trunk/] [rijndael/] [cipher/] [cipher.vhdl] - Rev 2

Compare with Previous | Blame | View Log

-- ------------------------------------------------------------------------
-- Copyright (C) 2010 Arif Endro Nugroho
-- All rights reserved.
-- 
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
-- 
-- 1. Redistributions of source code must retain the above copyright
--    notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright
--    notice, this list of conditions and the following disclaimer in the
--    documentation and/or other materials provided with the distribution.
-- 
-- THIS SOFTWARE IS PROVIDED BY ARIF ENDRO NUGROHO "AS IS" AND ANY EXPRESS
-- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL ARIF ENDRO NUGROHO BE LIABLE FOR ANY
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
-- 
-- End Of License.
-- ------------------------------------------------------------------------
--
-- Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)])
-- begin
--   byte state[4,Nb]
--   state = in
--
--   AddRoundKey(state, w[0, Nb-1])
--
--   for round = 1 step 1 to Nr-1
--     SubBytes(state)
--     ShiftRows(state)
--     MixColumns(state)
--     AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
--   end for
--
--   SubBytes(state)
--   ShiftRows(state)
--   AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
--
--   out = state
-- end
--
-- Nb = Number of Block, Nr = Number of Round
-- AES-128 => Nk(4), Nb(4), Nr(10)
-- AES-192 => Nk(6), Nb(4), Nr(12)
-- AES-256 => Nk(8), Nb(4), Nr(14)
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity cipher is
  port (
  pt               : in  bit_vector ( 31 downto 0); -- plain text
  key              : in  bit_vector ( 31 downto 0); -- source key
  Nk               : in  bit_vector (  3 downto 0); -- 128,192,256 => 4,6,8 (0100,0110,1000)
  ldpt             : in  bit;                       -- load signal for the first 128 bit block
  ct               : out bit_vector ( 31 downto 0); -- cipher text
  v                : out bit;                       -- valid cipher text output
  clk              : in  bit;                       -- master clock
  rst              : in  bit                        -- master reset
  );
end cipher;
 
architecture phy of cipher is
 
  signal ireg1     :     bit_vector (127 downto 0); -- 128 bit internal register 1
  signal ireg2     :     bit_vector (127 downto 0); -- 128 bit internal register 2
  signal ct2b      :     bit_vector (  1 downto 0); --   2 bit counter
  signal wsb1      :     bit_vector ( 31 downto 0); -- SubBytes
  signal wsb2      :     bit_vector ( 31 downto 0); -- SubBytes
  signal wsr       :     bit_vector ( 31 downto 0); -- ShiftRows
  signal wmc       :     bit_vector ( 31 downto 0); -- MixColumns
  signal ssm       :     bit_vector ( 31 downto 0); -- SubBytes, ShiftRows, MixColumns
  signal ikey      :     bit_vector ( 31 downto 0); -- internal round key
  signal rnd       :     bit_vector (  3 downto 0); -- current round number
  signal rnd_cr    :     bit_vector (  3 downto 0); -- currend round number carry
  signal ipt       :     bit_vector ( 31 downto 0); -- internal plain text
  signal s1i       :     bit_vector (  7 downto 0); --  Input SubBytes 1
  signal s2i       :     bit_vector (  7 downto 0); --  Input SubBytes 2
  signal s3i       :     bit_vector (  7 downto 0); --  Input SubBytes 3
  signal s4i       :     bit_vector (  7 downto 0); --  Input SubBytes 4
  signal s1o       :     bit_vector (  7 downto 0); -- Output SubBytes 1
  signal s2o       :     bit_vector (  7 downto 0); -- Output SubBytes 2
  signal s3o       :     bit_vector (  7 downto 0); -- Output SubBytes 3
  signal s4o       :     bit_vector (  7 downto 0); -- Output SubBytes 4
  signal x2ai      :     bit_vector (  7 downto 0); --  Input xtime 2  a
  signal x2bi      :     bit_vector (  7 downto 0); --  Input xtime 2  b
  signal x2ci      :     bit_vector (  7 downto 0); --  Input xtime 2  c
  signal x2di      :     bit_vector (  7 downto 0); --  Input xtime 2  d
  signal x2ao      :     bit_vector (  7 downto 0); -- Output xtime 2  a
  signal x2bo      :     bit_vector (  7 downto 0); -- Output xtime 2  b
  signal x2co      :     bit_vector (  7 downto 0); -- Output xtime 2  c
  signal x2do      :     bit_vector (  7 downto 0); -- Output xtime 2  d
  signal ct2b_rst  :     bit;                       -- reset for internal block operation
  signal swp       :     bit;                       -- swap internal register
  signal swp1      :     bit;                       -- swap internal register
  signal vld       :     bit;                       -- final round
  signal vld1      :     bit;                       -- final round
  signal ildpt     :     bit;                       -- internal load plain text
  signal ildpt_rst :     bit;                       -- internal load plain text reset
 
  component sbox
    port (
    di  : in  bit_vector (  7 downto 0);
    do  : out bit_vector (  7 downto 0)
    );
  end component;
 
  component c2b
    port (
    cnt : out bit_vector (  1 downto 0);
    clk : in  bit;
    rst : in  bit
    );
  end component;
 
  component xtime_2
    port (
    x2i : in  bit_vector (  7 downto 0);
    x2o : out bit_vector (  7 downto 0)
    );
  end component;
 
begin
 
  sb1 : sbox
  port map (
    di => s1i,
    do => s1o
    );
  sb2 : sbox
  port map (
    di => s2i,
    do => s2o
    );
  sb3 : sbox
  port map (
    di => s3i,
    do => s3o
    );
  sb4 : sbox
  port map (
    di => s4i,
    do => s4o
    );
  ctr1 : c2b
  port map (
    cnt => ct2b,
    clk => clk,
    rst => ct2b_rst
    );
  x2a : xtime_2
  port map (
    x2i => x2ai,
    x2o => x2ao
    );
  x2b : xtime_2
  port map (
    x2i => x2bi,
    x2o => x2bo
    );
  x2c : xtime_2
  port map (
    x2i => x2ci,
    x2o => x2co
    );
  x2d : xtime_2
  port map (
    x2i => x2di,
    x2o => x2do
    );
 
-- 007 039 071 103 | 007 039 071 103
-- 015 047 079 111 | 047 079 111 015
-- 023 055 087 119 | 087 119 023 055
-- 031 063 095 127 | 127 031 063 095
 
  with ct2b(01 downto 00) select
  wsb1             <= ireg1(127 downto 120) & ireg1( 87 downto  80) & ireg1( 47 downto  40) & ireg1(  7 downto   0) when B"00", -- 1st column
                      ireg1( 31 downto  24) & ireg1(119 downto 112) & ireg1( 79 downto  72) & ireg1( 39 downto  32) when B"11", -- 4th column
                      ireg1( 63 downto  56) & ireg1( 23 downto  16) & ireg1(111 downto 104) & ireg1( 71 downto  64) when B"10", -- 3rd column
                      ireg1( 95 downto  88) & ireg1( 55 downto  48) & ireg1( 15 downto   8) & ireg1(103 downto  96) when B"01"; -- 2nd column
  with ct2b(01 downto 00) select
  wsb2             <= ireg2(127 downto 120) & ireg2( 87 downto  80) & ireg2( 47 downto  40) & ireg2(  7 downto   0) when B"00", -- 1st column
                      ireg2( 31 downto  24) & ireg2(119 downto 112) & ireg2( 79 downto  72) & ireg2( 39 downto  32) when B"11", -- 4th column
                      ireg2( 63 downto  56) & ireg2( 23 downto  16) & ireg2(111 downto 104) & ireg2( 71 downto  64) when B"10", -- 3rd column
                      ireg2( 95 downto  88) & ireg2( 55 downto  48) & ireg2( 15 downto   8) & ireg2(103 downto  96) when B"01"; -- 2nd column
 
--SubBytes
  s1i(07 downto 00)<= wsb1(31 downto 24) when swp = '1' else wsb2(31 downto 24);
  s2i(07 downto 00)<= wsb1(23 downto 16) when swp = '1' else wsb2(23 downto 16);
  s3i(07 downto 00)<= wsb1(15 downto 08) when swp = '1' else wsb2(15 downto 08);
  s4i(07 downto 00)<= wsb1(07 downto 00) when swp = '1' else wsb2(07 downto 00);
 
--ShiftRows
  wsr              <= s1o & s2o & s3o & s4o;
 
--MixColumns
  x2ai             <= wsr(31 downto 24);
  x2bi             <= wsr(23 downto 16);
  x2ci             <= wsr(15 downto 08);
  x2di             <= wsr(07 downto 00);
 
  wmc(31 downto 24)<= x2ao xor x2bo xor x2bi xor x2ci xor x2di;
  wmc(23 downto 16)<= x2ai xor x2bo xor x2co xor x2ci xor x2di;
  wmc(15 downto 08)<= x2ai xor x2bi xor x2co xor x2do xor x2di;
  wmc(07 downto 00)<= x2ao xor x2ai xor x2bi xor x2ci xor x2do;
 
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      ildpt <= ldpt;
    end if;
  end process;
 
  ildpt_rst <= ((ildpt xor ldpt) and ldpt);
  ct2b_rst  <= rst or ildpt_rst;
 
  rnd_cr(0)          <= '0'; -- LSB always zero
  rnd_cr(3 downto 1) <= ( ((rnd(2 downto 0) and B"001") or (rnd(2 downto 0) and rnd_cr(2 downto 0))) or (B"001" and rnd_cr(2 downto 0)) );
 
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      if ((ildpt_rst or rst) = '1') then
        swp <= '0';
        rnd <= B"0000";
      elsif (not(not(ct2b(1)) or not(ct2b(0))) = '1') then
        swp <= not(swp);
        rnd <= ((rnd xor B"0001") xor rnd_cr);
      end if;
    end if;
  end process;
 
  vld  <= (not(Nk(3) or not(Nk(2)) or Nk(1) or Nk(0))      and      not(not(rnd(3)) or rnd(2) or not(rnd(1)) or rnd(0))) or    -- Nk 0100 (10 round)
	  (not(Nk(3) or not(Nk(2)) or not(Nk(1)) or Nk(0)) and      not(not(rnd(3)) or not(rnd(2)) or rnd(1) or rnd(0))) or    -- Nk 0110 (12 round)
	  (not(not(Nk(3)) or Nk(2) or Nk(1) or Nk(0))      and not(not(rnd(3)) or not(rnd(2)) or not(rnd(1)) or rnd(0)));      -- Nk 1000 (14 round)
 
  ssm  <= wmc when vld = '0' else wsr;
  ikey <= key;
 
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      if (rst = '1') then
        ireg1(127 downto 00) <= (others => '0');
        ireg2(127 downto 00) <= (others => '0');
      elsif (ildpt = '1') then
        ireg1(127 downto 00) <= ireg1(095 downto 00) & (ipt xor ikey); -- initial round
      elsif (  swp = '0') then
        ireg1(127 downto 00) <= ireg1(095 downto 00) & (ssm xor ikey);
      else
        ireg2(127 downto 00) <= ireg2(095 downto 00) & (ssm xor ikey);
      end if;
    end if;
  end process;
 
  process (clk)
  begin
    if ((clk = '1') and clk'event) then
      swp1 <= swp;
      vld1 <= vld;
      ipt  <= pt;
    end if;
  end process;
 
  ct  <= ireg1(31 downto 00) when swp1 = '0' else ireg2(31 downto 00);
  v   <= vld1;
 
end phy;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.