Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 17ed842

Browse files
emargolisrobszewczyk
authored andcommitted
Protect Against Key Error Denial-Of-Service Vulnerability.
The following mitigation mechanisms were implemented: -- Verify that the Key Error message was received over the same transport mechanism as was used to establish the security session. -- Verify that the message Id value presented in the Key Error message is equal to the last used message id. -- Randomize the initial 32-bit message counter on session establishment. This change addresses CVE security vulnerability: CVE-2019-5036
1 parent f71a979 commit 17ed842

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

src/lib/core/WeaveFabricState.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,17 +332,27 @@ WEAVE_ERROR WeaveFabricState::SetSessionKey(uint16_t keyId, uint64_t peerNodeId,
332332
err = FindSessionKey(keyId, peerNodeId, false, sessionKey);
333333
SuccessOrExit(err);
334334
335-
SetSessionKey(sessionKey, encType, authMode, encKey);
335+
err = SetSessionKey(sessionKey, encType, authMode, encKey);
336+
SuccessOrExit(err);
336337
337338
exit:
338339
return err;
339340
}
340341
341-
void WeaveFabricState::SetSessionKey(WeaveSessionKey *sessionKey, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey)
342+
WEAVE_ERROR WeaveFabricState::SetSessionKey(WeaveSessionKey *sessionKey, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey)
342343
{
344+
WEAVE_ERROR err;
345+
uint32_t msgId;
346+
347+
// Randomize the initial 32-bit message counter on session establishment.
348+
// This value should be secure random to prevent man-in-the-middle adversary
349+
// guessing this number.
350+
err = nl::Weave::Platform::Security::GetSecureRandomData(reinterpret_cast<uint8_t *>(&msgId), sizeof(msgId));
351+
SuccessOrExit(err);
352+
343353
sessionKey->MsgEncKey.EncType = encType;
344354
sessionKey->MsgEncKey.EncKey = *encKey;
345-
sessionKey->NextMsgId.Init(0);
355+
sessionKey->NextMsgId.Init(msgId);
346356
sessionKey->MaxRcvdMsgId = 0;
347357
sessionKey->RcvFlags = 0;
348358
sessionKey->AuthMode = authMode;
@@ -356,6 +366,9 @@ void WeaveFabricState::SetSessionKey(WeaveSessionKey *sessionKey, uint8_t encTyp
356366
sessionKey->MsgEncKey.KeyId, sessionKey->NodeId, encType, keyString);
357367
}
358368
#endif // WEAVE_CONFIG_SECURITY_TEST_MODE
369+
370+
exit:
371+
return err;
359372
}
360373
361374
WEAVE_ERROR WeaveFabricState::RemoveSessionKey(uint16_t keyId, uint64_t peerNodeId)

src/lib/core/WeaveFabricState.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ class NL_DLL_EXPORT WeaveFabricState
509509

510510
WEAVE_ERROR AllocSessionKey(uint64_t peerNodeId, uint16_t keyId, WeaveConnection *boundCon, WeaveSessionKey *& sessionKey);
511511
WEAVE_ERROR SetSessionKey(uint16_t keyId, uint64_t peerNodeId, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey);
512-
void SetSessionKey(WeaveSessionKey *sessionKey, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey);
512+
WEAVE_ERROR SetSessionKey(WeaveSessionKey *sessionKey, uint8_t encType, WeaveAuthMode authMode, const WeaveEncryptionKey *encKey);
513513
WEAVE_ERROR GetSessionKey(uint16_t keyId, uint64_t peerNodeId, WeaveSessionKey *& outSessionKey);
514514
WEAVE_ERROR FindSessionKey(uint16_t keyId, uint64_t peerNodeId, bool create, WeaveSessionKey *& retRec);
515515
WEAVE_ERROR RemoveSessionKey(uint16_t keyId, uint64_t peerNodeId);

src/lib/core/WeaveSecurityMgr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,6 +2567,7 @@ void WeaveSecurityManager::HandleKeyErrorMsg(ExchangeContext *ec, PacketBuffer*
25672567
WeaveSessionKey *sessionKey;
25682568
uint8_t *p = msgBuf->Start();
25692569
uint64_t srcNodeId = ec->PeerNodeId;
2570+
WeaveConnection *msgCon = ec->Con;
25702571
uint16_t keyId;
25712572
uint8_t encType;
25722573
uint16_t keyErrCode;
@@ -2623,6 +2624,16 @@ void WeaveSecurityManager::HandleKeyErrorMsg(ExchangeContext *ec, PacketBuffer*
26232624
err = FabricState->FindSessionKey(keyId, srcNodeId, false, sessionKey);
26242625
if (err == WEAVE_NO_ERROR)
26252626
{
2627+
// Ignore KeyError if it wasn't received over the same transport mechanism
2628+
// as was used to establish the security session.
2629+
if (msgCon != sessionKey->BoundCon)
2630+
ExitNow();
2631+
2632+
// Ignore KeyError if the message Id value presented in the Key Error message
2633+
// doesn't correspond to the last used message id.
2634+
if (messageId != sessionKey->NextMsgId.GetValue() - 1)
2635+
ExitNow();
2636+
26262637
// If the key refers to a shared session, add the shared session end nodes to the list
26272638
// of peer nodes associated with the key.
26282639
if (sessionKey->IsSharedSession())

0 commit comments

Comments
 (0)