altos: Get AES CBC-MAC packet transfers running
authorKeith Packard <keithp@keithp.com>
Thu, 21 Jul 2011 06:46:04 +0000 (23:46 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 27 Aug 2011 19:33:46 +0000 (12:33 -0700)
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 <keithp@keithp.com>
src/ao_aes.c
src/ao_launch.c [new file with mode: 0644]
src/ao_radio_cmac.c
src/ao_telelaunch.c [new file with mode: 0644]
src/cc1111/ao_pins.h
src/core/ao.h
src/product/ao_telebt.c
src/product/ao_teledongle.c
src/teledongle-v0.1/.sdcdbrc [new file with mode: 0644]
src/telelaunch-v0.1/Makefile.defs

index 649eda0681f3f3f7fb32fa1469a89ae331b7e996..d50fecfb997afacdbedc814a86a7ad3d70009fae 100644 (file)
 
 #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 (file)
index 0000000..4870869
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * 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");
+}
index 9b406a2190969db1ba2ef497c78911c88de00446..7648a2f599b46cc08f67022b95a3bafb214ea2bf 100644 (file)
@@ -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 <byte> ...\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 <length>\0Send AES-CMAC packet. Bytes to send follow on next line" },
        { ao_radio_cmac_recv,   "S <length> <timeout>\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 (file)
index 0000000..b540471
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * 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();
+}
index 9e9b3bf6c6ad32e04215a6a674f843747e517dc6..819dc7dfeafad5b4320143257e471b1eda3870b0 100644 (file)
        #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)
        #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)
        #define HAS_ACCEL               0
        #define HAS_IGNITE              1
        #define HAS_MONITOR             0
+       #define HAS_AES                 1
 #endif
 
 #if DBG_ON_P1
index 2394d401dcadf04770f6c21ab173ce9466bb58e2..2898852b974f9f14dd570a7c21d7e04913848cfa 100644 (file)
@@ -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);
index 8556517275f5d0e95b844d3afe35bbb9483468b7..5bbbf71b2ace93853f619a51186d6a093ef14f8f 100644 (file)
@@ -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();
index 008b200a0b75eb9f61a06e0b2d9f1cfe04f8a2ef..b8be9f45a480b4676f7c1524187a271279b4600c 100644 (file)
@@ -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 (file)
index 0000000..710b4a2
--- /dev/null
@@ -0,0 +1 @@
+--directory=..
index e4934ffa214dea97e96a2afb3e7bcbdcc8850b0f..56f5730bfa6d66edbc67928846992bf112322a01 100644 (file)
@@ -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