From 776df9ce2e7b4fa5cedda326988e66c614299af4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Jul 2011 23:46:04 -0700 Subject: [PATCH] altos: Get AES CBC-MAC packet transfers running This just has simple command-line based packet transfers for testing. This also adds special ao_telelaunch bits where the launch control code will live. Signed-off-by: Keith Packard --- src/ao_aes.c | 48 ++++++++++++----- src/ao_launch.c | 59 ++++++++++++++++++++ src/ao_radio_cmac.c | 90 +++++++++++++++++++++++++------ src/ao_telelaunch.c | 47 ++++++++++++++++ src/cc1111/ao_pins.h | 4 +- src/core/ao.h | 12 +++++ src/product/ao_telebt.c | 4 ++ src/product/ao_teledongle.c | 2 + src/teledongle-v0.1/.sdcdbrc | 1 + src/telelaunch-v0.1/Makefile.defs | 2 + 10 files changed, 237 insertions(+), 32 deletions(-) create mode 100644 src/ao_launch.c create mode 100644 src/ao_telelaunch.c create mode 100644 src/teledongle-v0.1/.sdcdbrc diff --git a/src/ao_aes.c b/src/ao_aes.c index 649eda06..d50fecfb 100644 --- a/src/ao_aes.c +++ b/src/ao_aes.c @@ -17,6 +17,10 @@ #include "ao.h" +#if !HAS_AES +#error Must define HAS_AES 1 +#endif + __xdata uint8_t ao_aes_mutex; __xdata uint8_t ao_aes_done; __xdata uint8_t ao_aes_dma_in, ao_aes_dma_out; @@ -45,21 +49,32 @@ ao_aes_set_key(__xdata uint8_t *in) ao_dma_set_transfer(ao_aes_dma_in, in, &ENCDIXADDR, - 7, + AO_AES_LEN, 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_dma_start(ao_aes_dma_in); ao_aes_done = 0; ENCCCS = ENCCCS_MODE_CBC_MAC | - ENCCCS_CMD_LOAD_KEY | - ENCCCS_START; - while (!ao_aes_done) + ENCCCS_CMD_LOAD_KEY; + ENCCCS |= ENCCCS_START; + __critical while (!ao_aes_done) ao_sleep(&ao_aes_done); } +void +ao_aes_zero_iv(void) +{ + uint8_t b; + + ENCCCS = ENCCCS_MODE_CBC_MAC | ENCCCS_CMD_LOAD_IV | ENCCCS_START; + for (b = 0; b < AO_AES_LEN; b++) + ENCDI = 0; +} + void ao_aes_run(__xdata uint8_t *in, __xdata uint8_t *out) @@ -69,7 +84,7 @@ ao_aes_run(__xdata uint8_t *in, ao_dma_set_transfer(ao_aes_dma_in, in, &ENCDIXADDR, - 7, + AO_AES_LEN, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | DMA_CFG0_TRIGGER_ENC_DW, @@ -81,7 +96,7 @@ ao_aes_run(__xdata uint8_t *in, ao_dma_set_transfer(ao_aes_dma_out, &ENCDOXADDR, out, - 7, + AO_AES_LEN, DMA_CFG0_WORDSIZE_8 | DMA_CFG0_TMODE_SINGLE | DMA_CFG0_TRIGGER_ENC_UP, @@ -93,24 +108,28 @@ ao_aes_run(__xdata uint8_t *in, case ao_aes_mode_cbc_mac: if (out) b = (ENCCCS_MODE_CBC | - ENCCCS_CMD_ENCRYPT | - ENCCCS_START); + ENCCCS_CMD_ENCRYPT); else b = (ENCCCS_MODE_CBC_MAC | - ENCCCS_CMD_ENCRYPT | - ENCCCS_START); + ENCCCS_CMD_ENCRYPT); break; default: return; } ao_aes_done = 0; - ENCCCS = b; + if (in) + ao_dma_start(ao_aes_dma_in); if (out) - while (!ao_aes_dma_out_done) + ao_dma_start(ao_aes_dma_out); + ENCCCS = b; + ENCCCS |= ENCCCS_START; + if (out) { + __critical while (!ao_aes_dma_out_done) ao_sleep(&ao_aes_dma_out_done); - else - while (!ao_aes_done) + } else { + __critical while (!ao_aes_done) ao_sleep(&ao_aes_done); + } } void @@ -118,5 +137,6 @@ 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); + S0CON = 0; ENCIE = 1; } diff --git a/src/ao_launch.c b/src/ao_launch.c new file mode 100644 index 00000000..4870869e --- /dev/null +++ b/src/ao_launch.c @@ -0,0 +1,59 @@ +/* + * 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" + +static void +ao_launch(void) +{ + enum ao_igniter_status arm_status, ignite_status; + + ao_led_off(AO_LED_RED); + ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); + for (;;) { + arm_status = ao_igniter_status(ao_igniter_drogue); + + switch (arm_status) { + case ao_igniter_unknown: + break; + case ao_igniter_active: + case ao_igniter_open: + break; + case ao_igniter_ready: + ignite_status = ao_igniter_status(ao_igniter_main); + switch (ignite_status) { + case ao_igniter_unknown: + /* some kind of failure signal here */ + break; + case ao_igniter_active: + break; + case ao_igniter_open: + break; + } + break; + } + ao_delay(AO_SEC_TO_TICKS(1)); + } +} + +static __xdata struct ao_task ao_launch_task; + +void +ao_launch_init(void) +{ + ao_add_task(&ao_launch_task, ao_launch, "launch status"); +} diff --git a/src/ao_radio_cmac.c b/src/ao_radio_cmac.c index 9b406a21..7648a2f5 100644 --- a/src/ao_radio_cmac.c +++ b/src/ao_radio_cmac.c @@ -40,62 +40,119 @@ getnibble(void) return 0; } +static uint8_t +getbyte(void) +{ + uint8_t b; + b = getnibble() << 4; + b |= getnibble(); + return b; +} + static void ao_radio_cmac_key(void) __reentrant { uint8_t i; for (i = 0; i < AO_CMAC_KEY_LEN; i++) { - ao_cmd_hex(); + cmac_key[i] = getbyte(); 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; + uint8_t i; + uint8_t len; - ao_cmd_hex(); + ao_cmd_decimal(); 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) { + if (ao_cmd_lex_i < AO_CMAC_KEY_LEN || + 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(); + flush(); + len = ao_cmd_lex_i; + for (i = 0; i < len; i++) { + cmac_data[i] = getbyte(); 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_zero_iv(); + for (i = 0; i < len; i += AO_CMAC_KEY_LEN) { + if (i + AO_CMAC_KEY_LEN < len) ao_aes_run(&cmac_data[i], NULL); else - ao_aes_run(&cmac_data[i], &cmac_data[ao_cmd_lex_i]); + ao_aes_run(&cmac_data[i], &cmac_data[len]); } ao_mutex_put(&ao_aes_mutex); +#if HAS_MONITOR ao_set_monitor(0); - ao_radio_send(cmac_data, ao_cmd_lex_i + AO_CMAC_KEY_LEN); +#endif + printf("send:"); + for (i = 0; i < len + AO_CMAC_KEY_LEN; i++) + printf(" %02x", cmac_data[i]); + printf("\n"); flush(); + ao_radio_send(cmac_data, len + AO_CMAC_KEY_LEN); } static void ao_radio_cmac_recv(void) __reentrant { - ao_cmd_hex(); + uint8_t len, i; + uint16_t timeout; + + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + if (ao_cmd_lex_i < AO_CMAC_KEY_LEN || + 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; + } + len = ao_cmd_lex_i; + ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) return; + timeout = ao_cmd_lex_i; +#if HAS_MONITOR + ao_set_monitor(0); +#endif + if (timeout) + ao_alarm(timeout); + if (!ao_radio_recv(cmac_data, len + AO_CMAC_KEY_LEN + 2)) { + printf("timeout\n"); + return; + } + ao_mutex_get(&ao_aes_mutex); + ao_aes_set_mode(ao_aes_mode_cbc_mac); + ao_aes_set_key(cmac_key); + ao_aes_zero_iv(); + for (i = 0; i < len; i += AO_CMAC_KEY_LEN) { + if (i + AO_CMAC_KEY_LEN < len) + ao_aes_run(&cmac_data[i], NULL); + else + ao_aes_run(&cmac_data[i], &cmac_data[len + AO_CMAC_KEY_LEN + 2]); + } + printf ("PACKET "); + for (i = 0; i < len + AO_CMAC_KEY_LEN + 2 + AO_CMAC_KEY_LEN; i++) + printf("%02x", cmac_data[i]); + printf ("\n"); } -__code struct ao_cmds ao_radio_cmac_cmds[] = { - { ao_radio_cmac_key, "k ...\0Set AES-CMAC key." }, +static __code struct ao_cmds ao_radio_cmac_cmds[] = { + { ao_radio_cmac_key, "k\0Set AES-CMAC key. 16 key bytes follow on next line" }, { 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 }, @@ -105,5 +162,4 @@ void ao_radio_cmac_init(void) { ao_cmd_register(&ao_radio_cmac_cmds[0]); - } diff --git a/src/ao_telelaunch.c b/src/ao_telelaunch.c new file mode 100644 index 00000000..b5404710 --- /dev/null +++ b/src/ao_telelaunch.c @@ -0,0 +1,47 @@ +/* + * 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" +#include "ao_pins.h" + +void +main(void) +{ + ao_clock_init(); + + /* Turn on the red LED until the system is stable */ + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_RED); + + ao_timer_init(); + ao_adc_init(); + ao_beep_init(); + ao_cmd_init(); + ao_spi_init(); + ao_storage_init(); + ao_usb_init(); + ao_radio_init(); + ao_igniter_init(); +#if HAS_DBG + ao_dbg_init(); +#endif + ao_aes_init(); + ao_radio_cmac_init(); + ao_launch_init(); + ao_config_init(); + ao_start_scheduler(); +} diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 9e9b3bf6..819dc7df 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -267,6 +267,7 @@ #define BT_LINK_PIN_INDEX 7 #define BT_LINK_PIN P2_1 #define HAS_MONITOR 1 + #define HAS_AES 1 #endif #if defined(TELEBT_V_0_1) @@ -322,7 +323,7 @@ #define IGNITE_ON_P2 1 #define IGNITE_ON_P0 0 #define PACKET_HAS_MASTER 0 - #define PACKET_HAS_SLAVE 1 + #define PACKET_HAS_SLAVE 0 #define AO_LED_RED 2 #define AO_LED_GREEN 1 #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) @@ -333,6 +334,7 @@ #define HAS_ACCEL 0 #define HAS_IGNITE 1 #define HAS_MONITOR 0 + #define HAS_AES 1 #endif #if DBG_ON_P1 diff --git a/src/core/ao.h b/src/core/ao.h index 2394d401..2898852b 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -1633,6 +1633,10 @@ ao_lcd_init(void); __xdata uint8_t ao_aes_mutex; +/* AES keys and blocks are 128 bits */ + +#define AO_AES_LEN 16 + enum ao_aes_mode { ao_aes_mode_cbc_mac }; @@ -1648,6 +1652,9 @@ ao_aes_set_mode(enum ao_aes_mode mode); void ao_aes_set_key(__xdata uint8_t *in); +void +ao_aes_zero_iv(void); + void ao_aes_run(__xdata uint8_t *in, __xdata uint8_t *out); @@ -1655,6 +1662,11 @@ ao_aes_run(__xdata uint8_t *in, void ao_aes_init(void); +/* ao_radio_cmac.c */ + +void +ao_radio_cmac_init(void); + /* ao_launch.c */ void ao_launch_init(void); diff --git a/src/product/ao_telebt.c b/src/product/ao_telebt.c index 85565172..5bbbf71b 100644 --- a/src/product/ao_telebt.c +++ b/src/product/ao_telebt.c @@ -44,6 +44,10 @@ main(void) ao_btm_init(); #if HAS_DBG ao_dbg_init(); +#endif +#if HAS_AES + ao_aes_init(); + ao_radio_cmac_init(); #endif ao_config_init(); ao_start_scheduler(); diff --git a/src/product/ao_teledongle.c b/src/product/ao_teledongle.c index 008b200a..b8be9f45 100644 --- a/src/product/ao_teledongle.c +++ b/src/product/ao_teledongle.c @@ -35,6 +35,8 @@ main(void) #if HAS_DBG ao_dbg_init(); #endif + ao_aes_init(); + ao_radio_cmac_init(); ao_config_init(); ao_start_scheduler(); } diff --git a/src/teledongle-v0.1/.sdcdbrc b/src/teledongle-v0.1/.sdcdbrc new file mode 100644 index 00000000..710b4a2f --- /dev/null +++ b/src/teledongle-v0.1/.sdcdbrc @@ -0,0 +1 @@ +--directory=.. diff --git a/src/telelaunch-v0.1/Makefile.defs b/src/telelaunch-v0.1/Makefile.defs index e4934ffa..56f5730b 100644 --- a/src/telelaunch-v0.1/Makefile.defs +++ b/src/telelaunch-v0.1/Makefile.defs @@ -5,6 +5,8 @@ SRC = \ $(SPI_DRIVER_SRC) \ $(EE_DRIVER_SRC) \ ao_launch.c \ + ao_aes.c \ + ao_radio_cmac.c \ $(DBG_SRC) PRODUCT=TeleLaunch-v0.1 -- 2.30.2