mirror of
https://github.com/espressif/openthread.git
synced 2026-09-09 02:30:11 +00:00
[crypto] introduce AesCcm::Nonce for IEEE 802.15.4 nonce (#13208)
This commit introduces the `AesCcm::Nonce` class to represent the IEEE 802.15.4 nonce byte sequence, replacing the previous `GenerateNonce()` method which operated on a raw byte array. Replacing `uint8_t *` buffers and `kNonceSize` with a dedicated, packed `Nonce` class makes the code cleaner and prevents potential buffer size mismatches at call sites. The new class provides an `InitFrom()` method to safely initialize the nonce from an extended address, frame counter, and security level. All callers in `Mac` (frame transmission and reception) and `Mle` (message security) have been updated to use the new `Nonce` class.
This commit is contained in:
+12
-11
@@ -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
|
||||
|
||||
+24
-14
@@ -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<Nonce>
|
||||
{
|
||||
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];
|
||||
|
||||
+23
-23
@@ -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);
|
||||
|
||||
+11
-11
@@ -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<KeyManager>().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);
|
||||
|
||||
Reference in New Issue
Block a user