From 436aba64c0c2af13e103769ba333dd48eca00f07 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 18 May 2020 09:35:45 -0700 Subject: [PATCH] [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`. --- include/openthread/link_raw.h | 12 ++--- include/openthread/platform/radio.h | 48 +++++++++++++------ src/core/api/link_raw_api.cpp | 17 +++---- src/core/crypto/aes_ccm.cpp | 5 ++ src/core/crypto/aes_ccm.hpp | 8 ++++ src/core/mac/link_raw.cpp | 10 ++-- src/core/mac/link_raw.hpp | 10 ++-- src/core/mac/mac.cpp | 23 +++++---- src/core/mac/mac.hpp | 2 +- src/core/mac/mac_frame.cpp | 2 +- src/core/mac/mac_frame.hpp | 4 +- src/core/mac/mac_types.hpp | 50 ++++++++++++++++++++ src/core/mac/sub_mac.cpp | 30 ++++++------ src/core/mac/sub_mac.hpp | 37 +++++++-------- src/core/radio/radio.hpp | 20 ++++---- src/core/radio/radio_platform.cpp | 14 +++--- src/core/thread/key_manager.cpp | 36 +++++++------- src/core/thread/key_manager.hpp | 70 ++++++++-------------------- src/core/thread/mle.cpp | 10 ++-- src/core/thread/mle_types.hpp | 6 +++ src/lib/spinel/radio_spinel.hpp | 18 ++++--- src/lib/spinel/radio_spinel_impl.hpp | 14 +++--- src/ncp/ncp_base_radio.cpp | 10 ++-- src/posix/platform/radio.cpp | 15 +++--- 24 files changed, 260 insertions(+), 211 deletions(-) diff --git a/include/openthread/link_raw.h b/include/openthread/link_raw.h index f3297fc65..486a5282a 100644 --- a/include/openthread/link_raw.h +++ b/include/openthread/link_raw.h @@ -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); /** * @} diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h index 1f08ff3dd..b5cd19f82 100644 --- a/include/openthread/platform/radio.h +++ b/include/openthread/platform/radio.h @@ -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); /** * @} diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp index f0b99beeb..e3f7f1389 100644 --- a/src/core/api/link_raw_api.cpp +++ b/src/core/api/link_raw_api.cpp @@ -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(aInstance)->Get().SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, - aNextKey); + return static_cast(aInstance)->Get().SetMacKey( + aKeyIdMode, aKeyId, *static_cast(aPrevKey), *static_cast(aCurrKey), + *static_cast(aNextKey)); } #if OPENTHREAD_RADIO diff --git a/src/core/crypto/aes_ccm.cpp b/src/core/crypto/aes_ccm.cpp index a59e3f856..1c245c10b 100644 --- a/src/core/crypto/aes_ccm.cpp +++ b/src/core/crypto/aes_ccm.cpp @@ -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, diff --git a/src/core/crypto/aes_ccm.hpp b/src/core/crypto/aes_ccm.hpp index 8682c8109..dd53f4214 100644 --- a/src/core/crypto/aes_ccm.hpp +++ b/src/core/crypto/aes_ccm.hpp @@ -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. * diff --git a/src/core/mac/link_raw.cpp b/src/core/mac/link_raw.cpp index 993aa1549..91f78866b 100644 --- a/src/core/mac/link_raw.cpp +++ b/src/core/mac/link_raw.cpp @@ -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; diff --git a/src/core/mac/link_raw.hpp b/src/core/mac/link_raw.hpp index b9f2d5a4f..003893a14 100644 --- a/src/core/mac/link_raw.hpp +++ b/src/core/mac/link_raw.hpp @@ -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. diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index b1338c596..b10cb564b 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -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(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(&sMode2Key); extAddress = static_cast(&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))); diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 8ec23cd49..01dd080e4 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -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[]; diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index 5d38a1d74..a9673ed51 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -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)); diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index db18a7fb0..faabf089a 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -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(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. diff --git a/src/core/mac/mac_types.hpp b/src/core/mac/mac_types.hpp index f38828ea0..636e9eef6 100644 --- a/src/core/mac/mac_types.hpp +++ b/src/core/mac/mac_types.hpp @@ -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. * diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 89b0917e7..589be6216 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -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().SetMacKey(aKeyIdMode, aKeyId, kMacKeySize, aPrevKey, aCurrKey, aNextKey); + Get().SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey); exit: return; diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index c1a21a0bf..4279daeff 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -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; diff --git a/src/core/radio/radio.hpp b/src/core/radio/radio.hpp index 841fcd73c..2fae17da7 100644 --- a/src/core/radio/radio.hpp +++ b/src/core/radio/radio.hpp @@ -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); } /** diff --git a/src/core/radio/radio_platform.cpp b/src/core/radio/radio_platform.cpp index 46fedf2bd..f73c21c4c 100644 --- a/src/core/radio/radio_platform.cpp +++ b/src/core/radio/radio_platform.cpp @@ -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); diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp index 53fe5b424..7ff564e0a 100644 --- a/src/core/thread/key_manager.cpp +++ b/src/core/thread/key_manager.cpp @@ -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().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prevKey + kMacKeyOffset, - currKey + kMacKeyOffset, nextKey + kMacKeyOffset); + mMleKey = cur.mKeys.mMleKey; + + Get().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) diff --git a/src/core/thread/key_manager.hpp b/src/core/thread/key_manager.hpp index 6ab23c40b..dd822f284 100644 --- a/src/core/thread/key_manager.hpp +++ b/src/core/thread/key_manager.hpp @@ -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; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 819bec9b2..fd3c40ec8 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -2541,7 +2541,7 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination) Crypto::AesCcm::GenerateNonce(Get().GetExtAddress(), Get().GetMleFrameCounter(), Mac::Frame::kSecEncMic32, nonce); - aesCcm.SetKey(Get().GetCurrentMleKey(), 16); + aesCcm.SetKey(Get().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().GetCurrentKeySequence()) { - mleKey = Get().GetCurrentMleKey(); + mleKey = &Get().GetCurrentMleKey(); } else { - mleKey = Get().GetTemporaryMleKey(keySequence); + mleKey = &Get().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, diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index 544d75414..add02bf2d 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -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; + /** * @} * diff --git a/src/lib/spinel/radio_spinel.hpp b/src/lib/spinel/radio_spinel.hpp index 387896b94..651c1856f 100644 --- a/src/lib/spinel/radio_spinel.hpp +++ b/src/lib/spinel/radio_spinel.hpp @@ -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 diff --git a/src/lib/spinel/radio_spinel_impl.hpp b/src/lib/spinel/radio_spinel_impl.hpp index 2a8138872..7870fc387 100644 --- a/src/lib/spinel/radio_spinel_impl.hpp +++ b/src/lib/spinel/radio_spinel_impl.hpp @@ -1012,19 +1012,19 @@ exit: } template -otError RadioSpinel::SetMacKey(uint8_t aKeyIdMode, - uint8_t aKeyId, - uint8_t aKeySize, - const uint8_t *aPrevKey, - const uint8_t *aCurrKey, - const uint8_t *aNextKey) +otError RadioSpinel::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; diff --git a/src/ncp/ncp_base_radio.cpp b/src/ncp/ncp_base_radio.cpp index 121fb8249..f6743095d 100644 --- a/src/ncp/ncp_base_radio.cpp +++ b/src/ncp/ncp_base_radio.cpp @@ -445,15 +445,17 @@ template <> otError NcpBase::HandlePropertySet(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(prevKey), + reinterpret_cast(currKey), reinterpret_cast(nextKey)); exit: return error; diff --git a/src/posix/platform/radio.cpp b/src/posix/platform/radio.cpp index fa8130d4f..195afe28a 100644 --- a/src/posix/platform/radio.cpp +++ b/src/posix/platform/radio.cpp @@ -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); }