[aes-ccm] misc enhancements (#5015)

- add a new enumeration type `Mode` to indicate the encryption vs.
  decryption mode in `AesCcm::Payload()` method.
- add `GetTagLength()` method and simplify `Finalize()`.
- change `AesCcm::Init()` to assert on bad tag length input param
  instead of returning `OT_ERROR_INVALID_ARGS`.
- reorder AesCcm member variable to help with alignments
- use CHAR_BIT
- remove check of tag length from Finalize
- use `memcpy`/`memset` to copy/clear buffers
This commit is contained in:
Abtin Keshavarzian
2020-05-28 22:02:22 -07:00
committed by Jonathan Hui
parent 72717f5178
commit f640774684
7 changed files with 87 additions and 120 deletions
+4 -10
View File
@@ -72,13 +72,12 @@ void otCryptoAesCcm(const uint8_t *aKey,
bool aEncrypt, bool aEncrypt,
void * aTag) void * aTag)
{ {
AesCcm aesCcm; AesCcm aesCcm;
uint8_t tagLength;
OT_ASSERT((aKey != NULL) && (aNonce != NULL) && (aPlainText != NULL) && (aCipherText != NULL) && (aTag != NULL)); OT_ASSERT((aKey != NULL) && (aNonce != NULL) && (aPlainText != NULL) && (aCipherText != NULL) && (aTag != NULL));
aesCcm.SetKey(aKey, aKeyLength); aesCcm.SetKey(aKey, aKeyLength);
SuccessOrExit(aesCcm.Init(aHeaderLength, aLength, aTagLength, aNonce, aNonceLength)); aesCcm.Init(aHeaderLength, aLength, aTagLength, aNonce, aNonceLength);
if (aHeaderLength != 0) if (aHeaderLength != 0)
{ {
@@ -86,13 +85,8 @@ void otCryptoAesCcm(const uint8_t *aKey,
aesCcm.Header(aHeader, aHeaderLength); aesCcm.Header(aHeader, aHeaderLength);
} }
aesCcm.Payload(aPlainText, aCipherText, aLength, aEncrypt); aesCcm.Payload(aPlainText, aCipherText, aLength, aEncrypt ? AesCcm::kEncrypt : AesCcm::kDecrypt);
aesCcm.Finalize(aTag, &tagLength); aesCcm.Finalize(aTag);
OT_ASSERT(aTagLength == tagLength);
exit:
return;
} }
#if OPENTHREAD_CONFIG_ECDSA_ENABLE #if OPENTHREAD_CONFIG_ECDSA_ENABLE
+20 -53
View File
@@ -33,6 +33,8 @@
#include "aes_ccm.hpp" #include "aes_ccm.hpp"
#include <limits.h>
#include "common/code_utils.hpp" #include "common/code_utils.hpp"
#include "common/debug.hpp" #include "common/debug.hpp"
#include "common/encoding.hpp" #include "common/encoding.hpp"
@@ -42,7 +44,7 @@ namespace Crypto {
void AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength) void AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength)
{ {
mEcb.SetKey(aKey, 8 * aKeyLength); mEcb.SetKey(aKey, CHAR_BIT * aKeyLength);
} }
void AesCcm::SetKey(const Mac::Key &aMacKey) void AesCcm::SetKey(const Mac::Key &aMacKey)
@@ -50,30 +52,20 @@ void AesCcm::SetKey(const Mac::Key &aMacKey)
SetKey(aMacKey.GetKey(), Mac::Key::kSize); SetKey(aMacKey.GetKey(), Mac::Key::kSize);
} }
otError AesCcm::Init(uint32_t aHeaderLength, void AesCcm::Init(uint32_t aHeaderLength,
uint32_t aPlainTextLength, uint32_t aPlainTextLength,
uint8_t aTagLength, uint8_t aTagLength,
const void *aNonce, const void *aNonce,
uint8_t aNonceLength) uint8_t aNonceLength)
{ {
const uint8_t *nonceBytes = reinterpret_cast<const uint8_t *>(aNonce); const uint8_t *nonceBytes = reinterpret_cast<const uint8_t *>(aNonce);
otError error = OT_ERROR_NONE;
uint8_t blockLength = 0; uint8_t blockLength = 0;
uint32_t len; uint32_t len;
uint8_t L; uint8_t L;
uint8_t i; uint8_t i;
// aTagLength must be even // Tag length must be even and within [kMinTagLength, kMaxTagLength]
aTagLength &= ~1; OT_ASSERT(((aTagLength & 0x1) == 0) && (kMinTagLength <= aTagLength) && (aTagLength <= kMaxTagLength));
if (aTagLength > sizeof(mBlock))
{
aTagLength = sizeof(mBlock);
}
else if (aTagLength < kTagLengthMin)
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
L = 0; L = 0;
@@ -111,10 +103,7 @@ otError AesCcm::Init(uint32_t aHeaderLength,
static_cast<uint8_t>(L - 1)); static_cast<uint8_t>(L - 1));
// write nonce // write nonce
for (i = 0; i < aNonceLength; i++) memcpy(&mBlock[1], nonceBytes, aNonceLength);
{
mBlock[1 + i] = nonceBytes[i];
}
// write len // write len
len = aPlainTextLength; len = aPlainTextLength;
@@ -150,16 +139,8 @@ otError AesCcm::Init(uint32_t aHeaderLength,
// init counter // init counter
mCtr[0] = L - 1; mCtr[0] = L - 1;
memcpy(&mCtr[1], nonceBytes, aNonceLength);
for (i = 0; i < aNonceLength; i++) memset(&mCtr[aNonceLength + 1], 0, sizeof(mCtr) - aNonceLength - 1);
{
mCtr[1 + i] = nonceBytes[i];
}
for (i = i + 1; i < sizeof(mCtr); i++)
{
mCtr[i] = 0;
}
mNonceLength = aNonceLength; mNonceLength = aNonceLength;
mHeaderLength = aHeaderLength; mHeaderLength = aHeaderLength;
@@ -169,9 +150,6 @@ otError AesCcm::Init(uint32_t aHeaderLength,
mBlockLength = blockLength; mBlockLength = blockLength;
mCtrLength = sizeof(mCtrPad); mCtrLength = sizeof(mCtrPad);
mTagLength = aTagLength; mTagLength = aTagLength;
exit:
return error;
} }
void AesCcm::Header(const void *aHeader, uint32_t aHeaderLength) void AesCcm::Header(const void *aHeader, uint32_t aHeaderLength)
@@ -206,7 +184,7 @@ void AesCcm::Header(const void *aHeader, uint32_t aHeaderLength)
} }
} }
void AesCcm::Payload(void *aPlainText, void *aCipherText, uint32_t aLength, bool aEncrypt) void AesCcm::Payload(void *aPlainText, void *aCipherText, uint32_t aLength, Mode aMode)
{ {
uint8_t *plaintextBytes = reinterpret_cast<uint8_t *>(aPlainText); uint8_t *plaintextBytes = reinterpret_cast<uint8_t *>(aPlainText);
uint8_t *ciphertextBytes = reinterpret_cast<uint8_t *>(aCipherText); uint8_t *ciphertextBytes = reinterpret_cast<uint8_t *>(aCipherText);
@@ -230,7 +208,7 @@ void AesCcm::Payload(void *aPlainText, void *aCipherText, uint32_t aLength, bool
mCtrLength = 0; mCtrLength = 0;
} }
if (aEncrypt) if (aMode == kEncrypt)
{ {
byte = plaintextBytes[i]; byte = plaintextBytes[i];
ciphertextBytes[i] = byte ^ mCtrPad[mCtrLength++]; ciphertextBytes[i] = byte ^ mCtrPad[mCtrLength++];
@@ -260,32 +238,21 @@ void AesCcm::Payload(void *aPlainText, void *aCipherText, uint32_t aLength, bool
} }
// reset counter // reset counter
for (uint8_t i = mNonceLength + 1; i < sizeof(mCtr); i++) memset(&mCtr[mNonceLength + 1], 0, sizeof(mCtr) - mNonceLength - 1);
{
mCtr[i] = 0;
}
} }
} }
void AesCcm::Finalize(void *aTag, uint8_t *aTagLength) void AesCcm::Finalize(void *aTag)
{ {
uint8_t *tagBytes = reinterpret_cast<uint8_t *>(aTag); uint8_t *tagBytes = reinterpret_cast<uint8_t *>(aTag);
OT_ASSERT(mPlainTextCur == mPlainTextLength); OT_ASSERT(mPlainTextCur == mPlainTextLength);
if (mTagLength > 0) mEcb.Encrypt(mCtr, mCtrPad);
{
mEcb.Encrypt(mCtr, mCtrPad);
for (int i = 0; i < mTagLength; i++) for (int i = 0; i < mTagLength; i++)
{
tagBytes[i] = mBlock[i] ^ mCtrPad[i];
}
}
if (aTagLength)
{ {
*aTagLength = mTagLength; tagBytes[i] = mBlock[i] ^ mCtrPad[i];
} }
} }
+32 -21
View File
@@ -62,7 +62,19 @@ class AesCcm
public: public:
enum enum
{ {
kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). kMinTagLength = 4, ///< Minimum tag length (in bytes).
kMaxTagLength = AesEcb::kBlockSize, ///< Maximum tag length (in bytes).
kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (in bytes).
};
/**
* This enumeration type represent the encryption vs decryption mode.
*
*/
enum Mode
{
kEncrypt, // Encryption mode.
kDecrypt, // Decryption mode.
}; };
/** /**
@@ -87,19 +99,16 @@ public:
* *
* @param[in] aHeaderLength Length of header in bytes. * @param[in] aHeaderLength Length of header in bytes.
* @param[in] aPlainTextLength Length of plaintext in bytes. * @param[in] aPlainTextLength Length of plaintext in bytes.
* @param[in] aTagLength Length of tag in bytes. * @param[in] aTagLength Length of tag in bytes (must be even and in `[kMinTagLength, kMaxTagLength]`).
* @param[in] aNonce A pointer to the nonce. * @param[in] aNonce A pointer to the nonce.
* @param[in] aNonceLength Length of nonce in bytes. * @param[in] aNonceLength Length of nonce in bytes.
* *
* @retval OT_ERROR_NONE Initialization was successful.
* @retval OT_ERROR_INVALID_ARGS Initialization failed.
*
*/ */
otError Init(uint32_t aHeaderLength, void Init(uint32_t aHeaderLength,
uint32_t aPlainTextLength, uint32_t aPlainTextLength,
uint8_t aTagLength, uint8_t aTagLength,
const void *aNonce, const void *aNonce,
uint8_t aNonceLength); uint8_t aNonceLength);
/** /**
* This method processes the header. * This method processes the header.
@@ -116,19 +125,26 @@ public:
* @param[inout] aPlainText A pointer to the plaintext. * @param[inout] aPlainText A pointer to the plaintext.
* @param[inout] aCipherText A pointer to the ciphertext. * @param[inout] aCipherText A pointer to the ciphertext.
* @param[in] aLength Payload length in bytes. * @param[in] aLength Payload length in bytes.
* @param[in] aEncrypt TRUE on encrypt and FALSE on decrypt. * @param[in] aMode Mode to indicate whether to encrypt (`kEncrypt`) or decrypt (`kDecrypt`).
* *
*/ */
void Payload(void *aPlainText, void *aCipherText, uint32_t aLength, bool aEncrypt); void Payload(void *aPlainText, void *aCipherText, uint32_t aLength, Mode aMode);
/**
* This method returns the tag length in bytes.
*
* @returns The tag length in bytes.
*
*/
uint8_t GetTagLength(void) const { return mTagLength; }
/** /**
* This method generates the tag. * This method generates the tag.
* *
* @param[out] aTag A pointer to the tag. * @param[out] aTag A pointer to the tag (must have `GetTagLength()` bytes).
* @param[out] aTagLength Length of the tag in bytes.
* *
*/ */
void Finalize(void *aTag, uint8_t *aTagLength); void Finalize(void *aTag);
/** /**
* This static method generates IEEE 802.15.4 nonce byte sequence. * This static method generates IEEE 802.15.4 nonce byte sequence.
@@ -145,22 +161,17 @@ public:
uint8_t * aNonce); uint8_t * aNonce);
private: private:
enum
{
kTagLengthMin = 4,
};
AesEcb mEcb; AesEcb mEcb;
uint8_t mBlock[AesEcb::kBlockSize]; uint8_t mBlock[AesEcb::kBlockSize];
uint8_t mCtr[AesEcb::kBlockSize]; uint8_t mCtr[AesEcb::kBlockSize];
uint8_t mCtrPad[AesEcb::kBlockSize]; uint8_t mCtrPad[AesEcb::kBlockSize];
uint8_t mNonceLength;
uint32_t mHeaderLength; uint32_t mHeaderLength;
uint32_t mHeaderCur; uint32_t mHeaderCur;
uint32_t mPlainTextLength; uint32_t mPlainTextLength;
uint32_t mPlainTextCur; uint32_t mPlainTextCur;
uint16_t mBlockLength; uint16_t mBlockLength;
uint16_t mCtrLength; uint16_t mCtrLength;
uint8_t mNonceLength;
uint8_t mTagLength; uint8_t mTagLength;
}; };
+5 -5
View File
@@ -1518,17 +1518,17 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne
aesCcm.SetKey(*macKey); aesCcm.SetKey(*macKey);
SuccessOrExit(aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce))); aesCcm.Init(aFrame.GetHeaderLength(), aFrame.GetPayloadLength(), tagLength, nonce, sizeof(nonce));
aesCcm.Header(aFrame.GetHeader(), aFrame.GetHeaderLength()); aesCcm.Header(aFrame.GetHeader(), aFrame.GetHeaderLength());
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), false); aesCcm.Payload(aFrame.GetPayload(), aFrame.GetPayload(), aFrame.GetPayloadLength(), Crypto::AesCcm::kDecrypt);
#else #else
// For fuzz tests, execute AES but do not alter the payload // For fuzz tests, execute AES but do not alter the payload
uint8_t fuzz[OT_RADIO_FRAME_MAX_SIZE]; uint8_t fuzz[OT_RADIO_FRAME_MAX_SIZE];
aesCcm.Payload(fuzz, aFrame.GetPayload(), aFrame.GetPayloadLength(), false); aesCcm.Payload(fuzz, aFrame.GetPayload(), aFrame.GetPayloadLength(), Crypto::AesCcm::kDecrypt);
#endif #endif
aesCcm.Finalize(tag, &tagLength); aesCcm.Finalize(tag);
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
VerifyOrExit(memcmp(tag, aFrame.GetFooter(), tagLength) == 0, OT_NOOP); VerifyOrExit(memcmp(tag, aFrame.GetFooter(), tagLength) == 0, OT_NOOP);
+3 -5
View File
@@ -1052,12 +1052,10 @@ void TxFrame::ProcessTransmitAesCcm(const ExtAddress &aExtAddress)
aesCcm.SetKey(GetAesKey()); aesCcm.SetKey(GetAesKey());
tagLength = GetFooterLength() - Frame::kFcsSize; tagLength = GetFooterLength() - Frame::kFcsSize;
error = aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce)); aesCcm.Init(GetHeaderLength(), GetPayloadLength(), tagLength, nonce, sizeof(nonce));
OT_ASSERT(error == OT_ERROR_NONE);
aesCcm.Header(GetHeader(), GetHeaderLength()); aesCcm.Header(GetHeader(), GetHeaderLength());
aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), true); aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), Crypto::AesCcm::kEncrypt);
aesCcm.Finalize(GetFooter(), &tagLength); aesCcm.Finalize(GetFooter());
SetIsSecurityProcessed(true); SetIsSecurityProcessed(true);
+9 -16
View File
@@ -2521,7 +2521,6 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination)
uint32_t keySequence; uint32_t keySequence;
uint8_t nonce[Crypto::AesCcm::kNonceSize]; uint8_t nonce[Crypto::AesCcm::kNonceSize];
uint8_t tag[4]; uint8_t tag[4];
uint8_t tagLength;
Crypto::AesCcm aesCcm; Crypto::AesCcm aesCcm;
uint8_t buf[64]; uint8_t buf[64];
uint16_t length; uint16_t length;
@@ -2542,9 +2541,8 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination)
Mac::Frame::kSecEncMic32, nonce); Mac::Frame::kSecEncMic32, nonce);
aesCcm.SetKey(Get<KeyManager>().GetCurrentMleKey()); aesCcm.SetKey(Get<KeyManager>().GetCurrentMleKey());
error = aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1), aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1), sizeof(tag),
sizeof(tag), nonce, sizeof(nonce)); nonce, sizeof(nonce));
OT_ASSERT(error == OT_ERROR_NONE);
aesCcm.Header(&mLinkLocal64.GetAddress(), sizeof(mLinkLocal64.GetAddress())); aesCcm.Header(&mLinkLocal64.GetAddress(), sizeof(mLinkLocal64.GetAddress()));
aesCcm.Header(&aDestination, sizeof(aDestination)); aesCcm.Header(&aDestination, sizeof(aDestination));
@@ -2555,14 +2553,13 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination)
while (aMessage.GetOffset() < aMessage.GetLength()) while (aMessage.GetOffset() < aMessage.GetLength())
{ {
length = aMessage.Read(aMessage.GetOffset(), sizeof(buf), buf); length = aMessage.Read(aMessage.GetOffset(), sizeof(buf), buf);
aesCcm.Payload(buf, buf, length, true); aesCcm.Payload(buf, buf, length, Crypto::AesCcm::kEncrypt);
aMessage.Write(aMessage.GetOffset(), length, buf); aMessage.Write(aMessage.GetOffset(), length, buf);
aMessage.MoveOffset(length); aMessage.MoveOffset(length);
} }
tagLength = sizeof(tag); aesCcm.Finalize(tag);
aesCcm.Finalize(tag, &tagLength); SuccessOrExit(error = aMessage.Append(tag, sizeof(tag)));
SuccessOrExit(error = aMessage.Append(tag, tagLength));
Get<KeyManager>().IncrementMleFrameCounter(); Get<KeyManager>().IncrementMleFrameCounter();
} }
@@ -2616,7 +2613,6 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
uint8_t buf[64]; uint8_t buf[64];
uint16_t length; uint16_t length;
uint8_t tag[4]; uint8_t tag[4];
uint8_t tagLength;
uint8_t command; uint8_t command;
Neighbor * neighbor; Neighbor * neighbor;
@@ -2677,10 +2673,8 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
Crypto::AesCcm::GenerateNonce(macAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce); Crypto::AesCcm::GenerateNonce(macAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce);
aesCcm.SetKey(*mleKey); aesCcm.SetKey(*mleKey);
SuccessOrExit(error = aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) + aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) + header.GetHeaderLength(),
header.GetHeaderLength(), aMessage.GetLength() - aMessage.GetOffset(), sizeof(messageTag), nonce, sizeof(nonce));
aMessage.GetLength() - aMessage.GetOffset(), sizeof(messageTag), nonce,
sizeof(nonce)));
aesCcm.Header(&aMessageInfo.GetPeerAddr(), sizeof(aMessageInfo.GetPeerAddr())); aesCcm.Header(&aMessageInfo.GetPeerAddr(), sizeof(aMessageInfo.GetPeerAddr()));
aesCcm.Header(&aMessageInfo.GetSockAddr(), sizeof(aMessageInfo.GetSockAddr())); aesCcm.Header(&aMessageInfo.GetSockAddr(), sizeof(aMessageInfo.GetSockAddr()));
@@ -2691,15 +2685,14 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
while (aMessage.GetOffset() < aMessage.GetLength()) while (aMessage.GetOffset() < aMessage.GetLength())
{ {
length = aMessage.Read(aMessage.GetOffset(), sizeof(buf), buf); length = aMessage.Read(aMessage.GetOffset(), sizeof(buf), buf);
aesCcm.Payload(buf, buf, length, false); aesCcm.Payload(buf, buf, length, Crypto::AesCcm::kDecrypt);
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
aMessage.Write(aMessage.GetOffset(), length, buf); aMessage.Write(aMessage.GetOffset(), length, buf);
#endif #endif
aMessage.MoveOffset(length); aMessage.MoveOffset(length);
} }
tagLength = sizeof(tag); aesCcm.Finalize(tag);
aesCcm.Finalize(tag, &tagLength);
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
VerifyOrExit(memcmp(messageTag, tag, sizeof(tag)) == 0, error = OT_ERROR_SECURITY); VerifyOrExit(memcmp(messageTag, tag, sizeof(tag)) == 0, error = OT_ERROR_SECURITY);
#endif #endif
+14 -10
View File
@@ -68,15 +68,17 @@ void TestMacBeaconFrame(void)
VerifyOrQuit(instance != NULL, "Null OpenThread instance"); VerifyOrQuit(instance != NULL, "Null OpenThread instance");
aesCcm.SetKey(key, sizeof(key)); aesCcm.SetKey(key, sizeof(key));
SuccessOrQuit(aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce)), "AesCcm::Init() failed"); aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
aesCcm.Header(test, headerLength); aesCcm.Header(test, headerLength);
aesCcm.Finalize(test + headerLength, &tagLength); VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
aesCcm.Finalize(test + headerLength);
VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, "TestMacBeaconFrame encrypt failed"); VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, "TestMacBeaconFrame encrypt failed");
SuccessOrQuit(aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce)), "AesCcm::Init() failed"); aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
aesCcm.Header(test, headerLength); aesCcm.Header(test, headerLength);
aesCcm.Finalize(test + headerLength, &tagLength); VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
aesCcm.Finalize(test + headerLength);
VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, "TestMacBeaconFrame decrypt failed"); VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, "TestMacBeaconFrame decrypt failed");
@@ -119,16 +121,18 @@ void TestMacCommandFrame()
ot::Crypto::AesCcm aesCcm; ot::Crypto::AesCcm aesCcm;
aesCcm.SetKey(key, sizeof(key)); aesCcm.SetKey(key, sizeof(key));
SuccessOrQuit(aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce)), "AesCcm::Init() failed"); aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
aesCcm.Header(test, headerLength); aesCcm.Header(test, headerLength);
aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, true); aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, ot::Crypto::AesCcm::kEncrypt);
aesCcm.Finalize(test + headerLength + payloadLength, &tagLength); VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
aesCcm.Finalize(test + headerLength + payloadLength);
VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, "TestMacCommandFrame encrypt failed"); VerifyOrQuit(memcmp(test, encrypted, sizeof(encrypted)) == 0, "TestMacCommandFrame encrypt failed");
SuccessOrQuit(aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce)), "AesCcm::Init() failed"); aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
aesCcm.Header(test, headerLength); aesCcm.Header(test, headerLength);
aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, false); aesCcm.Payload(test + headerLength, test + headerLength, payloadLength, ot::Crypto::AesCcm::kDecrypt);
aesCcm.Finalize(test + headerLength + payloadLength, &tagLength); VerifyOrQuit(aesCcm.GetTagLength() == tagLength, "AesCcm::GetTagLength() failed");
aesCcm.Finalize(test + headerLength + payloadLength);
VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, "TestMacCommandFrame decrypt failed"); VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0, "TestMacCommandFrame decrypt failed");
} }