Skip to content

Commit 213869f

Browse files
Stop allocating CASE buffer based on wire sizes (#17296)
* Stop allocating CASE buffer based on wire sizes - CASE was using direct lengths of TLV values to allocate heap values, without validations. - Added validations on lengths of Sigma2/3 TBE, with some room to grow - Updated tag order validation logic to be more explicit and easier to read. Fixes #8924 Test done: - Cert tests still pass - Unit tests still pass * Restyled by clang-format Co-authored-by: Restyled.io <[email protected]>
1 parent 94e8197 commit 213869f

File tree

1 file changed

+66
-25
lines changed

1 file changed

+66
-25
lines changed

src/protocols/secure_channel/CASESession.cpp

+66-25
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,43 @@
4444
#include <transport/PairingSession.h>
4545
#include <transport/SessionManager.h>
4646

47+
namespace {
48+
49+
enum
50+
{
51+
kTag_TBEData_SenderNOC = 1,
52+
kTag_TBEData_SenderICAC = 2,
53+
kTag_TBEData_Signature = 3,
54+
kTag_TBEData_ResumptionID = 4,
55+
};
56+
57+
enum
58+
{
59+
kTag_Sigma1_InitiatorRandom = 1,
60+
kTag_Sigma1_InitiatorSessionId = 2,
61+
kTag_Sigma1_DestinationId = 3,
62+
kTag_Sigma1_InitiatorEphPubKey = 4,
63+
kTag_Sigma1_InitiatorMRPParams = 5,
64+
kTag_Sigma1_ResumptionID = 6,
65+
kTag_Sigma1_InitiatorResumeMIC = 7,
66+
};
67+
68+
enum
69+
{
70+
kTag_Sigma2_ResponderRandom = 1,
71+
kTag_Sigma2_ResponderSessionId = 2,
72+
kTag_Sigma2_ResponderEphPubKey = 3,
73+
kTag_Sigma2_Encrypted2 = 4,
74+
kTag_Sigma2_ResponderMRPParams = 5,
75+
};
76+
77+
enum
78+
{
79+
kTag_Sigma3_Encrypted3 = 1,
80+
};
81+
82+
} // namespace
83+
4784
namespace chip {
4885

4986
using namespace Crypto;
@@ -72,14 +109,6 @@ constexpr uint8_t kTBEData3_Nonce[] =
72109
constexpr size_t kTBEDataNonceLength = sizeof(kTBEData2_Nonce);
73110
static_assert(sizeof(kTBEData2_Nonce) == sizeof(kTBEData3_Nonce), "TBEData2_Nonce and TBEData3_Nonce must be same size");
74111

75-
enum
76-
{
77-
kTag_TBEData_SenderNOC = 1,
78-
kTag_TBEData_SenderICAC = 2,
79-
kTag_TBEData_Signature = 3,
80-
kTag_TBEData_ResumptionID = 4,
81-
};
82-
83112
#ifdef ENABLE_HSM_HKDF
84113
using HKDF_sha_crypto = HKDF_shaHSM;
85114
#else
@@ -846,6 +875,8 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
846875

847876
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R2_Signed;
848877
size_t msg_r2_signed_len;
878+
size_t max_msg_r2_signed_enc_len;
879+
constexpr size_t kCaseOverheadForFutureTbeData = 128;
849880

850881
uint8_t sr2k[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES];
851882

@@ -860,8 +891,6 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
860891

861892
uint16_t responderSessionId;
862893

863-
uint32_t decodeTagIdSeq = 0;
864-
865894
VerifyOrExit(buf != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE);
866895

867896
ChipLogProgress(SecureChannel, "Received Sigma2 msg");
@@ -871,21 +900,18 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
871900
SuccessOrExit(err = tlvReader.EnterContainer(containerType));
872901

873902
// Retrieve Responder's Random value
874-
SuccessOrExit(err = tlvReader.Next());
875-
VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG);
903+
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_Sigma2_ResponderRandom)));
876904
SuccessOrExit(err = tlvReader.GetBytes(responderRandom, sizeof(responderRandom)));
877905

878906
// Assign Session ID
879-
SuccessOrExit(err = tlvReader.Next());
880-
VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG);
907+
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_UnsignedInteger, TLV::ContextTag(kTag_Sigma2_ResponderSessionId)));
881908
SuccessOrExit(err = tlvReader.Get(responderSessionId));
882909

883910
ChipLogDetail(SecureChannel, "Peer assigned session session ID %d", responderSessionId);
884911
SetPeerSessionId(responderSessionId);
885912

886913
// Retrieve Responder's Ephemeral Pubkey
887-
SuccessOrExit(err = tlvReader.Next());
888-
VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG);
914+
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_Sigma2_ResponderEphPubKey)));
889915
SuccessOrExit(err = tlvReader.GetBytes(mRemotePubKey, static_cast<uint32_t>(mRemotePubKey.Length())));
890916

891917
// Generate a Shared Secret
@@ -906,11 +932,18 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
906932
SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ buf, buflen }));
907933

908934
// Generate decrypted data
909-
SuccessOrExit(err = tlvReader.Next());
910-
VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG);
911-
VerifyOrExit(msg_R2_Encrypted.Alloc(tlvReader.GetLength()), err = CHIP_ERROR_NO_MEMORY);
935+
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_Sigma2_Encrypted2)));
936+
937+
max_msg_r2_signed_enc_len =
938+
TLV::EstimateStructOverhead(Credentials::kMaxCHIPCertLength, Credentials::kMaxCHIPCertLength, tbsData2Signature.Length(),
939+
SessionResumptionStorage::kResumptionIdSize, kCaseOverheadForFutureTbeData);
912940
msg_r2_encrypted_len_with_tag = tlvReader.GetLength();
941+
942+
// Validate we did not receive a buffer larger than legal
943+
VerifyOrExit(msg_r2_encrypted_len_with_tag <= max_msg_r2_signed_enc_len, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
913944
VerifyOrExit(msg_r2_encrypted_len_with_tag > CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
945+
VerifyOrExit(msg_R2_Encrypted.Alloc(msg_r2_encrypted_len_with_tag), err = CHIP_ERROR_NO_MEMORY);
946+
914947
SuccessOrExit(err = tlvReader.GetBytes(msg_R2_Encrypted.Get(), static_cast<uint32_t>(msg_r2_encrypted_len_with_tag)));
915948
msg_r2_encrypted_len = msg_r2_encrypted_len_with_tag - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
916949

@@ -971,7 +1004,7 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
9711004
// Retrieve responderMRPParams if present
9721005
if (tlvReader.Next() != CHIP_END_OF_TLV)
9731006
{
974-
SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(5), tlvReader));
1007+
SuccessOrExit(err = DecodeMRPParametersIfPresent(TLV::ContextTag(kTag_Sigma2_ResponderMRPParams), tlvReader));
9751008
}
9761009

9771010
exit:
@@ -1126,9 +1159,12 @@ CHIP_ERROR CASESession::HandleSigma3(System::PacketBufferHandle && msg)
11261159
const uint8_t * buf = msg->Start();
11271160
const uint16_t bufLen = msg->DataLength();
11281161

1162+
constexpr size_t kCaseOverheadForFutureTbeData = 128;
1163+
11291164
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R3_Encrypted;
11301165
size_t msg_r3_encrypted_len = 0;
11311166
size_t msg_r3_encrypted_len_with_tag = 0;
1167+
size_t max_msg_r3_signed_enc_len;
11321168
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R3_Signed;
11331169
size_t msg_r3_signed_len;
11341170

@@ -1144,20 +1180,25 @@ CHIP_ERROR CASESession::HandleSigma3(System::PacketBufferHandle && msg)
11441180

11451181
uint8_t msg_salt[kIPKSize + kSHA256_Hash_Length];
11461182

1147-
uint32_t decodeTagIdSeq = 0;
1148-
11491183
ChipLogProgress(SecureChannel, "Received Sigma3 msg");
11501184

11511185
tlvReader.Init(std::move(msg));
11521186
SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag()));
11531187
SuccessOrExit(err = tlvReader.EnterContainer(containerType));
11541188

11551189
// Fetch encrypted data
1156-
SuccessOrExit(err = tlvReader.Next());
1157-
VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG);
1158-
VerifyOrExit(msg_R3_Encrypted.Alloc(tlvReader.GetLength()), err = CHIP_ERROR_NO_MEMORY);
1190+
max_msg_r3_signed_enc_len = TLV::EstimateStructOverhead(Credentials::kMaxCHIPCertLength, Credentials::kMaxCHIPCertLength,
1191+
tbsData3Signature.Length(), kCaseOverheadForFutureTbeData);
1192+
1193+
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, TLV::ContextTag(kTag_Sigma3_Encrypted3)));
1194+
11591195
msg_r3_encrypted_len_with_tag = tlvReader.GetLength();
1196+
1197+
// Validate we did not receive a buffer larger than legal
1198+
VerifyOrExit(msg_r3_encrypted_len_with_tag <= max_msg_r3_signed_enc_len, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
11601199
VerifyOrExit(msg_r3_encrypted_len_with_tag > CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
1200+
1201+
VerifyOrExit(msg_R3_Encrypted.Alloc(msg_r3_encrypted_len_with_tag), err = CHIP_ERROR_NO_MEMORY);
11611202
SuccessOrExit(err = tlvReader.GetBytes(msg_R3_Encrypted.Get(), static_cast<uint32_t>(msg_r3_encrypted_len_with_tag)));
11621203
msg_r3_encrypted_len = msg_r3_encrypted_len_with_tag - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
11631204

0 commit comments

Comments
 (0)