diff --git a/src/core/crypto/aes_ccm.hpp b/src/core/crypto/aes_ccm.hpp index f95c34aa0..b9fa3846b 100644 --- a/src/core/crypto/aes_ccm.hpp +++ b/src/core/crypto/aes_ccm.hpp @@ -142,20 +142,6 @@ public: */ void Header(const void *aHeader, uint32_t aHeaderLength); - /** - * Processes the header. - * - * @tparam ObjectType The object type. - * - * @param[in] aObject A reference to the object to add to header. - */ - template void Header(const ObjectType &aObject) - { - static_assert(!TypeTraits::IsPointer::kValue, "ObjectType must not be a pointer"); - - Header(&aObject, sizeof(ObjectType)); - } - /** * Processes the payload. * diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index bb0b9034c..1704ee7cc 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1499,11 +1499,10 @@ exit: } #endif -Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, - Message &aMessage, - const Ip6::MessageInfo &aMessageInfo, - uint16_t aCmdOffset, - const SecurityHeader &aHeader) +Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, + Message &aMessage, + uint16_t aCmdOffset, + const AesCcmAuthData &aAuthData) { // This method performs MLE message security. Based on `aMode` it // can be used to encrypt and append tag to `aMessage` or to @@ -1528,20 +1527,14 @@ Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, uint8_t tag[kMleSecurityTagSize]; Mac::ExtAddress extAddress; uint32_t keySequence; - uint16_t payloadLength = aMessage.GetLength() - aCmdOffset; - const Ip6::Address *senderAddress = &aMessageInfo.GetSockAddr(); - const Ip6::Address *receiverAddress = &aMessageInfo.GetPeerAddr(); + uint16_t payloadLength = aMessage.GetLength() - aCmdOffset; switch (aMode) { case Crypto::AesCcm::kEncrypt: - // Use the initialized values for `senderAddress`, - // `receiverAddress` and `payloadLength` break; case Crypto::AesCcm::kDecrypt: - senderAddress = &aMessageInfo.GetPeerAddr(); - receiverAddress = &aMessageInfo.GetSockAddr(); // Ensure message contains command field (uint8_t) and // tag. Then exclude the tag from payload to decrypt. VerifyOrExit(aCmdOffset + sizeof(uint8_t) + kMleSecurityTagSize <= aMessage.GetLength(), error = kErrorParse); @@ -1549,21 +1542,18 @@ Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, break; } - extAddress.SetFromIid(senderAddress->GetIid()); - nonce.InitFrom(extAddress, aHeader.GetFrameCounter(), Mac::Frame::kSecurityEncMic32); + extAddress.SetFromIid(aAuthData.mSenderAddr.GetIid()); + nonce.InitFrom(extAddress, aAuthData.mSecurityHeader.GetFrameCounter(), Mac::Frame::kSecurityEncMic32); - keySequence = aHeader.GetKeyId(); + keySequence = aAuthData.mSecurityHeader.GetKeyId(); aesCcm.SetKey(keySequence == Get().GetCurrentKeySequence() ? Get().GetCurrentMleKey() : Get().GetTemporaryMleKey(keySequence)); - aesCcm.Init(sizeof(Ip6::Address) + sizeof(Ip6::Address) + sizeof(SecurityHeader), payloadLength, - kMleSecurityTagSize, &nonce, sizeof(nonce)); + aesCcm.Init(sizeof(AesCcmAuthData), payloadLength, kMleSecurityTagSize, &nonce, sizeof(nonce)); - aesCcm.Header(*senderAddress); - aesCcm.Header(*receiverAddress); - aesCcm.Header(aHeader); + aesCcm.Header(&aAuthData, sizeof(AesCcmAuthData)); #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (aMode == Crypto::AesCcm::kDecrypt) @@ -1596,7 +1586,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn Error error = kErrorNone; RxInfo rxInfo(aMessage, aMessageInfo); uint8_t securitySuite; - SecurityHeader header; + AesCcmAuthData authData; uint32_t keySequence; uint32_t frameCounter; Mac::ExtAddress extAddr; @@ -1641,15 +1631,17 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn VerifyOrExit(!IsDisabled()); VerifyOrExit(securitySuite == k154Security, error = kErrorParse); - SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(header)); + SuccessOrExit(error = aMessage.ReadAtAndAdvanceOffset(authData.mSecurityHeader)); - VerifyOrExit(header.IsSecurityControlValid(), error = kErrorParse); + VerifyOrExit(authData.mSecurityHeader.IsSecurityControlValid(), error = kErrorParse); - keySequence = header.GetKeyId(); - frameCounter = header.GetFrameCounter(); + keySequence = authData.mSecurityHeader.GetKeyId(); + frameCounter = authData.mSecurityHeader.GetFrameCounter(); - SuccessOrExit( - error = ProcessMessageSecurity(Crypto::AesCcm::kDecrypt, aMessage, aMessageInfo, aMessage.GetOffset(), header)); + authData.mSenderAddr = aMessageInfo.GetPeerAddr(); + authData.mReceiverAddr = aMessageInfo.GetSockAddr(); + + SuccessOrExit(error = ProcessMessageSecurity(Crypto::AesCcm::kDecrypt, aMessage, aMessage.GetOffset(), authData)); IgnoreError(aMessage.ReadAtAndAdvanceOffset(command)); @@ -3901,18 +3893,20 @@ Error Mle::TxMessage::SendTo(const Ip6::Address &aDestination) if (securitySuite == k154Security) { - SecurityHeader header; + AesCcmAuthData authData; // Update the fields in the security header - IgnoreError(Read(offset, header)); - header.SetFrameCounter(Get().GetMleFrameCounter()); - header.SetKeyId(Get().GetCurrentKeySequence()); - Write(offset, header); + IgnoreError(Read(offset, authData.mSecurityHeader)); + authData.mSecurityHeader.SetFrameCounter(Get().GetMleFrameCounter()); + authData.mSecurityHeader.SetKeyId(Get().GetCurrentKeySequence()); + Write(offset, authData.mSecurityHeader); offset += sizeof(SecurityHeader); - SuccessOrExit( - error = Get().ProcessMessageSecurity(Crypto::AesCcm::kEncrypt, *this, messageInfo, offset, header)); + authData.mSenderAddr = messageInfo.GetSockAddr(); + authData.mReceiverAddr = messageInfo.GetPeerAddr(); + + SuccessOrExit(error = Get().ProcessMessageSecurity(Crypto::AesCcm::kEncrypt, *this, offset, authData)); Get().IncrementMleFrameCounter(); } diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 86bd50964..3b976a076 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1829,6 +1829,24 @@ private: uint8_t mKeyIndex; } OT_TOOL_PACKED_END; + static_assert(sizeof(SecurityHeader) == 10, "SecurityHeader is not packed"); + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + OT_TOOL_PACKED_BEGIN + struct AesCcmAuthData + { + // Represents the authenticated data used during MLE AES-CCM + // security processing. It includes the sender and receiver + // IPv6 addresses followed by the Aux Security Header. + + Ip6::Address mSenderAddr; + Ip6::Address mReceiverAddr; + SecurityHeader mSecurityHeader; + } OT_TOOL_PACKED_END; + + static_assert(sizeof(AesCcmAuthData) == 42, "AesCcmAuthData is not packed"); + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class ParentCandidate : public Parent @@ -2385,11 +2403,10 @@ private: bool HasUnregisteredAddress(void) const; bool ShouldRegisterUnicastAddrWithParent(const Ip6::Netif::UnicastAddress &aUnicastAddress) const; bool ShouldRegisterMulticastAddrsWithParent(void) const; - Error ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, - Message &aMessage, - const Ip6::MessageInfo &aMessageInfo, - uint16_t aCmdOffset, - const SecurityHeader &aHeader); + Error ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, + Message &aMessage, + uint16_t aCmdOffset, + const AesCcmAuthData &aAuthData); #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH void InformPreviousParent(void); diff --git a/tests/unit/test_aes.cpp b/tests/unit/test_aes.cpp index f82f28aa4..385cd39a1 100644 --- a/tests/unit/test_aes.cpp +++ b/tests/unit/test_aes.cpp @@ -226,7 +226,7 @@ void TestInPlaceAesCcmProcessing(void) // Encrypt in place aesCcm.Init(kHeaderLength, msgLength - kHeaderLength, kTagLength, kNonce, sizeof(kNonce)); - aesCcm.Header(header); + aesCcm.Header(&header, sizeof(header)); aesCcm.Payload(*message, kHeaderLength, msgLength - kHeaderLength, Crypto::AesCcm::kEncrypt); // Append the tag @@ -237,7 +237,7 @@ void TestInPlaceAesCcmProcessing(void) // Decrypt in place aesCcm.Init(kHeaderLength, msgLength - kHeaderLength, kTagLength, kNonce, sizeof(kNonce)); - aesCcm.Header(header); + aesCcm.Header(&header, sizeof(header)); aesCcm.Payload(*message, kHeaderLength, msgLength - kHeaderLength, Crypto::AesCcm::kDecrypt); // Check the tag against what is the message