mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 16:47:47 +00:00
[key-manager] update how the "Key Switch Guard Timer" is reset (#10347)
This commit updates the resetting of the Key Switch Guard Timer. It is now reset under two conditions: - The device itself triggers a key rotation and moves to the next key sequence after the rotation time has passed since the last switch. - The device receives a MAC or MLE message with an incoming key index matching the next key index. Regarding MLE messages, this rule is applied regardless of the message being classified as Authoritative or Peer.
This commit is contained in:
committed by
Jonathan Hui
parent
185b0e18e7
commit
9c1f1f3dfb
@@ -275,7 +275,8 @@ uint32_t otThreadGetKeySequenceCounter(otInstance *aInstance)
|
||||
|
||||
void otThreadSetKeySequenceCounter(otInstance *aInstance, uint32_t aKeySequenceCounter)
|
||||
{
|
||||
AsCoreType(aInstance).Get<KeyManager>().SetCurrentKeySequence(aKeySequenceCounter, KeyManager::kForceUpdate);
|
||||
AsCoreType(aInstance).Get<KeyManager>().SetCurrentKeySequence(
|
||||
aKeySequenceCounter, KeyManager::kForceUpdate | KeyManager::kGuardTimerUnchanged);
|
||||
}
|
||||
|
||||
uint16_t otThreadGetKeySwitchGuardTime(otInstance *aInstance)
|
||||
|
||||
@@ -1641,7 +1641,7 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig
|
||||
|
||||
if (keySequence > keyManager.GetCurrentKeySequence())
|
||||
{
|
||||
keyManager.SetCurrentKeySequence(keySequence, KeyManager::kApplyKeySwitchGuard);
|
||||
keyManager.SetCurrentKeySequence(keySequence, KeyManager::kApplySwitchGuard | KeyManager::kResetGuardTimer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -368,11 +368,11 @@ void KeyManager::UpdateKeyMaterial(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence, KeySequenceUpdateMode aUpdateMode)
|
||||
void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence, KeySeqUpdateFlags aFlags)
|
||||
{
|
||||
VerifyOrExit(aKeySequence != mKeySequence, Get<Notifier>().SignalIfFirst(kEventThreadKeySeqCounterChanged));
|
||||
|
||||
if (aUpdateMode == kApplyKeySwitchGuard)
|
||||
if (aFlags & kApplySwitchGuard)
|
||||
{
|
||||
VerifyOrExit(mKeySwitchGuardTimer == 0);
|
||||
}
|
||||
@@ -384,7 +384,11 @@ void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence, KeySequenceUpdateM
|
||||
mMleFrameCounter = 0;
|
||||
|
||||
ResetKeyRotationTimer();
|
||||
mKeySwitchGuardTimer = mKeySwitchGuardTime;
|
||||
|
||||
if (aFlags & kResetGuardTimer)
|
||||
{
|
||||
mKeySwitchGuardTimer = mKeySwitchGuardTime;
|
||||
}
|
||||
|
||||
Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
|
||||
|
||||
@@ -528,7 +532,7 @@ void KeyManager::CheckForKeyRotation(void)
|
||||
{
|
||||
if (mHoursSinceKeyRotation >= mSecurityPolicy.mRotationTime)
|
||||
{
|
||||
SetCurrentKeySequence(mKeySequence + 1, kForceUpdate);
|
||||
SetCurrentKeySequence(mKeySequence + 1, kForceUpdate | kResetGuardTimer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,16 +221,24 @@ class KeyManager : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Determines whether to apply or ignore key switch guard when updating the key sequence.
|
||||
* Defines bit-flag constants specifying how to handle key sequence update used in `KeySeqUpdateFlags`.
|
||||
*
|
||||
*/
|
||||
enum KeySeqUpdateFlag : uint8_t
|
||||
{
|
||||
kApplySwitchGuard = (1 << 0), ///< Apply key switch guard check.
|
||||
kForceUpdate = (0 << 0), ///< Ignore key switch guard check and forcibly update.
|
||||
kResetGuardTimer = (1 << 1), ///< On key seq change, reset the guard timer.
|
||||
kGuardTimerUnchanged = (0 << 1), ///< On key seq change, leave guard timer unchanged.
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a combination of `KeySeqUpdateFlag` bits.
|
||||
*
|
||||
* Used as input by `SetCurrentKeySequence()`.
|
||||
*
|
||||
*/
|
||||
enum KeySequenceUpdateMode : uint8_t
|
||||
{
|
||||
kApplyKeySwitchGuard, ///< Apply key switch guard check before setting the new key sequence.
|
||||
kForceUpdate, ///< Ignore key switch guard check and forcibly update the key sequence to new value.
|
||||
};
|
||||
typedef uint8_t KeySeqUpdateFlags;
|
||||
|
||||
/**
|
||||
* Initializes the object.
|
||||
@@ -342,14 +350,12 @@ public:
|
||||
/**
|
||||
* Sets the current key sequence value.
|
||||
*
|
||||
* If @p aMode is `kApplyKeySwitchGuard`, the current key switch guard timer is checked and only if it is zero, key
|
||||
* sequence will be updated.
|
||||
*
|
||||
* @param[in] aKeySequence The key sequence value.
|
||||
* @param[in] aUpdateMode Whether or not to apply the key switch guard.
|
||||
* @param[in] aFlags Specify behavior when updating the key sequence, i.e., whether or not to apply the
|
||||
* key switch guard or reset guard timer upon change.
|
||||
*
|
||||
*/
|
||||
void SetCurrentKeySequence(uint32_t aKeySequence, KeySequenceUpdateMode aUpdateMode);
|
||||
void SetCurrentKeySequence(uint32_t aKeySequence, KeySeqUpdateFlags aFlags);
|
||||
|
||||
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
|
||||
/**
|
||||
|
||||
+24
-13
@@ -371,7 +371,8 @@ void Mle::Restore(void)
|
||||
|
||||
SuccessOrExit(Get<Settings>().Read(networkInfo));
|
||||
|
||||
Get<KeyManager>().SetCurrentKeySequence(networkInfo.GetKeySequence(), KeyManager::kForceUpdate);
|
||||
Get<KeyManager>().SetCurrentKeySequence(networkInfo.GetKeySequence(),
|
||||
KeyManager::kForceUpdate | KeyManager::kGuardTimerUnchanged);
|
||||
Get<KeyManager>().SetMleFrameCounter(networkInfo.GetMleFrameCounter());
|
||||
Get<KeyManager>().SetAllMacFrameCounters(networkInfo.GetMacFrameCounter(), /* aSetIfLarger */ false);
|
||||
|
||||
@@ -2721,33 +2722,43 @@ void Mle::ProcessKeySequence(RxInfo &aRxInfo)
|
||||
// neighbor.
|
||||
// Otherwise larger key seq MUST NOT be adopted.
|
||||
|
||||
bool isNextKeySeq;
|
||||
KeyManager::KeySeqUpdateFlags flags = 0;
|
||||
|
||||
VerifyOrExit(aRxInfo.mKeySequence > Get<KeyManager>().GetCurrentKeySequence());
|
||||
|
||||
isNextKeySeq = (aRxInfo.mKeySequence - Get<KeyManager>().GetCurrentKeySequence() == 1);
|
||||
|
||||
switch (aRxInfo.mClass)
|
||||
{
|
||||
case RxInfo::kAuthoritativeMessage:
|
||||
Get<KeyManager>().SetCurrentKeySequence(aRxInfo.mKeySequence, KeyManager::kForceUpdate);
|
||||
flags = KeyManager::kForceUpdate;
|
||||
break;
|
||||
|
||||
case RxInfo::kPeerMessage:
|
||||
if ((aRxInfo.mNeighbor != nullptr) && aRxInfo.mNeighbor->IsStateValid())
|
||||
VerifyOrExit(aRxInfo.IsNeighborStateValid());
|
||||
|
||||
if (!isNextKeySeq)
|
||||
{
|
||||
if (aRxInfo.mKeySequence - Get<KeyManager>().GetCurrentKeySequence() == 1)
|
||||
{
|
||||
Get<KeyManager>().SetCurrentKeySequence(aRxInfo.mKeySequence, KeyManager::kApplyKeySwitchGuard);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogInfo("Large key seq jump in peer class msg from 0x%04x ", aRxInfo.mNeighbor->GetRloc16());
|
||||
ReestablishLinkWithNeighbor(*aRxInfo.mNeighbor);
|
||||
}
|
||||
LogInfo("Large key seq jump in peer class msg from 0x%04x ", aRxInfo.mNeighbor->GetRloc16());
|
||||
ReestablishLinkWithNeighbor(*aRxInfo.mNeighbor);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
flags = KeyManager::kApplySwitchGuard;
|
||||
break;
|
||||
|
||||
case RxInfo::kUnknown:
|
||||
break;
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
if (isNextKeySeq)
|
||||
{
|
||||
flags |= KeyManager::kResetGuardTimer;
|
||||
}
|
||||
|
||||
Get<KeyManager>().SetCurrentKeySequence(aRxInfo.mKeySequence, flags);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user