From: Keith Packard Date: Sat, 16 Jul 2011 01:51:33 +0000 (-0700) Subject: altos: Start work on AES and raw radio interfaces. X-Git-Tag: 1.0.9.1~43 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=a731d240f802d37524ce84c3c6acf22bcda4d522;ds=sidebyside altos: Start work on AES and raw radio interfaces. We probably don't want this raw radio interface, but it's a start. Signed-off-by: Keith Packard --- diff --git a/src/ao_aes.c b/src/ao_aes.c new file mode 100644 index 00000000..649eda06 --- /dev/null +++ b/src/ao_aes.c @@ -0,0 +1,122 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" + +__xdata uint8_t ao_aes_mutex; +__xdata uint8_t ao_aes_done; +__xdata uint8_t ao_aes_dma_in, ao_aes_dma_out; +__xdata uint8_t ao_aes_dma_in_done, ao_aes_dma_out_done; +__pdata enum ao_aes_mode ao_aes_current_mode; + +void +ao_aes_isr(void) __interrupt 4 +{ + S0CON = 0; + if (ENCCCS & ENCCCS_RDY) { + ao_aes_done = 1; + ao_wakeup(&ao_aes_done); + } +} + +void +ao_aes_set_mode(enum ao_aes_mode mode) +{ + ao_aes_current_mode = mode; +} + +void +ao_aes_set_key(__xdata uint8_t *in) +{ + ao_dma_set_transfer(ao_aes_dma_in, + in, + &ENCDIXADDR, + 7, + DMA_CFG0_WORDSIZE_8 | + DMA_CFG0_TMODE_SINGLE | + DMA_CFG0_TRIGGER_ENC_DW, + DMA_CFG1_SRCINC_1 | + DMA_CFG1_DESTINC_0 | + DMA_CFG1_PRIORITY_LOW); + ao_aes_done = 0; + ENCCCS = ENCCCS_MODE_CBC_MAC | + ENCCCS_CMD_LOAD_KEY | + ENCCCS_START; + while (!ao_aes_done) + ao_sleep(&ao_aes_done); +} + +void +ao_aes_run(__xdata uint8_t *in, + __xdata uint8_t *out) +{ + uint8_t b; + if (in) { + ao_dma_set_transfer(ao_aes_dma_in, + in, + &ENCDIXADDR, + 7, + DMA_CFG0_WORDSIZE_8 | + DMA_CFG0_TMODE_SINGLE | + DMA_CFG0_TRIGGER_ENC_DW, + DMA_CFG1_SRCINC_1 | + DMA_CFG1_DESTINC_0 | + DMA_CFG1_PRIORITY_LOW); + } + if (out) { + ao_dma_set_transfer(ao_aes_dma_out, + &ENCDOXADDR, + out, + 7, + DMA_CFG0_WORDSIZE_8 | + DMA_CFG0_TMODE_SINGLE | + DMA_CFG0_TRIGGER_ENC_UP, + DMA_CFG1_SRCINC_0 | + DMA_CFG1_DESTINC_1 | + DMA_CFG1_PRIORITY_LOW); + } + switch (ao_aes_current_mode) { + case ao_aes_mode_cbc_mac: + if (out) + b = (ENCCCS_MODE_CBC | + ENCCCS_CMD_ENCRYPT | + ENCCCS_START); + else + b = (ENCCCS_MODE_CBC_MAC | + ENCCCS_CMD_ENCRYPT | + ENCCCS_START); + break; + default: + return; + } + ao_aes_done = 0; + ENCCCS = b; + if (out) + while (!ao_aes_dma_out_done) + ao_sleep(&ao_aes_dma_out_done); + else + while (!ao_aes_done) + ao_sleep(&ao_aes_done); +} + +void +ao_aes_init(void) +{ + ao_aes_dma_in = ao_dma_alloc(&ao_aes_dma_in_done); + ao_aes_dma_out = ao_dma_alloc(&ao_aes_dma_out_done); + ENCIE = 1; +} diff --git a/src/ao_radio_cmac.c b/src/ao_radio_cmac.c new file mode 100644 index 00000000..4b118d02 --- /dev/null +++ b/src/ao_radio_cmac.c @@ -0,0 +1,100 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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; version 2 of the License. + * + * 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" + +#define AO_CMAC_KEY_LEN 16 +#define AO_CMAC_MAX_LEN (128 - AO_CMAC_KEY_LEN) + +static __xdata uint8_t cmac_key[AO_CMAC_KEY_LEN]; +static __xdata uint8_t cmac_data[AO_CMAC_MAX_LEN + AO_CMAC_KEY_LEN + 2 + AO_CMAC_KEY_LEN]; + +static uint8_t +getnibble(void) +{ + __pdata char c; + + c = getchar(); + if ('0' <= c && c <= '9') + return c - '0'; + if ('a' <= c && c <= 'f') + return c - ('a' - 10); + if ('A' <= c && c <= 'F') + return c - ('A' - 10); + ao_cmd_status = ao_cmd_lex_error; + return 0; +} + +static void +ao_radio_cmac_key(void) __reentrant +{ + uint8_t i; + + for (i = 0; i < AO_CMAC_KEY_LEN; i++) { + ao_cmd_hex(); + if (ao_cmd_status != ao_cmd_success) + return; + cmac_key[i] = ao_cmd_lex_i; + } +} + +static void +ao_radio_cmac_send(void) __reentrant +{ + uint8_t i, b; + + ao_cmd_hex(); + if (ao_cmd_status != ao_cmd_success) + return; + if (ao_cmd_lex_i > AO_CMAC_MAX_LEN || ao_cmd_lex_i % AO_CMAC_KEY_LEN != 0) { + ao_cmd_status = ao_cmd_syntax_error; + return; + } + for (i = 0; i < ao_cmd_lex_i; i++) { + b = getnibble() << 4; + b |= getnibble(); + if (ao_cmd_status != ao_cmd_success) + return; + cmac_data[i] = b; + } + ao_mutex_get(&ao_aes_mutex); + ao_aes_set_mode(ao_aes_mode_cbc_mac); + ao_aes_set_key(cmac_key); + for (i = 0; i < ao_cmd_lex_i; i += AO_CMAC_KEY_LEN) { + if (i + AO_CMAC_KEY_LEN < ao_cmd_lex_i) + ao_aes_run(&cmac_data[i], NULL); + else + ao_aes_run(&cmac_data[i], &cmac_data[ao_cmd_lex_i]); + } + ao_mutex_put(&ao_aes_mutex); + ao_set_monitor(0); + ao_radio_send(cmac_data, ao_cmd_lex_i + AO_CMAC_KEY_LEN); +} + +__code struct ao_cmds ao_radio_cmac_cmds[] = { + { ao_radio_cmac_key, "k ...\0Set AES-CMAC key." }, + { ao_radio_cmac_send, "s \0Send AES-CMAC packet. Bytes to send follow on next line" }, + { ao_radio_cmac_recv, "S \0Receive AES-CMAC packet. Timeout in ms" }, + { 0, NULL }, +}; + +void +ao_radio_cmac_init(void) +{ + ao_cmd_register(&ao_radio_cmac_cmds[0]); + +} diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 19ea0cfd..9e9b3bf6 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -108,6 +108,7 @@ #define SPI_CS_ON_P0 0 #define HAS_IGNITE 0 #define HAS_MONITOR 1 + #define HAS_AES 1 #endif #if defined(TELEMINI_V_1_0) @@ -212,6 +213,7 @@ #define SPI_CS_ON_P0 1 #define HAS_IGNITE 0 #define HAS_MONITOR 1 + #define HAS_AES 1 #endif #if defined(TIDONGLE) @@ -235,6 +237,7 @@ #define SPI_CS_ON_P0 1 #define HAS_IGNITE 0 #define HAS_MONITOR 1 + #define HAS_AES 1 #endif #if defined(TELEBT_V_0_0) @@ -300,6 +303,7 @@ #define BT_LINK_PIN_INDEX 7 #define BT_LINK_PIN P1_7 #define HAS_MONITOR 1 + #define HAS_AES 1 #endif #if defined(TELELAUNCH_V_0_1) diff --git a/src/cc1111/cc1111.h b/src/cc1111/cc1111.h index e52aa79f..11ea8bbb 100644 --- a/src/cc1111/cc1111.h +++ b/src/cc1111/cc1111.h @@ -768,7 +768,7 @@ struct cc_dma_channel { # define DMA_CFG0_TRIGGER_ADC_CH7 28 # define DMA_CFG0_TRIGGER_I2STX 28 # define DMA_CFG0_TRIGGER_ENC_DW 29 -# define DMA_CFG0_TRIGGER_DNC_UP 30 +# define DMA_CFG0_TRIGGER_ENC_UP 30 # define DMA_CFG1_SRCINC_MASK (3 << 6) # define DMA_CFG1_SRCINC_0 (0 << 6) @@ -1303,4 +1303,26 @@ __xdata __at (0xdf3c) uint8_t RF_PKTSTATUS; __xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC; #define RF_VCO_VC_DAC_OFF 0x3d +/* AES engine */ + +__sfr at 0xB1 ENCDI; +__sfr at 0xB2 ENCDO; +__xdata at (0xDFB1) volatile uint8_t ENCDIXADDR; +__xdata at (0xDFB2) volatile uint8_t ENCDOXADDR; + +__sfr at 0xB3 ENCCCS; + +#define ENCCCS_MODE_CBC (0 << 4) +#define ENCCCS_MODE_CFB (1 << 4) +#define ENCCCS_MODE_OFB (2 << 4) +#define ENCCCS_MODE_CTR (3 << 4) +#define ENCCCS_MODE_ECB (4 << 4) +#define ENCCCS_MODE_CBC_MAC (5 << 4) +#define ENCCCS_RDY (1 << 3) +#define ENCCCS_CMD_ENCRYPT (0 << 1) +#define ENCCCS_CMD_DECRYPT (1 << 1) +#define ENCCCS_CMD_LOAD_KEY (2 << 1) +#define ENCCCS_CMD_LOAD_IV (3 << 1) +#define ENCCCS_START (1 << 0) + #endif diff --git a/src/core/ao.h b/src/core/ao.h index 0cff0436..0275cad1 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -1629,4 +1629,30 @@ ao_companion_init(void); void ao_lcd_init(void); +/* ao_aes.c */ + +__xdata uint8_t ao_aes_mutex; + +enum ao_aes_mode { + ao_aes_mode_cbc_mac +}; + +#if HAS_AES +void +ao_aes_isr(void) __interrupt 4; +#endif + +void +ao_aes_set_mode(enum ao_aes_mode mode); + +void +ao_aes_set_key(__xdata uint8_t *in); + +void +ao_aes_run(__xdata uint8_t *in, + __xdata uint8_t *out); + +void +ao_aes_init(void); + #endif /* _AO_H_ */