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,