diff --git a/src/core/crypto/aes_ccm.cpp b/src/core/crypto/aes_ccm.cpp index a160749ea..e940cf3d5 100644 --- a/src/core/crypto/aes_ccm.cpp +++ b/src/core/crypto/aes_ccm.cpp @@ -40,6 +40,11 @@ namespace ot { namespace Crypto { +//--------------------------------------------------------------------------------------------------------------------- +// AesCcm + +static_assert(sizeof(AesCcm::Nonce) == 13, "Nonce format is not valid"); + void AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength) { Key cryptoKey; @@ -283,18 +288,14 @@ void AesCcm::Finalize(void *aTag) } } -void AesCcm::GenerateNonce(const Mac::ExtAddress &aAddress, - uint32_t aFrameCounter, - uint8_t aSecurityLevel, - uint8_t *aNonce) +//--------------------------------------------------------------------------------------------------------------------- +// AesCcm::Nonce + +void AesCcm::Nonce::InitFrom(const Mac::ExtAddress &aExtAddress, uint32_t aFrameCounter, uint8_t aSecurityLevel) { - memcpy(aNonce, aAddress.m8, sizeof(Mac::ExtAddress)); - aNonce += sizeof(Mac::ExtAddress); - - BigEndian::WriteUint32(aFrameCounter, aNonce); - aNonce += sizeof(uint32_t); - - aNonce[0] = aSecurityLevel; + mExtAddress = aExtAddress; + mFrameCounter = BigEndian::HostSwap32(aFrameCounter); + mSecurityLevel = aSecurityLevel; } } // namespace Crypto diff --git a/src/core/crypto/aes_ccm.hpp b/src/core/crypto/aes_ccm.hpp index 675ac03f5..f95c34aa0 100644 --- a/src/core/crypto/aes_ccm.hpp +++ b/src/core/crypto/aes_ccm.hpp @@ -63,7 +63,6 @@ class AesCcm public: static constexpr uint8_t kMinTagLength = 4; ///< Minimum tag length (in bytes). static constexpr uint8_t kMaxTagLength = AesEcb::kBlockSize; ///< Maximum tag length (in bytes). - static constexpr uint8_t kNonceSize = 13; ///< Size of IEEE 802.15.4 Nonce (in bytes). /** * Type represent the encryption vs decryption mode. @@ -74,6 +73,30 @@ public: kDecrypt, // Decryption mode. }; + /** + * Represents an IEEE 802.15.4 nonce byte sequence. + */ + OT_TOOL_PACKED_BEGIN + class Nonce : public Clearable + { + public: + /** + * Initializes the nonce from a given extended address, frame counter, and security level. + * + * @param[in] aExtAddress An extended address. + * @param[in] aFrameCounter A frame counter. + * @param[in] aSecurityLevel A security level. + */ + void InitFrom(const Mac::ExtAddress &aExtAddress, uint32_t aFrameCounter, uint8_t aSecurityLevel); + + private: + Mac::ExtAddress mExtAddress; + uint32_t mFrameCounter; + uint8_t mSecurityLevel; + } OT_TOOL_PACKED_END; + + static_assert(sizeof(Nonce) == 13, "Nonce format is not valid"); + /** * Sets the key. * @@ -174,19 +197,6 @@ public: */ void Finalize(void *aTag); - /** - * Generates IEEE 802.15.4 nonce byte sequence. - * - * @param[in] aAddress An extended address. - * @param[in] aFrameCounter A frame counter. - * @param[in] aSecurityLevel A security level. - * @param[out] aNonce A buffer (with `kNonceSize` bytes) to place the generated nonce. - */ - static void GenerateNonce(const Mac::ExtAddress &aAddress, - uint32_t aFrameCounter, - uint8_t aSecurityLevel, - uint8_t *aNonce); - private: AesEcb mEcb; uint8_t mBlock[AesEcb::kBlockSize]; diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index 09d85ce06..a06ef449b 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -1375,23 +1375,23 @@ void TxFrame::CopyFrom(const TxFrame &aFromFrame) void TxFrame::ProcessTransmitAesCcm(const ExtAddress &aExtAddress) { #if OPENTHREAD_FTD || OPENTHREAD_MTD || OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE - uint32_t frameCounter = 0; - uint8_t securityLevel; - uint8_t nonce[Crypto::AesCcm::kNonceSize]; - uint8_t tagLength; - Crypto::AesCcm aesCcm; + uint32_t frameCounter = 0; + uint8_t securityLevel; + uint8_t tagLength; + Crypto::AesCcm aesCcm; + Crypto::AesCcm::Nonce nonce; VerifyOrExit(GetSecurityEnabled()); SuccessOrExit(GetSecurityLevel(securityLevel)); SuccessOrExit(GetFrameCounter(frameCounter)); - Crypto::AesCcm::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce); + nonce.InitFrom(aExtAddress, frameCounter, securityLevel); aesCcm.SetKey(GetAesKey()); tagLength = GetFooterLength() - GetFcsSize(); - aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce)); + aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, &nonce, sizeof(nonce)); aesCcm.Header(GetHeader(), GetHeaderLength()); aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), Crypto::AesCcm::kEncrypt); aesCcm.Finalize(GetFooter()); @@ -1408,23 +1408,23 @@ exit: #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_MAC_SOFTWARE_RETX_SECURITY_ENABLE void TxFrame::DecryptTransmitAesCcm(const ExtAddress &aExtAddress) { - uint32_t frameCounter = 0; - uint8_t securityLevel; - uint8_t nonce[Crypto::AesCcm::kNonceSize]; - uint8_t tagLength; - Crypto::AesCcm aesCcm; + uint32_t frameCounter = 0; + uint8_t securityLevel; + uint8_t tagLength; + Crypto::AesCcm aesCcm; + Crypto::AesCcm::Nonce nonce; VerifyOrExit(GetSecurityEnabled() && IsSecurityProcessed()); SuccessOrExit(GetSecurityLevel(securityLevel)); SuccessOrExit(GetFrameCounter(frameCounter)); - Crypto::AesCcm::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce); + nonce.InitFrom(aExtAddress, frameCounter, securityLevel); aesCcm.SetKey(GetAesKey()); tagLength = GetFooterLength() - GetFcsSize(); - aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce)); + aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, &nonce, sizeof(nonce)); aesCcm.Header(GetHeader(), GetHeaderLength()); aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), Crypto::AesCcm::kDecrypt); // Note: We skip aesCcm.Finalize() checking because we are only decrypting back to plaintext, @@ -1624,25 +1624,25 @@ exit: Error RxFrame::ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMaterial &aMacKey) { #if OPENTHREAD_FTD || OPENTHREAD_MTD - Error error = kErrorSecurity; - uint32_t frameCounter = 0; - uint8_t securityLevel; - uint8_t nonce[Crypto::AesCcm::kNonceSize]; - uint8_t tag[kMaxMicSize]; - uint8_t tagLength; - Crypto::AesCcm aesCcm; + Error error = kErrorSecurity; + uint32_t frameCounter = 0; + uint8_t securityLevel; + uint8_t tag[kMaxMicSize]; + uint8_t tagLength; + Crypto::AesCcm aesCcm; + Crypto::AesCcm::Nonce nonce; VerifyOrExit(GetSecurityEnabled(), error = kErrorNone); SuccessOrExit(GetSecurityLevel(securityLevel)); SuccessOrExit(GetFrameCounter(frameCounter)); - Crypto::AesCcm::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce); + nonce.InitFrom(aExtAddress, frameCounter, securityLevel); aesCcm.SetKey(aMacKey); tagLength = GetFooterLength() - GetFcsSize(); - aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce)); + aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, &nonce, sizeof(nonce)); aesCcm.Header(GetHeader(), GetHeaderLength()); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), Crypto::AesCcm::kDecrypt); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 6a9bb7637..19f1b590f 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1520,15 +1520,15 @@ Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, // `kErrorNone` message encrypted and tag appended to message. // `kErrorNoBufs` could not grow the message to append the tag. - Error error = kErrorNone; - Crypto::AesCcm aesCcm; - uint8_t nonce[Crypto::AesCcm::kNonceSize]; - 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(); + Error error = kErrorNone; + Crypto::AesCcm aesCcm; + Crypto::AesCcm::Nonce nonce; + 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(); switch (aMode) { @@ -1548,7 +1548,7 @@ Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, } extAddress.SetFromIid(senderAddress->GetIid()); - Crypto::AesCcm::GenerateNonce(extAddress, aHeader.GetFrameCounter(), Mac::Frame::kSecurityEncMic32, nonce); + nonce.InitFrom(extAddress, aHeader.GetFrameCounter(), Mac::Frame::kSecurityEncMic32); keySequence = aHeader.GetKeyId(); @@ -1557,7 +1557,7 @@ Error Mle::ProcessMessageSecurity(Crypto::AesCcm::Mode aMode, : Get().GetTemporaryMleKey(keySequence)); aesCcm.Init(sizeof(Ip6::Address) + sizeof(Ip6::Address) + sizeof(SecurityHeader), payloadLength, - kMleSecurityTagSize, nonce, sizeof(nonce)); + kMleSecurityTagSize, &nonce, sizeof(nonce)); aesCcm.Header(*senderAddress); aesCcm.Header(*receiverAddress);