Add key rotation timer and key switch guard timer. (#732) (#751)

This commit is contained in:
Hubert Miś
2016-10-06 09:11:40 -07:00
committed by Jonathan Hui
parent 2c21e83d89
commit 06535536de
4 changed files with 179 additions and 11 deletions
+16
View File
@@ -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); }
+90 -9
View File
@@ -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
+70 -2
View File
@@ -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;
};
/**
+3
View File
@@ -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);