net/ieee802154/security: make default cipher_ops implementations private

This commit is contained in:
Leandro Lanzieri 2021-02-02 09:08:44 +01:00
parent e31daf1583
commit 2f28a91c4f
No known key found for this signature in database
GPG Key ID: F4E9A721761C7593
2 changed files with 72 additions and 84 deletions

View File

@ -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;

View File

@ -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);
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);
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)
{
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)
{
/* 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,
static void _sec_ecb(const ieee802154_sec_dev_t *dev,
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,
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,