mirror of
https://github.com/espressif/openthread.git
synced 2026-08-30 05:49:54 +00:00
@@ -233,6 +233,22 @@ public:
|
||||
*/
|
||||
static uint32_t MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; }
|
||||
|
||||
/**
|
||||
* This static method returns the number of milliseconds given hours.
|
||||
*
|
||||
* @returns The number of milliseconds.
|
||||
*
|
||||
*/
|
||||
static uint32_t HoursToMsec(uint32_t aHours) { return SecToMsec(aHours * 3600u); }
|
||||
|
||||
/**
|
||||
* This static method returns the number of hours given milliseconds.
|
||||
*
|
||||
* @returns The number of hours.
|
||||
*
|
||||
*/
|
||||
static uint32_t MsecToHours(uint32_t aMilliseconds) { return MsecToSec(aMilliseconds / 3600u); }
|
||||
|
||||
private:
|
||||
void Fired(void) { mHandler(mContext); }
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <common/code_utils.hpp>
|
||||
#include <common/timer.hpp>
|
||||
#include <crypto/hmac_sha256.hpp>
|
||||
#include <thread/key_manager.hpp>
|
||||
#include <thread/mle_router.hpp>
|
||||
@@ -45,12 +46,28 @@ static const uint8_t kThreadString[] =
|
||||
};
|
||||
|
||||
KeyManager::KeyManager(ThreadNetif &aThreadNetif):
|
||||
mNetif(aThreadNetif)
|
||||
mNetif(aThreadNetif),
|
||||
mKeyRotationTimer(aThreadNetif.GetIp6().mTimerScheduler, &KeyManager::HandleKeyRotationTimer, this)
|
||||
{
|
||||
mMasterKeyLength = 0;
|
||||
mKeySequence = 0;
|
||||
mMacFrameCounter = 0;
|
||||
mMleFrameCounter = 0;
|
||||
|
||||
mKeyRotationTime = kDefaultKeyRotationTime;
|
||||
mKeySwitchGuardTime = kDefaultKeySwitchGuardTime;
|
||||
mKeySwitchGuardEnabled = false;
|
||||
}
|
||||
|
||||
void KeyManager::Start(void)
|
||||
{
|
||||
mKeySwitchGuardEnabled = false;
|
||||
mKeyRotationTimer.Start(Timer::HoursToMsec(mKeyRotationTime));
|
||||
}
|
||||
|
||||
void KeyManager::Stop(void)
|
||||
{
|
||||
mKeyRotationTimer.Stop();
|
||||
}
|
||||
|
||||
const uint8_t *KeyManager::GetMasterKey(uint8_t *aKeyLength) const
|
||||
@@ -107,16 +124,57 @@ uint32_t KeyManager::GetCurrentKeySequence(void) const
|
||||
|
||||
void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence)
|
||||
{
|
||||
if (aKeySequence != mKeySequence)
|
||||
uint32_t now;
|
||||
uint32_t guardStartTimestamp;
|
||||
uint32_t guardEndTimestamp;
|
||||
|
||||
if (aKeySequence == mKeySequence)
|
||||
{
|
||||
mKeySequence = aKeySequence;
|
||||
ComputeKey(mKeySequence, mKey);
|
||||
|
||||
mMacFrameCounter = 0;
|
||||
mMleFrameCounter = 0;
|
||||
|
||||
mNetif.SetStateChangedFlags(OT_NET_KEY_SEQUENCE);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
// Check if the guard timer has expired if key rotation is requested.
|
||||
if ((aKeySequence == (mKeySequence + 1)) &&
|
||||
mKeyRotationTimer.IsRunning() &&
|
||||
mKeySwitchGuardEnabled)
|
||||
{
|
||||
now = Timer::GetNow();
|
||||
guardStartTimestamp = mKeyRotationTimer.Gett0();
|
||||
guardEndTimestamp = guardStartTimestamp + Timer::HoursToMsec(mKeySwitchGuardTime);
|
||||
|
||||
// Check for timer overflow
|
||||
if (guardEndTimestamp < mKeyRotationTimer.Gett0())
|
||||
{
|
||||
if ((now > guardStartTimestamp) || (now < guardEndTimestamp))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((now > guardStartTimestamp) && (now < guardEndTimestamp))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mKeySequence = aKeySequence;
|
||||
ComputeKey(mKeySequence, mKey);
|
||||
|
||||
mMacFrameCounter = 0;
|
||||
mMleFrameCounter = 0;
|
||||
|
||||
if (mKeyRotationTimer.IsRunning())
|
||||
{
|
||||
mKeySwitchGuardEnabled = true;
|
||||
mKeyRotationTimer.Start(Timer::HoursToMsec(mKeyRotationTime));
|
||||
}
|
||||
|
||||
mNetif.SetStateChangedFlags(OT_NET_KEY_SEQUENCE);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t *KeyManager::GetCurrentMacKey(void) const
|
||||
@@ -182,4 +240,27 @@ void KeyManager::IncrementKekFrameCounter(void)
|
||||
mKekFrameCounter++;
|
||||
}
|
||||
|
||||
ThreadError KeyManager::SetKeyRotation(uint32_t aKeyRotation)
|
||||
{
|
||||
ThreadError result = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aKeyRotation >= static_cast<uint32_t>(kMinKeyRotationTime), result = kThreadError_InvalidArgs);
|
||||
VerifyOrExit(aKeyRotation <= static_cast<uint32_t>(kMaxKeyRotationTime), result = kThreadError_InvalidArgs);
|
||||
|
||||
mKeyRotationTime = aKeyRotation;
|
||||
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
void KeyManager::HandleKeyRotationTimer(void *aContext)
|
||||
{
|
||||
static_cast<KeyManager *>(aContext)->HandleKeyRotationTimer();
|
||||
}
|
||||
|
||||
void KeyManager::HandleKeyRotationTimer(void)
|
||||
{
|
||||
SetCurrentKeySequence(mKeySequence + 1);
|
||||
}
|
||||
|
||||
} // namespace Thread
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread-types.h>
|
||||
#include <common/timer.hpp>
|
||||
#include <crypto/hmac_sha256.hpp>
|
||||
|
||||
namespace Thread {
|
||||
@@ -63,6 +64,18 @@ public:
|
||||
*/
|
||||
explicit KeyManager(ThreadNetif &aThreadNetif);
|
||||
|
||||
/**
|
||||
* This method starts KeyManager rotation timer and sets guard timer to initial value.
|
||||
*
|
||||
*/
|
||||
void Start(void);
|
||||
|
||||
/**
|
||||
* This method stops KeyManager timers.
|
||||
*
|
||||
*/
|
||||
void Stop(void);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Thread Master Key
|
||||
*
|
||||
@@ -195,14 +208,66 @@ public:
|
||||
*/
|
||||
void IncrementKekFrameCounter(void);
|
||||
|
||||
/**
|
||||
* This method returns the KeyRotation time.
|
||||
*
|
||||
* The KeyRotation time is the time interval after witch security key will be automatically rotated.
|
||||
*
|
||||
* @returns The KeyRotation value in hours.
|
||||
*/
|
||||
uint32_t GetKeyRotation(void) const { return mKeyRotationTime; }
|
||||
|
||||
/**
|
||||
* This method sets the KeyRotation time.
|
||||
*
|
||||
* The KeyRotation time is the time interval after witch security key will be automatically rotated.
|
||||
* It's value shall be in range [kMinKeyRotationTime, kMaxKeyRotationTime].
|
||||
*
|
||||
* @param[in] aKeyRotation The KeyRotation value in hours.
|
||||
*
|
||||
* @retval kThreadError_None KeyRotation time updated.
|
||||
* @retval kThreadError_InvalidArgs @p aKeyRotation is out of range.
|
||||
*
|
||||
*/
|
||||
ThreadError SetKeyRotation(uint32_t aKeyRotation);
|
||||
|
||||
/**
|
||||
* This method returns the KeySwitchGuardTime.
|
||||
*
|
||||
* The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented.
|
||||
*
|
||||
* @returns The KeySwitchGuardTime value in hours.
|
||||
*
|
||||
*/
|
||||
uint32_t GetKeySwitchGuardTime(void) const { return mKeySwitchGuardTime; }
|
||||
|
||||
/**
|
||||
* This method sets the KeySwitchGuardTime.
|
||||
*
|
||||
* The KeySwitchGuardTime is the time interval during which key rotation procedure is prevented.
|
||||
*
|
||||
* @param[in] aKeySwitchGuardTime The KeySwitchGuardTime value in hours.
|
||||
*
|
||||
*/
|
||||
void SetKeySwitchGuardTime(uint32_t aKeySwitchGuardTime) { mKeySwitchGuardTime = aKeySwitchGuardTime; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxKeyLength = 16,
|
||||
kMinKeyRotationTime = 1,
|
||||
kMaxKeyRotationTime = 0xffffffff / 3600u / 1000u,
|
||||
kDefaultKeyRotationTime = 672,
|
||||
kDefaultKeySwitchGuardTime = 624,
|
||||
};
|
||||
|
||||
ThreadError ComputeKey(uint32_t aKeySequence, uint8_t *aKey);
|
||||
|
||||
static void HandleKeyRotationTimer(void *aContext);
|
||||
void HandleKeyRotationTimer(void);
|
||||
|
||||
ThreadNetif &mNetif;
|
||||
|
||||
uint8_t mMasterKey[kMaxKeyLength];
|
||||
uint8_t mMasterKeyLength;
|
||||
|
||||
@@ -214,10 +279,13 @@ private:
|
||||
uint32_t mMacFrameCounter;
|
||||
uint32_t mMleFrameCounter;
|
||||
|
||||
uint32_t mKeyRotationTime;
|
||||
uint32_t mKeySwitchGuardTime;
|
||||
bool mKeySwitchGuardEnabled;
|
||||
Timer mKeyRotationTimer;
|
||||
|
||||
uint8_t mKek[kMaxKeyLength];
|
||||
uint32_t mKekFrameCounter;
|
||||
|
||||
ThreadNetif &mNetif;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -201,6 +201,8 @@ ThreadError Mle::Start(void)
|
||||
mDeviceState = kDeviceStateDetached;
|
||||
SetStateDetached();
|
||||
|
||||
mKeyManager.Start();
|
||||
|
||||
if (GetRloc16() == Mac::kShortAddrInvalid)
|
||||
{
|
||||
BecomeChild(kMleAttachAnyPartition);
|
||||
@@ -222,6 +224,7 @@ exit:
|
||||
|
||||
ThreadError Mle::Stop(void)
|
||||
{
|
||||
mKeyManager.Stop();
|
||||
SetStateDetached();
|
||||
mNetif.RemoveUnicastAddress(mLinkLocal16);
|
||||
mNetif.RemoveUnicastAddress(mMeshLocal16);
|
||||
|
||||
Reference in New Issue
Block a user