drivers/at86rf2xx: Use hardware security for IEEE 802.15.4 security

This commit is contained in:
Fabian Hüßler 2020-10-02 19:39:43 +02:00
parent 1b5bcec554
commit f074e8a635
2 changed files with 106 additions and 0 deletions

View File

@ -28,14 +28,91 @@
#include "luid.h" #include "luid.h"
#include "byteorder.h" #include "byteorder.h"
#include "net/ieee802154.h" #include "net/ieee802154.h"
#if IS_USED(IEEE802154_SECURITY)
#include "net/ieee802154_security.h"
#endif
#include "net/gnrc.h" #include "net/gnrc.h"
#include "at86rf2xx_registers.h" #include "at86rf2xx_registers.h"
#include "at86rf2xx_internal.h" #include "at86rf2xx_internal.h"
#include "at86rf2xx_netdev.h" #include "at86rf2xx_netdev.h"
#if IS_USED(MODULE_AT86RF2XX_AES_SPI)
#include "at86rf2xx_aes.h"
#endif
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
#include "debug.h" #include "debug.h"
#if IS_USED(MODULE_AT86RF2XX_AES_SPI) && \
IS_USED(MODULE_IEEE802154_SECURITY)
/**
* @brief Pass the 802.15.4 encryption key to the transceiver hardware
*
* @param[in] dev Abstract security device descriptor
* @param[in] key Encryption key to be used
* @param[in] key_size Size of the encryption key in bytes
*/
static void _at86rf2xx_set_key(ieee802154_sec_dev_t *dev,
const uint8_t *key, uint8_t key_size)
{
(void)key_size;
at86rf2xx_aes_key_write_encrypt((at86rf2xx_t *)dev->ctx, key);
}
/**
* @brief Compute CBC-MAC from IEEE 802.15.4 security context
*
* @param[in] dev Abstract security device descriptor
* @param[out] cipher Buffer to store cipher blocks
* @param[in] iv Initial vector
* @param[in] plain Input data blocks
* @param[in] nblocks Number of blocks
*/
static void _at86rf2xx_cbc(const ieee802154_sec_dev_t *dev,
uint8_t *cipher,
uint8_t *iv,
const uint8_t *plain,
uint8_t nblocks)
{
at86rf2xx_aes_cbc_encrypt((at86rf2xx_t *)dev->ctx,
(aes_block_t *)cipher,
NULL,
iv,
(aes_block_t *)plain,
nblocks);
}
/**
* @brief Perform ECB encryption
*
* @param[in] dev Abstract security device descriptor
* @param[out] cipher Output cipher blocks
* @param[in] plain Plain blocks
* @param[in] nblocks Number of blocks
*/
static void _at86rf2xx_ecb(const ieee802154_sec_dev_t *dev,
uint8_t *cipher,
const uint8_t *plain,
uint8_t nblocks)
{
at86rf2xx_aes_ecb_encrypt((at86rf2xx_t *)dev->ctx,
(aes_block_t *)cipher,
NULL,
(aes_block_t *)plain,
nblocks);
}
/**
* @brief Struct that contains IEEE 802.15.4 security operations
* which are implemented, using the transceiver´s hardware
* crypto capabilities
*/
static const ieee802154_radio_cipher_ops_t _at86rf2xx_cipher_ops = {
.set_key = _at86rf2xx_set_key,
.ecb = _at86rf2xx_ecb,
.cbc = _at86rf2xx_cbc
};
#endif /* IS_USED(MODULE_AT86RF2XX_COMMON_AES_SPI) && \
IS_USED(MODULE_IEEE802154_SECURITY) */
void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params, uint8_t index) void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params, uint8_t index)
{ {
@ -152,6 +229,16 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
/* clear interrupt flags */ /* clear interrupt flags */
at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS); at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
#if IS_USED(MODULE_IEEE802154_SECURITY) && \
IS_USED(MODULE_AT86RF2XX_AES_SPI)
dev->netdev.sec_ctx.dev.cipher_ops = &_at86rf2xx_cipher_ops;
dev->netdev.sec_ctx.dev.ctx = dev;
/* All configurations of the security module, the SRAM content,
and keys are reset during DEEP_SLEEP or RESET state. */
at86rf2xx_aes_key_write_encrypt(dev,
dev->netdev.sec_ctx.cipher.context.context);
#endif
/* State to return after receiving or transmitting */ /* State to return after receiving or transmitting */
dev->idle_state = AT86RF2XX_PHY_STATE_RX; dev->idle_state = AT86RF2XX_PHY_STATE_RX;
/* go into RX state */ /* go into RX state */

View File

@ -39,6 +39,9 @@
#include "at86rf2xx_netdev.h" #include "at86rf2xx_netdev.h"
#include "at86rf2xx_internal.h" #include "at86rf2xx_internal.h"
#include "at86rf2xx_registers.h" #include "at86rf2xx_registers.h"
#if IS_USED(MODULE_AT86RF2XX_AES_SPI)
#include "at86rf2xx_aes.h"
#endif
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
#include "debug.h" #include "debug.h"
@ -665,6 +668,22 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ #endif /* MODULE_NETDEV_IEEE802154_OQPSK */
#if IS_USED(MODULE_AT86RF2XX_COMMON_AES_SPI) && \
IS_USED(MODULE_IEEE802154_SECURITY)
case NETOPT_ENCRYPTION_KEY:
assert(len >= IEEE802154_SEC_KEY_LENGTH);
at86rf2xx_aes_key_write_encrypt(dev, val);
if (memcmp(dev->netdev.sec_ctx.cipher.context.context, val, len)) {
/* If the key changes, the frame conter can be reset to 0*/
dev->netdev.sec_ctx.frame_counter = 0;
}
memcpy(dev->netdev.sec_ctx.cipher.context.context, val,
IEEE802154_SEC_KEY_LENGTH);
res = IEEE802154_SEC_KEY_LENGTH;
break;
#endif /* IS_USED(MODULE_AT86RF2XX_AES_SPI) && \
IS_USED(MODULE_IEEE802154_SECURITY) */
default: default:
break; break;
} }