From 54a2fabe4ffb95a0335b47e80e2b6482e566dfd2 Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Mon, 4 Jan 2021 10:18:21 -0500 Subject: [PATCH] make AES asynchronous behind a couple FIFOs, now running at 120 MHz --- sbus-to-ztex-gateware/aes_wrapper.vhd | 136 +++++++++++++++ sbus-to-ztex-gateware/sbus_fsm.vhd | 232 +++++++++++++++----------- 2 files changed, 275 insertions(+), 93 deletions(-) create mode 100644 sbus-to-ztex-gateware/aes_wrapper.vhd diff --git a/sbus-to-ztex-gateware/aes_wrapper.vhd b/sbus-to-ztex-gateware/aes_wrapper.vhd new file mode 100644 index 0000000..21a368a --- /dev/null +++ b/sbus-to-ztex-gateware/aes_wrapper.vhd @@ -0,0 +1,136 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity aes_wrapper is + port ( + aes_wrapper_rst : in std_logic; + aes_wrapper_clk : in std_logic; +-- iskey?, keylen, encdec, cbc, data (256 or 128 + 128) + input_fifo_out : in std_logic_vector(259 downto 0); + input_fifo_empty: in std_logic; + input_fifo_rd_en : out std_logic; +-- data (128) + output_fifo_in : out std_logic_vector(127 downto 0); + output_fifo_full : in std_logic; + output_fifo_wr_en : out std_logic + ); + TYPE AES_States IS ( AES_IDLE, AES_INIT1, AES_INIT2, AES_CRYPT1, AES_CRYPT2 ); + SIGNAL AES_State : AES_States := AES_IDLE; + + signal aes_reset_n : std_logic; + signal aes_encdec : std_logic; + signal aes_init : std_logic; + signal aes_next : std_logic; + signal aes_ready : std_logic; + signal aes_key : std_logic_vector(255 downto 0); + signal aes_keylen : std_logic; + signal aes_block : std_logic_vector(127 downto 0); + signal aes_result : std_logic_vector(127 downto 0); + signal aes_result_valid : std_logic; + + constant iskey_idx : integer := 259; + constant keylen_idx : integer := 258; + constant encdec_idx : integer := 257; + constant cbc_idx : integer := 256; +end aes_wrapper; + + +architecture RTL of aes_wrapper is + + component aes_core is + port ( + clk : in std_logic; + reset_n: in std_logic; + encdec: in std_logic; + init: in std_logic; + xnext: in std_logic; + ready: out std_logic; + key: in std_logic_vector(255 downto 0); + keylen: in std_logic; + xblock: in std_logic_vector(127 downto 0); + result: out std_logic_vector(127 downto 0); + result_valid: out std_logic + ); + end component aes_core; + + +begin + + label_aes_core: aes_core port map( + clk => aes_wrapper_clk, + reset_n => aes_reset_n, + encdec => aes_encdec, + init => aes_init, + xnext => aes_next, + ready => aes_ready, + key => aes_key, + keylen => aes_keylen, + xblock => aes_block, + result => aes_result, + result_valid => aes_result_valid + ); + + aes_wrapper: process (aes_wrapper_rst, aes_wrapper_clk) + begin -- process aes_wrapper + IF (aes_wrapper_rst = '0') THEN + aes_reset_n <= '0'; + AES_State <= AES_IDLE; + + ELSIF RISING_EDGE(aes_wrapper_clk) then + aes_reset_n <= '1'; + input_fifo_rd_en <= '0'; + output_fifo_wr_en <= '0'; + CASE AES_State IS + WHEN AES_IDLE => + IF ((input_fifo_empty = '0') AND + (output_fifo_full = '0') AND + (aes_ready = '1') + ) then + input_fifo_rd_en <= '1'; + IF (input_fifo_out(iskey_idx) = '1') THEN + aes_key <= input_fifo_out(255 downto 0); + aes_keylen <= input_fifo_out(keylen_idx); + aes_init <= '1'; + aes_encdec <= input_fifo_out(encdec_idx); + AES_State <= AES_INIT1; + ELSE + aes_next <= '1'; + aes_encdec <= input_fifo_out(encdec_idx); + IF (input_fifo_out(cbc_idx) = '0') THEN + -- normal mode + aes_block <= input_fifo_out(127 downto 0); + ELSE + -- cbc mode + aes_block <= input_fifo_out(127 downto 0) XOR input_fifo_out(255 downto 128); + END IF; + AES_State <= AES_CRYPT1; + END IF; + END IF; + + WHEN AES_INIT1 => + AES_State <= AES_INIT2; + + WHEN AES_INIT2 => + aes_init <= '0'; + IF (aes_ready = '1') THEN + AES_State <= AES_IDLE; + END IF; + + WHEN AES_CRYPT1 => + AES_State <= AES_CRYPT2; + + WHEN AES_CRYPT2 => + aes_next <= '0'; + IF (aes_result_valid = '1') then + output_fifo_wr_en <= '1'; + output_fifo_in <= aes_result; + AES_State <= AES_IDLE; + END IF; + + END CASE; + end IF; + + end process aes_wrapper; + +end RTL; diff --git a/sbus-to-ztex-gateware/sbus_fsm.vhd b/sbus-to-ztex-gateware/sbus_fsm.vhd index 663b50c..9975496 100644 --- a/sbus-to-ztex-gateware/sbus_fsm.vhd +++ b/sbus-to-ztex-gateware/sbus_fsm.vhd @@ -214,7 +214,7 @@ ARCHITECTURE RTL OF SBusFSM IS SBus_Master_Write_Final ); TYPE Uart_States IS ( UART_IDLE, UART_WAITING ); - TYPE AES_States IS ( AES_IDLE, AES_INIT1, AES_INIT2, AES_CRYPT1, AES_CRYPT2 ); + TYPE AES_States IS ( AES_IDLE, AES_INIT1, AES_CRYPT1, AES_CRYPT2 ); SIGNAL State : SBus_States := SBus_Start; SIGNAL Uart_State : Uart_States := UART_IDLE; @@ -234,6 +234,7 @@ ARCHITECTURE RTL OF SBusFSM IS signal BUF_ERRs_I, BUF_ERRs_O : std_logic; -- buffers for ERRs from/to -- signal uart_clk : std_logic; -- 5.76 MHz clock for FIFO write & UART + signal aes_clk_out : std_logic; -- 100 MHz clock for AES signal fifo_rst : STD_LOGIC := '1'; -- start in reset mode signal fifo_din : STD_LOGIC_VECTOR ( 7 downto 0 ); @@ -245,17 +246,20 @@ ARCHITECTURE RTL OF SBusFSM IS signal r_TX_DV : std_logic := '0'; signal w_TX_DONE : std_logic; signal r_TX_BYTE : std_logic_vector(7 downto 0) := (others => '0'); - - signal aes_reset_n : std_logic; - signal aes_encdec : std_logic; - signal aes_init : std_logic; - signal aes_next : std_logic; - signal aes_ready : std_logic; - signal aes_key : std_logic_vector(255 downto 0); - signal aes_keylen : std_logic; - signal aes_block : std_logic_vector(127 downto 0); - signal aes_result : std_logic_vector(127 downto 0); - signal aes_result_valid : std_logic; + + signal aes_wrapper_rst : std_logic := '0'; + signal fifo_toaes_din : STD_LOGIC_VECTOR ( 259 downto 0 ); + signal fifo_toaes_wr_en : STD_LOGIC; + signal fifo_toaes_rd_en : STD_LOGIC; + signal fifo_toaes_dout : STD_LOGIC_VECTOR ( 259 downto 0 ); + signal fifo_toaes_full : STD_LOGIC; + signal fifo_toaes_empty : STD_LOGIC; + signal fifo_fromaes_din : STD_LOGIC_VECTOR ( 127 downto 0 ); + signal fifo_fromaes_wr_en : STD_LOGIC; + signal fifo_fromaes_rd_en : STD_LOGIC; + signal fifo_fromaes_dout : STD_LOGIC_VECTOR ( 127 downto 0 ); + signal fifo_fromaes_full : STD_LOGIC; + signal fifo_fromaes_empty : STD_LOGIC; -- SIGNAL LIFE_COUNTER48 : natural range 0 to 48000000 := 300; -- SIGNAL LIFE_COUNTER25 : natural range 0 to 25000000 := 300; @@ -263,6 +267,9 @@ ARCHITECTURE RTL OF SBusFSM IS -- counter to wait 20s before enabling SBus signals, without this the SS20 won't POST reliably... -- this means a need to probe-sbus from the PROM to find the board (or warm reset) SIGNAL OE_COUNTER : natural range 0 to 960000000 := 960000000; + + SIGNAL AES_RST_COUNTER : natural range 0 to 31 := 31; + SIGNAL AES_TIMEOUT_COUNTER : natural range 0 to 63 := 63; -- 16 registers for GCM (12 used), 4 for DMA (2 used ATM), 16 for AES (13 used ATM) type REGISTERS_TYPE is array(0 to 64) of std_logic_vector(31 downto 0); @@ -462,6 +469,30 @@ ARCHITECTURE RTL OF SBusFSM IS empty : out STD_LOGIC ); end component; + component fifo_generator_to_aes is + Port ( + wr_clk : in STD_LOGIC; + rd_clk : in STD_LOGIC; + din : in STD_LOGIC_VECTOR ( 259 downto 0 ); + wr_en : in STD_LOGIC; + rd_en : in STD_LOGIC; + dout : out STD_LOGIC_VECTOR ( 259 downto 0 ); + full : out STD_LOGIC; + empty : out STD_LOGIC + ); + end component; + component fifo_generator_from_aes is + Port ( + wr_clk : in STD_LOGIC; + rd_clk : in STD_LOGIC; + din : in STD_LOGIC_VECTOR ( 127 downto 0 ); + wr_en : in STD_LOGIC; + rd_en : in STD_LOGIC; + dout : out STD_LOGIC_VECTOR ( 127 downto 0 ); + full : out STD_LOGIC; + empty : out STD_LOGIC + ); + end component; component uart_tx is generic ( @@ -482,21 +513,25 @@ ARCHITECTURE RTL OF SBusFSM IS -- clk_out1 : out std_logic); -- end component clk_wiz_0; - component aes_core is - port ( - clk : in std_logic; - reset_n: in std_logic; - encdec: in std_logic; - init: in std_logic; - xnext: in std_logic; - ready: out std_logic; - key: in std_logic_vector(255 downto 0); - keylen: in std_logic; - xblock: in std_logic_vector(127 downto 0); - result: out std_logic_vector(127 downto 0); - result_valid: out std_logic - ); - end component aes_core; + component clk_wiz_aes is + port(clk_out1 : out std_logic; + clk_in1 : in std_logic); + end component clk_wiz_aes; + + component aes_wrapper is + port ( + aes_wrapper_rst : in std_logic; + aes_wrapper_clk : in std_logic; +-- iskey?, keylen, encdec, cbc, data (256 or 128 + 128) + input_fifo_out : in std_logic_vector(259 downto 0); + input_fifo_empty: in std_logic; + input_fifo_rd_en : out std_logic; +-- data (128) + output_fifo_in : out std_logic_vector(127 downto 0); + output_fifo_full : in std_logic; + output_fifo_wr_en : out std_logic + ); + end component aes_wrapper; PROCEDURE SBus_Set_Default( -- signal SBUS_3V3_ACKs : OUT std_logic_vector(2 downto 0); @@ -565,13 +600,33 @@ BEGIN label_prom: Prom PORT MAP (addr => p_addr, data => p_data); - label_mas: mastrovito_V2_multiplication PORT MAP( a => mas_a, b => mas_b, c => mas_c ); + --label_mas: mastrovito_V2_multiplication PORT MAP( a => mas_a, b => mas_b, c => mas_c ); label_fifo: fifo_generator_uart port map(rst => fifo_rst, wr_clk => SBUS_3V3_CLK, rd_clk => fxclk_in, din => fifo_din, wr_en => fifo_wr_en, rd_en => fifo_rd_en, dout => fifo_dout, full => fifo_full, empty => fifo_empty); + + + + label_fifo_toaes: fifo_generator_to_aes port map(wr_clk => SBUS_3V3_CLK, rd_clk => aes_clk_out, + din => fifo_toaes_din, wr_en => fifo_toaes_wr_en, rd_en => fifo_toaes_rd_en, + dout => fifo_toaes_dout, full => fifo_toaes_full, empty => fifo_toaes_empty); + label_fifo_fromaes: fifo_generator_from_aes port map(wr_clk => aes_clk_out, rd_clk => SBUS_3V3_CLK, + din => fifo_fromaes_din, wr_en => fifo_fromaes_wr_en, rd_en => fifo_fromaes_rd_en, + dout => fifo_fromaes_dout, full => fifo_fromaes_full, empty => fifo_fromaes_empty); + label_aes_wrapper: aes_wrapper port map( + aes_wrapper_rst => aes_wrapper_rst, -- fixme + aes_wrapper_clk => aes_clk_out, + input_fifo_out => fifo_toaes_dout, + input_fifo_empty => fifo_toaes_empty, + input_fifo_rd_en => fifo_toaes_rd_en, + output_fifo_in => fifo_fromaes_din, + output_fifo_full => fifo_fromaes_full, + output_fifo_wr_en => fifo_fromaes_wr_en + ); -- label_clk_wiz: clk_wiz_0 port map(clk_out1 => uart_clk, clk_in1 => fxclk_in); + label_aes_clk_wiz: clk_wiz_aes port map(clk_out1 => aes_clk_out, clk_in1 => fxclk_in); label_uart : uart_tx generic map ( @@ -585,20 +640,6 @@ BEGIN o_tx_serial => TX, o_tx_done => w_TX_DONE ); - - label_aes_core: aes_core port map( - clk => SBUS_3V3_CLK, - reset_n => aes_reset_n, - encdec => aes_encdec, - init => aes_init, - xnext => aes_next, - ready => aes_ready, - key => aes_key, - keylen => aes_keylen, - xblock => aes_block, - result => aes_result, - result_valid => aes_result_valid - ); PROCESS (SBUS_3V3_CLK, SBUS_3V3_RSTs) variable do_gcm : boolean := false; @@ -612,11 +653,12 @@ BEGIN IF (SBUS_3V3_RSTs = '0') THEN State <= SBus_Start; fifo_rst <= '1'; - aes_reset_n <= '0'; RES_COUNTER <= 4; ELSIF RISING_EDGE(SBUS_3V3_CLK) THEN fifo_wr_en <= '0'; + fifo_toaes_wr_en <= '0'; + fifo_fromaes_rd_en <= '0'; -- LIFE_COUNTER25 <= LIFE_COUNTER25 - 1; CASE State IS @@ -1150,9 +1192,6 @@ BEGIN -- fifo_wr_en <= '1'; fifo_din <= x"2A"; -- "*" State <= SBus_Idle; ELSE - aes_reset_n <= '1'; - aes_init <= '0'; - aes_next <= '0'; fifo_rst <= '0'; RES_COUNTER <= RES_COUNTER - 1; END IF; @@ -1167,69 +1206,64 @@ BEGIN WHEN AES_IDLE => IF ((REGISTERS(REG_INDEX_AES128_CTRL)(31) = '1') AND (REGISTERS(REG_INDEX_AES128_CTRL)(30) = '0') AND - (aes_ready ='1') + (fifo_toaes_full = '0') ) THEN fifo_wr_en <= '1'; fifo_din <= x"30"; -- "0" -- start & !busy & !aesbusy -> start processing - if (REGISTERS(REG_INDEX_AES128_CTRL)(28) = '1') THEN - IF (REGISTERS(REG_INDEX_AES128_CTRL)(26) = '0') THEN -- aes128 - aes_key <= REGISTERS(REG_INDEX_AES128_KEY1) & REGISTERS(REG_INDEX_AES128_KEY2) & - REGISTERS(REG_INDEX_AES128_KEY3) & REGISTERS(REG_INDEX_AES128_KEY4) & - x"00000000000000000000000000000000"; - aes_keylen <= '0'; - ELSE - aes_key <= REGISTERS(REG_INDEX_AES128_KEY1) & REGISTERS(REG_INDEX_AES128_KEY2) & - REGISTERS(REG_INDEX_AES128_KEY3) & REGISTERS(REG_INDEX_AES128_KEY4) & - REGISTERS(REG_INDEX_AES128_KEY5) & REGISTERS(REG_INDEX_AES128_KEY6) & - REGISTERS(REG_INDEX_AES128_KEY7) & REGISTERS(REG_INDEX_AES128_KEY8); - aes_keylen <= '1'; - END IF; - aes_init <= '1'; - aes_encdec <= '1'; + if (REGISTERS(REG_INDEX_AES128_CTRL)(28) = '1') THEN --newkey + fifo_toaes_din <= + '1' & -- iskey + REGISTERS(REG_INDEX_AES128_CTRL)(26) & -- keylen + '1' & -- encdec + REGISTERS(REG_INDEX_AES128_CTRL)(27) & -- cbc + REGISTERS(REG_INDEX_AES128_KEY1) & REGISTERS(REG_INDEX_AES128_KEY2) & + REGISTERS(REG_INDEX_AES128_KEY3) & REGISTERS(REG_INDEX_AES128_KEY4) & + REGISTERS(REG_INDEX_AES128_KEY5) & REGISTERS(REG_INDEX_AES128_KEY6) & + REGISTERS(REG_INDEX_AES128_KEY7) & REGISTERS(REG_INDEX_AES128_KEY8); + fifo_toaes_wr_en <= '1'; AES_State <= AES_INIT1; ELSE - aes_next <= '1'; - aes_encdec <= '1'; + fifo_toaes_din <= + '0' & -- !iskey + REGISTERS(REG_INDEX_AES128_CTRL)(26) & -- keylen + '1' & -- encdec + REGISTERS(REG_INDEX_AES128_CTRL)(27) & -- cbc + REGISTERS(REG_INDEX_AES128_OUT1) & REGISTERS(REG_INDEX_AES128_OUT2) & + REGISTERS(REG_INDEX_AES128_OUT3) & REGISTERS(REG_INDEX_AES128_OUT4) & + REGISTERS(REG_INDEX_AES128_DATA1) & REGISTERS(REG_INDEX_AES128_DATA2) & + REGISTERS(REG_INDEX_AES128_DATA3) & REGISTERS(REG_INDEX_AES128_DATA4); + fifo_toaes_wr_en <= '1'; AES_State <= AES_CRYPT1; - end IF; - - REGISTERS(REG_INDEX_AES128_CTRL)(30) <= '1'; -- busy - IF (REGISTERS(REG_INDEX_AES128_CTRL)(27) = '0') THEN - -- normal mode - aes_block <= REGISTERS(REG_INDEX_AES128_DATA1) & REGISTERS(REG_INDEX_AES128_DATA2) & - REGISTERS(REG_INDEX_AES128_DATA3) & REGISTERS(REG_INDEX_AES128_DATA4); - ELSE - -- cbc mode - aes_block <= - (REGISTERS(REG_INDEX_AES128_DATA1) XOR REGISTERS(REG_INDEX_AES128_OUT1)) - & (REGISTERS(REG_INDEX_AES128_DATA2) XOR REGISTERS(REG_INDEX_AES128_OUT2)) - & (REGISTERS(REG_INDEX_AES128_DATA3) XOR REGISTERS(REG_INDEX_AES128_OUT3)) - & (REGISTERS(REG_INDEX_AES128_DATA4) XOR REGISTERS(REG_INDEX_AES128_OUT4)); END IF; END IF; + when AES_INIT1 => fifo_wr_en <= '1'; fifo_din <= x"31"; -- "1" - AES_State <= AES_INIT2; - WHEN AES_INIT2 => - aes_init <= '0'; - fifo_wr_en <= '1'; fifo_din <= x"32"; -- "2" - IF (aes_ready = '1') THEN - aes_next <= '1'; - AES_State <= AES_CRYPT1; - END IF; + fifo_toaes_wr_en <= '0'; + REGISTERS(REG_INDEX_AES128_CTRL)(28) <= '0'; + AES_State <= AES_IDLE; + when AES_CRYPT1 => + AES_TIMEOUT_COUNTER <= 63; fifo_wr_en <= '1'; fifo_din <= x"33"; -- "3" + fifo_toaes_wr_en <= '0'; AES_State <= AES_CRYPT2; WHEN AES_CRYPT2 => + AES_TIMEOUT_COUNTER <= AES_TIMEOUT_COUNTER - 1; fifo_wr_en <= '1'; fifo_din <= x"34"; -- "4" - aes_next <= '0'; - IF (aes_result_valid = '1') THEN - fifo_wr_en <= '1'; fifo_din <= x"35"; -- "5" + IF (fifo_fromaes_empty = '0') THEN + fifo_wr_en <= '1'; fifo_din <= x"35"; -- "5" + fifo_fromaes_rd_en <= '1'; -- start & busy & !aesbusy -> done processing - REGISTERS(REG_INDEX_AES128_OUT1) <= aes_result(127 downto 96); - REGISTERS(REG_INDEX_AES128_OUT2) <= aes_result( 95 downto 64); - REGISTERS(REG_INDEX_AES128_OUT3) <= aes_result( 63 downto 32); - REGISTERS(REG_INDEX_AES128_OUT4) <= aes_result( 31 downto 0); + REGISTERS(REG_INDEX_AES128_OUT1) <= fifo_fromaes_dout(127 downto 96); + REGISTERS(REG_INDEX_AES128_OUT2) <= fifo_fromaes_dout( 95 downto 64); + REGISTERS(REG_INDEX_AES128_OUT3) <= fifo_fromaes_dout( 63 downto 32); + REGISTERS(REG_INDEX_AES128_OUT4) <= fifo_fromaes_dout( 31 downto 0); + REGISTERS(REG_INDEX_AES128_CTRL) <= (others => '0'); + AES_State <= AES_IDLE; + ELSIF (AES_TIMEOUT_COUNTER = 0) THEN + fifo_wr_en <= '1'; fifo_din <= x"36"; -- "6" + -- oups REGISTERS(REG_INDEX_AES128_CTRL) <= (others => '0'); AES_State <= AES_IDLE; END IF; @@ -1294,4 +1328,16 @@ BEGIN END IF; END PROCESS; + process (aes_clk_out) + BEGIN + IF RISING_EDGE(aes_clk_out) THEN + if (AES_RST_COUNTER = 0) THEN + aes_wrapper_rst <= '1'; + else + AES_RST_COUNTER <= (AES_RST_COUNTER - 1); + aes_wrapper_rst <= '0'; + end if; + END IF; + END PROCESS; + END rtl;