1
0
mirror of synced 2026-01-17 08:32:53 +00:00

Adding basic AES support (using AES block from https://github.com/mbgh/aes128-hdl)

This commit is contained in:
Romain Dolbeau 2020-12-19 11:43:56 -05:00
parent 1b25261073
commit 8afe45ea54
3 changed files with 159 additions and 14 deletions

View File

@ -89,16 +89,22 @@ struct rdfpga_128bits_alt {
#define RDFPGA_WH _IOW(0, 2, struct rdfpga_128bits)
#define RDFPGA_WI _IOW(0, 3, struct rdfpga_128bits)
#define RDFPGA_RC _IOR(0, 4, struct rdfpga_128bits)
#define RDFPGA_WL _IOW(0, 1, uint32_t)
#define RDFPGA_WL _IOW(0, 5, uint32_t)
#define RDFPGA_AESWK _IOW(0, 10, struct rdfpga_128bits)
#define RDFPGA_AESWD _IOW(0, 11, struct rdfpga_128bits)
#define RDFPGA_AESRO _IOR(0, 12, struct rdfpga_128bits)
int
rdfpga_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
struct rdfpga_softc *sc = device_lookup_private(&rdfpga_cd, minor(dev));
struct rdfpga_128bits_alt *bits = (struct rdfpga_128bits_alt*)data;
int err = 0, i;
int err = 0, i, ctr = 0;
uint32_t ctrl;
switch (cmd) {
/* GCM */
case RDFPGA_WC:
for (i = 0 ; i < 2 ; i++)
bus_space_write_8(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_GCM_C + (i*8)), bits->x[i] );
@ -118,6 +124,40 @@ rdfpga_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
case RDFPGA_WL:
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_REG_LED, *(uint32_t*)data);
break;
/* AES */
case RDFPGA_AESWK:
ctrl = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_REG_AES128_CTRL);
if (ctrl)
return EBUSY;
for (i = 0 ; i < 2 ; i++)
bus_space_write_8(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_AES128_KEY + (i*8)), bits->x[i] );
sc->aes_key_refresh = 1;
break;
case RDFPGA_AESWD:
ctrl = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_REG_AES128_CTRL);
if (ctrl)
return EBUSY;
for (i = 0 ; i < 2 ; i++)
bus_space_write_8(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_AES128_DATA + (i*8)), bits->x[i] );
ctrl = RDFPGA_MASK_AES128_START;
if (sc->aes_key_refresh) {
ctrl |= RDFPGA_MASK_AES128_NEWKEY;
sc->aes_key_refresh = 0;
}
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_REG_AES128_CTRL, ctrl);
break;
case RDFPGA_AESRO:
ctrl = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_REG_AES128_CTRL);
while (ctrl && (ctr < 3)) {
delay(1);
ctrl = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs, RDFPGA_REG_AES128_CTRL);
ctr ++;
}
if (ctrl)
return EBUSY;
for (i = 0 ; i < 2 ; i++)
bits->x[i] = bus_space_read_8(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_AES128_OUT + (i*8)));
break;
default:
err = EINVAL;
break;
@ -129,32 +169,32 @@ rdfpga_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
int
rdfpga_open(dev_t dev, int flags, int mode, struct lwp *l)
{
#if 0
struct rdfpga_softc *sc = device_lookup_private(&rdfpga_cd, minor(dev));
int i;
for (i = 0 ; i < 4 ; i++)
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_GCM_C + (i*4)), 0);
for (i = 0 ; i < 4 ; i++)
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_GCM_H + (i*4)), 0);
for (i = 0 ; i < 4 ; i++)
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_GCM_I + (i*4)), 0);
#endif
return (0);
}
int
rdfpga_close(dev_t dev, int flags, int mode, struct lwp *l)
{
#if 0
struct rdfpga_softc *sc = device_lookup_private(&rdfpga_cd, minor(dev));
int i;
for (i = 0 ; i < 4 ; i++)
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_GCM_C + (i*4)), 0);
for (i = 0 ; i < 4 ; i++)
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_GCM_H + (i*4)), 0);
for (i = 0 ; i < 4 ; i++)
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_GCM_I + (i*4)), 0);
#endif
return (0);
}
@ -314,6 +354,7 @@ rdfpga_attach(device_t parent, device_t self, void *aux)
struct sbus_softc *sbsc = device_private(parent);
int node;
int sbusburst;
int i;
/* bus_dma_tag_t dt = sa->sa_dmatag; */
sc->sc_bustag = sa->sa_bustag;
@ -366,4 +407,8 @@ rdfpga_attach(device_t parent, device_t self, void *aux)
} else {
aprint_normal_dev(self, "dmamap: %lu %lu %d (%p)\n", sc->sc_dmamap->dm_maxsegsz, sc->sc_dmamap->dm_mapsize, sc->sc_dmamap->dm_nsegs, sc->sc_dmatag->_dmamap_load);
}
for (i = 0 ; i < 2 ; i++)
bus_space_write_8(sc->sc_bustag, sc->sc_bhregs, (RDFPGA_REG_AES128_KEY + (i*8)), 0ull);
sc->aes_key_refresh = 1;
}

