Merge pull request #1425 from kkrentz/llsec-fixes

random LLSEC fixes
This commit is contained in:
Simon Duquennoy 2016-04-19 17:29:00 +02:00
commit d828557563
25 changed files with 167 additions and 146 deletions

View file

@ -78,13 +78,6 @@
#define NETSTACK_CONF_LLSEC nullsec_driver #define NETSTACK_CONF_LLSEC nullsec_driver
#endif /* NETSTACK_CONF_LLSEC */ #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 /* NETSTACK_CONF_NETWORK specifies the network layer and can be either
sicslowpan_driver, for IPv6 networking, or rime_driver, for the sicslowpan_driver, for IPv6 networking, or rime_driver, for the
custom Rime network stack. */ custom Rime network stack. */

5
core/net/llsec/README.md Normal file
View file

@ -0,0 +1,5 @@
Link layer security is implemented as a new netstack layer, which is located in between the MAC and the NETWORK layer. The interface of LLSEC drivers is defined in [llsec.h](llsec.h). Additionally, LLSEC drivers may define a special [FRAMER](../mac/framer.h), which calls the actual FRAMER underneath. By default, the LLSEC driver `nullsec` is used, which does nothing.
# TODO
* Most main files do not call LLSEC.init, yet

View file

@ -45,6 +45,9 @@
#include "net/llsec/anti-replay.h" #include "net/llsec/anti-replay.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include "net/llsec/llsec802154.h"
#if LLSEC802154_USES_FRAME_COUNTER
/* This node's current frame counter value */ /* This node's current frame counter value */
static uint32_t counter; static uint32_t counter;
@ -107,5 +110,6 @@ anti_replay_was_replayed(struct anti_replay_info *info)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* LLSEC802154_USES_FRAME_COUNTER */
/** @} */ /** @} */

View file

@ -41,8 +41,11 @@
#include "llsec/ccm-star-packetbuf.h" #include "llsec/ccm-star-packetbuf.h"
#include "net/linkaddr.h" #include "net/linkaddr.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include "net/llsec/llsec802154.h"
#include <string.h> #include <string.h>
#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static const uint8_t * static const uint8_t *
get_extended_address(const linkaddr_t *addr) get_extended_address(const linkaddr_t *addr)
@ -76,3 +79,4 @@ ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward)
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */

View file

@ -56,28 +56,13 @@
#include "net/mac/frame802154.h" #include "net/mac/frame802154.h"
#include "net/ip/uip.h" #include "net/ip/uip.h"
#ifdef LLSEC802154_CONF_SECURITY_LEVEL #ifdef LLSEC802154_CONF_ENABLED
#define LLSEC802154_SECURITY_LEVEL LLSEC802154_CONF_SECURITY_LEVEL #define LLSEC802154_ENABLED LLSEC802154_CONF_ENABLED
#else /* LLSEC802154_CONF_SECURITY_LEVEL */ #else /* LLSEC802154_CONF_ENABLED */
#define LLSEC802154_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE #define LLSEC802154_ENABLED 0
#endif /* LLSEC802154_CONF_SECURITY_LEVEL */ #endif /* LLSEC802154_CONF_ENABLED */
#if ((LLSEC802154_SECURITY_LEVEL < 0) || (LLSEC802154_SECURITY_LEVEL > 7)) #define LLSEC802154_MIC_LEN(sec_lvl) (2 << (sec_lvl & 3))
#error "unsupported security level"
#endif
#define LLSEC802154_SECURITY_LEVEL_MIC (LLSEC802154_SECURITY_LEVEL & 3)
#if LLSEC802154_SECURITY_LEVEL_MIC
#define LLSEC802154_MIC_LENGTH (2 << LLSEC802154_SECURITY_LEVEL_MIC)
#else
#define LLSEC802154_MIC_LENGTH 0
#endif
#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 #ifdef LLSEC802154_CONF_USES_EXPLICIT_KEYS
#define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS #define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS
@ -88,9 +73,15 @@
#ifdef LLSEC802154_CONF_USES_FRAME_COUNTER #ifdef LLSEC802154_CONF_USES_FRAME_COUNTER
#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_CONF_USES_FRAME_COUNTER #define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_CONF_USES_FRAME_COUNTER
#else /* LLSEC802154_CONF_USES_FRAME_COUNTER */ #else /* LLSEC802154_CONF_USES_FRAME_COUNTER */
#define LLSEC802154_USES_FRAME_COUNTER (LLSEC802154_SECURITY_LEVEL != FRAME802154_SECURITY_LEVEL_NONE) #define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_ENABLED
#endif /* LLSEC802154_CONF_USES_FRAME_COUNTER */ #endif /* LLSEC802154_CONF_USES_FRAME_COUNTER */
#ifdef LLSEC802154_CONF_USES_AUX_HEADER
#define LLSEC802154_USES_AUX_HEADER LLSEC802154_CONF_USES_AUX_HEADER
#else /* LLSEC802154_CONF_USES_AUX_HEADER */
#define LLSEC802154_USES_AUX_HEADER LLSEC802154_ENABLED
#endif /* LLSEC802154_CONF_USES_AUX_HEADER */
#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN #if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN
#define LLSEC802154_HTONS(n) (n) #define LLSEC802154_HTONS(n) (n)
#define LLSEC802154_HTONL(n) (n) #define LLSEC802154_HTONL(n) (n)

