mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[key-manager] clarify otPlatRadioSetMacKey() and add counter safeguard (#11201)
This commit clarifies the intended behavior of the radio platform API `otPlatRadioSetMacKey()` by recommending that implementations also clear the MAC frame counter value (tracked by the radio). It also adds a safeguard for this in `KeyManager` by changing the order of operations. The MAC frame counter is now reset before updating the key sequence and MAC keys. A comment explains the rationale behind this ordering. This is to avoid potential issue where a large counter value may be used with the new MAC key which could then hinder frame transmission for a long duration.
This commit is contained in:
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (473)
|
||||
#define OPENTHREAD_API_VERSION (474)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -702,6 +702,10 @@ void otPlatRadioSetRxOnWhenIdle(otInstance *aInstance, bool aEnable);
|
||||
*
|
||||
* Is used when radio provides OT_RADIO_CAPS_TRANSMIT_SEC capability.
|
||||
*
|
||||
* The radio platform should reset the current security MAC frame counter tracked by the radio on this call. While this
|
||||
* is highly recommended, the OpenThread stack, as a safeguard, will also reset the frame counter using the
|
||||
* `otPlatRadioSetMacFrameCounter()` before calling this API.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aKeyIdMode The key ID mode.
|
||||
* @param[in] aKeyId Current MAC key index.
|
||||
|
||||
@@ -371,12 +371,37 @@ void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence, KeySeqUpdateFlags
|
||||
VerifyOrExit(mKeySwitchGuardTimer == 0);
|
||||
}
|
||||
|
||||
mKeySequence = aKeySequence;
|
||||
UpdateKeyMaterial();
|
||||
// MAC frame counters are reset before updating keys. This order
|
||||
// safeguards against issues that can arise when the radio
|
||||
// platform handles TX security and counter assignment. The
|
||||
// radio platform might prepare an enhanced ACK to a received
|
||||
// frame from an parallel (e.g., ISR) context, which consumes
|
||||
// a MAC frame counter value.
|
||||
//
|
||||
// Ideally, a call to `otPlatRadioSetMacKey()`, which sets the MAC
|
||||
// keys on the radio, should also reset the frame counter tracked
|
||||
// by the radio. However, if this is not implemented by the radio
|
||||
// platform, resetting the counter first ensures new keys always
|
||||
// start with a zero counter and avoids potential issue below.
|
||||
//
|
||||
// If the MAC key is updated before the frame counter is cleared,
|
||||
// the radio could receive and send an enhanced ACK between these
|
||||
// two actions, possibly using the new MAC key with a larger
|
||||
// (current) frame counter value. This could then prevent the
|
||||
// receiver from accepting subsequent transmissions after the
|
||||
// frame counter reset for a long time.
|
||||
//
|
||||
// While resetting counters first might briefly cause an enhanced
|
||||
// ACK to be sent with the old key and a zero counter (which might
|
||||
// be rejected by the receiver), this is a transient issue that
|
||||
// quickly resolves itself.
|
||||
|
||||
SetAllMacFrameCounters(0, /* aSetIfLarger */ false);
|
||||
mMleFrameCounter = 0;
|
||||
|
||||
mKeySequence = aKeySequence;
|
||||
UpdateKeyMaterial();
|
||||
|
||||
ResetKeyRotationTimer();
|
||||
|
||||
if (aFlags & kResetGuardTimer)
|
||||
|
||||
Reference in New Issue
Block a user