From f91d3f6c0122c7ce849c47305add585be3ea210f Mon Sep 17 00:00:00 2001 From: jgko Date: Fri, 14 Aug 2009 20:33:43 +0000 Subject: [PATCH] Adding in cc2420 security support codes --- apps/tests/cc2420/TestSecurity/README.txt | 60 +++ .../TestSecurity/RadioCountToLeds1/Makefile | 8 + .../RadioCountToLeds1/RadioCountToLeds.h | 42 ++ .../RadioCountToLeds1/RadioCountToLedsAppC.nc | 64 +++ .../RadioCountToLeds1/RadioCountToLedsC.nc | 158 +++++++ tos/chips/cc2420/CC2420.h | 33 +- tos/chips/cc2420/CC2420ActiveMessageC.nc | 1 - tos/chips/cc2420/csma/CC2420CsmaP.nc | 4 + tos/chips/cc2420/interfaces/CC2420Keys.nc | 33 ++ .../cc2420/interfaces/CC2420SecurityMode.nc | 35 ++ tos/chips/cc2420/receive/CC2420ReceiveC.nc | 9 + tos/chips/cc2420/receive/CC2420ReceiveP.nc | 394 +++++++++++++++++- tos/chips/cc2420/security/CC2420KeysC.nc | 46 ++ tos/chips/cc2420/security/CC2420KeysP.nc | 85 ++++ tos/chips/cc2420/security/SecAMSenderC.nc | 59 +++ tos/chips/cc2420/security/SecAMSenderP.nc | 174 ++++++++ tos/chips/cc2420/spi/CC2420SpiC.nc | 12 + tos/chips/cc2420/transmit/CC2420TransmitC.nc | 7 + tos/chips/cc2420/transmit/CC2420TransmitP.nc | 160 ++++++- tos/platforms/epic/.platform | 1 + tos/platforms/micaz/.platform | 1 + tos/platforms/telosb/.platform | 1 + 22 files changed, 1356 insertions(+), 31 deletions(-) create mode 100644 apps/tests/cc2420/TestSecurity/README.txt create mode 100644 apps/tests/cc2420/TestSecurity/RadioCountToLeds1/Makefile create mode 100644 apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLeds.h create mode 100644 apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsAppC.nc create mode 100644 apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsC.nc create mode 100644 tos/chips/cc2420/interfaces/CC2420Keys.nc create mode 100644 tos/chips/cc2420/interfaces/CC2420SecurityMode.nc create mode 100644 tos/chips/cc2420/security/CC2420KeysC.nc create mode 100644 tos/chips/cc2420/security/CC2420KeysP.nc create mode 100644 tos/chips/cc2420/security/SecAMSenderC.nc create mode 100644 tos/chips/cc2420/security/SecAMSenderP.nc diff --git a/apps/tests/cc2420/TestSecurity/README.txt b/apps/tests/cc2420/TestSecurity/README.txt new file mode 100644 index 00000000..061b7f57 --- /dev/null +++ b/apps/tests/cc2420/TestSecurity/README.txt @@ -0,0 +1,60 @@ +README for TestSecurity + +Author/Contact: +JeongGil Ko +Razvan Musaloiu-E. +Jong Hyun Lim + +Description: + +SecAMSend provides an interface to send Active Message based packets +while using the CC2420 in-line security options. + +Instructions: + +All three in-line security options are implemented. The user can +enable each mode by selecting one of the three commands, setCtr() to +enable counter mode encryption, setCbcMac() to enable CBC-MAC +authentication, and setCcm() to enable both functions (CCM) to the +packet. + +The first parameter of all options lets the user select which of the +two keys it will be using for security. + +The second parameter, sets the number of payload bytes to skip for +encryption, number of bytes that will be skipped for authentication or +the number of bytes that will be authenticated but not encrypted. By +default when CCM is used the authentication starts at the byte after +the length byte. Setting this second parameter to 0 will encrypt +and/or sign all the payload, whereas, when this value is set to the +length of the payload no bytes will be encrypted and/or signed. + +The third parameter for CBC-MAC and CCM are used to specify the number +of bytes in the authentication field. The user can select an even +number between 4 and 16 for this parameter. + +After specifying the three options the user can call a normal AMSend +procedure to transmit secured packets. + +Before this process please note that the setKey() command should be +used to specify the key the user desires to use for both the +transmitter and the receiver. + +Please note that in the Makefile the flag CC2420_HW_SECURITY MUST be +added for the security features to be active. + +Two application programs are included with security options +enabled. The first application, RadioCountToLeds1, is a modification +of RadioCountToLeds in the TinyOS 2.x repository. It dedicates one +node (TOS_NODE_ID 1) to be the transmitting node and other nodes to +receive its broadcast packets. Node 1 can use any of the three options +enabled. The second application, RadioCountToLeds2, is a modification +of the previous RadioCountToLeds1. Instead of only sending packets +with security enabled, node 1 sends each secured and un-secured +packets one at a time. The receivers distinguish between secured and +un-secured packets and process the un-secured ones through the normal +receive path and the secured ones through the secured receive path. + +Known bugs/limitations: + +None. diff --git a/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/Makefile b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/Makefile new file mode 100644 index 00000000..e7c53eba --- /dev/null +++ b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/Makefile @@ -0,0 +1,8 @@ +COMPONENT=RadioCountToLedsAppC +CFLAGS+=-DCC2420_HW_ACKNOWLEDGEMENTS +CFLAGS+=-DCC2420_HW_SECURITY +#CFLAGS+=-DCC2420_DEF_CHANNEL=25 +CFLAGS+=-DPACKET_LINK +CFLAGS+=-DTOSH_DATA_LENGTH=115 +CFLAGS+=-I%T/lib/printf +include $(MAKERULES) diff --git a/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLeds.h b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLeds.h new file mode 100644 index 00000000..404470df --- /dev/null +++ b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLeds.h @@ -0,0 +1,42 @@ +/* + * "Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + * + * Copyright (c) 2002-2003 Intel Corporation + * All rights reserved. + * + * This file is distributed under the terms in the attached INTEL-LICENSE + * file. If you do not find these files, copies can be found by writing to + * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, + * 94704. Attention: Intel License Inquiry. + */ + +#ifndef RADIO_COUNT_TO_LEDS_H +#define RADIO_COUNT_TO_LEDS_H + +typedef nx_struct radio_count_msg { + nx_uint16_t counter; + nx_uint16_t counter2[20]; +} radio_count_msg_t; + +enum { + AM_RADIO_COUNT_MSG = 6, +}; + +#endif diff --git a/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsAppC.nc b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsAppC.nc new file mode 100644 index 00000000..9d7ceb8c --- /dev/null +++ b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsAppC.nc @@ -0,0 +1,64 @@ +/* + * "Copyright (c) 2000-2005 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + * + * Copyright (c) 2002-2003 Intel Corporation + * All rights reserved. + * + * This file is distributed under the terms in the attached INTEL-LICENSE + * file. If you do not find these files, copies can be found by writing to + * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, + * 94704. Attention: Intel License Inquiry. + */ + +#include "RadioCountToLeds.h" + +/** + * Configuration for the RadioCountToLeds application. RadioCountToLeds + * maintains a 4Hz counter, broadcasting its value in an AM packet + * every time it gets updated. A RadioCountToLeds node that hears a counter + * displays the bottom three bits on its LEDs. This application is a useful + * test to show that basic AM communication and timers work. + * + * @author Philip Levis + * @date June 6 2005 + */ + +configuration RadioCountToLedsAppC {} +implementation { + components MainC, RadioCountToLedsC as App, LedsC, NoLedsC; + components new SecAMSenderC(AM_RADIO_COUNT_MSG) as AMSenderC; + components new AMReceiverC(AM_RADIO_COUNT_MSG); + components new TimerMilliC(); + components CC2420KeysC; + components ActiveMessageC; + + App.Boot -> MainC.Boot; + App.Receive -> AMReceiverC; + App.AMSend -> AMSenderC; + App.AMControl -> ActiveMessageC; + App.Leds -> LedsC; + App.MilliTimer -> TimerMilliC; + App.Packet -> AMSenderC; + App.CC2420Security -> AMSenderC; + App.CC2420Keys -> CC2420KeysC; + + components CC2420ActiveMessageC as Radio; + App.PacketLink -> Radio; +} diff --git a/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsC.nc b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsC.nc new file mode 100644 index 00000000..91a70b39 --- /dev/null +++ b/apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsC.nc @@ -0,0 +1,158 @@ +/* + * "Copyright (c) 2000-2005 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + * + * Copyright (c) 2002-2003 Intel Corporation + * All rights reserved. + * + * This file is distributed under the terms in the attached INTEL-LICENSE + * file. If you do not find these files, copies can be found by writing to + * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, + * 94704. Attention: Intel License Inquiry. + */ + +#include "Timer.h" +#include "RadioCountToLeds.h" +//#include "printf.h" +/** + * Implementation of the RadioCountToLeds application. RadioCountToLeds + * maintains a 4Hz counter, broadcasting its value in an AM packet + * every time it gets updated. A RadioCountToLeds node that hears a counter + * displays the bottom three bits on its LEDs. This application is a useful + * test to show that basic AM communication and timers work. + * + * @author Philip Levis + * @date June 6 2005 + */ + +module RadioCountToLedsC { + uses { + interface Leds; + interface Boot; + interface Receive; + interface AMSend; + interface Timer as MilliTimer; + interface SplitControl as AMControl; + interface Packet; + interface CC2420SecurityMode as CC2420Security; + interface CC2420Keys; + + interface PacketLink; + } +} +implementation { + + message_t packet; + uint8_t key[16] = {0x98,0x67,0x7F,0xAF,0xD6,0xAD,0xB7,0x0C,0x59,0xE8,0xD9,0x47,0xC9,0x71,0x15,0x0F}; + uint8_t keyReady = 0; // should be set to 1 when key setting is done + + bool locked; + uint16_t counter = 0; + + event void Boot.booted() + { + call AMControl.start(); + } + + event void AMControl.startDone(error_t err) + { + if (err == SUCCESS) { + call CC2420Keys.setKey(1, key); + if(TOS_NODE_ID == 1) + call MilliTimer.startPeriodic(128); + } else { + call AMControl.start(); + } + } + + event void AMControl.stopDone(error_t err) + { + } + + event void CC2420Keys.setKeyDone(uint8_t keyNo, uint8_t* skey) + { + keyReady = 1; + } + + event void MilliTimer.fired() + { + counter++; + dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter); + if (locked) { + return; + } + else if(keyReady == 1) { + + radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t)); + + if (rcm == NULL) { + return; + } + + rcm->counter = counter; + //call CC2420Security.setCtr(&packet, 0, 0); + //call CC2420Security.setCbcMac(&packet, 0, 0, 16); + call CC2420Security.setCcm(&packet, 1, 0, 16); + call PacketLink.setRetries(&packet, 3); + if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t)) == SUCCESS) { + dbg("RadioCountToLedsC", "RadioCountToLedsC: packet sent.\n", counter); + locked = TRUE; + } + } + } + + event message_t* Receive.receive(message_t* bufPtr, + void* payload, uint8_t len) + { + dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len); + if (len != sizeof(radio_count_msg_t)) {return bufPtr;} + else { + radio_count_msg_t* rcm = (radio_count_msg_t*)payload; + printf("counter: %d len: %d\n",rcm->counter, len); + printfflush(); + if (rcm->counter & 0x1) { + call Leds.led0On(); + } + else { + call Leds.led0Off(); + } + if (rcm->counter & 0x2) { + call Leds.led1On(); + } + else { + call Leds.led1Off(); + } + if (rcm->counter & 0x4) { + call Leds.led2On(); + } + else { + call Leds.led2Off(); + } + return bufPtr; + } + } + + event void AMSend.sendDone(message_t* msg, error_t error) + { + if (&packet == msg) { + locked = FALSE; + } + } + +} diff --git a/tos/chips/cc2420/CC2420.h b/tos/chips/cc2420/CC2420.h index 798107f0..bdaefd6b 100644 --- a/tos/chips/cc2420/CC2420.h +++ b/tos/chips/cc2420/CC2420.h @@ -81,6 +81,17 @@ typedef uint8_t cc2420_status_t; * All of these fields will be filled in automatically by the radio stack * when you attempt to send a message. */ +/** + * CC2420 Security Header + */ +typedef nx_struct security_header_t { + nx_uint8_t secLevel:3; + nx_uint8_t keyMode:2; + nx_uint8_t reserved:3; + nx_uint32_t frameCounter; + nx_uint8_t keyID[1]; // One byte for now +} security_header_t; + typedef nx_struct cc2420_header_t { nxle_uint8_t length; nxle_uint16_t fcf; @@ -88,6 +99,10 @@ typedef nx_struct cc2420_header_t { nxle_uint16_t destpan; nxle_uint16_t dest; nxle_uint16_t src; + +#ifdef CC2420_HW_SECURITY + security_header_t secHdr; +#endif /** I-Frame 6LowPAN interoperability byte */ #ifdef CC2420_IFRAME_TYPE @@ -99,7 +114,7 @@ typedef nx_struct cc2420_header_t { #endif } cc2420_header_t; - + /** * CC2420 Packet Footer */ @@ -407,6 +422,22 @@ enum cc2420_sfdmux_enums { CC2420_SFDMUX_XOSC16M_STABLE = 24, }; +enum cc2420_security_enums{ + CC2420_NO_SEC = 0, + CC2420_CBC_MAC = 1, + CC2420_CTR = 2, + CC2420_CCM = 3, + NO_SEC = 0, + CBC_MAC_4 = 1, + CBC_MAC_8 = 2, + CBC_MAC_16 = 3, + CTR = 4, + CCM_4 = 5, + CCM_8 = 6, + CCM_16 = 7 +}; +norace uint8_t SECURITYLOCK = 0; + enum { CC2420_INVALID_TIMESTAMP = 0x80000000L, diff --git a/tos/chips/cc2420/CC2420ActiveMessageC.nc b/tos/chips/cc2420/CC2420ActiveMessageC.nc index 21734736..509bc6fb 100644 --- a/tos/chips/cc2420/CC2420ActiveMessageC.nc +++ b/tos/chips/cc2420/CC2420ActiveMessageC.nc @@ -114,5 +114,4 @@ implementation { AM.CC2420Config -> CC2420ControlC; AM.SubBackoff -> CsmaC; - } diff --git a/tos/chips/cc2420/csma/CC2420CsmaP.nc b/tos/chips/cc2420/csma/CC2420CsmaP.nc index e67f9217..7c0ef75d 100644 --- a/tos/chips/cc2420/csma/CC2420CsmaP.nc +++ b/tos/chips/cc2420/csma/CC2420CsmaP.nc @@ -134,7 +134,11 @@ implementation { } header->length = len + CC2420_SIZE; +#ifdef CC2420_HW_SECURITY + header->fcf &= ((1 << IEEE154_FCF_ACK_REQ)|(1 << IEEE154_FCF_SECURITY_ENABLED)); +#else header->fcf &= 1 << IEEE154_FCF_ACK_REQ; +#endif header->fcf |= ( ( IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE ) | ( 1 << IEEE154_FCF_INTRAPAN ) | ( IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE ) | diff --git a/tos/chips/cc2420/interfaces/CC2420Keys.nc b/tos/chips/cc2420/interfaces/CC2420Keys.nc new file mode 100644 index 00000000..aedf58f6 --- /dev/null +++ b/tos/chips/cc2420/interfaces/CC2420Keys.nc @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2008 Johns Hopkins University. +* All rights reserved. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation for any purpose, without fee, and without written +* agreement is hereby granted, provided that the above copyright +* notice, the (updated) modification history and the author appear in +* all copies of this source code. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, +* OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @author JeongGil Ko + * @author Razvan Musaloiu-E. + * @author Jong Hyun Lim + */ + +interface CC2420Keys +{ + command error_t setKey(uint8_t keyNo, uint8_t* key); + event void setKeyDone(uint8_t keyNo, uint8_t* key); +} diff --git a/tos/chips/cc2420/interfaces/CC2420SecurityMode.nc b/tos/chips/cc2420/interfaces/CC2420SecurityMode.nc new file mode 100644 index 00000000..dca7a40d --- /dev/null +++ b/tos/chips/cc2420/interfaces/CC2420SecurityMode.nc @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2008 Johns Hopkins University. +* All rights reserved. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation for any purpose, without fee, and without written +* agreement is hereby granted, provided that the above copyright +* notice, the (updated) modification history and the author appear in +* all copies of this source code. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, +* OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @author JeongGil Ko + * @author Razvan Musaloiu-E. + * @author Jong Hyun Lim + */ + +interface CC2420SecurityMode +{ + command error_t setCtr(message_t* msg, uint8_t setKey, uint8_t setSkip); + // Valid sizes are: 4, 6, 8, 10, 12, 14, 16 + command error_t setCbcMac(message_t* msg, uint8_t setKey, uint8_t setSkip, uint8_t size); + command error_t setCcm(message_t* msg, uint8_t setKey, uint8_t setSkip, uint8_t size); +} diff --git a/tos/chips/cc2420/receive/CC2420ReceiveC.nc b/tos/chips/cc2420/receive/CC2420ReceiveC.nc index 14c723f6..f659a9e1 100644 --- a/tos/chips/cc2420/receive/CC2420ReceiveC.nc +++ b/tos/chips/cc2420/receive/CC2420ReceiveC.nc @@ -78,4 +78,13 @@ implementation { CC2420ReceiveP.PacketTimeStamp -> CC2420PacketC; CC2420ReceiveP.CC2420Config -> CC2420ControlC; + CC2420ReceiveP.SECCTRL0 -> Spi.SECCTRL0; + CC2420ReceiveP.SECCTRL1 -> Spi.SECCTRL1; + CC2420ReceiveP.SRXDEC -> Spi.SRXDEC; + CC2420ReceiveP.RXNONCE -> Spi.RXNONCE; + CC2420ReceiveP.KEY0 -> Spi.KEY0; + CC2420ReceiveP.KEY1 -> Spi.KEY1; + CC2420ReceiveP.RXFIFO_RAM -> Spi.RXFIFO_RAM; + CC2420ReceiveP.SNOP -> Spi.SNOP; + } diff --git a/tos/chips/cc2420/receive/CC2420ReceiveP.nc b/tos/chips/cc2420/receive/CC2420ReceiveP.nc index 5bd4e852..80fe56d0 100644 --- a/tos/chips/cc2420/receive/CC2420ReceiveP.nc +++ b/tos/chips/cc2420/receive/CC2420ReceiveP.nc @@ -33,6 +33,8 @@ * @author Jonathan Hui * @author David Moss * @author Jung Il Choi + * @author JeongGil Ko + * @author Razvan Musaloiu-E * @version $Revision$ $Date$ */ @@ -62,6 +64,15 @@ module CC2420ReceiveP @safe() { uses interface CC2420Config; uses interface PacketTimeStamp; + uses interface CC2420Strobe as SRXDEC; + uses interface CC2420Register as SECCTRL0; + uses interface CC2420Register as SECCTRL1; + uses interface CC2420Ram as KEY0; + uses interface CC2420Ram as KEY1; + uses interface CC2420Ram as RXNONCE; + uses interface CC2420Ram as RXFIFO_RAM; + uses interface CC2420Strobe as SNOP; + uses interface Leds; } @@ -71,6 +82,8 @@ implementation { S_STOPPED, S_STARTED, S_RX_LENGTH, + S_RX_DEC, + S_RX_DEC_WAIT, S_RX_FCF, S_RX_PAYLOAD, } cc2420_receive_state_t; @@ -88,8 +101,12 @@ implementation { uint8_t m_timestamp_size; /** Number of packets we missed because we were doing something else */ +#ifdef CC2420_HW_SECURITY + norace uint8_t m_missed_packets; +#else uint8_t m_missed_packets; - +#endif + /** TRUE if we are receiving a valid packet into the stack */ bool receivingPacket; @@ -101,9 +118,22 @@ implementation { norace message_t* ONE_NOK m_p_rx_buf; message_t m_rx_buf; - +#ifdef CC2420_HW_SECURITY + norace cc2420_receive_state_t m_state; +#else cc2420_receive_state_t m_state; - +#endif + norace uint8_t packetLength = 0; + norace uint8_t pos = 0; + norace uint8_t secHdrPos = 0; + uint8_t nonceValue[16] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + norace uint8_t skip; + norace uint8_t securityOn = 0; + norace uint8_t authentication = 0; + norace uint8_t micLength = 0; + uint8_t flush_flag = 0; + uint16_t startTime = 0; + /***************** Prototypes ****************/ void reset_state(); void beginReceive(); @@ -111,9 +141,11 @@ implementation { void waitForNextPacket(); void flush(); bool passesAddressCheck(message_t * ONE msg); - + void beginDec(); + void dec(); + task void receiveDone_task(); - + /***************** Init Commands ****************/ command error_t Init.init() { m_p_rx_buf = &m_rx_buf; @@ -178,17 +210,310 @@ implementation { /***************** InterruptFIFOP Events ****************/ async event void InterruptFIFOP.fired() { if ( m_state == S_STARTED ) { +#ifndef CC2420_HW_SECURITY + m_state = S_RX_LENGTH; beginReceive(); - +#else + m_state = S_RX_DEC; + atomic receivingPacket = TRUE; + beginDec(); +#endif } else { m_missed_packets++; } } + + /*****************Decryption Options*********************/ +#ifdef CC2420_HW_SECURITY + task void waitTask(){ + + if(SECURITYLOCK == 1){ + post waitTask(); + }else{ + m_state = S_RX_DEC; + beginDec(); + } + } + + void beginDec(){ + if(call SpiResource.isOwner()) { + dec(); + } else if (call SpiResource.immediateRequest() == SUCCESS) { + dec(); + } else { + call SpiResource.request(); + } + } + + norace uint8_t decLoopCount = 0; + + task void waitDecTask(){ + + cc2420_status_t status; + + call CSN.clr(); + status = call SNOP.strobe(); + call CSN.set(); + + atomic decLoopCount ++; + + if(decLoopCount > 10){ + call CSN.clr(); + atomic call SECCTRL0.write((0 << CC2420_SECCTRL0_SEC_MODE) | + (0 << CC2420_SECCTRL0_SEC_M) | + (0 << CC2420_SECCTRL0_SEC_RXKEYSEL) | + (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) | + (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ; + call CSN.set(); + SECURITYLOCK = 0; + call SpiResource.release(); + atomic flush_flag = 1; + beginReceive(); + }else if(status & CC2420_STATUS_ENC_BUSY){ + post waitDecTask(); + }else{ + call CSN.clr(); + atomic call SECCTRL0.write((0 << CC2420_SECCTRL0_SEC_MODE) | + (0 << CC2420_SECCTRL0_SEC_M) | + (0 << CC2420_SECCTRL0_SEC_RXKEYSEL) | + (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) | + (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ; + call CSN.set(); + SECURITYLOCK = 0; + call SpiResource.release(); + beginReceive(); + } + + } + + void waitDec(){ + cc2420_status_t status; + call CSN.clr(); + status = call SNOP.strobe(); + call CSN.set(); + + if(status & CC2420_STATUS_ENC_BUSY){ + atomic decLoopCount = 1; + post waitDecTask(); + }else{ + call CSN.clr(); + atomic call SECCTRL0.write((0 << CC2420_SECCTRL0_SEC_MODE) | + (0 << CC2420_SECCTRL0_SEC_M) | + (0 << CC2420_SECCTRL0_SEC_RXKEYSEL) | + (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) | + (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ; + call CSN.set(); + SECURITYLOCK = 0; + call SpiResource.release(); + beginReceive(); + } + } + + void dec(){ + cc2420_header_t header; + security_header_t secHdr; + uint8_t mode, key, temp, crc; + + atomic pos = (packetLength+pos)%RXFIFO_SIZE; + atomic secHdrPos = (pos+10)%RXFIFO_SIZE; + + if (pos + 3 > RXFIFO_SIZE){ + temp = RXFIFO_SIZE - pos; + call CSN.clr(); + atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, temp); + call CSN.set(); + call CSN.clr(); + atomic call RXFIFO_RAM.read(0,(uint8_t*)&header+temp, 3-temp); + call CSN.set(); + }else{ + call CSN.clr(); + atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, 3); + call CSN.set(); + } + + packetLength = header.length+1; + + if(packetLength == 6){ // ACK packet + m_state = S_RX_LENGTH; + call SpiResource.release(); + beginReceive(); + return; + } + + if (pos + sizeof(cc2420_header_t) > RXFIFO_SIZE){ + temp = RXFIFO_SIZE - pos; + call CSN.clr(); + atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, temp); + call CSN.set(); + call CSN.clr(); + atomic call RXFIFO_RAM.read(0,(uint8_t*)&header+temp, sizeof(cc2420_header_t)-temp); + call CSN.set(); + }else{ + call CSN.clr(); + atomic call RXFIFO_RAM.read(pos,(uint8_t*)&header, sizeof(cc2420_header_t)); + call CSN.set(); + } + + if (pos+header.length+1 > RXFIFO_SIZE){ + temp = header.length - (RXFIFO_SIZE - pos); + call CSN.clr(); + atomic call RXFIFO_RAM.read(temp,&crc, 1); + call CSN.set(); + }else{ + call CSN.clr(); + atomic call RXFIFO_RAM.read(pos+header.length,&crc, 1); + call CSN.set(); + } + + if(header.length+1 > RXFIFO_SIZE || !(crc << 7)){ + atomic flush_flag = 1; + m_state = S_RX_LENGTH; + call SpiResource.release(); + beginReceive(); + return; + } + if( (header.fcf & (1 << IEEE154_FCF_SECURITY_ENABLED)) && (crc << 7) ){ + if(call CC2420Config.isAddressRecognitionEnabled()){ + if(!(header.dest==call CC2420Config.getShortAddr() || header.dest==AM_BROADCAST_ADDR)){ + packetLength = header.length + 1; + m_state = S_RX_LENGTH; + call SpiResource.release(); + beginReceive(); + return; + } + } + if(SECURITYLOCK == 1){ + call SpiResource.release(); + post waitTask(); + return; + }else{ + //We are going to decrypt so lock the registers + atomic SECURITYLOCK = 1; + + if (secHdrPos + sizeof(security_header_t) > RXFIFO_SIZE){ + temp = RXFIFO_SIZE - secHdrPos; + call CSN.clr(); + atomic call RXFIFO_RAM.read(secHdrPos,(uint8_t*)&secHdr, temp); + call CSN.set(); + call CSN.clr(); + atomic call RXFIFO_RAM.read(0,(uint8_t*)&secHdr+temp, sizeof(security_header_t) - temp); + call CSN.set(); + } else { + call CSN.clr(); + atomic call RXFIFO_RAM.read(secHdrPos,(uint8_t*)&secHdr, sizeof(security_header_t)); + call CSN.set(); + } + + key = secHdr.keyID[0]; + + if (secHdr.secLevel == NO_SEC){ + mode = CC2420_NO_SEC; + micLength = 0; + }else if (secHdr.secLevel == CBC_MAC_4){ + mode = CC2420_CBC_MAC; + micLength = 4; + }else if (secHdr.secLevel == CBC_MAC_8){ + mode = CC2420_CBC_MAC; + micLength = 8; + }else if (secHdr.secLevel == CBC_MAC_16){ + mode = CC2420_CBC_MAC; + micLength = 16; + }else if (secHdr.secLevel == CTR){ + mode = CC2420_CTR; + micLength = 0; + }else if (secHdr.secLevel == CCM_4){ + mode = CC2420_CCM; + micLength = 4; + }else if (secHdr.secLevel == CCM_8){ + mode = CC2420_CCM; + micLength = 8; + }else if (secHdr.secLevel == CCM_16){ + mode = CC2420_CCM; + micLength = 16; + }else{ + atomic SECURITYLOCK = 0; + packetLength = header.length + 1; + m_state = S_RX_LENGTH; + call SpiResource.release(); + beginReceive(); + return; + } + + if(mode < 4 && mode > 0) { // if mode is valid - + securityOn = 1; + + memcpy(&nonceValue[3], &(secHdr.frameCounter), 4); + skip = secHdr.reserved; + + if(mode == CC2420_CBC_MAC || mode == CC2420_CCM){ + authentication = 1; + call CSN.clr(); + atomic call SECCTRL0.write((mode << CC2420_SECCTRL0_SEC_MODE) | + ((micLength-2)/2 << CC2420_SECCTRL0_SEC_M) | + (key << CC2420_SECCTRL0_SEC_RXKEYSEL) | + (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) | + (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ; + call CSN.set(); + }else{ + call CSN.clr(); + atomic call SECCTRL0.write((mode << CC2420_SECCTRL0_SEC_MODE) | + (1 << CC2420_SECCTRL0_SEC_M) | + (key << CC2420_SECCTRL0_SEC_RXKEYSEL) | + (1 << CC2420_SECCTRL0_SEC_CBC_HEAD) | + (1 << CC2420_SECCTRL0_RXFIFO_PROTECTION)) ; + call CSN.set(); + } + + call CSN.clr(); +#ifndef TFRAMES_ENABLED + atomic call SECCTRL1.write(skip+11+sizeof(security_header_t))+((skip+11+sizeof(security_header_t))<<8); +#else + atomic call SECCTRL1.write(skip+10+sizeof(security_header_t))+((skip+10+sizeof(security_header_t))<<8); +#endif + call CSN.set(); + + call CSN.clr(); + atomic call RXNONCE.write(0, nonceValue, 16); + call CSN.set(); + + call CSN.clr(); + atomic call SRXDEC.strobe(); + call CSN.set(); + + atomic decLoopCount = 0; + post waitDecTask(); + return; + + }else{ + atomic SECURITYLOCK = 0; + packetLength = header.length + 1; + m_state = S_RX_LENGTH; + call SpiResource.release(); + beginReceive(); + return; + } + } + }else{ + packetLength = header.length + 1; + m_state = S_RX_LENGTH; + call SpiResource.release(); + beginReceive(); + return; + } + } +#endif /***************** SpiResource Events ****************/ event void SpiResource.granted() { +#ifdef CC2420_HW_SECURITY + if(m_state == S_RX_DEC){ + dec(); + }else{ + receive(); + } +#else receive(); +#endif } /***************** RXFIFO Events ****************/ @@ -207,7 +532,8 @@ implementation { case S_RX_LENGTH: m_state = S_RX_FCF; - if ( rxFrameLength + 1 > m_bytes_left ) { + packetLength = rxFrameLength+1; + if ( rxFrameLength + 1 > m_bytes_left || flush_flag == 1) { // Length of this packet is bigger than the RXFIFO, flush it out. flush(); @@ -266,20 +592,19 @@ implementation { call SACK.strobe(); call CSN.set(); call CSN.clr(); - call RXFIFO.beginRead(buf + 1 + SACK_HEADER_LENGTH, - rxFrameLength - SACK_HEADER_LENGTH); + call RXFIFO.beginRead(buf + 1 + SACK_HEADER_LENGTH, + rxFrameLength - SACK_HEADER_LENGTH); return; } } - // Didn't flip CSn, we're ok to continue reading. call RXFIFO.continueRead(buf + 1 + SACK_HEADER_LENGTH, - rxFrameLength - SACK_HEADER_LENGTH); + rxFrameLength - SACK_HEADER_LENGTH); break; - + case S_RX_PAYLOAD: + call CSN.set(); - if(!m_missed_packets) { // Release the SPI only if there are no more frames to download call SpiResource.release(); @@ -342,20 +667,32 @@ implementation { uint8_t length = header->length; uint8_t tmpLen __DEPUTY_UNUSED__ = sizeof(message_t) - (offsetof(message_t, data) - sizeof(cc2420_header_t)); uint8_t* COUNT(tmpLen) buf = TCAST(uint8_t* COUNT(tmpLen), header); - + metadata->crc = buf[ length ] >> 7; metadata->lqi = buf[ length ] & 0x7f; metadata->rssi = buf[ length - 1 ]; - + if (passesAddressCheck(m_p_rx_buf) && length >= CC2420_SIZE) { +#ifdef CC2420_HW_SECURITY + if(securityOn == 1){ + if(m_missed_packets > 0){ + m_missed_packets --; + } + if(authentication){ + length -= micLength; + } + } + micLength = 0; + securityOn = 0; + authentication = 0; +#endif m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data, length - CC2420_SIZE); } - atomic receivingPacket = FALSE; waitForNextPacket(); } - + /****************** CC2420Config Events ****************/ event void CC2420Config.syncDone( error_t error ) { } @@ -366,7 +703,6 @@ implementation { */ void beginReceive() { m_state = S_RX_LENGTH; - atomic receivingPacket = TRUE; if(call SpiResource.isOwner()) { receive(); @@ -383,7 +719,14 @@ implementation { * Flush out the Rx FIFO */ void flush() { + flush_flag = 0; + pos =0; + packetLength =0; + micLength = 0; + securityOn = 0; + authentication = 0; reset_state(); + call CSN.set(); call CSN.clr(); call SFLUSHRX.strobe(); @@ -427,14 +770,20 @@ implementation { * If the line stays low without generating an interrupt, that means * there's still more data to be received. */ + if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) { // A new packet is buffered up and ready to go if ( m_missed_packets ) { m_missed_packets--; } - - beginReceive(); - +#ifdef CC2420_HW_SECURITY + call SpiResource.release(); + m_state = S_RX_DEC; + beginDec(); +#else + beginReceive(); +#endif + } else { // Wait for the next packet to arrive m_state = S_STARTED; @@ -468,4 +817,5 @@ implementation { return (header->dest == call CC2420Config.getShortAddr() || header->dest == AM_BROADCAST_ADDR); } + } diff --git a/tos/chips/cc2420/security/CC2420KeysC.nc b/tos/chips/cc2420/security/CC2420KeysC.nc new file mode 100644 index 00000000..ab995ff9 --- /dev/null +++ b/tos/chips/cc2420/security/CC2420KeysC.nc @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2008 Johns Hopkins University. +* All rights reserved. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation for any purpose, without fee, and without written +* agreement is hereby granted, provided that the above copyright +* notice, the (updated) modification history and the author appear in +* all copies of this source code. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, +* OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @author JeongGil Ko + * @author Razvan Musaloiu-E. + * @author Jong Hyun Lim + */ + +configuration CC2420KeysC +{ + provides interface CC2420Keys; +} + +implementation +{ + components new CC2420SpiC(); + components HplCC2420PinsC as Pins; + components CC2420KeysP; + + CC2420Keys = CC2420KeysP; + + CC2420KeysP.CSN -> Pins.CSN; + CC2420KeysP.KEY0 -> CC2420SpiC.KEY0; + CC2420KeysP.KEY1 -> CC2420SpiC.KEY1; + CC2420KeysP.Resource -> CC2420SpiC.Resource; +} diff --git a/tos/chips/cc2420/security/CC2420KeysP.nc b/tos/chips/cc2420/security/CC2420KeysP.nc new file mode 100644 index 00000000..bf0348cc --- /dev/null +++ b/tos/chips/cc2420/security/CC2420KeysP.nc @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2008 Johns Hopkins University. +* All rights reserved. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation for any purpose, without fee, and without written +* agreement is hereby granted, provided that the above copyright +* notice, the (updated) modification history and the author appear in +* all copies of this source code. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, +* OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @author JeongGil Ko + * @author Razvan Musaloiu-E. + * @author Jong Hyun Lim + */ + +module CC2420KeysP +{ + provides interface CC2420Keys; + + uses { + interface GeneralIO as CSN; + interface CC2420Ram as KEY0; + interface CC2420Ram as KEY1; + interface Resource; + } +} + +implementation +{ + uint8_t *currentKey = NULL; + bool currentKeyNo; + + task void resourceReq() + { + error_t error; + error = call Resource.immediateRequest(); + if(error != SUCCESS){ + post resourceReq(); + } + } + + command error_t CC2420Keys.setKey(uint8_t keyNo, uint8_t* key) + { + if (currentKey != NULL || keyNo > 1) { + return FAIL; + } + currentKey = key; + currentKeyNo = keyNo; + + if(call Resource.request() != SUCCESS){ + post resourceReq(); + } + + return SUCCESS; + } + + event void Resource.granted() + { + if (currentKeyNo) { + call CSN.clr(); + call KEY1.write(0, currentKey, 16); + call CSN.set(); + } else { + call CSN.clr(); + call KEY0.write(0, currentKey, 16); + call CSN.set(); + } + call Resource.release(); + currentKey = NULL; + signal CC2420Keys.setKeyDone(currentKeyNo, currentKey); + } +} diff --git a/tos/chips/cc2420/security/SecAMSenderC.nc b/tos/chips/cc2420/security/SecAMSenderC.nc new file mode 100644 index 00000000..99405fc4 --- /dev/null +++ b/tos/chips/cc2420/security/SecAMSenderC.nc @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2008 Johns Hopkins University. +* All rights reserved. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation for any purpose, without fee, and without written +* agreement is hereby granted, provided that the above copyright +* notice, the (updated) modification history and the author appear in +* all copies of this source code. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, +* OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @author JeongGil Ko + * @author Razvan Musaloiu-E. + * @author Jong Hyun Lim + */ + +generic configuration SecAMSenderC(am_id_t id) +{ + provides { + interface AMSend; + interface Packet; + interface AMPacket; + interface PacketAcknowledgements as Acks; + interface CC2420SecurityMode; + } +} + +implementation +{ + components ActiveMessageC; + components NoLedsC; + components LedsC; + components new CC2420SpiC(); + components CC2420ActiveMessageC; + components new AMSenderC(id); + components new SecAMSenderP(id); + + AMSend = SecAMSenderP.AMSend; + Packet = AMSenderC; + Acks = CC2420ActiveMessageC; + AMPacket = CC2420ActiveMessageC; + CC2420SecurityMode = SecAMSenderP; + + SecAMSenderP.SubAMSend -> AMSenderC; + SecAMSenderP.SecurityPacket -> AMSenderC; + SecAMSenderP.Leds -> NoLedsC; +} diff --git a/tos/chips/cc2420/security/SecAMSenderP.nc b/tos/chips/cc2420/security/SecAMSenderP.nc new file mode 100644 index 00000000..3d8d2ac4 --- /dev/null +++ b/tos/chips/cc2420/security/SecAMSenderP.nc @@ -0,0 +1,174 @@ +/* +* Copyright (c) 2008 Johns Hopkins University. +* All rights reserved. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation for any purpose, without fee, and without written +* agreement is hereby granted, provided that the above copyright +* notice, the (updated) modification history and the author appear in +* all copies of this source code. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, +* OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @author JeongGil Ko + * @author Razvan Musaloiu-E. + * @author Jong Hyun Lim + */ + +generic module SecAMSenderP(am_id_t id) +{ + provides { + interface AMSend; + interface CC2420SecurityMode; + } + + uses { + interface AMSend as SubAMSend; + interface Packet as SecurityPacket; + interface AMPacket; + interface Leds; + } +} + +implementation +{ + uint32_t nonceCounter = 0; + uint8_t secLevel = NO_SEC; + uint8_t keyIndex = 0; + uint8_t reserved = 0; // skip in cc2420 implementations + uint8_t micLength = 0; + uint8_t length; + + command error_t AMSend.send(am_addr_t addr, message_t* msg, uint8_t len) + { + cc2420_header_t* hdr = (cc2420_header_t*)msg->header; + security_header_t* secHdr = (security_header_t*)&hdr->secHdr; + + if(secHdr->secLevel == CBC_MAC_4 || secHdr->secLevel == CCM_4){ + micLength = 4; + }else if(secHdr->secLevel == CBC_MAC_8 || secHdr->secLevel == CCM_8){ + micLength = 8; + }else if(secHdr->secLevel == CBC_MAC_16 || secHdr->secLevel == CCM_16){ + micLength = 16; + } + + return call SubAMSend.send(addr, msg, len + (((secHdr->secLevel >= CBC_MAC_4 && secHdr->secLevel <= CBC_MAC_16) || (secHdr->secLevel >= CCM_4 && secHdr->secLevel <= CCM_16)) ? micLength : 0)); + } + + command uint8_t AMSend.maxPayloadLength() + { + return call SecurityPacket.maxPayloadLength(); + } + + command void* AMSend.getPayload(message_t* msg, uint8_t len) + { + return call SecurityPacket.getPayload(msg, len); + } + + command error_t AMSend.cancel(message_t* msg) { return call SubAMSend.cancel(msg); } + event void SubAMSend.sendDone(message_t *msg, error_t error) { signal AMSend.sendDone(msg, error); } + + + + + command error_t CC2420SecurityMode.setCtr(message_t* msg, uint8_t setKey, uint8_t setSkip) + { + cc2420_header_t* hdr = (cc2420_header_t*)msg->header; + security_header_t* secHdr = (security_header_t*)&hdr->secHdr; + + if (setKey > 1 || setSkip > 7){ + return FAIL; + } + secLevel = CTR; + keyIndex = setKey; + reserved = setSkip; + + nonceCounter++; + + secHdr->secLevel = secLevel; + secHdr->keyMode = 1; // Fixed to 1 for now + secHdr->reserved = reserved; //skip in cc2420 + secHdr->frameCounter = nonceCounter; + secHdr->keyID[0] = keyIndex; // Always first position for now due to fixed keyMode + hdr->fcf |= 1 << IEEE154_FCF_SECURITY_ENABLED; + return SUCCESS; + } + + + + command error_t CC2420SecurityMode.setCbcMac(message_t* msg, uint8_t setKey, uint8_t setSkip, uint8_t size) + { + cc2420_header_t* hdr = (cc2420_header_t*)msg->header; + security_header_t* secHdr = (security_header_t*)&hdr->secHdr; + + if (setKey > 1 || (size != 4 && size != 8 && size != 16) || (setSkip > 7)){ + return FAIL; + } + + if(size == 4) + secLevel = CBC_MAC_4; + else if (size == 8) + secLevel = CBC_MAC_8; + else if (size == 16) + secLevel = CBC_MAC_16; + else + return FAIL; + keyIndex = setKey; + reserved = setSkip; + + nonceCounter++; + + secHdr->secLevel = secLevel; + secHdr->keyMode = 1; // Fixed to 1 for now + secHdr->reserved = reserved; //skip in cc2420 + secHdr->frameCounter = nonceCounter; + secHdr->keyID[0] = keyIndex; // Always first position for now due to fixed keyMode + hdr->fcf |= 1 << IEEE154_FCF_SECURITY_ENABLED; + + return SUCCESS; + } + + + command error_t CC2420SecurityMode.setCcm(message_t* msg, uint8_t setKey, uint8_t setSkip, uint8_t size) + { + cc2420_header_t* hdr = (cc2420_header_t*)msg->header; + security_header_t* secHdr = (security_header_t*)&hdr->secHdr; + + if (setKey > 1 || (size != 4 && size != 8 && size != 16) || (setSkip > 7)){ + return FAIL; + } + + if(size == 4) + secLevel = CCM_4; + else if (size == 8) + secLevel = CCM_8; + else if (size == 16) + secLevel = CCM_16; + else + return FAIL; + keyIndex = setKey; + reserved = setSkip; + + nonceCounter++; + + secHdr->secLevel = secLevel; + secHdr->keyMode = 1; // Fixed to 1 for now + secHdr->reserved = reserved; //skip in cc2420 + secHdr->frameCounter = nonceCounter; + secHdr->keyID[0] = keyIndex; // Always first position for now due to fixed keyMode + hdr->fcf |= 1 << IEEE154_FCF_SECURITY_ENABLED; + + return SUCCESS; + } +} diff --git a/tos/chips/cc2420/spi/CC2420SpiC.nc b/tos/chips/cc2420/spi/CC2420SpiC.nc index 50e015e9..582b46af 100644 --- a/tos/chips/cc2420/spi/CC2420SpiC.nc +++ b/tos/chips/cc2420/spi/CC2420SpiC.nc @@ -86,6 +86,12 @@ generic configuration CC2420SpiC() { provides interface CC2420Ram as PANID; provides interface CC2420Ram as SHORTADR; provides interface CC2420Ram as TXFIFO_RAM; + provides interface CC2420Ram as RXFIFO_RAM; + provides interface CC2420Ram as KEY0; + provides interface CC2420Ram as KEY1; + provides interface CC2420Ram as SABUF; + provides interface CC2420Ram as TXNONCE; + provides interface CC2420Ram as RXNONCE; // fifos provides interface CC2420Fifo as RXFIFO; @@ -150,6 +156,12 @@ implementation { PANID = Spi.Ram[ CC2420_RAM_PANID ]; SHORTADR = Spi.Ram[ CC2420_RAM_SHORTADR ]; TXFIFO_RAM = Spi.Ram[ CC2420_RAM_TXFIFO ]; + RXFIFO_RAM = Spi.Ram[ CC2420_RAM_RXFIFO ]; + KEY0 = Spi.Ram[ CC2420_RAM_KEY0 ]; + KEY1 = Spi.Ram[ CC2420_RAM_KEY1 ]; + SABUF = Spi.Ram[ CC2420_RAM_SABUF ]; + TXNONCE = Spi.Ram[ CC2420_RAM_TXNONCE ]; + RXNONCE = Spi.Ram[ CC2420_RAM_RXNONCE ]; // fifos RXFIFO = Spi.Fifo[ CC2420_RXFIFO ]; diff --git a/tos/chips/cc2420/transmit/CC2420TransmitC.nc b/tos/chips/cc2420/transmit/CC2420TransmitC.nc index 8624d981..bb79ee1b 100644 --- a/tos/chips/cc2420/transmit/CC2420TransmitC.nc +++ b/tos/chips/cc2420/transmit/CC2420TransmitC.nc @@ -84,6 +84,12 @@ implementation { CC2420TransmitP.TXFIFO -> Spi.TXFIFO; CC2420TransmitP.TXFIFO_RAM -> Spi.TXFIFO_RAM; CC2420TransmitP.MDMCTRL1 -> Spi.MDMCTRL1; + CC2420TransmitP.SECCTRL0 -> Spi.SECCTRL0; + CC2420TransmitP.SECCTRL1 -> Spi.SECCTRL1; + CC2420TransmitP.STXENC -> Spi.STXENC; + CC2420TransmitP.TXNONCE -> Spi.TXNONCE; + CC2420TransmitP.KEY0 -> Spi.KEY0; + CC2420TransmitP.KEY1 -> Spi.KEY1; components CC2420ReceiveC; CC2420TransmitP.CC2420Receive -> CC2420ReceiveC; @@ -96,4 +102,5 @@ implementation { components LedsC; CC2420TransmitP.Leds -> LedsC; + } diff --git a/tos/chips/cc2420/transmit/CC2420TransmitP.nc b/tos/chips/cc2420/transmit/CC2420TransmitP.nc index a8367e54..d51cd72d 100644 --- a/tos/chips/cc2420/transmit/CC2420TransmitP.nc +++ b/tos/chips/cc2420/transmit/CC2420TransmitP.nc @@ -33,6 +33,8 @@ * @author Jonathan Hui * @author David Moss * @author Jung Il Choi Initial SACK implementation + * @author JeongGil Ko + * @author Razvan Musaloiu-E * @version $Revision$ $Date$ */ @@ -71,6 +73,13 @@ module CC2420TransmitP @safe() { uses interface CC2420Strobe as SFLUSHTX; uses interface CC2420Register as MDMCTRL1; + uses interface CC2420Strobe as STXENC; + uses interface CC2420Register as SECCTRL0; + uses interface CC2420Register as SECCTRL1; + uses interface CC2420Ram as KEY0; + uses interface CC2420Ram as KEY1; + uses interface CC2420Ram as TXNONCE; + uses interface CC2420Receive; uses interface Leds; } @@ -96,6 +105,12 @@ implementation { enum { CC2420_ABORT_PERIOD = 320 }; + + uint16_t startTime = 0; + norace uint8_t secCtrlMode = 0; + norace uint8_t nonceValue[16] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + norace uint8_t skip; + norace uint16_t CTR_SECCTRL0, CTR_SECCTRL1; norace message_t * ONE_NOK m_msg; @@ -104,6 +119,8 @@ implementation { norace uint8_t m_tx_power; cc2420_transmit_state_t m_state = S_STOPPED; + + uint8_t securityChecked = 0; bool m_receiving = FALSE; @@ -130,6 +147,7 @@ implementation { error_t resend( bool cca ); void loadTXFIFO(); void attemptSend(); + void securityCheck(); void congestionBackoff(); error_t acquireSpiResource(); error_t releaseSpiResource(); @@ -374,7 +392,6 @@ implementation { if ( type == IEEE154_TYPE_ACK && m_msg) { ack_header = call CC2420PacketBody.getHeader( ack_msg ); msg_header = call CC2420PacketBody.getHeader( m_msg ); - if ( m_state == S_ACK_WAIT && msg_header->dsn == ack_header->dsn ) { call BackoffTimer.stop(); @@ -533,6 +550,7 @@ implementation { return FAIL; } + securityChecked = 0; m_state = S_LOAD; m_cca = cca; m_msg = p_msg; @@ -577,7 +595,131 @@ implementation { return SUCCESS; } - +#ifdef CC2420_HW_SECURITY + + /* + inline void uwait(uint16_t u) { + uint16_t t0 = TAR; + while((TAR - t0) <= u); + } + */ + + task void waitTask(){ + call Leds.led2Toggle(); + if(SECURITYLOCK == 1){ + post waitTask(); + }else{ + securityCheck(); + } + } + + void securityCheck(){ + + cc2420_header_t* msg_header; + cc2420_status_t status; + security_header_t* secHdr; + uint8_t mode; + uint8_t key; + uint8_t micLength; + uint16_t currentStatus; + + msg_header = call CC2420PacketBody.getHeader( m_msg ); + + if(!(msg_header->fcf & (1 << IEEE154_FCF_SECURITY_ENABLED))){ + return; + } + + if(SECURITYLOCK == 1){ + post waitTask(); + }else { + //Will perform encryption lock registers + atomic SECURITYLOCK = 1; + + secHdr = (security_header_t*) &msg_header->secHdr; + memcpy(&nonceValue[3], &(secHdr->frameCounter), 4); + + skip = secHdr->reserved; + key = secHdr->keyID[0]; // For now this is the only key selection mode. + + if (secHdr->secLevel == NO_SEC){ + mode = CC2420_NO_SEC; + micLength = 4; + }else if (secHdr->secLevel == CBC_MAC_4){ + mode = CC2420_CBC_MAC; + micLength = 4; + }else if (secHdr->secLevel == CBC_MAC_8){ + mode = CC2420_CBC_MAC; + micLength = 8; + }else if (secHdr->secLevel == CBC_MAC_16){ + mode = CC2420_CBC_MAC; + micLength = 16; + }else if (secHdr->secLevel == CTR){ + mode = CC2420_CTR; + micLength = 4; + }else if (secHdr->secLevel == CCM_4){ + mode = CC2420_CCM; + micLength = 4; + }else if (secHdr->secLevel == CCM_8){ + mode = CC2420_CCM; + micLength = 8; + }else if (secHdr->secLevel == CCM_16){ + mode = CC2420_CCM; + micLength = 16; + }else{ + return; + } + + CTR_SECCTRL0 = ((mode << CC2420_SECCTRL0_SEC_MODE) | + ((micLength-2)/2 << CC2420_SECCTRL0_SEC_M) | + (key << CC2420_SECCTRL0_SEC_TXKEYSEL) | + (1 << CC2420_SECCTRL0_SEC_CBC_HEAD)) ; +#ifndef TFRAMES_ENABLED + CTR_SECCTRL1 = (skip+11+sizeof(security_header_t))+((skip+11+sizeof(security_header_t))<<8); +#else + CTR_SECCTRL1 = (skip+10+sizeof(security_header_t))+((skip+10+sizeof(security_header_t))<<8); +#endif + + call CSN.clr(); + call SECCTRL0.write(CTR_SECCTRL0); + call CSN.set(); + + call CSN.clr(); + call SECCTRL1.write(CTR_SECCTRL1); + call CSN.set(); + + call CSN.clr(); + call TXNONCE.write(0, nonceValue, 16); + call CSN.set(); + + call CSN.clr(); + status = call SNOP.strobe(); + call CSN.set(); + + while(status & CC2420_STATUS_ENC_BUSY){ + //uwait(1*1024); + call CSN.clr(); + status = call SNOP.strobe(); + call CSN.set(); + } + + call CSN.clr(); + call STXENC.strobe(); + call CSN.set(); + + call CSN.clr(); + call SECCTRL0.read(¤tStatus); + call CSN.set(); + + call CSN.clr(); + call SECCTRL0.write(currentStatus && ~(3 << CC2420_SECCTRL0_SEC_MODE)); + call CSN.set(); + + atomic SECURITYLOCK = 0; + + } + } +#endif + /** * Attempt to send the packet we have loaded into the tx buffer on * the radio chip. The STXONCCA will send the packet immediately if @@ -604,10 +746,13 @@ implementation { signal Send.sendDone( m_msg, ECANCEL ); return; } - - +#ifdef CC2420_HW_SECURITY + if(securityChecked != 1){ + securityCheck(); + } + securityChecked = 1; +#endif call CSN.clr(); - status = m_cca ? call STXONCCA.strobe() : call STXON.strobe(); if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) { status = call SNOP.strobe(); @@ -615,11 +760,11 @@ implementation { congestion = FALSE; } } - + m_state = congestion ? S_SAMPLE_CCA : S_SFD; call CSN.set(); } - + if ( congestion ) { totalCcaChecks = 0; releaseSpiResource(); @@ -701,5 +846,6 @@ implementation { call ChipSpiResource.attemptRelease(); signal Send.sendDone( m_msg, err ); } + } diff --git a/tos/platforms/epic/.platform b/tos/platforms/epic/.platform index 5fa10d9e..ff94acc0 100644 --- a/tos/platforms/epic/.platform +++ b/tos/platforms/epic/.platform @@ -26,6 +26,7 @@ push( @includes, qw( %T/chips/cc2420/spi %T/chips/cc2420/transmit %T/chips/cc2420/unique + %T/chips/cc2420/security %T/chips/msp430 %T/chips/msp430/adc12 %T/chips/msp430/dma diff --git a/tos/platforms/micaz/.platform b/tos/platforms/micaz/.platform index 33e6f51c..def15d33 100644 --- a/tos/platforms/micaz/.platform +++ b/tos/platforms/micaz/.platform @@ -25,6 +25,7 @@ push( @includes, qw( %T/chips/cc2420/spi %T/chips/cc2420/transmit %T/chips/cc2420/unique + %T/chips/cc2420/security %T/platforms/mica2/chips/at45db %T/platforms/mica/chips/at45db %T/chips/at45db diff --git a/tos/platforms/telosb/.platform b/tos/platforms/telosb/.platform index 5fab8f26..25c6401c 100644 --- a/tos/platforms/telosb/.platform +++ b/tos/platforms/telosb/.platform @@ -25,6 +25,7 @@ push( @includes, qw( %T/chips/cc2420/spi %T/chips/cc2420/transmit %T/chips/cc2420/unique + %T/chips/cc2420/security %T/chips/msp430 %T/chips/msp430/adc12 %T/chips/msp430/dma -- 2.39.2