]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Adding in cc2420 security support codes
authorjgko <jgko>
Fri, 14 Aug 2009 20:33:43 +0000 (20:33 +0000)
committerjgko <jgko>
Fri, 14 Aug 2009 20:33:43 +0000 (20:33 +0000)
22 files changed:
apps/tests/cc2420/TestSecurity/README.txt [new file with mode: 0644]
apps/tests/cc2420/TestSecurity/RadioCountToLeds1/Makefile [new file with mode: 0644]
apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLeds.h [new file with mode: 0644]
apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsAppC.nc [new file with mode: 0644]
apps/tests/cc2420/TestSecurity/RadioCountToLeds1/RadioCountToLedsC.nc [new file with mode: 0644]
tos/chips/cc2420/CC2420.h
tos/chips/cc2420/CC2420ActiveMessageC.nc
tos/chips/cc2420/csma/CC2420CsmaP.nc
tos/chips/cc2420/interfaces/CC2420Keys.nc [new file with mode: 0644]
tos/chips/cc2420/interfaces/CC2420SecurityMode.nc [new file with mode: 0644]
tos/chips/cc2420/receive/CC2420ReceiveC.nc
tos/chips/cc2420/receive/CC2420ReceiveP.nc
tos/chips/cc2420/security/CC2420KeysC.nc [new file with mode: 0644]
tos/chips/cc2420/security/CC2420KeysP.nc [new file with mode: 0644]
tos/chips/cc2420/security/SecAMSenderC.nc [new file with mode: 0644]
tos/chips/cc2420/security/SecAMSenderP.nc [new file with mode: 0644]
tos/chips/cc2420/spi/CC2420SpiC.nc
tos/chips/cc2420/transmit/CC2420TransmitC.nc
tos/chips/cc2420/transmit/CC2420TransmitP.nc
tos/platforms/epic/.platform
tos/platforms/micaz/.platform
tos/platforms/telosb/.platform

diff --git a/apps/tests/cc2420/TestSecurity/README.txt b/apps/tests/cc2420/TestSecurity/README.txt
new file mode 100644 (file)
index 0000000..061b7f5
--- /dev/null
@@ -0,0 +1,60 @@
+README for TestSecurity
+
+Author/Contact:
+JeongGil Ko <jgko@cs.jhu.edu>
+Razvan Musaloiu-E. <razvanm@cs.jhu.edu>
+Jong Hyun Lim <ljh@cs.jhu.edu>
+
+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 (file)
index 0000000..e7c53eb
--- /dev/null
@@ -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 (file)
index 0000000..404470d
--- /dev/null
@@ -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 (file)
index 0000000..9d7ceb8
--- /dev/null
@@ -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 (file)
index 0000000..91a70b3
--- /dev/null
@@ -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<TMilli> 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;
+    }
+  }
+
+}
index 798107f0ebcb0367ee9e7822cfc8d1b5d0ca095c..bdaefd6b4c5b6cf92a15ad04c0d8ad54af929556 100644 (file)
@@ -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,
index 21734736d9323621bb96db1dce851a46e8985b2e..509bc6fb869de26da15ef36a8911251248e827e5 100644 (file)
@@ -114,5 +114,4 @@ implementation {
   AM.CC2420Config -> CC2420ControlC;
   
   AM.SubBackoff -> CsmaC;
-  
 }
index e67f921763774af7c11d0e2492e7a9973083b020..7c0ef75deda6505e04ea073b4edda864e4807adc 100644 (file)
@@ -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 (file)
index 0000000..aedf58f
--- /dev/null
@@ -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 (file)
index 0000000..dca7a40
--- /dev/null
@@ -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);
+}
index 14c723f6e68f31f9e1c5a6407f7dbdfeadff40f5..f659a9e11f549729f4fa766e757f0d7d68c54ae1 100644 (file)
@@ -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;
+
 }
index 5bd4e852e54eb383c85a67d7be24b94a80e15a47..80fe56d03acf39a5099cd227bce89c4a99ecedc9 100644 (file)
@@ -33,6 +33,8 @@
  * @author Jonathan Hui <jhui@archrock.com>
  * @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<T32khz,uint32_t>;
 
+  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 (file)
index 0000000..ab995ff
--- /dev/null
@@ -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 (file)
index 0000000..bf0348c
--- /dev/null
@@ -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 (file)
index 0000000..99405fc
--- /dev/null
@@ -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 (file)
index 0000000..3d8d2ac
--- /dev/null
@@ -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;
+  }
+}
index 50e015e9a9bc3ccbf899c925dedebd6bf689854c..582b46af58d34c405ae667b2aa17fff47091713b 100644 (file)
@@ -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 ];
index 8624d981ed92dd30e1fb102bac78daaea25f123b..bb79ee1b1c92344a1c4d822758147861c555fa88 100644 (file)
@@ -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;
+
 }
index a8367e54c99f0342df952fd65fda1dc59baf2e5c..d51cd72dccc3415fcd2c052b1b7efe2bdfc48e5b 100644 (file)
@@ -33,6 +33,8 @@
  * @author Jonathan Hui <jhui@archrock.com>
  * @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(&currentStatus);
+      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 );
   }
+
 }
 
index 5fa10d9e8adbcd6d3ce794db7690990272f02a25..ff94acc039b45708ad702b4094c26b560b88fce8 100644 (file)
@@ -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
index 33e6f51cd653c11bc3689364b8e266f18c2ce8cf..def15d339b413b945841313dd8c1c4641ef829dc 100644 (file)
@@ -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
index 5fab8f266ded070330723927cc8cad79f1a27b4d..25c6401cbc070b9c0f4deaa77de138d18f48c0e1 100644 (file)
@@ -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