View file

@ -0,0 +1,21 @@
`noncoresec` is a noncompromise-resilient 802.15.4 security implementation, which uses a network-wide key. Add these lines to your `project_conf.h` to enable `noncoresec`:
```c
#undef LLSEC802154_CONF_ENABLED
#define LLSEC802154_CONF_ENABLED 1
#undef NETSTACK_CONF_FRAMER
#define NETSTACK_CONF_FRAMER noncoresec_framer
#undef NETSTACK_CONF_LLSEC
#define NETSTACK_CONF_LLSEC noncoresec_driver
#undef NONCORESEC_CONF_SEC_LVL
#define NONCORESEC_CONF_SEC_LVL 1
```
`NONCORESEC_CONF_SEC_LVL` defines the length of MICs and whether encryption is enabled or not.
Setting the network-wide key works as follows:
```c
#define NONCORESEC_CONF_KEY { 0x00 , 0x01 , 0x02 , 0x03 , \
0x04 , 0x05 , 0x06 , 0x07 , \
0x08 , 0x09 , 0x0A , 0x0B , \
0x0C , 0x0D , 0x0E , 0x0F }
```

View file

@ -47,7 +47,6 @@
#include "net/llsec/llsec802154.h" #include "net/llsec/llsec802154.h"
#include "net/llsec/ccm-star-packetbuf.h" #include "net/llsec/ccm-star-packetbuf.h"
#include "net/mac/frame802154.h" #include "net/mac/frame802154.h"
#include "net/mac/framer-802154.h"
#include "net/netstack.h" #include "net/netstack.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include "net/nbr-table.h" #include "net/nbr-table.h"
@ -55,7 +54,22 @@
#include "lib/ccm-star.h" #include "lib/ccm-star.h"
#include <string.h> #include <string.h>
#define WITH_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2)) #ifdef NONCORESEC_CONF_DECORATED_FRAMER
#define DECORATED_FRAMER NONCORESEC_CONF_DECORATED_FRAMER
#else /* NONCORESEC_CONF_DECORATED_FRAMER */
#define DECORATED_FRAMER framer_802154
#endif /* NONCORESEC_CONF_DECORATED_FRAMER */
extern const struct framer DECORATED_FRAMER;
#ifdef NONCORESEC_CONF_SEC_LVL
#define SEC_LVL NONCORESEC_CONF_SEC_LVL
#else /* NONCORESEC_CONF_SEC_LVL */
#define SEC_LVL 2
#endif /* NONCORESEC_CONF_SEC_LVL */
#define WITH_ENCRYPTION (SEC_LVL & (1 << 2))
#define MIC_LEN LLSEC802154_MIC_LEN(SEC_LVL)
#ifdef NONCORESEC_CONF_KEY #ifdef NONCORESEC_CONF_KEY
#define NONCORESEC_KEY NONCORESEC_CONF_KEY #define NONCORESEC_KEY NONCORESEC_CONF_KEY
@ -76,6 +90,8 @@
#define PRINTF(...) #define PRINTF(...)
#endif /* DEBUG */ #endif /* DEBUG */
#if LLSEC802154_USES_AUX_HEADER && SEC_LVL && LLSEC802154_USES_FRAME_COUNTER
/* network-wide CCM* key */ /* network-wide CCM* key */
static uint8_t key[16] = NONCORESEC_KEY; static uint8_t key[16] = NONCORESEC_KEY;
NBR_TABLE(struct anti_replay_info, anti_replay_table); NBR_TABLE(struct anti_replay_info, anti_replay_table);
@ -91,7 +107,7 @@ aead(uint8_t hdrlen, int forward)
uint8_t *a; uint8_t *a;
uint8_t a_len; uint8_t a_len;
uint8_t *result; uint8_t *result;
uint8_t generated_mic[LLSEC802154_MIC_LENGTH]; uint8_t generated_mic[MIC_LEN];
uint8_t *mic; uint8_t *mic;
ccm_star_packetbuf_set_nonce(nonce, forward); ccm_star_packetbuf_set_nonce(nonce, forward);
@ -113,30 +129,29 @@ aead(uint8_t hdrlen, int forward)
CCM_STAR.aead(nonce, CCM_STAR.aead(nonce,
m, m_len, m, m_len,
a, a_len, a, a_len,
result, LLSEC802154_MIC_LENGTH, result, MIC_LEN,
forward); forward);
if(forward) { if(forward) {
packetbuf_set_datalen(packetbuf_datalen() + LLSEC802154_MIC_LENGTH); packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN);
return 1; return 1;
} else { } else {
return (memcmp(generated_mic, mic, LLSEC802154_MIC_LENGTH) == 0); return (memcmp(generated_mic, mic, MIC_LEN) == 0);
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
add_security_header(void) add_security_header(void)
{ {
if(!packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) {
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL);
anti_replay_set_counter();
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
send(mac_callback_t sent, void *ptr) send(mac_callback_t sent, void *ptr)
{ {
add_security_header();
anti_replay_set_counter();
NETSTACK_MAC.send(sent, ptr); NETSTACK_MAC.send(sent, ptr);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -145,8 +160,7 @@ create(void)
{ {
int result; int result;
add_security_header(); result = DECORATED_FRAMER.create();
result = framer_802154.create();
if(result == FRAMER_FAILED) { if(result == FRAMER_FAILED) {
return result; return result;
} }
@ -163,12 +177,12 @@ parse(void)
const linkaddr_t *sender; const linkaddr_t *sender;
struct anti_replay_info* info; struct anti_replay_info* info;
result = framer_802154.parse(); result = DECORATED_FRAMER.parse();
if(result == FRAMER_FAILED) { if(result == FRAMER_FAILED) {
return result; return result;
} }
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) { if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != SEC_LVL) {
PRINTF("noncoresec: received frame with wrong security level\n"); PRINTF("noncoresec: received frame with wrong security level\n");
return FRAMER_FAILED; return FRAMER_FAILED;
} }
@ -178,7 +192,7 @@ parse(void)
return FRAMER_FAILED; return FRAMER_FAILED;
} }
packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH); packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN);
if(!aead(result, 0)) { if(!aead(result, 0)) {
PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n", PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n",
@ -233,7 +247,7 @@ static int
length(void) length(void)
{ {
add_security_header(); add_security_header();
return framer_802154.length() + LLSEC802154_MIC_LENGTH; return DECORATED_FRAMER.length() + MIC_LEN;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void
@ -256,5 +270,6 @@ const struct framer noncoresec_framer = {
parse parse
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#endif /* LLSEC802154_USES_AUX_HEADER && SEC_LVL && LLSEC802154_USES_FRAME_COUNTER */
/** @} */ /** @} */

View file

@ -102,7 +102,7 @@ addr_len(uint8_t mode)
} }
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
#if LLSEC802154_USES_EXPLICIT_KEYS #if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS
static uint8_t static uint8_t
get_key_id_len(uint8_t key_id_mode) get_key_id_len(uint8_t key_id_mode)
{ {
@ -117,7 +117,7 @@ get_key_id_len(uint8_t key_id_mode)
return 0; return 0;
} }
} }
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Get current PAN ID */ /* Get current PAN ID */
uint16_t uint16_t
@ -317,7 +317,7 @@ field_len(frame802154_t *p, field_length_t *flen)
flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3); flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3);
flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3); flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3);
#if LLSEC802154_SECURITY_LEVEL #if LLSEC802154_USES_AUX_HEADER
/* Aux security header */ /* Aux security header */
if(p->fcf.security_enabled & 1) { if(p->fcf.security_enabled & 1) {
flen->aux_sec_len = 1; /* FCF + possibly frame counter and key ID */ flen->aux_sec_len = 1; /* FCF + possibly frame counter and key ID */
@ -333,7 +333,7 @@ field_len(frame802154_t *p, field_length_t *flen)
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
; ;
} }
#endif /* LLSEC802154_SECURITY_LEVEL */ #endif /* LLSEC802154_USES_AUX_HEADER */
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/** /**
@ -418,7 +418,7 @@ frame802154_create(frame802154_t *p, uint8_t *buf)
for(c = flen.src_addr_len; c > 0; c--) { for(c = flen.src_addr_len; c > 0; c--) {
buf[pos++] = p->src_addr[c - 1]; buf[pos++] = p->src_addr[c - 1];
} }
#if LLSEC802154_SECURITY_LEVEL #if LLSEC802154_USES_AUX_HEADER
/* Aux header */ /* Aux header */
if(flen.aux_sec_len) { if(flen.aux_sec_len) {
buf[pos++] = p->aux_hdr.security_control.security_level buf[pos++] = p->aux_hdr.security_control.security_level
@ -447,7 +447,7 @@ frame802154_create(frame802154_t *p, uint8_t *buf)
} }
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
} }
#endif /* LLSEC802154_SECURITY_LEVEL */ #endif /* LLSEC802154_USES_AUX_HEADER */
return (int)pos; return (int)pos;
} }
@ -570,7 +570,7 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
pf->src_pid = 0; pf->src_pid = 0;
} }
#if LLSEC802154_SECURITY_LEVEL #if LLSEC802154_USES_AUX_HEADER
if(fcf.security_enabled) { if(fcf.security_enabled) {
pf->aux_hdr.security_control.security_level = p[0] & 7; pf->aux_hdr.security_control.security_level = p[0] & 7;
#if LLSEC802154_USES_EXPLICIT_KEYS #if LLSEC802154_USES_EXPLICIT_KEYS
@ -599,7 +599,7 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
} }
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
} }
#endif /* LLSEC802154_SECURITY_LEVEL */ #endif /* LLSEC802154_USES_AUX_HEADER */
/* header length */ /* header length */
c = p - data; c = p - data;

