Merge pull request #557 from kkrentz/llsec-integration

Integration of Link Layer Security
This commit is contained in:
Adam Dunkels 2014-10-08 15:45:46 +02:00
commit d891d11324
90 changed files with 2895 additions and 795 deletions

View file

@ -106,3 +106,4 @@ env:
- BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502'
- BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm'
- BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja'
- BUILD_TYPE='llsec' MAKE_TARGETS='cooja'

View file

@ -62,7 +62,7 @@ MODULES += core/sys core/dev core/lib
CONTIKI_SOURCEFILES += $(CONTIKIFILES)
CONTIKIDIRS += ${addprefix $(CONTIKI)/core/,dev lib net net/mac net/rime \
CONTIKIDIRS += ${addprefix $(CONTIKI)/core/,dev lib net net/llsec net/mac net/rime \
net/rpl sys cfs ctk lib/ctk loader . }
oname = ${patsubst %.c,%.o,${patsubst %.S,%.o,$(1)}}

View file

@ -73,6 +73,18 @@
/* #define NETSTACK_CONF_MAC csma_driver */
#endif /* NETSTACK_CONF_MAC */
/* NETSTACK_CONF_LLSEC specifies the link layer security driver. */
#ifndef NETSTACK_CONF_LLSEC
#define NETSTACK_CONF_LLSEC nullsec_driver
#endif /* NETSTACK_CONF_LLSEC */
/* To avoid unnecessary complexity, we assume the common case of
a constant LoWPAN-wide IEEE 802.15.4 security level, which
can be specified by defining LLSEC802154_CONF_SECURITY_LEVEL. */
#ifndef LLSEC802154_CONF_SECURITY_LEVEL
#define LLSEC802154_CONF_SECURITY_LEVEL 0
#endif /* LLSEC802154_CONF_SECURITY_LEVEL */
/* NETSTACK_CONF_NETWORK specifies the network layer and can be either
sicslowpan_driver, for IPv6 networking, or rime_driver, for the
custom Rime network stack. */
@ -208,13 +220,12 @@
#define SICSLOWPAN_CONF_FRAG 1
#endif /* SICSLOWPAN_CONF_FRAG */
/* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD specifies the maximum size of
packets before they get fragmented. The default is 127 bytes (the
maximum size of a 802.15.4 frame) - 25 bytes (for the 802.15.4 MAC
layer header). This can be increased for systems with larger packet
sizes. */
/* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is the maximum available size for
frame headers, link layer security-related overhead, as well as
6LoWPAN payload. By default, SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is
127 bytes (MTU of 802.15.4) - 2 bytes (Footer of 802.15.4). */
#ifndef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD (127 - 25)
#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD (127 - 2)
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
/* SICSLOWPAN_CONF_COMPRESSION_THRESHOLD sets a lower threshold for

198
core/lib/aes-128.c Normal file
View file

@ -0,0 +1,198 @@
/* --COPYRIGHT--,BSD
* Copyright (c) 2011, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 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 OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) 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.
* --/COPYRIGHT--*/
/*
* TI_aes_128_encr_only.c
*
* Created on: Nov 3, 2011
* Author: Eric Peeters
*/
/**
* \file
* Wrapped AES-128 implementation from Texas Instruments.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "lib/aes-128.h"
#include <string.h>
static const uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static uint8_t round_keys[11][AES_128_KEY_LENGTH];
/*---------------------------------------------------------------------------*/
/* multiplies by 2 in GF(2) */
static uint8_t
galois_mul2(uint8_t value)
{
if(value >> 7) {
value = value << 1;
return value ^ 0x1b;
} else {
return value << 1;
}
}
/*---------------------------------------------------------------------------*/
static void
set_key(uint8_t *key)
{
uint8_t i;
uint8_t j;
uint8_t rcon;
rcon = 0x01;
memcpy(round_keys[0], key, AES_128_KEY_LENGTH);
for(i = 1; i <= 10; i++) {
round_keys[i][0] = sbox[round_keys[i - 1][13]] ^ round_keys[i - 1][0] ^ rcon;
round_keys[i][1] = sbox[round_keys[i - 1][14]] ^ round_keys[i - 1][1];
round_keys[i][2] = sbox[round_keys[i - 1][15]] ^ round_keys[i - 1][2];
round_keys[i][3] = sbox[round_keys[i - 1][12]] ^ round_keys[i - 1][3];
for(j = 4; j < AES_128_BLOCK_SIZE; j++) {
round_keys[i][j] = round_keys[i - 1][j] ^ round_keys[i][j - 4];
}
rcon = galois_mul2(rcon);
}
}
/*---------------------------------------------------------------------------*/
static void
encrypt(uint8_t *state)
{
uint8_t buf1, buf2, buf3, buf4, round, i;
/* round 0 */
/* AddRoundKey */
for(i = 0; i < AES_128_BLOCK_SIZE; i++) {
state[i] = state[i] ^ round_keys[0][i];
}
for(round = 1; round <= 10; round++) {
/* ByteSub */
for(i = 0; i < AES_128_BLOCK_SIZE; i++) {
state[i] = sbox[state[i]];
}
/* ShiftRow */
buf1 = state[1];
state[1] = state[5];
state[5] = state[9];
state[9] = state[13];
state[13] = buf1;
buf1 = state[2];
buf2 = state[6];
state[2] = state[10];
state[6] = state[14];
state[10] = buf1;
state[14] = buf2;
buf1 = state[15];
state[15] = state[11];
state[11] = state[7];
state[7] = state[3];
state[3] = buf1;
/* last round skips MixColumn */
if(round < 10) {
/* MixColumn */
for(i = 0; i < 4; i++) {
buf4 = (i << 2);
buf1 = state[buf4] ^ state[buf4 + 1] ^ state[buf4 + 2] ^ state[buf4 + 3];
buf2 = state[buf4];
buf3 = state[buf4] ^ state[buf4 + 1];
buf3 = galois_mul2(buf3);
state[buf4] = state[buf4] ^ buf3 ^ buf1;
buf3 = state[buf4 + 1] ^ state[buf4 + 2];
buf3 = galois_mul2(buf3);
state[buf4 + 1] = state[buf4 + 1] ^ buf3 ^ buf1;
buf3 = state[buf4 + 2] ^ state[buf4 + 3];
buf3 = galois_mul2(buf3);
state[buf4 + 2] = state[buf4 + 2] ^ buf3 ^ buf1;
buf3 = state[buf4 + 3] ^ buf2;
buf3 = galois_mul2(buf3);
state[buf4 + 3] = state[buf4 + 3] ^ buf3 ^ buf1;
}
}
/* AddRoundKey */
for(i = 0; i < AES_128_BLOCK_SIZE; i++) {
state[i] = state[i] ^ round_keys[round][i];
}
}
}
/*---------------------------------------------------------------------------*/
void
aes_128_padded_encrypt(uint8_t *plaintext_and_result, uint8_t plaintext_len)
{
uint8_t block[AES_128_BLOCK_SIZE];
memset(block, 0, AES_128_BLOCK_SIZE);
memcpy(block, plaintext_and_result, plaintext_len);
AES_128.encrypt(block);
memcpy(plaintext_and_result, block, plaintext_len);
}
/*---------------------------------------------------------------------------*/
void
aes_128_set_padded_key(uint8_t *key, uint8_t key_len)
{
uint8_t block[AES_128_BLOCK_SIZE];
memset(block, 0, AES_128_BLOCK_SIZE);
memcpy(block, key, key_len);
AES_128.set_key(block);
}
/*---------------------------------------------------------------------------*/
const struct aes_128_driver aes_128_driver = {
set_key,
encrypt
};
/*---------------------------------------------------------------------------*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,44 +32,51 @@
/**
* \file
* Interface to the CC2420 AES encryption/decryption functions
* AES-128.
* \author
* Adam Dunkels <adam@sics.se>
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef CC2420_AES_H_
#define CC2420_AES_H_
#ifndef AES_H_
#define AES_H_
#include "contiki.h"
#define AES_128_BLOCK_SIZE 16
#define AES_128_KEY_LENGTH 16
#ifdef AES_128_CONF
#define AES_128 AES_128_CONF
#else /* AES_128_CONF */
#define AES_128 aes_128_driver
#endif /* AES_128_CONF */
/**
* \brief Setup an AES key
* \param key A pointer to a 16-byte AES key
* \param index The key index: either 0 or 1.
*
* This function sets up an AES key with the CC2420
* chip. The AES key can later be used with the
* cc2420_aes_cipher() function to encrypt or decrypt
* data.
*
* The CC2420 can store two separate keys in its
* memory. The keys are indexed as 0 or 1 and the key
* index is given by the 'index' parameter.
*
* Structure of AES drivers.
*/
void cc2420_aes_set_key(const uint8_t *key, int index);
struct aes_128_driver {
/**
* \brief Sets the current key.
*/
void (* set_key)(uint8_t *key);
/**
* \brief Encrypts.
*/
void (* encrypt)(uint8_t *plaintext_and_result);
};
/**
* \brief Encrypt/decrypt data with AES
* \param data A pointer to the data to be encrypted/decrypted
* \param len The length of the data to be encrypted/decrypted
* \param key_index The key to use. The key must have previously been set up with cc2420_aes_set_key().
*
* This function encrypts/decrypts data with AES. A
* pointer to the data is passed as a parameter, and the
* function overwrites the data with the encrypted data.
*
* \brief Pads the plaintext with zeroes before calling AES_128.encrypt
*/
void cc2420_aes_cipher(uint8_t *data, int len, int key_index);
void aes_128_padded_encrypt(uint8_t *plaintext_and_result, uint8_t plaintext_len);
/**
* \brief Pads the key with zeroes before calling AES_128.set_key
*/
void aes_128_set_padded_key(uint8_t *key, uint8_t key_len);
#endif /* CC2420_AES_H_ */
extern const struct aes_128_driver AES_128;
#endif /* AES_H_ */

View file

@ -155,11 +155,13 @@ void uip_log(char *msg);
/** @} */
/** \brief Size of the 802.15.4 payload (127byte - 25 for MAC header) */
/** \brief Maximum available size for frame headers,
link layer security-related overhead, as well as
6LoWPAN payload. */
#ifdef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
#define MAC_MAX_PAYLOAD SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
#else /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
#define MAC_MAX_PAYLOAD 102
#define MAC_MAX_PAYLOAD (127 - 2)
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
@ -1341,7 +1343,7 @@ send_packet(linkaddr_t *dest)
/* Provide a callback function to receive the result of
a packet transmission. */
NETSTACK_MAC.send(&packet_sent, NULL);
NETSTACK_LLSEC.send(&packet_sent, NULL);
/* If we are sending multiple packets in a row, we need to let the
watchdog know that we are still alive. */
@ -1361,6 +1363,7 @@ static uint8_t
output(const uip_lladdr_t *localdest)
{
int framer_hdrlen;
int max_payload;
/* The MAC address of the destination of the packet */
linkaddr_t dest;
@ -1443,8 +1446,9 @@ output(const uip_lladdr_t *localdest)
#else /* USE_FRAMER_HDRLEN */
framer_hdrlen = 21;
#endif /* USE_FRAMER_HDRLEN */
max_payload = MAC_MAX_PAYLOAD - framer_hdrlen - NETSTACK_LLSEC.get_overhead();
if((int)uip_len - (int)uncomp_hdr_len > (int)MAC_MAX_PAYLOAD - framer_hdrlen - (int)packetbuf_hdr_len) {
if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) {
#if SICSLOWPAN_CONF_FRAG
struct queuebuf *q;
/*
@ -1477,7 +1481,7 @@ output(const uip_lladdr_t *localdest)
/* Copy payload and send */
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8;
packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8;
PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, my_tag);
memcpy(packetbuf_ptr + packetbuf_hdr_len,
(uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len);
@ -1513,7 +1517,7 @@ output(const uip_lladdr_t *localdest)
/* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8;
packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8;
while(processed_ip_out_len < uip_len) {
PRINTFO("sicslowpan output: fragment ");
PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;

View file

@ -64,8 +64,15 @@
typedef union {
unsigned char u8[LINKADDR_SIZE];
#if LINKADDR_SIZE == 2
uint16_t u16;
#endif /* LINKADDR_SIZE == 2 */
} linkaddr_t;
typedef union {
uint8_t u8[8];
uint16_t u16[4];
} linkaddr_extended_t;
/**
* \brief Copy a Rime address

View file

@ -0,0 +1,110 @@
/**
* \addtogroup llsec802154
* @{
*/
/*
* Copyright (c) 2014, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Protects against replay attacks by comparing with the last
* unicast or broadcast frame counter of the sender.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "net/llsec/anti-replay.h"
#include "net/packetbuf.h"
/* This node's current frame counter value */
static uint32_t counter;
/*---------------------------------------------------------------------------*/
void
anti_replay_set_counter(void)
{
frame802154_frame_counter_t reordered_counter;
reordered_counter.u32 = LLSEC802154_HTONL(++counter);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, reordered_counter.u16[0]);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, reordered_counter.u16[1]);
}
/*---------------------------------------------------------------------------*/
uint32_t
anti_replay_get_counter(void)
{
frame802154_frame_counter_t disordered_counter;
disordered_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
disordered_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
return LLSEC802154_HTONL(disordered_counter.u32);
}
/*---------------------------------------------------------------------------*/
void
anti_replay_init_info(struct anti_replay_info *info)
{
info->last_broadcast_counter
= info->last_unicast_counter
= anti_replay_get_counter();
}
/*---------------------------------------------------------------------------*/
int
anti_replay_was_replayed(struct anti_replay_info *info)
{
uint32_t received_counter;
received_counter = anti_replay_get_counter();
if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) {
/* broadcast */
if(received_counter <= info->last_broadcast_counter) {
return 1;
} else {
info->last_broadcast_counter = received_counter;
return 0;
}
} else {
/* unicast */
if(received_counter <= info->last_unicast_counter) {
return 1;
} else {
info->last_unicast_counter = received_counter;
return 0;
}
}
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,79 @@
/**
* \addtogroup llsec802154
* @{
*/
/*
* Copyright (c) 2014, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Interface to anti-replay mechanisms.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef ANTI_REPLAY_H
#define ANTI_REPLAY_H
#include "contiki.h"
struct anti_replay_info {
uint32_t last_broadcast_counter;
uint32_t last_unicast_counter;
};
/**
* \brief Sets the frame counter packetbuf attributes.
*/
void anti_replay_set_counter(void);
/**
* \brief Gets the frame counter from packetbuf.
*/
uint32_t anti_replay_get_counter(void);
/**
* \brief Initializes the anti-replay information about the sender
*/
void anti_replay_init_info(struct anti_replay_info *info);
/**
* \brief Checks if received frame was replayed
* \param last_counters Anti-replay information about the sender
* \retval 0 <-> received frame was not replayed
*/
int anti_replay_was_replayed(struct anti_replay_info *info);
#endif /* ANTI_REPLAY_H */
/** @} */

190
core/net/llsec/ccm.c Normal file
View file

