mirror of
https://github.com/espressif/openthread.git
synced 2026-09-19 23:47:33 +00:00
[aes-ccm] add lower-bound check for tag length (#2008)
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<const uint8_t *>(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)
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user