View file

@ -98,7 +98,7 @@ create_frame(int type, int do_create)
/* Insert IEEE 802.15.4 version bits. */ /* Insert IEEE 802.15.4 version bits. */
params.fcf.frame_version = FRAME802154_VERSION; params.fcf.frame_version = FRAME802154_VERSION;
#if LLSEC802154_SECURITY_LEVEL #if LLSEC802154_USES_AUX_HEADER
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) {
params.fcf.security_enabled = 1; params.fcf.security_enabled = 1;
} }
@ -116,7 +116,7 @@ create_frame(int type, int do_create)
params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); 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); params.aux_hdr.key_source.u16[0] = packetbuf_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY_LEVEL */ #endif /* LLSEC802154_USES_AUX_HEADER */
/* Increment and set the data sequence number. */ /* Increment and set the data sequence number. */
if(!do_create) { if(!do_create) {
@ -238,7 +238,7 @@ parse(void)
packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq);
#endif #endif
#if LLSEC802154_SECURITY_LEVEL #if LLSEC802154_USES_AUX_HEADER
if(frame.fcf.security_enabled) { if(frame.fcf.security_enabled) {
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level);
#if LLSEC802154_USES_FRAME_COUNTER #if LLSEC802154_USES_FRAME_COUNTER
@ -251,7 +251,7 @@ parse(void)
packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
} }
#endif /* LLSEC802154_SECURITY_LEVEL */ #endif /* LLSEC802154_USES_AUX_HEADER */
PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTF("15.4-IN: %2X", frame.fcf.frame_type);
PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));

