[nrf528xx] add platform radio support for transmit security (#5184)

This commit is contained in:
Jintao Lin
2020-07-07 13:12:50 -07:00
committed by GitHub
parent 9f0df30493
commit f7e16fec24
10 changed files with 157 additions and 18 deletions
+148 -9
View File
@@ -66,10 +66,12 @@
#define SHORT_ADDRESS_SIZE 2 ///< Size of MAC short address.
#define US_PER_MS 1000ULL ///< Microseconds in millisecond.
#define ACK_REQUEST_OFFSET 1 ///< Byte containing Ack request bit (+1 for frame length byte).
#define ACK_REQUEST_BIT (1 << 5) ///< Ack request bit.
#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte).
#define FRAME_PENDING_BIT (1 << 4) ///< Frame Pending bit.
#define ACK_REQUEST_OFFSET 1 ///< Byte containing Ack request bit (+1 for frame length byte).
#define ACK_REQUEST_BIT (1 << 5) ///< Ack request bit.
#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte).
#define FRAME_PENDING_BIT (1 << 4) ///< Frame Pending bit.
#define SECURITY_ENABLED_OFFSET 1 ///< Byte containing security enabled bit (+1 for frame length byte).
#define SECURITY_ENABLED_BIT (1 << 3) ///< Security enabled bit.
#define RSSI_SETTLE_TIME_US 40 ///< RSSI settle time in microseconds.
@@ -120,6 +122,17 @@ typedef enum
static uint32_t sPendingEvents;
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
static uint32_t sMacFrameCounter;
static uint8_t sKeyId;
static struct otMacKey sPrevKey;
static struct otMacKey sCurrKey;
static struct otMacKey sNextKey;
static bool sAckedWithSecEnhAck;
static uint32_t sAckFrameCounter;
static uint8_t sAckKeyId;
#endif
static void dataInit(void)
{
sDisabled = true;
@@ -191,6 +204,57 @@ static inline void clearPendingEvents(void)
} while (__STREXW(pendingEvents, (uint32_t *)&sPendingEvents));
}
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
static void txAckProcessSecurity(uint8_t *aAckFrame)
{
otRadioFrame ackFrame;
struct otMacKey *key = NULL;
uint8_t keyId;
sAckedWithSecEnhAck = false;
otEXPECT(aAckFrame[SECURITY_ENABLED_OFFSET] & SECURITY_ENABLED_BIT);
memset(&ackFrame, 0, sizeof(ackFrame));
ackFrame.mPsdu = &aAckFrame[1];
ackFrame.mLength = aAckFrame[0];
keyId = otMacFrameGetKeyId(&ackFrame);
otEXPECT(otMacFrameIsKeyIdMode1(&ackFrame) && keyId != 0);
if (keyId == sKeyId)
{
key = &sCurrKey;
}
else if (keyId == sKeyId - 1)
{
key = &sPrevKey;
}
else if (keyId == sKeyId + 1)
{
key = &sNextKey;
}
else
{
otEXPECT(false);
}
sAckFrameCounter = sMacFrameCounter;
sAckKeyId = keyId;
sAckedWithSecEnhAck = true;
ackFrame.mInfo.mTxInfo.mAesKey = key;
otMacFrameSetKeyId(&ackFrame, keyId);
otMacFrameSetFrameCounter(&ackFrame, sMacFrameCounter++);
otMacFrameProcessTransmitAesCcm(&ackFrame, &sExtAddress);
exit:
return;
}
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
#if !OPENTHREAD_CONFIG_ENABLE_PLATFORM_EUI64_CUSTOM_SOURCE
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
@@ -429,6 +493,9 @@ otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
OT_UNUSED_VARIABLE(aInstance);
return (otRadioCaps)(OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF |
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
OT_RADIO_CAPS_TRANSMIT_SEC |
#endif
OT_RADIO_CAPS_SLEEP_TO_TX);
}
@@ -824,6 +891,18 @@ void nrf_802154_received_timestamp_raw(uint8_t *p_data, int8_t power, uint8_t lq
sAckedWithFramePending = false;
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
// Inform if this frame was acknowledged with secured Enh-ACK.
if (p_data[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT && otMacFrameIsVersion2015(receivedFrame))
{
receivedFrame->mInfo.mRxInfo.mAckedWithSecEnhAck = sAckedWithSecEnhAck;
receivedFrame->mInfo.mRxInfo.mAckFrameCounter = sAckFrameCounter;
receivedFrame->mInfo.mRxInfo.mAckKeyId = sAckKeyId;
}
sAckedWithSecEnhAck = false;
#endif
otSysEventSignalPending();
}
@@ -857,14 +936,22 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error)
}
sAckedWithFramePending = false;
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
sAckedWithSecEnhAck = false;
#endif
setPendingEvent(kPendingEventReceiveFailed);
}
void nrf_802154_tx_ack_started(const uint8_t *p_data)
void nrf_802154_tx_ack_started(uint8_t *p_data)
{
// Check if the frame pending bit is set in ACK frame.
sAckedWithFramePending = p_data[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT;
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
// Update IE and secure Enh-ACK.
txAckProcessSecurity(p_data);
#endif
}
void nrf_802154_transmitted_raw(const uint8_t *aFrame, uint8_t *aAckPsdu, int8_t aPower, uint8_t aLqi)
@@ -928,9 +1015,10 @@ int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
void nrf_802154_tx_started(const uint8_t *aFrame)
{
bool notifyFrameUpdated = false;
bool processSecurity = false;
assert(aFrame == sTransmitPsdu);
// Update IE and secure transmit frame
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0)
{
@@ -946,14 +1034,30 @@ void nrf_802154_tx_started(const uint8_t *aFrame)
*(++timeIe) = (uint8_t)(time & 0xff);
}
notifyFrameUpdated = true;
processSecurity = true;
}
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (notifyFrameUpdated)
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
otEXPECT(otMacFrameIsSecurityEnabled(&sTransmitFrame) && otMacFrameIsKeyIdMode1(&sTransmitFrame) &&
!sTransmitFrame.mInfo.mTxInfo.mIsSecurityProcessed);
sTransmitFrame.mInfo.mTxInfo.mAesKey = &sCurrKey;
if (!sTransmitFrame.mInfo.mTxInfo.mIsARetx)
{
otMacFrameProcessTransmitAesCcm(&sTransmitFrame, &sExtAddress);
otMacFrameSetKeyId(&sTransmitFrame, sKeyId);
otMacFrameSetFrameCounter(&sTransmitFrame, sMacFrameCounter++);
}
processSecurity = true;
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
otEXPECT(processSecurity);
otMacFrameProcessTransmitAesCcm(&sTransmitFrame, &sExtAddress);
exit:
return;
}
#endif
@@ -971,3 +1075,38 @@ uint32_t nrf_802154_random_get(void)
{
return otRandomNonCryptoGetUint32();
}
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKey *aPrevKey,
const otMacKey *aCurrKey,
const otMacKey *aNextKey)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aKeyIdMode);
assert(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);
CRITICAL_REGION_ENTER();
sKeyId = aKeyId;
memcpy(sPrevKey.m8, aPrevKey->m8, OT_MAC_KEY_SIZE);
memcpy(sCurrKey.m8, aCurrKey->m8, OT_MAC_KEY_SIZE);
memcpy(sNextKey.m8, aNextKey->m8, OT_MAC_KEY_SIZE);
CRITICAL_REGION_EXIT();
}
void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
{
OT_UNUSED_VARIABLE(aInstance);
CRITICAL_REGION_ENTER();
sMacFrameCounter = aMacFrameCounter;
CRITICAL_REGION_EXIT();
}
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
@@ -73,7 +73,7 @@ void nrf_802154_ack_generator_init(void)
nrf_802154_enh_ack_generator_init();
}
const uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame)
uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame)
{
// This function should not be called if ACK is not requested.
assert(p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT);
@@ -49,6 +49,6 @@ void nrf_802154_ack_generator_init(void);
* @returns Either pointer to a constant buffer that contains PHR and PSDU
* of the created ACK frame, or NULL in case of an invalid frame.
*/
const uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame);
uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame);
#endif // NRF_802154_ACK_GENERATOR_H
@@ -334,7 +334,7 @@ void nrf_802154_enh_ack_generator_init(void)
// Intentionally empty.
}
const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame)
uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame)
{
nrf_802154_frame_parser_mhr_data_t frame_offsets;
@@ -53,6 +53,6 @@ void nrf_802154_enh_ack_generator_init(void);
* @returns Pointer to a constant buffer that contains PHR and PSDU
* of the created Enhanced ACK frame.
*/
const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame);
uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame);
#endif // NRF_802154_ENH_ACK_GENERATOR_H
@@ -53,7 +53,7 @@ void nrf_802154_imm_ack_generator_init(void)
memcpy(m_ack_data, ack_data, sizeof(ack_data));
}
const uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame)
uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame)
{
// Set valid sequence number in ACK frame.
m_ack_data[DSN_OFFSET] = p_frame[DSN_OFFSET];
@@ -53,6 +53,6 @@ void nrf_802154_imm_ack_generator_init(void);
* @returns Pointer to a constant buffer that contains PHR and PSDU of the created
* Immediate ACK frame.
*/
const uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame);
uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame);
#endif // NRF_802154_IMM_ACK_GENERATOR_H
+1 -1
View File
@@ -697,7 +697,7 @@ void nrf_802154_ack_timeout_set(uint32_t time)
#endif // NRF_802154_ACK_TIMEOUT_ENABLED
__WEAK void nrf_802154_tx_ack_started(const uint8_t * p_data)
__WEAK void nrf_802154_tx_ack_started(uint8_t * p_data)
{
(void)p_data;
}
+1 -1
View File
@@ -537,7 +537,7 @@ bool nrf_802154_continuous_carrier(void);
*
* @param[in] p_data Pointer to a buffer with PHR and PSDU of the ACK frame.
*/
extern void nrf_802154_tx_ack_started(const uint8_t * p_data);
extern void nrf_802154_tx_ack_started(uint8_t * p_data);
#if NRF_802154_USE_RAW_API
@@ -165,7 +165,7 @@ static rx_buffer_t * const mp_current_rx_buffer = &nrf_802154_rx_buffers[0];
#endif
static const uint8_t * mp_ack; ///< Pointer to Ack frame buffer.
static uint8_t * mp_ack; ///< Pointer to Ack frame buffer.
static const uint8_t * mp_tx_data; ///< Pointer to the data to transmit.
static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us].
static uint8_t m_ed_result; ///< Result of the current energy detection procedure.