@ -0,0 +1,190 @@
/**
* \addtogroup llsec802154
* @{
*/
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* AES_128-based CCM* implementation.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "net/llsec/ccm.h"
#include "net/llsec/llsec802154.h"
#include "net/packetbuf.h"
#include "lib/aes-128.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
static void
set_nonce(uint8_t *nonce,
uint8_t flags,
const uint8_t *extended_source_address,
uint8_t counter)
{
/* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */
/* flags || extended_source_address || frame_counter || sec_lvl || counter */
nonce[0] = flags;
memcpy(nonce + 1, extended_source_address, 8);
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
nonce[13] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
nonce[14] = 0;
nonce[15] = counter;
}
/*---------------------------------------------------------------------------*/
/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */
static void
ctr_step(const uint8_t *extended_source_address,
uint8_t pos,
uint8_t *m_and_result,
uint8_t m_len,
uint8_t counter)
{
uint8_t a[AES_128_BLOCK_SIZE];
uint8_t i;
set_nonce(a, CCM_ENCRYPTION_FLAGS, extended_source_address, counter);
AES_128.encrypt(a);
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
m_and_result[pos + i] ^= a[i];
}
}
/*---------------------------------------------------------------------------*/
static void
mic(const uint8_t *extended_source_address,
uint8_t *result,
uint8_t mic_len)
{
uint8_t x[AES_128_BLOCK_SIZE];
uint8_t pos;
uint8_t i;
uint8_t a_len;
uint8_t *a;
#if LLSEC802154_USES_ENCRYPTION
uint8_t shall_encrypt;
uint8_t m_len;
uint8_t *m;
shall_encrypt = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2);
if(shall_encrypt) {
a_len = packetbuf_hdrlen();
m_len = packetbuf_datalen();
} else {
a_len = packetbuf_totlen();
m_len = 0;
}
set_nonce(x,
CCM_AUTH_FLAGS(a_len, mic_len),
extended_source_address,
m_len);
#else /* LLSEC802154_USES_ENCRYPTION */
a_len = packetbuf_totlen();
set_nonce(x,
CCM_AUTH_FLAGS(a_len, mic_len),
extended_source_address,
0);
#endif /* LLSEC802154_USES_ENCRYPTION */
AES_128.encrypt(x);
a = packetbuf_hdrptr();
if(a_len) {
x[1] = x[1] ^ a_len;
for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= a[i - 2];
}
AES_128.encrypt(x);
pos = 14;
while(pos < a_len) {
for(i = 0; (pos + i < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= a[pos + i];
}
pos += AES_128_BLOCK_SIZE;
AES_128.encrypt(x);
}
}
#if LLSEC802154_USES_ENCRYPTION
if(shall_encrypt) {
m = a + a_len;
pos = 0;
while(pos < m_len) {
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= m[pos + i];
}
pos += AES_128_BLOCK_SIZE;
AES_128.encrypt(x);
}
}
#endif /* LLSEC802154_USES_ENCRYPTION */
ctr_step(extended_source_address, 0, x, AES_128_BLOCK_SIZE, 0);
memcpy(result, x, mic_len);
}
/*---------------------------------------------------------------------------*/
static void
ctr(const uint8_t *extended_source_address)
{
uint8_t m_len;
uint8_t *m;
uint8_t pos;
uint8_t counter;
m_len = packetbuf_datalen();
m = (uint8_t *) packetbuf_dataptr();
pos = 0;
counter = 1;
while(pos < m_len) {
ctr_step(extended_source_address, pos, m, m_len, counter++);
pos += AES_128_BLOCK_SIZE;
}
}
/*---------------------------------------------------------------------------*/
const struct ccm_driver ccm_driver = {
mic,
ctr
};
/*---------------------------------------------------------------------------*/
/** @} */

85
core/net/llsec/ccm.h Normal file
View file

@ -0,0 +1,85 @@
/**
* \addtogroup llsec802154
* @{
*/
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* CCM* header file.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef CCM_H_
#define CCM_H_
#include "contiki.h"
#include "net/mac/frame802154.h"
/* see RFC 3610 */
#define CCM_AUTH_FLAGS(Adata, M) ((Adata ? (1 << 6) : 0) | (((M - 2) >> 1) << 3) | 1)
#define CCM_ENCRYPTION_FLAGS 1
#ifdef CCM_CONF
#define CCM CCM_CONF
#else /* CCM_CONF */
#define CCM ccm_driver
#endif /* CCM_CONF */
/**
* Structure of CCM drivers.
*/
struct ccm_driver {
/**
* \brief Generates a MIC over the frame in the packetbuf.
* \param result The generated MIC will be put here
* \param mic_len <= 16; set to LLSEC802154_MIC_LENGTH to be compliant
*/
void (* mic)(const uint8_t *extended_source_address,
uint8_t *result,
uint8_t mic_len);
/**
* \brief XORs the frame in the packetbuf with the key stream.
*/
void (* ctr)(const uint8_t *extended_source_address);
};
extern const struct ccm_driver CCM;
#endif /* CCM_H_ */
/** @} */

95
core/net/llsec/llsec.h Normal file
View file

@ -0,0 +1,95 @@
/**
* \defgroup llsec Link Layer Security
*
* Layer for implementing link layer security.
*
* NETSTACK_LLSEC sits in between NETSTACK_MAC and NETSTACK_NETWORK
* protocols. All NETSTACK_MAC protocols invoke NETSTACK_LLSEC.input()
* for incoming packets. Likewise, all NETSTACK_NETWORK protocols
* invoke NETSTACK_LLSEC.send(...) for outgoing packets.
*
* The bootstrap function of llsec_drivers can be used to defer the start
* of upper layers so as to bootstrap pairwise keys. Only contiki-sky-main.c
* supports this at the moment.
*
* @{
*/
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Link layer security header file.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef LLSEC_H_
#define LLSEC_H_
#include "net/mac/mac.h"
typedef void (* llsec_on_bootstrapped_t)(void);
/**
* The structure of a link layer security driver.
*/
struct llsec_driver {
char *name;
/** Bootstraps link layer security and thereafter starts upper layers. */
void (* bootstrap)(llsec_on_bootstrapped_t on_bootstrapped);
/** Secures outgoing frames before passing them to NETSTACK_MAC. */
void (* send)(mac_callback_t sent_callback, void *ptr);
/**
* Once the NETSTACK_FRAMER wrote the headers, the LLSEC driver
* can generate a MIC over the entire frame.
* \return Returns != 0 <-> success
*/
int (* on_frame_created)(void);
/**
* Decrypts incoming frames;
* filters out injected or replayed frames.
*/
void (* input)(void);
/** Returns the security-related overhead per frame in bytes */
uint8_t (* get_overhead)(void);
};
#endif /* LLSEC_H_ */
/** @} */

View file

@ -0,0 +1,90 @@
/**
* \addtogroup llsec
* @{
*/
/**
* \defgroup llsec802154
*
* Common functionality of 802.15.4-compliant llsec_drivers.
*
* @{
*/
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Common functionality of 802.15.4-compliant llsec_drivers.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef LLSEC802154_H_
#define LLSEC802154_H_
#include "net/mac/frame802154.h"
#include "net/ip/uip.h"
#ifdef LLSEC802154_CONF_SECURITY_LEVEL
#define LLSEC802154_SECURITY_LEVEL LLSEC802154_CONF_SECURITY_LEVEL
#else /* LLSEC802154_CONF_SECURITY_LEVEL */
#define LLSEC802154_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE
#endif /* LLSEC802154_CONF_SECURITY_LEVEL */
#define LLSEC802154_MIC_LENGTH ((LLSEC802154_SECURITY_LEVEL & 3) * 4)
#ifdef LLSEC802154_CONF_USES_ENCRYPTION
#define LLSEC802154_USES_ENCRYPTION LLSEC802154_CONF_USES_ENCRYPTION
#else /* LLSEC802154_CONF_USES_ENCRYPTION */
#define LLSEC802154_USES_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2))
#endif /* LLSEC802154_CONF_USES_ENCRYPTION */
#ifdef LLSEC802154_CONF_USES_EXPLICIT_KEYS
#define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS
#else /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */
#define LLSEC802154_USES_EXPLICIT_KEYS 0
#endif /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */
#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN
#define LLSEC802154_HTONS(n) (n)
#define LLSEC802154_HTONL(n) (n)
#else /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */
#define LLSEC802154_HTONS(n) (uint16_t)((((uint16_t) (n)) << 8) | (((uint16_t) (n)) >> 8))
#define LLSEC802154_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16))
#endif /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */
#endif /* LLSEC802154_H_ */
/** @} */
/** @} */

View file

