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
#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. */

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/packetbuf.h"
#include "net/llsec/llsec802154.h"
#if LLSEC802154_USES_FRAME_COUNTER
/* This node's current frame counter value */
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 "net/linkaddr.h"
#include "net/packetbuf.h"
#include "net/llsec/llsec802154.h"
#include <string.h>
#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER
/*---------------------------------------------------------------------------*/
static const uint8_t *
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);
}
/*---------------------------------------------------------------------------*/
#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */

View file

@ -56,28 +56,13 @@
#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 */
#ifdef LLSEC802154_CONF_ENABLED
#define LLSEC802154_ENABLED LLSEC802154_CONF_ENABLED
#else /* LLSEC802154_CONF_ENABLED */
#define LLSEC802154_ENABLED 0
#endif /* LLSEC802154_CONF_ENABLED */
#if ((LLSEC802154_SECURITY_LEVEL < 0) || (LLSEC802154_SECURITY_LEVEL > 7))
#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 */
#define LLSEC802154_MIC_LEN(sec_lvl) (2 << (sec_lvl & 3))
#ifdef 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
#define LLSEC802154_USES_FRAME_COUNTER 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 */
#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
#define LLSEC802154_HTONS(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/ccm-star-packetbuf.h"
#include "net/mac/frame802154.h"
#include "net/mac/framer-802154.h"
#include "net/netstack.h"
#include "net/packetbuf.h"
#include "net/nbr-table.h"
@ -55,7 +54,22 @@
#include "lib/ccm-star.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
#define NONCORESEC_KEY NONCORESEC_CONF_KEY
@ -76,6 +90,8 @@
#define PRINTF(...)
#endif /* DEBUG */
#if LLSEC802154_USES_AUX_HEADER && SEC_LVL && LLSEC802154_USES_FRAME_COUNTER
/* network-wide CCM* key */
static uint8_t key[16] = NONCORESEC_KEY;
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_len;
uint8_t *result;
uint8_t generated_mic[LLSEC802154_MIC_LENGTH];
uint8_t generated_mic[MIC_LEN];
uint8_t *mic;
ccm_star_packetbuf_set_nonce(nonce, forward);
@ -113,30 +129,29 @@ aead(uint8_t hdrlen, int forward)
CCM_STAR.aead(nonce,
m, m_len,
a, a_len,
result, LLSEC802154_MIC_LENGTH,
result, MIC_LEN,
forward);
if(forward) {
packetbuf_set_datalen(packetbuf_datalen() + LLSEC802154_MIC_LENGTH);
packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN);
return 1;
} else {
return (memcmp(generated_mic, mic, LLSEC802154_MIC_LENGTH) == 0);
return (memcmp(generated_mic, mic, MIC_LEN) == 0);
}
}
/*---------------------------------------------------------------------------*/
static 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_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL);
anti_replay_set_counter();
}
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL);
}
/*---------------------------------------------------------------------------*/
static void
send(mac_callback_t sent, void *ptr)
{
add_security_header();
anti_replay_set_counter();
NETSTACK_MAC.send(sent, ptr);
}
/*---------------------------------------------------------------------------*/
@ -145,8 +160,7 @@ create(void)
{
int result;
add_security_header();
result = framer_802154.create();
result = DECORATED_FRAMER.create();
if(result == FRAMER_FAILED) {
return result;
}
@ -163,12 +177,12 @@ parse(void)
const linkaddr_t *sender;
struct anti_replay_info* info;
result = framer_802154.parse();
result = DECORATED_FRAMER.parse();
if(result == FRAMER_FAILED) {
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");
return FRAMER_FAILED;
}
@ -178,7 +192,7 @@ parse(void)
return FRAMER_FAILED;
}
packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH);
packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN);
if(!aead(result, 0)) {
PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n",
@ -233,7 +247,7 @@ static int
length(void)
{
add_security_header();
return framer_802154.length() + LLSEC802154_MIC_LENGTH;
return DECORATED_FRAMER.length() + MIC_LEN;
}
/*---------------------------------------------------------------------------*/
static void
@ -256,5 +270,6 @@ const struct framer noncoresec_framer = {
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
get_key_id_len(uint8_t key_id_mode)
{
@ -117,7 +117,7 @@ get_key_id_len(uint8_t key_id_mode)
return 0;
}
}
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS */
/*---------------------------------------------------------------------------*/
/* Get current PAN ID */
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->src_addr_len = addr_len(p->fcf.src_addr_mode & 3);
#if LLSEC802154_SECURITY_LEVEL
#if LLSEC802154_USES_AUX_HEADER
/* Aux security header */
if(p->fcf.security_enabled & 1) {
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_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--) {
buf[pos++] = p->src_addr[c - 1];
}
#if LLSEC802154_SECURITY_LEVEL
#if LLSEC802154_USES_AUX_HEADER
/* Aux header */
if(flen.aux_sec_len) {
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_SECURITY_LEVEL */
#endif /* LLSEC802154_USES_AUX_HEADER */
return (int)pos;
}
@ -570,7 +570,7 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
pf->src_pid = 0;
}
#if LLSEC802154_SECURITY_LEVEL
#if LLSEC802154_USES_AUX_HEADER
if(fcf.security_enabled) {
pf->aux_hdr.security_control.security_level = p[0] & 7;
#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_SECURITY_LEVEL */
#endif /* LLSEC802154_USES_AUX_HEADER */
/* header length */
c = p - data;

View file

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

View file

@ -51,7 +51,7 @@
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
#define RDC_WITH_DUPLICATE_DETECTION !LLSEC802154_CONF_ENABLED
#endif /* RDC_CONF_WITH_DUPLICATE_DETECTION */
/* 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:
```
/* Enable security */
#undef LLSEC802154_CONF_SECURITY_LEVEL
#define LLSEC802154_CONF_SECURITY_LEVEL 1
#undef LLSEC802154_CONF_ENABLED
#define LLSEC802154_CONF_ENABLED 1
/* TSCH uses explicit keys to identify k1 and k2 */
#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS
#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;
linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr);
#endif
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
p.fcf.security_enabled = 1;
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.key_index = TSCH_SECURITY_KEY_INDEX_ACK;
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
if((curr_len = frame802154_create(&p, buf)) == 0) {
return 0;
@ -166,13 +166,13 @@ tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
if(frame->fcf.ie_list_present) {
int mic_len = 0;
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
/* Check if there is space for the security MIC (if any) */
mic_len = tsch_security_mic_len(frame);
if(buf_size < curr_len + mic_len) {
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 */
if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
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[1] = 0xff;
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
p.fcf.security_enabled = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0;
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.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX);
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
if((curr_len = frame802154_create(&p, buf)) == 0) {
return 0;
@ -387,14 +387,14 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
if(frame->fcf.ie_list_present) {
/* Calculate space needed for the security MIC, if any, before attempting to parse IEs */
int mic_len = 0;
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(!frame_without_mic) {
mic_len = tsch_security_mic_len(frame);
if(buf_size < curr_len + mic_len) {
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 */
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-private.h"
#include "net/mac/frame802154.h"
#include "net/llsec/llsec802154.h"
#include "net/mac/frame802154e-ie.h"
/******** Configuration *******/
/* To enable TSCH security:
* - set LLSEC802154_CONF_SECURITY_LEVEL
* - set LLSEC802154_CONF_ENABLED
* - set LLSEC802154_CONF_USES_EXPLICIT_KEYS
* - unset LLSEC802154_CONF_USES_FRAME_COUNTER
* */
#define TSCH_SECURITY_ENABLED (LLSEC802154_CONF_SECURITY_LEVEL != 0)
#if TSCH_SECURITY_ENABLED && !LLSEC802154_CONF_USES_EXPLICIT_KEYS
#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_EXPLICIT_KEYS unset
#endif /* TSCH_SECURITY_ENABLED */
#if TSCH_SECURITY_ENABLED && LLSEC802154_CONF_USES_FRAME_COUNTER
#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_FRAME_COUNTER set
#endif /* TSCH_SECURITY_ENABLED */
#if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS
#error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset
#endif /* LLSEC802154_ENABLED */
#if LLSEC802154_ENABLED && LLSEC802154_USES_FRAME_COUNTER
#error LLSEC802154_ENABLED set but LLSEC802154_USES_FRAME_COUNTER set
#endif /* LLSEC802154_ENABLED */
/* K1, defined in 6TiSCH minimal, is well-known (offers no security) and used for EBs only */
#ifdef TSCH_SECURITY_CONF_K1

View file

@ -404,10 +404,10 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
} else {
/* packet payload */
static void *packet;
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
/* encrypted payload */
static uint8_t encrypted_packet[TSCH_PACKET_MAX_LEN];
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
/* packet payload length */
static uint8_t packet_len;
/* packet seqno */
@ -434,7 +434,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
packet_ready = 1;
}
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
/* 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. */
@ -445,7 +445,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
packet = encrypted_packet;
}
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
/* prepare packet to send: copy to radio buffer */
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;
}
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(ack_len != 0) {
if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame),
&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),
"!failed to parse ACK"));
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
}
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_used = is_drift_correction_used;
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);
#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));
);
@ -708,7 +712,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
packet_duration = TSCH_PACKET_DURATION(current_input->len);
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
/* Decrypt and verify incoming frame */
if(frame_valid) {
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));
frame_valid = 0;
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
if(frame_valid) {
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),
&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) {
/* 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);
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
/* Copy to radio buffer */
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? */
int tsch_is_associated = 0;
/* 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) */
struct asn_t current_asn;
/* Device rank or join priority:
@ -177,7 +177,7 @@ tsch_set_coordinator(int enable)
void
tsch_set_pan_secured(int enable)
{
tsch_is_pan_secured = TSCH_SECURITY_ENABLED && enable;
tsch_is_pan_secured = LLSEC802154_ENABLED && enable;
}
/*---------------------------------------------------------------------------*/
void
@ -455,21 +455,21 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
}
#endif /* TSCH_JOIN_SECURED_ONLY */
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(!tsch_security_parse_frame(input_eb->payload, hdrlen,
input_eb->len - hdrlen - tsch_security_mic_len(&frame),
&frame, (linkaddr_t*)&frame.src_addr, &current_asn)) {
PRINTF("TSCH:! parse_eb: failed to authenticate\n");
return 0;
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
#if !TSCH_SECURITY_ENABLED
#if !LLSEC802154_ENABLED
if(frame.fcf.security_enabled == 1) {
PRINTF("TSCH:! parse_eb: we do not support security, but EB is secured\n");
return 0;
}
#endif /* !TSCH_SECURITY_ENABLED */
#endif /* !LLSEC802154_ENABLED */
#if TSCH_JOIN_MY_PANID_ONLY
/* 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_MAC_SEQNO, tsch_packet_seqno);
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
/* 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_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);
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE,
tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset);
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_MAC_SEQNO, tsch_packet_seqno);
#if TSCH_SECURITY_ENABLED
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
/* 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_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);
}
#endif /* TSCH_SECURITY_ENABLED */
#endif /* LLSEC802154_ENABLED */
packet_count_before = tsch_queue_packet_count(addr);

View file

@ -84,8 +84,8 @@
#ifdef TSCH_CONF_JOIN_SECURED_ONLY
#define TSCH_JOIN_SECURED_ONLY TSCH_CONF_JOIN_SECURED_ONLY
#else
/* By default, set if TSCH_SECURITY_ENABLED is also non-zero */
#define TSCH_JOIN_SECURED_ONLY TSCH_SECURITY_ENABLED
/* By default, set if LLSEC802154_ENABLED is also non-zero */
#define TSCH_JOIN_SECURED_ONLY LLSEC802154_ENABLED
#endif
/* 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 */
PACKETBUF_ATTR_PENDING,
PACKETBUF_ATTR_FRAME_TYPE,
#if LLSEC802154_SECURITY_LEVEL
#if LLSEC802154_USES_AUX_HEADER
PACKETBUF_ATTR_SECURITY_LEVEL,
#endif /* LLSEC802154_SECURITY_LEVEL */
#endif /* LLSEC802154_USES_AUX_HEADER */
#if LLSEC802154_USES_FRAME_COUNTER
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1,
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3,
@ -288,29 +288,6 @@ enum {
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
#define PACKETBUF_NUM_ADDRS 4
#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. */
if(node_id == 1) {
if(LLSEC802154_CONF_SECURITY_LEVEL) {
if(LLSEC802154_ENABLED) {
node_role = role_6dr_sec;
} else {
node_role = role_6dr;
@ -169,7 +169,7 @@ PROCESS_THREAD(node_process, ev, data)
|| etimer_expired(&et));
if(ev == sensors_event && data == &button_sensor && button_sensor.value(0) > 0) {
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;
}
etimer_restart(&et);
@ -182,7 +182,7 @@ PROCESS_THREAD(node_process, ev, data)
printf("Init: node starting with role %s\n",
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;
if(is_coordinator) {

View file

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

View file

@ -142,7 +142,7 @@
#if WITH_TSCH_SECURITY
/* 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 */
#define TSCH_CONF_JOIN_SECURED_ONLY 0
/* 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. */
if(node_id == 1) {
if(LLSEC802154_CONF_SECURITY_LEVEL) {
if(LLSEC802154_ENABLED) {
node_role = role_6dr_sec;
} else {
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");
#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 */
is_coordinator = node_role > role_6ln;

View file

@ -37,4 +37,4 @@
* 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 <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 */
static void
@ -70,8 +73,8 @@ test_sec_lvl_6()
/* Frame Counter */
0x05 , 0x00 , 0x00 , 0x00 ,
0x01 , 0xCE };
uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x4F , 0xDE , 0x52 , 0x90 ,
0x61 , 0xF9 , 0xC6 , 0xF1 };
uint8_t oracle[MIC_LEN] = { 0x4F , 0xDE , 0x52 , 0x90 ,
0x61 , 0xF9 , 0xC6 , 0xF1 };
uint8_t nonce[13];
frame802154_frame_counter_t counter;
@ -84,7 +87,7 @@ test_sec_lvl_6()
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_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL);
packetbuf_hdrreduce(29);
CCM_STAR.set_key(key);
@ -92,10 +95,10 @@ test_sec_lvl_6()
CCM_STAR.aead(nonce,
packetbuf_dataptr(), packetbuf_datalen(),
packetbuf_hdrptr(), packetbuf_hdrlen(),
((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH,
((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN,
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");
} else {
printf("Failure\n");
@ -115,7 +118,7 @@ test_sec_lvl_6()
CCM_STAR.aead(nonce,
packetbuf_dataptr(), packetbuf_datalen(),
packetbuf_hdrptr(), packetbuf_hdrlen(),
((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH,
((uint8_t *) packetbuf_hdrptr()) + 30, MIC_LEN,
0);
if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) {
printf("Success\n");

View file

@ -37,4 +37,4 @@
* 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 <string.h>
#define SEC_LVL 2
#define MIC_LEN LLSEC802154_MIC_LEN(2)
/*---------------------------------------------------------------------------*/
/* Test vector C.1 from FIPS Pub 197 */
static void
@ -97,10 +100,10 @@ test_sec_lvl_2()
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 };
uint8_t oracle[MIC_LEN] = { 0x22 , 0x3B , 0xC1 , 0xEC ,
0x84 , 0x1A , 0xB5 , 0x53 };
frame802154_frame_counter_t counter;
uint8_t mic[LLSEC802154_MIC_LENGTH];
uint8_t mic[MIC_LEN];
uint8_t nonce[13];
printf("Testing verification ... ");
@ -112,7 +115,7 @@ test_sec_lvl_2()
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_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, SEC_LVL);
packetbuf_hdrreduce(18);
CCM_STAR.set_key(key);
@ -120,10 +123,10 @@ test_sec_lvl_2()
CCM_STAR.aead(nonce,
NULL, 0,
packetbuf_hdrptr(), packetbuf_totlen(),
((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), LLSEC802154_MIC_LENGTH,
((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), MIC_LEN,
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");
} else {
printf("Failure\n");