diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 7bc58c258..ffd3be61c 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -922,7 +922,7 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm) switch (keyIdMode) { case Frame::kKeyIdMode0: - aFrame.SetAesKey(keyManager.GetKek()); + aFrame.SetAesKey(keyManager.GetKek().GetKey()); extAddress = &GetExtAddress(); if (!aFrame.IsARetransmission()) @@ -1414,7 +1414,7 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne switch (keyIdMode) { case Frame::kKeyIdMode0: - macKey = keyManager.GetKek(); + macKey = keyManager.GetKek().GetKey(); VerifyOrExit(macKey != NULL); extAddress = &aSrcAddr.GetExtended(); break; diff --git a/src/core/meshcop/commissioner.cpp b/src/core/meshcop/commissioner.cpp index 3c8ec5dbd..5f5011471 100644 --- a/src/core/meshcop/commissioner.cpp +++ b/src/core/meshcop/commissioner.cpp @@ -1029,8 +1029,8 @@ otError Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::MessageInf if (aMessage.GetSubType() == Message::kSubTypeJoinerFinalizeResponse) { - SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kJoinerRouterKek, Get().GetKek(), - KeyManager::kMaxKeyLength)); + SuccessOrExit( + error = Tlv::AppendTlv(*message, Tlv::kJoinerRouterKek, Get().GetKek().GetKey(), Kek::kSize)); } tlv.SetType(Tlv::kJoinerDtlsEncapsulation); diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp index d7ce42412..ea9807c72 100644 --- a/src/core/meshcop/joiner_router.cpp +++ b/src/core/meshcop/joiner_router.cpp @@ -190,7 +190,7 @@ void JoinerRouter::HandleRelayTransmit(Coap::Message &aMessage, const Ip6::Messa otError error; uint16_t joinerPort; uint8_t joinerIid[Ip6::Address::kInterfaceIdentifierSize]; - uint8_t kek[KeyManager::kMaxKeyLength]; + Kek kek; uint16_t offset; uint16_t length; Message * message = NULL; @@ -218,7 +218,7 @@ void JoinerRouter::HandleRelayTransmit(Coap::Message &aMessage, const Ip6::Messa SuccessOrExit(error = mSocket.SendTo(*message, messageInfo)); - if (Tlv::ReadTlv(aMessage, Tlv::kJoinerRouterKek, kek, sizeof(kek)) == OT_ERROR_NONE) + if (Tlv::ReadTlv(aMessage, Tlv::kJoinerRouterKek, &kek, sizeof(kek)) == OT_ERROR_NONE) { otLogInfoMeshCoP("Received kek"); @@ -232,7 +232,7 @@ exit: } } -otError JoinerRouter::DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const uint8_t *aKek) +otError JoinerRouter::DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const Kek &aKek) { otError error = OT_ERROR_NONE; Message * message = Get().New(Message::kTypeOther, 0); @@ -243,7 +243,7 @@ otError JoinerRouter::DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessage metadata.mMessageInfo = aMessageInfo; metadata.mMessageInfo.SetPeerPort(kCoapUdpPort); metadata.mSendTime = TimerMilli::GetNow() + kJoinerEntrustTxDelay; - memcpy(metadata.mKek, aKek, sizeof(metadata.mKek)); + metadata.mKek = aKek; SuccessOrExit(error = metadata.AppendTo(*message)); @@ -288,8 +288,7 @@ void JoinerRouter::SendDelayedJoinerEntrust(void) // change (i.e., retransmission). Otherweise, we wait for Joiner // Entrust Response before handling any other pending delayed // Jointer Entrust message. - VerifyOrExit(!mExpectJoinEntRsp || - memcmp(Get().GetKek(), metadata.mKek, KeyManager::kMaxKeyLength) == 0); + VerifyOrExit(!mExpectJoinEntRsp || (Get().GetKek() == metadata.mKek)); if (TimerMilli::GetNow() < metadata.mSendTime) { diff --git a/src/core/meshcop/joiner_router.hpp b/src/core/meshcop/joiner_router.hpp index 27c03bf80..7d1945e36 100644 --- a/src/core/meshcop/joiner_router.hpp +++ b/src/core/meshcop/joiner_router.hpp @@ -89,9 +89,9 @@ private: otError AppendTo(Message &aMessage) { return aMessage.Append(this, sizeof(*this)); } void ReadFrom(const Message &aMessage); - Ip6::MessageInfo mMessageInfo; // Message info of the message to send. - TimeMilli mSendTime; // Time when the message shall be sent. - uint8_t mKek[KeyManager::kMaxKeyLength]; // KEK used by MAC layer to encode this message. + Ip6::MessageInfo mMessageInfo; // Message info of the message to send. + TimeMilli mSendTime; // Time when the message shall be sent. + Kek mKek; // KEK used by MAC layer to encode this message. }; static void HandleStateChanged(Notifier::Callback &aCallback, otChangedFlags aFlags); @@ -112,7 +112,7 @@ private: static void HandleTimer(Timer &aTimer); void HandleTimer(void); - otError DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const uint8_t *aKek); + otError DelaySendingJoinerEntrust(const Ip6::MessageInfo &aMessageInfo, const Kek &aKek); void SendDelayedJoinerEntrust(void); otError SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo); Coap::Message *PrepareJoinerEntrustMessage(void); diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp index f8abc5386..0140125d9 100644 --- a/src/core/thread/key_manager.cpp +++ b/src/core/thread/key_manager.cpp @@ -218,9 +218,15 @@ void KeyManager::IncrementMleFrameCounter(void) } } +void KeyManager::SetKek(const Kek &aKek) +{ + mKek = aKek; + mKekFrameCounter = 0; +} + void KeyManager::SetKek(const uint8_t *aKek) { - memcpy(mKek, aKek, sizeof(mKek)); + memcpy(mKek.m8, aKek, sizeof(mKek)); mKekFrameCounter = 0; } diff --git a/src/core/thread/key_manager.hpp b/src/core/thread/key_manager.hpp index c8dfa99e8..1318f534b 100644 --- a/src/core/thread/key_manager.hpp +++ b/src/core/thread/key_manager.hpp @@ -137,6 +137,55 @@ public: } OT_TOOL_PACKED_END; +/** + * + * 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. +}; + /** * This class defines Thread Key Manager. * @@ -146,8 +195,7 @@ class KeyManager : public InstanceLocator public: enum { - kMaxKeyLength = 16, - kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). + kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). }; /** @@ -336,7 +384,15 @@ public: * @returns A pointer to the KEK. * */ - const uint8_t *GetKek(void) const { return mKek; } + const Kek &GetKek(void) const { return mKek; } + + /** + * This method sets the KEK. + * + * @param[in] aKek A KEK. + * + */ + void SetKek(const Kek &aKek); /** * This method sets the KEK. @@ -479,7 +535,7 @@ private: #if OPENTHREAD_MTD || OPENTHREAD_FTD Pskc mPskc; #endif - uint8_t mKek[kMaxKeyLength]; + Kek mKek; uint32_t mKekFrameCounter; uint8_t mSecurityPolicyFlags;