View File

@ -43,21 +43,25 @@ struct rdfpga_softc {
int sc_bufsiz; /* Size of buffer */
bus_dma_tag_t sc_dmatag;
bus_dmamap_t sc_dmamap; /* DMA map for bus_dma_* */
int aes_key_refresh;
};
/* led */
#define RDFPGA_REG_LED 0x0 /* 1 reg */
/* gcm stuff */
#define RDFGPA_REG_GCM_BASE 0x40
#define RDFPGA_REG_GCM_H (RDFGPA_REG_GCM_BASE + 0x00) /* 4 regs */
#define RDFPGA_REG_GCM_C (RDFGPA_REG_GCM_BASE + 0x10) /* 4 regs */
#define RDFPGA_REG_GCM_I (RDFGPA_REG_GCM_BASE + 0x20) /* 4 regs */
/* dma, currently to read data in GCM */
#define RDFPGA_REG_DMA_BASE 0x80
#define RDFPGA_REG_DMA_ADDR (RDFPGA_REG_DMA_BASE + 0x00)
#define RDFPGA_REG_DMA_CTRL (RDFPGA_REG_DMA_BASE + 0x04)
#define RDFPGA_MASK_DMA_CTRL_START 0x80000000
#define RDFPGA_MASK_DMA_CTRL_BUSY 0x40000000
#define RDFPGA_MASK_DMA_CTRL_BUSY 0x40000000 /* unused */
#define RDFPGA_MASK_DMA_CTRL_ERR 0x20000000
/* #define RDFPGA_MASK_DMA_CTRL_RW 0x10000000 */
#define RDFPGA_MASK_DMA_CTRL_BLKCNT 0x00000FFF
@ -66,4 +70,16 @@ struct rdfpga_softc {
#define RDFPGA_VAL_DMA_MAX_SZ 65536
/* having a go at AES128 */
#define RDFPGA_REG_AES128_BASE 0xc0
#define RDFPGA_REG_AES128_KEY (RDFPGA_REG_AES128_BASE + 0x00) /* 4 regs */
#define RDFPGA_REG_AES128_DATA (RDFPGA_REG_AES128_BASE + 0x10) /* 4 regs */
#define RDFPGA_REG_AES128_OUT (RDFPGA_REG_AES128_BASE + 0x20) /* 4 regs */
#define RDFPGA_REG_AES128_CTRL (RDFPGA_REG_AES128_BASE + 0x30)
#define RDFPGA_MASK_AES128_START 0x80000000
#define RDFPGA_MASK_AES128_BUSY 0x40000000
#define RDFPGA_MASK_AES128_ERR 0x20000000
#define RDFPGA_MASK_AES128_NEWKEY 0x10000000
#endif /* _RDFPGA_H_ */

View File

@ -95,6 +95,19 @@ ENTITY SBusFSM is
CONSTANT REG_INDEX_DMA_CTRL2 : integer := 34; -- placeholder
CONSTANT REG_INDEX_DMA_CTRL3 : integer := 35; -- placeholder
CONSTANT REG_INDEX_AES128_KEY1 : integer := 48;
CONSTANT REG_INDEX_AES128_KEY2 : integer := 49;
CONSTANT REG_INDEX_AES128_KEY3 : integer := 50;
CONSTANT REG_INDEX_AES128_KEY4 : integer := 51;
CONSTANT REG_INDEX_AES128_DATA1 : integer := 52;
CONSTANT REG_INDEX_AES128_DATA2 : integer := 53;
CONSTANT REG_INDEX_AES128_DATA3 : integer := 54;
CONSTANT REG_INDEX_AES128_DATA4 : integer := 55;
CONSTANT REG_INDEX_AES128_OUT1 : integer := 56;
CONSTANT REG_INDEX_AES128_OUT2 : integer := 57;
CONSTANT REG_INDEX_AES128_OUT3 : integer := 58;
CONSTANT REG_INDEX_AES128_OUT4 : integer := 59;
CONSTANT REG_INDEX_AES128_CTRL : integer := 60;
-- OFFSET to REGS; (8 downto 0) so 9 bits
CONSTANT REG_OFFSET_LED : std_logic_vector(8 downto 0) := conv_std_logic_vector(REG_INDEX_LED *4, 9);
@ -180,9 +193,11 @@ ARCHITECTURE RTL OF SBusFSM IS
SBus_Master_Read_Finish
);
TYPE Uart_States IS ( UART_IDLE, UART_WAITING );
TYPE AES_States IS ( AES_IDLE, AES_STARTED, AES_BUSY );
SIGNAL State : SBus_States := SBus_Start;
SIGNAL Uart_State : Uart_States := UART_IDLE;
SIGNAL AES_State : AES_States := AES_IDLE;
SIGNAL LED_RESET: std_logic := '0';
signal DATA_T : std_logic := '1'; -- I/O control for DATA IOBUF, default to input
signal BUF_DATA_I, BUF_DATA_O : std_logic_vector(31 downto 0); -- buffers for data from/to
@ -210,7 +225,14 @@ ARCHITECTURE RTL OF SBusFSM IS
signal w_TX_DONE : std_logic;
signal r_TX_BYTE : std_logic_vector(7 downto 0) := (others => '0');
-- signal aes_Clk_CI : std_logic;
signal aes_Reset_RBI : std_logic;
signal aes_Start_SI : std_logic;
signal aes_NewCipherkey_SI : std_logic;
signal aes_Busy_SO : std_logic;
signal aes_Plaintext_DI : std_logic_vector(127 downto 0);
signal aes_Cipherkey_DI : std_logic_vector(127 downto 0);
signal aes_Ciphertext_DO : std_logic_vector(127 downto 0);
-- SIGNAL LIFE_COUNTER48 : natural range 0 to 48000000 := 300;
-- SIGNAL LIFE_COUNTER25 : natural range 0 to 25000000 := 300;
@ -383,10 +405,23 @@ ARCHITECTURE RTL OF SBusFSM IS
);
end component uart_tx;
component clk_wiz_0 is
port(clk_in1 : in std_logic;
clk_out1 : out std_logic);
end component clk_wiz_0;
-- component clk_wiz_0 is
-- port(clk_in1 : in std_logic;
-- clk_out1 : out std_logic);
-- end component clk_wiz_0;
component aes128 is
port (
Clk_CI : in std_logic;
Reset_RBI : in std_logic;
Start_SI : in std_logic;
NewCipherkey_SI : in std_logic;
Busy_SO : out std_logic;
Plaintext_DI : in std_logic_vector(127 downto 0);
Cipherkey_DI : in std_logic_vector(127 downto 0);
Ciphertext_DO : out std_logic_vector(127 downto 0)
);
end component aes128;
PROCEDURE SBus_Set_Default(
-- signal SBUS_3V3_ACKs : OUT std_logic_vector(2 downto 0);
@ -476,6 +511,15 @@ BEGIN
o_tx_done => w_TX_DONE
);
label_aes128: aes128 port map(
Clk_CI => SBUS_3V3_CLK,
Reset_RBI => aes_Reset_RBI,
Start_SI => aes_Start_SI,
NewCipherkey_SI => aes_NewCipherkey_SI,
Busy_SO => aes_Busy_SO,
Plaintext_DI => aes_Plaintext_DI,
Cipherkey_DI => aes_Cipherkey_DI,
Ciphertext_DO => aes_Ciphertext_DO);
PROCESS (SBUS_3V3_CLK, SBUS_3V3_RSTs)
variable do_gcm : boolean := false;
@ -489,10 +533,12 @@ BEGIN
IF (SBUS_3V3_RSTs = '0') THEN
State <= SBus_Start;
fifo_rst <= '1';
aes_Reset_RBI <= '0'; -- it's active low, really
RES_COUNTER <= 4;
ELSIF RISING_EDGE(SBUS_3V3_CLK) THEN
fifo_wr_en <= '0';
aes_Start_SI <= '0';
-- LIFE_COUNTER25 <= LIFE_COUNTER25 - 1;
CASE State IS
@ -649,7 +695,8 @@ BEGIN
BUF_ERRs_O <= '1'; -- no late error
State <= SBus_Slave_Error;
END IF;
-- -- -- --
-- -- -- -- END IDLE
WHEN SBus_Slave_Ack_Reg_Write =>
fifo_wr_en <= '1'; fifo_din <= x"45"; -- "E"
BUF_ACKs_O <= ACK_IDLE; -- need one cycle of idle
@ -929,6 +976,8 @@ BEGIN
-- fifo_wr_en <= '1'; fifo_din <= x"2A"; -- "*"
State <= SBus_Idle;
ELSE
aes_Reset_RBI <= '1';
aes_Start_SI <= '0';
fifo_rst <= '0';
RES_COUNTER <= RES_COUNTER - 1;
END IF;
@ -938,6 +987,41 @@ BEGIN
END IF;
END CASE;
CASE AES_State IS
WHEN AES_IDLE =>
IF ((REGISTERS(REG_INDEX_AES128_CTRL)(31) = '1') AND
(REGISTERS(REG_INDEX_AES128_CTRL)(30) = '0') AND
(aes_Busy_SO ='0')
) THEN
fifo_wr_en <= '1'; fifo_din <= x"30"; -- "0"
-- start & !busy & !aesbusy -> start processing
aes_Cipherkey_DI <= REGISTERS(REG_INDEX_AES128_KEY1) & REGISTERS(REG_INDEX_AES128_KEY2) &
REGISTERS(REG_INDEX_AES128_KEY3) & REGISTERS(REG_INDEX_AES128_KEY4);
aes_Plaintext_DI <= REGISTERS(REG_INDEX_AES128_DATA1) & REGISTERS(REG_INDEX_AES128_DATA2) &
REGISTERS(REG_INDEX_AES128_DATA3) & REGISTERS(REG_INDEX_AES128_DATA4);
aes_NewCipherkey_SI <= REGISTERS(REG_INDEX_AES128_CTRL)(28);
aes_Start_SI <= '1';
REGISTERS(REG_INDEX_AES128_CTRL)(30) <= '1'; -- busy
AES_State <= AES_STARTED;
END IF;
WHEN AES_STARTED =>
fifo_wr_en <= '1'; fifo_din <= x"31"; -- "1"
IF (aes_Busy_SO ='1') THEN
AES_State <= AES_BUSY;
END IF;
WHEN AES_BUSY =>
IF (aes_Busy_SO ='0') THEN
fifo_wr_en <= '1'; fifo_din <= x"32"; -- "2"
-- start & busy & !aesbusy -> done processing
REGISTERS(REG_INDEX_AES128_OUT1) <= aes_Ciphertext_DO(127 downto 96);
REGISTERS(REG_INDEX_AES128_OUT2) <= aes_Ciphertext_DO( 95 downto 64);
REGISTERS(REG_INDEX_AES128_OUT3) <= aes_Ciphertext_DO( 63 downto 32);
REGISTERS(REG_INDEX_AES128_OUT4) <= aes_Ciphertext_DO( 31 downto 0);
REGISTERS(REG_INDEX_AES128_CTRL) <= (others => '0');
AES_State <= AES_IDLE;
END IF;
END CASE;
END IF;
END PROCESS;
@ -996,6 +1080,6 @@ BEGIN
OE_COUNTER <= OE_COUNTER - 1;
END IF;
END IF;
END PROCESS;
END PROCESS;
END rtl;