From f7e16fec240439f54998463f6d8ab2945edbe5b3 Mon Sep 17 00:00:00 2001 From: Jintao Lin Date: Wed, 8 Jul 2020 04:12:50 +0800 Subject: [PATCH] [nrf528xx] add platform radio support for transmit security (#5184) --- examples/platforms/nrf528xx/src/radio.c | 157 +++++++++++++++++- .../ack_generator/nrf_802154_ack_generator.c | 2 +- .../ack_generator/nrf_802154_ack_generator.h | 2 +- .../nrf_802154_enh_ack_generator.c | 2 +- .../nrf_802154_enh_ack_generator.h | 2 +- .../nrf_802154_imm_ack_generator.c | 2 +- .../nrf_802154_imm_ack_generator.h | 2 +- .../drivers/radio/nrf_802154.c | 2 +- .../drivers/radio/nrf_802154.h | 2 +- .../drivers/radio/nrf_802154_core.c | 2 +- 10 files changed, 157 insertions(+), 18 deletions(-) diff --git a/examples/platforms/nrf528xx/src/radio.c b/examples/platforms/nrf528xx/src/radio.c index dde635134..d8612ac4d 100644 --- a/examples/platforms/nrf528xx/src/radio.c +++ b/examples/platforms/nrf528xx/src/radio.c @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c index a9730642e..54545f5d3 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.c @@ -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); diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h index 561ec80bc..059a19feb 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_ack_generator.h @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c index 998575832..c4410665a 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.c @@ -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; diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h index 15005db73..91e812d11 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_enh_ack_generator.h @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c index 748e622eb..bc2605022 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.c @@ -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]; diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h index 8504a51b4..db6be61eb 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/ack_generator/nrf_802154_imm_ack_generator.h @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c index 02d9fdbba..a2c590b8e 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c @@ -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; } diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h index b1adba48f..ad982a3ed 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h @@ -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 diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c index ea15796f7..e938f394b 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c @@ -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.