[aes-ccm] add lower-bound check for tag length (#2008)

This commit is contained in:
Jonathan Hui
2017-07-18 08:32:36 -07:00
committed by GitHub
parent 5ba896266c
commit 702ec2551f
7 changed files with 36 additions and 78 deletions
+1 -1
View File
@@ -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)
{
+10 -2
View File
@@ -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)
+10 -2
View File
@@ -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];
+7 -2
View File
@@ -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);
+8 -4
View File
@@ -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());
-65
View File
@@ -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;
-2
View File
@@ -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