mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 13:47:47 +00:00
[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:
+29
-53
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user