View file

@ -51,7 +51,7 @@
frame because it has seen its sequence number already. Replay frame because it has seen its sequence number already. Replay
protection should be implemented at the LLSEC layer where the protection should be implemented at the LLSEC layer where the
authenticity of frames is verified. */ authenticity of frames is verified. */
#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_SECURITY_LEVEL #define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_ENABLED
#endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */ #endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */
/* List of packets to be sent by RDC layer */ /* List of packets to be sent by RDC layer */

View file

@ -128,8 +128,8 @@ To configure TSCH, see the macros in `.h` files under `core/net/mac/tsch/` and r
To include TSCH standard-compliant security, set the following: To include TSCH standard-compliant security, set the following:
``` ```
/* Enable security */ /* Enable security */
#undef LLSEC802154_CONF_SECURITY_LEVEL #undef LLSEC802154_CONF_ENABLED
#define LLSEC802154_CONF_SECURITY_LEVEL 1 #define LLSEC802154_CONF_ENABLED 1
/* TSCH uses explicit keys to identify k1 and k2 */ /* TSCH uses explicit keys to identify k1 and k2 */
#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS #undef LLSEC802154_CONF_USES_EXPLICIT_KEYS
#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 #define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1

View file

@ -94,7 +94,7 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size,
p.src_pid = IEEE802154_PANID; p.src_pid = IEEE802154_PANID;
linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr); linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr);
#endif #endif
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(tsch_is_pan_secured) { if(tsch_is_pan_secured) {
p.fcf.security_enabled = 1; p.fcf.security_enabled = 1;
p.aux_hdr.security_control.security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK; p.aux_hdr.security_control.security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK;
@ -103,7 +103,7 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size,
p.aux_hdr.security_control.frame_counter_size = 1; p.aux_hdr.security_control.frame_counter_size = 1;
p.aux_hdr.key_index = TSCH_SECURITY_KEY_INDEX_ACK; p.aux_hdr.key_index = TSCH_SECURITY_KEY_INDEX_ACK;
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
if((curr_len = frame802154_create(&p, buf)) == 0) { if((curr_len = frame802154_create(&p, buf)) == 0) {
return 0; return 0;
@ -166,13 +166,13 @@ tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
if(frame->fcf.ie_list_present) { if(frame->fcf.ie_list_present) {
int mic_len = 0; int mic_len = 0;
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
/* Check if there is space for the security MIC (if any) */ /* Check if there is space for the security MIC (if any) */
mic_len = tsch_security_mic_len(frame); mic_len = tsch_security_mic_len(frame);
if(buf_size < curr_len + mic_len) { if(buf_size < curr_len + mic_len) {
return 0; return 0;
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
/* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */
if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
return 0; return 0;
@ -222,7 +222,7 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
p.dest_addr[0] = 0xff; p.dest_addr[0] = 0xff;
p.dest_addr[1] = 0xff; p.dest_addr[1] = 0xff;
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(tsch_is_pan_secured) { if(tsch_is_pan_secured) {
p.fcf.security_enabled = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0; p.fcf.security_enabled = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0;
p.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); p.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
@ -231,7 +231,7 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
p.aux_hdr.security_control.frame_counter_size = 1; p.aux_hdr.security_control.frame_counter_size = 1;
p.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); p.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX);
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
if((curr_len = frame802154_create(&p, buf)) == 0) { if((curr_len = frame802154_create(&p, buf)) == 0) {
return 0; return 0;
@ -387,14 +387,14 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
if(frame->fcf.ie_list_present) { if(frame->fcf.ie_list_present) {
/* Calculate space needed for the security MIC, if any, before attempting to parse IEs */ /* Calculate space needed for the security MIC, if any, before attempting to parse IEs */
int mic_len = 0; int mic_len = 0;
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(!frame_without_mic) { if(!frame_without_mic) {
mic_len = tsch_security_mic_len(frame); mic_len = tsch_security_mic_len(frame);
if(buf_size < curr_len + mic_len) { if(buf_size < curr_len + mic_len) {
return 0; return 0;
} }
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
/* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */
if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {

View file

@ -39,22 +39,23 @@
#include "net/mac/tsch/tsch-asn.h" #include "net/mac/tsch/tsch-asn.h"
#include "net/mac/tsch/tsch-private.h" #include "net/mac/tsch/tsch-private.h"
#include "net/mac/frame802154.h" #include "net/mac/frame802154.h"
#include "net/llsec/llsec802154.h"
#include "net/mac/frame802154e-ie.h" #include "net/mac/frame802154e-ie.h"
/******** Configuration *******/ /******** Configuration *******/
/* To enable TSCH security: /* To enable TSCH security:
* - set LLSEC802154_CONF_SECURITY_LEVEL * - set LLSEC802154_CONF_ENABLED
* - set LLSEC802154_CONF_USES_EXPLICIT_KEYS * - set LLSEC802154_CONF_USES_EXPLICIT_KEYS
* - unset LLSEC802154_CONF_USES_FRAME_COUNTER * - unset LLSEC802154_CONF_USES_FRAME_COUNTER
* */ * */
#define TSCH_SECURITY_ENABLED (LLSEC802154_CONF_SECURITY_LEVEL != 0)
#if TSCH_SECURITY_ENABLED && !LLSEC802154_CONF_USES_EXPLICIT_KEYS #if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS
#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_EXPLICIT_KEYS unset #error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
#if TSCH_SECURITY_ENABLED && LLSEC802154_CONF_USES_FRAME_COUNTER #if LLSEC802154_ENABLED && LLSEC802154_USES_FRAME_COUNTER
#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_FRAME_COUNTER set #error LLSEC802154_ENABLED set but LLSEC802154_USES_FRAME_COUNTER set
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
/* K1, defined in 6TiSCH minimal, is well-known (offers no security) and used for EBs only */ /* K1, defined in 6TiSCH minimal, is well-known (offers no security) and used for EBs only */
#ifdef TSCH_SECURITY_CONF_K1 #ifdef TSCH_SECURITY_CONF_K1

View file

@ -404,10 +404,10 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
} else { } else {
/* packet payload */ /* packet payload */
static void *packet; static void *packet;
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
/* encrypted payload */ /* encrypted payload */
static uint8_t encrypted_packet[TSCH_PACKET_MAX_LEN]; static uint8_t encrypted_packet[TSCH_PACKET_MAX_LEN];
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
/* packet payload length */ /* packet payload length */
static uint8_t packet_len; static uint8_t packet_len;
/* packet seqno */ /* packet seqno */
@ -434,7 +434,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
packet_ready = 1; packet_ready = 1;
} }
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(tsch_is_pan_secured) { if(tsch_is_pan_secured) {
/* If we are going to encrypt, we need to generate the output in a separate buffer and keep /* If we are going to encrypt, we need to generate the output in a separate buffer and keep
* the original untouched. This is to allow for future retransmissions. */ * the original untouched. This is to allow for future retransmissions. */
@ -445,7 +445,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
packet = encrypted_packet; packet = encrypted_packet;
} }
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
/* prepare packet to send: copy to radio buffer */ /* prepare packet to send: copy to radio buffer */
if(packet_ready && NETSTACK_RADIO.prepare(packet, packet_len) == 0) { /* 0 means success */ if(packet_ready && NETSTACK_RADIO.prepare(packet, packet_len) == 0) { /* 0 means success */
@ -530,7 +530,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
ack_len = 0; ack_len = 0;
} }
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(ack_len != 0) { if(ack_len != 0) {
if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame), if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame),
&frame, &current_neighbor->addr, &current_asn)) { &frame, &current_neighbor->addr, &current_asn)) {
@ -544,7 +544,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
snprintf(log->message, sizeof(log->message), snprintf(log->message, sizeof(log->message),
"!failed to parse ACK")); "!failed to parse ACK"));
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
} }
if(ack_len != 0) { if(ack_len != 0) {
@ -604,7 +604,11 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
log->tx.drift = drift_correction; log->tx.drift = drift_correction;
log->tx.drift_used = is_drift_correction_used; log->tx.drift_used = is_drift_correction_used;
log->tx.is_data = ((((uint8_t *)(queuebuf_dataptr(current_packet->qb)))[0]) & 7) == FRAME802154_DATAFRAME; log->tx.is_data = ((((uint8_t *)(queuebuf_dataptr(current_packet->qb)))[0]) & 7) == FRAME802154_DATAFRAME;
#if LLSEC802154_ENABLED
log->tx.sec_level = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL); log->tx.sec_level = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL);
#else /* LLSEC802154_ENABLED */
log->tx.sec_level = 0;
#endif /* LLSEC802154_ENABLED */
log->tx.dest = TSCH_LOG_ID_FROM_LINKADDR(queuebuf_addr(current_packet->qb, PACKETBUF_ADDR_RECEIVER)); log->tx.dest = TSCH_LOG_ID_FROM_LINKADDR(queuebuf_addr(current_packet->qb, PACKETBUF_ADDR_RECEIVER));
); );
@ -708,7 +712,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
packet_duration = TSCH_PACKET_DURATION(current_input->len); packet_duration = TSCH_PACKET_DURATION(current_input->len);
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
/* Decrypt and verify incoming frame */ /* Decrypt and verify incoming frame */
if(frame_valid) { if(frame_valid) {
if(tsch_security_parse_frame( if(tsch_security_parse_frame(
@ -727,7 +731,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
"!failed to parse frame %u %u", header_len, current_input->len)); "!failed to parse frame %u %u", header_len, current_input->len));
frame_valid = 0; frame_valid = 0;
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
if(frame_valid) { if(frame_valid) {
if(linkaddr_cmp(&destination_address, &linkaddr_node_addr) if(linkaddr_cmp(&destination_address, &linkaddr_node_addr)
@ -761,12 +765,12 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf), ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf),
&source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack); &source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack);
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(tsch_is_pan_secured) { if(tsch_is_pan_secured) {
/* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */ /* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */
ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, &current_asn); ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, &current_asn);
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
/* Copy to radio buffer */ /* Copy to radio buffer */
NETSTACK_RADIO.prepare((const void *)ack_buf, ack_len); NETSTACK_RADIO.prepare((const void *)ack_buf, ack_len);

View file

@ -141,7 +141,7 @@ int tsch_is_coordinator = 0;
/* Are we associated to a TSCH network? */ /* Are we associated to a TSCH network? */
int tsch_is_associated = 0; int tsch_is_associated = 0;
/* Is the PAN running link-layer security? */ /* Is the PAN running link-layer security? */
int tsch_is_pan_secured = TSCH_SECURITY_ENABLED; int tsch_is_pan_secured = LLSEC802154_ENABLED;
/* The current Absolute Slot Number (ASN) */ /* The current Absolute Slot Number (ASN) */
struct asn_t current_asn; struct asn_t current_asn;
/* Device rank or join priority: /* Device rank or join priority:
@ -177,7 +177,7 @@ tsch_set_coordinator(int enable)
void void
tsch_set_pan_secured(int enable) tsch_set_pan_secured(int enable)
{ {
tsch_is_pan_secured = TSCH_SECURITY_ENABLED && enable; tsch_is_pan_secured = LLSEC802154_ENABLED && enable;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
void void
@ -455,21 +455,21 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
} }
#endif /* TSCH_JOIN_SECURED_ONLY */ #endif /* TSCH_JOIN_SECURED_ONLY */
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(!tsch_security_parse_frame(input_eb->payload, hdrlen, if(!tsch_security_parse_frame(input_eb->payload, hdrlen,
input_eb->len - hdrlen - tsch_security_mic_len(&frame), input_eb->len - hdrlen - tsch_security_mic_len(&frame),
&frame, (linkaddr_t*)&frame.src_addr, &current_asn)) { &frame, (linkaddr_t*)&frame.src_addr, &current_asn)) {
PRINTF("TSCH:! parse_eb: failed to authenticate\n"); PRINTF("TSCH:! parse_eb: failed to authenticate\n");
return 0; return 0;
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
#if !TSCH_SECURITY_ENABLED #if !LLSEC802154_ENABLED
if(frame.fcf.security_enabled == 1) { if(frame.fcf.security_enabled == 1) {
PRINTF("TSCH:! parse_eb: we do not support security, but EB is secured\n"); PRINTF("TSCH:! parse_eb: we do not support security, but EB is secured\n");
return 0; return 0;
} }
#endif /* !TSCH_SECURITY_ENABLED */ #endif /* !LLSEC802154_ENABLED */
#if TSCH_JOIN_MY_PANID_ONLY #if TSCH_JOIN_MY_PANID_ONLY
/* Check if the EB comes from the PAN ID we expect */ /* Check if the EB comes from the PAN ID we expect */
@ -746,14 +746,14 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data)
} }
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(tsch_is_pan_secured) { if(tsch_is_pan_secured) {
/* Set security level, key id and index */ /* Set security level, key id and index */
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_EB); packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_EB);
packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */ packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */
packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_EB); packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_EB);
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE, eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE,
tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset); tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset);
if(eb_len != 0) { if(eb_len != 0) {
@ -907,14 +907,14 @@ send_packet(mac_callback_t sent, void *ptr)
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
#if TSCH_SECURITY_ENABLED #if LLSEC802154_ENABLED
if(tsch_is_pan_secured) { if(tsch_is_pan_secured) {
/* Set security level, key id and index */ /* Set security level, key id and index */
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_OTHER); packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_OTHER);
packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */ packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */
packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_OTHER); packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_OTHER);
} }
#endif /* TSCH_SECURITY_ENABLED */ #endif /* LLSEC802154_ENABLED */
packet_count_before = tsch_queue_packet_count(addr); packet_count_before = tsch_queue_packet_count(addr);

