mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
[mac] adding otMacKey and Mac::Key (#4967)
This commit adds a new type `otMacKey` which represents a MAC security key (used by AES-CCM to perform frame security) and core subclass of this as `Mac::Key`. The same type is used as `Mle::Key`. The `KeyManager`, `Mac`, `Mle`, and other modules are updated to use the new `Key` types. The public OT API `otLinkRawSetMacKey` and radio platform `otPlatRadioSetMacKey()` are also updated to use `otMacKey`.
This commit is contained in:
committed by
GitHub
parent
72109da6f1
commit
436aba64c0
@@ -344,12 +344,12 @@ otError otLinkRawSrcMatchClearExtEntries(otInstance *aInstance);
|
||||
* @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled.
|
||||
*
|
||||
*/
|
||||
otError otLinkRawSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey);
|
||||
otError otLinkRawSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const otMacKey *aPrevKey,
|
||||
const otMacKey *aCurrKey,
|
||||
const otMacKey *aNextKey);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -161,6 +161,26 @@ struct otExtAddress
|
||||
*/
|
||||
typedef struct otExtAddress otExtAddress;
|
||||
|
||||
#define OT_MAC_KEY_SIZE 16 ///< Size of the MAC Key in bytes.
|
||||
|
||||
/**
|
||||
* @struct otMacKey
|
||||
*
|
||||
* This structure represents a MAC Key.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct otMacKey
|
||||
{
|
||||
uint8_t m8[OT_MAC_KEY_SIZE]; ///< MAC Key bytes.
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This structure represents a MAC Key.
|
||||
*
|
||||
*/
|
||||
typedef struct otMacKey otMacKey;
|
||||
|
||||
/**
|
||||
* This structure represents the IEEE 802.15.4 Header IE (Information Element) related information of a radio frame.
|
||||
*/
|
||||
@@ -191,13 +211,13 @@ typedef struct otRadioFrame
|
||||
*/
|
||||
struct
|
||||
{
|
||||
const uint8_t *mAesKey; ///< The key used for AES-CCM frame security.
|
||||
otRadioIeInfo *mIeInfo; ///< The pointer to the Header IE(s) related information.
|
||||
uint8_t mMaxCsmaBackoffs; ///< Maximum number of backoffs attempts before declaring CCA failure.
|
||||
uint8_t mMaxFrameRetries; ///< Maximum number of retries allowed after a transmission failure.
|
||||
bool mIsARetx : 1; ///< True if this frame is a retransmission (ignored by radio driver).
|
||||
bool mCsmaCaEnabled : 1; ///< Set to true to enable CSMA-CA for this packet, false otherwise.
|
||||
bool mIsSecurityProcessed : 1; ///< True if SubMac should skip the AES processing of this frame.
|
||||
const otMacKey *mAesKey; ///< The key used for AES-CCM frame security.
|
||||
otRadioIeInfo * mIeInfo; ///< The pointer to the Header IE(s) related information.
|
||||
uint8_t mMaxCsmaBackoffs; ///< Maximum number of backoffs attempts before declaring CCA failure.
|
||||
uint8_t mMaxFrameRetries; ///< Maximum number of retries allowed after a transmission failure.
|
||||
bool mIsARetx : 1; ///< True if this frame is a retransmission (ignored by radio driver).
|
||||
bool mCsmaCaEnabled : 1; ///< Set to true to enable CSMA-CA for this packet, false otherwise.
|
||||
bool mIsSecurityProcessed : 1; ///< True if SubMac should skip the AES processing of this frame.
|
||||
} mTxInfo;
|
||||
|
||||
/**
|
||||
@@ -443,19 +463,17 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable);
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aKeyIdMode The key ID mode.
|
||||
* @param[in] aKeyId Current MAC key index.
|
||||
* @param[in] aKeySize The key size.
|
||||
* @param[in] aPrevKey A pointer to the previous MAC key.
|
||||
* @param[in] aCurrKey A pointer to the current MAC key.
|
||||
* @param[in] aNextKey A pointer to the next MAC key.
|
||||
*
|
||||
*/
|
||||
void otPlatRadioSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
uint8_t aKeySize,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey);
|
||||
void otPlatRadioSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const otMacKey *aPrevKey,
|
||||
const otMacKey *aCurrKey,
|
||||
const otMacKey *aNextKey);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -221,15 +221,16 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError otLinkRawSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey)
|
||||
otError otLinkRawSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const otMacKey *aPrevKey,
|
||||
const otMacKey *aCurrKey,
|
||||
const otMacKey *aNextKey)
|
||||
{
|
||||
return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey,
|
||||
aNextKey);
|
||||
return static_cast<Instance *>(aInstance)->Get<Mac::LinkRaw>().SetMacKey(
|
||||
aKeyIdMode, aKeyId, *static_cast<const Mac::Key *>(aPrevKey), *static_cast<const Mac::Key *>(aCurrKey),
|
||||
*static_cast<const Mac::Key *>(aNextKey));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_RADIO
|
||||
|
||||
@@ -45,6 +45,11 @@ void AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength)
|
||||
mEcb.SetKey(aKey, 8 * aKeyLength);
|
||||
}
|
||||
|
||||
void AesCcm::SetKey(const Mac::Key &aMacKey)
|
||||
{
|
||||
SetKey(aMacKey.GetKey(), Mac::Key::kSize);
|
||||
}
|
||||
|
||||
otError AesCcm::Init(uint32_t aHeaderLength,
|
||||
uint32_t aPlainTextLength,
|
||||
uint8_t aTagLength,
|
||||
|
||||
@@ -74,6 +74,14 @@ public:
|
||||
*/
|
||||
void SetKey(const uint8_t *aKey, uint16_t aKeyLength);
|
||||
|
||||
/**
|
||||
* This method sets the key.
|
||||
*
|
||||
* @param[in] aMacKey A MAC key.
|
||||
*
|
||||
*/
|
||||
void SetKey(const Mac::Key &aMacKey);
|
||||
|
||||
/**
|
||||
* This method initializes the AES CCM computation.
|
||||
*
|
||||
|
||||
@@ -205,11 +205,11 @@ void LinkRaw::InvokeEnergyScanDone(int8_t aEnergyScanMaxRssi)
|
||||
}
|
||||
}
|
||||
|
||||
otError LinkRaw::SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey)
|
||||
otError LinkRaw::SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const Key &aPrevKey,
|
||||
const Key &aCurrKey,
|
||||
const Key &aNextKey)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
|
||||
@@ -256,11 +256,11 @@ public:
|
||||
* @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled.
|
||||
*
|
||||
*/
|
||||
otError SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey);
|
||||
otError SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const Key &aPrevKey,
|
||||
const Key &aCurrKey,
|
||||
const Key &aNextKey);
|
||||
|
||||
/**
|
||||
* This method records the status of a frame transmission attempt and is mainly used for logging failures.
|
||||
|
||||
+11
-12
@@ -54,8 +54,8 @@
|
||||
namespace ot {
|
||||
namespace Mac {
|
||||
|
||||
const uint8_t Mac::sMode2Key[] = {0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f,
|
||||
0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66};
|
||||
const otMacKey Mac::sMode2Key = {
|
||||
{0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f, 0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66}};
|
||||
|
||||
const otExtAddress Mac::sMode2ExtAddress = {
|
||||
{0x35, 0x06, 0xfe, 0xb8, 0x23, 0xd4, 0x87, 0x12},
|
||||
@@ -958,7 +958,7 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame)
|
||||
switch (keyIdMode)
|
||||
{
|
||||
case Frame::kKeyIdMode0:
|
||||
aFrame.SetAesKey(keyManager.GetKek().GetKey());
|
||||
aFrame.SetAesKey(keyManager.GetKek());
|
||||
extAddress = &GetExtAddress();
|
||||
|
||||
if (!aFrame.IsARetransmission())
|
||||
@@ -989,7 +989,7 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame)
|
||||
case Frame::kKeyIdMode2:
|
||||
{
|
||||
const uint8_t keySource[] = {0xff, 0xff, 0xff, 0xff};
|
||||
aFrame.SetAesKey(sMode2Key);
|
||||
aFrame.SetAesKey(static_cast<const Key &>(sMode2Key));
|
||||
mKeyIdMode2FrameCounter++;
|
||||
aFrame.SetFrameCounter(mKeyIdMode2FrameCounter);
|
||||
aFrame.SetKeySource(keySource);
|
||||
@@ -1432,7 +1432,7 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne
|
||||
uint8_t tagLength;
|
||||
uint8_t keyid;
|
||||
uint32_t keySequence = 0;
|
||||
const uint8_t * macKey;
|
||||
const Key * macKey;
|
||||
const ExtAddress *extAddress;
|
||||
Crypto::AesCcm aesCcm;
|
||||
|
||||
@@ -1449,8 +1449,7 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne
|
||||
switch (keyIdMode)
|
||||
{
|
||||
case Frame::kKeyIdMode0:
|
||||
macKey = keyManager.GetKek().GetKey();
|
||||
VerifyOrExit(macKey != NULL, OT_NOOP);
|
||||
macKey = &keyManager.GetKek();
|
||||
extAddress = &aSrcAddr.GetExtended();
|
||||
break;
|
||||
|
||||
@@ -1463,17 +1462,17 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne
|
||||
if (keyid == (keyManager.GetCurrentKeySequence() & 0x7f))
|
||||
{
|
||||
keySequence = keyManager.GetCurrentKeySequence();
|
||||
macKey = mSubMac.GetCurrentMacKey();
|
||||
macKey = &mSubMac.GetCurrentMacKey();
|
||||
}
|
||||
else if (keyid == ((keyManager.GetCurrentKeySequence() - 1) & 0x7f))
|
||||
{
|
||||
keySequence = keyManager.GetCurrentKeySequence() - 1;
|
||||
macKey = mSubMac.GetPreviousMacKey();
|
||||
macKey = &mSubMac.GetPreviousMacKey();
|
||||
}
|
||||
else if (keyid == ((keyManager.GetCurrentKeySequence() + 1) & 0x7f))
|
||||
{
|
||||
keySequence = keyManager.GetCurrentKeySequence() + 1;
|
||||
macKey = mSubMac.GetNextMacKey();
|
||||
macKey = &mSubMac.GetNextMacKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1503,7 +1502,7 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne
|
||||
break;
|
||||
|
||||
case Frame::kKeyIdMode2:
|
||||
macKey = sMode2Key;
|
||||
macKey = static_cast<const Key *>(&sMode2Key);
|
||||
extAddress = static_cast<const ExtAddress *>(&sMode2ExtAddress);
|
||||
break;
|
||||
|
||||
@@ -1515,7 +1514,7 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne
|
||||
Crypto::AesCcm::GenerateNonce(*extAddress, frameCounter, securityLevel, nonce);
|
||||
tagLength = aFrame.GetFooterLength() - Frame::kFcsSize;
|
||||
|
||||
aesCcm.SetKey(macKey, 16);
|
||||
aesCcm.SetKey(*macKey);
|
||||
|
||||
SuccessOrExit(aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)));
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ private:
|
||||
|
||||
static const char *OperationToString(Operation aOperation);
|
||||
|
||||
static const uint8_t sMode2Key[];
|
||||
static const otMacKey sMode2Key;
|
||||
static const otExtAddress sMode2ExtAddress;
|
||||
static const otExtendedPanId sExtendedPanidInit;
|
||||
static const char sNetworkNameInit[];
|
||||
|
||||
@@ -1049,7 +1049,7 @@ void TxFrame::ProcessTransmitAesCcm(const ExtAddress &aExtAddress)
|
||||
|
||||
Crypto::AesCcm::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce);
|
||||
|
||||
aesCcm.SetKey(GetAesKey(), 16);
|
||||
aesCcm.SetKey(GetAesKey());
|
||||
tagLength = GetFooterLength() - Frame::kFcsSize;
|
||||
|
||||
error = aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce));
|
||||
|
||||
@@ -1171,7 +1171,7 @@ public:
|
||||
* @returns The pointer to the key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetAesKey(void) const { return mInfo.mTxInfo.mAesKey; }
|
||||
const Mac::Key &GetAesKey(void) const { return *static_cast<const Mac::Key *>(mInfo.mTxInfo.mAesKey); }
|
||||
|
||||
/**
|
||||
* This method sets the key used for frame encryption and authentication (AES CCM).
|
||||
@@ -1179,7 +1179,7 @@ public:
|
||||
* @param[in] aAesKey The pointer to the key.
|
||||
*
|
||||
*/
|
||||
void SetAesKey(const uint8_t *aAesKey) { mInfo.mTxInfo.mAesKey = aAesKey; }
|
||||
void SetAesKey(const Mac::Key &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; }
|
||||
|
||||
/**
|
||||
* This method copies the PSDU and all attributes from another frame.
|
||||
|
||||
@@ -442,6 +442,56 @@ private:
|
||||
Type mType; ///< The address type (Short, Extended, or none).
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents a MAC key.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class Key : public otMacKey
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kSize = OT_MAC_KEY_SIZE, // Key size in bytes.
|
||||
};
|
||||
|
||||
/**
|
||||
* This method clears the key (set all bytes to zero).
|
||||
*
|
||||
*/
|
||||
void Clear(void) { memset(m8, 0, kSize); }
|
||||
|
||||
/**
|
||||
* This method gets a pointer to the buffer containing the key.
|
||||
*
|
||||
* @returns A pointer to the buffer containing the key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetKey(void) const { return m8; }
|
||||
|
||||
/**
|
||||
* This method evaluates whether or not two keys match.
|
||||
*
|
||||
* @param[in] aOtherKey The key to compare with.
|
||||
*
|
||||
* @retval TRUE If the key matches the @p aOtherKey.
|
||||
* @retval FALSE If the key does not match the @p aOtherKey.
|
||||
*
|
||||
*/
|
||||
bool operator==(const Key &aOtherKey) const { return memcmp(m8, aOtherKey.m8, kSize) == 0; }
|
||||
|
||||
/**
|
||||
* This method evaluates whether or not two keys match.
|
||||
*
|
||||
* @param[in] aOtherKey The key to compare with.
|
||||
*
|
||||
* @retval TRUE If the key does not match @p aOtherKey.
|
||||
* @retval FALSE If the key does match @p aOtherKey.
|
||||
*
|
||||
*/
|
||||
bool operator!=(const Key &aOtherKey) const { return !(*this == aOtherKey); }
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This structure represents an IEEE 802.15.4 Extended PAN Identifier.
|
||||
*
|
||||
|
||||
+14
-16
@@ -63,9 +63,9 @@ SubMac::SubMac(Instance &aInstance)
|
||||
, mTimer(aInstance, &SubMac::HandleTimer, this)
|
||||
{
|
||||
mExtAddress.Clear();
|
||||
memset(mPrevKey, 0, sizeof(mPrevKey));
|
||||
memset(mCurrKey, 0, sizeof(mCurrKey));
|
||||
memset(mNextKey, 0, sizeof(mNextKey));
|
||||
mPrevKey.Clear();
|
||||
mCurrKey.Clear();
|
||||
mNextKey.Clear();
|
||||
}
|
||||
|
||||
otRadioCaps SubMac::GetCaps(void) const
|
||||
@@ -244,6 +244,7 @@ void SubMac::ProcessTransmitSecurity(void)
|
||||
VerifyOrExit(keyIdMode == Frame::kKeyIdMode1, OT_NOOP);
|
||||
|
||||
mTransmitFrame.SetAesKey(GetCurrentMacKey());
|
||||
|
||||
if (!mTransmitFrame.IsARetransmission())
|
||||
{
|
||||
mTransmitFrame.SetKeyId(mKeyId);
|
||||
@@ -623,11 +624,11 @@ void SubMac::SetState(State aState)
|
||||
}
|
||||
}
|
||||
|
||||
void SubMac::SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey)
|
||||
void SubMac::SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const Key &aPrevKey,
|
||||
const Key &aCurrKey,
|
||||
const Key &aNextKey)
|
||||
{
|
||||
switch (aKeyIdMode)
|
||||
{
|
||||
@@ -635,13 +636,10 @@ void SubMac::SetMacKey(uint8_t aKeyIdMode,
|
||||
case Frame::kKeyIdMode2:
|
||||
break;
|
||||
case Frame::kKeyIdMode1:
|
||||
OT_ASSERT(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);
|
||||
|
||||
mKeyId = aKeyId;
|
||||
memcpy(mPrevKey, aPrevKey, sizeof(mPrevKey));
|
||||
memcpy(mCurrKey, aCurrKey, sizeof(mCurrKey));
|
||||
memcpy(mNextKey, aNextKey, sizeof(mNextKey));
|
||||
|
||||
mKeyId = aKeyId;
|
||||
mPrevKey = aPrevKey;
|
||||
mCurrKey = aCurrKey;
|
||||
mNextKey = aNextKey;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -651,7 +649,7 @@ void SubMac::SetMacKey(uint8_t aKeyIdMode,
|
||||
|
||||
VerifyOrExit(!ShouldHandleTransmitSecurity(), OT_NOOP);
|
||||
|
||||
Get<Radio>().SetMacKey(aKeyIdMode, aKeyId, kMacKeySize, aPrevKey, aCurrKey, aNextKey);
|
||||
Get<Radio>().SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey);
|
||||
|
||||
exit:
|
||||
return;
|
||||
|
||||
+16
-21
@@ -82,7 +82,6 @@ public:
|
||||
enum
|
||||
{
|
||||
kInvalidRssiValue = 127, ///< Invalid Received Signal Strength Indicator (RSSI) value.
|
||||
kMacKeySize = 16, ///< MAC Key size (bytes)
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -353,40 +352,36 @@ public:
|
||||
*
|
||||
* @param[in] aKeyIdMode MAC key ID mode.
|
||||
* @param[in] aKeyId The key ID.
|
||||
* @param[in] aPrevKey A pointer to the previous MAC key.
|
||||
* @param[in] aCurrKey A pointer to the current MAC key.
|
||||
* @param[in] aNextKey A pointer to the next MAC key.
|
||||
* @param[in] aPrevKey The previous MAC key.
|
||||
* @param[in] aCurrKey The current MAC key.
|
||||
* @param[in] aNextKey The next MAC key.
|
||||
*
|
||||
*/
|
||||
void SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey);
|
||||
void SetMacKey(uint8_t aKeyIdMode, uint8_t aKeyId, const Key &aPrevKey, const Key &aCurrKey, const Key &aNextKey);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the current MAC key.
|
||||
* This method returns a reference to the current MAC key.
|
||||
*
|
||||
* @returns A pointer to the current MAC key.
|
||||
* @returns A reference to the current MAC key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetCurrentMacKey(void) const { return mCurrKey; }
|
||||
const Key &GetCurrentMacKey(void) const { return mCurrKey; }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the previous MAC key.
|
||||
* This method returns a reference to the previous MAC key.
|
||||
*
|
||||
* @returns A pointer to the previous MAC key.
|
||||
* @returns A reference to the previous MAC key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetPreviousMacKey(void) const { return mPrevKey; }
|
||||
const Key &GetPreviousMacKey(void) const { return mPrevKey; }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the next MAC key.
|
||||
* This method returns a reference to the next MAC key.
|
||||
*
|
||||
* @returns A pointer to the next MAC key.
|
||||
* @returns A reference to the next MAC key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetNextMacKey(void) const { return mNextKey; }
|
||||
const Key &GetNextMacKey(void) const { return mNextKey; }
|
||||
|
||||
private:
|
||||
enum
|
||||
@@ -459,9 +454,9 @@ private:
|
||||
Callbacks mCallbacks;
|
||||
otLinkPcapCallback mPcapCallback;
|
||||
void * mPcapCallbackContext;
|
||||
uint8_t mPrevKey[kMacKeySize];
|
||||
uint8_t mCurrKey[kMacKeySize];
|
||||
uint8_t mNextKey[kMacKeySize];
|
||||
Key mPrevKey;
|
||||
Key mCurrKey;
|
||||
Key mNextKey;
|
||||
uint8_t mKeyId;
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
|
||||
TimerMicro mTimer;
|
||||
|
||||
@@ -252,20 +252,18 @@ public:
|
||||
*
|
||||
* @param[in] aKeyIdMode MAC key ID mode.
|
||||
* @param[in] aKeyId Current MAC key index.
|
||||
* @param[in] aKeySize MAC key size in bytes.
|
||||
* @param[in] aPrevKey A pointer to the previous MAC key.
|
||||
* @param[in] aCurrKey A pointer to the current MAC key.
|
||||
* @param[in] aNextKey A pointer to the next MAC key.
|
||||
* @param[in] aPrevKey The previous MAC key.
|
||||
* @param[in] aCurrKey The current MAC key.
|
||||
* @param[in] aNextKey The next MAC key.
|
||||
*
|
||||
*/
|
||||
void SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
uint8_t aKeySize,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey)
|
||||
void SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const Mac::Key &aPrevKey,
|
||||
const Mac::Key &aCurrKey,
|
||||
const Mac::Key &aNextKey)
|
||||
{
|
||||
otPlatRadioSetMacKey(GetInstance(), aKeyIdMode, aKeyId, aKeySize, aPrevKey, aCurrKey, aNextKey);
|
||||
otPlatRadioSetMacKey(GetInstance(), aKeyIdMode, aKeyId, &aPrevKey, &aCurrKey, &aNextKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -125,18 +125,16 @@ OT_TOOL_WEAK otRadioState otPlatRadioGetState(otInstance *aInstance)
|
||||
return OT_RADIO_STATE_INVALID;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatRadioSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
uint8_t aKeySize,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey)
|
||||
OT_TOOL_WEAK 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);
|
||||
OT_UNUSED_VARIABLE(aKeyId);
|
||||
OT_UNUSED_VARIABLE(aKeySize);
|
||||
OT_UNUSED_VARIABLE(aPrevKey);
|
||||
OT_UNUSED_VARIABLE(aCurrKey);
|
||||
OT_UNUSED_VARIABLE(aNextKey);
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "crypto/hmac_sha256.hpp"
|
||||
#include "thread/mle_router.hpp"
|
||||
#include "thread/thread_netif.hpp"
|
||||
|
||||
@@ -145,7 +144,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void KeyManager::ComputeKey(uint32_t aKeySequence, uint8_t *aKey)
|
||||
void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys)
|
||||
{
|
||||
Crypto::HmacSha256 hmac;
|
||||
uint8_t keySequenceBytes[sizeof(uint32_t)];
|
||||
@@ -156,22 +155,23 @@ void KeyManager::ComputeKey(uint32_t aKeySequence, uint8_t *aKey)
|
||||
hmac.Update(keySequenceBytes, sizeof(keySequenceBytes));
|
||||
hmac.Update(kThreadString, sizeof(kThreadString));
|
||||
|
||||
hmac.Finish(aKey);
|
||||
hmac.Finish(aHashKeys.mHash);
|
||||
}
|
||||
|
||||
void KeyManager::UpdateKeyMaterial()
|
||||
void KeyManager::UpdateKeyMaterial(void)
|
||||
{
|
||||
uint8_t prevKey[Crypto::HmacSha256::kHashSize];
|
||||
uint8_t currKey[Crypto::HmacSha256::kHashSize];
|
||||
uint8_t nextKey[Crypto::HmacSha256::kHashSize];
|
||||
HashKeys prev;
|
||||
HashKeys cur;
|
||||
HashKeys next;
|
||||
|
||||
ComputeKey(mKeySequence - 1, prevKey);
|
||||
ComputeKey(mKeySequence, currKey);
|
||||
ComputeKey(mKeySequence + 1, nextKey);
|
||||
ComputeKeys(mKeySequence - 1, prev);
|
||||
ComputeKeys(mKeySequence, cur);
|
||||
ComputeKeys(mKeySequence + 1, next);
|
||||
|
||||
memcpy(mMleKey, currKey, kMleKeySize);
|
||||
Get<Mac::SubMac>().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prevKey + kMacKeyOffset,
|
||||
currKey + kMacKeyOffset, nextKey + kMacKeyOffset);
|
||||
mMleKey = cur.mKeys.mMleKey;
|
||||
|
||||
Get<Mac::SubMac>().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prev.mKeys.mMacKey,
|
||||
cur.mKeys.mMacKey, next.mKeys.mMacKey);
|
||||
}
|
||||
|
||||
void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence)
|
||||
@@ -202,10 +202,14 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t *KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
|
||||
const Mle::Key &KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
|
||||
{
|
||||
ComputeKey(aKeySequence, mTemporaryKey);
|
||||
return mTemporaryKey;
|
||||
HashKeys hashKeys;
|
||||
|
||||
ComputeKeys(aKeySequence, hashKeys);
|
||||
mTemporaryMleKey = hashKeys.mKeys.mMleKey;
|
||||
|
||||
return mTemporaryMleKey;
|
||||
}
|
||||
|
||||
void KeyManager::IncrementMacFrameCounter(void)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "common/timer.hpp"
|
||||
#include "crypto/hmac_sha256.hpp"
|
||||
#include "mac/mac_types.hpp"
|
||||
#include "thread/mle_types.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
@@ -142,49 +143,7 @@ public:
|
||||
* This class represents a Key Encryption Key (KEK).
|
||||
*
|
||||
*/
|
||||
class Kek
|
||||
{
|
||||
friend class KeyManager;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kSize = 16, // KEK size in bytes.
|
||||
};
|
||||
|
||||
/**
|
||||
* This method returns the KEK.
|
||||
*
|
||||
* @returns A pointer to buffer containing the KEK.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetKey(void) const { return m8; }
|
||||
|
||||
/**
|
||||
* This method evaluates whether or not two KEKs match.
|
||||
*
|
||||
* @param[in] aOther The KEK to compare.
|
||||
*
|
||||
* @retval TRUE If the KEKs match.
|
||||
* @retval FALSE If the KEKs do not match.
|
||||
*
|
||||
*/
|
||||
bool operator==(const Kek &aOther) const { return memcmp(m8, aOther.m8, sizeof(Kek)) == 0; }
|
||||
|
||||
/**
|
||||
* This method evaluates whether or not the KEK match.
|
||||
*
|
||||
* @param[in] aOther The KEK to compare.
|
||||
*
|
||||
* @retval TRUE If the KEK do not match.
|
||||
* @retval FALSE If the KEK match.
|
||||
*
|
||||
*/
|
||||
bool operator!=(const Kek &aOther) const { return !(*this == aOther); }
|
||||
|
||||
private:
|
||||
uint8_t m8[kSize]; ///< Buffer containing the KEK.
|
||||
};
|
||||
typedef Mac::Key Kek;
|
||||
|
||||
/**
|
||||
* This class defines Thread Key Manager.
|
||||
@@ -283,7 +242,7 @@ public:
|
||||
* @returns A pointer to the current MLE key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetCurrentMleKey(void) const { return mMleKey; }
|
||||
const Mle::Key &GetCurrentMleKey(void) const { return mMleKey; }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a temporary MLE key computed from the given key sequence.
|
||||
@@ -293,7 +252,7 @@ public:
|
||||
* @returns A pointer to the temporary MLE key.
|
||||
*
|
||||
*/
|
||||
const uint8_t *GetTemporaryMleKey(uint32_t aKeySequence);
|
||||
const Mle::Key &GetTemporaryMleKey(uint32_t aKeySequence);
|
||||
|
||||
/**
|
||||
* This method returns the current MAC Frame Counter value.
|
||||
@@ -526,12 +485,23 @@ private:
|
||||
kMinKeyRotationTime = 1,
|
||||
kDefaultKeyRotationTime = 672,
|
||||
kDefaultKeySwitchGuardTime = 624,
|
||||
kMacKeyOffset = 16,
|
||||
kMleKeySize = 16,
|
||||
kOneHourIntervalInMsec = 3600u * 1000u,
|
||||
};
|
||||
|
||||
void ComputeKey(uint32_t aKeySequence, uint8_t *aKey);
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct Keys
|
||||
{
|
||||
Mle::Key mMleKey;
|
||||
Mac::Key mMacKey;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
union HashKeys
|
||||
{
|
||||
uint8_t mHash[Crypto::HmacSha256::kHashSize];
|
||||
Keys mKeys;
|
||||
};
|
||||
|
||||
void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys);
|
||||
|
||||
void StartKeyRotationTimer(void);
|
||||
static void HandleKeyRotationTimer(Timer &aTimer);
|
||||
@@ -543,8 +513,8 @@ private:
|
||||
MasterKey mMasterKey;
|
||||
|
||||
uint32_t mKeySequence;
|
||||
uint8_t mMleKey[kMleKeySize];
|
||||
uint8_t mTemporaryKey[Crypto::HmacSha256::kHashSize];
|
||||
Mle::Key mMleKey;
|
||||
Mle::Key mTemporaryMleKey;
|
||||
|
||||
uint32_t mMacFrameCounter;
|
||||
uint32_t mMleFrameCounter;
|
||||
|
||||
@@ -2541,7 +2541,7 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination)
|
||||
Crypto::AesCcm::GenerateNonce(Get<Mac::Mac>().GetExtAddress(), Get<KeyManager>().GetMleFrameCounter(),
|
||||
Mac::Frame::kSecEncMic32, nonce);
|
||||
|
||||
aesCcm.SetKey(Get<KeyManager>().GetCurrentMleKey(), 16);
|
||||
aesCcm.SetKey(Get<KeyManager>().GetCurrentMleKey());
|
||||
error = aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1),
|
||||
sizeof(tag), nonce, sizeof(nonce));
|
||||
OT_ASSERT(error == OT_ERROR_NONE);
|
||||
@@ -2606,7 +2606,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
otError error = OT_ERROR_NONE;
|
||||
Header header;
|
||||
uint32_t keySequence;
|
||||
const uint8_t * mleKey;
|
||||
const Key * mleKey;
|
||||
uint32_t frameCounter;
|
||||
uint8_t messageTag[4];
|
||||
uint8_t nonce[Crypto::AesCcm::kNonceSize];
|
||||
@@ -2658,11 +2658,11 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
|
||||
if (keySequence == Get<KeyManager>().GetCurrentKeySequence())
|
||||
{
|
||||
mleKey = Get<KeyManager>().GetCurrentMleKey();
|
||||
mleKey = &Get<KeyManager>().GetCurrentMleKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
mleKey = Get<KeyManager>().GetTemporaryMleKey(keySequence);
|
||||
mleKey = &Get<KeyManager>().GetTemporaryMleKey(keySequence);
|
||||
}
|
||||
|
||||
VerifyOrExit(aMessage.GetOffset() + header.GetLength() + sizeof(messageTag) <= aMessage.GetLength(),
|
||||
@@ -2676,7 +2676,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
frameCounter = header.GetFrameCounter();
|
||||
Crypto::AesCcm::GenerateNonce(macAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce);
|
||||
|
||||
aesCcm.SetKey(mleKey, 16);
|
||||
aesCcm.SetKey(*mleKey);
|
||||
SuccessOrExit(error = aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) +
|
||||
header.GetHeaderLength(),
|
||||
aMessage.GetLength() - aMessage.GetOffset(), sizeof(messageTag), nonce,
|
||||
|
||||
@@ -647,6 +647,12 @@ private:
|
||||
uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class represents a MLE key.
|
||||
*
|
||||
*/
|
||||
typedef Mac::Key Key;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -602,22 +602,20 @@ public:
|
||||
*
|
||||
* @param[in] aKeyIdMode The key ID mode.
|
||||
* @param[in] aKeyId The key index.
|
||||
* @param[in] aKeySize The key length.
|
||||
* @param[in] aPrevKey The pointer to the previous MAC key.
|
||||
* @param[in] aCurrKey The pointer to the current MAC key.
|
||||
* @param[in] aNextKey The pointer to the next MAC key.
|
||||
* @param[in] aPrevKey The previous MAC key.
|
||||
* @param[in] aCurrKey The current MAC key.
|
||||
* @param[in] aNextKey The next MAC key.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Succeeded.
|
||||
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
|
||||
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
|
||||
*
|
||||
*/
|
||||
otError SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
uint8_t aKeySize,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey);
|
||||
otError SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const otMacKey &aPrevKey,
|
||||
const otMacKey &aCurrKey,
|
||||
const otMacKey &aNextKey);
|
||||
|
||||
/**
|
||||
* This method checks whether the spinel interface is radio-only
|
||||
|
||||
@@ -1012,19 +1012,19 @@ exit:
|
||||
}
|
||||
|
||||
template <typename InterfaceType, typename ProcessContextType>
|
||||
otError RadioSpinel<InterfaceType, ProcessContextType>::SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
uint8_t aKeySize,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey)
|
||||
otError RadioSpinel<InterfaceType, ProcessContextType>::SetMacKey(uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const otMacKey &aPrevKey,
|
||||
const otMacKey &aCurrKey,
|
||||
const otMacKey &aNextKey)
|
||||
{
|
||||
otError error;
|
||||
|
||||
SuccessOrExit(error = Set(SPINEL_PROP_RCP_MAC_KEY,
|
||||
SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_DATA_WLEN_S
|
||||
SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_DATA_WLEN_S,
|
||||
aKeyIdMode, aKeyId, aPrevKey, aKeySize, aCurrKey, aKeySize, aNextKey, aKeySize));
|
||||
aKeyIdMode, aKeyId, aPrevKey.m8, sizeof(otMacKey), aCurrKey.m8, sizeof(otMacKey),
|
||||
aNextKey.m8, sizeof(otMacKey)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -445,15 +445,17 @@ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_MAC_KEY>(void)
|
||||
SuccessOrExit(error = mDecoder.ReadUint8(keyId));
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadDataWithLen(prevKey, keySize));
|
||||
VerifyOrExit(keySize == Mac::SubMac::kMacKeySize, error = OT_ERROR_INVALID_ARGS);
|
||||
VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadDataWithLen(currKey, keySize));
|
||||
VerifyOrExit(keySize == Mac::SubMac::kMacKeySize, error = OT_ERROR_INVALID_ARGS);
|
||||
VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
SuccessOrExit(error = mDecoder.ReadDataWithLen(nextKey, keySize));
|
||||
VerifyOrExit(keySize == Mac::SubMac::kMacKeySize, error = OT_ERROR_INVALID_ARGS);
|
||||
VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
error = otLinkRawSetMacKey(mInstance, keyIdMode, keyId, prevKey, currKey, nextKey);
|
||||
error =
|
||||
otLinkRawSetMacKey(mInstance, keyIdMode, keyId, reinterpret_cast<const otMacKey *>(prevKey),
|
||||
reinterpret_cast<const otMacKey *>(currKey), reinterpret_cast<const otMacKey *>(nextKey));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -475,14 +475,13 @@ otRadioState otPlatRadioGetState(otInstance *aInstance)
|
||||
return sRadioSpinel.GetState();
|
||||
}
|
||||
|
||||
void otPlatRadioSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
uint8_t aKeySize,
|
||||
const uint8_t *aPrevKey,
|
||||
const uint8_t *aCurrKey,
|
||||
const uint8_t *aNextKey)
|
||||
void otPlatRadioSetMacKey(otInstance * aInstance,
|
||||
uint8_t aKeyIdMode,
|
||||
uint8_t aKeyId,
|
||||
const otMacKey *aPrevKey,
|
||||
const otMacKey *aCurrKey,
|
||||
const otMacKey *aNextKey)
|
||||
{
|
||||
SuccessOrDie(sRadioSpinel.SetMacKey(aKeyIdMode, aKeyId, aKeySize, aPrevKey, aCurrKey, aNextKey));
|
||||
SuccessOrDie(sRadioSpinel.SetMacKey(aKeyIdMode, aKeyId, *aPrevKey, *aCurrKey, *aNextKey));
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user