@ -0,0 +1,221 @@
/**
* \addtogroup noncoresec
* @{
*/
/*
* Copyright (c) 2014, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* 802.15.4 security implementation, which uses a network-wide key
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "net/llsec/noncoresec/noncoresec.h"
#include "net/llsec/anti-replay.h"
#include "net/llsec/llsec802154.h"
#include "net/llsec/ccm.h"
#include "net/mac/frame802154.h"
#include "net/netstack.h"
#include "net/packetbuf.h"
#include "net/nbr-table.h"
#include "net/linkaddr.h"
#include "lib/aes-128.h"
#include <string.h>
#define WITH_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2))
#ifdef NONCORESEC_CONF_KEY
#define NONCORESEC_KEY NONCORESEC_CONF_KEY
#else /* NONCORESEC_CONF_KEY */
#define NONCORESEC_KEY { 0x00 , 0x01 , 0x02 , 0x03 , \
0x04 , 0x05 , 0x06 , 0x07 , \
0x08 , 0x09 , 0x0A , 0x0B , \
0x0C , 0x0D , 0x0E , 0x0F }
#endif /* NONCORESEC_CONF_KEY */
#define SECURITY_HEADER_LENGTH 5
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else /* DEBUG */
#define PRINTF(...)
#endif /* DEBUG */
/* network-wide CCM* key */
static uint8_t key[16] = NONCORESEC_KEY;
NBR_TABLE(struct anti_replay_info, anti_replay_table);
/*---------------------------------------------------------------------------*/
static const uint8_t *
get_extended_address(const linkaddr_t *addr)
#if LINKADDR_SIZE == 2
{
/* workaround for short addresses: derive EUI64 as in RFC 6282 */
static linkaddr_extended_t template = { { 0x00 , 0x00 , 0x00 ,
0xFF , 0xFE , 0x00 , 0x00 , 0x00 } };
template.u16[3] = LLSEC802154_HTONS(addr->u16);
return template.u8;
}
#else /* LINKADDR_SIZE == 2 */
{
return addr->u8;
}
#endif /* LINKADDR_SIZE == 2 */
/*---------------------------------------------------------------------------*/
static void
send(mac_callback_t sent, void *ptr)
{
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL);
anti_replay_set_counter();
NETSTACK_MAC.send(sent, ptr);
}
/*---------------------------------------------------------------------------*/
static int
on_frame_created(void)
{
uint8_t *dataptr;
uint8_t data_len;
dataptr = packetbuf_dataptr();
data_len = packetbuf_datalen();
CCM.mic(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH);
#if WITH_ENCRYPTION
CCM.ctr(get_extended_address(&linkaddr_node_addr));
#endif /* WITH_ENCRYPTION */
packetbuf_set_datalen(data_len + LLSEC802154_MIC_LENGTH);
return 1;
}
/*---------------------------------------------------------------------------*/
static void
input(void)
{
uint8_t generated_mic[LLSEC802154_MIC_LENGTH];
uint8_t *received_mic;
const linkaddr_t *sender;
struct anti_replay_info* info;
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) {
PRINTF("noncoresec: received frame with wrong security level\n");
return;
}
sender = packetbuf_addr(PACKETBUF_ADDR_SENDER);
if(linkaddr_cmp(sender, &linkaddr_node_addr)) {
PRINTF("noncoresec: frame from ourselves\n");
return;
}
packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH);
#if WITH_ENCRYPTION
CCM.ctr(get_extended_address(sender));
#endif /* WITH_ENCRYPTION */
CCM.mic(get_extended_address(sender), generated_mic, LLSEC802154_MIC_LENGTH);
received_mic = ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen();
if(memcmp(generated_mic, received_mic, LLSEC802154_MIC_LENGTH) != 0) {
PRINTF("noncoresec: received nonauthentic frame %"PRIu32"\n",
anti_replay_get_counter());
return;
}
info = nbr_table_get_from_lladdr(anti_replay_table, sender);
if(!info) {
info = nbr_table_add_lladdr(anti_replay_table, sender);
if(!info) {
PRINTF("noncoresec: could not get nbr_table_item\n");
return;
}
/*
* Locking avoids replay attacks due to removed neighbor table items.
* Unfortunately, an attacker can mount a memory-based DoS attack
* on this by replaying broadcast frames from other network parts.
* However, this is not an issue as long as the network size does not
* exceed NBR_TABLE_MAX_NEIGHBORS.
*
* To avoid locking, we could swap anti-replay information
* to external flash. Locking is also unnecessary when using
* pairwise session keys, as done in coresec.
*/
if(!nbr_table_lock(anti_replay_table, info)) {
nbr_table_remove(anti_replay_table, info);
PRINTF("noncoresec: could not lock\n");
return;
}
anti_replay_init_info(info);
} else {
if(anti_replay_was_replayed(info)) {
PRINTF("noncoresec: received replayed frame %"PRIu32"\n",
anti_replay_get_counter());
return;
}
}
NETSTACK_NETWORK.input();
}
/*---------------------------------------------------------------------------*/
static uint8_t
get_overhead(void)
{
return SECURITY_HEADER_LENGTH + LLSEC802154_MIC_LENGTH;
}
/*---------------------------------------------------------------------------*/
static void
bootstrap(llsec_on_bootstrapped_t on_bootstrapped)
{
AES_128.set_key(key);
nbr_table_register(anti_replay_table, NULL);
on_bootstrapped();
}
/*---------------------------------------------------------------------------*/
const struct llsec_driver noncoresec_driver = {
"noncoresec",
bootstrap,
send,
on_frame_created,
input,
get_overhead
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,63 @@
/**
* \addtogroup llsec
* @{
*/
/**
* \defgroup noncoresec
*
* Noncompromise-resilient 802.15.4 security
*
* @{
*/
/*
* Copyright (c) 2014, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* 802.15.4 security implementation, which uses a network-wide key
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef NONCORESEC_H_
#define NONCORESEC_H_
#include "net/llsec/llsec.h"
extern const struct llsec_driver noncoresec_driver;
#endif /* NONCORESEC_H_ */
/** @} */
/** @} */

92
core/net/llsec/nullsec.c Normal file
View file

@ -0,0 +1,92 @@
/**
* \addtogroup nullsec
* @{
*/
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Insecure link layer security driver.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "net/llsec/nullsec.h"
#include "net/mac/frame802154.h"
#include "net/netstack.h"
#include "net/packetbuf.h"
/*---------------------------------------------------------------------------*/
static void
bootstrap(llsec_on_bootstrapped_t on_bootstrapped)
{
on_bootstrapped();
}
/*---------------------------------------------------------------------------*/
static void
send(mac_callback_t sent, void *ptr)
{
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
NETSTACK_MAC.send(sent, ptr);
}
/*---------------------------------------------------------------------------*/
static int
on_frame_created(void)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static void
input(void)
{
NETSTACK_NETWORK.input();
}
/*---------------------------------------------------------------------------*/
static uint8_t
get_overhead(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
const struct llsec_driver nullsec_driver = {
"nullsec",
bootstrap,
send,
on_frame_created,
input,
get_overhead
};
/*---------------------------------------------------------------------------*/
/** @} */

63
core/net/llsec/nullsec.h Normal file
View file

@ -0,0 +1,63 @@
/**
* \addtogroup llsec
* @{
*/
/**
* \defgroup nullsec
*
* Insecure link layer security driver.
*
* @{
*/
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Insecure link layer security driver.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef NULLSEC_H_
#define NULLSEC_H_
#include "net/llsec/llsec.h"
extern const struct llsec_driver nullsec_driver;
#endif /* NULLSEC_H_ */
/** @} */
/** @} */

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2014, Fraunhofer Heinrich-Hertz-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
*/
/**
* \file
* Creates and parses the ContikiMAC header.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "net/mac/contikimac/contikimac-framer.h"
#include "net/packetbuf.h"
#include "net/netstack.h"
#include <string.h>
#define CONTIKIMAC_ID 0x00
/* SHORTEST_PACKET_SIZE is the shortest packet that ContikiMAC
allows. Packets have to be a certain size to be able to be detected
by two consecutive CCA checks, and here is where we define this
shortest size.
Padded packets will have the wrong ipv6 checksum unless CONTIKIMAC_HEADER
is used (on both sides) and the receiver will ignore them.
With no header, reduce to transmit a proper multicast RPL DIS. */
#ifdef CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE
#define SHORTEST_PACKET_SIZE CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE
#else /* CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE */
#define SHORTEST_PACKET_SIZE 43
#endif /* CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE */
#ifdef CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER
#define DECORATED_FRAMER CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER
#else /* CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER */
#define DECORATED_FRAMER framer_802154
#endif /* CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER */
extern const struct framer DECORATED_FRAMER;
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/* 2-byte header for recovering padded packets.
Wireshark will not understand such packets at present. */
struct hdr {
uint8_t id;
uint8_t len;
};
/*---------------------------------------------------------------------------*/
static int
create(void)
{
struct hdr *chdr;
int hdr_len;
if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) {
PRINTF("contikimac-framer: too large header\n");
return FRAMER_FAILED;
}
chdr = packetbuf_hdrptr();
chdr->id = CONTIKIMAC_ID;
chdr->len = 0;
hdr_len = DECORATED_FRAMER.create();
if(hdr_len < 0) {
PRINTF("contikimac-framer: decorated framer failed\n");
return FRAMER_FAILED;
}
return hdr_len + sizeof(struct hdr);
}
/*---------------------------------------------------------------------------*/
static void
pad(void)
{
int transmit_len;
uint8_t *ptr;
uint8_t zeroes_count;
transmit_len = packetbuf_totlen();
if(transmit_len < SHORTEST_PACKET_SIZE) {
/* Padding required */
zeroes_count = SHORTEST_PACKET_SIZE - transmit_len;
ptr = packetbuf_dataptr();
memset(ptr + packetbuf_datalen(), 0, zeroes_count);
packetbuf_set_datalen(packetbuf_datalen() + zeroes_count);
}
}
/*---------------------------------------------------------------------------*/
static int
create_and_secure(void)
{
struct hdr *chdr;
int hdr_len;
hdr_len = create();
if(hdr_len < 0) {
return FRAMER_FAILED;
}
packetbuf_compact();
if(!NETSTACK_LLSEC.on_frame_created()) {
PRINTF("contikimac-framer: securing failed\n");
return FRAMER_FAILED;
}
chdr = (struct hdr *)(((uint8_t *) packetbuf_dataptr()) - sizeof(struct hdr));
chdr->len = packetbuf_datalen();
pad();
return hdr_len;
}
/*---------------------------------------------------------------------------*/
static int
parse(void)
{
int hdr_len;
struct hdr *chdr;
hdr_len = DECORATED_FRAMER.parse();
if(hdr_len < 0) {
return FRAMER_FAILED;
}
chdr = packetbuf_dataptr();
if(chdr->id != CONTIKIMAC_ID) {
PRINTF("contikimac-framer: CONTIKIMAC_ID is missing\n");
return FRAMER_FAILED;
}
if(!packetbuf_hdrreduce(sizeof(struct hdr))) {
PRINTF("contikimac-framer: packetbuf_hdrreduce failed\n");
return FRAMER_FAILED;
}
packetbuf_set_datalen(chdr->len);
chdr->len = 0;
return hdr_len + sizeof(struct hdr);
}
/*---------------------------------------------------------------------------*/
const struct framer contikimac_framer = {
create,
create_and_secure,
parse
};
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2014, Fraunhofer Heinrich-Hertz-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
*/
/**
* \file
* Creates and parses the ContikiMAC header.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef CONTIKIMAC_FRAMER_H_
#define CONTIKIMAC_FRAMER_H_
#include "net/mac/framer.h"
extern const struct framer contikimac_framer;
#endif /* CONTIKIMAC_FRAMER_H_ */

View file

@ -61,13 +61,6 @@
#else /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */
#define WITH_PHASE_OPTIMIZATION 1
#endif /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */
/* Two byte header added to allow recovery of padded short packets */
/* Wireshark will not understand such packets at present */
#ifdef CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
#define WITH_CONTIKIMAC_HEADER CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
#else
#define WITH_CONTIKIMAC_HEADER 1
#endif
/* More aggressive radio sleeping when channel is busy with other traffic */
#ifndef WITH_FAST_SLEEP
#define WITH_FAST_SLEEP 1
@ -90,15 +83,6 @@
#define WITH_PHASE_OPTIMIZATION 0
#endif
#if WITH_CONTIKIMAC_HEADER
#define CONTIKIMAC_ID 0x00
struct hdr {
uint8_t id;
uint8_t len;
};
#endif /* WITH_CONTIKIMAC_HEADER */
/* CYCLE_TIME for channel cca checks, in rtimer ticks. */
#ifdef CONTIKIMAC_CONF_CYCLE_TIME
#define CYCLE_TIME (CONTIKIMAC_CONF_CYCLE_TIME)
@ -211,21 +195,6 @@ static int we_are_receiving_burst = 0;
to a neighbor for which we have a phase lock. */
#define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60
/* SHORTEST_PACKET_SIZE is the shortest packet that ContikiMAC
allows. Packets have to be a certain size to be able to be detected
by two consecutive CCA checks, and here is where we define this
shortest size.
Padded packets will have the wrong ipv6 checksum unless CONTIKIMAC_HEADER
is used (on both sides) and the receiver will ignore them.
With no header, reduce to transmit a proper multicast RPL DIS. */
#ifdef CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE
#define SHORTEST_PACKET_SIZE CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE
#else
#define SHORTEST_PACKET_SIZE 43
#endif
#define ACK_LEN 3
#include <stdio.h>
@ -528,7 +497,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
rtimer_clock_t encounter_time = 0;
int strobes;
uint8_t got_strobe_ack = 0;
int hdrlen, len;
int len;
uint8_t is_broadcast = 0;
uint8_t is_reliable = 0;
uint8_t is_known_receiver = 0;
@ -537,10 +506,7 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
int ret;
uint8_t contikimac_was_on;
uint8_t seqno;
#if WITH_CONTIKIMAC_HEADER
struct hdr *chdr;
#endif /* WITH_CONTIKIMAC_HEADER */
/* Exit if RDC and radio were explicitly turned off */
if(!contikimac_is_on && !contikimac_keep_radio_on) {
PRINTF("contikimac: radio is turned off\n");
@ -583,65 +549,17 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) ||
packetbuf_attr(PACKETBUF_ATTR_ERELIABLE);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
#if WITH_CONTIKIMAC_HEADER
hdrlen = packetbuf_totlen();
if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) {
/* Failed to allocate space for contikimac header */
PRINTF("contikimac: send failed, too large header\n");
return MAC_TX_ERR_FATAL;
if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) {
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
if(NETSTACK_FRAMER.create_and_secure() < 0) {
PRINTF("contikimac: framer failed\n");
return MAC_TX_ERR_FATAL;
}
}
chdr = packetbuf_hdrptr();
chdr->id = CONTIKIMAC_ID;
chdr->len = hdrlen;
/* Create the MAC header for the data packet. */
hdrlen = NETSTACK_FRAMER.create();
if(hdrlen < 0) {
/* Failed to send */
PRINTF("contikimac: send failed, too large header\n");
packetbuf_hdr_remove(sizeof(struct hdr));
return MAC_TX_ERR_FATAL;
}
hdrlen += sizeof(struct hdr);
#else
/* Create the MAC header for the data packet. */
hdrlen = NETSTACK_FRAMER.create();
if(hdrlen < 0) {
/* Failed to send */
PRINTF("contikimac: send failed, too large header\n");
return MAC_TX_ERR_FATAL;
}
#endif
/* Make sure that the packet is longer or equal to the shortest
packet length. */
transmit_len = packetbuf_totlen();
if(transmit_len < SHORTEST_PACKET_SIZE) {
/* Pad with zeroes */
uint8_t *ptr;
ptr = packetbuf_dataptr();
memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen());
PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen());
transmit_len = SHORTEST_PACKET_SIZE;
}
packetbuf_compact();
#ifdef NETSTACK_ENCRYPT
NETSTACK_ENCRYPT();
#endif /* NETSTACK_ENCRYPT */
transmit_len = packetbuf_totlen();
NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len);
/* Remove the MAC-layer header since it will be recreated next time around. */
packetbuf_hdr_remove(hdrlen);
if(!is_broadcast && !is_receiver_awake) {
#if WITH_PHASE_OPTIMIZATION
ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
@ -865,33 +783,55 @@ qsend_packet(mac_callback_t sent, void *ptr)
static void
qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
{
struct rdc_buf_list *curr = buf_list;
struct rdc_buf_list *curr;
struct rdc_buf_list *next;
int ret;
int is_receiver_awake;
if(curr == NULL) {
if(buf_list == NULL) {
return;
}
/* Do not send during reception of a burst */
if(we_are_receiving_burst) {
/* Prepare the packetbuf for callback */
queuebuf_to_packetbuf(curr->buf);
queuebuf_to_packetbuf(buf_list->buf);
/* Return COLLISION so the MAC may try again later */
mac_call_sent_callback(sent, ptr, MAC_TX_COLLISION, 1);
return;
}
/* Create and secure frames in advance */
curr = buf_list;
do {
next = list_item_next(curr);
queuebuf_to_packetbuf(curr->buf);
if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) {
/* create and secure this frame */
if(next != NULL) {
packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1);
}
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
if(NETSTACK_FRAMER.create_and_secure() < 0) {
PRINTF("contikimac: framer failed\n");
mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
return;
}
packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1);
queuebuf_update_from_packetbuf(curr->buf);
}
curr = next;
} while(next != NULL);
/* The receiver needs to be awoken before we send */
is_receiver_awake = 0;
curr = buf_list;
do { /* A loop sending a burst of packets from buf_list */
next = list_item_next(curr);
/* Prepare the packetbuf */
queuebuf_to_packetbuf(curr->buf);
if(next != NULL) {
packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1);
}
/* Send the current packet */
ret = send_packet(sent, ptr, curr, is_receiver_awake);
if(ret != MAC_TX_DEFERRED) {
@ -908,7 +848,7 @@ qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
/* The transmission failed, we stop the burst */
next = NULL;
}
} while(next != NULL);
} while((next != NULL) && packetbuf_attr(PACKETBUF_ATTR_PENDING));
}
/*---------------------------------------------------------------------------*/
/* Timer callback triggered when receiving a burst, after having
@ -931,23 +871,7 @@ input_packet(void)
/* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/
#ifdef NETSTACK_DECRYPT
NETSTACK_DECRYPT();
#endif /* NETSTACK_DECRYPT */
if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) {
#if WITH_CONTIKIMAC_HEADER
struct hdr *chdr;
chdr = packetbuf_dataptr();
if(chdr->id != CONTIKIMAC_ID) {
PRINTF("contikimac: failed to parse hdr (%u)\n", packetbuf_totlen());
return;
}
packetbuf_hdrreduce(sizeof(struct hdr));
packetbuf_set_datalen(chdr->len);
#endif /* WITH_CONTIKIMAC_HEADER */
if(packetbuf_datalen() > 0 &&
packetbuf_totlen() > 0 &&
(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
@ -958,6 +882,8 @@ input_packet(void)
broadcast address. */
/* If FRAME_PENDING is set, we are receiving a packets in a burst */
/* TODO To prevent denial-of-sleep attacks, the transceiver should
be disabled upon receipt of an unauthentic frame. */
we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING);
if(we_are_receiving_burst) {
on();
@ -969,6 +895,7 @@ input_packet(void)
ctimer_stop(&ct);
}
#if RDC_WITH_DUPLICATE_DETECTION
/* Check for duplicate packet. */
if(mac_sequence_is_duplicate()) {
/* Drop the packet. */
@ -976,6 +903,7 @@ input_packet(void)
return;
}
mac_sequence_register_seqno();
#endif /* RDC_WITH_DUPLICATE_DETECTION */
#if CONTIKIMAC_CONF_COMPOWER
/* Accumulate the power consumption for the packet reception. */

View file

@ -396,7 +396,7 @@ send_packet(mac_callback_t sent, void *ptr)
static void
input_packet(void)
{
NETSTACK_NETWORK.input();
NETSTACK_LLSEC.input();
}
/*---------------------------------------------------------------------------*/
static int

View file

@ -63,6 +63,7 @@
#include "sys/cc.h"
#include "net/mac/frame802154.h"
#include "net/llsec/llsec802154.h"
#include <string.h>
/**
@ -91,6 +92,23 @@ addr_len(uint8_t mode)
}
}
/*----------------------------------------------------------------------------*/
#if LLSEC802154_USES_EXPLICIT_KEYS
static uint8_t
get_key_id_len(uint8_t key_id_mode)
{
switch(key_id_mode) {
case FRAME802154_1_BYTE_KEY_ID_MODE:
return 1;
case FRAME802154_5_BYTE_KEY_ID_MODE:
return 5;
case FRAME802154_9_BYTE_KEY_ID_MODE:
return 9;
default:
return 0;
}
}
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
/*----------------------------------------------------------------------------*/
static void
field_len(frame802154_t *p, field_length_t *flen)
{
@ -120,28 +138,16 @@ field_len(frame802154_t *p, field_length_t *flen)
flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3);
flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3);
#if LLSEC802154_SECURITY_LEVEL
/* Aux security header */
if(p->fcf.security_enabled & 1) {
/* TODO Aux security header not yet implemented */
#if 0
switch(p->aux_hdr.security_control.key_id_mode) {
case 0:
flen->aux_sec_len = 5; /* minimum value */
break;
case 1:
flen->aux_sec_len = 6;
break;
case 2:
flen->aux_sec_len = 10;
break;
case 3:
flen->aux_sec_len = 14;
break;
default:
break;
}
#endif
flen->aux_sec_len = 5
#if LLSEC802154_USES_EXPLICIT_KEYS
+ get_key_id_len(p->aux_hdr.security_control.key_id_mode);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
;
}
#endif /* LLSEC802154_SECURITY_LEVEL */
}
/*----------------------------------------------------------------------------*/
/**
@ -171,70 +177,79 @@ frame802154_hdrlen(frame802154_t *p)
*
* \param buf Pointer to the buffer to use for the frame.
*
* \param buf_len The length of the buffer to use for the frame.
*
* \return The length of the frame header or 0 if there was
* insufficient space in the buffer for the frame headers.
* \return The length of the frame header
*/
int
frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len)
frame802154_create(frame802154_t *p, uint8_t *buf)
{
int c;
field_length_t flen;
uint8_t *tx_frame_buffer;
uint8_t pos;
#if LLSEC802154_USES_EXPLICIT_KEYS
uint8_t key_id_mode;
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
field_len(p, &flen);
if(3 + flen.dest_pid_len + flen.dest_addr_len +
flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len > buf_len) {
/* Too little space for headers. */
return 0;
}
/* OK, now we have field lengths. Time to actually construct */
/* the outgoing frame, and store it in tx_frame_buffer */
tx_frame_buffer = buf;
tx_frame_buffer[0] = (p->fcf.frame_type & 7) |
/* the outgoing frame, and store it in buf */
buf[0] = (p->fcf.frame_type & 7) |
((p->fcf.security_enabled & 1) << 3) |
((p->fcf.frame_pending & 1) << 4) |
((p->fcf.ack_required & 1) << 5) |
((p->fcf.panid_compression & 1) << 6);
tx_frame_buffer[1] = ((p->fcf.dest_addr_mode & 3) << 2) |
buf[1] = ((p->fcf.dest_addr_mode & 3) << 2) |
((p->fcf.frame_version & 3) << 4) |
((p->fcf.src_addr_mode & 3) << 6);
/* sequence number */
tx_frame_buffer[2] = p->seq;
buf[2] = p->seq;
pos = 3;
/* Destination PAN ID */
if(flen.dest_pid_len == 2) {
tx_frame_buffer[pos++] = p->dest_pid & 0xff;
tx_frame_buffer[pos++] = (p->dest_pid >> 8) & 0xff;
buf[pos++] = p->dest_pid & 0xff;
buf[pos++] = (p->dest_pid >> 8) & 0xff;
}
/* Destination address */
for(c = flen.dest_addr_len; c > 0; c--) {
tx_frame_buffer[pos++] = p->dest_addr[c - 1];
buf[pos++] = p->dest_addr[c - 1];
}
/* Source PAN ID */
if(flen.src_pid_len == 2) {
tx_frame_buffer[pos++] = p->src_pid & 0xff;
tx_frame_buffer[pos++] = (p->src_pid >> 8) & 0xff;
buf[pos++] = p->src_pid & 0xff;
buf[pos++] = (p->src_pid >> 8) & 0xff;
}
/* Source address */
for(c = flen.src_addr_len; c > 0; c--) {
tx_frame_buffer[pos++] = p->src_addr[c - 1];
buf[pos++] = p->src_addr[c - 1];
}
#if LLSEC802154_SECURITY_LEVEL
/* Aux header */
if(flen.aux_sec_len) {
/* TODO Aux security header not yet implemented */
/* pos += flen.aux_sec_len; */
buf[pos++] = p->aux_hdr.security_control.security_level
#if LLSEC802154_USES_EXPLICIT_KEYS
| (p->aux_hdr.security_control.key_id_mode << 3)
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
;
memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4);
pos += 4;
#if LLSEC802154_USES_EXPLICIT_KEYS
key_id_mode = p->aux_hdr.security_control.key_id_mode;
if(key_id_mode) {
c = (key_id_mode - 1) * 4;
memcpy(buf + pos, p->aux_hdr.key_source.u8, c);
pos += c;
buf[pos++] = p->aux_hdr.key_index;
}
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_SECURITY_LEVEL */
return (int)pos;
}
@ -254,6 +269,9 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
uint8_t *p;
frame802154_fcf_t fcf;
int c;
#if LLSEC802154_USES_EXPLICIT_KEYS
uint8_t key_id_mode;
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
if(len < 3) {
return 0;
@ -336,11 +354,30 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null);
pf->src_pid = 0;
}
#if LLSEC802154_SECURITY_LEVEL
if(fcf.security_enabled) {
/* TODO aux security header, not yet implemented */
/* return 0; */
pf->aux_hdr.security_control.security_level = p[0] & 7;
#if LLSEC802154_USES_EXPLICIT_KEYS
pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3;
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
p += 1;
memcpy(pf->aux_hdr.frame_counter.u8, p, 4);
p += 4;
#if LLSEC802154_USES_EXPLICIT_KEYS
key_id_mode = pf->aux_hdr.security_control.key_id_mode;
if(key_id_mode) {
c = (key_id_mode - 1) * 4;
memcpy(pf->aux_hdr.key_source.u8, p, c);
p += c;
pf->aux_hdr.key_index = p[0];
p += 1;
}
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_SECURITY_LEVEL */
/* header length */
c = p - data;

View file

@ -66,9 +66,9 @@
#ifdef IEEE802154_CONF_PANID
#define IEEE802154_PANID IEEE802154_CONF_PANID
#else
#else /* IEEE802154_CONF_PANID */
#define IEEE802154_PANID 0xABCD
#endif
#endif /* IEEE802154_CONF_PANID */
/* Macros & Defines */
@ -96,9 +96,19 @@
#define FRAME802154_IEEE802154_2003 (0x00)
#define FRAME802154_IEEE802154_2006 (0x01)
#define FRAME802154_SECURITY_LEVEL_NONE (0)
#define FRAME802154_SECURITY_LEVEL_128 (3)
#define FRAME802154_SECURITY_LEVEL_NONE (0)
#define FRAME802154_SECURITY_LEVEL_MIC_32 (1)
#define FRAME802154_SECURITY_LEVEL_MIC_64 (2)
#define FRAME802154_SECURITY_LEVEL_MIC_128 (3)
#define FRAME802154_SECURITY_LEVEL_ENC (4)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_32 (5)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_64 (6)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_128 (7)
#define FRAME802154_IMPLICIT_KEY (0)
#define FRAME802154_1_BYTE_KEY_ID_MODE (1)
#define FRAME802154_5_BYTE_KEY_ID_MODE (2)
#define FRAME802154_9_BYTE_KEY_ID_MODE (3)
/**
* @brief The IEEE 802.15.4 frame has a number of constant/fixed fields that
@ -135,11 +145,23 @@ typedef struct {
uint8_t reserved; /**< 3 bit. Reserved bits */
} frame802154_scf_t;
typedef union {
uint32_t u32;
uint16_t u16[2];
uint8_t u8[4];
} frame802154_frame_counter_t;
typedef union {
uint16_t u16[4];
uint8_t u8[8];
} frame802154_key_source_t;
/** \brief 802.15.4 Aux security header */
typedef struct {
frame802154_scf_t security_control; /**< Security control bitfield */
uint32_t frame_counter; /**< Frame counter, used for security */
uint8_t key[9]; /**< The key itself, or an index to the key */
frame802154_scf_t security_control; /**< Security control bitfield */
frame802154_frame_counter_t frame_counter; /**< Frame counter, used for security */
frame802154_key_source_t key_source; /**< Key Source subfield */
uint8_t key_index; /**< Key Index subfield */
} frame802154_aux_hdr_t;
/** \brief Parameters used by the frame802154_create() function. These
@ -147,21 +169,21 @@ typedef struct {
* specification for details.
*/
typedef struct {
frame802154_fcf_t fcf; /**< Frame control field */
uint8_t seq; /**< Sequence number */
uint16_t dest_pid; /**< Destination PAN ID */
uint8_t dest_addr[8]; /**< Destination address */
uint16_t src_pid; /**< Source PAN ID */
uint8_t src_addr[8]; /**< Source address */
frame802154_aux_hdr_t aux_hdr; /**< Aux security header */
uint8_t *payload; /**< Pointer to 802.15.4 frame payload */
int payload_len; /**< Length of payload field */
frame802154_fcf_t fcf; /**< Frame control field */
uint8_t seq; /**< Sequence number */
uint16_t dest_pid; /**< Destination PAN ID */
uint8_t dest_addr[8]; /**< Destination address */
uint16_t src_pid; /**< Source PAN ID */
uint8_t src_addr[8]; /**< Source address */
frame802154_aux_hdr_t aux_hdr; /**< Aux security header */
uint8_t *payload; /**< Pointer to 802.15.4 payload */
int payload_len; /**< Length of payload field */
} frame802154_t;
/* Prototypes */
int frame802154_hdrlen(frame802154_t *p);
int frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len);
int frame802154_create(frame802154_t *p, uint8_t *buf);
int frame802154_parse(uint8_t *data, int length, frame802154_t *pf);
/** @} */

