Merge pull request #558 from joakimeriksson/contrib/csma-llsec
Add back link layer security for CSMA
This commit is contained in:
commit
f24be610f5
|
@ -347,6 +347,12 @@ off(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
max_payload(void)
|
||||||
|
{
|
||||||
|
return PACKETBUF_SIZE;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
init(void)
|
init(void)
|
||||||
{
|
{
|
||||||
|
@ -371,7 +377,8 @@ const struct mac_driver ble_ipsp_mac_driver = {
|
||||||
send_packet,
|
send_packet,
|
||||||
NULL,
|
NULL,
|
||||||
on,
|
on,
|
||||||
off
|
off,
|
||||||
|
max_payload
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,16 +32,21 @@ udp_rx_callback(struct simple_udp_connection *c,
|
||||||
const uint8_t *data,
|
const uint8_t *data,
|
||||||
uint16_t datalen)
|
uint16_t datalen)
|
||||||
{
|
{
|
||||||
unsigned count = *(unsigned *)data;
|
|
||||||
LOG_INFO("Received response %u from ", count);
|
LOG_INFO("Received response '%.*s' from ", datalen, (char *) data);
|
||||||
LOG_INFO_6ADDR(sender_addr);
|
LOG_INFO_6ADDR(sender_addr);
|
||||||
|
#if LLSEC802154_CONF_ENABLED
|
||||||
|
LOG_INFO_(" LLSEC LV:%d", uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
|
||||||
|
#endif
|
||||||
LOG_INFO_("\n");
|
LOG_INFO_("\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
PROCESS_THREAD(udp_client_process, ev, data)
|
PROCESS_THREAD(udp_client_process, ev, data)
|
||||||
{
|
{
|
||||||
static struct etimer periodic_timer;
|
static struct etimer periodic_timer;
|
||||||
static unsigned count;
|
static unsigned count;
|
||||||
|
static char str[32];
|
||||||
uip_ipaddr_t dest_ipaddr;
|
uip_ipaddr_t dest_ipaddr;
|
||||||
|
|
||||||
PROCESS_BEGIN();
|
PROCESS_BEGIN();
|
||||||
|
@ -59,7 +64,8 @@ PROCESS_THREAD(udp_client_process, ev, data)
|
||||||
LOG_INFO("Sending request %u to ", count);
|
LOG_INFO("Sending request %u to ", count);
|
||||||
LOG_INFO_6ADDR(&dest_ipaddr);
|
LOG_INFO_6ADDR(&dest_ipaddr);
|
||||||
LOG_INFO_("\n");
|
LOG_INFO_("\n");
|
||||||
simple_udp_sendto(&udp_conn, &count, sizeof(count), &dest_ipaddr);
|
snprintf(str, sizeof(str), "hello %d", count);
|
||||||
|
simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr);
|
||||||
count++;
|
count++;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Not reachable yet\n");
|
LOG_INFO("Not reachable yet\n");
|
||||||
|
|
|
@ -54,15 +54,13 @@ udp_rx_callback(struct simple_udp_connection *c,
|
||||||
const uint8_t *data,
|
const uint8_t *data,
|
||||||
uint16_t datalen)
|
uint16_t datalen)
|
||||||
{
|
{
|
||||||
unsigned count = *(unsigned *)data;
|
LOG_INFO("Received request '%.*s' from ", datalen, (char *) data);
|
||||||
LOG_INFO("Received request %u from ", count);
|
|
||||||
LOG_INFO_6ADDR(sender_addr);
|
LOG_INFO_6ADDR(sender_addr);
|
||||||
LOG_INFO_("\n");
|
LOG_INFO_("\n");
|
||||||
#if WITH_SERVER_REPLY
|
#if WITH_SERVER_REPLY
|
||||||
LOG_INFO("Sending response %u to ", count);
|
/* send back the same string to the client as an echo reply */
|
||||||
LOG_INFO_6ADDR(sender_addr);
|
LOG_INFO("Sending response.\n");
|
||||||
LOG_INFO_("\n");
|
simple_udp_sendto(&udp_conn, data, datalen, sender_addr);
|
||||||
simple_udp_sendto(&udp_conn, &count, sizeof(count), sender_addr);
|
|
||||||
#endif /* WITH_SERVER_REPLY */
|
#endif /* WITH_SERVER_REPLY */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -126,24 +126,6 @@
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
/** \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 (127 - 2)
|
|
||||||
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
|
|
||||||
|
|
||||||
/** \brief Maximum size of a frame header. This value is
|
|
||||||
* used in case framer returns an error */
|
|
||||||
#ifdef SICSLOWPAN_CONF_MAC_MAX_HEADER
|
|
||||||
#define MAC_MAX_HEADER SICSLOWPAN_CONF_MAC_MAX_HEADER
|
|
||||||
#else /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
|
|
||||||
#define MAC_MAX_HEADER 21
|
|
||||||
#endif /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
|
|
||||||
|
|
||||||
/* set this to zero if not compressing EXT_HDR - for backwards compatibility */
|
/* set this to zero if not compressing EXT_HDR - for backwards compatibility */
|
||||||
#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
|
#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
|
||||||
#define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR
|
#define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR
|
||||||
|
@ -246,7 +228,7 @@ static uint16_t my_tag;
|
||||||
#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE
|
#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE
|
||||||
#else
|
#else
|
||||||
/* The default fragment size (110 bytes for 127-2 bytes frames) */
|
/* The default fragment size (110 bytes for 127-2 bytes frames) */
|
||||||
#define SICSLOWPAN_FRAGMENT_SIZE (MAC_MAX_PAYLOAD - 15)
|
#define SICSLOWPAN_FRAGMENT_SIZE (127 - 2 - 15)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Assuming that the worst growth for uncompression is 38 bytes */
|
/* Assuming that the worst growth for uncompression is 38 bytes */
|
||||||
|
@ -1544,8 +1526,6 @@ fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) {
|
||||||
static uint8_t
|
static uint8_t
|
||||||
output(const linkaddr_t *localdest)
|
output(const linkaddr_t *localdest)
|
||||||
{
|
{
|
||||||
int framer_hdrlen;
|
|
||||||
int max_payload;
|
|
||||||
int frag_needed;
|
int frag_needed;
|
||||||
|
|
||||||
/* The MAC address of the destination of the packet */
|
/* The MAC address of the destination of the packet */
|
||||||
|
@ -1584,13 +1564,23 @@ output(const linkaddr_t *localdest)
|
||||||
|
|
||||||
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC */
|
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC */
|
||||||
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
||||||
framer_hdrlen = NETSTACK_FRAMER.length();
|
#if LLSEC802154_USES_AUX_HEADER
|
||||||
if(framer_hdrlen < 0) {
|
/* copy LLSEC level */
|
||||||
/* Framing failed, we assume the maximum header length */
|
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
|
||||||
framer_hdrlen = MAC_MAX_HEADER;
|
uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
|
||||||
}
|
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||||
|
packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
|
||||||
|
uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
|
||||||
|
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||||
|
#endif /* LLSEC802154_USES_AUX_HEADER */
|
||||||
|
|
||||||
mac_max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
|
mac_max_payload = NETSTACK_MAC.max_payload();
|
||||||
|
|
||||||
|
if(mac_max_payload <= 0) {
|
||||||
|
/* Framing failed, drop packet */
|
||||||
|
LOG_WARN("output: failed to calculate payload size - dropping packet\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to compress the headers */
|
/* Try to compress the headers */
|
||||||
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
|
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
|
||||||
|
@ -1611,22 +1601,17 @@ output(const linkaddr_t *localdest)
|
||||||
}
|
}
|
||||||
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */
|
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */
|
||||||
|
|
||||||
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC.
|
/* Use the mac_max_payload to understand what is the max payload in a MAC
|
||||||
* We calculate it here only to make a better decision of whether the outgoing packet
|
* packet. We calculate it here only to make a better decision of whether
|
||||||
* needs to be fragmented or not. */
|
* the outgoing packet needs to be fragmented or not. */
|
||||||
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
|
||||||
framer_hdrlen = NETSTACK_FRAMER.length();
|
|
||||||
if(framer_hdrlen < 0) {
|
|
||||||
/* Framing failed, we assume the maximum header length */
|
|
||||||
framer_hdrlen = MAC_MAX_HEADER;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
|
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
||||||
frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > max_payload;
|
|
||||||
|
frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > mac_max_payload;
|
||||||
LOG_INFO("output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
|
LOG_INFO("output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
|
||||||
uncomp_hdr_len, packetbuf_hdr_len,
|
uncomp_hdr_len, packetbuf_hdr_len,
|
||||||
uip_len, uip_len - uncomp_hdr_len + packetbuf_hdr_len,
|
uip_len, uip_len - uncomp_hdr_len + packetbuf_hdr_len,
|
||||||
max_payload, frag_needed);
|
mac_max_payload, frag_needed);
|
||||||
|
|
||||||
if(frag_needed) {
|
if(frag_needed) {
|
||||||
#if SICSLOWPAN_CONF_FRAG
|
#if SICSLOWPAN_CONF_FRAG
|
||||||
|
@ -1646,11 +1631,11 @@ output(const linkaddr_t *localdest)
|
||||||
/* Total IPv6 payload */
|
/* Total IPv6 payload */
|
||||||
int total_payload = (uip_len - uncomp_hdr_len);
|
int total_payload = (uip_len - uncomp_hdr_len);
|
||||||
/* IPv6 payload that goes to first fragment */
|
/* IPv6 payload that goes to first fragment */
|
||||||
int frag1_payload = (max_payload - packetbuf_hdr_len - SICSLOWPAN_FRAG1_HDR_LEN) & 0xfffffff8;
|
int frag1_payload = (mac_max_payload - packetbuf_hdr_len - SICSLOWPAN_FRAG1_HDR_LEN) & 0xfffffff8;
|
||||||
/* max IPv6 payload in each FRAGN. Must be multiple of 8 bytes */
|
/* max IPv6 payload in each FRAGN. Must be multiple of 8 bytes */
|
||||||
int fragn_max_payload = (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
|
int fragn_max_payload = (mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
|
||||||
/* max IPv6 payload in the last fragment. Needs not be multiple of 8 bytes */
|
/* max IPv6 payload in the last fragment. Needs not be multiple of 8 bytes */
|
||||||
int last_fragn_max_payload = max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
|
int last_fragn_max_payload = mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
|
||||||
/* sum of all IPv6 payload that goes to non-first and non-last fragments */
|
/* sum of all IPv6 payload that goes to non-first and non-last fragments */
|
||||||
int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
|
int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
|
||||||
/* Ceiling of: 2 + middle_fragn_total_payload / fragn_max_payload */
|
/* Ceiling of: 2 + middle_fragn_total_payload / fragn_max_payload */
|
||||||
|
@ -1802,6 +1787,9 @@ input(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear uipbuf and set default attributes */
|
||||||
|
uipbuf_clear();
|
||||||
|
|
||||||
/* This is default uip_buf since we assume that this is not fragmented */
|
/* This is default uip_buf since we assume that this is not fragmented */
|
||||||
buffer = (uint8_t *)UIP_IP_BUF;
|
buffer = (uint8_t *)UIP_IP_BUF;
|
||||||
|
|
||||||
|
@ -1836,7 +1824,6 @@ input(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = frag_info[frag_context].first_frag;
|
buffer = frag_info[frag_context].first_frag;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SICSLOWPAN_DISPATCH_FRAGN:
|
case SICSLOWPAN_DISPATCH_FRAGN:
|
||||||
/*
|
/*
|
||||||
|
@ -2000,6 +1987,19 @@ input(void)
|
||||||
callback->input_callback();
|
callback->input_callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LLSEC802154_USES_AUX_HEADER
|
||||||
|
/*
|
||||||
|
* Assuming that the last packet in packetbuf is containing
|
||||||
|
* the LLSEC state so that it can be copied to uipbuf.
|
||||||
|
*/
|
||||||
|
uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
|
||||||
|
packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
|
||||||
|
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||||
|
uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
|
||||||
|
packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
|
||||||
|
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||||
|
#endif /* LLSEC802154_USES_AUX_HEADER */
|
||||||
|
|
||||||
tcpip_input();
|
tcpip_input();
|
||||||
#if SICSLOWPAN_CONF_FRAG
|
#if SICSLOWPAN_CONF_FRAG
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,6 +388,7 @@ uip_init(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
uipbuf_init();
|
||||||
uip_ds6_init();
|
uip_ds6_init();
|
||||||
uip_icmp6_init();
|
uip_icmp6_init();
|
||||||
uip_nd6_init();
|
uip_nd6_init();
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static uint16_t uipbuf_attrs[UIPBUF_ATTR_MAX];
|
static uint16_t uipbuf_attrs[UIPBUF_ATTR_MAX];
|
||||||
|
static uint16_t uipbuf_default_attrs[UIPBUF_ATTR_MAX];
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -197,15 +198,21 @@ uipbuf_set_attr(uint8_t type, uint16_t value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
uipbuf_set_default_attr(uint8_t type, uint16_t value)
|
||||||
|
{
|
||||||
|
if(type < UIPBUF_ATTR_MAX) {
|
||||||
|
uipbuf_default_attrs[type] = value;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
uipbuf_clear_attr(void)
|
uipbuf_clear_attr(void)
|
||||||
{
|
{
|
||||||
/* set everything to "zero" */
|
/* set everything to "defaults" */
|
||||||
memset(uipbuf_attrs, 0, sizeof(uipbuf_attrs));
|
memcpy(uipbuf_attrs, uipbuf_default_attrs, sizeof(uipbuf_attrs));
|
||||||
|
|
||||||
/* And initialize anything that should be initialized */
|
|
||||||
uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS,
|
|
||||||
UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED);
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -227,3 +234,17 @@ uipbuf_is_attr_flag(uint16_t flag)
|
||||||
return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag;
|
return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uipbuf_init(void)
|
||||||
|
{
|
||||||
|
memset(uipbuf_default_attrs, 0, sizeof(uipbuf_default_attrs));
|
||||||
|
/* And initialize anything that should be initialized */
|
||||||
|
uipbuf_set_default_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS,
|
||||||
|
UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED);
|
||||||
|
/* set the not-set default value - this will cause the MAC layer to
|
||||||
|
configure its default */
|
||||||
|
uipbuf_set_default_attr(UIPBUF_ATTR_LLSEC_LEVEL,
|
||||||
|
UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -125,6 +125,17 @@ uint16_t uipbuf_get_attr(uint8_t type);
|
||||||
*/
|
*/
|
||||||
int uipbuf_set_attr(uint8_t type, uint16_t value);
|
int uipbuf_set_attr(uint8_t type, uint16_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set the default value of the attribute
|
||||||
|
* \param type The attribute to set the default value of
|
||||||
|
* \param value The value to set
|
||||||
|
* \retval 0 - indicates failure of setting the value
|
||||||
|
* \retval 1 - indicates success of setting the value
|
||||||
|
*
|
||||||
|
* This function sets the default value of a uipbuf attribute.
|
||||||
|
*/
|
||||||
|
int uipbuf_set_default_attr(uint8_t type, uint16_t value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set bits in the uipbuf attribute flags.
|
* \brief Set bits in the uipbuf attribute flags.
|
||||||
* \param flag_bits The bits to set in the flag.
|
* \param flag_bits The bits to set in the flag.
|
||||||
|
@ -159,6 +170,14 @@ uint16_t uipbuf_is_attr_flag(uint16_t flag_bits);
|
||||||
*/
|
*/
|
||||||
void uipbuf_clear_attr(void);
|
void uipbuf_clear_attr(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize uipbuf attributes.
|
||||||
|
*
|
||||||
|
* This function initialize all attributes in the uipbuf
|
||||||
|
* attributes including all flags.
|
||||||
|
*/
|
||||||
|
void uipbuf_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The bits defined for uipbuf attributes flag.
|
* \brief The bits defined for uipbuf attributes flag.
|
||||||
*
|
*
|
||||||
|
@ -168,6 +187,9 @@ void uipbuf_clear_attr(void);
|
||||||
/* Avoid using prefix compression on the packet (6LoWPAN) */
|
/* Avoid using prefix compression on the packet (6LoWPAN) */
|
||||||
#define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_PREFIX_COMPRESSION 0x02
|
#define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_PREFIX_COMPRESSION 0x02
|
||||||
|
|
||||||
|
/* MAC will set the default for this packet */
|
||||||
|
#define UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT 0xffff
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief The attributes defined for uipbuf attributes function.
|
* \brief The attributes defined for uipbuf attributes function.
|
||||||
*
|
*
|
||||||
|
|
|
@ -505,6 +505,12 @@ off(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
max_payload(void)
|
||||||
|
{
|
||||||
|
return BLE_L2CAP_NODE_MTU;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
const struct mac_driver ble_l2cap_driver = {
|
const struct mac_driver ble_l2cap_driver = {
|
||||||
"ble-l2cap",
|
"ble-l2cap",
|
||||||
init,
|
init,
|
||||||
|
@ -512,6 +518,7 @@ const struct mac_driver ble_l2cap_driver = {
|
||||||
input,
|
input,
|
||||||
on,
|
on,
|
||||||
off,
|
off,
|
||||||
|
max_payload,
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
PROCESS_THREAD(ble_l2cap_tx_process, ev, data)
|
PROCESS_THREAD(ble_l2cap_tx_process, ev, data)
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup csma
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "net/mac/csma/anti-replay.h"
|
||||||
|
#include "net/packetbuf.h"
|
||||||
|
#include "net/mac/llsec802154.h"
|
||||||
|
|
||||||
|
#if LLSEC802154_USES_FRAME_COUNTER
|
||||||
|
|
||||||
|
/* This node's current frame counter value */
|
||||||
|
static uint32_t counter;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
anti_replay_set_counter(void)
|
||||||
|
{
|
||||||
|
frame802154_frame_counter_t reordered_counter;
|
||||||
|
|
||||||
|
++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(packetbuf_holds_broadcast()) {
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#endif /* LLSEC802154_USES_FRAME_COUNTER */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup llsec802154
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
||||||
|
* \param info Anti-replay information about the sender
|
||||||
|
*/
|
||||||
|
void anti_replay_init_info(struct anti_replay_info *info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks if received frame was replayed
|
||||||
|
* \param info 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 */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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* convenience functions for LLSEC use
|
||||||
|
* \author
|
||||||
|
* Justin King-Lacroix <justin.kinglacroix@gmail.com>
|
||||||
|
* Konrad Krentz <konrad.krentz@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "net/linkaddr.h"
|
||||||
|
#include "net/packetbuf.h"
|
||||||
|
#include "net/mac/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)
|
||||||
|
#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 */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward)
|
||||||
|
{
|
||||||
|
const linkaddr_t *source_addr;
|
||||||
|
|
||||||
|
source_addr = forward ? &linkaddr_node_addr : packetbuf_addr(PACKETBUF_ADDR_SENDER);
|
||||||
|
memcpy(nonce, get_extended_address(source_addr), 8);
|
||||||
|
nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
|
||||||
|
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
|
||||||
|
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
|
||||||
|
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
|
||||||
|
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CCM_STAR_PACKETBUF_H_
|
||||||
|
#define CCM_STAR_PACKETBUF_H_
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward);
|
||||||
|
|
||||||
|
#endif /* CCM_STAR_PACKETBUF_H_ */
|
|
@ -40,6 +40,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "net/mac/csma/csma.h"
|
#include "net/mac/csma/csma.h"
|
||||||
|
#include "net/mac/csma/csma-security.h"
|
||||||
#include "net/packetbuf.h"
|
#include "net/packetbuf.h"
|
||||||
#include "net/queuebuf.h"
|
#include "net/queuebuf.h"
|
||||||
#include "dev/watchdog.h"
|
#include "dev/watchdog.h"
|
||||||
|
@ -169,9 +170,16 @@ send_one_packet(void *ptr)
|
||||||
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
|
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
|
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
|
||||||
|
|
||||||
if(NETSTACK_FRAMER.create() < 0) {
|
#if LLSEC802154_ENABLED
|
||||||
|
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||||
|
/* This should possibly be taken from upper layers in the future */
|
||||||
|
packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, CSMA_LLSEC_KEY_ID_MODE);
|
||||||
|
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||||
|
#endif /* LLSEC802154_ENABLED */
|
||||||
|
|
||||||
|
if(csma_security_create_frame() < 0) {
|
||||||
/* Failed to allocate space for headers */
|
/* Failed to allocate space for headers */
|
||||||
LOG_ERR("failed to create packet\n");
|
LOG_ERR("failed to create packet, seqno: %d\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
|
||||||
ret = MAC_TX_ERR_FATAL;
|
ret = MAC_TX_ERR_FATAL;
|
||||||
} else {
|
} else {
|
||||||
int is_broadcast;
|
int is_broadcast;
|
||||||
|
|
|
@ -0,0 +1,308 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, RISE SICS
|
||||||
|
* 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
|
||||||
|
* CSMA security
|
||||||
|
* \author
|
||||||
|
* Joakim Eriksson <joakim.eriksson@ri.se>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup csma
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "net/mac/csma/csma.h"
|
||||||
|
#include "net/mac/csma/anti-replay.h"
|
||||||
|
#include "net/mac/csma/csma-security.h"
|
||||||
|
#include "net/mac/framer/frame802154.h"
|
||||||
|
#include "net/mac/framer/framer-802154.h"
|
||||||
|
#include "net/mac/llsec802154.h"
|
||||||
|
#include "net/netstack.h"
|
||||||
|
#include "net/packetbuf.h"
|
||||||
|
#include "lib/ccm-star.h"
|
||||||
|
#include "lib/aes-128.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "ccm-star-packetbuf.h"
|
||||||
|
/* Log configuration */
|
||||||
|
#include "sys/log.h"
|
||||||
|
#define LOG_MODULE "CSMA"
|
||||||
|
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||||
|
|
||||||
|
#if LOG_LEVEL == LOG_LEVEL_DBG
|
||||||
|
static const char * HEX = "0123456789ABCDEF";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER
|
||||||
|
|
||||||
|
#define MIC_LEN(level) LLSEC802154_MIC_LEN(level)
|
||||||
|
|
||||||
|
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||||
|
#define LLSEC_KEY_INDEX (FRAME802154_IMPLICIT_KEY == packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE) \
|
||||||
|
? 0 \
|
||||||
|
: packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX))
|
||||||
|
#define LLSEC_KEY_MODE (packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE))
|
||||||
|
#else
|
||||||
|
#define LLSEC_KEY_INDEX (0)
|
||||||
|
#define LLSEC_KEY_MODE (FRAME802154_IMPLICIT_KEY)
|
||||||
|
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The keys for LLSEC for CSMA
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t u8[16];
|
||||||
|
} aes_key_t;
|
||||||
|
static aes_key_t keys[CSMA_LLSEC_MAXKEYS];
|
||||||
|
|
||||||
|
/* assumed to be 16 bytes */
|
||||||
|
int
|
||||||
|
csma_security_set_key(uint8_t index, const uint8_t *key)
|
||||||
|
{
|
||||||
|
if(key != NULL && index < CSMA_LLSEC_MAXKEYS) {
|
||||||
|
memcpy(keys[index].u8, key, 16);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define N_KEYS (sizeof(keys) / sizeof(aes_key))
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
aead(uint8_t hdrlen, int forward)
|
||||||
|
{
|
||||||
|
uint8_t totlen;
|
||||||
|
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
|
||||||
|
uint8_t *m;
|
||||||
|
uint8_t m_len;
|
||||||
|
uint8_t *a;
|
||||||
|
uint8_t a_len;
|
||||||
|
uint8_t *result;
|
||||||
|
/* Allocate for MAX level */
|
||||||
|
uint8_t generated_mic[MIC_LEN(7)];
|
||||||
|
uint8_t *mic;
|
||||||
|
uint8_t key_index;
|
||||||
|
aes_key_t *key;
|
||||||
|
uint8_t with_encryption;
|
||||||
|
|
||||||
|
key_index = LLSEC_KEY_INDEX;
|
||||||
|
if(key_index >= CSMA_LLSEC_MAXKEYS) {
|
||||||
|
LOG_ERR("Key not available: %u\n", key_index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = &keys[key_index];
|
||||||
|
|
||||||
|
ccm_star_packetbuf_set_nonce(nonce, forward);
|
||||||
|
totlen = packetbuf_totlen();
|
||||||
|
a = packetbuf_hdrptr();
|
||||||
|
|
||||||
|
with_encryption =
|
||||||
|
(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x4) ? 1 : 0;
|
||||||
|
|
||||||
|
if(with_encryption) {
|
||||||
|
a_len = hdrlen;
|
||||||
|
m = a + a_len;
|
||||||
|
m_len = totlen - hdrlen;
|
||||||
|
} else {
|
||||||
|
a_len = totlen;
|
||||||
|
m = NULL;
|
||||||
|
m_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mic = a + totlen;
|
||||||
|
result = forward ? mic : generated_mic;
|
||||||
|
|
||||||
|
CCM_STAR.set_key(key->u8);
|
||||||
|
CCM_STAR.aead(nonce,
|
||||||
|
m, m_len,
|
||||||
|
a, a_len,
|
||||||
|
result, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07),
|
||||||
|
forward);
|
||||||
|
|
||||||
|
if(forward) {
|
||||||
|
packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07));
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return (memcmp(generated_mic, mic, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
csma_security_create_frame(void)
|
||||||
|
{
|
||||||
|
int hdr_len;
|
||||||
|
|
||||||
|
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
|
||||||
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 &&
|
||||||
|
LLSEC_KEY_INDEX != 0xffff) {
|
||||||
|
anti_replay_set_counter();
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr_len = NETSTACK_FRAMER.create();
|
||||||
|
if(hdr_len < 0) {
|
||||||
|
return hdr_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0) {
|
||||||
|
#if LOG_LEVEL == LOG_LEVEL_DBG
|
||||||
|
int i = 0;
|
||||||
|
uint8_t *p;
|
||||||
|
LOG_DBG(" Payload before (%d):", packetbuf_totlen());
|
||||||
|
p = packetbuf_hdrptr();
|
||||||
|
for(i = 0; i < packetbuf_totlen(); i++) {
|
||||||
|
LOG_DBG_("%c%c", HEX[(p[i] >> 4) & 0x0f], HEX[p[i] & 0x0f]);
|
||||||
|
}
|
||||||
|
LOG_DBG("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!aead(hdr_len, 1)) {
|
||||||
|
LOG_ERR("failed to encrypt packet to ");
|
||||||
|
LOG_ERR_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||||
|
LOG_ERR_("\n");
|
||||||
|
return FRAMER_FAILED;
|
||||||
|
}
|
||||||
|
LOG_INFO("LLSEC-OUT:");
|
||||||
|
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
LOG_INFO_(" ");
|
||||||
|
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||||
|
LOG_INFO_(" %u (%u) LV:%d, KEY:0x%02x\n", packetbuf_datalen(), packetbuf_totlen(),
|
||||||
|
packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL), LLSEC_KEY_INDEX);
|
||||||
|
|
||||||
|
#if LOG_LEVEL == LOG_LEVEL_DBG
|
||||||
|
LOG_DBG(" Payload after: (%d)", packetbuf_totlen());
|
||||||
|
p = packetbuf_hdrptr();
|
||||||
|
for(i = 0; i < packetbuf_totlen(); i++) {
|
||||||
|
LOG_DBG_("%c%c", HEX[(p[i] >> 4) & 0x0f], HEX[p[i] & 0x0f]);
|
||||||
|
}
|
||||||
|
LOG_DBG_("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
return hdr_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
csma_security_frame_len(void)
|
||||||
|
{
|
||||||
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 &&
|
||||||
|
LLSEC_KEY_INDEX != 0xffff) {
|
||||||
|
return NETSTACK_FRAMER.length() +
|
||||||
|
MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07);
|
||||||
|
}
|
||||||
|
return NETSTACK_FRAMER.length();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
csma_security_parse_frame(void)
|
||||||
|
{
|
||||||
|
int hdr_len;
|
||||||
|
|
||||||
|
hdr_len = NETSTACK_FRAMER.parse();
|
||||||
|
if(hdr_len < 0) {
|
||||||
|
return hdr_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) == 0) {
|
||||||
|
/* No security - no more processing required */
|
||||||
|
return hdr_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("LLSEC-IN: ");
|
||||||
|
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
LOG_INFO_(" ");
|
||||||
|
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||||
|
LOG_INFO_(" %d %u (%u) LV:%d KM:%d KEY:0x%02x\n", hdr_len, packetbuf_datalen(),
|
||||||
|
packetbuf_totlen(), packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL),
|
||||||
|
LLSEC_KEY_MODE,
|
||||||
|
LLSEC_KEY_INDEX);
|
||||||
|
|
||||||
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != CSMA_LLSEC_SECURITY_LEVEL) {
|
||||||
|
LOG_INFO("received frame with wrong security level (%u) from ",
|
||||||
|
packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
|
||||||
|
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
LOG_INFO_("\n");
|
||||||
|
return FRAMER_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(LLSEC_KEY_MODE != CSMA_LLSEC_KEY_ID_MODE) {
|
||||||
|
LOG_INFO("received frame with wrong key id mode (%u) from ", LLSEC_KEY_MODE);
|
||||||
|
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
LOG_INFO("\n");
|
||||||
|
return FRAMER_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), &linkaddr_node_addr)) {
|
||||||
|
LOG_INFO("frame from ourselves\n");
|
||||||
|
return FRAMER_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(packetbuf_datalen() <= MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) {
|
||||||
|
LOG_ERR("MIC error - too little data in frame!\n");
|
||||||
|
return FRAMER_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07));
|
||||||
|
if(!aead(hdr_len, 0)) {
|
||||||
|
LOG_INFO("received unauthentic frame %u from ",
|
||||||
|
(unsigned int) anti_replay_get_counter());
|
||||||
|
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
LOG_INFO_("\n");
|
||||||
|
return FRAMER_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO anti-reply protection */
|
||||||
|
return hdr_len;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#else
|
||||||
|
/* The "unsecure" version of the create frame / parse frame */
|
||||||
|
int
|
||||||
|
csma_security_create_frame(void)
|
||||||
|
{
|
||||||
|
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
|
||||||
|
return NETSTACK_FRAMER.create();
|
||||||
|
}
|
||||||
|
int
|
||||||
|
csma_security_parse_frame(void)
|
||||||
|
{
|
||||||
|
return NETSTACK_FRAMER.parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tiny Mesh AS
|
||||||
|
* 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
|
||||||
|
* LLSEC802154 Security related configuration
|
||||||
|
* \author
|
||||||
|
* Olav Frengstad <olav@tiny-mesh.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CSMA_SECURITY_H_
|
||||||
|
#define CSMA_SECURITY_H_
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CSMA_CONF_LLSEC_DEFAULT_KEY0
|
||||||
|
#define CSMA_LLSEC_DEFAULT_KEY0 CSMA_CONF_LLSEC_DEFAULT_KEY0
|
||||||
|
#else
|
||||||
|
#define CSMA_LLSEC_DEFAULT_KEY0 {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CSMA_CONF_LLSEC_SECURITY_LEVEL
|
||||||
|
#define CSMA_LLSEC_SECURITY_LEVEL CSMA_CONF_LLSEC_SECURITY_LEVEL
|
||||||
|
#else
|
||||||
|
#define CSMA_LLSEC_SECURITY_LEVEL 5
|
||||||
|
#endif /* CSMA_CONF_LLSEC_SECURITY_LEVEL */
|
||||||
|
|
||||||
|
#ifdef CSMA_CONF_LLSEC_KEY_ID_MODE
|
||||||
|
#define CSMA_LLSEC_KEY_ID_MODE CSMA_CONF_LLSEC_KEY_ID_MODE
|
||||||
|
#else
|
||||||
|
#define CSMA_LLSEC_KEY_ID_MODE FRAME802154_IMPLICIT_KEY
|
||||||
|
#endif /* CSMA_CONF_LLSEC_KEY_ID_MODE */
|
||||||
|
|
||||||
|
#ifdef CSMA_CONF_LLSEC_KEY_INDEX
|
||||||
|
#define CSMA_LLSEC_KEY_INDEX CSMA_CONF_LLSEC_KEY_INDEX
|
||||||
|
#else
|
||||||
|
#define CSMA_LLSEC_KEY_INDEX 0
|
||||||
|
#endif /* CSMA_CONF_LLSEC_KEY_INDEX */
|
||||||
|
|
||||||
|
#ifdef CSMA_CONF_LLSEC_MAXKEYS
|
||||||
|
#define CSMA_LLSEC_MAXKEYS CSMA_CONF_LLSEC_MAXKEYS
|
||||||
|
#else
|
||||||
|
#define CSMA_LLSEC_MAXKEYS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CSMA_SECURITY_H_ */
|
|
@ -49,10 +49,25 @@
|
||||||
#define LOG_MODULE "CSMA"
|
#define LOG_MODULE "CSMA"
|
||||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_sec(void)
|
||||||
|
{
|
||||||
|
#if LLSEC802154_USES_AUX_HEADER
|
||||||
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) ==
|
||||||
|
PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT) {
|
||||||
|
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
|
||||||
|
CSMA_LLSEC_SECURITY_LEVEL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
send_packet(mac_callback_t sent, void *ptr)
|
send_packet(mac_callback_t sent, void *ptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
init_sec();
|
||||||
|
|
||||||
csma_output_packet(sent, ptr);
|
csma_output_packet(sent, ptr);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -70,7 +85,7 @@ input_packet(void)
|
||||||
if(packetbuf_datalen() == CSMA_ACK_LEN) {
|
if(packetbuf_datalen() == CSMA_ACK_LEN) {
|
||||||
/* Ignore ack packets */
|
/* Ignore ack packets */
|
||||||
LOG_DBG("ignored ack\n");
|
LOG_DBG("ignored ack\n");
|
||||||
} else if(NETSTACK_FRAMER.parse() < 0) {
|
} else if(csma_security_parse_frame() < 0) {
|
||||||
LOG_ERR("failed to parse %u\n", packetbuf_datalen());
|
LOG_ERR("failed to parse %u\n", packetbuf_datalen());
|
||||||
} else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
|
} else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
|
||||||
&linkaddr_node_addr) &&
|
&linkaddr_node_addr) &&
|
||||||
|
@ -131,16 +146,41 @@ off(void)
|
||||||
static void
|
static void
|
||||||
init(void)
|
init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if LLSEC802154_USES_AUX_HEADER
|
||||||
|
#ifdef CSMA_LLSEC_DEFAULT_KEY0
|
||||||
|
uint8_t key[16] = CSMA_LLSEC_DEFAULT_KEY0;
|
||||||
|
csma_security_set_key(0, key);
|
||||||
|
#endif
|
||||||
|
#endif /* LLSEC802154_USES_AUX_HEADER */
|
||||||
csma_output_init();
|
csma_output_init();
|
||||||
on();
|
on();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
max_payload(void)
|
||||||
|
{
|
||||||
|
int framer_hdrlen;
|
||||||
|
|
||||||
|
init_sec();
|
||||||
|
|
||||||
|
framer_hdrlen = NETSTACK_FRAMER.length();
|
||||||
|
|
||||||
|
if(framer_hdrlen < 0) {
|
||||||
|
/* Framing failed, we assume the maximum header length */
|
||||||
|
framer_hdrlen = CSMA_MAC_MAX_HEADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CSMA_MAC_LEN - framer_hdrlen;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
const struct mac_driver csma_driver = {
|
const struct mac_driver csma_driver = {
|
||||||
"CSMA",
|
"CSMA",
|
||||||
init,
|
init,
|
||||||
send_packet,
|
send_packet,
|
||||||
input_packet,
|
input_packet,
|
||||||
on,
|
on,
|
||||||
off
|
off,
|
||||||
|
max_payload,
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -65,6 +65,25 @@
|
||||||
|
|
||||||
#define CSMA_ACK_LEN 3
|
#define CSMA_ACK_LEN 3
|
||||||
|
|
||||||
|
/* Default MAC len for 802.15.4 classic */
|
||||||
|
#ifdef CSMA_MAC_CONF_LEN
|
||||||
|
#define CSMA_MAC_LEN CSMA_MAC_CONF_LEN
|
||||||
|
#else
|
||||||
|
#define CSMA_MAC_LEN 127 - 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* just a default - with LLSEC, etc */
|
||||||
|
#define CSMA_MAC_MAX_HEADER 21
|
||||||
|
|
||||||
|
|
||||||
extern const struct mac_driver csma_driver;
|
extern const struct mac_driver csma_driver;
|
||||||
|
|
||||||
|
/* CSMA security framer functions */
|
||||||
|
int csma_security_create_frame(void);
|
||||||
|
int csma_security_parse_frame(void);
|
||||||
|
|
||||||
|
/* key management for CSMA */
|
||||||
|
int csma_security_set_key(uint8_t index, const uint8_t *key);
|
||||||
|
|
||||||
|
|
||||||
#endif /* CSMA_H_ */
|
#endif /* CSMA_H_ */
|
||||||
|
|
|
@ -74,6 +74,12 @@
|
||||||
#define LLSEC802154_USES_AUX_HEADER LLSEC802154_ENABLED
|
#define LLSEC802154_USES_AUX_HEADER LLSEC802154_ENABLED
|
||||||
#endif /* LLSEC802154_CONF_USES_AUX_HEADER */
|
#endif /* LLSEC802154_CONF_USES_AUX_HEADER */
|
||||||
|
|
||||||
|
#ifdef LLSEC802154_CONF_USES_FRAME_COUNTER
|
||||||
|
#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_CONF_USES_FRAME_COUNTER
|
||||||
|
#else
|
||||||
|
#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_ENABLED
|
||||||
|
#endif /* LLSEC802154_CONF_USES_FRAME_COUNTER */
|
||||||
|
|
||||||
#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)
|
||||||
|
|
|
@ -76,6 +76,9 @@ struct mac_driver {
|
||||||
|
|
||||||
/** Turn the MAC layer off. */
|
/** Turn the MAC layer off. */
|
||||||
int (* off)(void);
|
int (* off)(void);
|
||||||
|
|
||||||
|
/** Read out estimated max payload size based on payload in packetbuf */
|
||||||
|
int (* max_payload)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Generic MAC return values. */
|
/* Generic MAC return values. */
|
||||||
|
|
|
@ -67,6 +67,12 @@ off(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
max_payload(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
init(void)
|
init(void)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +84,7 @@ const struct mac_driver nullmac_driver = {
|
||||||
send_packet,
|
send_packet,
|
||||||
packet_input,
|
packet_input,
|
||||||
on,
|
on,
|
||||||
off
|
off,
|
||||||
|
max_payload,
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -66,8 +66,8 @@
|
||||||
/* 1 channel, sequence length 1 */
|
/* 1 channel, sequence length 1 */
|
||||||
#define TSCH_HOPPING_SEQUENCE_1_1 (uint8_t[]){ 20 }
|
#define TSCH_HOPPING_SEQUENCE_1_1 (uint8_t[]){ 20 }
|
||||||
|
|
||||||
/* Max TSCH packet lenght */
|
/* Max TSCH packet lenght - last bytes are CRC in default 802.15.4 packets */
|
||||||
#define TSCH_PACKET_MAX_LEN MIN(127, PACKETBUF_SIZE)
|
#define TSCH_PACKET_MAX_LEN MIN(127 - 2, PACKETBUF_SIZE)
|
||||||
|
|
||||||
/* The jitter to remove in ticks.
|
/* The jitter to remove in ticks.
|
||||||
* This should be the sum of measurement errors on Tx and Rx nodes.
|
* This should be the sum of measurement errors on Tx and Rx nodes.
|
||||||
|
|
|
@ -1151,13 +1151,21 @@ turn_off(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
max_payload(void)
|
||||||
|
{
|
||||||
|
/* Setup security... before. */
|
||||||
|
return TSCH_PACKET_MAX_LEN - NETSTACK_FRAMER.length();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
const struct mac_driver tschmac_driver = {
|
const struct mac_driver tschmac_driver = {
|
||||||
"TSCH",
|
"TSCH",
|
||||||
tsch_init,
|
tsch_init,
|
||||||
send_packet,
|
send_packet,
|
||||||
packet_input,
|
packet_input,
|
||||||
turn_on,
|
turn_on,
|
||||||
turn_off
|
turn_off,
|
||||||
|
max_payload,
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
#include "net/linkaddr.h"
|
#include "net/linkaddr.h"
|
||||||
#include "net/mac/llsec802154.h"
|
#include "net/mac/llsec802154.h"
|
||||||
|
#include "net/mac/csma/csma-security.h"
|
||||||
#include "net/mac/tsch/tsch-conf.h"
|
#include "net/mac/tsch/tsch-conf.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,6 +239,11 @@ enum {
|
||||||
PACKETBUF_ATTR_KEY_INDEX,
|
PACKETBUF_ATTR_KEY_INDEX,
|
||||||
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||||
|
|
||||||
|
#if LLSEC802154_USES_FRAME_COUNTER
|
||||||
|
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1,
|
||||||
|
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3,
|
||||||
|
#endif /* LLSEC802154_USES_FRAME_COUNTER */
|
||||||
|
|
||||||
/* Scope 2 attributes: used between end-to-end nodes. */
|
/* Scope 2 attributes: used between end-to-end nodes. */
|
||||||
/* These must be last */
|
/* These must be last */
|
||||||
PACKETBUF_ADDR_SENDER,
|
PACKETBUF_ADDR_SENDER,
|
||||||
|
@ -277,6 +283,8 @@ void packetbuf_attr_copyfrom(struct packetbuf_attr *attrs,
|
||||||
#define PACKETBUF_ATTR_BYTE 8
|
#define PACKETBUF_ATTR_BYTE 8
|
||||||
#define PACKETBUF_ADDRSIZE (LINKADDR_SIZE * PACKETBUF_ATTR_BYTE)
|
#define PACKETBUF_ADDRSIZE (LINKADDR_SIZE * PACKETBUF_ATTR_BYTE)
|
||||||
|
|
||||||
|
#define PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT 0xffff
|
||||||
|
|
||||||
struct packetbuf_attrlist {
|
struct packetbuf_attrlist {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
|
|
|
@ -64,6 +64,20 @@ struct tx_callback {
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static struct tx_callback callbacks[MAX_CALLBACKS];
|
static struct tx_callback callbacks[MAX_CALLBACKS];
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
init_sec(void)
|
||||||
|
{
|
||||||
|
/* use the CSMA LLSEC config parameter */
|
||||||
|
#if LLSEC802154_USES_AUX_HEADER
|
||||||
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) ==
|
||||||
|
PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT) {
|
||||||
|
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
|
||||||
|
CSMA_LLSEC_SECURITY_LEVEL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void
|
void
|
||||||
packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx)
|
packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx)
|
||||||
{
|
{
|
||||||
|
@ -164,6 +178,13 @@ off()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
max_payload()
|
||||||
|
{
|
||||||
|
init_sec();
|
||||||
|
return 127 - NETSTACK_FRAMER.length();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
init(void)
|
init(void)
|
||||||
{
|
{
|
||||||
|
@ -176,6 +197,7 @@ const struct mac_driver border_router_mac_driver = {
|
||||||
send_packet,
|
send_packet,
|
||||||
packet_input,
|
packet_input,
|
||||||
on,
|
on,
|
||||||
off
|
off,
|
||||||
|
max_payload,
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -55,6 +55,9 @@
|
||||||
#if MAC_CONF_WITH_TSCH
|
#if MAC_CONF_WITH_TSCH
|
||||||
#include "net/mac/tsch/tsch.h"
|
#include "net/mac/tsch/tsch.h"
|
||||||
#endif /* MAC_CONF_WITH_TSCH */
|
#endif /* MAC_CONF_WITH_TSCH */
|
||||||
|
#if MAC_CONF_WITH_CSMA
|
||||||
|
#include "net/mac/csma/csma.h"
|
||||||
|
#endif
|
||||||
#include "net/routing/routing.h"
|
#include "net/routing/routing.h"
|
||||||
#include "net/mac/llsec802154.h"
|
#include "net/mac/llsec802154.h"
|
||||||
|
|
||||||
|
@ -424,7 +427,7 @@ PT_THREAD(cmd_rpl_global_repair(struct pt *pt, shell_output_func output, char *a
|
||||||
{
|
{
|
||||||
PT_BEGIN(pt);
|
PT_BEGIN(pt);
|
||||||
|
|
||||||
SHELL_OUTPUT(output, "Triggering routing global repair\n")
|
SHELL_OUTPUT(output, "Triggering routing global repair\n");
|
||||||
NETSTACK_ROUTING.global_repair("Shell");
|
NETSTACK_ROUTING.global_repair("Shell");
|
||||||
|
|
||||||
PT_END(pt);
|
PT_END(pt);
|
||||||
|
@ -447,7 +450,7 @@ PT_THREAD(cmd_rpl_refresh_routes(struct pt *pt, shell_output_func output, char *
|
||||||
{
|
{
|
||||||
PT_BEGIN(pt);
|
PT_BEGIN(pt);
|
||||||
|
|
||||||
SHELL_OUTPUT(output, "Triggering routes refresh\n")
|
SHELL_OUTPUT(output, "Triggering routes refresh\n");
|
||||||
rpl_refresh_routes("Shell");
|
rpl_refresh_routes("Shell");
|
||||||
|
|
||||||
PT_END(pt);
|
PT_END(pt);
|
||||||
|
@ -729,6 +732,73 @@ PT_THREAD(cmd_6top(struct pt *pt, shell_output_func output, char *args))
|
||||||
}
|
}
|
||||||
#endif /* TSCH_WITH_SIXTOP */
|
#endif /* TSCH_WITH_SIXTOP */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if LLSEC802154_ENABLED
|
||||||
|
static
|
||||||
|
PT_THREAD(cmd_llsec_setlv(struct pt *pt, shell_output_func output, char *args))
|
||||||
|
{
|
||||||
|
|
||||||
|
PT_BEGIN(pt);
|
||||||
|
|
||||||
|
if(args == NULL) {
|
||||||
|
SHELL_OUTPUT(output, "Default LLSEC level is %d\n",
|
||||||
|
uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
|
||||||
|
PT_EXIT(pt);
|
||||||
|
} else {
|
||||||
|
int lv = atoi(args);
|
||||||
|
if(lv < 0 || lv > 7) {
|
||||||
|
SHELL_OUTPUT(output, "Illegal LLSEC Level %d\n", lv);
|
||||||
|
PT_EXIT(pt);
|
||||||
|
} else {
|
||||||
|
uipbuf_set_default_attr(UIPBUF_ATTR_LLSEC_LEVEL, lv);
|
||||||
|
uipbuf_clear_attr();
|
||||||
|
SHELL_OUTPUT(output, "LLSEC default level set %d\n", lv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PT_END(pt);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static
|
||||||
|
PT_THREAD(cmd_llsec_setkey(struct pt *pt, shell_output_func output, char *args))
|
||||||
|
{
|
||||||
|
char *next_args;
|
||||||
|
|
||||||
|
PT_BEGIN(pt);
|
||||||
|
|
||||||
|
SHELL_ARGS_INIT(args, next_args);
|
||||||
|
|
||||||
|
if(args == NULL) {
|
||||||
|
SHELL_OUTPUT(output, "Provide an index and a 16-char string for the key\n");
|
||||||
|
PT_EXIT(pt);
|
||||||
|
} else {
|
||||||
|
int key;
|
||||||
|
SHELL_ARGS_NEXT(args, next_args);
|
||||||
|
key = atoi(args);
|
||||||
|
if(key < 0) {
|
||||||
|
SHELL_OUTPUT(output, "Illegal LLSEC Key index %d\n", key);
|
||||||
|
PT_EXIT(pt);
|
||||||
|
} else {
|
||||||
|
#if MAC_CONF_WITH_CSMA
|
||||||
|
/* Get next arg (key-string) */
|
||||||
|
SHELL_ARGS_NEXT(args, next_args);
|
||||||
|
if(args == NULL) {
|
||||||
|
SHELL_OUTPUT(output, "Provide both an index and a key\n");
|
||||||
|
} else if(strlen(args) == 16) {
|
||||||
|
csma_security_set_key(key, (const uint8_t *) args);
|
||||||
|
SHELL_OUTPUT(output, "Set key for index %d\n", key);
|
||||||
|
} else {
|
||||||
|
SHELL_OUTPUT(output, "Wrong length of key: '%s' (%d)\n", args, strlen(args));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SHELL_OUTPUT(output, "Set key not supported.\n");
|
||||||
|
PT_EXIT(pt);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PT_END(pt);
|
||||||
|
}
|
||||||
|
#endif /* LLSEC802154_ENABLED */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
shell_commands_init(void)
|
shell_commands_init(void)
|
||||||
{
|
{
|
||||||
|
@ -801,6 +871,10 @@ const struct shell_command_t builtin_shell_commands[] = {
|
||||||
#if TSCH_WITH_SIXTOP
|
#if TSCH_WITH_SIXTOP
|
||||||
{ "6top", cmd_6top, "'> 6top help': Shows 6top command usage" },
|
{ "6top", cmd_6top, "'> 6top help': Shows 6top command usage" },
|
||||||
#endif /* TSCH_WITH_SIXTOP */
|
#endif /* TSCH_WITH_SIXTOP */
|
||||||
|
#if LLSEC802154_ENABLED
|
||||||
|
{ "llsec-set-level", cmd_llsec_setlv, "'> llsec-set-level <lv>': Set the level of link layer security (show if no lv argument)"},
|
||||||
|
{ "llsec-set-key", cmd_llsec_setkey, "'> llsec-set-key <id> <key>': Set the key of link layer security"},
|
||||||
|
#endif /* LLSEC802154_ENABLED */
|
||||||
{ NULL, NULL, NULL },
|
{ NULL, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue