Skip to content

Commit 2a15d46

Browse files
authored
[CASESession] Follow up to refactoring Sigma Parsing functions PR (#37425)
* Make ConstructTBSData outparam a MutableByteSpan instead of a Pointer + Len * Adding a msgR2Decrypted struct member to improve clarity * Clarifying Logs when Assigining Peer SessionID * Removing TODO on validating signature before validation credentials * changing Logs to ScopedNodeID instead of just NodeID
1 parent a38f2aa commit 2a15d46

File tree

2 files changed

+61
-56
lines changed

2 files changed

+61
-56
lines changed

src/protocols/secure_channel/CASESession.cpp

+52-48
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,7 @@ CASESession::NextStep CASESession::HandleSigma1(System::PacketBufferHandle && ms
10541054

10551055
ReturnErrorVariantOnFailure(NextStep, ParseSigma1(tlvReader, parsedSigma1));
10561056

1057-
ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", parsedSigma1.initiatorSessionId);
1057+
ChipLogDetail(SecureChannel, "Peer (Initiator) assigned session ID %d", parsedSigma1.initiatorSessionId);
10581058
SetPeerSessionId(parsedSigma1.initiatorSessionId);
10591059

10601060
// Set the Session parameters provided in the Sigma1 message
@@ -1222,23 +1222,23 @@ CHIP_ERROR CASESession::PrepareSigma2(EncodeSigma2Inputs & outSigma2Data)
12221222
ReturnErrorOnFailure(DeriveSigmaKey(saltSpan, ByteSpan(kKDFSR2Info), sr2k));
12231223

12241224
// Construct Sigma2 TBS Data
1225-
size_t msgR2SignedLen = EstimateStructOverhead(kMaxCHIPCertLength, // responderNoc
1226-
kMaxCHIPCertLength, // responderICAC
1227-
kP256_PublicKey_Length, // responderEphPubKey
1228-
kP256_PublicKey_Length // InitiatorEphPubKey
1229-
);
1230-
12311225
P256ECDSASignature tbsData2Signature;
12321226
{
1227+
size_t msgR2SignedLen = EstimateStructOverhead(kMaxCHIPCertLength, // responderNoc
1228+
kMaxCHIPCertLength, // responderICAC
1229+
kP256_PublicKey_Length, // responderEphPubKey
1230+
kP256_PublicKey_Length // InitiatorEphPubKey
1231+
);
1232+
12331233
chip::Platform::ScopedMemoryBuffer<uint8_t> msgR2Signed;
12341234
VerifyOrReturnError(msgR2Signed.Alloc(msgR2SignedLen), CHIP_ERROR_NO_MEMORY);
1235+
MutableByteSpan msgR2SignedSpan{ msgR2Signed.Get(), msgR2SignedLen };
12351236

12361237
ReturnErrorOnFailure(ConstructTBSData(nocCert, icaCert, ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()),
1237-
ByteSpan(mRemotePubKey, mRemotePubKey.Length()), msgR2Signed.Get(), msgR2SignedLen));
1238+
ByteSpan(mRemotePubKey, mRemotePubKey.Length()), msgR2SignedSpan));
12381239

12391240
// Generate a Signature
1240-
ReturnErrorOnFailure(
1241-
mFabricsTable->SignWithOpKeypair(mFabricIndex, ByteSpan{ msgR2Signed.Get(), msgR2SignedLen }, tbsData2Signature));
1241+
ReturnErrorOnFailure(mFabricsTable->SignWithOpKeypair(mFabricIndex, msgR2SignedSpan, tbsData2Signature));
12421242
}
12431243
// Construct Sigma2 TBE Data
12441244
size_t msgR2SignedEncLen = EstimateStructOverhead(nocCert.size(), // responderNoc
@@ -1381,7 +1381,8 @@ CHIP_ERROR CASESession::HandleSigma2Resume(System::PacketBufferHandle && msg)
13811381
GetRemoteSessionParameters());
13821382
}
13831383

1384-
ChipLogDetail(SecureChannel, "Peer assigned session ID %d", parsedSigma2Resume.responderSessionId);
1384+
ChipLogDetail(SecureChannel, "Peer " ChipLogFormatScopedNodeId " assigned session ID %d", ChipLogValueScopedNodeId(GetPeer()),
1385+
parsedSigma2Resume.responderSessionId);
13851386
SetPeerSessionId(parsedSigma2Resume.responderSessionId);
13861387

13871388
if (mSessionResumptionStorage != nullptr)
@@ -1517,12 +1518,15 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
15171518
nullptr, 0, parsedSigma2.msgR2MIC.data(), parsedSigma2.msgR2MIC.size(), sr2k.KeyHandle(),
15181519
kTBEData2_Nonce, kTBEDataNonceLength, parsedSigma2.msgR2EncryptedPayload.data()));
15191520

1521+
parsedSigma2.msgR2Decrypted = std::move(parsedSigma2.msgR2Encrypted);
1522+
size_t msgR2DecryptedLength = parsedSigma2.msgR2EncryptedPayload.size();
1523+
15201524
ContiguousBufferTLVReader decryptedDataTlvReader;
1521-
decryptedDataTlvReader.Init(parsedSigma2.msgR2EncryptedPayload.data(), parsedSigma2.msgR2EncryptedPayload.size());
1525+
decryptedDataTlvReader.Init(parsedSigma2.msgR2Decrypted.Get(), msgR2DecryptedLength);
15221526
ParsedSigma2TBEData parsedSigma2TBEData;
15231527
ReturnErrorOnFailure(ParseSigma2TBEData(decryptedDataTlvReader, parsedSigma2TBEData));
15241528

1525-
// Validate responder identity located in msgR2Encrypted
1529+
// Validate responder identity located in msgR2Decrypted
15261530
// Constructing responder identity
15271531
P256PublicKey responderPublicKey;
15281532
{
@@ -1540,7 +1544,7 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
15401544
VerifyOrReturnError(mPeerNodeId == responderNodeId, CHIP_ERROR_INVALID_CASE_PARAMETER);
15411545
}
15421546

1543-
// Construct msgR2Signed and validate the signature in msgR2Encrypted.
1547+
// Construct msgR2Signed and validate the signature in msgR2Decrypted.
15441548
size_t msgR2SignedLen = EstimateStructOverhead(parsedSigma2TBEData.responderNOC.size(), // resonderNOC
15451549
parsedSigma2TBEData.responderICAC.size(), // responderICAC
15461550
kP256_PublicKey_Length, // responderEphPubKey
@@ -1549,16 +1553,18 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
15491553

15501554
chip::Platform::ScopedMemoryBuffer<uint8_t> msgR2Signed;
15511555
VerifyOrReturnError(msgR2Signed.Alloc(msgR2SignedLen), CHIP_ERROR_NO_MEMORY);
1556+
MutableByteSpan msgR2SignedSpan{ msgR2Signed.Get(), msgR2SignedLen };
15521557

1553-
ReturnErrorOnFailure(ConstructTBSData(
1554-
parsedSigma2TBEData.responderNOC, parsedSigma2TBEData.responderICAC, ByteSpan(mRemotePubKey, mRemotePubKey.Length()),
1555-
ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), msgR2Signed.Get(), msgR2SignedLen));
1558+
ReturnErrorOnFailure(ConstructTBSData(parsedSigma2TBEData.responderNOC, parsedSigma2TBEData.responderICAC,
1559+
ByteSpan(mRemotePubKey, mRemotePubKey.Length()),
1560+
ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), msgR2SignedSpan));
15561561

15571562
// Validate signature
1558-
ReturnErrorOnFailure(
1559-
responderPublicKey.ECDSA_validate_msg_signature(msgR2Signed.Get(), msgR2SignedLen, parsedSigma2TBEData.tbsData2Signature));
1563+
ReturnErrorOnFailure(responderPublicKey.ECDSA_validate_msg_signature(msgR2SignedSpan.data(), msgR2SignedSpan.size(),
1564+
parsedSigma2TBEData.tbsData2Signature));
15601565

1561-
ChipLogDetail(SecureChannel, "Peer assigned session ID %d", parsedSigma2.responderSessionId);
1566+
ChipLogDetail(SecureChannel, "Peer " ChipLogFormatScopedNodeId " assigned session ID %d", ChipLogValueScopedNodeId(GetPeer()),
1567+
parsedSigma2.responderSessionId);
15621568
SetPeerSessionId(parsedSigma2.responderSessionId);
15631569

15641570
std::copy(parsedSigma2TBEData.resumptionId.begin(), parsedSigma2TBEData.resumptionId.end(), mNewResumptionId.begin());
@@ -1728,14 +1734,18 @@ CHIP_ERROR CASESession::SendSigma3a()
17281734
ReturnErrorOnFailure(mFabricsTable->FetchNOCCert(mFabricIndex, data.nocCert));
17291735

17301736
// Prepare Sigma3 TBS Data Blob
1731-
data.msg_r3_signed_len =
1732-
EstimateStructOverhead(data.icaCert.size(), data.nocCert.size(), kP256_PublicKey_Length, kP256_PublicKey_Length);
1737+
size_t msgR3SignedLen = EstimateStructOverhead(data.nocCert.size(), // initiatorNOC
1738+
data.icaCert.size(), // initiatorICAC
1739+
kP256_PublicKey_Length, // initiatorEphPubKey
1740+
kP256_PublicKey_Length // responderEphPubKey
1741+
);
17331742

1734-
VerifyOrReturnError(data.msg_R3_Signed.Alloc(data.msg_r3_signed_len), CHIP_ERROR_NO_MEMORY);
1743+
VerifyOrReturnError(data.msgR3Signed.Alloc(msgR3SignedLen), CHIP_ERROR_NO_MEMORY);
1744+
data.msgR3SignedSpan = MutableByteSpan{ data.msgR3Signed.Get(), msgR3SignedLen };
17351745

1736-
ReturnErrorOnFailure(
1737-
ConstructTBSData(data.nocCert, data.icaCert, ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()),
1738-
ByteSpan(mRemotePubKey, mRemotePubKey.Length()), data.msg_R3_Signed.Get(), data.msg_r3_signed_len));
1746+
ReturnErrorOnFailure(ConstructTBSData(data.nocCert, data.icaCert,
1747+
ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()),
1748+
ByteSpan(mRemotePubKey, mRemotePubKey.Length()), data.msgR3SignedSpan));
17391749

17401750
if (data.keystore != nullptr)
17411751
{
@@ -1759,14 +1769,12 @@ CHIP_ERROR CASESession::SendSigma3b(SendSigma3Data & data, bool & cancel)
17591769
if (data.keystore != nullptr)
17601770
{
17611771
// Recommended case: delegate to operational keystore
1762-
ReturnErrorOnFailure(data.keystore->SignWithOpKeypair(
1763-
data.fabricIndex, ByteSpan{ data.msg_R3_Signed.Get(), data.msg_r3_signed_len }, data.tbsData3Signature));
1772+
ReturnErrorOnFailure(data.keystore->SignWithOpKeypair(data.fabricIndex, data.msgR3SignedSpan, data.tbsData3Signature));
17641773
}
17651774
else
17661775
{
17671776
// Legacy case: delegate to fabric table fabric info
1768-
ReturnErrorOnFailure(data.fabricTable->SignWithOpKeypair(
1769-
data.fabricIndex, ByteSpan{ data.msg_R3_Signed.Get(), data.msg_r3_signed_len }, data.tbsData3Signature));
1777+
ReturnErrorOnFailure(data.fabricTable->SignWithOpKeypair(data.fabricIndex, data.msgR3SignedSpan, data.tbsData3Signature));
17701778
}
17711779

17721780
// Prepare Sigma3 TBE Data Blob
@@ -1950,17 +1958,18 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
19501958
SuccessOrExit(err = ParseSigma3TBEData(decryptedDataTlvReader, data));
19511959

19521960
// Step 3 - Construct Sigma3 TBS Data
1953-
data.msgR3SignedLen = TLV::EstimateStructOverhead(data.initiatorNOC.size(), // initiatorNOC
1954-
data.initiatorICAC.size(), // initiatorICAC
1955-
kP256_PublicKey_Length, // initiatorEphPubKey
1956-
kP256_PublicKey_Length // responderEphPubKey
1961+
size_t msgR3SignedLen = TLV::EstimateStructOverhead(data.initiatorNOC.size(), // initiatorNOC
1962+
data.initiatorICAC.size(), // initiatorICAC
1963+
kP256_PublicKey_Length, // initiatorEphPubKey
1964+
kP256_PublicKey_Length // responderEphPubKey
19571965
);
19581966

1959-
VerifyOrExit(data.msgR3Signed.Alloc(data.msgR3SignedLen), err = CHIP_ERROR_NO_MEMORY);
1967+
VerifyOrExit(data.msgR3Signed.Alloc(msgR3SignedLen), err = CHIP_ERROR_NO_MEMORY);
1968+
data.msgR3SignedSpan = MutableByteSpan{ data.msgR3Signed.Get(), msgR3SignedLen };
19601969

19611970
SuccessOrExit(err = ConstructTBSData(data.initiatorNOC, data.initiatorICAC, ByteSpan(mRemotePubKey, mRemotePubKey.Length()),
19621971
ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()),
1963-
data.msgR3Signed.Get(), data.msgR3SignedLen));
1972+
data.msgR3SignedSpan));
19641973

19651974
// Prepare for Step 4/5
19661975
{
@@ -1977,9 +1986,9 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
19771986

19781987
// initiatorNOC and initiatorICAC are spans into msgR3Encrypted
19791988
// which is going away, so to save memory, redirect them to their
1980-
// copies in msg_R3_signed, which is staying around
1989+
// copies in msgR3Signed, which is staying around
19811990
TLV::ContiguousBufferTLVReader signedDataTlvReader;
1982-
signedDataTlvReader.Init(data.msgR3Signed.Get(), data.msgR3SignedLen);
1991+
signedDataTlvReader.Init(data.msgR3SignedSpan);
19831992
SuccessOrExit(err = signedDataTlvReader.Next(containerType, AnonymousTag()));
19841993
SuccessOrExit(err = signedDataTlvReader.EnterContainer(containerType));
19851994

@@ -2089,14 +2098,9 @@ CHIP_ERROR CASESession::HandleSigma3b(HandleSigma3Data & data, bool & cancel)
20892098
unused, initiatorFabricId, data.initiatorNodeId, initiatorPublicKey));
20902099
VerifyOrReturnError(data.fabricId == initiatorFabricId, CHIP_ERROR_INVALID_CASE_PARAMETER);
20912100

2092-
// TODO - Validate message signature prior to validating the received operational credentials.
2093-
// The op cert check requires traversal of cert chain, that is a more expensive operation.
2094-
// If message signature check fails, the cert chain check will be unnecessary, but with the
2095-
// current flow of code, a malicious node can trigger a DoS style attack on the device.
2096-
// The same change should be made in Sigma2 processing.
20972101
// Step 7 - Validate Signature
2098-
ReturnErrorOnFailure(
2099-
initiatorPublicKey.ECDSA_validate_msg_signature(data.msgR3Signed.Get(), data.msgR3SignedLen, data.tbsData3Signature));
2102+
ReturnErrorOnFailure(initiatorPublicKey.ECDSA_validate_msg_signature(data.msgR3SignedSpan.data(), data.msgR3SignedSpan.size(),
2103+
data.tbsData3Signature));
21002104

21012105
return CHIP_NO_ERROR;
21022106
}
@@ -2241,12 +2245,12 @@ CHIP_ERROR CASESession::ValidateSigmaResumeMIC(const ByteSpan & resumeMIC, const
22412245
}
22422246

22432247
CHIP_ERROR CASESession::ConstructTBSData(const ByteSpan & senderNOC, const ByteSpan & senderICAC, const ByteSpan & senderPubKey,
2244-
const ByteSpan & receiverPubKey, uint8_t * tbsData, size_t & tbsDataLen)
2248+
const ByteSpan & receiverPubKey, MutableByteSpan & outTbsData)
22452249
{
22462250
TLVWriter tlvWriter;
22472251
TLVType outerContainerType = kTLVType_NotSpecified;
22482252

2249-
tlvWriter.Init(tbsData, tbsDataLen);
2253+
tlvWriter.Init(outTbsData);
22502254
ReturnErrorOnFailure(tlvWriter.StartContainer(AnonymousTag(), kTLVType_Structure, outerContainerType));
22512255
ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(TBSDataTags::kSenderNOC), senderNOC));
22522256
if (!senderICAC.empty())
@@ -2257,7 +2261,7 @@ CHIP_ERROR CASESession::ConstructTBSData(const ByteSpan & senderNOC, const ByteS
22572261
ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(TBSDataTags::kReceiverPubKey), receiverPubKey));
22582262
ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType));
22592263
ReturnErrorOnFailure(tlvWriter.Finalize());
2260-
tbsDataLen = static_cast<size_t>(tlvWriter.GetLengthWritten());
2264+
outTbsData.reduce_size(static_cast<size_t>(tlvWriter.GetLengthWritten()));
22612265

22622266
return CHIP_NO_ERROR;
22632267
}

src/protocols/secure_channel/CASESession.h

+9-8
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
249249
ByteSpan responderEphPubKey;
250250

251251
Platform::ScopedMemoryBufferWithSize<uint8_t> msgR2Encrypted;
252+
Platform::ScopedMemoryBufferWithSize<uint8_t> msgR2Decrypted;
252253
// Below ByteSpans are Backed by: msgR2Encrypted buffer
253254
// Lifetime: Valid as long as msgR2Encrypted is not released
254255
MutableByteSpan msgR2EncryptedPayload;
@@ -260,8 +261,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
260261

261262
struct ParsedSigma2TBEData
262263
{
263-
// Below ByteSpans are Backed by: msgR2Encrypted Buffer, member of ParsedSigma2 struct
264-
// Lifetime: Valid for the lifetime of the instance of ParsedSigma2 that contains the msgR2Encrypted Buffer.
264+
// Below ByteSpans are Backed by: msgR2Decrypted Buffer, member of ParsedSigma2 struct
265+
// Lifetime: Valid for the lifetime of the instance of ParsedSigma2 that contains the msgR2Decrypted Buffer.
265266
ByteSpan responderNOC;
266267
ByteSpan responderICAC;
267268
ByteSpan resumptionId;
@@ -297,8 +298,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
297298
const FabricTable * fabricTable;
298299
const Crypto::OperationalKeystore * keystore;
299300

300-
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R3_Signed;
301-
size_t msg_r3_signed_len;
301+
chip::Platform::ScopedMemoryBuffer<uint8_t> msgR3Signed;
302+
MutableByteSpan msgR3SignedSpan;
302303

303304
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R3_Encrypted;
304305
size_t msg_r3_encrypted_len;
@@ -315,7 +316,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
315316
struct HandleSigma3Data
316317
{
317318
chip::Platform::ScopedMemoryBuffer<uint8_t> msgR3Signed;
318-
size_t msgR3SignedLen;
319+
MutableByteSpan msgR3SignedSpan;
319320

320321
// Below ByteSpans are Backed by: msgR3Encrypted Buffer, local to the HandleSigma3a() method,
321322
// The Spans are later modified to point to the msgR3Signed member of this struct.
@@ -382,9 +383,9 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
382383
* Parse a decrypted TBEData2Encrypted message. This function will return success only if the message passes schema checks.
383384
*
384385
* @param tlvReader a reference to the TLVReader that points to the decrypted TBEData2Encrypted buffer (i.e.
385-
* msgR2Encrypted member of ParsedSigma2 struct)
386+
* msgR2Decrypted member of ParsedSigma2 struct)
386387
* @param outParsedSigma2TBEData a reference to ParsedSigma2TBEData. All members of parsedMessage will stay valid as long
387-
* as the msgR2Encrypted member of ParsedSigma2 is valid
388+
* as the msgR2Decrypted member of ParsedSigma2 is valid
388389
*
389390
* @note Calls to this function must always be made with a newly created and fresh ParsedSigma2TBEData parameter.
390391
**/
@@ -513,7 +514,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
513514
CHIP_ERROR ConstructSaltSigma2(const ByteSpan & rand, const Crypto::P256PublicKey & pubkey, const ByteSpan & ipk,
514515
MutableByteSpan & salt);
515516
CHIP_ERROR ConstructTBSData(const ByteSpan & senderNOC, const ByteSpan & senderICAC, const ByteSpan & senderPubKey,
516-
const ByteSpan & receiverPubKey, uint8_t * tbsData, size_t & tbsDataLen);
517+
const ByteSpan & receiverPubKey, MutableByteSpan & outTbsData);
517518
CHIP_ERROR ConstructSaltSigma3(const ByteSpan & ipk, MutableByteSpan & salt);
518519

519520
CHIP_ERROR ConstructSigmaResumeKey(const ByteSpan & initiatorRandom, const ByteSpan & resumptionID, const ByteSpan & skInfo,

0 commit comments

Comments
 (0)