From 1b5bcec554565638847e3c69c46415e6f4e9f4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20H=C3=BC=C3=9Fler?= Date: Fri, 2 Oct 2020 14:48:36 +0200 Subject: [PATCH] drivers/netdev: Add IEEE 802.15.4 security --- drivers/include/net/netdev/ieee802154.h | 6 ++++ drivers/netdev/ieee802154.c | 44 ++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/drivers/include/net/netdev/ieee802154.h b/drivers/include/net/netdev/ieee802154.h index 131fa981a0..7af8c5dd90 100644 --- a/drivers/include/net/netdev/ieee802154.h +++ b/drivers/include/net/netdev/ieee802154.h @@ -22,6 +22,9 @@ #include "net/eui_provider.h" #include "net/ieee802154.h" +#if IS_USED(MODULE_IEEE802154_SECURITY) +#include "net/ieee802154_security.h" +#endif #include "net/gnrc/nettype.h" #include "net/netopt.h" #include "net/netdev.h" @@ -116,6 +119,9 @@ typedef struct { uint8_t page; /**< channel page */ uint16_t flags; /**< flags as defined above */ int16_t txpower; /**< tx power in dBm */ +#if IS_USED(MODULE_IEEE802154_SECURITY) || defined (Doxygen) + ieee802154_sec_context_t sec_ctx; /**< security context */ +#endif /** @} */ } netdev_ieee802154_t; diff --git a/drivers/netdev/ieee802154.c b/drivers/netdev/ieee802154.c index 1b9793bafc..2296ffa19f 100644 --- a/drivers/netdev/ieee802154.c +++ b/drivers/netdev/ieee802154.c @@ -45,6 +45,12 @@ void netdev_ieee802154_reset(netdev_ieee802154_t *dev) /* Initialize PAN ID and call netdev::set to propagate it */ dev->pan = CONFIG_IEEE802154_DEFAULT_PANID; dev->netdev.driver->set(&dev->netdev, NETOPT_NID, &dev->pan, sizeof(dev->pan)); + +#if IS_USED(MODULE_IEEE802154_SECURITY) + ieee802154_sec_init(&dev->sec_ctx); + const netopt_enable_t e = NETOPT_ENABLE; + netdev_ieee802154_set(dev, NETOPT_ENCRYPTION, &e, sizeof(e)); +#endif } static inline uint16_t _get_ieee802154_pdu(netdev_ieee802154_t *dev) @@ -115,6 +121,18 @@ int netdev_ieee802154_get(netdev_ieee802154_t *dev, netopt_t opt, void *value, *((uint16_t *)value) = (uint16_t)dev->chan; res = sizeof(dev->chan); break; +#if IS_USED(MODULE_IEEE802154_SECURITY) + case NETOPT_ENCRYPTION: + assert(max_len == sizeof(netopt_enable_t)); + if (dev->flags & NETDEV_IEEE802154_SECURITY_EN) { + *((netopt_enable_t *)value) = NETOPT_ENABLE; + } + else { + *((netopt_enable_t *)value) = NETOPT_DISABLE; + } + res = sizeof(netopt_enable_t); + break; +#endif /* IS_USED(MODULE_IEEE802154_SECURITY) */ case NETOPT_ACK_REQ: assert(max_len == sizeof(netopt_enable_t)); if (dev->flags & NETDEV_IEEE802154_ACK_REQ) { @@ -159,6 +177,9 @@ int netdev_ieee802154_get(netdev_ieee802154_t *dev, netopt_t opt, void *value, *((uint16_t *)value) = (_get_ieee802154_pdu(dev) - IEEE802154_MAX_HDR_LEN) +#if IS_USED(MODULE_IEEE802154_SECURITY) + -IEEE802154_MAX_AUX_HDR_LEN +#endif /* IS_USED(MODULE_IEEE802154_SECURITY) */ - IEEE802154_FCS_LEN; res = sizeof(uint16_t); break; @@ -219,6 +240,28 @@ int netdev_ieee802154_set(netdev_ieee802154_t *dev, netopt_t opt, const void *va dev->pan = *((uint16_t *)value); res = sizeof(dev->pan); break; +#if IS_USED(MODULE_IEEE802154_SECURITY) + case NETOPT_ENCRYPTION: + assert(len == sizeof(netopt_enable_t)); + if ((*(bool *)value)) { + dev->flags |= NETDEV_IEEE802154_SECURITY_EN; + } + else { + dev->flags &= ~NETDEV_IEEE802154_SECURITY_EN; + } + res = sizeof(netopt_enable_t); + break; + case NETOPT_ENCRYPTION_KEY: + assert(len >= IEEE802154_SEC_KEY_LENGTH); + if (memcmp(dev->sec_ctx.cipher.context.context, value, len)) { + /* If the key changes, the frame conter can be reset to 0*/ + dev->sec_ctx.frame_counter = 0; + } + memcpy(dev->sec_ctx.cipher.context.context, value, + IEEE802154_SEC_KEY_LENGTH); + res = IEEE802154_SEC_KEY_LENGTH; + break; +#endif /* IS_USED(MODULE_IEEE802154_SECURITY) */ case NETOPT_ACK_REQ: if ((*(bool *)value)) { dev->flags |= NETDEV_IEEE802154_ACK_REQ; @@ -283,5 +326,4 @@ int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr) return 1; } - /** @} */