[simulation] support transmit security at simulation radio (#5118)

This commit adds transmit security support for simulation radio so
that security Enh-ACK could be handled at radio layer. This commit
also fixes issue #5041.
This commit is contained in:
Jintao Lin
2020-06-22 12:23:16 -07:00
committed by GitHub
parent 4e1a3bf670
commit 5c722a770c
4 changed files with 213 additions and 17 deletions
+110 -14
View File
@@ -117,7 +117,18 @@ static bool sSrcMatchEnabled = false;
static bool sRadioCoexEnabled = true;
#endif
otRadioCaps gRadioCaps = OT_RADIO_CAPS_NONE;
otRadioCaps gRadioCaps =
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
OT_RADIO_CAPS_TRANSMIT_SEC;
#else
OT_RADIO_CAPS_NONE;
#endif
static uint32_t sMacFrameCounter;
static uint8_t sKeyId;
static struct otMacKey sPrevKey;
static struct otMacKey sCurrKey;
static struct otMacKey sNextKey;
static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
{
@@ -543,12 +554,66 @@ static void radioComputeCrc(struct RadioMessage *aMessage, uint16_t aLength)
aMessage->mPsdu[crc_offset + 1] = crc >> 8;
}
static otError radioProcessTransmitSecurity(otRadioFrame *aFrame)
{
otError error = OT_ERROR_NONE;
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
struct otMacKey *key = NULL;
uint8_t keyId;
otEXPECT(otMacFrameIsSecurityEnabled(aFrame) && otMacFrameIsKeyIdMode1(aFrame) &&
!aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
if (otMacFrameIsAck(aFrame))
{
keyId = otMacFrameGetKeyId(aFrame);
otEXPECT_ACTION(keyId != 0, error = OT_ERROR_FAILED);
if (keyId == sKeyId)
{
key = &sCurrKey;
}
else if (keyId == sKeyId - 1)
{
key = &sPrevKey;
}
else if (keyId == sKeyId + 1)
{
key = &sNextKey;
}
else
{
error = OT_ERROR_SECURITY;
otEXPECT(false);
}
}
else
{
key = &sCurrKey;
keyId = sKeyId;
}
aFrame->mInfo.mTxInfo.mAesKey = key;
if (!aFrame->mInfo.mTxInfo.mIsARetx)
{
otMacFrameSetKeyId(aFrame, keyId);
otMacFrameSetFrameCounter(aFrame, sMacFrameCounter++);
}
#else
otEXPECT(!aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
otMacFrameProcessTransmitAesCcm(aFrame, &sExtAddress);
exit:
return error;
}
void radioSendMessage(otInstance *aInstance)
{
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
bool notifyFrameUpdated = false;
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0)
{
uint8_t *timeIe = sTransmitFrame.mPsdu + sTransmitFrame.mInfo.mTxInfo.mIeInfo->mTimeIeOffset;
@@ -562,19 +627,12 @@ void radioSendMessage(otInstance *aInstance)
time = time >> 8;
*(++timeIe) = (uint8_t)(time & 0xff);
}
notifyFrameUpdated = true;
}
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
if (notifyFrameUpdated)
{
otMacFrameProcessTransmitAesCcm(&sTransmitFrame, &sExtAddress);
}
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
#endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
sTransmitMessage.mChannel = sTransmitFrame.mChannel;
otEXPECT(radioProcessTransmitSecurity(&sTransmitFrame) == OT_ERROR_NONE);
otPlatRadioTxStarted(aInstance, &sTransmitFrame);
radioComputeCrc(&sTransmitMessage, sTransmitFrame.mLength);
radioTransmit(&sTransmitMessage, &sTransmitFrame);
@@ -602,6 +660,8 @@ void radioSendMessage(otInstance *aInstance)
// Wait for echo radio in virtual time mode.
sTxWait = true;
#endif // OPENTHREAD_SIMULATION_VIRTUAL_TIME
exit:
return;
}
bool platformRadioIsTransmitPending(void)
@@ -754,6 +814,7 @@ void radioSendAck(void)
{
otEXPECT(otMacFrameGenerateEnhAck(&sReceiveFrame, sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending, NULL, 0,
&sAckFrame) == OT_ERROR_NONE);
otEXPECT(radioProcessTransmitSecurity(&sAckFrame) == OT_ERROR_NONE);
}
else
#endif
@@ -791,6 +852,13 @@ void radioProcessFrame(otInstance *aInstance)
if (otMacFrameIsAckRequested(&sReceiveFrame))
{
radioSendAck();
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
if (otMacFrameIsSecurityEnabled(&sAckFrame))
{
sReceiveFrame.mInfo.mRxInfo.mAckedWithSecEnhAck = true;
sReceiveFrame.mInfo.mRxInfo.mAckFrameCounter = otMacFrameGetFrameCounter(&sAckFrame);
}
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
}
exit:
@@ -947,3 +1015,31 @@ exit:
return error;
}
#endif
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);
otEXPECT(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);
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);
exit:
return;
}
void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
{
OT_UNUSED_VARIABLE(aInstance);
sMacFrameCounter = aMacFrameCounter;
}
+43
View File
@@ -159,3 +159,46 @@ void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCsl
static_cast<Mac::Frame *>(aFrame)->SetCslIe(aCslPeriod, aCslPhase);
}
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame)
{
return static_cast<const Mac::Frame *>(aFrame)->GetSecurityEnabled();
}
bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame)
{
uint8_t keyIdMode;
otError error;
error = static_cast<const Mac::Frame *>(aFrame)->GetKeyIdMode(keyIdMode);
return (error == OT_ERROR_NONE) ? (keyIdMode == Mac::Frame::kKeyIdMode1) : false;
}
uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame)
{
uint8_t keyId = 0;
IgnoreError(static_cast<const Mac::Frame *>(aFrame)->GetKeyId(keyId));
return keyId;
}
void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId)
{
static_cast<Mac::Frame *>(aFrame)->SetKeyId(aKeyId);
}
uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame)
{
uint32_t frameCounter = UINT32_MAX;
IgnoreError(static_cast<Mac::Frame *>(aFrame)->GetFrameCounter(frameCounter));
return frameCounter;
}
void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter)
{
static_cast<Mac::Frame *>(aFrame)->SetFrameCounter(aFrameCounter);
}
+60
View File
@@ -211,6 +211,66 @@ otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame,
*/
void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase);
/**
* Tell if the security of @p aFrame is enabled.
*
* @param[in] aFrame A pointer to the frame.
*
* @retval true The frame has security enabled.
* @retval false The frame does not have security enabled.
*
*/
bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame);
/**
* Tell if the key ID mode of @p aFrame is 1.
*
* @param[in] aFrame A pointer to the frame.
*
* @retval true The frame key ID mode is 1.
* @retval false The frame security is not enabled or key ID mode is not 1.
*
*/
bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame);
/**
* Get the key ID of @p aFrame.
*
* @param[in] aFrame A pointer to the frame.
*
* @returns The key ID of the frame with key ID mode 1. Returns 0 if failed.
*
*/
uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame);
/**
* Set key ID to @p aFrame with key ID mode 1.
*
* @param[inout] aFrame A pointer to the frame to be modified.
* @param[in] aKeyId Key ID to be set to the frame.
*
*/
void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId);
/**
* Get the frame counter of @p aFrame.
*
* @param[in] aFrame A pointer to the frame.
*
* @returns The frame counter of the frame. Returns UINT32_MAX if failed.
*
*/
uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame);
/**
* Set frame counter to @p aFrame.
*
* @param[inout] aFrame A pointer to the frame to be modified.
* @param[in] aFrameCounter Frame counter to be set to the frame.
*
*/
void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter);
#ifdef __cplusplus
} // extern "C"
#endif
-3
View File
@@ -1092,7 +1092,6 @@ otError TxFrame::GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, con
PanId panId;
uint8_t footerLength;
uint8_t securityControlField;
uint32_t frameCounter;
uint8_t keyId;
mChannel = aFrame.mChannel;
@@ -1170,11 +1169,9 @@ otError TxFrame::GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, con
if (aFrame.GetSecurityEnabled())
{
SuccessOrExit(error = aFrame.GetSecurityControlField(securityControlField));
SuccessOrExit(error = aFrame.GetFrameCounter(frameCounter));
SuccessOrExit(error = aFrame.GetKeyId(keyId));
SetSecurityControlField(securityControlField);
SetFrameCounter(frameCounter);
SetKeyId(keyId);
}