View file

@ -38,6 +38,7 @@
#include "net/mac/framer-802154.h"
#include "net/mac/frame802154.h"
#include "net/llsec/llsec802154.h"
#include "net/packetbuf.h"
#include "lib/random.h"
#include <string.h>
@ -90,7 +91,7 @@ static int
create_frame(int type, int do_create)
{
frame802154_t params;
int len;
int hdr_len;
/* init to zeros */
memset(&params, 0, sizeof(params));
@ -101,8 +102,7 @@ create_frame(int type, int do_create)
}
/* Build the FCF. */
params.fcf.frame_type = FRAME802154_DATAFRAME;
params.fcf.security_enabled = 0;
params.fcf.frame_type = packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE);
params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) {
params.fcf.ack_required = 0;
@ -111,8 +111,23 @@ create_frame(int type, int do_create)
}
params.fcf.panid_compression = 0;
/* Insert IEEE 802.15.4 (2003) version bit. */
params.fcf.frame_version = FRAME802154_IEEE802154_2003;
/* Insert IEEE 802.15.4 (2006) version bits. */
params.fcf.frame_version = FRAME802154_IEEE802154_2006;
#if LLSEC802154_SECURITY_LEVEL
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) {
params.fcf.security_enabled = 1;
}
/* Setting security-related attributes */
params.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
#if LLSEC802154_USES_EXPLICIT_KEYS
params.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE);
params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX);
params.aux_hdr.key_source.u16[0] = packetbuf_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY_LEVEL */
/* Increment and set the data sequence number. */
if(!do_create) {
@ -123,6 +138,10 @@ create_frame(int type, int do_create)
params.seq = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
} else {
/* Ensure that the sequence number 0 is not used as it would bypass the above check. */
if(mac_dsn == 0) {
mac_dsn++;
}
params.seq = mac_dsn++;
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, params.seq);
}
@ -172,21 +191,21 @@ create_frame(int type, int do_create)
params.payload = packetbuf_dataptr();
params.payload_len = packetbuf_datalen();
len = frame802154_hdrlen(&params);
hdr_len = frame802154_hdrlen(&params);
if(!do_create) {
/* Only calculate header length */
return len;
return hdr_len;
} else if(packetbuf_hdralloc(len)) {
frame802154_create(&params, packetbuf_hdrptr(), len);
} else if(packetbuf_hdralloc(hdr_len)) {
frame802154_create(&params, packetbuf_hdrptr());
PRINTF("15.4-OUT: %2X", params.fcf.frame_type);
PRINTADDR(params.dest_addr);
PRINTF("%d %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen());
PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen());
return len;
return hdr_len;
} else {
PRINTF("15.4-OUT: too large header: %u\n", len);
PRINTF("15.4-OUT: too large header: %u\n", hdr_len);
return FRAMER_FAILED;
}
}
@ -207,13 +226,16 @@ static int
parse(void)
{
frame802154_t frame;
int len;
len = packetbuf_datalen();
if(frame802154_parse(packetbuf_dataptr(), len, &frame) &&
packetbuf_hdrreduce(len - frame.payload_len)) {
int hdr_len;
hdr_len = frame802154_parse(packetbuf_dataptr(), packetbuf_datalen(), &frame);
if(hdr_len && packetbuf_hdrreduce(hdr_len)) {
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type);
if(frame.fcf.dest_addr_mode) {
if(frame.dest_pid != mac_src_pan_id &&
frame.dest_pid != FRAME802154_BROADCASTPANDID) {
frame.dest_pid != FRAME802154_BROADCASTPANDID) {
/* Packet to another PAN */
PRINTF("15.4: for another pan %u\n", frame.dest_pid);
return FRAMER_FAILED;
@ -226,17 +248,34 @@ parse(void)
packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending);
/* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq);
#if LLSEC802154_SECURITY_LEVEL
if(frame.fcf.security_enabled) {
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]);
#if LLSEC802154_USES_EXPLICIT_KEYS
packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode);
packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index);
packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_SECURITY_LEVEL */
PRINTF("15.4-IN: %2X", frame.fcf.frame_type);
PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
PRINTF("%u (%u)\n", packetbuf_datalen(), len);
return len - frame.payload_len;
PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen());
return hdr_len;
}
return FRAMER_FAILED;
}
/*---------------------------------------------------------------------------*/
const struct framer framer_802154 = {
hdr_length, create, parse
hdr_length,
create,
framer_canonical_create_and_secure,
parse
};
/*---------------------------------------------------------------------------*/

View file

@ -97,5 +97,8 @@ parse(void)
}
/*---------------------------------------------------------------------------*/
const struct framer framer_nullmac = {
hdr_length, create, parse
hdr_length,
create,
framer_canonical_create_and_secure,
parse
};

50
core/net/mac/framer.c Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014, Fraunhofer Heinrich-Hertz-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
*/
#include "net/mac/framer.h"
#include "net/packetbuf.h"
#include "net/netstack.h"
/*---------------------------------------------------------------------------*/
int
framer_canonical_create_and_secure(void)
{
int hdr_len;
hdr_len = NETSTACK_FRAMER.create();
if(hdr_len >= 0) {
packetbuf_compact();
if(!NETSTACK_LLSEC.on_frame_created()) {
return FRAMER_FAILED;
}
}
return hdr_len;
}
/*---------------------------------------------------------------------------*/

View file

@ -47,8 +47,13 @@ struct framer {
int (* length)(void);
int (* create)(void);
/** Creates the frame and calls LLSEC.on_frame_created() */
int (* create_and_secure)(void);
int (* parse)(void);
};
int framer_canonical_create_and_secure(void);
#endif /* FRAMER_H_ */

View file

@ -54,7 +54,7 @@ send_packet(mac_callback_t sent, void *ptr)
static void
packet_input(void)
{
NETSTACK_NETWORK.input();
NETSTACK_LLSEC.input();
}
/*---------------------------------------------------------------------------*/
static int

View file

