diff --git a/src/core/api/crypto_api.cpp b/src/core/api/crypto_api.cpp index df2ea8dab..9582b8aa3 100644 --- a/src/core/api/crypto_api.cpp +++ b/src/core/api/crypto_api.cpp @@ -69,7 +69,7 @@ void otCryptoAesCcm( assert((aKey != NULL) && (aNonce != NULL) && (aPlainText != NULL) && (aCipherText != NULL) && (aTag != NULL)); SuccessOrExit(aesCcm.SetKey(aKey, aKeyLength)); - aesCcm.Init(aHeaderLength, aLength, aTagLength, aNonce, aNonceLength); + SuccessOrExit(aesCcm.Init(aHeaderLength, aLength, aTagLength, aNonce, aNonceLength)); if (aHeaderLength != 0) { diff --git a/src/core/crypto/aes_ccm.cpp b/src/core/crypto/aes_ccm.cpp index d5271fea9..f85cc9a71 100644 --- a/src/core/crypto/aes_ccm.cpp +++ b/src/core/crypto/aes_ccm.cpp @@ -47,10 +47,11 @@ otError AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength) return OT_ERROR_NONE; } -void AesCcm::Init(uint32_t aHeaderLength, uint32_t aPlainTextLength, uint8_t aTagLength, - const void *aNonce, uint8_t aNonceLength) +otError AesCcm::Init(uint32_t aHeaderLength, uint32_t aPlainTextLength, uint8_t aTagLength, + const void *aNonce, uint8_t aNonceLength) { const uint8_t *nonceBytes = reinterpret_cast(aNonce); + otError error = OT_ERROR_NONE; uint8_t blockLength = 0; uint32_t len; uint8_t L; @@ -63,6 +64,10 @@ void AesCcm::Init(uint32_t aHeaderLength, uint32_t aPlainTextLength, uint8_t aTa { aTagLength = sizeof(mBlock); } + else if (aTagLength < kTagLengthMin) + { + ExitNow(error = OT_ERROR_INVALID_ARGS); + } L = 0; @@ -159,6 +164,9 @@ void AesCcm::Init(uint32_t aHeaderLength, uint32_t aPlainTextLength, uint8_t aTa mBlockLength = blockLength; mCtrLength = sizeof(mCtrPad); mTagLength = aTagLength; + +exit: + return error; } void AesCcm::Header(const void *aHeader, uint32_t aHeaderLength) diff --git a/src/core/crypto/aes_ccm.hpp b/src/core/crypto/aes_ccm.hpp index 444c2b2ff..6c31fac59 100644 --- a/src/core/crypto/aes_ccm.hpp +++ b/src/core/crypto/aes_ccm.hpp @@ -75,9 +75,12 @@ public: * @param[in] aNonce A pointer to the nonce. * @param[in] aNonceLength Length of nonce in bytes. * + * @retval OT_ERROR_NONE Initialization was successful. + * @retval OT_ERROR_INVALID_ARGS Initialization failed. + * */ - void Init(uint32_t aHeaderLength, uint32_t aPlainTextLength, uint8_t aTagLength, - const void *aNonce, uint8_t aNonceLength); + otError Init(uint32_t aHeaderLength, uint32_t aPlainTextLength, uint8_t aTagLength, + const void *aNonce, uint8_t aNonceLength); /** * This method processes the header. @@ -109,6 +112,11 @@ public: void Finalize(void *aTag, uint8_t *aTagLength); private: + enum + { + kTagLengthMin = 4, + }; + AesEcb mEcb; uint8_t mBlock[AesEcb::kBlockSize]; uint8_t mCtr[AesEcb::kBlockSize]; diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index d259ac596..b9860a178 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -693,6 +693,7 @@ void Mac::ProcessTransmitSecurity(Frame &aFrame) Crypto::AesCcm aesCcm; const uint8_t *key = NULL; const ExtAddress *extAddress = NULL; + otError error; if (aFrame.GetSecurityEnabled() == false) { @@ -759,7 +760,8 @@ void Mac::ProcessTransmitSecurity(Frame &aFrame) aesCcm.SetKey(key, 16); tagLength = aFrame.GetFooterLength() - Frame::kFcsSize; - aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)); + error = aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)); + assert(error == OT_ERROR_NONE); aesCcm.Header(aFrame.GetHeader(), aFrame.GetHeaderLength()); aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), true); @@ -1429,7 +1431,10 @@ otError Mac::ProcessReceiveSecurity(Frame &aFrame, const Address &aSrcAddr, Neig tagLength = aFrame.GetFooterLength() - Frame::kFcsSize; aesCcm.SetKey(macKey, 16); - aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)); + + error = aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce)); + VerifyOrExit(error == OT_ERROR_NONE, error = OT_ERROR_SECURITY); + aesCcm.Header(aFrame.GetHeader(), aFrame.GetHeaderLength()); aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), false); aesCcm.Finalize(tag, &tagLength); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 4361762ef..b4f8c21d0 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1906,8 +1906,9 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination) nonce); aesCcm.SetKey(netif.GetKeyManager().GetCurrentMleKey(), 16); - aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1), - sizeof(tag), nonce, sizeof(nonce)); + error = aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1), + sizeof(tag), nonce, sizeof(nonce)); + assert(error == OT_ERROR_NONE); aesCcm.Header(&mLinkLocal64.GetAddress(), sizeof(mLinkLocal64.GetAddress())); aesCcm.Header(&aDestination, sizeof(aDestination)); @@ -2051,8 +2052,11 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn GenerateNonce(macAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce); aesCcm.SetKey(mleKey, 16); - aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) + header.GetHeaderLength(), - aMessage.GetLength() - aMessage.GetOffset(), sizeof(messageTag), nonce, sizeof(nonce)); + SuccessOrExit(aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) + + header.GetHeaderLength(), + aMessage.GetLength() - aMessage.GetOffset(), + sizeof(messageTag), nonce, sizeof(nonce))); + aesCcm.Header(&aMessageInfo.GetPeerAddr(), sizeof(aMessageInfo.GetPeerAddr())); aesCcm.Header(&aMessageInfo.GetSockAddr(), sizeof(aMessageInfo.GetSockAddr())); aesCcm.Header(header.GetBytes() + 1, header.GetHeaderLength()); diff --git a/tests/unit/test_aes.cpp b/tests/unit/test_aes.cpp index a9f4d6f76..c9222fec9 100644 --- a/tests/unit/test_aes.cpp +++ b/tests/unit/test_aes.cpp @@ -106,70 +106,6 @@ void TestMacBeaconFrame(void) testFreeInstance(instance); } -/** - * Verifies test vectors from IEEE 802.15.4-2006 Annex C Section C.2.1 - */ -void TestMacDataFrame() -{ - uint8_t key[] = - { - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - }; - - uint8_t test[] = - { - 0x69, 0xDC, 0x84, 0x21, 0x43, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x48, 0xDE, 0xAC, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x48, 0xDE, 0xAC, 0x04, 0x05, 0x00, - 0x00, 0x00, 0x61, 0x62, 0x63, 0x64 - }; - - uint8_t encrypted[] = - { - 0x69, 0xDC, 0x84, 0x21, 0x43, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x48, 0xDE, 0xAC, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x48, 0xDE, 0xAC, 0x04, 0x05, 0x00, - 0x00, 0x00, 0xD4, 0x3E, 0x02, 0x2B - }; - - uint8_t decrypted[] = - { - 0x69, 0xDC, 0x84, 0x21, 0x43, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x48, 0xDE, 0xAC, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x48, 0xDE, 0xAC, 0x04, 0x05, 0x00, - 0x00, 0x00, 0x61, 0x62, 0x63, 0x64 - }; - - ot::Crypto::AesCcm aesCcm; - uint32_t headerLength = sizeof(test) - 4; - uint32_t payloadLength = 4; - uint8_t tagLength = 0; - - uint8_t nonce[] = - { - 0xAC, 0xDE, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x05, 0x04, - }; - - aesCcm.SetKey(key, sizeof(key)); - aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce)); - aesCcm.Header(test, headerLength); - aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, true); - aesCcm.Finalize(test + headerLength + payloadLength, &tagLength); - - VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, - "TestMacDataFrame encrypt failed"); - - aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce)); - aesCcm.Header(test, headerLength); - aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, false); - aesCcm.Finalize(test + headerLength + payloadLength, &tagLength); - - VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, - "TestMacDataFrame decrypt failed"); -} - /** * Verifies test vectors from IEEE 802.15.4-2006 Annex C Section C.2.3 */ @@ -239,7 +175,6 @@ void TestMacCommandFrame() int main(void) { TestMacBeaconFrame(); - TestMacDataFrame(); TestMacCommandFrame(); printf("All tests passed\n"); return 0; diff --git a/tests/unit/test_windows.cpp b/tests/unit/test_windows.cpp index 8bc151199..cfd002387 100644 --- a/tests/unit/test_windows.cpp +++ b/tests/unit/test_windows.cpp @@ -37,7 +37,6 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; // test_aes.cpp void TestMacBeaconFrame(); -void TestMacDataFrame(); void TestMacCommandFrame(); // test_hmac_sha256.cpp @@ -133,7 +132,6 @@ namespace ot // test_aes.cpp TEST_METHOD(TestMacBeaconFrame) { ::TestMacBeaconFrame(); } - TEST_METHOD(TestMacDataFrame) { ::TestMacDataFrame(); } TEST_METHOD(TestMacCommandFrame) { ::TestMacCommandFrame(); } // test_hmac_sha256.cpp