View file

@ -84,8 +84,8 @@
#ifdef TSCH_CONF_JOIN_SECURED_ONLY #ifdef TSCH_CONF_JOIN_SECURED_ONLY
#define TSCH_JOIN_SECURED_ONLY TSCH_CONF_JOIN_SECURED_ONLY #define TSCH_JOIN_SECURED_ONLY TSCH_CONF_JOIN_SECURED_ONLY
#else #else
/* By default, set if TSCH_SECURITY_ENABLED is also non-zero */ /* By default, set if LLSEC802154_ENABLED is also non-zero */
#define TSCH_JOIN_SECURED_ONLY TSCH_SECURITY_ENABLED #define TSCH_JOIN_SECURED_ONLY LLSEC802154_ENABLED
#endif #endif
/* By default, join any PAN ID. Otherwise, wait for an EB from IEEE802154_PANID */ /* By default, join any PAN ID. Otherwise, wait for an EB from IEEE802154_PANID */

View file

@ -255,9 +255,9 @@ enum {
#endif /* NETSTACK_CONF_WITH_RIME */ #endif /* NETSTACK_CONF_WITH_RIME */
PACKETBUF_ATTR_PENDING, PACKETBUF_ATTR_PENDING,
PACKETBUF_ATTR_FRAME_TYPE, PACKETBUF_ATTR_FRAME_TYPE,
#if LLSEC802154_SECURITY_LEVEL #if LLSEC802154_USES_AUX_HEADER
PACKETBUF_ATTR_SECURITY_LEVEL, PACKETBUF_ATTR_SECURITY_LEVEL,
#endif /* LLSEC802154_SECURITY_LEVEL */ #endif /* LLSEC802154_USES_AUX_HEADER */
#if LLSEC802154_USES_FRAME_COUNTER #if LLSEC802154_USES_FRAME_COUNTER
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1,
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3,
@ -288,29 +288,6 @@ enum {
PACKETBUF_ATTR_MAX PACKETBUF_ATTR_MAX
}; };
/* Define surrogates when 802.15.4 security is off */
#if !LLSEC802154_SECURITY_LEVEL
enum {
PACKETBUF_ATTR_SECURITY_LEVEL,
};
#endif /* LLSEC802154_SECURITY_LEVEL */
#if !LLSEC802154_USES_FRAME_COUNTER
enum {
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1,
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3
};
#endif /* LLSEC802154_USES_FRAME_COUNTER */
/* 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 */
#if NETSTACK_CONF_WITH_RIME #if NETSTACK_CONF_WITH_RIME
#define PACKETBUF_NUM_ADDRS 4 #define PACKETBUF_NUM_ADDRS 4
#else /* NETSTACK_CONF_WITH_RIME */ #else /* NETSTACK_CONF_WITH_RIME */

