diff options
| -rw-r--r-- | src/ao_aes.c | 48 | ||||
| -rw-r--r-- | src/ao_launch.c | 59 | ||||
| -rw-r--r-- | src/ao_radio_cmac.c | 90 | ||||
| -rw-r--r-- | src/ao_telelaunch.c | 47 | ||||
| -rw-r--r-- | src/cc1111/ao_pins.h | 4 | ||||
| -rw-r--r-- | src/core/ao.h | 12 | ||||
| -rw-r--r-- | src/product/ao_telebt.c | 4 | ||||
| -rw-r--r-- | src/product/ao_teledongle.c | 2 | ||||
| -rw-r--r-- | src/teledongle-v0.1/.sdcdbrc | 1 | ||||
| -rw-r--r-- | src/telelaunch-v0.1/Makefile.defs | 2 | 
10 files changed, 237 insertions, 32 deletions
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,22 +49,33 @@ 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 <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"); +} 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 <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 index 00000000..b5404710 --- /dev/null +++ b/src/ao_telelaunch.c @@ -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(); +} 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  }; @@ -1649,12 +1653,20 @@ 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);  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 @@ -45,6 +45,10 @@ main(void)  #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  | 
