From 2f28a91c4fe13ffa8b98bf3a952c9785e86d19a7 Mon Sep 17 00:00:00 2001 From: Leandro Lanzieri Date: Tue, 2 Feb 2021 09:08:44 +0100 Subject: [PATCH] net/ieee802154/security: make default cipher_ops implementations private --- sys/include/net/ieee802154_security.h | 60 ++------------- sys/net/link_layer/ieee802154/security.c | 96 ++++++++++++++++-------- 2 files changed, 72 insertions(+), 84 deletions(-) diff --git a/sys/include/net/ieee802154_security.h b/sys/include/net/ieee802154_security.h index 09c2094694..58ca1327c3 100644 --- a/sys/include/net/ieee802154_security.h +++ b/sys/include/net/ieee802154_security.h @@ -40,6 +40,12 @@ typedef struct ieee802154_sec_dev ieee802154_sec_dev_t; /** * @brief Struct of security operations + * + * @note A device can indicate that the fallback implementations should be + * used by setting the corresponding member to `NULL`, or pointing to + * @ref ieee802154_radio_cipher_ops, which does the same. Note that + * @ref ieee802154_radio_cipher_ops is the default security operations + * driver assigned when @ref ieee802154_sec_init is called. */ typedef struct ieee802154_radio_cipher_ops { /** @@ -402,7 +408,7 @@ int ieee802154_sec_encrypt_frame(ieee802154_sec_context_t *ctx, * * @param[in] ctx IEEE 802.15.4 security context * @param[in] frame_size Size of received frame - * @param[in] header Poinzter to header, which is also the frame + * @param[in] header Pointer to header, which is also the frame * @param[in, out] header_size in: Header size; out: Size of header and auxiliary header * @param[out] payload Will point to the beginning of the payload * @param[out] payload_size Pointer to store the payload size @@ -423,57 +429,7 @@ int ieee802154_sec_decrypt_frame(ieee802154_sec_context_t *ctx, const uint8_t *src_address); /** - * @brief Set the encryption key to be used for the next cipher operation - * - * This function should be the default callback operation to set the encryption key, - * if a radio does not provide special hardware security features. - * - * @param[in] dev Security device - * @param[in] key Key to be use for the next cipher operation - * @param[in] key_size Key size - */ -void ieee802154_sec_set_key(ieee802154_sec_dev_t *dev, - const uint8_t *key, uint8_t key_size); - -/** - * @brief Perform ECB block cipher for IEEE802154 security layer - * - * This function should be the default callback operation to perform ECB, - * if a radio does not provide special hardware security features. - * - * @param[in] dev Security device - * @param[out] cipher Output cipher blocks - * @param[in] plain Input plain blocks - * @param[in] nblocks Number of blocks - */ -void ieee802154_sec_ecb(const ieee802154_sec_dev_t *dev, - uint8_t *cipher, - const uint8_t *plain, - uint8_t nblocks); - -/** - * @brief Perform CBC block cipher for IEEE802154 security layer - * MIC computation - * - * This function should be the default callback operation to perform CBC, - * if a radio does not provide special hardware security features. - * - * @param[in] dev Security device - * @param[out] cipher Output cipher blocks - * @param[in] iv Initial vector - * @param[in] plain Input plain blocks - * @param[in] nblocks Number of blocks - */ -void ieee802154_sec_cbc(const ieee802154_sec_dev_t *dev, - uint8_t *cipher, - uint8_t *iv, - const uint8_t *plain, - uint8_t nblocks); - -/** - * @brief Implements @ref ieee802154_sec_set_key, - * @ref ieee802154_sec_ecb, - * @ref ieee802154_sec_cbc + * @brief Default descriptor that will fallback to default implementations */ extern const ieee802154_radio_cipher_ops_t ieee802154_radio_cipher_ops; diff --git a/sys/net/link_layer/ieee802154/security.c b/sys/net/link_layer/ieee802154/security.c index 40a0c770f6..63eedd9fc6 100644 --- a/sys/net/link_layer/ieee802154/security.c +++ b/sys/net/link_layer/ieee802154/security.c @@ -24,9 +24,9 @@ #include "net/ieee802154_security.h" const ieee802154_radio_cipher_ops_t ieee802154_radio_cipher_ops = { - .set_key = ieee802154_sec_set_key, - .ecb = ieee802154_sec_ecb, - .cbc = ieee802154_sec_cbc + .set_key = NULL, + .ecb = NULL, + .cbc = NULL }; static inline uint16_t _min(uint16_t a, uint16_t b) @@ -34,6 +34,41 @@ static inline uint16_t _min(uint16_t a, uint16_t b) return a < b ? a : b; } +/** + * @brief Perform an ECB block cipher for IEEE 802.15.4 security layer. + * + * This is the fallback implementation for the case where the security device + * does not provide an specific implementation. + * + * @param[in] dev Security device + * @param[out] cipher Output cipher blocks + * @param[in] plain Input plain blocks + * @param[in] nblocks Number of blocks + */ +static void _sec_ecb(const ieee802154_sec_dev_t *dev, + uint8_t *cipher, + const uint8_t *plain, + uint8_t nblocks); + +/** + * @brief Perform a CBC block cipher for IEEE 802.15.4 security layer MIC + * computation. + * + * This is the fallback implementation for the case where the security device + * does not provide an specific implementation. + * + * @param[in] dev Security device + * @param[out] cipher Output cipher blocks + * @param[in] iv Initial vector + * @param[in] plain Input plain blocks + * @param[in] nblocks Number of blocks + */ +static void _sec_cbc(const ieee802154_sec_dev_t *dev, + uint8_t *cipher, + uint8_t *iv, + const uint8_t *plain, + uint8_t nblocks); + /** * @brief Flag field of CCM input block * @@ -254,7 +289,12 @@ static uint8_t _ecb(ieee802154_sec_context_t *ctx, const uint8_t *Ai, uint16_t size) { uint16_t s = _min(IEEE802154_SEC_BLOCK_SIZE, size); - ctx->dev.cipher_ops->ecb(&ctx->dev, tmp2, Ai, 1); + if (ctx->dev.cipher_ops->ecb) { + ctx->dev.cipher_ops->ecb(&ctx->dev, tmp2, Ai, 1); + } + else { + _sec_ecb(&ctx->dev, tmp2, Ai, 1); + } memcpy(tmp1, data, s); memset(tmp1 + s, 0, IEEE802154_SEC_BLOCK_SIZE - s); _memxor(tmp1, tmp2, IEEE802154_SEC_BLOCK_SIZE); @@ -272,13 +312,20 @@ static uint8_t _cbc_next(ieee802154_sec_context_t *ctx, uint16_t s = _min(IEEE802154_SEC_BLOCK_SIZE, size); memcpy(tmp, next, s); memset(tmp + s, 0, IEEE802154_SEC_BLOCK_SIZE - s); - ctx->dev.cipher_ops->cbc(&ctx->dev, last, last, tmp, 1); + if (ctx->dev.cipher_ops->cbc){ + ctx->dev.cipher_ops->cbc(&ctx->dev, last, last, tmp, 1); + } + else { + _sec_cbc(&ctx->dev, last, last, tmp, 1); + } return s; } static void _set_key(ieee802154_sec_context_t *ctx, const uint8_t *key) { - ctx->dev.cipher_ops->set_key(&ctx->dev, key, IEEE802154_SEC_BLOCK_SIZE); + if (ctx->dev.cipher_ops->set_key) { + ctx->dev.cipher_ops->set_key(&ctx->dev, key, IEEE802154_SEC_BLOCK_SIZE); + } memcpy(ctx->cipher.context.context, key, IEEE802154_SEC_KEY_LENGTH); } @@ -481,39 +528,24 @@ int ieee802154_sec_decrypt_frame(ieee802154_sec_context_t *ctx, return IEEE802154_SEC_OK; } -void ieee802154_sec_set_key(ieee802154_sec_dev_t *ctx, - const uint8_t *key, uint8_t key_size) +static void _sec_ecb(const ieee802154_sec_dev_t *dev, + uint8_t *cipher, + const uint8_t *plain, + uint8_t nblocks) { - /* This is a dummy implementation of the set_key callback - in ieee802154_radio_cipher_ops_t. - The copying of the key is done in the static _set_key() function, - which wraps around the set_key callback and then copies. - For the software encryption / decryption, there is - nothing else to do, hence the NOP. For hardware support, - the key must be transferred to the transceiver. */ - (void)ctx; - (void)key; - (void)key_size; -} - -void ieee802154_sec_ecb(const ieee802154_sec_dev_t *ctx, - uint8_t *cipher, - const uint8_t *plain, - uint8_t nblocks) -{ - cipher_encrypt_ecb(&((ieee802154_sec_context_t *)ctx->ctx)->cipher, + cipher_encrypt_ecb(&((ieee802154_sec_context_t *)dev->ctx)->cipher, plain, nblocks * IEEE802154_SEC_BLOCK_SIZE, cipher); } -void ieee802154_sec_cbc(const ieee802154_sec_dev_t *ctx, - uint8_t *cipher, - uint8_t *iv, - const uint8_t *plain, - uint8_t nblocks) +static void _sec_cbc(const ieee802154_sec_dev_t *dev, + uint8_t *cipher, + uint8_t *iv, + const uint8_t *plain, + uint8_t nblocks) { - cipher_encrypt_cbc(&((ieee802154_sec_context_t *)ctx->ctx)->cipher, + cipher_encrypt_cbc(&((ieee802154_sec_context_t *)dev->ctx)->cipher, iv, plain, nblocks * IEEE802154_SEC_BLOCK_SIZE,