--- /dev/null
+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.
--- /dev/null
+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)
--- /dev/null
+/*
+ * "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
--- /dev/null
+/*
+ * "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;
+}
--- /dev/null
+/*
+ * "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;
+ }
+ }
+
+}
* 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;
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
#endif
} cc2420_header_t;
-
+
/**
* CC2420 Packet Footer
*/
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,
AM.CC2420Config -> CC2420ControlC;
AM.SubBackoff -> CsmaC;
-
}
}
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 ) |
--- /dev/null
+/*
+* 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);
+}
--- /dev/null
+/*
+* 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);
+}
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;
+
}
* @author Jonathan Hui <jhui@archrock.com>
* @author David Moss
* @author Jung Il Choi
+ * @author JeongGil Ko
+ * @author Razvan Musaloiu-E
* @version $Revision$ $Date$
*/
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;
}
S_STOPPED,
S_STARTED,
S_RX_LENGTH,
+ S_RX_DEC,
+ S_RX_DEC_WAIT,
S_RX_FCF,
S_RX_PAYLOAD,
} cc2420_receive_state_t;
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;
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();
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;
/***************** 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 ****************/
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();
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();
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 ) {
}
*/
void beginReceive() {
m_state = S_RX_LENGTH;
-
atomic receivingPacket = TRUE;
if(call SpiResource.isOwner()) {
receive();
* 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();
* 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;
return (header->dest == call CC2420Config.getShortAddr()
|| header->dest == AM_BROADCAST_ADDR);
}
+
}
--- /dev/null
+/*
+* 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;
+}
--- /dev/null
+/*
+* 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);
+ }
+}
--- /dev/null
+/*
+* 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;
+}
--- /dev/null
+/*
+* 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;
+ }
+}
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;
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 ];
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;
components LedsC;
CC2420TransmitP.Leds -> LedsC;
+
}
* @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$
*/
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;
}
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;
norace uint8_t m_tx_power;
cc2420_transmit_state_t m_state = S_STOPPED;
+
+ uint8_t securityChecked = 0;
bool m_receiving = FALSE;
error_t resend( bool cca );
void loadTXFIFO();
void attemptSend();
+ void securityCheck();
void congestionBackoff();
error_t acquireSpiResource();
error_t releaseSpiResource();
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();
return FAIL;
}
+ securityChecked = 0;
m_state = S_LOAD;
m_cca = cca;
m_msg = p_msg;
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
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();
congestion = FALSE;
}
}
-
+
m_state = congestion ? S_SAMPLE_CCA : S_SFD;
call CSN.set();
}
-
+
if ( congestion ) {
totalCcaChecks = 0;
releaseSpiResource();
call ChipSpiResource.attemptRelease();
signal Send.sendDone( m_msg, err );
}
+
}
%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
%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
%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