@ -120,16 +120,11 @@ send_one_packet(mac_callback_t sent, void *ptr)
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
#endif /* NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW */
if(NETSTACK_FRAMER.create() < 0) {
if(NETSTACK_FRAMER.create_and_secure() < 0) {
/* Failed to allocate space for headers */
PRINTF("nullrdc: send failed, too large header\n");
ret = MAC_TX_ERR_FATAL;
} else {
#ifdef NETSTACK_ENCRYPT
NETSTACK_ENCRYPT();
#endif /* NETSTACK_ENCRYPT */
#if NULLRDC_802154_AUTOACK
int is_broadcast;
uint8_t dsn;
@ -275,9 +270,6 @@ packet_input(void)
original_datalen = packetbuf_datalen();
original_dataptr = packetbuf_dataptr();
#ifdef NETSTACK_DECRYPT
NETSTACK_DECRYPT();
#endif /* NETSTACK_DECRYPT */
#if NULLRDC_802154_AUTOACK
if(packetbuf_datalen() == ACK_LEN) {
@ -298,6 +290,7 @@ packet_input(void)
int duplicate = 0;
#if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
#if RDC_WITH_DUPLICATE_DETECTION
/* Check for duplicate packet. */
duplicate = mac_sequence_is_duplicate();
if(duplicate) {
@ -307,8 +300,10 @@ packet_input(void)
} else {
mac_sequence_register_seqno();
}
#endif /* RDC_WITH_DUPLICATE_DETECTION */
#endif /* NULLRDC_802154_AUTOACK */
/* TODO We may want to acknowledge only authentic frames */
#if NULLRDC_SEND_802154_ACK
{
frame802154_t info154;

View file

@ -217,6 +217,7 @@ phase_wait(const linkaddr_t *neighbor, rtimer_clock_t cycle_time,
p = memb_alloc(&queued_packets_memb);
if(p != NULL) {
if(buf_list == NULL) {
packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1);
p->q = queuebuf_new_from_packetbuf();
}
p->mac_callback = mac_callback;

View file

@ -44,6 +44,16 @@
#include "contiki-conf.h"
#include "net/mac/mac.h"
#ifdef RDC_CONF_WITH_DUPLICATE_DETECTION
#define RDC_WITH_DUPLICATE_DETECTION RDC_CONF_WITH_DUPLICATE_DETECTION
#else /* RDC_CONF_WITH_DUPLICATE_DETECTION */
/* As frames can be spoofed, the RDC layer should not discard a
frame because it has seen its sequence number already. Replay
protection should be implemented at the LLSEC layer where the
authenticity of frames is verified. */
#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_SECURITY_LEVEL
#endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */
/* List of packets to be sent by RDC layer */
struct rdc_buf_list {
struct rdc_buf_list *next;

View file

@ -157,7 +157,7 @@ send_packet(mac_callback_t sent, void *ptr)
len = frame802154_hdrlen(&params);
if(packetbuf_hdralloc(len)) {
int ret;
frame802154_create(&params, packetbuf_hdrptr(), len);
frame802154_create(&params, packetbuf_hdrptr());
PRINTF("6MAC-UT: %2X", params.fcf.frame_type);
PRINTADDR(params.dest_addr);

View file

@ -46,9 +46,5 @@ netstack_init(void)
NETSTACK_RDC.init();
NETSTACK_MAC.init();
NETSTACK_NETWORK.init();
#ifdef NETSTACK_ENCRYPTION_INIT
NETSTACK_ENCRYPTION_INIT();
#endif /* NETSTACK_ENCRYPTION_INIT */
}
/*---------------------------------------------------------------------------*/

View file

@ -28,6 +28,7 @@
*
* This file is part of the Contiki operating system.
*
* $Id: netstack.h,v 1.6 2010/10/03 20:37:32 adamdunkels Exp $
*/
/**
@ -50,6 +51,14 @@
#endif /* NETSTACK_CONF_NETWORK */
#endif /* NETSTACK_NETWORK */
#ifndef NETSTACK_LLSEC
#ifdef NETSTACK_CONF_LLSEC
#define NETSTACK_LLSEC NETSTACK_CONF_LLSEC
#else /* NETSTACK_CONF_LLSEC */
#define NETSTACK_LLSEC nullsec_driver
#endif /* NETSTACK_CONF_LLSEC */
#endif /* NETSTACK_LLSEC */
#ifndef NETSTACK_MAC
#ifdef NETSTACK_CONF_MAC
#define NETSTACK_MAC NETSTACK_CONF_MAC
@ -96,6 +105,7 @@
#endif /* NETSTACK_CONF_FRAMER */
#endif /* NETSTACK_FRAMER */
#include "net/llsec/llsec.h"
#include "net/mac/mac.h"
#include "net/mac/rdc.h"
#include "net/mac/framer.h"
@ -115,6 +125,7 @@ struct network_driver {
};
extern const struct network_driver NETSTACK_NETWORK;
extern const struct llsec_driver NETSTACK_LLSEC;
extern const struct rdc_driver NETSTACK_RDC;
extern const struct mac_driver NETSTACK_MAC;
extern const struct radio_driver NETSTACK_RADIO;

View file

@ -244,7 +244,16 @@ packetbuf_datalen(void)
uint8_t
packetbuf_hdrlen(void)
{
return PACKETBUF_HDR_SIZE - hdrptr;
uint8_t hdrlen;
hdrlen = PACKETBUF_HDR_SIZE - hdrptr;
if(hdrlen) {
/* outbound packet */
return hdrlen;
} else {
/* inbound packet */
return bufptr;
}
}
/*---------------------------------------------------------------------------*/
uint16_t

View file

@ -54,6 +54,7 @@
#include "contiki-conf.h"
#include "net/linkaddr.h"
#include "net/llsec/llsec802154.h"
/**
* \brief The size of the packetbuf, in bytes
@ -132,7 +133,7 @@ void *packetbuf_dataptr(void);
void *packetbuf_hdrptr(void);
/**
* \brief Get the length of the header in the packetbuf, for outbound packets
* \brief Get the length of the header in the packetbuf
* \return Length of the header in the packetbuf
*
* For outbound packets, the packetbuf consists of two
@ -347,7 +348,8 @@ enum {
PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
PACKETBUF_ATTR_MAC_SEQNO,
PACKETBUF_ATTR_MAC_ACK,
PACKETBUF_ATTR_IS_CREATED_AND_SECURED,
/* Scope 1 attributes: used between two neighbors only. */
PACKETBUF_ATTR_RELIABLE,
PACKETBUF_ATTR_PACKET_ID,
@ -356,6 +358,17 @@ enum {
PACKETBUF_ATTR_MAX_REXMIT,
PACKETBUF_ATTR_NUM_REXMIT,
PACKETBUF_ATTR_PENDING,
PACKETBUF_ATTR_FRAME_TYPE,
#if LLSEC802154_SECURITY_LEVEL
PACKETBUF_ATTR_SECURITY_LEVEL,
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1,
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3,
#if LLSEC802154_USES_EXPLICIT_KEYS
PACKETBUF_ATTR_KEY_ID_MODE,
PACKETBUF_ATTR_KEY_INDEX,
PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1,
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY_LEVEL */
/* Scope 2 attributes: used between end-to-end nodes. */
PACKETBUF_ATTR_HOPS,
@ -373,6 +386,24 @@ enum {
PACKETBUF_ATTR_MAX
};
/* Define surrogates when 802.15.4 security is off */
#if !LLSEC802154_SECURITY_LEVEL
enum {
PACKETBUF_ATTR_SECURITY_LEVEL,
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1,
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3
};
#endif /* LLSEC802154_SECURITY_LEVEL */
/* Define surrogates when not using explicit keys */
#if !LLSEC802154_USES_EXPLICIT_KEYS
enum {
PACKETBUF_ATTR_KEY_ID_MODE,
PACKETBUF_ATTR_KEY_INDEX,
PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1
};
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#define PACKETBUF_NUM_ADDRS 4
#define PACKETBUF_NUM_ATTRS (PACKETBUF_ATTR_MAX - PACKETBUF_NUM_ADDRS)
#define PACKETBUF_ADDR_FIRST PACKETBUF_ADDR_SENDER

View file

@ -405,6 +405,19 @@ queuebuf_update_attr_from_packetbuf(struct queuebuf *buf)
}
/*---------------------------------------------------------------------------*/
void
queuebuf_update_from_packetbuf(struct queuebuf *buf)
{
struct queuebuf_data *buframptr = queuebuf_load_to_ram(buf);
packetbuf_attr_copyto(buframptr->attrs, buframptr->addrs);
buframptr->len = packetbuf_copyto(buframptr->data);
#if WITH_SWAP
if(buf->location == IN_CFS) {
queuebuf_flush_tmpdata();
}
#endif
}
/*---------------------------------------------------------------------------*/
void
queuebuf_free(struct queuebuf *buf)
{
if(memb_inmemb(&bufmem, buf)) {

View file

@ -96,6 +96,7 @@ struct queuebuf *queuebuf_new_from_packetbuf_debug(const char *file, int line);
struct queuebuf *queuebuf_new_from_packetbuf(void);
#endif /* QUEUEBUF_DEBUG */
void queuebuf_update_attr_from_packetbuf(struct queuebuf *b);
void queuebuf_update_from_packetbuf(struct queuebuf *b);
void queuebuf_to_packetbuf(struct queuebuf *b);
void queuebuf_free(struct queuebuf *b);

View file

@ -180,7 +180,7 @@ rime_output(struct channel *c)
if(chameleon_create(c)) {
packetbuf_compact();
NETSTACK_MAC.send(packet_sent, c);
NETSTACK_LLSEC.send(packet_sent, c);
return 1;
}
return 0;

View file

@ -229,7 +229,7 @@ int contiki_maca_read(void *buf, unsigned short bufsize) {
}
#endif
PRINTF("\n\r");
free_packet(p);
maca_free_packet(p);
return bufsize;
} else {
return 0;

View file

@ -71,7 +71,7 @@ extern volatile uint8_t prm_mode;
void tx_packet(volatile packet_t *p);
volatile packet_t* rx_packet(void);
volatile packet_t* get_free_packet(void);
void free_packet(volatile packet_t *p);
void maca_free_packet(volatile packet_t *p);
void free_all_packets(void);
extern volatile packet_t *rx_head, *tx_head;

View file

@ -300,7 +300,7 @@ void bound_check(volatile packet_t *p) {
/* public packet routines */
/* heads are to the right */
/* ends are to the left */
void free_packet(volatile packet_t *p) {
void maca_free_packet(volatile packet_t *p) {
safe_irq_disable(MACA);
BOUND_CHECK(p);
@ -495,7 +495,7 @@ void free_all_packets(void) {
free_head = 0;
for(i=0; i<NUM_PACKETS; i++) {
free_packet((volatile packet_t *)&(packet_pool[i]));
maca_free_packet((volatile packet_t *)&(packet_pool[i]));
}
rx_head = 0; rx_end = 0;
tx_head = 0; tx_end = 0;
@ -517,7 +517,7 @@ void free_tx_head(void) {
p = tx_head;
tx_head = tx_head->left;
if(tx_head == 0) { tx_end = 0; }
free_packet(p);
maca_free_packet(p);
// print_packets("free tx head");
irq_restore();

View file

@ -94,7 +94,7 @@ void main(void) {
/* print and free the packet */
printf("autoack-rx --- ");
print_packet(p);
free_packet(p);
maca_free_packet(p);
}
if(uart1_can_get()) {

View file

@ -139,7 +139,7 @@ void main(void) {
if(p) {
printf("RX: ");
print_packet(p);
free_packet(p);
maca_free_packet(p);
}
}

View file

@ -146,7 +146,7 @@ void main(void) {
print_packet(p);
type = get_packet_type((packet_t *) p);
addr = 0; /* FIXME */
free_packet(p);
maca_free_packet(p);
/* pick a new address if someone else is using ours */
if(addr == my_addr) {
my_addr = random_short_addr();

View file

@ -87,7 +87,7 @@ void main(void) {
/* print and free the packet */
printf("rftest-rx --- ");
print_packet(p);
free_packet(p);
maca_free_packet(p);
}
if(uart1_can_get()) {

View file

@ -94,7 +94,7 @@ void main(void) {
check_maca();
while((p = rx_packet())) {
if(p) free_packet(p);
if(p) maca_free_packet(p);
}
p = get_free_packet();

View file

@ -1,118 +0,0 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* AES encryption functions.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "cc2420.h"
#include "cc2420-aes.h"
#include "dev/spi.h"
#define KEYLEN 16
#define MAX_DATALEN 16
#define CC2420_WRITE_RAM_REV(buffer,adr,count) \
do { \
uint8_t i; \
CC2420_SPI_ENABLE(); \
SPI_WRITE_FAST(0x80 | (adr & 0x7f)); \
SPI_WRITE_FAST((adr >> 1) & 0xc0); \
for(i = (count); i > 0; i--) { \
SPI_WRITE_FAST(((uint8_t*)(buffer))[i - 1]); \
} \
SPI_WAITFORTx_ENDED(); \
CC2420_SPI_DISABLE(); \
} while(0)
#define MIN(a,b) ((a) < (b)? (a): (b))
/*---------------------------------------------------------------------------*/
void
cc2420_aes_set_key(const uint8_t *key, int index)
{
switch(index) {
case 0:
CC2420_WRITE_RAM_REV(key, CC2420RAM_KEY0, KEYLEN);
break;
case 1:
CC2420_WRITE_RAM_REV(key, CC2420RAM_KEY1, KEYLEN);
break;
}
}
/*---------------------------------------------------------------------------*/
/* Encrypt at most 16 bytes of data. */
static void
cipher16(uint8_t *data, int len)
{
uint8_t status;
len = MIN(len, MAX_DATALEN);
CC2420_WRITE_RAM(data, CC2420RAM_SABUF, len);
CC2420_STROBE(CC2420_SAES);
/* Wait for the encryption to finish */
do {
CC2420_GET_STATUS(status);
} while(status & BV(CC2420_ENC_BUSY));
CC2420_READ_RAM(data, CC2420RAM_SABUF, len);
}
/*---------------------------------------------------------------------------*/
void
cc2420_aes_cipher(uint8_t *data, int len, int key_index)
{
int i;
uint16_t secctrl0;
CC2420_READ_REG(CC2420_SECCTRL0, secctrl0);
secctrl0 &= ~(CC2420_SECCTRL0_SAKEYSEL0 | CC2420_SECCTRL0_SAKEYSEL1);
switch(key_index) {
case 0:
secctrl0 |= CC2420_SECCTRL0_SAKEYSEL0;
break;
case 1:
secctrl0 |= CC2420_SECCTRL0_SAKEYSEL1;
break;
}
CC2420_WRITE_REG(CC2420_SECCTRL0, secctrl0);
for(i = 0; i < len; i = i + MAX_DATALEN) {
cipher16(data + i, MIN(len - i, MAX_DATALEN));
}
}
/*---------------------------------------------------------------------------*/

View file

@ -52,12 +52,6 @@
#define WITH_SEND_CCA 1
#define FOOTER_LEN 2
#ifndef CC2420_CONF_CHECKSUM
#define CC2420_CONF_CHECKSUM 0
#endif /* CC2420_CONF_CHECKSUM */
#ifndef CC2420_CONF_CHANNEL
#define CC2420_CONF_CHANNEL 26
#endif /* CC2420_CONF_CHANNEL */
@ -66,26 +60,28 @@
#define CC2420_CONF_CCA_THRESH -45
#endif /* CC2420_CONF_CCA_THRESH */
#ifndef CC2420_CONF_AUTOACK
#define CC2420_CONF_AUTOACK 0
#endif /* CC2420_CONF_AUTOACK */
#if CC2420_CONF_CHECKSUM
#include "lib/crc16.h"
#define CHECKSUM_LEN 2
#else
#define CHECKSUM_LEN 0
#endif /* CC2420_CONF_CHECKSUM */
#define AUX_LEN (CHECKSUM_LEN + FOOTER_LEN)
#define CHECKSUM_LEN 2
#define FOOTER_LEN 2
#define FOOTER1_CRC_OK 0x80
#define FOOTER1_CORRELATION 0x7f
#ifdef CC2420_CONF_RSSI_OFFSET
#define RSSI_OFFSET CC2420_CONF_RSSI_OFFSET
#else /* CC2420_CONF_RSSI_OFFSET */
/* The RSSI_OFFSET is approximate -45 (see CC2420 specification) */
#define RSSI_OFFSET -45
#endif /* CC2420_CONF_RSSI_OFFSET */
enum write_ram_order {
/* Begin with writing the first given byte */
WRITE_RAM_IN_ORDER,
/* Begin with writing the last given byte */
WRITE_RAM_REVERSE
};
#define DEBUG 0
#if DEBUG
@ -135,17 +131,6 @@ rtimer_clock_t cc2420_time_of_arrival, cc2420_time_of_departure;
int cc2420_authority_level_of_sender;
int cc2420_packets_seen, cc2420_packets_read;
/* static uint8_t volatile pending; */
#define BUSYWAIT_UNTIL(cond, max_time) \
do { \
rtimer_clock_t t0; \
t0 = RTIMER_NOW(); \
while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \
} while(0)
volatile uint8_t cc2420_sfd_counter;
volatile uint16_t cc2420_sfd_start_time;
volatile uint16_t cc2420_sfd_end_time;
@ -168,7 +153,6 @@ static int cc2420_send(const void *data, unsigned short len);
static int cc2420_receiving_packet(void);
static int pending_packet(void);
static int cc2420_cca(void);
/*static int detected_energy(void);*/
signed char cc2420_last_rssi;
uint8_t cc2420_last_correlation;
@ -204,7 +188,7 @@ get_value(radio_param_t param, radio_value_t *value)
return RADIO_RESULT_OK;
case RADIO_PARAM_RSSI:
/* Return the RSSI value in dBm */
*value = cc2420_rssi() + RSSI_OFFSET;
*value = cc2420_rssi();
return RADIO_RESULT_OK;
case RADIO_CONST_CHANNEL_MIN:
*value = 11;
@ -281,8 +265,6 @@ const struct radio_driver cc2420_driver =
cc2420_transmit,
cc2420_send,
cc2420_read,
/* cc2420_set_channel, */
/* detected_energy, */
cc2420_cca,
cc2420_receiving_packet,
pending_packet,
@ -295,29 +277,141 @@ const struct radio_driver cc2420_driver =
};
/*---------------------------------------------------------------------------*/
/* Sends a strobe */
static void
strobe(enum cc2420_register regname)
{
CC2420_STROBE(regname);
CC2420_SPI_ENABLE();
SPI_WRITE(regname);
CC2420_SPI_DISABLE();
}
/*---------------------------------------------------------------------------*/
static void
getrxdata(void *buf, int len)
/* Reads a register */
static uint16_t
getreg(enum cc2420_register regname)
{
CC2420_READ_FIFO_BUF(buf, len);
uint16_t value;
CC2420_SPI_ENABLE();
SPI_WRITE(regname | 0x40);
value = (uint8_t)SPI_RXBUF;
SPI_TXBUF = 0;
SPI_WAITFOREORx();
value = SPI_RXBUF << 8;
SPI_TXBUF = 0;
SPI_WAITFOREORx();
value |= SPI_RXBUF;
CC2420_SPI_DISABLE();
return value;
}
/*---------------------------------------------------------------------------*/
/**
* Writes to a register.
* Note: the SPI_WRITE(0) seems to be needed for getting the
* write reg working on the Z1 / MSP430X platform
*/
static void
getrxbyte(uint8_t *byte)
setreg(enum cc2420_register regname, uint16_t value)
{
CC2420_READ_FIFO_BYTE(*byte);
CC2420_SPI_ENABLE();
SPI_WRITE_FAST(regname);
SPI_WRITE_FAST((uint8_t) (value >> 8));
SPI_WRITE_FAST((uint8_t) (value & 0xff));
SPI_WAITFORTx_ENDED();
SPI_WRITE(0);
CC2420_SPI_DISABLE();
}
/*---------------------------------------------------------------------------*/
static void
read_ram(uint8_t *buffer, uint16_t adr, uint16_t count)
{
uint8_t i;
CC2420_SPI_ENABLE();
SPI_WRITE(0x80 | ((adr) & 0x7f));
SPI_WRITE((((adr) >> 1) & 0xc0) | 0x20);
SPI_RXBUF;
for(i = 0; i < count; i++) {
SPI_READ(((uint8_t*) buffer)[i]);
}
CC2420_SPI_DISABLE();
}
/*---------------------------------------------------------------------------*/
/* Write to RAM in the CC2420 */
static void
write_ram(const uint8_t *buffer,
uint16_t adr,
uint16_t count,
enum write_ram_order order)
{
uint8_t i;
CC2420_SPI_ENABLE();
SPI_WRITE_FAST(0x80 | (adr & 0x7f));
SPI_WRITE_FAST((adr >> 1) & 0xc0);
if(order == WRITE_RAM_IN_ORDER) {
for(i = 0; i < count; i++) {
SPI_WRITE_FAST((buffer)[i]);
}
} else {
for(i = count; i > 0; i--) {
SPI_WRITE_FAST((buffer)[i - 1]);
}
}
SPI_WAITFORTx_ENDED();
CC2420_SPI_DISABLE();
}
/*---------------------------------------------------------------------------*/
static void
write_fifo_buf(const uint8_t *buffer, uint16_t count)
{
uint8_t i;
CC2420_SPI_ENABLE();
SPI_WRITE_FAST(CC2420_TXFIFO);
for(i = 0; i < count; i++) {
SPI_WRITE_FAST((buffer)[i]);
}
SPI_WAITFORTx_ENDED();
CC2420_SPI_DISABLE();
}
/*---------------------------------------------------------------------------*/
/* Returns the current status */
static uint8_t
get_status(void)
{
uint8_t status;
CC2420_SPI_ENABLE();
SPI_WRITE(CC2420_SNOP);
status = SPI_RXBUF;
CC2420_SPI_DISABLE();
return status;
}
/*---------------------------------------------------------------------------*/
static void
getrxdata(uint8_t *buffer, int count)
{
uint8_t i;
CC2420_SPI_ENABLE();
SPI_WRITE(CC2420_RXFIFO | 0x40);
(void) SPI_RXBUF;
for(i = 0; i < count; i++) {
SPI_READ(buffer[i]);
}
clock_delay(1);
CC2420_SPI_DISABLE();
}
/*---------------------------------------------------------------------------*/
static void
flushrx(void)
{
uint8_t dummy;
getrxbyte(&dummy);
getrxdata(&dummy, 1);
strobe(CC2420_SFLUSHRX);
strobe(CC2420_SFLUSHRX);
if(dummy) {
@ -325,39 +419,34 @@ flushrx(void)
}
}
/*---------------------------------------------------------------------------*/
static unsigned int
status(void)
static void
wait_for_status(uint8_t status_bit)
{
uint8_t status;
CC2420_GET_STATUS(status);
return status;
rtimer_clock_t t0;
t0 = RTIMER_NOW();
while(!(get_status() & status_bit)
&& RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (RTIMER_SECOND / 10)));
}
/*---------------------------------------------------------------------------*/
static void
wait_for_status(unsigned int mask)
wait_for_transmission(void)
{
BUSYWAIT_UNTIL((status() & mask), RTIMER_SECOND / 10);
rtimer_clock_t t0;
t0 = RTIMER_NOW();
while((get_status() & BV(CC2420_TX_ACTIVE))
&& RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (RTIMER_SECOND / 10)));
}
/*---------------------------------------------------------------------------*/
static void
wait_for_not_status(unsigned int mask)
{
BUSYWAIT_UNTIL(!(status() & mask), RTIMER_SECOND / 10);
}
/*---------------------------------------------------------------------------*/
static uint8_t locked, lock_on, lock_off;
static void
on(void)
{
CC2420_ENABLE_FIFOP_INT();
strobe(CC2420_SRXON);
wait_for_status(BV(CC2420_XOSC16M_STABLE));
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
receive_on = 1;
}
/*---------------------------------------------------------------------------*/
static void
off(void)
{
@ -365,7 +454,7 @@ off(void)
receive_on = 0;
/* Wait for transmission to end before turning radio off. */
wait_for_not_status(BV(CC2420_TX_ACTIVE));
wait_for_transmission();
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
strobe(CC2420_SRFOFF);
@ -376,6 +465,7 @@ off(void)
}
}
/*---------------------------------------------------------------------------*/
static uint8_t locked, lock_on, lock_off;
#define GET_LOCK() locked++
static void RELEASE_LOCK(void) {
if(locked == 1) {
@ -391,26 +481,47 @@ static void RELEASE_LOCK(void) {
locked--;
}
/*---------------------------------------------------------------------------*/
static unsigned
getreg(enum cc2420_register regname)
static void
init_security(void)
{
unsigned reg;
CC2420_READ_REG(regname, reg);
return reg;
/* only use key 0 */
setreg(CC2420_SECCTRL0, 0);
setreg(CC2420_SECCTRL1, 0);
}
/*---------------------------------------------------------------------------*/
static void
setreg(enum cc2420_register regname, unsigned value)
set_key(uint8_t *key)
{
CC2420_WRITE_REG(regname, value);
GET_LOCK();
write_ram(key, CC2420RAM_KEY0, 16, WRITE_RAM_REVERSE);
RELEASE_LOCK();
}
/*---------------------------------------------------------------------------*/
static void
write_ram(const void *buf, uint16_t addr, int count)
encrypt(uint8_t *plaintext_and_result)
{
CC2420_WRITE_RAM(buf, addr, count);
GET_LOCK();
write_ram(plaintext_and_result,
CC2420RAM_SABUF,
16,
WRITE_RAM_IN_ORDER);
strobe(CC2420_SAES);
while(get_status() & BV(CC2420_ENC_BUSY));
read_ram(plaintext_and_result, CC2420RAM_SABUF, 16);
RELEASE_LOCK();
}
/*---------------------------------------------------------------------------*/
const struct aes_128_driver cc2420_aes_128_driver = {
set_key,
encrypt
};
/*---------------------------------------------------------------------------*/
static void
set_txpower(uint8_t power)
{
@ -422,6 +533,7 @@ set_txpower(uint8_t power)
}
/*---------------------------------------------------------------------------*/
#define AUTOACK (1 << 4)
#define AUTOCRC (1 << 5)
#define ADR_DECODE (1 << 11)
#define RXFIFO_PROTECTION (1 << 9)
#define CORR_THR(n) (((n) & 0x1f) << 6)
@ -451,6 +563,8 @@ cc2420_init(void)
/* Turn on the crystal oscillator. */
strobe(CC2420_SXOSCON);
/* And wait until it stabilizes */
wait_for_status(BV(CC2420_XOSC16M_STABLE));
/* Turn on/off automatic packet acknowledgment and address decoding. */
reg = getreg(CC2420_MDMCTRL0);
@ -460,6 +574,12 @@ cc2420_init(void)
#else
reg &= ~(AUTOACK | ADR_DECODE);
#endif /* CC2420_CONF_AUTOACK */
/* Enabling CRC in hardware; this is required by AUTOACK anyway
and provides us with RSSI and link quality indication (LQI)
information. */
reg |= AUTOCRC;
setreg(CC2420_MDMCTRL0, reg);
/* Set transmission turnaround time to the lower setting (8 symbols
@ -479,10 +599,7 @@ cc2420_init(void)
/* Set the FIFOP threshold to maximum. */
setreg(CC2420_IOCFG0, FIFOP_THR(127));
/* Turn off "Security enable" (page 32). */
reg = getreg(CC2420_SECCTRL0);
reg &= ~RXFIFO_PROTECTION;
setreg(CC2420_SECCTRL0, reg);
init_security();
cc2420_set_pan_addr(0xffff, 0x0000, NULL);
cc2420_set_channel(CC2420_CONF_CHANNEL);
@ -498,10 +615,7 @@ static int
cc2420_transmit(unsigned short payload_len)
{
int i, txpower;
#if CC2420_CONF_CHECKSUM
uint16_t checksum;
#endif /* CC2420_CONF_CHECKSUM */
GET_LOCK();
txpower = 0;
@ -540,11 +654,11 @@ cc2420_transmit(unsigned short payload_len)
if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) {
/* Write timestamp to last two bytes of packet in TXFIFO. */
write_ram(&sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2);
write_ram((uint8_t *) &sfd_timestamp, CC2420RAM_TXFIFO + payload_len - 1, 2, WRITE_RAM_IN_ORDER);
}
}
if(!(status() & BV(CC2420_TX_ACTIVE))) {
if(!(get_status() & BV(CC2420_TX_ACTIVE))) {
/* SFD went high but we are not transmitting. This means that
we just started receiving a packet, so we drop the
transmission. */
@ -557,7 +671,7 @@ cc2420_transmit(unsigned short payload_len)
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
/* We wait until transmission has ended so that we get an
accurate measurement of the transmission time.*/
wait_for_not_status(BV(CC2420_TX_ACTIVE));
wait_for_transmission();
#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2420_get_txpower());
@ -599,9 +713,7 @@ static int
cc2420_prepare(const void *payload, unsigned short payload_len)
{
uint8_t total_len;
#if CC2420_CONF_CHECKSUM
uint16_t checksum;
#endif /* CC2420_CONF_CHECKSUM */
GET_LOCK();
PRINTF("cc2420: sending %d bytes\n", payload_len);
@ -614,16 +726,10 @@ cc2420_prepare(const void *payload, unsigned short payload_len)
/* Write packet to TX FIFO. */
strobe(CC2420_SFLUSHTX);
#if CC2420_CONF_CHECKSUM
checksum = crc16_data(payload, payload_len, 0);
#endif /* CC2420_CONF_CHECKSUM */
total_len = payload_len + AUX_LEN;
CC2420_WRITE_FIFO_BUF(&total_len, 1);
CC2420_WRITE_FIFO_BUF(payload, payload_len);
#if CC2420_CONF_CHECKSUM
CC2420_WRITE_FIFO_BUF(&checksum, CHECKSUM_LEN);
#endif /* CC2420_CONF_CHECKSUM */
total_len = payload_len + CHECKSUM_LEN;
write_fifo_buf(&total_len, 1);
write_fifo_buf(payload, payload_len);
RELEASE_LOCK();
return 0;
}
@ -656,7 +762,7 @@ cc2420_off(void)
we don't actually switch the radio off now, but signal that the
driver should switch off the radio once the packet has been
received and processed, by setting the 'lock_off' variable. */
if(status() & BV(CC2420_TX_ACTIVE)) {
if(get_status() & BV(CC2420_TX_ACTIVE)) {
lock_off = 1;
} else {
off();
@ -701,13 +807,9 @@ cc2420_set_channel(int c)
channel = c;
f = 5 * (c - 11) + 357 + 0x4000;
/*
* Writing RAM requires crystal oscillator to be stable.
*/
wait_for_status(BV(CC2420_XOSC16M_STABLE));
/* Wait for any transmission to end. */
wait_for_not_status(BV(CC2420_TX_ACTIVE));
wait_for_transmission();
setreg(CC2420_FSCTRL, f);
@ -726,30 +828,13 @@ cc2420_set_pan_addr(unsigned pan,
unsigned addr,
const uint8_t *ieee_addr)
{
uint16_t f = 0;
uint8_t tmp[2];
GET_LOCK();
/*
* Writing RAM requires crystal oscillator to be stable.
*/
wait_for_status(BV(CC2420_XOSC16M_STABLE));
tmp[0] = pan & 0xff;
tmp[1] = pan >> 8;
write_ram(&tmp, CC2420RAM_PANID, 2);
tmp[0] = addr & 0xff;
tmp[1] = addr >> 8;
write_ram(&tmp, CC2420RAM_SHORTADDR, 2);
write_ram((uint8_t *) &pan, CC2420RAM_PANID, 2, WRITE_RAM_IN_ORDER);
write_ram((uint8_t *) &addr, CC2420RAM_SHORTADDR, 2, WRITE_RAM_IN_ORDER);
if(ieee_addr != NULL) {
uint8_t tmp_addr[8];
/* LSB first, MSB last for 802.15.4 addresses in CC2420 */
for (f = 0; f < 8; f++) {
tmp_addr[7 - f] = ieee_addr[f];
}
write_ram(tmp_addr, CC2420RAM_IEEEADDR, 8);
write_ram(ieee_addr, CC2420RAM_IEEEADDR, 8, WRITE_RAM_REVERSE);
}
RELEASE_LOCK();
}
@ -764,8 +849,6 @@ cc2420_interrupt(void)
process_poll(&cc2420_process);
last_packet_timestamp = cc2420_sfd_start_time;
/* pending++; */
cc2420_packets_seen++;
return 1;
}
/*---------------------------------------------------------------------------*/
@ -796,99 +879,60 @@ PROCESS_THREAD(cc2420_process, ev, data)
static int
cc2420_read(void *buf, unsigned short bufsize)
{
uint8_t footer[2];
uint8_t footer[FOOTER_LEN];
uint8_t len;
#if CC2420_CONF_CHECKSUM
uint16_t checksum;
#endif /* CC2420_CONF_CHECKSUM */
if(!CC2420_FIFOP_IS_1) {
return 0;
}
/* if(!pending) {
return 0;
}*/
/* pending = 0; */
GET_LOCK();
cc2420_packets_read++;
getrxbyte(&len);
getrxdata(&len, 1);
if(len > CC2420_MAX_PACKET_LEN) {
/* Oops, we must be out of sync. */
flushrx();
RIMESTATS_ADD(badsynch);
RELEASE_LOCK();
return 0;
}
if(len <= AUX_LEN) {
flushrx();
} else if(len <= FOOTER_LEN) {
RIMESTATS_ADD(tooshort);
RELEASE_LOCK();
return 0;
}
if(len - AUX_LEN > bufsize) {
flushrx();
} else if(len - FOOTER_LEN > bufsize) {
RIMESTATS_ADD(toolong);
RELEASE_LOCK();
return 0;
}
getrxdata(buf, len - AUX_LEN);
#if CC2420_CONF_CHECKSUM
getrxdata(&checksum, CHECKSUM_LEN);
#endif /* CC2420_CONF_CHECKSUM */
getrxdata(footer, FOOTER_LEN);
#if CC2420_CONF_CHECKSUM
if(checksum != crc16_data(buf, len - AUX_LEN, 0)) {
PRINTF("checksum failed 0x%04x != 0x%04x\n",
checksum, crc16_data(buf, len - AUX_LEN, 0));
}
if(footer[1] & FOOTER1_CRC_OK &&
checksum == crc16_data(buf, len - AUX_LEN, 0)) {
#else
if(footer[1] & FOOTER1_CRC_OK) {
#endif /* CC2420_CONF_CHECKSUM */
cc2420_last_rssi = footer[0];
cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION;
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2420_last_rssi);
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2420_last_correlation);
RIMESTATS_ADD(llrx);
} else {
RIMESTATS_ADD(badcrc);
len = AUX_LEN;
}
if(CC2420_FIFOP_IS_1) {
if(!CC2420_FIFO_IS_1) {
/* Clean up in case of FIFO overflow! This happens for every
* full length frame and is signaled by FIFOP = 1 and FIFO =
* 0. */
flushrx();
getrxdata((uint8_t *) buf, len - FOOTER_LEN);
getrxdata(footer, FOOTER_LEN);
if(footer[1] & FOOTER1_CRC_OK) {
cc2420_last_rssi = footer[0] + RSSI_OFFSET;
cc2420_last_correlation = footer[1] & FOOTER1_CORRELATION;
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2420_last_rssi);
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2420_last_correlation);
RIMESTATS_ADD(llrx);
} else {
/* Another packet has been received and needs attention. */
process_poll(&cc2420_process);
RIMESTATS_ADD(badcrc);
len = FOOTER_LEN;
}
if(CC2420_FIFOP_IS_1) {
if(!CC2420_FIFO_IS_1) {
/* Clean up in case of FIFO overflow! This happens for every
* full length frame and is signaled by FIFOP = 1 and FIFO =
* 0. */
flushrx();
} else {
/* Another packet has been received and needs attention. */
process_poll(&cc2420_process);
}
}
RELEASE_LOCK();
return len - FOOTER_LEN;
}
flushrx();
RELEASE_LOCK();
if(len < AUX_LEN) {
return 0;
}
return len - AUX_LEN;
return 0;
}
/*---------------------------------------------------------------------------*/
void
@ -927,7 +971,8 @@ cc2420_rssi(void)
}
wait_for_status(BV(CC2420_RSSI_VALID));
rssi = (int)((signed char)getreg(CC2420_RSSI));
rssi = (int)((signed char) getreg(CC2420_RSSI));
rssi += RSSI_OFFSET;
if(radio_was_off) {
cc2420_off();
@ -936,14 +981,6 @@ cc2420_rssi(void)
return rssi;
}
/*---------------------------------------------------------------------------*/
/*
static int
detected_energy(void)
{
return cc2420_rssi();
}
*/
/*---------------------------------------------------------------------------*/
static int
cc2420_cca(void)
{

View file

@ -36,6 +36,7 @@
* \author
* Adam Dunkels <adam@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#ifndef CC2420_H_
@ -45,6 +46,7 @@
#include "dev/spi.h"
#include "dev/radio.h"
#include "cc2420_const.h"
#include "lib/aes-128.h"
int cc2420_init(void);
@ -88,116 +90,6 @@ int cc2420_off(void);
void cc2420_set_cca_threshold(int value);
/************************************************************************/
/* Additional SPI Macros for the CC2420 */
/************************************************************************/
/* Send a strobe to the CC2420 */
#define CC2420_STROBE(s) \
do { \
CC2420_SPI_ENABLE(); \
SPI_WRITE(s); \
CC2420_SPI_DISABLE(); \
} while (0)
/* Write to a register in the CC2420 */
/* Note: the SPI_WRITE(0) seems to be needed for getting the */
/* write reg working on the Z1 / MSP430X platform */
#define CC2420_WRITE_REG(adr,data) \
do { \
CC2420_SPI_ENABLE(); \
SPI_WRITE_FAST(adr); \
SPI_WRITE_FAST((uint8_t)((data) >> 8)); \
SPI_WRITE_FAST((uint8_t)(data & 0xff)); \
SPI_WAITFORTx_ENDED(); \
SPI_WRITE(0); \
CC2420_SPI_DISABLE(); \
} while(0)
/* Read a register in the CC2420 */
#define CC2420_READ_REG(adr,data) \
do { \
CC2420_SPI_ENABLE(); \
SPI_WRITE(adr | 0x40); \
data = (uint8_t)SPI_RXBUF; \
SPI_TXBUF = 0; \
SPI_WAITFOREORx(); \
data = SPI_RXBUF << 8; \
SPI_TXBUF = 0; \
SPI_WAITFOREORx(); \
data |= SPI_RXBUF; \
CC2420_SPI_DISABLE(); \
} while(0)
#define CC2420_READ_FIFO_BYTE(data) \
do { \
CC2420_SPI_ENABLE(); \
SPI_WRITE(CC2420_RXFIFO | 0x40); \
(void)SPI_RXBUF; \
SPI_READ(data); \
clock_delay(1); \
CC2420_SPI_DISABLE(); \
} while(0)
#define CC2420_READ_FIFO_BUF(buffer,count) \
do { \
uint8_t i; \
CC2420_SPI_ENABLE(); \
SPI_WRITE(CC2420_RXFIFO | 0x40); \
(void)SPI_RXBUF; \
for(i = 0; i < (count); i++) { \
SPI_READ(((uint8_t *)(buffer))[i]); \
} \
clock_delay(1); \
CC2420_SPI_DISABLE(); \
} while(0)
#define CC2420_WRITE_FIFO_BUF(buffer,count) \
do { \
uint8_t i; \
CC2420_SPI_ENABLE(); \
SPI_WRITE_FAST(CC2420_TXFIFO); \
for(i = 0; i < (count); i++) { \
SPI_WRITE_FAST(((uint8_t *)(buffer))[i]); \
} \
SPI_WAITFORTx_ENDED(); \
CC2420_SPI_DISABLE(); \
} while(0)
/* Write to RAM in the CC2420 */
#define CC2420_WRITE_RAM(buffer,adr,count) \
do { \
uint8_t i; \
CC2420_SPI_ENABLE(); \
SPI_WRITE_FAST(0x80 | ((adr) & 0x7f)); \
SPI_WRITE_FAST(((adr) >> 1) & 0xc0); \
for(i = 0; i < (count); i++) { \
SPI_WRITE_FAST(((uint8_t*)(buffer))[i]); \
} \
SPI_WAITFORTx_ENDED(); \
CC2420_SPI_DISABLE(); \
} while(0)
/* Read from RAM in the CC2420 */
#define CC2420_READ_RAM(buffer,adr,count) \
do { \
uint8_t i; \
CC2420_SPI_ENABLE(); \
SPI_WRITE(0x80 | ((adr) & 0x7f)); \
SPI_WRITE((((adr) >> 1) & 0xc0) | 0x20); \
SPI_RXBUF; \
for(i = 0; i < (count); i++) { \
SPI_READ(((uint8_t*)(buffer))[i]); \
} \
CC2420_SPI_DISABLE(); \
} while(0)
/* Read status of the CC2420 */
#define CC2420_GET_STATUS(s) \
do { \
CC2420_SPI_ENABLE(); \
SPI_WRITE(CC2420_SNOP); \
s = SPI_RXBUF; \
CC2420_SPI_DISABLE(); \
} while (0)
extern const struct aes_128_driver cc2420_aes_128_driver;
#endif /* CC2420_H_ */

View file

@ -123,5 +123,8 @@ parse(void)
}
/*---------------------------------------------------------------------------*/
const struct framer no_framer = {
hdr_length, create, parse
hdr_length,
create,
framer_canonical_create_and_secure,
parse
};

View file

@ -125,7 +125,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
/* parse frame before sending to get addresses, etc. */
no_framer.parse();
NETSTACK_MAC.send(packet_sent, &packet_ids[packet_pos]);
NETSTACK_LLSEC.send(packet_sent, &packet_ids[packet_pos]);
packet_pos++;
if(packet_pos >= sizeof(packet_ids)) {

View file

@ -0,0 +1,14 @@
CONTIKI_PROJECT = tests
all: $(CONTIKI_PROJECT)
CONTIKI = ../../../..
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
WITH_UIP6=1
UIP_CONF_IPV6=1
CFLAGS+= -DUIP_CONF_IPV6_RPL
#linker optimizations
SMALL=1
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Testing CTR
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#define LLSEC802154_CONF_SECURITY_LEVEL 6

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Testing CTR
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "contiki.h"
#include "net/packetbuf.h"
#include "net/netstack.h"
#include "net/llsec/llsec802154.h"
#include "net/llsec/ccm.h"
#include "net/mac/frame802154.h"
#include "lib/aes-128.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
/* Test vector C.2.1.2 from IEEE 802.15.4-2006 */
static void
test_sec_lvl_6()
{
uint8_t key[16] = { 0xC0 , 0xC1 , 0xC2 , 0xC3 ,
0xC4 , 0xC5 , 0xC6 , 0xC7 ,
0xC8 , 0xC9 , 0xCA , 0xCB ,
0xCC , 0xCD , 0xCE , 0xCF };
uint8_t extended_source_address[8] = { 0xAC , 0xDE , 0x48 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x01 };
uint8_t data[30] = { 0x2B , 0xDC , 0x84 , 0x21 , 0x43 ,
/* Destination Address */
0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0xDE , 0xAC ,
/* PAN-ID */
0xFF , 0xFF ,
/* Source Address */
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0xDE , 0xAC ,
/* Security Level */
0x06 ,
/* Frame Counter */
0x05 , 0x00 , 0x00 , 0x00 ,
0x01 , 0xCE };
uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x4F , 0xDE , 0x52 , 0x90 ,
0x61 , 0xF9 , 0xC6 , 0xF1 };
frame802154_frame_counter_t counter;
uint8_t mic[LLSEC802154_MIC_LENGTH];
printf("Testing verification ... ");
packetbuf_clear();
packetbuf_set_datalen(30);
memcpy(packetbuf_hdrptr(), data, 30);
counter.u32 = 5;
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, counter.u16[1]);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL);
packetbuf_hdrreduce(29);
AES_128.set_key(key);
CCM.mic(extended_source_address, mic, LLSEC802154_MIC_LENGTH);
if(memcmp(mic, oracle, LLSEC802154_MIC_LENGTH) == 0) {
printf("Success\n");
} else {
printf("Failure\n");
}
printf("Testing encryption ... ");
CCM.ctr(extended_source_address);
if(((uint8_t *) packetbuf_hdrptr())[29] == 0xD8) {
printf("Success\n");
} else {
printf("Failure\n");
}
printf("Testing decryption ... ");
CCM.ctr(extended_source_address);
if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) {
printf("Success\n");
} else {
printf("Failure\n");
}
}
/*---------------------------------------------------------------------------*/
PROCESS(ccm_encryption_tests_process, "CCM* encryption tests process");
AUTOSTART_PROCESSES(&ccm_encryption_tests_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ccm_encryption_tests_process, ev, data)
{
PROCESS_BEGIN();
test_sec_lvl_6();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,14 @@
CONTIKI_PROJECT = tests
all: $(CONTIKI_PROJECT)
CONTIKI = ../../../..
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
WITH_UIP6=1
UIP_CONF_IPV6=1
CFLAGS+= -DUIP_CONF_IPV6_RPL
#linker optimizations
SMALL=1
include $(CONTIKI)/Makefile.include

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Testing CCM* MICs
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#define LLSEC802154_CONF_SECURITY_LEVEL 2

View file

@ -0,0 +1,137 @@
/*
* Copyright (c) 2013, Hasso-Plattner-Institut.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* 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.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Testing CCM*-MICs
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
#include "contiki.h"
#include "net/packetbuf.h"
#include "net/netstack.h"
#include "net/llsec/llsec802154.h"
#include "net/llsec/ccm.h"
#include "net/mac/frame802154.h"
#include "lib/aes-128.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
/* Test vector C.1 from FIPS Pub 197 */
static void
test_aes_128()
{
uint8_t key[16] = { 0x00 , 0x01 , 0x02 , 0x03 ,
0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B ,
0x0C , 0x0D , 0x0E , 0x0F };
uint8_t data[16] = { 0x00 , 0x11 , 0x22 , 0x33 ,
0x44 , 0x55 , 0x66 , 0x77 ,
0x88 , 0x99 , 0xAA , 0xBB ,
0xCC , 0xDD , 0xEE , 0xFF };
uint8_t oracle[16] = { 0x69 , 0xC4 , 0xE0 , 0xD8 ,
0x6A , 0x7B , 0x04 , 0x30 ,
0xD8 , 0xCD , 0xB7 , 0x80 ,
0x70 , 0xB4 , 0xC5 , 0x5A };
printf("Testing AES-128 ... ");
AES_128.set_key(key);
AES_128.encrypt(data);
if(memcmp(data, oracle, 16) == 0) {
printf("Success\n");
} else {
printf("Failure\n");
}
}
/*---------------------------------------------------------------------------*/
/* Test vector C.2.1.2 from IEEE 802.15.4-2006 */
static void
test_sec_lvl_2()
{
uint8_t key[16] = { 0xC0 , 0xC1 , 0xC2 , 0xC3 ,
0xC4 , 0xC5 , 0xC6 , 0xC7 ,
0xC8 , 0xC9 , 0xCA , 0xCB ,
0xCC , 0xCD , 0xCE , 0xCF };
uint8_t extended_source_address[8] = { 0xAC , 0xDE , 0x48 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x01 };
uint8_t data[26] = { 0x08 , 0xD0 , 0x84 , 0x21 , 0x43 ,
/* Source Address */
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0xDE , 0xAC ,
/* Security Level*/
0x02 ,
/* Frame Counter */
0x05 , 0x00 , 0x00 , 0x00 ,
/* Payload */
0x55 , 0xCF , 0x00 , 0x00 , 0x51 , 0x52 , 0x53 , 0x54 };
uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x22 , 0x3B , 0xC1 , 0xEC ,
0x84 , 0x1A , 0xB5 , 0x53 };
frame802154_frame_counter_t counter;
uint8_t mic[LLSEC802154_MIC_LENGTH];
printf("Testing verification ... ");
packetbuf_clear();
packetbuf_set_datalen(26);
memcpy(packetbuf_hdrptr(), data, 26);
counter.u32 = 5;
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]);
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, counter.u16[1]);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL);
packetbuf_hdrreduce(18);
AES_128.set_key(key);
CCM.mic(extended_source_address, mic, LLSEC802154_MIC_LENGTH);
if(memcmp(mic, oracle, LLSEC802154_MIC_LENGTH) == 0) {
printf("Success\n");
} else {
printf("Failure\n");
}
}
/*---------------------------------------------------------------------------*/
PROCESS(ccm_verification_tests_process, "CCM* verification tests process");
AUTOSTART_PROCESSES(&ccm_verification_tests_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ccm_verification_tests_process, ev, data)
{
PROCESS_BEGIN();
test_aes_128();
test_sec_lvl_2();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -10,7 +10,7 @@ CFLAGS=-DUIP_CONF_IPV6=0 -DUIP_CONF_IPV6_RPL=0
CONTIKI = ../..
MODULES+=core/net/mac/sicslowmac core/net/mac
MODULES+=core/net/mac/sicslowmac core/net/mac core/net/llsec
PROJECT_SOURCEFILES += fakeuip.c

View file

@ -237,10 +237,8 @@ typedef unsigned short uip_stats_t;
#define NETSTACK_CONF_RDC contikimac_driver
/* Default is two CCA separated by 500 usec */
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8
/* Wireshark won't decode with the header, but padded packets will fail ipv6 checksum */
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
/* So without the header this needed for RPL mesh to form */
#define CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length
#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length
/* Not tested much yet */
#define WITH_PHASE_OPTIMIZATION 0
#define CONTIKIMAC_CONF_COMPOWER 1

View file

@ -35,4 +35,5 @@ AVRDUDE_MCU=m1284p
include $(CONTIKIAVR)/Makefile.avr
include $(CONTIKIAVR)/radio/Makefile.radio
MODULES += core/net/ipv6 core/net/ipv4 core/net/ip core/net/mac core/net core/net/rime core/net/mac/sicslowmac
MODULES += core/net/ipv6 core/net/ipv4 core/net/ip core/net/mac core/net core/net/rime core/net/mac/sicslowmac \
core/net/llsec

View file

@ -253,10 +253,8 @@ typedef unsigned short uip_stats_t;
#define NETSTACK_CONF_RDC contikimac_driver
/* Default is two CCA separated by 500 usec */
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8
/* Wireshark won't decode with the header, but padded packets will fail ipv6 checksum */
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
/* So without the header this needed for RPL mesh to form */
#define CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length
#define CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE 43-18 //multicast RPL DIS length
/* Not tested much yet */
#define WITH_PHASE_OPTIMIZATION 0
#define CONTIKIMAC_CONF_COMPOWER 1

View file

@ -68,7 +68,8 @@ include $(CONTIKIAVR)/radio/Makefile.radio
ifndef CONTIKI_NO_NET
MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 \
core/net/rime core/net/mac core/net/mac/sicslowmac
core/net/rime core/net/mac core/net/mac/sicslowmac \
core/net/llsec
else
vpath %.c $(CONTIKI)/core/net/ipv6
CONTIKI_SOURCEFILES += sicslowpan.c linkaddr.c

View file

@ -47,4 +47,5 @@ CONTIKI_CPU=$(CONTIKI)/cpu/cc253x
include $(CONTIKI_CPU)/Makefile.cc253x
# Default modules
MODULES += core/net/ip core/net/ipv6 core/net/rime core/net core/net/mac core/net/rpl
MODULES += core/net/ip core/net/ipv6 core/net/rime core/net core/net/mac core/net/rpl \
core/net/llsec

View file

@ -28,7 +28,8 @@ CONTIKI_CPU=$(CONTIKI)/cpu/cc2538
include $(CONTIKI_CPU)/Makefile.cc2538
MODULES += core/net core/net/ipv6 core/net/mac core/net/ip \
core/net/rpl core/net/rime core/net/mac/contikimac
core/net/rpl core/net/rime core/net/mac/contikimac \
core/net/llsec
BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py

View file

@ -308,7 +308,6 @@ typedef uint32_t rtimer_clock_t;
#define NULLRDC_802154_AUTOACK_HW 1
/* Configure ContikiMAC for when it's selected */
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0
#define WITH_FAST_SLEEP 1

View file

@ -90,4 +90,5 @@ ifeq ($(UIP_CONF_IPV6),1)
endif # UIP_CONF_IPV6
MODULES += core/net core/net/ip core/net/ipv4 \
core/net/ipv6 core/net/mac core/net/rime core/net/rpl
core/net/ipv6 core/net/mac core/net/rime core/net/rpl \
core/net/llsec

View file

@ -51,7 +51,7 @@ uip_driver_send(void)
/* XXX we should provide a callback function that is called when the
packet is sent. For now, we just supply a NULL pointer. */
NETSTACK_MAC.send(NULL, NULL);
NETSTACK_LLSEC.send(NULL, NULL);
return 1;
}
/*--------------------------------------------------------------------*/

View file

@ -21,4 +21,5 @@ endif
include $(CONTIKIMC1322X)/Makefile.mc1322x
MODULES+=core/net/ip core/net/ipv4 core/net core/net/rpl \
core/net/ipv6 core/net/rime core/net/mac
core/net/ipv6 core/net/rime core/net/mac \
core/net/llsec

View file

@ -62,4 +62,5 @@ MODULES += \
core/net/ipv6 \
core/net/rime \
core/net/mac \
core/net/mac/sicslowmac
core/net/mac/sicslowmac \
core/net/llsec

View file

@ -63,4 +63,5 @@ run: $(CONTIKI_PROJECT).$(TARGET).srec
~/adi-contiki/github/rl78flash/rl78flash -vv -i -m3 $(PROG_UART) -b500000 -a $<
MODULES+=core/net/ip core/net/ipv4 core/net core/net/rpl \
core/net/ipv6 core/net/rime core/net/mac core/net/mac/sicslowmac
core/net/ipv6 core/net/rime core/net/mac core/net/mac/sicslowmac \
core/net/llsec

View file

@ -3,7 +3,7 @@
MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 \
core/net/mac core/net/rpl core/net/rime core/net/mac/contikimac \
dev/cc2420
core/net/llsec dev/cc2420
ifdef IAR
CFLAGS+=-e --vla -Ohz --multiplier=32 --multiplier_location=4C0 --hw_workaround=CPU40 --core=430X --data_model small --double=32 -D__MSP430F5438A__=1

View file

@ -44,7 +44,6 @@
larger than a specified size, if no ContikiMAC header should be
used. */
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define CXMAC_CONF_ANNOUNCEMENTS 0
#define XMAC_CONF_ANNOUNCEMENTS 0

View file

@ -22,4 +22,5 @@ ifeq ($(HOST_OS),Windows)
endif
MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 \
core/net/rpl core/net/rime core/net/mac core/net/mac/contikimac
core/net/rpl core/net/rime core/net/mac core/net/mac/contikimac \
core/net/llsec

View file

@ -125,7 +125,6 @@
larger than a specified size, if no ContikiMAC header should be
used. */
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define UIP_CONF_UDP 1

View file

@ -46,4 +46,5 @@ ifneq ($(strip $(HAVE_PRGBOARD_FILE)), )
endif
MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 core/net/rime \
core/net/mac core/net/rpl core/net/mac/cxmac dev/cc2420
core/net/mac core/net/rpl core/net/mac/cxmac \
core/net/llsec dev/cc2420

View file

@ -47,4 +47,4 @@ CURSES_LIBS ?= -lncurses
TARGET_LIBFILES += $(CURSES_LIBS)
MODULES+=core/net/ip core/net/ipv4 core/net core/net/ipv6 core/net/rime \
core/net/mac core/net/rpl core/ctk
core/net/mac core/net/rpl core/ctk core/net/llsec

View file

@ -87,8 +87,6 @@ typedef uint32_t rtimer_clock_t;
#define RDC_CONF_HARDWARE_CSMA 1
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#ifdef WITH_UIP6
#define UIP_CONF_ROUTER 1
#ifndef UIP_CONF_IPV6_RPL

View file

@ -88,4 +88,5 @@ include $(CONTIKI)/cpu/cc2430/Makefile.cc2430
contiki-$(TARGET).a:# $(addprefix $(OBJECTDIR)/,symbols.rel)
MODULES += core/net/ipv6 core/net/ip core/net/rime core/net core/net/mac core/net/rpl
MODULES += core/net/ipv6 core/net/ip core/net/rime core/net core/net/mac core/net/rpl \
core/net/llsec

View file

@ -1,7 +1,7 @@
# $Id: Makefile.common,v 1.3 2010/08/24 16:24:11 joxe Exp $
ARCH=spi.c ds2411.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c \
cc2420.c cc2420-aes.c cc2420-arch.c cc2420-arch-sfd.c \
cc2420.c cc2420-arch.c cc2420-arch-sfd.c \
sky-sensors.c uip-ipchksum.c \
uart1.c slip_uart1.c uart1-putchar.c

View file

@ -13,4 +13,5 @@ include $(CONTIKI)/platform/sky/Makefile.common
MODULES += core/net/ipv6 core/net/ipv4 core/net/rime core/net/mac \
core/net core/net/ip core/net/rpl \
core/net/mac/contikimac core/net/mac/cxmac \
core/net/llsec core/net/llsec/noncoresec \
dev/cc2420 dev/sht11 dev/ds2411

View file

@ -48,7 +48,6 @@
larger than a specified size, if no ContikiMAC header should be
used. */
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define CXMAC_CONF_ANNOUNCEMENTS 0
#define XMAC_CONF_ANNOUNCEMENTS 0
@ -212,7 +211,9 @@
#define UIP_CONF_TCP_SPLIT 0
#ifndef AES_128_CONF
#define AES_128_CONF cc2420_aes_128_driver
#endif /* AES_128_CONF */
/* include the project config */
/* PROJECT_CONF_H might be defined in the project Makefile */

View file

@ -97,6 +97,13 @@ static uint8_t is_gateway;
#include "experiment-setup.h"
#endif
#define DEBUG 1
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else /* DEBUG */
#define PRINTF(...)
#endif /* DEBUG */
void init_platform(void);
/*---------------------------------------------------------------------------*/
@ -144,11 +151,11 @@ set_rime_addr(void)
}
#endif
linkaddr_set_node_addr(&addr);
printf("Rime started with address ");
PRINTF("Rime started with address ");
for(i = 0; i < sizeof(addr.u8) - 1; i++) {
printf("%d.", addr.u8[i]);
PRINTF("%d.", addr.u8[i]);
}
printf("%d\n", addr.u8[i]);
PRINTF("%d\n", addr.u8[i]);
}
/*---------------------------------------------------------------------------*/
#if !PROCESS_CONF_NO_PROCESS_NAMES
@ -171,9 +178,9 @@ set_gateway(void)
{
if(!is_gateway) {
leds_on(LEDS_RED);
printf("%d.%d: making myself the IP network gateway.\n\n",
PRINTF("%d.%d: making myself the IP network gateway.\n\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
PRINTF("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
uip_ipaddr_to_quad(&uip_hostaddr));
uip_over_mesh_set_gateway(&linkaddr_node_addr);
uip_over_mesh_make_announced_gateway();
@ -182,6 +189,65 @@ set_gateway(void)
}
#endif /* WITH_UIP */
/*---------------------------------------------------------------------------*/
static void
start_autostart_processes()
{
#if !PROCESS_CONF_NO_PROCESS_NAMES
print_processes(autostart_processes);
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
autostart_start(autostart_processes);
}
/*---------------------------------------------------------------------------*/
#if WITH_UIP6
static void
start_uip6()
{
NETSTACK_NETWORK.init();
process_start(&tcpip_process, NULL);
#if DEBUG
PRINTF("Tentative link-local IPv6 address ");
{
uip_ds6_addr_t *lladdr;
int i;
lladdr = uip_ds6_get_link_local(-1);
for(i = 0; i < 7; ++i) {
PRINTF("%02x%02x:", lladdr->ipaddr.u8[i * 2],
lladdr->ipaddr.u8[i * 2 + 1]);
}
PRINTF("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
}
#endif /* DEBUG */
if(!UIP_CONF_IPV6_RPL) {
uip_ipaddr_t ipaddr;
int i;
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
PRINTF("Tentative global IPv6 address ");
for(i = 0; i < 7; ++i) {
PRINTF("%02x%02x:",
ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
}
PRINTF("%02x%02x\n",
ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
}
}
#endif /* WITH_UIP6 */
/*---------------------------------------------------------------------------*/
static void
start_network_layer()
{
#if WITH_UIP6
start_uip6();
#endif /* WITH_UIP6 */
start_autostart_processes();
/* To support link layer security in combination with WITH_UIP and
* TIMESYNCH_CONF_ENABLED further things may need to be moved here */
}
/*---------------------------------------------------------------------------*/
#if WITH_TINYOS_AUTO_IDS
uint16_t TOS_NODE_ID = 0x1234; /* non-zero */
uint16_t TOS_LOCAL_ADDRESS = 0x1234; /* non-zero */
@ -262,21 +328,21 @@ main(int argc, char **argv)
linkaddr_node_addr.u8[1];
memset(longaddr, 0, sizeof(longaddr));
linkaddr_copy((linkaddr_t *)&longaddr, &linkaddr_node_addr);
printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
PRINTF("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
longaddr[0], longaddr[1], longaddr[2], longaddr[3],
longaddr[4], longaddr[5], longaddr[6], longaddr[7]);
cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
}
printf(CONTIKI_VERSION_STRING " started. ");
PRINTF(CONTIKI_VERSION_STRING " started. ");
if(node_id > 0) {
printf("Node id is set to %u.\n", node_id);
PRINTF("Node id is set to %u.\n", node_id);
} else {
printf("Node id is not set.\n");
PRINTF("Node id is not set.\n");
}
/* printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
/* PRINTF("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
ds2411_id[0], ds2411_id[1], ds2411_id[2], ds2411_id[3],
ds2411_id[4], ds2411_id[5], ds2411_id[6], ds2411_id[7]);*/
@ -284,58 +350,28 @@ main(int argc, char **argv)
memcpy(&uip_lladdr.addr, ds2411_id, sizeof(uip_lladdr.addr));
/* Setup nullmac-like MAC for 802.15.4 */
/* sicslowpan_init(sicslowmac_init(&cc2420_driver)); */
/* printf(" %s channel %u\n", sicslowmac_driver.name, CC2420_CONF_CCA_THRESH); */
/* PRINTF(" %s channel %u\n", sicslowmac_driver.name, CC2420_CONF_CCA_THRESH); */
/* Setup X-MAC for 802.15.4 */
queuebuf_init();
NETSTACK_RDC.init();
NETSTACK_MAC.init();
NETSTACK_NETWORK.init();
printf("%s %s, channel check rate %lu Hz, radio channel %u, CCA threshold %i\n",
NETSTACK_MAC.name, NETSTACK_RDC.name,
PRINTF("%s %s %s, channel check rate %lu Hz, radio channel %u, CCA threshold %i\n",
NETSTACK_LLSEC.name, NETSTACK_MAC.name, NETSTACK_RDC.name,
CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
NETSTACK_RDC.channel_check_interval()),
CC2420_CONF_CHANNEL,
CC2420_CONF_CCA_THRESH);
process_start(&tcpip_process, NULL);
printf("Tentative link-local IPv6 address ");
{
uip_ds6_addr_t *lladdr;
int i;
lladdr = uip_ds6_get_link_local(-1);
for(i = 0; i < 7; ++i) {
printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
lladdr->ipaddr.u8[i * 2 + 1]);
}
printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
}
if(!UIP_CONF_IPV6_RPL) {
uip_ipaddr_t ipaddr;
int i;
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
printf("Tentative global IPv6 address ");
for(i = 0; i < 7; ++i) {
printf("%02x%02x:",
ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
}
printf("%02x%02x\n",
ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
}
#else /* WITH_UIP6 */
NETSTACK_RDC.init();
NETSTACK_MAC.init();
NETSTACK_NETWORK.init();
printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
NETSTACK_MAC.name, NETSTACK_RDC.name,
PRINTF("%s %s %s, channel check rate %lu Hz, radio channel %u\n",
NETSTACK_LLSEC.name, NETSTACK_MAC.name, NETSTACK_RDC.name,
CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
NETSTACK_RDC.channel_check_interval()),
CC2420_CONF_CHANNEL);
@ -377,7 +413,7 @@ main(int argc, char **argv)
uip_over_mesh_set_gateway_netif(&slipif);
uip_fw_default(&meshif);
uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
printf("uIP started with IP address %d.%d.%d.%d\n",
PRINTF("uIP started with IP address %d.%d.%d.%d\n",
uip_ipaddr_to_quad(&hostaddr));
}
#endif /* WITH_UIP */
@ -387,12 +423,7 @@ main(int argc, char **argv)
watchdog_start();
#if !PROCESS_CONF_NO_PROCESS_NAMES
print_processes(autostart_processes);
#else /* !PROCESS_CONF_NO_PROCESS_NAMES */
putchar('\n'); /* include putchar() */
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
autostart_start(autostart_processes);
NETSTACK_LLSEC.bootstrap(start_network_layer);
/*
* This is the scheduler loop.

View file

@ -56,4 +56,5 @@ contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/,symbols.o}
MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 core/net/mac \
core/net/rime core/net/mac/contikimac core/net/rpl \
core/net/llsec \
dev/cc2520 dev/sht11

View file

@ -42,7 +42,6 @@
larger than a specified size, if no ContikiMAC header should be
used. */
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define CXMAC_CONF_ANNOUNCEMENTS 0
#define XMAC_CONF_ANNOUNCEMENTS 0

View file

@ -13,7 +13,7 @@ endif
CLEAN += symbols.c symbols.h
ARCH=msp430.c leds.c watchdog.c xmem.c \
spi.c cc2420.c cc2420-aes.c cc2420-arch.c cc2420-arch-sfd.c\
spi.c cc2420.c cc2420-arch.c cc2420-arch-sfd.c\
node-id.c sensors.c button-sensor.c cfs-coffee.c \
radio-sensor.c uart0.c uart0-putchar.c uip-ipchksum.c \
slip.c slip_uart0.c \

View file

@ -11,4 +11,5 @@ endif
MODULES += core/net core/net/ip core/net/ipv6 core/net/ipv4 core/net/rpl \
core/net/rime core/net/mac core/net/mac/contikimac \
core/net/llsec \
dev/cc2420 dev/sht11

View file

@ -51,7 +51,6 @@
larger than a specified size, if no ContikiMAC header should be
used. */
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63
#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0
#define CC2420_CONF_AUTOACK 1
#define NETSTACK_RDC_CHANNEL_CHECK_RATE 8

View file

@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>llsec validation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<identifier>mtype139</identifier>
<description>Verification</description>
<source>[CONTIKI_DIR]/examples/llsec/ccm-tests/verification/tests.c</source>
<commands>make tests.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<identifier>mtype792</identifier>
<description>Encryption</description>
<source>[CONTIKI_DIR]/examples/llsec/ccm-tests/encryption/tests.c</source>
<commands>make tests.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>8.103036578104216</x>
<y>28.0005728229897</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype139</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>87.3441626132979</x>
<y>25.080887412193555</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype792</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>280</width>
<z>4</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<moterelations>true</moterelations>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<viewport>4.451315754531486 0.0 0.0 4.451315754531486 -18.43281074329661 54.85882989079608</viewport>
</plugin_config>
<width>400</width>
<z>3</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter>Success</filter>
<formatted_time />
<coloring />
</plugin_config>
<width>1520</width>
<z>2</z>
<height>240</height>
<location_x>400</location_x>
<location_y>160</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Notes
<plugin_config>
<notes>A simple test script that runs the tests in examples/llsec/ccm-tests/</notes>
<decorations>true</decorations>
</plugin_config>
<width>1240</width>
<z>0</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.ScriptRunner
<plugin_config>
<script>TIMEOUT(2000, log.log("last message: " + msg + "\n"));&#xD;
var successes = 0;&#xD;
do {&#xD;
YIELD();&#xD;
if(msg.contains('Success')) {&#xD;
successes++;&#xD;
}&#xD;
} while(successes &lt; 5);&#xD;
&#xD;
log.testOK();</script>
<active>true</active>
</plugin_config>
<width>600</width>
<z>1</z>
<height>700</height>
<location_x>288</location_x>
<location_y>199</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1 @@
include ../Makefile.simulation-test