[mle] define separate TxChallenge and RxChallenge types (#9304)

This commit defines two types to track challenge or response TLV data
in MLE messages:

- `TxChallenge` represents the maximum-sized challenge data to include
  and send in MLE messages. OpenThread always uses the maximum size
  of 8 bytes for challenge data in the messages it sends.
- `RxChallenge` represents variable-length challenge data read from a
  received MLE message.

The two separate types help to simplify their use in code.
This commit is contained in:
Abtin Keshavarzian
2023-07-20 10:07:09 -07:00
committed by GitHub
parent 5fc0e7774c
commit b19b2cfa75
8 changed files with 230 additions and 206 deletions
+29 -53
View File
@@ -1801,7 +1801,7 @@ Error Mle::SendChildIdRequest(void)
}
VerifyOrExit((message = NewMleMessage(kCommandChildIdRequest)) != nullptr, error = kErrorNoBufs);
SuccessOrExit(error = message->AppendResponseTlv(mParentCandidate.mChallenge));
SuccessOrExit(error = message->AppendResponseTlv(mParentCandidate.mRxChallenge));
SuccessOrExit(error = message->AppendLinkFrameCounterTlv());
SuccessOrExit(error = message->AppendMleFrameCounterTlv());
SuccessOrExit(error = message->AppendModeTlv(mDeviceMode));
@@ -2139,7 +2139,7 @@ exit:
return error;
}
Error Mle::SendChildUpdateResponse(const TlvList &aTlvList, const Challenge &aChallenge)
Error Mle::SendChildUpdateResponse(const TlvList &aTlvList, const RxChallenge &aChallenge)
{
Error error = kErrorNone;
Ip6::Address destination;
@@ -3118,7 +3118,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
{
Error error = kErrorNone;
int8_t rss = aRxInfo.mMessageInfo.GetThreadLinkInfo()->GetRss();
Challenge response;
RxChallenge response;
uint16_t version;
uint16_t sourceAddress;
LeaderData leaderData;
@@ -3288,7 +3288,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
// Challenge
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(mParentCandidate.mChallenge));
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(mParentCandidate.mRxChallenge));
InitNeighbor(mParentCandidate, aRxInfo);
mParentCandidate.SetRloc16(sourceAddress);
@@ -3447,11 +3447,11 @@ exit:
void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
{
Error error = kErrorNone;
uint16_t sourceAddress;
Challenge challenge;
TlvList requestedTlvList;
TlvList tlvList;
Error error = kErrorNone;
uint16_t sourceAddress;
RxChallenge challenge;
TlvList requestedTlvList;
TlvList tlvList;
// Source Address
SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));
@@ -3467,7 +3467,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
tlvList.Add(Tlv::kLinkFrameCounter);
break;
case kErrorNotFound:
challenge.mLength = 0;
challenge.Clear();
break;
default:
ExitNow(error = kErrorParse);
@@ -3531,7 +3531,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
ProcessKeySequence(aRxInfo);
#if OPENTHREAD_CONFIG_MULTI_RADIO
if ((aRxInfo.mNeighbor != nullptr) && (challenge.mLength != 0))
if ((aRxInfo.mNeighbor != nullptr) && !challenge.IsEmpty())
{
aRxInfo.mNeighbor->ClearLastRxFragmentTag();
}
@@ -3545,14 +3545,14 @@ exit:
void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
{
Error error = kErrorNone;
uint8_t status;
uint8_t mode;
Challenge response;
uint32_t linkFrameCounter;
uint32_t mleFrameCounter;
uint16_t sourceAddress;
uint32_t timeout;
Error error = kErrorNone;
uint8_t status;
uint8_t mode;
RxChallenge response;
uint32_t linkFrameCounter;
uint32_t mleFrameCounter;
uint16_t sourceAddress;
uint32_t timeout;
Log(kMessageReceive, kTypeChildUpdateResponseOfParent, aRxInfo.mMessageInfo.GetPeerAddr());
@@ -3561,7 +3561,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
case kErrorNone:
break;
case kErrorNotFound:
response.mLength = 0;
response.Clear();
break;
default:
ExitNow(error = kErrorParse);
@@ -3681,7 +3681,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
OT_ASSERT(false);
}
aRxInfo.mClass = (response.mLength == 0) ? RxInfo::kPeerMessage : RxInfo::kAuthoritativeMessage;
aRxInfo.mClass = response.IsEmpty() ? RxInfo::kPeerMessage : RxInfo::kAuthoritativeMessage;
exit:
@@ -4413,20 +4413,6 @@ void Mle::TlvList::AddElementsFrom(const TlvList &aTlvList)
}
}
//---------------------------------------------------------------------------------------------------------------------
// Challenge
void Mle::Challenge::GenerateRandom(void)
{
mLength = kMaxChallengeSize;
IgnoreError(Random::Crypto::FillBuffer(mBuffer, mLength));
}
bool Mle::Challenge::Matches(const uint8_t *aBuffer, uint8_t aLength) const
{
return (mLength == aLength) && (memcmp(mBuffer, aBuffer, aLength) == 0);
}
//---------------------------------------------------------------------------------------------------------------------
// DelayedResponseMetadata
@@ -4529,19 +4515,14 @@ Error Mle::TxMessage::AppendModeTlv(DeviceMode aMode) { return Tlv::Append<ModeT
Error Mle::TxMessage::AppendTimeoutTlv(uint32_t aTimeout) { return Tlv::Append<TimeoutTlv>(*this, aTimeout); }
Error Mle::TxMessage::AppendChallengeTlv(const Challenge &aChallenge)
Error Mle::TxMessage::AppendChallengeTlv(const TxChallenge &aChallenge)
{
return Tlv::Append<ChallengeTlv>(*this, aChallenge.mBuffer, aChallenge.mLength);
return Tlv::Append<ChallengeTlv>(*this, &aChallenge, sizeof(aChallenge));
}
Error Mle::TxMessage::AppendChallengeTlv(const uint8_t *aChallenge, uint8_t aChallengeLength)
Error Mle::TxMessage::AppendResponseTlv(const RxChallenge &aResponse)
{
return Tlv::Append<ChallengeTlv>(*this, aChallenge, aChallengeLength);
}
Error Mle::TxMessage::AppendResponseTlv(const Challenge &aResponse)
{
return Tlv::Append<ResponseTlv>(*this, aResponse.mBuffer, aResponse.mLength);
return Tlv::Append<ResponseTlv>(*this, aResponse.GetBytes(), aResponse.GetLength());
}
Error Mle::TxMessage::AppendLinkFrameCounterTlv(void)
@@ -4960,30 +4941,25 @@ Error Mle::TxMessage::AppendPendingDatasetTlv(void)
//---------------------------------------------------------------------------------------------------------------------
// RxMessage
Error Mle::RxMessage::ReadChallengeOrResponse(uint8_t aTlvType, Challenge &aBuffer) const
Error Mle::RxMessage::ReadChallengeOrResponse(uint8_t aTlvType, RxChallenge &aRxChallenge) const
{
Error error;
uint16_t offset;
uint16_t length;
SuccessOrExit(error = Tlv::FindTlvValueOffset(*this, aTlvType, offset, length));
VerifyOrExit(length >= kMinChallengeSize, error = kErrorParse);
length = Min(length, kMaxChallengeSize);
ReadBytes(offset, aBuffer.mBuffer, length);
aBuffer.mLength = static_cast<uint8_t>(length);
error = aRxChallenge.ReadFrom(*this, offset, length);
exit:
return error;
}
Error Mle::RxMessage::ReadChallengeTlv(Challenge &aChallenge) const
Error Mle::RxMessage::ReadChallengeTlv(RxChallenge &aChallenge) const
{
return ReadChallengeOrResponse(Tlv::kChallenge, aChallenge);
}
Error Mle::RxMessage::ReadResponseTlv(Challenge &aResponse) const
Error Mle::RxMessage::ReadResponseTlv(RxChallenge &aResponse) const
{
return ReadChallengeOrResponse(Tlv::kResponse, aResponse);
}
+22 -73
View File
@@ -881,45 +881,6 @@ protected:
void AddElementsFrom(const TlvList &aTlvList);
};
/**
* Represents a Challenge (or Response) data.
*
*/
struct Challenge
{
uint8_t mBuffer[kMaxChallengeSize]; ///< Buffer containing the challenge/response byte sequence.
uint8_t mLength; ///< Challenge length (in bytes).
/**
* Generates a cryptographically secure random sequence to populate the challenge data.
*
*/
void GenerateRandom(void);
/**
* Indicates whether the Challenge matches a given buffer.
*
* @param[in] aBuffer A pointer to a buffer to compare with the Challenge.
* @param[in] aLength Length of @p aBuffer (in bytes).
*
* @retval TRUE If the Challenge matches the given buffer.
* @retval FALSE If the Challenge does not match the given buffer.
*
*/
bool Matches(const uint8_t *aBuffer, uint8_t aLength) const;
/**
* Indicates whether two Challenge data byte sequences are equal or not.
*
* @param[in] aOther Another Challenge data to compare.
*
* @retval TRUE If the two Challenges match.
* @retval FALSE If the two Challenges do not match.
*
*/
bool operator==(const Challenge &aOther) const { return Matches(aOther.mBuffer, aOther.mLength); }
};
/**
* Represents an MLE Tx message.
*
@@ -958,18 +919,6 @@ protected:
*/
Error AppendTimeoutTlv(uint32_t aTimeout);
/**
* Appends a Challenge TLV to the message.
*
* @param[in] aChallenge A pointer to the Challenge value.
* @param[in] aChallengeLength The length of the Challenge value in bytes.
*
* @retval kErrorNone Successfully appended the Challenge TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV.
*
*/
Error AppendChallengeTlv(const uint8_t *aChallenge, uint8_t aChallengeLength);
/**
* Appends a Challenge TLV to the message.
*
@@ -979,18 +928,18 @@ protected:
* @retval kErrorNoBufs Insufficient buffers available to append the Challenge TLV.
*
*/
Error AppendChallengeTlv(const Challenge &aChallenge);
Error AppendChallengeTlv(const TxChallenge &aChallenge);
/**
* Appends a Response TLV to the message.
*
* @param[in] aResponse A reference to the Response data.
* @param[in] aResponse The Response data.
*
* @retval kErrorNone Successfully appended the Response TLV.
* @retval kErrorNoBufs Insufficient buffers available to append the Response TLV.
*
*/
Error AppendResponseTlv(const Challenge &aResponse);
Error AppendResponseTlv(const RxChallenge &aResponse);
/**
* Appends a Link Frame Counter TLV to the message.
@@ -1299,26 +1248,26 @@ protected:
/**
* Reads Challenge TLV from the message.
*
* @param[out] aChallenge A reference to the Challenge data where to output the read value.
* @param[out] aChallenge A `RxChallenge` to output the read challenge data.
*
* @retval kErrorNone Successfully read the Challenge TLV.
* @retval kErrorNotFound Challenge TLV was not found in the message.
* @retval kErrorParse Challenge TLV was found but could not be parsed.
*
*/
Error ReadChallengeTlv(Challenge &aChallenge) const;
Error ReadChallengeTlv(RxChallenge &aChallenge) const;
/**
* Reads Response TLV from the message.
*
* @param[out] aResponse A reference to the Response data where to output the read value.
* @param[out] aResponse A `RxChallenge` to output the read challenge data.
*
* @retval kErrorNone Successfully read the Response TLV.
* @retval kErrorNotFound Response TLV was not found in the message.
* @retval kErrorParse Response TLV was found but could not be parsed.
*
*/
Error ReadResponseTlv(Challenge &aResponse) const;
Error ReadResponseTlv(RxChallenge &aResponse) const;
/**
* Reads Link and MLE Frame Counters from the message.
@@ -1391,7 +1340,7 @@ protected:
#endif
private:
Error ReadChallengeOrResponse(uint8_t aTlvType, Challenge &aBuffer) const;
Error ReadChallengeOrResponse(uint8_t aTlvType, RxChallenge &aRxChallenge) const;
};
/**
@@ -1563,14 +1512,14 @@ protected:
/**
* Generates an MLE Child Update Response message.
*
* @param[in] aTlvList A list of requested TLV types.
* @param[in] aChallenge The Challenge for the response.
* @param[in] aTlvList A list of requested TLV types.
* @param[in] aChallenge The challenge data to include in response.
*
* @retval kErrorNone Successfully generated an MLE Child Update Response message.
* @retval kErrorNoBufs Insufficient buffers to generate the MLE Child Update Response message.
*
*/
Error SendChildUpdateResponse(const TlvList &aTlvList, const Challenge &aChallenge);
Error SendChildUpdateResponse(const TlvList &aTlvList, const RxChallenge &aChallenge);
/**
* Sets the RLOC16 assigned to the Thread interface.
@@ -1898,16 +1847,16 @@ private:
void Clear(void);
void CopyTo(Parent &aParent) const;
Challenge mChallenge;
int8_t mPriority;
uint8_t mLinkQuality3;
uint8_t mLinkQuality2;
uint8_t mLinkQuality1;
uint16_t mSedBufferSize;
uint8_t mSedDatagramCount;
uint8_t mLinkMargin;
LeaderData mLeaderData;
bool mIsSingleton;
RxChallenge mRxChallenge;
int8_t mPriority;
uint8_t mLinkQuality3;
uint8_t mLinkQuality2;
uint8_t mLinkQuality1;
uint16_t mSedBufferSize;
uint8_t mSedDatagramCount;
uint8_t mLinkMargin;
LeaderData mLeaderData;
bool mIsSingleton;
};
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
@@ -2068,7 +2017,7 @@ private:
MessageQueue mDelayedResponses;
Challenge mParentRequestChallenge;
TxChallenge mParentRequestChallenge;
AttachMode mAttachMode;
ParentCandidate mParentCandidate;
+38 -39
View File
@@ -610,12 +610,11 @@ Error MleRouter::SendLinkRequest(Neighbor *aNeighbor)
if (!aNeighbor->IsStateValid())
{
aNeighbor->GenerateChallenge();
SuccessOrExit(error =
message->AppendChallengeTlv(aNeighbor->GetChallenge(), aNeighbor->GetChallengeSize()));
SuccessOrExit(error = message->AppendChallengeTlv(aNeighbor->GetChallenge()));
}
else
{
Challenge challenge;
TxChallenge challenge;
challenge.GenerateRandom();
SuccessOrExit(error = message->AppendChallengeTlv(challenge));
@@ -635,13 +634,13 @@ exit:
void MleRouter::HandleLinkRequest(RxInfo &aRxInfo)
{
Error error = kErrorNone;
Neighbor *neighbor = nullptr;
Challenge challenge;
uint16_t version;
LeaderData leaderData;
uint16_t sourceAddress;
TlvList requestedTlvList;
Error error = kErrorNone;
Neighbor *neighbor = nullptr;
RxChallenge challenge;
uint16_t version;
LeaderData leaderData;
uint16_t sourceAddress;
TlvList requestedTlvList;
Log(kMessageReceive, kTypeLinkRequest, aRxInfo.mMessageInfo.GetPeerAddr());
@@ -741,7 +740,7 @@ exit:
Error MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
Neighbor *aNeighbor,
const TlvList &aRequestedTlvList,
const Challenge &aChallenge)
const RxChallenge &aChallenge)
{
static const uint8_t kRouterTlvs[] = {Tlv::kLinkMargin};
@@ -794,7 +793,7 @@ Error MleRouter::SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
{
aNeighbor->GenerateChallenge();
SuccessOrExit(error = message->AppendChallengeTlv(aNeighbor->GetChallenge(), aNeighbor->GetChallengeSize()));
SuccessOrExit(error = message->AppendChallengeTlv(aNeighbor->GetChallenge()));
SuccessOrExit(error = message->AppendTlvRequestTlv(kRouterTlvs));
aNeighbor->SetLastHeard(TimerMilli::GetNow());
aNeighbor->SetState(Neighbor::kStateLinkRequest);
@@ -848,7 +847,7 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
Router *router;
Neighbor::State neighborState;
uint16_t version;
Challenge response;
RxChallenge response;
uint16_t sourceAddress;
uint32_t linkFrameCounter;
uint32_t mleFrameCounter;
@@ -877,7 +876,7 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
switch (neighborState)
{
case Neighbor::kStateLinkRequest:
VerifyOrExit(response.Matches(router->GetChallenge(), router->GetChallengeSize()), error = kErrorSecurity);
VerifyOrExit(response == router->GetChallenge(), error = kErrorSecurity);
break;
case Neighbor::kStateInvalid:
@@ -1030,8 +1029,8 @@ Error MleRouter::HandleLinkAccept(RxInfo &aRxInfo, bool aRequest)
if (aRequest)
{
Challenge challenge;
TlvList requestedTlvList;
RxChallenge challenge;
TlvList requestedTlvList;
// Challenge
SuccessOrExit(error = aRxInfo.mMessage.ReadChallengeTlv(challenge));
@@ -1388,7 +1387,7 @@ void MleRouter::HandleParentRequest(RxInfo &aRxInfo)
Mac::ExtAddress extAddr;
uint16_t version;
uint8_t scanMask;
Challenge challenge;
RxChallenge challenge;
Child *child;
uint8_t modeBitmask;
DeviceMode mode;
@@ -1756,7 +1755,7 @@ exit:
return;
}
void MleRouter::SendParentResponse(Child *aChild, const Challenge &aChallenge, bool aRoutersOnlyRequest)
void MleRouter::SendParentResponse(Child *aChild, const RxChallenge &aChallenge, bool aRoutersOnlyRequest)
{
Error error = kErrorNone;
Ip6::Address destination;
@@ -1785,7 +1784,7 @@ void MleRouter::SendParentResponse(Child *aChild, const Challenge &aChallenge, b
#endif
aChild->GenerateChallenge();
SuccessOrExit(error = message->AppendChallengeTlv(aChild->GetChallenge(), aChild->GetChallengeSize()));
SuccessOrExit(error = message->AppendChallengeTlv(aChild->GetChallenge()));
SuccessOrExit(error = message->AppendLinkMarginTlv(aChild->GetLinkInfo().GetLinkMargin()));
SuccessOrExit(error = message->AppendConnectivityTlv());
SuccessOrExit(error = message->AppendVersionTlv());
@@ -2040,7 +2039,7 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo)
Error error = kErrorNone;
Mac::ExtAddress extAddr;
uint16_t version;
Challenge response;
RxChallenge response;
uint32_t linkFrameCounter;
uint32_t mleFrameCounter;
uint8_t modeBitmask;
@@ -2071,7 +2070,7 @@ void MleRouter::HandleChildIdRequest(RxInfo &aRxInfo)
// Response
SuccessOrExit(error = aRxInfo.mMessage.ReadResponseTlv(response));
VerifyOrExit(response.Matches(child->GetChallenge(), child->GetChallengeSize()), error = kErrorSecurity);
VerifyOrExit(response == child->GetChallenge(), error = kErrorSecurity);
// Remove existing MLE messages
Get<MeshForwarder>().RemoveMessages(*child, Message::kSubTypeMleGeneral);
@@ -2224,7 +2223,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo)
Mac::ExtAddress extAddr;
uint8_t modeBitmask;
DeviceMode mode;
Challenge challenge;
RxChallenge challenge;
LeaderData leaderData;
uint32_t timeout;
uint16_t supervisionInterval;
@@ -2247,7 +2246,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo)
tlvList.Add(Tlv::kResponse);
break;
case kErrorNotFound:
challenge.mLength = 0;
challenge.Clear();
break;
default:
ExitNow(error = kErrorParse);
@@ -2287,7 +2286,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo)
// Parent MUST include Leader Data TLV in Child Update Response
tlvList.Add(Tlv::kLeaderData);
if (challenge.mLength != 0)
if (!challenge.IsEmpty())
{
tlvList.Add(Tlv::kMleFrameCounter);
tlvList.Add(Tlv::kLinkFrameCounter);
@@ -2432,7 +2431,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo)
// from a detached child trying to restore its link with its
// parent which is indicated by the presence of Challenge TLV in
// the message.
if (challenge.mLength != 0)
if (!challenge.IsEmpty())
{
child->ClearLastRxFragmentTag();
}
@@ -2448,15 +2447,15 @@ exit:
void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo)
{
Error error = kErrorNone;
uint16_t sourceAddress;
uint32_t timeout;
Challenge response;
uint8_t status;
uint32_t linkFrameCounter;
uint32_t mleFrameCounter;
LeaderData leaderData;
Child *child;
Error error = kErrorNone;
uint16_t sourceAddress;
uint32_t timeout;
RxChallenge response;
uint8_t status;
uint32_t linkFrameCounter;
uint32_t mleFrameCounter;
LeaderData leaderData;
Child *child;
if ((aRxInfo.mNeighbor == nullptr) || IsActiveRouter(aRxInfo.mNeighbor->GetRloc16()) ||
!Get<ChildTable>().Contains(*aRxInfo.mNeighbor))
@@ -2471,11 +2470,11 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo)
switch (aRxInfo.mMessage.ReadResponseTlv(response))
{
case kErrorNone:
VerifyOrExit(response.Matches(child->GetChallenge(), child->GetChallengeSize()), error = kErrorSecurity);
VerifyOrExit(response == child->GetChallenge(), error = kErrorSecurity);
break;
case kErrorNotFound:
VerifyOrExit(child->IsStateValid(), error = kErrorSecurity);
response.mLength = 0;
response.Clear();
break;
default:
ExitNow(error = kErrorNone);
@@ -2594,7 +2593,7 @@ void MleRouter::HandleChildUpdateResponse(RxInfo &aRxInfo)
child->SetKeySequence(aRxInfo.mKeySequence);
child->GetLinkInfo().AddRss(aRxInfo.mMessageInfo.GetThreadLinkInfo()->GetRss());
aRxInfo.mClass = (response.mLength == 0) ? RxInfo::kPeerMessage : RxInfo::kAuthoritativeMessage;
aRxInfo.mClass = response.IsEmpty() ? RxInfo::kPeerMessage : RxInfo::kAuthoritativeMessage;
exit:
LogProcessError(kTypeChildUpdateResponseOfChild, error);
@@ -3040,7 +3039,7 @@ Error MleRouter::SendChildUpdateRequest(Child &aChild)
{
SuccessOrExit(error = message->AppendTlvRequestTlv(kTlvs));
aChild.GenerateChallenge();
SuccessOrExit(error = message->AppendChallengeTlv(aChild.GetChallenge(), aChild.GetChallengeSize()));
SuccessOrExit(error = message->AppendChallengeTlv(aChild.GetChallenge()));
}
destination.SetToLinkLocalAddress(aChild.GetExtAddress());
@@ -3062,7 +3061,7 @@ exit:
void MleRouter::SendChildUpdateResponse(Child *aChild,
const Ip6::MessageInfo &aMessageInfo,
const TlvList &aTlvList,
const Challenge &aChallenge)
const RxChallenge &aChallenge)
{
Error error = kErrorNone;
TxMessage *message;
+5 -5
View File
@@ -617,14 +617,14 @@ private:
Error SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
Neighbor *aNeighbor,
const TlvList &aRequestedTlvList,
const Challenge &aChallenge);
void SendParentResponse(Child *aChild, const Challenge &aChallenge, bool aRoutersOnlyRequest);
const RxChallenge &aChallenge);
void SendParentResponse(Child *aChild, const RxChallenge &aChallenge, bool aRoutersOnlyRequest);
Error SendChildIdResponse(Child &aChild);
Error SendChildUpdateRequest(Child &aChild);
void SendChildUpdateResponse(Child *aChild,
const Ip6::MessageInfo &aMessageInfo,
const TlvList &aTlvList,
const Challenge &aChallenge);
const RxChallenge &aChallenge);
void SendDataResponse(const Ip6::Address &aDestination,
const TlvList &aTlvList,
uint16_t aDelay,
@@ -668,8 +668,8 @@ private:
ChildTable mChildTable;
RouterTable mRouterTable;
uint8_t mChallengeTimeout;
Challenge mChallenge;
uint8_t mChallengeTimeout;
TxChallenge mChallenge;
uint16_t mNextChildId;
uint8_t mNetworkIdTimeout;
+32
View File
@@ -35,6 +35,8 @@
#include "common/array.hpp"
#include "common/code_utils.hpp"
#include "common/message.hpp"
#include "common/random.hpp"
namespace ot {
namespace Mle {
@@ -150,6 +152,36 @@ uint8_t RouterIdSet::GetNumberOfAllocatedIds(void) const
return count;
}
//---------------------------------------------------------------------------------------------------------------------
// TxChallenge
void TxChallenge::GenerateRandom(void) { IgnoreError(Random::Crypto::Fill(*this)); }
//---------------------------------------------------------------------------------------------------------------------
// RxChallenge
Error RxChallenge::ReadFrom(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
{
Error error = kErrorNone;
Clear();
aLength = Min<uint16_t>(aLength, kMaxChallengeSize);
VerifyOrExit(kMinChallengeSize <= aLength, error = kErrorParse);
SuccessOrExit(error = aMessage.Read(aOffset, mArray.GetArrayBuffer(), aLength));
mArray.SetLength(static_cast<uint8_t>(aLength));
exit:
return error;
}
bool RxChallenge::operator==(const TxChallenge &aTxChallenge) const
{
return (mArray.GetLength() == kMaxChallengeSize) &&
(memcmp(mArray.GetArrayBuffer(), aTxChallenge.m8, kMaxChallengeSize) == 0);
}
//---------------------------------------------------------------------------------------------------------------------
const char *RoleToString(DeviceRole aRole)
+97 -2
View File
@@ -45,6 +45,7 @@
#include <openthread/thread_ftd.h>
#endif
#include "common/array.hpp"
#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/code_utils.hpp"
@@ -57,6 +58,9 @@
#include "thread/network_data_types.hpp"
namespace ot {
class Message;
namespace Mle {
/**
@@ -130,8 +134,8 @@ constexpr uint16_t kMaxChildId = 511; ///< Maximum Child ID
constexpr uint8_t kRouterIdOffset = 10; ///< Bit offset of Router ID in RLOC16
constexpr uint8_t kRlocPrefixLength = 14; ///< Prefix length of RLOC in bytes
constexpr uint16_t kMinChallengeSize = 4; ///< Minimum Challenge size in bytes.
constexpr uint16_t kMaxChallengeSize = 8; ///< Maximum Challenge size in bytes.
constexpr uint8_t kMinChallengeSize = 4; ///< Minimum Challenge size in bytes.
constexpr uint8_t kMaxChallengeSize = 8; ///< Maximum Challenge size in bytes.
/*
* Routing Protocol Constants
@@ -574,6 +578,97 @@ private:
uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
} OT_TOOL_PACKED_END;
class RxChallenge;
/**
* Represents a max-sized challenge data to send in MLE message.
*
* OpenThread always uses max size challenge when sending MLE messages.
*
*/
class TxChallenge : public Clearable<TxChallenge>
{
friend class RxChallenge;
public:
/**
* Generates a cryptographically secure random sequence to populate the challenge data.
*
*/
void GenerateRandom(void);
private:
uint8_t m8[kMaxChallengeSize];
};
/**
* Represents a received Challenge data from an MLE message.
*
*/
class RxChallenge
{
public:
/**
* Clears the challenge.
*
*/
void Clear(void) { mArray.Clear(); }
/**
* Indicates whether or not the challenge data is empty.
*
* @retval TRUE The challenge is empty.
* @retval FALSE The challenge is not empty.
*
*/
bool IsEmpty(void) const { return mArray.GetLength() == 0; }
/**
* Gets a pointer to challenge data bytes.
*
* @return A pointer to the challenge data bytes.
*
*/
const uint8_t *GetBytes(void) const { return mArray.GetArrayBuffer(); }
/**
* Gets the length of challenge data.
*
* @returns The length of challenge data in bytes.
*
*/
uint8_t GetLength(void) const { return mArray.GetLength(); }
/**
* Reads the challenge bytes from given message.
*
* If the given @p aLength is longer than `kMaxChallengeSize`, only `kMaxChallengeSize` bytes will be read.
*
* @param[in] aMessage The message to read the challenge from.
* @param[in] aOffset The offset in @p aMessage to read from.
* @param[in] aLength Number of bytes to read.
*
* @retval kErrorNone Successfully read the challenge data from @p aMessage.
* @retval kErrorParse Not enough bytes to read, or invalid @p aLength (smaller than `kMinChallgeSize`).
*
*/
Error ReadFrom(const Message &aMessage, uint16_t aOffset, uint16_t aLength);
/**
* Compares the `RxChallenge` with a given `TxChallenge`.
*
* @param[in] aTxChallenge The `TxChallenge` to compare with.
*
* @retval TRUE The two challenges are equal.
* @retval FALSE The two challenges are not equal.
*
*/
bool operator==(const TxChallenge &aTxChallenge) const;
private:
Array<uint8_t, kMaxChallengeSize> mArray;
};
/**
* Represents a MLE Key Material
*
-11
View File
@@ -196,12 +196,6 @@ bool Neighbor::IsLastRxFragmentTagSet(void) const
}
#endif
void Neighbor::GenerateChallenge(void)
{
IgnoreError(
Random::Crypto::FillBuffer(mValidPending.mPending.mChallenge, sizeof(mValidPending.mPending.mChallenge)));
}
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
void Neighbor::AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss)
{
@@ -492,11 +486,6 @@ exit:
}
#endif
void Child::GenerateChallenge(void)
{
IgnoreError(Random::Crypto::FillBuffer(mAttachChallenge, sizeof(mAttachChallenge)));
}
#if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
bool Child::HasMlrRegisteredAddress(const Ip6::Address &aAddress) const
{
+7 -23
View File
@@ -652,7 +652,7 @@ public:
* Generates a new challenge value for MLE Link Request/Response exchanges.
*
*/
void GenerateChallenge(void);
void GenerateChallenge(void) { mValidPending.mPending.mChallenge.GenerateRandom(); }
/**
* Returns the current challenge value for MLE Link Request/Response exchanges.
@@ -660,15 +660,7 @@ public:
* @returns The current challenge value.
*
*/
const uint8_t *GetChallenge(void) const { return mValidPending.mPending.mChallenge; }
/**
* Returns the size (bytes) of the challenge value for MLE Link Request/Response exchanges.
*
* @returns The size (bytes) of the challenge value for MLE Link Request/Response exchanges.
*
*/
uint8_t GetChallengeSize(void) const { return sizeof(mValidPending.mPending.mChallenge); }
const Mle::TxChallenge &GetChallenge(void) const { return mValidPending.mPending.mChallenge; }
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
/**
@@ -819,7 +811,7 @@ private:
} mValid;
struct
{
uint8_t mChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
Mle::TxChallenge mChallenge; ///< The challenge value
} mPending;
} mValidPending;
@@ -1183,7 +1175,7 @@ public:
* Generates a new challenge value to use during a child attach.
*
*/
void GenerateChallenge(void);
void GenerateChallenge(void) { mAttachChallenge.GenerateRandom(); }
/**
* Gets the current challenge value used during attach.
@@ -1191,15 +1183,7 @@ public:
* @returns The current challenge value.
*
*/
const uint8_t *GetChallenge(void) const { return mAttachChallenge; }
/**
* Gets the challenge size (bytes) used during attach.
*
* @returns The challenge size (bytes).
*
*/
uint8_t GetChallengeSize(void) const { return sizeof(mAttachChallenge); }
const Mle::TxChallenge &GetChallenge(void) const { return mAttachChallenge; }
/**
* Clears the requested TLV list.
@@ -1355,8 +1339,8 @@ private:
union
{
uint8_t mRequestTlvs[kMaxRequestTlvs]; ///< Requested MLE TLVs
uint8_t mAttachChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
uint8_t mRequestTlvs[kMaxRequestTlvs]; ///< Requested MLE TLVs
Mle::TxChallenge mAttachChallenge; ///< The challenge value
};
uint16_t mSupervisionInterval; // Supervision interval for the child (in sec).