From c5d59843c4ed9f08e50b811c1191e96d8c2d1788 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 29 May 2018 11:00:13 +0200 Subject: [PATCH 01/14] added linklayer security for CSMA --- os/net/mac/csma/anti-replay.c | 115 ++++++++++++ os/net/mac/csma/anti-replay.h | 80 ++++++++ os/net/mac/csma/ccm-star-packetbuf.c | 80 ++++++++ os/net/mac/csma/ccm-star-packetbuf.h | 39 ++++ os/net/mac/csma/csma-output.c | 10 +- os/net/mac/csma/csma-security.c | 267 +++++++++++++++++++++++++++ os/net/mac/csma/csma-security.h | 74 ++++++++ os/net/mac/csma/csma.c | 8 +- os/net/mac/csma/csma.h | 8 + os/net/packetbuf.h | 5 + 10 files changed, 684 insertions(+), 2 deletions(-) create mode 100644 os/net/mac/csma/anti-replay.c create mode 100644 os/net/mac/csma/anti-replay.h create mode 100644 os/net/mac/csma/ccm-star-packetbuf.c create mode 100644 os/net/mac/csma/ccm-star-packetbuf.h create mode 100644 os/net/mac/csma/csma-security.c create mode 100644 os/net/mac/csma/csma-security.h diff --git a/os/net/mac/csma/anti-replay.c b/os/net/mac/csma/anti-replay.c new file mode 100644 index 000000000..347674184 --- /dev/null +++ b/os/net/mac/csma/anti-replay.c @@ -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 + */ + +/** + * \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 */ + +/** @} */ diff --git a/os/net/mac/csma/anti-replay.h b/os/net/mac/csma/anti-replay.h new file mode 100644 index 000000000..9211a6e7a --- /dev/null +++ b/os/net/mac/csma/anti-replay.h @@ -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 + */ + +/** + * \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 */ + +/** @} */ diff --git a/os/net/mac/csma/ccm-star-packetbuf.c b/os/net/mac/csma/ccm-star-packetbuf.c new file mode 100644 index 000000000..17b9befdc --- /dev/null +++ b/os/net/mac/csma/ccm-star-packetbuf.c @@ -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 + * Konrad Krentz + */ + +#include "net/linkaddr.h" +#include "net/packetbuf.h" +#include "net/mac/llsec802154.h" +#include + +#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 */ diff --git a/os/net/mac/csma/ccm-star-packetbuf.h b/os/net/mac/csma/ccm-star-packetbuf.h new file mode 100644 index 000000000..578bdef96 --- /dev/null +++ b/os/net/mac/csma/ccm-star-packetbuf.h @@ -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_ */ diff --git a/os/net/mac/csma/csma-output.c b/os/net/mac/csma/csma-output.c index 1773e0cb0..65505532e 100644 --- a/os/net/mac/csma/csma-output.c +++ b/os/net/mac/csma/csma-output.c @@ -40,6 +40,7 @@ */ #include "net/mac/csma/csma.h" +#include "net/mac/csma/csma-security.h" #include "net/packetbuf.h" #include "net/queuebuf.h" #include "dev/watchdog.h" @@ -169,7 +170,14 @@ send_one_packet(void *ptr) packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr); packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); - if(NETSTACK_FRAMER.create() < 0) { +#if LLSEC802154_ENABLED + /* These should possibly be taken from upper layers in the future */ + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, CSMA_LLSEC_SECURITY_LEVEL); + packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, CSMA_LLSEC_KEY_ID_MODE); + packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, CSMA_LLSEC_KEY_INDEX); +#endif /* LLSEC802154_ENABLED */ + + if(csma_security_create_frame() < 0) { /* Failed to allocate space for headers */ LOG_ERR("failed to create packet\n"); ret = MAC_TX_ERR_FATAL; diff --git a/os/net/mac/csma/csma-security.c b/os/net/mac/csma/csma-security.c new file mode 100644 index 000000000..ec7f7767a --- /dev/null +++ b/os/net/mac/csma/csma-security.c @@ -0,0 +1,267 @@ +/* + * 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 + */ + +/** + * \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 +#include +#include "ccm-star-packetbuf.h" +/* Log configuration */ +#include "sys/log.h" +#define LOG_MODULE "CSMA" +#define LOG_LEVEL LOG_LEVEL_MAC + +#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER + +/** + * 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 */ +void +csma_security_set_key(uint8_t index, uint8_t *key) +{ + if(key != NULL && index < CSMA_LLSEC_MAXKEYS) { + memcpy(keys[index].u8, key, 16); + } +} + +#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; + uint8_t generated_mic[MIC_LEN]; + uint8_t *mic; + uint8_t key_index; + aes_key_t *key; + uint8_t with_encryption; + + key_index = packetbuf_attr(PACKETBUF_ATTR_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, + forward); + + if(forward) { + packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN); + return 1; + } else { + return (memcmp(generated_mic, mic, MIC_LEN) == 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 && + packetbuf_attr(PACKETBUF_ATTR_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(!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) KEY:0x%02x\n", packetbuf_datalen(), packetbuf_totlen(), + packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX)); + } + return hdr_len; +} + +/*---------------------------------------------------------------------------*/ +int +csma_security_frame_len(void) +{ + if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 && + packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX) != 0xffff) { + return NETSTACK_FRAMER.length() + MIC_LEN; + } + 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), + packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE), + packetbuf_attr(PACKETBUF_ATTR_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(packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE) != CSMA_LLSEC_KEY_ID_MODE) { + LOG_INFO("received frame with wrong key id mode (%u) from ", + packetbuf_attr(PACKETBUF_ATTR_KEY_ID_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) { + LOG_ERR("MIC error - too little data in frame!\n"); + return FRAMER_FAILED; + } + + packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN); + 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 */ + +/** @} */ diff --git a/os/net/mac/csma/csma-security.h b/os/net/mac/csma/csma-security.h new file mode 100644 index 000000000..d99f6292b --- /dev/null +++ b/os/net/mac/csma/csma-security.h @@ -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 + */ + +#ifndef CSMA_SECURITY_H_ +#define CSMA_SECURITY_H_ + + +#ifdef CSMA_CONF_LLSEC_DEFAULT_KEY0 +#define CSMA_LLSEC_DEFAULT_KEY0 CSMA_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_ */ diff --git a/os/net/mac/csma/csma.c b/os/net/mac/csma/csma.c index 7259e35c8..4db20fa9a 100644 --- a/os/net/mac/csma/csma.c +++ b/os/net/mac/csma/csma.c @@ -70,7 +70,7 @@ input_packet(void) if(packetbuf_datalen() == CSMA_ACK_LEN) { /* Ignore ack packets */ 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()); } else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) && @@ -131,6 +131,12 @@ off(void) static void init(void) { + +#ifdef CSMA_LLSEC_DEFAULT_KEY0 + uint8_t key[16] = CSMA_LLSEC_DEFAULT_KEY0; + csma_security_set_key(0, key); +#endif + csma_output_init(); on(); } diff --git a/os/net/mac/csma/csma.h b/os/net/mac/csma/csma.h index 9e0773f28..655e59134 100644 --- a/os/net/mac/csma/csma.h +++ b/os/net/mac/csma/csma.h @@ -67,4 +67,12 @@ 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 */ +void csma_security_set_key(uint8_t index, uint8_t *key); + + #endif /* CSMA_H_ */ diff --git a/os/net/packetbuf.h b/os/net/packetbuf.h index 20e071474..2429e84b0 100644 --- a/os/net/packetbuf.h +++ b/os/net/packetbuf.h @@ -238,6 +238,11 @@ enum { PACKETBUF_ATTR_KEY_INDEX, #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. */ /* These must be last */ PACKETBUF_ADDR_SENDER, From df130952c7cab9855f34a51be45915089fad22c3 Mon Sep 17 00:00:00 2001 From: Olav Frengstad Date: Mon, 27 Aug 2018 22:42:46 +0200 Subject: [PATCH 02/14] Ensure correct setup LLSEC for CSMA * Add `LLSEC_KEY_INDEX` for switching between implicit/explicit keys * Add missing `LLSEC_CONF_* * Conditionally include required CSMA setup for IPv6 (enable security when calculating frame length) * Setup default key * Always export `csma_security_set_key/2` --- os/net/ipv6/sicslowpan.c | 9 +++++++++ os/net/mac/csma/csma-output.c | 4 +++- os/net/mac/csma/csma-security.c | 30 +++++++++++++++++++++--------- os/net/mac/csma/csma-security.h | 4 +++- os/net/mac/llsec802154.h | 6 ++++++ 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index 9e4e3a8b4..2789e4e7d 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -74,6 +74,10 @@ #include "net/packetbuf.h" #include "net/queuebuf.h" +#if MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED +#include "net/mac/csma/csma-security.h" +#endif /* MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED */ + #include "net/routing/routing.h" /* Log configuration */ @@ -1615,6 +1619,11 @@ output(const linkaddr_t *localdest) } #endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */ +#if MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, + FRAME802154_SECURITY_LEVEL_NONE != CSMA_LLSEC_SECURITY_LEVEL); +#endif /* MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED */ + /* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC. * We calculate it here only to make a better decision of whether the outgoing packet * needs to be fragmented or not. */ diff --git a/os/net/mac/csma/csma-output.c b/os/net/mac/csma/csma-output.c index 65505532e..b7eab163c 100644 --- a/os/net/mac/csma/csma-output.c +++ b/os/net/mac/csma/csma-output.c @@ -173,13 +173,15 @@ send_one_packet(void *ptr) #if LLSEC802154_ENABLED /* These should possibly be taken from upper layers in the future */ packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, CSMA_LLSEC_SECURITY_LEVEL); +#if LLSEC802154_USES_EXPLICIT_KEYS packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, CSMA_LLSEC_KEY_ID_MODE); packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, CSMA_LLSEC_KEY_INDEX); +#endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_ENABLED */ if(csma_security_create_frame() < 0) { /* 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; } else { int is_broadcast; diff --git a/os/net/mac/csma/csma-security.c b/os/net/mac/csma/csma-security.c index ec7f7767a..50faf2723 100644 --- a/os/net/mac/csma/csma-security.c +++ b/os/net/mac/csma/csma-security.c @@ -63,6 +63,18 @@ #if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER +#define MIC_LEN LLSEC802154_MIC_LEN(CSMA_LLSEC_SECURITY_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 */ @@ -98,7 +110,7 @@ aead(uint8_t hdrlen, int forward) aes_key_t *key; uint8_t with_encryption; - key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); + key_index = LLSEC_KEY_INDEX; if(key_index > CSMA_LLSEC_MAXKEYS) { LOG_ERR("Key not available: %u\n", key_index); return 0; @@ -149,7 +161,7 @@ csma_security_create_frame(void) packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 && - packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX) != 0xffff) { + LLSEC_KEY_INDEX != 0xffff) { anti_replay_set_counter(); } @@ -170,7 +182,7 @@ csma_security_create_frame(void) LOG_INFO_(" "); LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); LOG_INFO_(" %u (%u) KEY:0x%02x\n", packetbuf_datalen(), packetbuf_totlen(), - packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX)); + LLSEC_KEY_INDEX); } return hdr_len; } @@ -180,7 +192,7 @@ int csma_security_frame_len(void) { if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 && - packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX) != 0xffff) { + LLSEC_KEY_INDEX != 0xffff) { return NETSTACK_FRAMER.length() + MIC_LEN; } return NETSTACK_FRAMER.length(); @@ -207,8 +219,8 @@ csma_security_parse_frame(void) 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), - packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE), - packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX)); + 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 ", @@ -218,9 +230,8 @@ csma_security_parse_frame(void) return FRAMER_FAILED; } - if(packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE) != CSMA_LLSEC_KEY_ID_MODE) { - LOG_INFO("received frame with wrong key id mode (%u) from ", - packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE)); + 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; @@ -262,6 +273,7 @@ csma_security_parse_frame(void) { return NETSTACK_FRAMER.parse(); } + #endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */ /** @} */ diff --git a/os/net/mac/csma/csma-security.h b/os/net/mac/csma/csma-security.h index d99f6292b..d58885f5c 100644 --- a/os/net/mac/csma/csma-security.h +++ b/os/net/mac/csma/csma-security.h @@ -42,7 +42,7 @@ #ifdef CSMA_CONF_LLSEC_DEFAULT_KEY0 -#define CSMA_LLSEC_DEFAULT_KEY0 CSMA_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 @@ -71,4 +71,6 @@ #define CSMA_LLSEC_MAXKEYS 1 #endif +void csma_security_set_key(uint8_t index, uint8_t *key); + #endif /* CSMA_SECURITY_H_ */ diff --git a/os/net/mac/llsec802154.h b/os/net/mac/llsec802154.h index fe1a9d231..e808fef7a 100644 --- a/os/net/mac/llsec802154.h +++ b/os/net/mac/llsec802154.h @@ -74,6 +74,12 @@ #define LLSEC802154_USES_AUX_HEADER LLSEC802154_ENABLED #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 #define LLSEC802154_HTONS(n) (n) #define LLSEC802154_HTONL(n) (n) From c42fae82daea5a63b2b875e4dcb9ff492b07621b Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sat, 20 Oct 2018 22:25:55 +0200 Subject: [PATCH 03/14] added uipbuf attributes for llsec level and key and added payloadlen in mac --- arch/cpu/nrf52832/ble/ble-mac.c | 9 ++++- os/net/ipv6/sicslowpan.c | 29 +++++++-------- os/net/ipv6/uip6.c | 1 + os/net/ipv6/uipbuf.c | 31 +++++++++++++--- os/net/ipv6/uipbuf.h | 22 +++++++++++ os/net/mac/ble/ble-l2cap.c | 7 ++++ os/net/mac/csma/csma-security.c | 37 +++++++++++++++---- os/net/mac/csma/csma.c | 35 +++++++++++++++++- os/net/mac/csma/csma.h | 11 ++++++ os/net/mac/mac.h | 3 ++ os/net/mac/nullmac/nullmac.c | 9 ++++- os/net/mac/tsch/tsch.c | 13 ++++++- os/net/packetbuf.h | 3 ++ .../native/border-router-mac.c | 24 +++++++++++- 14 files changed, 200 insertions(+), 34 deletions(-) diff --git a/arch/cpu/nrf52832/ble/ble-mac.c b/arch/cpu/nrf52832/ble/ble-mac.c index 4fe1ef934..d604a911d 100644 --- a/arch/cpu/nrf52832/ble/ble-mac.c +++ b/arch/cpu/nrf52832/ble/ble-mac.c @@ -347,6 +347,12 @@ off(void) return 1; } /*---------------------------------------------------------------------------*/ +static int +max_payload(void) +{ + return PACKETBUF_SIZE; +} +/*---------------------------------------------------------------------------*/ static void init(void) { @@ -371,7 +377,8 @@ const struct mac_driver ble_ipsp_mac_driver = { send_packet, NULL, on, - off + off, + max_payload }; /*---------------------------------------------------------------------------*/ /** diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index 2789e4e7d..6f15af4f4 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -74,10 +74,6 @@ #include "net/packetbuf.h" #include "net/queuebuf.h" -#if MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED -#include "net/mac/csma/csma-security.h" -#endif /* MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED */ - #include "net/routing/routing.h" /* Log configuration */ @@ -1618,23 +1614,26 @@ output(const linkaddr_t *localdest) return 0; } #endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */ - -#if MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED - packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, - FRAME802154_SECURITY_LEVEL_NONE != CSMA_LLSEC_SECURITY_LEVEL); -#endif /* MAC_CONF_WITH_CSMA && LLSEC802154_CONF_ENABLED */ - +#if LLSEC802154_USES_AUX_HEADER + /* copy LLSEC level */ + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, + 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 */ /* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC. * We calculate it here only to make a better decision of whether 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 = NETSTACK_MAC.max_payload(); + if(max_payload <= 0) { + /* Framing failed, drop packet */ + LOG_WARN("output: failed to calculate payload size - dropping packet\n"); + return 0; } - max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > max_payload; 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, diff --git a/os/net/ipv6/uip6.c b/os/net/ipv6/uip6.c index dfbec52b7..82d7900db 100644 --- a/os/net/ipv6/uip6.c +++ b/os/net/ipv6/uip6.c @@ -409,6 +409,7 @@ uip_init(void) { int c; + uipbuf_init(); uip_ds6_init(); uip_icmp6_init(); uip_nd6_init(); diff --git a/os/net/ipv6/uipbuf.c b/os/net/ipv6/uipbuf.c index 6ccbb99aa..d2004c727 100644 --- a/os/net/ipv6/uipbuf.c +++ b/os/net/ipv6/uipbuf.c @@ -37,6 +37,7 @@ /*---------------------------------------------------------------------------*/ static uint16_t uipbuf_attrs[UIPBUF_ATTR_MAX]; +static uint16_t uipbuf_default_attrs[UIPBUF_ATTR_MAX]; /*---------------------------------------------------------------------------*/ /* Get the next header given the buffer - start indicates that this is @@ -101,15 +102,21 @@ uipbuf_set_attr(uint8_t type, uint16_t value) 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 uipbuf_clear_attr(void) { - /* set everything to "zero" */ - memset(uipbuf_attrs, 0, sizeof(uipbuf_attrs)); - - /* And initialize anything that should be initialized */ - uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, - UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED); + /* set everything to "defaults" */ + memcpy(uipbuf_attrs, uipbuf_default_attrs, sizeof(uipbuf_attrs)); } /*---------------------------------------------------------------------------*/ void @@ -131,3 +138,15 @@ uipbuf_is_attr_flag(uint16_t flag) return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag; } /*---------------------------------------------------------------------------*/ +void +uipbuf_init(void) +{ + /* And initialize anything that should be initialized */ + uipbuf_set_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_attr(UIPBUF_ATTR_LLSEC_LEVEL, UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT); +} + +/*---------------------------------------------------------------------------*/ diff --git a/os/net/ipv6/uipbuf.h b/os/net/ipv6/uipbuf.h index 337ffe17f..6af4e590b 100644 --- a/os/net/ipv6/uipbuf.h +++ b/os/net/ipv6/uipbuf.h @@ -81,6 +81,17 @@ uint16_t uipbuf_get_attr(uint8_t type); */ 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. * \param flag_bits The bits to set in the flag. @@ -115,6 +126,14 @@ uint16_t uipbuf_is_attr_flag(uint16_t flag_bits); */ 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. * @@ -124,6 +143,9 @@ void uipbuf_clear_attr(void); /* Avoid using prefix compression on the packet (6LoWPAN) */ #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. * diff --git a/os/net/mac/ble/ble-l2cap.c b/os/net/mac/ble/ble-l2cap.c index 076d919e8..fb755cc85 100644 --- a/os/net/mac/ble/ble-l2cap.c +++ b/os/net/mac/ble/ble-l2cap.c @@ -505,6 +505,12 @@ off(void) return 0; } /*---------------------------------------------------------------------------*/ +static int +max_payload(void) +{ + return BLE_L2CAP_NODE_MTU; +} +/*---------------------------------------------------------------------------*/ const struct mac_driver ble_l2cap_driver = { "ble-l2cap", init, @@ -512,6 +518,7 @@ const struct mac_driver ble_l2cap_driver = { input, on, off, + max_payload, }; /*---------------------------------------------------------------------------*/ PROCESS_THREAD(ble_l2cap_tx_process, ev, data) diff --git a/os/net/mac/csma/csma-security.c b/os/net/mac/csma/csma-security.c index 50faf2723..83853b81b 100644 --- a/os/net/mac/csma/csma-security.c +++ b/os/net/mac/csma/csma-security.c @@ -61,9 +61,11 @@ #define LOG_MODULE "CSMA" #define LOG_LEVEL LOG_LEVEL_MAC +static const char * HEX = "0123456789ABCDEF"; + #if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER -#define MIC_LEN LLSEC802154_MIC_LEN(CSMA_LLSEC_SECURITY_LEVEL) +#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) \ @@ -104,7 +106,8 @@ aead(uint8_t hdrlen, int forward) uint8_t *a; uint8_t a_len; uint8_t *result; - uint8_t generated_mic[MIC_LEN]; + /* Allocate for MAX level */ + uint8_t generated_mic[MIC_LEN(7)]; uint8_t *mic; uint8_t key_index; aes_key_t *key; @@ -142,14 +145,14 @@ aead(uint8_t hdrlen, int forward) CCM_STAR.aead(nonce, m, m_len, a, a_len, - result, MIC_LEN, + result, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07), forward); if(forward) { - packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN); + packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)); return 1; } else { - return (memcmp(generated_mic, mic, MIC_LEN) == 0); + return (memcmp(generated_mic, mic, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) == 0); } } @@ -171,6 +174,15 @@ csma_security_create_frame(void) } if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0) { + 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"); + if(!aead(hdr_len, 1)) { LOG_ERR("failed to encrypt packet to "); LOG_ERR_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); @@ -183,6 +195,14 @@ csma_security_create_frame(void) LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); LOG_INFO_(" %u (%u) KEY:0x%02x\n", packetbuf_datalen(), packetbuf_totlen(), LLSEC_KEY_INDEX); + + 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"); + } return hdr_len; } @@ -193,7 +213,8 @@ csma_security_frame_len(void) { if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 && LLSEC_KEY_INDEX != 0xffff) { - return NETSTACK_FRAMER.length() + MIC_LEN; + return NETSTACK_FRAMER.length() + + MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07); } return NETSTACK_FRAMER.length(); } @@ -242,12 +263,12 @@ csma_security_parse_frame(void) return FRAMER_FAILED; } - if(packetbuf_datalen() <= MIC_LEN) { + 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_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()); diff --git a/os/net/mac/csma/csma.c b/os/net/mac/csma/csma.c index 4db20fa9a..f9fb6d697 100644 --- a/os/net/mac/csma/csma.c +++ b/os/net/mac/csma/csma.c @@ -49,10 +49,25 @@ #define LOG_MODULE "CSMA" #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 send_packet(mac_callback_t sent, void *ptr) { + + init_sec(); + csma_output_packet(sent, ptr); } /*---------------------------------------------------------------------------*/ @@ -141,12 +156,30 @@ init(void) 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 = { "CSMA", init, send_packet, input_packet, on, - off + off, + max_payload, }; /*---------------------------------------------------------------------------*/ diff --git a/os/net/mac/csma/csma.h b/os/net/mac/csma/csma.h index 655e59134..96f48e326 100644 --- a/os/net/mac/csma/csma.h +++ b/os/net/mac/csma/csma.h @@ -65,6 +65,17 @@ #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 +#endif + +/* just a default - with LLSEC, etc */ +#define CSMA_MAC_MAX_HEADER 21 + + extern const struct mac_driver csma_driver; /* CSMA security framer functions */ diff --git a/os/net/mac/mac.h b/os/net/mac/mac.h index 4f2a75b15..f64838b4c 100644 --- a/os/net/mac/mac.h +++ b/os/net/mac/mac.h @@ -76,6 +76,9 @@ struct mac_driver { /** Turn the MAC layer off. */ int (* off)(void); + + /** Read out estimated max payload size based on payload in packetbuf */ + int (* max_payload)(void); }; /* Generic MAC return values. */ diff --git a/os/net/mac/nullmac/nullmac.c b/os/net/mac/nullmac/nullmac.c index a6199a3f9..de92ee5d8 100644 --- a/os/net/mac/nullmac/nullmac.c +++ b/os/net/mac/nullmac/nullmac.c @@ -67,6 +67,12 @@ off(void) return 0; } /*---------------------------------------------------------------------------*/ +static int +max_payload(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ static void init(void) { @@ -78,6 +84,7 @@ const struct mac_driver nullmac_driver = { send_packet, packet_input, on, - off + off, + max_payload, }; /*---------------------------------------------------------------------------*/ diff --git a/os/net/mac/tsch/tsch.c b/os/net/mac/tsch/tsch.c index 25b565809..719a09b9f 100644 --- a/os/net/mac/tsch/tsch.c +++ b/os/net/mac/tsch/tsch.c @@ -62,6 +62,9 @@ #include "net/mac/tsch/sixtop/sixtop.h" #endif +/* Needed to estimate the MAC lenght */ +#define TSCH_MAC_MAX_LEN 127 + #if FRAME802154_VERSION < FRAME802154_IEEE802154_2015 #error TSCH: FRAME802154_VERSION must be at least FRAME802154_IEEE802154_2015 #endif @@ -1128,13 +1131,21 @@ turn_off(void) return 1; } /*---------------------------------------------------------------------------*/ +static int +max_payload(void) +{ + /* Setup security... before. */ + return TSCH_MAC_MAX_LEN - NETSTACK_FRAMER.length(); +} +/*---------------------------------------------------------------------------*/ const struct mac_driver tschmac_driver = { "TSCH", tsch_init, send_packet, packet_input, turn_on, - turn_off + turn_off, + max_payload, }; /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/net/packetbuf.h b/os/net/packetbuf.h index 2429e84b0..c077ae940 100644 --- a/os/net/packetbuf.h +++ b/os/net/packetbuf.h @@ -55,6 +55,7 @@ #include "contiki.h" #include "net/linkaddr.h" #include "net/mac/llsec802154.h" +#include "net/mac/csma/csma-security.h" #include "net/mac/tsch/tsch-conf.h" /** @@ -282,6 +283,8 @@ void packetbuf_attr_copyfrom(struct packetbuf_attr *attrs, #define PACKETBUF_ATTR_BYTE 8 #define PACKETBUF_ADDRSIZE (LINKADDR_SIZE * PACKETBUF_ATTR_BYTE) +#define PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT 0xffff + struct packetbuf_attrlist { uint8_t type; uint8_t len; diff --git a/os/services/rpl-border-router/native/border-router-mac.c b/os/services/rpl-border-router/native/border-router-mac.c index fbf8b6496..786a35321 100644 --- a/os/services/rpl-border-router/native/border-router-mac.c +++ b/os/services/rpl-border-router/native/border-router-mac.c @@ -42,6 +42,7 @@ #include "net/netstack.h" #include "packetutils.h" #include "border-router.h" +#include "net/mac/csma-security.h" #include /*---------------------------------------------------------------------------*/ @@ -64,6 +65,19 @@ struct tx_callback { /*---------------------------------------------------------------------------*/ static struct tx_callback callbacks[MAX_CALLBACKS]; /*---------------------------------------------------------------------------*/ +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 packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx) { @@ -164,6 +178,13 @@ off() return 1; } /*---------------------------------------------------------------------------*/ +static int +max_payload() +{ + init_sec(); + return 127 - NETSTACK_FRAMER.length(); +} +/*---------------------------------------------------------------------------*/ static void init(void) { @@ -176,6 +197,7 @@ const struct mac_driver border_router_mac_driver = { send_packet, packet_input, on, - off + off, + max_payload, }; /*---------------------------------------------------------------------------*/ From 3542fa8d85ba9840d017574bdb1305f646c53474 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sat, 20 Oct 2018 22:27:02 +0200 Subject: [PATCH 04/14] added back more textual representation of messages in rpl-udp example - good for debugging LLSEC encryption --- examples/rpl-udp/udp-client.c | 7 ++++--- examples/rpl-udp/udp-server.c | 12 ++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/rpl-udp/udp-client.c b/examples/rpl-udp/udp-client.c index 1fb030034..fb13a2073 100644 --- a/examples/rpl-udp/udp-client.c +++ b/examples/rpl-udp/udp-client.c @@ -32,8 +32,7 @@ udp_rx_callback(struct simple_udp_connection *c, const uint8_t *data, uint16_t datalen) { - unsigned count = *(unsigned *)data; - LOG_INFO("Received response %u from ", count); + LOG_INFO("Received response '%s' from ", (char *) data); LOG_INFO_6ADDR(sender_addr); LOG_INFO_("\n"); } @@ -42,6 +41,7 @@ PROCESS_THREAD(udp_client_process, ev, data) { static struct etimer periodic_timer; static unsigned count; + static char str[32]; uip_ipaddr_t dest_ipaddr; PROCESS_BEGIN(); @@ -59,7 +59,8 @@ PROCESS_THREAD(udp_client_process, ev, data) LOG_INFO("Sending request %u to ", count); LOG_INFO_6ADDR(&dest_ipaddr); LOG_INFO_("\n"); - simple_udp_sendto(&udp_conn, &count, sizeof(count), &dest_ipaddr); + snprintf(str, sizeof(str), "hello from the client:%d", count); + simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr); count++; } else { LOG_INFO("Not reachable yet\n"); diff --git a/examples/rpl-udp/udp-server.c b/examples/rpl-udp/udp-server.c index 399cabfc4..d69a97c78 100644 --- a/examples/rpl-udp/udp-server.c +++ b/examples/rpl-udp/udp-server.c @@ -54,15 +54,19 @@ udp_rx_callback(struct simple_udp_connection *c, const uint8_t *data, uint16_t datalen) { - unsigned count = *(unsigned *)data; - LOG_INFO("Received request %u from ", count); + char *str = (char *)data; + char outstr[32]; + LOG_INFO("Received request '%s' from ", str); LOG_INFO_6ADDR(sender_addr); LOG_INFO_("\n"); #if WITH_SERVER_REPLY - LOG_INFO("Sending response %u to ", count); + /* send the number that came in - and is at the end */ + snprintf(outstr, sizeof(outstr), "hello from the server:%s", + &data[strlen("hello from the client:")]); + LOG_INFO("Sending response '%s' to ", outstr); LOG_INFO_6ADDR(sender_addr); LOG_INFO_("\n"); - simple_udp_sendto(&udp_conn, &count, sizeof(count), sender_addr); + simple_udp_sendto(&udp_conn, outstr, strlen(outstr), sender_addr); #endif /* WITH_SERVER_REPLY */ } /*---------------------------------------------------------------------------*/ From d3c95c9a6ead04d42e747a0b179c60cb5d2f54b6 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sat, 20 Oct 2018 22:27:19 +0200 Subject: [PATCH 05/14] added llsec shell commands --- os/services/shell/shell-commands.c | 73 ++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index e8bb4b6b2..32ff763f0 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -729,6 +729,75 @@ PT_THREAD(cmd_6top(struct pt *pt, shell_output_func output, char *args)) } #endif /* TSCH_WITH_SIXTOP */ /*---------------------------------------------------------------------------*/ +#if LLSEC802154_ENABLED +static +PT_THREAD(cmd_llsec_setlv(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, "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); + } + } + SHELL_ARGS_NEXT(args, next_args); + + 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 || key > 16) { + 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 && strlen(args) == 16) { + csma_security_set_key(key, (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 shell_commands_init(void) { @@ -801,6 +870,10 @@ const struct shell_command_t builtin_shell_commands[] = { #if TSCH_WITH_SIXTOP { "6top", cmd_6top, "'> 6top help': Shows 6top command usage" }, #endif /* TSCH_WITH_SIXTOP */ +#if LLSEC802154_ENABLED + { "llsec-set-level", cmd_llsec_setlv, "'> llsec-set-level ': Set the level of link layer security (show if no lv argument)"}, + { "llsec-set-key", cmd_llsec_setkey, "'> llsec-set-key ': Set the key of link layer security (show if no id key argument)"}, +#endif /* LLSEC802154_ENABLED */ { NULL, NULL, NULL }, }; From a2eec4c985a22b0015dcac5f78babafad2f6d1d9 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sat, 20 Oct 2018 22:41:02 +0200 Subject: [PATCH 06/14] fixed csma-security debug output --- os/net/mac/csma/csma-security.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/os/net/mac/csma/csma-security.c b/os/net/mac/csma/csma-security.c index 83853b81b..26caed1d5 100644 --- a/os/net/mac/csma/csma-security.c +++ b/os/net/mac/csma/csma-security.c @@ -61,7 +61,9 @@ #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 @@ -174,6 +176,7 @@ csma_security_create_frame(void) } 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()); @@ -182,6 +185,7 @@ csma_security_create_frame(void) 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 "); @@ -196,12 +200,14 @@ csma_security_create_frame(void) LOG_INFO_(" %u (%u) KEY:0x%02x\n", packetbuf_datalen(), packetbuf_totlen(), 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; From 0a3b89008040225101336076a496d6f77677445f Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 23 Oct 2018 07:50:15 +0200 Subject: [PATCH 07/14] fixed rpl-udp example --- examples/rpl-udp/udp-client.c | 4 ++-- examples/rpl-udp/udp-server.c | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/examples/rpl-udp/udp-client.c b/examples/rpl-udp/udp-client.c index fb13a2073..8628e834c 100644 --- a/examples/rpl-udp/udp-client.c +++ b/examples/rpl-udp/udp-client.c @@ -32,7 +32,7 @@ udp_rx_callback(struct simple_udp_connection *c, const uint8_t *data, uint16_t datalen) { - LOG_INFO("Received response '%s' from ", (char *) data); + LOG_INFO("Received response '%.*s' from ", datalen, (char *) data); LOG_INFO_6ADDR(sender_addr); LOG_INFO_("\n"); } @@ -59,7 +59,7 @@ PROCESS_THREAD(udp_client_process, ev, data) LOG_INFO("Sending request %u to ", count); LOG_INFO_6ADDR(&dest_ipaddr); LOG_INFO_("\n"); - snprintf(str, sizeof(str), "hello from the client:%d", count); + snprintf(str, sizeof(str), "hello %d", count); simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr); count++; } else { diff --git a/examples/rpl-udp/udp-server.c b/examples/rpl-udp/udp-server.c index d69a97c78..072eb8ae8 100644 --- a/examples/rpl-udp/udp-server.c +++ b/examples/rpl-udp/udp-server.c @@ -54,19 +54,13 @@ udp_rx_callback(struct simple_udp_connection *c, const uint8_t *data, uint16_t datalen) { - char *str = (char *)data; - char outstr[32]; - LOG_INFO("Received request '%s' from ", str); + LOG_INFO("Received request '%.*s' from ", datalen, (char *) data); LOG_INFO_6ADDR(sender_addr); LOG_INFO_("\n"); #if WITH_SERVER_REPLY - /* send the number that came in - and is at the end */ - snprintf(outstr, sizeof(outstr), "hello from the server:%s", - &data[strlen("hello from the client:")]); - LOG_INFO("Sending response '%s' to ", outstr); - LOG_INFO_6ADDR(sender_addr); - LOG_INFO_("\n"); - simple_udp_sendto(&udp_conn, outstr, strlen(outstr), sender_addr); + /* send back the same string to the client as an echo reply */ + LOG_INFO("Sending response.\n"); + simple_udp_sendto(&udp_conn, data, datalen, sender_addr); #endif /* WITH_SERVER_REPLY */ } /*---------------------------------------------------------------------------*/ From 008cffe81a24760e2fa005eacd9cc94d1f3d82ee Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 23 Oct 2018 07:51:46 +0200 Subject: [PATCH 08/14] fixed compilation issues --- os/net/ipv6/uipbuf.c | 8 +++++--- os/net/mac/csma/csma-security.h | 2 +- os/net/mac/csma/csma.c | 3 ++- os/services/rpl-border-router/native/border-router-mac.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/os/net/ipv6/uipbuf.c b/os/net/ipv6/uipbuf.c index d2004c727..c25e4523f 100644 --- a/os/net/ipv6/uipbuf.c +++ b/os/net/ipv6/uipbuf.c @@ -141,12 +141,14 @@ uipbuf_is_attr_flag(uint16_t flag) void uipbuf_init(void) { + memset(uipbuf_default_attrs, 0, sizeof(uipbuf_default_attrs)); /* And initialize anything that should be initialized */ - uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, - UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED); + 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_attr(UIPBUF_ATTR_LLSEC_LEVEL, UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT); + uipbuf_set_default_attr(UIPBUF_ATTR_LLSEC_LEVEL, + UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT); } /*---------------------------------------------------------------------------*/ diff --git a/os/net/mac/csma/csma-security.h b/os/net/mac/csma/csma-security.h index d58885f5c..4e9f9b391 100644 --- a/os/net/mac/csma/csma-security.h +++ b/os/net/mac/csma/csma-security.h @@ -44,7 +44,7 @@ #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} +#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 diff --git a/os/net/mac/csma/csma.c b/os/net/mac/csma/csma.c index f9fb6d697..63808192f 100644 --- a/os/net/mac/csma/csma.c +++ b/os/net/mac/csma/csma.c @@ -147,11 +147,12 @@ static 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(); on(); } diff --git a/os/services/rpl-border-router/native/border-router-mac.c b/os/services/rpl-border-router/native/border-router-mac.c index 786a35321..7fe4fc6ed 100644 --- a/os/services/rpl-border-router/native/border-router-mac.c +++ b/os/services/rpl-border-router/native/border-router-mac.c @@ -42,7 +42,6 @@ #include "net/netstack.h" #include "packetutils.h" #include "border-router.h" -#include "net/mac/csma-security.h" #include /*---------------------------------------------------------------------------*/ @@ -65,6 +64,7 @@ struct tx_callback { /*---------------------------------------------------------------------------*/ static struct tx_callback callbacks[MAX_CALLBACKS]; /*---------------------------------------------------------------------------*/ +void init_sec(void) { /* use the CSMA LLSEC config parameter */ From 42dfc81af265a29547ae7a2fbfc5025486ee527d Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 30 Oct 2018 13:38:16 +0100 Subject: [PATCH 09/14] added LLSEC attributes form packetbuf to uipbuf when receiving IP packet, and a few other minor fixes --- examples/rpl-udp/udp-client.c | 3 ++- os/net/ipv6/sicslowpan.c | 13 +++++++++++++ os/net/mac/csma/csma-output.c | 4 +--- os/net/mac/csma/csma-security.c | 12 +++++++----- os/net/mac/csma/csma-security.h | 2 -- os/net/mac/csma/csma.h | 2 +- os/services/shell/shell-commands.c | 15 +++++++-------- 7 files changed, 31 insertions(+), 20 deletions(-) diff --git a/examples/rpl-udp/udp-client.c b/examples/rpl-udp/udp-client.c index 8628e834c..4c27cf1db 100644 --- a/examples/rpl-udp/udp-client.c +++ b/examples/rpl-udp/udp-client.c @@ -59,7 +59,8 @@ PROCESS_THREAD(udp_client_process, ev, data) LOG_INFO("Sending request %u to ", count); LOG_INFO_6ADDR(&dest_ipaddr); LOG_INFO_("\n"); - snprintf(str, sizeof(str), "hello %d", count); + /* avoid the risk of not fitting the '\0' in the string */ + snprintf(str, sizeof(str) - 1, "hello %d", count); simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr); count++; } else { diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index 6f15af4f4..e61cb3731 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -2012,6 +2012,19 @@ input(void) 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(); #if SICSLOWPAN_CONF_FRAG } diff --git a/os/net/mac/csma/csma-output.c b/os/net/mac/csma/csma-output.c index b7eab163c..fcc548f89 100644 --- a/os/net/mac/csma/csma-output.c +++ b/os/net/mac/csma/csma-output.c @@ -171,11 +171,9 @@ send_one_packet(void *ptr) packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); #if LLSEC802154_ENABLED - /* These should possibly be taken from upper layers in the future */ - packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, CSMA_LLSEC_SECURITY_LEVEL); #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); - packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, CSMA_LLSEC_KEY_INDEX); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_ENABLED */ diff --git a/os/net/mac/csma/csma-security.c b/os/net/mac/csma/csma-security.c index 26caed1d5..0b44fa348 100644 --- a/os/net/mac/csma/csma-security.c +++ b/os/net/mac/csma/csma-security.c @@ -88,12 +88,14 @@ typedef struct { static aes_key_t keys[CSMA_LLSEC_MAXKEYS]; /* assumed to be 16 bytes */ -void -csma_security_set_key(uint8_t index, uint8_t *key) +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)) @@ -116,7 +118,7 @@ aead(uint8_t hdrlen, int forward) uint8_t with_encryption; key_index = LLSEC_KEY_INDEX; - if(key_index > CSMA_LLSEC_MAXKEYS) { + if(key_index >= CSMA_LLSEC_MAXKEYS) { LOG_ERR("Key not available: %u\n", key_index); return 0; } @@ -197,8 +199,8 @@ csma_security_create_frame(void) LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); LOG_INFO_(" "); LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); - LOG_INFO_(" %u (%u) KEY:0x%02x\n", packetbuf_datalen(), packetbuf_totlen(), - LLSEC_KEY_INDEX); + 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()); diff --git a/os/net/mac/csma/csma-security.h b/os/net/mac/csma/csma-security.h index 4e9f9b391..97092b84d 100644 --- a/os/net/mac/csma/csma-security.h +++ b/os/net/mac/csma/csma-security.h @@ -71,6 +71,4 @@ #define CSMA_LLSEC_MAXKEYS 1 #endif -void csma_security_set_key(uint8_t index, uint8_t *key); - #endif /* CSMA_SECURITY_H_ */ diff --git a/os/net/mac/csma/csma.h b/os/net/mac/csma/csma.h index 96f48e326..dd5688666 100644 --- a/os/net/mac/csma/csma.h +++ b/os/net/mac/csma/csma.h @@ -83,7 +83,7 @@ int csma_security_create_frame(void); int csma_security_parse_frame(void); /* key management for CSMA */ -void csma_security_set_key(uint8_t index, uint8_t *key); +int csma_security_set_key(uint8_t index, const uint8_t *key); #endif /* CSMA_H_ */ diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index 32ff763f0..0ec04c7c4 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -55,6 +55,9 @@ #if MAC_CONF_WITH_TSCH #include "net/mac/tsch/tsch.h" #endif /* MAC_CONF_WITH_TSCH */ +#if MAC_CONF_WITH_CSMA +#include "net/mac/csma/csma.h" +#endif #include "net/routing/routing.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); - SHELL_OUTPUT(output, "Triggering routing global repair\n") + SHELL_OUTPUT(output, "Triggering routing global repair\n"); NETSTACK_ROUTING.global_repair("Shell"); PT_END(pt); @@ -447,7 +450,7 @@ PT_THREAD(cmd_rpl_refresh_routes(struct pt *pt, shell_output_func output, char * { PT_BEGIN(pt); - SHELL_OUTPUT(output, "Triggering routes refresh\n") + SHELL_OUTPUT(output, "Triggering routes refresh\n"); rpl_refresh_routes("Shell"); PT_END(pt); @@ -733,12 +736,9 @@ PT_THREAD(cmd_6top(struct pt *pt, shell_output_func output, char *args)) static PT_THREAD(cmd_llsec_setlv(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, "Default LLSEC level is %d\n", uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL)); @@ -754,7 +754,6 @@ PT_THREAD(cmd_llsec_setlv(struct pt *pt, shell_output_func output, char *args)) SHELL_OUTPUT(output, "LLSEC default level set %d\n", lv); } } - SHELL_ARGS_NEXT(args, next_args); PT_END(pt); } @@ -775,7 +774,7 @@ PT_THREAD(cmd_llsec_setkey(struct pt *pt, shell_output_func output, char *args)) int key; SHELL_ARGS_NEXT(args, next_args); key = atoi(args); - if(key < 0 || key > 16) { + if(key < 0) { SHELL_OUTPUT(output, "Illegal LLSEC Key index %d\n", key); PT_EXIT(pt); } else { @@ -783,7 +782,7 @@ PT_THREAD(cmd_llsec_setkey(struct pt *pt, shell_output_func output, char *args)) /* Get next arg (key-string) */ SHELL_ARGS_NEXT(args, next_args); if(args != NULL && strlen(args) == 16) { - csma_security_set_key(key, (uint8_t *) args); + 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)); From 35123e9dd8b5f0920469015d03bfb7793bf2ccc3 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 30 Oct 2018 16:22:18 +0100 Subject: [PATCH 10/14] fixed better packet size assumptions --- os/net/mac/csma/csma.h | 2 +- os/net/mac/tsch/tsch-const.h | 4 ++-- os/net/mac/tsch/tsch.c | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/os/net/mac/csma/csma.h b/os/net/mac/csma/csma.h index dd5688666..88396db0b 100644 --- a/os/net/mac/csma/csma.h +++ b/os/net/mac/csma/csma.h @@ -69,7 +69,7 @@ #ifdef CSMA_MAC_CONF_LEN #define CSMA_MAC_LEN CSMA_MAC_CONF_LEN #else -#define CSMA_MAC_LEN 127 +#define CSMA_MAC_LEN 127 - 2 #endif /* just a default - with LLSEC, etc */ diff --git a/os/net/mac/tsch/tsch-const.h b/os/net/mac/tsch/tsch-const.h index edc989378..f78b9883d 100644 --- a/os/net/mac/tsch/tsch-const.h +++ b/os/net/mac/tsch/tsch-const.h @@ -66,8 +66,8 @@ /* 1 channel, sequence length 1 */ #define TSCH_HOPPING_SEQUENCE_1_1 (uint8_t[]){ 20 } -/* Max TSCH packet lenght */ -#define TSCH_PACKET_MAX_LEN MIN(127, PACKETBUF_SIZE) +/* Max TSCH packet lenght - last bytes are CRC in default 802.15.4 packets */ +#define TSCH_PACKET_MAX_LEN MIN(127 - 2, PACKETBUF_SIZE) /* The jitter to remove in ticks. * This should be the sum of measurement errors on Tx and Rx nodes. diff --git a/os/net/mac/tsch/tsch.c b/os/net/mac/tsch/tsch.c index 719a09b9f..8c79c299c 100644 --- a/os/net/mac/tsch/tsch.c +++ b/os/net/mac/tsch/tsch.c @@ -62,9 +62,6 @@ #include "net/mac/tsch/sixtop/sixtop.h" #endif -/* Needed to estimate the MAC lenght */ -#define TSCH_MAC_MAX_LEN 127 - #if FRAME802154_VERSION < FRAME802154_IEEE802154_2015 #error TSCH: FRAME802154_VERSION must be at least FRAME802154_IEEE802154_2015 #endif @@ -1135,7 +1132,7 @@ static int max_payload(void) { /* Setup security... before. */ - return TSCH_MAC_MAX_LEN - NETSTACK_FRAMER.length(); + return TSCH_PACKET_MAX_LEN - NETSTACK_FRAMER.length(); } /*---------------------------------------------------------------------------*/ const struct mac_driver tschmac_driver = { From 16ac869645846d981f61a61d410dcd56a93e14ef Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Tue, 30 Oct 2018 16:58:45 +0100 Subject: [PATCH 11/14] removed some no longer needed hard-coded calculations in the sicslowpan code --- examples/rpl-udp/udp-client.c | 8 +++- os/net/ipv6/sicslowpan.c | 79 +++++++++++++---------------------- 2 files changed, 34 insertions(+), 53 deletions(-) diff --git a/examples/rpl-udp/udp-client.c b/examples/rpl-udp/udp-client.c index 4c27cf1db..7f24c8bac 100644 --- a/examples/rpl-udp/udp-client.c +++ b/examples/rpl-udp/udp-client.c @@ -32,9 +32,14 @@ udp_rx_callback(struct simple_udp_connection *c, const uint8_t *data, uint16_t datalen) { + LOG_INFO("Received response '%.*s' from ", datalen, (char *) data); 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"); + } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(udp_client_process, ev, data) @@ -59,8 +64,7 @@ PROCESS_THREAD(udp_client_process, ev, data) LOG_INFO("Sending request %u to ", count); LOG_INFO_6ADDR(&dest_ipaddr); LOG_INFO_("\n"); - /* avoid the risk of not fitting the '\0' in the string */ - snprintf(str, sizeof(str) - 1, "hello %d", count); + snprintf(str, sizeof(str), "hello %d", count); simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr); count++; } else { diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index e61cb3731..90ec7d2d8 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -130,24 +130,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 */ #ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR #define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR @@ -250,7 +232,7 @@ static uint16_t my_tag; #define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE #else /* 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 /* Assuming that the worst growth for uncompression is 38 bytes */ @@ -1548,8 +1530,6 @@ fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) { static uint8_t output(const linkaddr_t *localdest) { - int framer_hdrlen; - int max_payload; int frag_needed; /* The MAC address of the destination of the packet */ @@ -1588,13 +1568,23 @@ output(const linkaddr_t *localdest) /* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC */ 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; - } +#if LLSEC802154_USES_AUX_HEADER + /* copy LLSEC level */ + packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, + 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 */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 @@ -1614,31 +1604,18 @@ output(const linkaddr_t *localdest) return 0; } #endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */ -#if LLSEC802154_USES_AUX_HEADER - /* copy LLSEC level */ - packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, - 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 */ - /* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC. - * We calculate it here only to make a better decision of whether the outgoing packet - * needs to be fragmented or not. */ - packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest); - max_payload = NETSTACK_MAC.max_payload(); - if(max_payload <= 0) { - /* Framing failed, drop packet */ - LOG_WARN("output: failed to calculate payload size - dropping packet\n"); - return 0; - } - frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > max_payload; + /* Use the mac_max_payload to understand what is the max payload in a MAC + * packet. We calculate it here only to make a better decision of whether + * the outgoing packet needs to be fragmented or not. */ + + packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest); + + 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", 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 SICSLOWPAN_CONF_FRAG @@ -1658,11 +1635,11 @@ output(const linkaddr_t *localdest) /* Total IPv6 payload */ int total_payload = (uip_len - uncomp_hdr_len); /* 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 */ - 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 */ - 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 */ 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 */ From ef9b1f32ba313c62354be83a3cbab1a2e7003620 Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Fri, 2 Nov 2018 15:19:27 +0100 Subject: [PATCH 12/14] Update os/services/shell/shell-commands.c Co-Authored-By: joakimeriksson --- os/services/shell/shell-commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index 0ec04c7c4..b72003683 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -871,7 +871,7 @@ const struct shell_command_t builtin_shell_commands[] = { #endif /* TSCH_WITH_SIXTOP */ #if LLSEC802154_ENABLED { "llsec-set-level", cmd_llsec_setlv, "'> llsec-set-level ': Set the level of link layer security (show if no lv argument)"}, - { "llsec-set-key", cmd_llsec_setkey, "'> llsec-set-key ': Set the key of link layer security (show if no id key argument)"}, + { "llsec-set-key", cmd_llsec_setkey, "'> llsec-set-key ': Set the key of link layer security"}, #endif /* LLSEC802154_ENABLED */ { NULL, NULL, NULL }, }; From 93c7aae49e3466054d87aa6e45aed06da333d4b2 Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Fri, 2 Nov 2018 15:20:07 +0100 Subject: [PATCH 13/14] Update os/services/shell/shell-commands.c Co-Authored-By: joakimeriksson --- os/services/shell/shell-commands.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index b72003683..c8b7d862e 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -781,7 +781,9 @@ PT_THREAD(cmd_llsec_setkey(struct pt *pt, shell_output_func output, char *args)) #if MAC_CONF_WITH_CSMA /* Get next arg (key-string) */ SHELL_ARGS_NEXT(args, next_args); - if(args != NULL && strlen(args) == 16) { + 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 { From ecb214bb2d949b15804516da36e1c8294bb8dfee Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 2 Nov 2018 15:32:03 +0100 Subject: [PATCH 14/14] clear uipbuf including its attributes before creating a packet --- os/net/ipv6/sicslowpan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/os/net/ipv6/sicslowpan.c b/os/net/ipv6/sicslowpan.c index e2ffc24fd..d61d44baf 100644 --- a/os/net/ipv6/sicslowpan.c +++ b/os/net/ipv6/sicslowpan.c @@ -1787,6 +1787,9 @@ input(void) return; } + /* Clear uipbuf and set default attributes */ + uipbuf_clear(); + /* This is default uip_buf since we assume that this is not fragmented */ buffer = (uint8_t *)UIP_IP_BUF; @@ -1821,7 +1824,6 @@ input(void) } buffer = frag_info[frag_context].first_frag; - break; case SICSLOWPAN_DISPATCH_FRAGN: /*