View file

@ -144,7 +144,7 @@ PROCESS_THREAD(node_process, ev, data)
/* Set node with ID == 1 as coordinator, convenient in Cooja. */ /* Set node with ID == 1 as coordinator, convenient in Cooja. */
if(node_id == 1) { if(node_id == 1) {
if(LLSEC802154_CONF_SECURITY_LEVEL) { if(LLSEC802154_ENABLED) {
node_role = role_6dr_sec; node_role = role_6dr_sec;
} else { } else {
node_role = role_6dr; node_role = role_6dr;
@ -169,7 +169,7 @@ PROCESS_THREAD(node_process, ev, data)
|| etimer_expired(&et)); || etimer_expired(&et));
if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) { if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) {
node_role = (node_role + 1) % 3; node_role = (node_role + 1) % 3;
if(LLSEC802154_CONF_SECURITY_LEVEL == 0 && node_role == role_6dr_sec) { if(LLSEC802154_ENABLED == 0 && node_role == role_6dr_sec) {
node_role = (node_role + 1) % 3; node_role = (node_role + 1) % 3;
} }
etimer_restart(&et); etimer_restart(&et);
@ -182,7 +182,7 @@ PROCESS_THREAD(node_process, ev, data)
printf("Init: node starting with role %s\n", printf("Init: node starting with role %s\n",
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec");
tsch_set_pan_secured(LLSEC802154_CONF_SECURITY_LEVEL && (node_role == role_6dr_sec)); tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec));
is_coordinator = node_role > role_6ln; is_coordinator = node_role > role_6ln;
if(is_coordinator) { if(is_coordinator) {

View file

@ -100,8 +100,8 @@
#if WITH_SECURITY #if WITH_SECURITY
/* Enable security */ /* Enable security */
#undef LLSEC802154_CONF_SECURITY_LEVEL #undef LLSEC802154_CONF_ENABLED
#define LLSEC802154_CONF_SECURITY_LEVEL 1 #define LLSEC802154_CONF_ENABLED 1
/* TSCH uses explicit keys to identify k1 and k2 */ /* TSCH uses explicit keys to identify k1 and k2 */
#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS #undef LLSEC802154_CONF_USES_EXPLICIT_KEYS
#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 #define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1

View file

@ -142,7 +142,7 @@
#if WITH_TSCH_SECURITY #if WITH_TSCH_SECURITY
/* Set security level to the maximum, even if unused, to all crypto code */ /* Set security level to the maximum, even if unused, to all crypto code */
#define LLSEC802154_CONF_SECURITY_LEVEL 7 #define LLSEC802154_CONF_ENABLED 1
/* Attempt to associate from both secured and non-secured EBs */ /* Attempt to associate from both secured and non-secured EBs */
#define TSCH_CONF_JOIN_SECURED_ONLY 0 #define TSCH_CONF_JOIN_SECURED_ONLY 0
/* We need explicit keys to identify k1 and k2 */ /* We need explicit keys to identify k1 and k2 */

View file

@ -152,7 +152,7 @@ PROCESS_THREAD(node_process, ev, data)
/* Set node with ID == 1 as coordinator, handy in Cooja. */ /* Set node with ID == 1 as coordinator, handy in Cooja. */
if(node_id == 1) { if(node_id == 1) {
if(LLSEC802154_CONF_SECURITY_LEVEL) { if(LLSEC802154_ENABLED) {
node_role = role_6dr_sec; node_role = role_6dr_sec;
} else { } else {
node_role = role_6dr; node_role = role_6dr;
@ -165,7 +165,7 @@ PROCESS_THREAD(node_process, ev, data)
node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec");
#if WITH_TSCH #if WITH_TSCH
tsch_set_pan_secured(LLSEC802154_CONF_SECURITY_LEVEL && (node_role == role_6dr_sec)); tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec));
#endif /* WITH_TSCH */ #endif /* WITH_TSCH */
is_coordinator = node_role > role_6ln; is_coordinator = node_role > role_6ln;

View file

@ -37,4 +37,4 @@
* Konrad Krentz <konrad.krentz@gmail.com> * Konrad Krentz <konrad.krentz@gmail.com>
*/ */
#define LLSEC802154_CONF_SECURITY_LEVEL 6 #define LLSEC802154_CONF_ENABLED 1

View file

@ -47,6 +47,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define SEC_LVL 6
#define MIC_LEN LLSEC802154_MIC_LEN(6)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Test vector C.2.1.2 from IEEE 802.15.4-2006 */ /* Test vector C.2.1.2 from IEEE 802.15.4-2006 */
static void static void
@ -70,7 +73,7 @@ test_sec_lvl_6()
/* Frame Counter */ /* Frame Counter */
0x05 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x01 , 0xCE }; 0x01 , 0xCE };
uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x4F , 0xDE , 0x52 , 0x90 , uint8_t oracle[MIC_LEN] = { 0x4F , 0xDE , 0x52 , 0x90 ,
0x61 , 0xF9 , 0xC6 , 0xF1 }; 0x61 , 0xF9 , 0xC6 , 0xF1 };
uint8_t nonce[13]; uint8_t nonce[13];
frame802154_frame_counter_t counter; frame802154_frame_counter_t counter;
@ -84,7 +87,7 @@ test_sec_lvl_6()
counter.u32 = 5; counter.u32 = 5;
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]); 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_FRAME_COUNTER_BYTES_2_3, counter.u16[1]);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL);
packetbuf_hdrreduce(29); packetbuf_hdrreduce(29);
CCM_STAR.set_key(key); CCM_STAR.set_key(key);
@ -92,10 +95,10 @@ test_sec_lvl_6()
CCM_STAR.aead(nonce, CCM_STAR.aead(nonce,
packetbuf_dataptr(), packetbuf_datalen(), packetbuf_dataptr(), packetbuf_datalen(),
packetbuf_hdrptr(), packetbuf_hdrlen(), packetbuf_hdrptr(), packetbuf_hdrlen(),
((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH, ((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN,
1); 1);
if(memcmp(((uint8_t *) packetbuf_hdrptr()) + 30, oracle, LLSEC802154_MIC_LENGTH) == 0) { if(memcmp(((uint8_t *) packetbuf_hdrptr()) + 30, oracle, MIC_LEN) == 0) {
printf("Success\n"); printf("Success\n");
} else { } else {
printf("Failure\n"); printf("Failure\n");
@ -115,7 +118,7 @@ test_sec_lvl_6()
CCM_STAR.aead(nonce, CCM_STAR.aead(nonce,
packetbuf_dataptr(), packetbuf_datalen(), packetbuf_dataptr(), packetbuf_datalen(),
packetbuf_hdrptr(), packetbuf_hdrlen(), packetbuf_hdrptr(), packetbuf_hdrlen(),
((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH, ((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN,
0); 0);
if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) { if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) {
printf("Success\n"); printf("Success\n");

View file

@ -37,4 +37,4 @@
* Konrad Krentz <konrad.krentz@gmail.com> * Konrad Krentz <konrad.krentz@gmail.com>
*/ */
#define LLSEC802154_CONF_SECURITY_LEVEL 2 #define LLSEC802154_CONF_ENABLED 1

View file

@ -48,6 +48,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define SEC_LVL 2
#define MIC_LEN LLSEC802154_MIC_LEN(2)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Test vector C.1 from FIPS Pub 197 */ /* Test vector C.1 from FIPS Pub 197 */
static void static void
@ -97,10 +100,10 @@ test_sec_lvl_2()
0x05 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
/* Payload */ /* Payload */
0x55 , 0xCF , 0x00 , 0x00 , 0x51 , 0x52 , 0x53 , 0x54 }; 0x55 , 0xCF , 0x00 , 0x00 , 0x51 , 0x52 , 0x53 , 0x54 };
uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x22 , 0x3B , 0xC1 , 0xEC , uint8_t oracle[MIC_LEN] = { 0x22 , 0x3B , 0xC1 , 0xEC ,
0x84 , 0x1A , 0xB5 , 0x53 }; 0x84 , 0x1A , 0xB5 , 0x53 };
frame802154_frame_counter_t counter; frame802154_frame_counter_t counter;
uint8_t mic[LLSEC802154_MIC_LENGTH]; uint8_t mic[MIC_LEN];
uint8_t nonce[13]; uint8_t nonce[13];
printf("Testing verification ... "); printf("Testing verification ... ");
@ -112,7 +115,7 @@ test_sec_lvl_2()
counter.u32 = 5; counter.u32 = 5;
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, counter.u16[0]); 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_FRAME_COUNTER_BYTES_2_3, counter.u16[1]);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL);
packetbuf_hdrreduce(18); packetbuf_hdrreduce(18);
CCM_STAR.set_key(key); CCM_STAR.set_key(key);
@ -120,10 +123,10 @@ test_sec_lvl_2()
CCM_STAR.aead(nonce, CCM_STAR.aead(nonce,
NULL, 0, NULL, 0,
packetbuf_hdrptr(), packetbuf_totlen(), packetbuf_hdrptr(), packetbuf_totlen(),
((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), LLSEC802154_MIC_LENGTH, ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), MIC_LEN,
1); 1);
if(memcmp(((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), oracle, LLSEC802154_MIC_LENGTH) == 0) { if(memcmp(((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), oracle, MIC_LEN) == 0) {
printf("Success\n"); printf("Success\n");
} else { } else {
printf("Failure\n"); printf("Failure\n");