Skip to content

Commit d785361

Browse files
committed
factoring out ParseSigma2
1 parent 2ca952f commit d785361

File tree

2 files changed

+128
-65
lines changed

2 files changed

+128
-65
lines changed

src/protocols/secure_channel/CASESession.cpp

+112-65
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,7 @@ CHIP_ERROR CASESession::HandleSigma2Resume(System::PacketBufferHandle && msg)
14421442
GetRemoteSessionParameters());
14431443
}
14441444

1445-
ChipLogDetail(SecureChannel, "Peer assigned session session ID %d", responderSessionId);
1445+
ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", responderSessionId);
14461446
SetPeerSessionId(responderSessionId);
14471447

14481448
if (mSessionResumptionStorage != nullptr)
@@ -1485,24 +1485,16 @@ CHIP_ERROR CASESession::HandleSigma2_and_SendSigma3(System::PacketBufferHandle &
14851485
CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
14861486
{
14871487
MATTER_TRACE_SCOPE("HandleSigma2", "CASESession");
1488-
CHIP_ERROR err = CHIP_NO_ERROR;
1489-
System::PacketBufferTLVReader tlvReader;
1490-
TLV::TLVReader decryptedDataTlvReader;
1491-
TLV::TLVType containerType = TLV::kTLVType_Structure;
1488+
TLVReader decryptedDataTlvReader;
14921489

14931490
const uint8_t * buf = msg->Start();
14941491
size_t buflen = msg->DataLength();
14951492

14961493
uint8_t msg_salt[kIPKSize + kSigmaParamRandomNumberSize + kP256_PublicKey_Length + kSHA256_Hash_Length];
14971494

14981495
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R2_Encrypted;
1499-
size_t msg_r2_encrypted_len = 0;
1500-
size_t msg_r2_encrypted_len_with_tag = 0;
15011496

15021497
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R2_Signed;
1503-
size_t msg_r2_signed_len;
1504-
size_t max_msg_r2_signed_enc_len;
1505-
constexpr size_t kCaseOverheadForFutureTbeData = 128;
15061498

15071499
AutoReleaseSessionKey sr2k(*mSessionManager->GetSessionKeystore());
15081500

@@ -1511,13 +1503,24 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
15111503
NodeId responderNodeId;
15121504
P256PublicKey responderPublicKey;
15131505

1514-
uint8_t responderRandom[kSigmaParamRandomNumberSize];
1506+
// uint8_t responderRandom[kSigmaParamRandomNumberSize];
15151507
ByteSpan responderNOC;
15161508
ByteSpan responderICAC;
15171509

1518-
uint16_t responderSessionId;
1510+
// uint16_t responderSessionId;
1511+
1512+
TLVType containerType = kTLVType_Structure;
1513+
size_t msg_r2_signed_len;
1514+
1515+
size_t msg_r2_encrypted_len = 0;
15191516

15201517
ChipLogProgress(SecureChannel, "Received Sigma2 msg");
1518+
CHIP_ERROR err = CHIP_NO_ERROR;
1519+
1520+
System::PacketBufferTLVReader tlvReader;
1521+
tlvReader.Init(std::move(msg));
1522+
1523+
ParsedSigma2 parsedSigma2;
15211524

15221525
FabricId fabricId = kUndefinedFabricId;
15231526
{
@@ -1530,71 +1533,56 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
15301533
VerifyOrExit(mEphemeralKey != nullptr, err = CHIP_ERROR_INTERNAL);
15311534
VerifyOrExit(buf != nullptr, err = CHIP_ERROR_MESSAGE_INCOMPLETE);
15321535

1533-
tlvReader.Init(std::move(msg));
1534-
SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag()));
1535-
SuccessOrExit(err = tlvReader.EnterContainer(containerType));
1536-
1537-
// Retrieve Responder's Random value
1538-
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(Sigma2Tags::kResponderRandom)));
1539-
SuccessOrExit(err = tlvReader.GetBytes(responderRandom, sizeof(responderRandom)));
1536+
SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ buf, buflen }));
15401537

1541-
// Assign Session ID
1542-
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_UnsignedInteger, AsTlvContextTag(Sigma2Tags::kResponderSessionId)));
1543-
SuccessOrExit(err = tlvReader.Get(responderSessionId));
1538+
ParseSigma2(tlvReader, parsedSigma2);
15441539

1545-
ChipLogDetail(SecureChannel, "Peer assigned session session ID %d", responderSessionId);
1546-
SetPeerSessionId(responderSessionId);
1540+
ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", parsedSigma2.responderSessionId);
1541+
SetPeerSessionId(parsedSigma2.responderSessionId);
15471542

1548-
// Retrieve Responder's Ephemeral Pubkey
1549-
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(Sigma2Tags::kResponderEphPubKey)));
1550-
SuccessOrExit(err = tlvReader.GetBytes(mRemotePubKey, static_cast<uint32_t>(mRemotePubKey.Length())));
1543+
// ParseSigma2 ensures that:
1544+
// mRemotePubKey.Length() == responderEphPubKey.size() == kP256_PublicKey_Length.
1545+
memcpy(mRemotePubKey.Bytes(), parsedSigma2.responderEphPubKey.data(), mRemotePubKey.Length());
15511546

15521547
// Generate a Shared Secret
15531548
SuccessOrExit(err = mEphemeralKey->ECDH_derive_secret(mRemotePubKey, mSharedSecret));
15541549

15551550
// Generate the S2K key
15561551
{
15571552
MutableByteSpan saltSpan(msg_salt);
1558-
SuccessOrExit(err = ConstructSaltSigma2(ByteSpan(responderRandom), mRemotePubKey, ByteSpan(mIPK), saltSpan));
1559-
SuccessOrExit(err = DeriveSigmaKey(saltSpan, ByteSpan(kKDFSR2Info), sr2k));
1553+
ReturnErrorOnFailure(
1554+
err = ConstructSaltSigma2(ByteSpan(parsedSigma2.responderRandom), mRemotePubKey, ByteSpan(mIPK), saltSpan));
1555+
ReturnErrorOnFailure(err = DeriveSigmaKey(saltSpan, ByteSpan(kKDFSR2Info), sr2k));
15601556
}
15611557

1562-
SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ buf, buflen }));
1563-
1564-
// Generate decrypted data
1565-
SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(Sigma2Tags::kEncrypted2)));
1566-
1567-
max_msg_r2_signed_enc_len =
1568-
TLV::EstimateStructOverhead(Credentials::kMaxCHIPCertLength, Credentials::kMaxCHIPCertLength, tbsData2Signature.Length(),
1569-
SessionResumptionStorage::kResumptionIdSize, kCaseOverheadForFutureTbeData);
1570-
msg_r2_encrypted_len_with_tag = tlvReader.GetLength();
1571-
1572-
// Validate we did not receive a buffer larger than legal
1573-
VerifyOrExit(msg_r2_encrypted_len_with_tag <= max_msg_r2_signed_enc_len, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
1574-
VerifyOrExit(msg_r2_encrypted_len_with_tag > CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
1575-
VerifyOrExit(msg_R2_Encrypted.Alloc(msg_r2_encrypted_len_with_tag), err = CHIP_ERROR_NO_MEMORY);
1558+
if (parsedSigma2.responderMrpParamsPresent)
1559+
{
1560+
SetRemoteSessionParameters(parsedSigma2.responderSessionParams);
1561+
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
1562+
GetRemoteSessionParameters());
1563+
}
1564+
/**********************************************************************************************************************************
1565+
*/
15761566

1577-
SuccessOrExit(err = tlvReader.GetBytes(msg_R2_Encrypted.Get(), static_cast<uint32_t>(msg_r2_encrypted_len_with_tag)));
1578-
msg_r2_encrypted_len = msg_r2_encrypted_len_with_tag - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
1567+
msg_r2_encrypted_len = parsedSigma2.msgR2Encrypted.AllocatedSize() - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
15791568

1580-
SuccessOrExit(err = AES_CCM_decrypt(msg_R2_Encrypted.Get(), msg_r2_encrypted_len, nullptr, 0,
1581-
msg_R2_Encrypted.Get() + msg_r2_encrypted_len, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES,
1582-
sr2k.KeyHandle(), kTBEData2_Nonce, kTBEDataNonceLength, msg_R2_Encrypted.Get()));
1569+
SuccessOrExit(err = AES_CCM_decrypt(parsedSigma2.msgR2Encrypted.Get(), msg_r2_encrypted_len, nullptr, 0,
1570+
parsedSigma2.msgR2Encrypted.Get() + msg_r2_encrypted_len, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES,
1571+
sr2k.KeyHandle(), kTBEData2_Nonce, kTBEDataNonceLength, parsedSigma2.msgR2Encrypted.Get()));
15831572

1584-
decryptedDataTlvReader.Init(msg_R2_Encrypted.Get(), msg_r2_encrypted_len);
1585-
containerType = TLV::kTLVType_Structure;
1586-
SuccessOrExit(err = decryptedDataTlvReader.Next(containerType, TLV::AnonymousTag()));
1573+
decryptedDataTlvReader.Init(parsedSigma2.msgR2Encrypted.Get(), msg_r2_encrypted_len);
1574+
SuccessOrExit(err = decryptedDataTlvReader.Next(containerType, AnonymousTag()));
15871575
SuccessOrExit(err = decryptedDataTlvReader.EnterContainer(containerType));
15881576

1589-
SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSenderNOC)));
1577+
SuccessOrExit(err = decryptedDataTlvReader.Next(kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSenderNOC)));
15901578
SuccessOrExit(err = decryptedDataTlvReader.Get(responderNOC));
15911579

15921580
SuccessOrExit(err = decryptedDataTlvReader.Next());
15931581
if (decryptedDataTlvReader.GetTag() == AsTlvContextTag(TBEDataTags::kSenderICAC))
15941582
{
1595-
VerifyOrExit(decryptedDataTlvReader.GetType() == TLV::kTLVType_ByteString, err = CHIP_ERROR_WRONG_TLV_TYPE);
1583+
VerifyOrExit(decryptedDataTlvReader.GetType() == kTLVType_ByteString, err = CHIP_ERROR_WRONG_TLV_TYPE);
15961584
SuccessOrExit(err = decryptedDataTlvReader.Get(responderICAC));
1597-
SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSignature)));
1585+
SuccessOrExit(err = decryptedDataTlvReader.Next(kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSignature)));
15981586
}
15991587

16001588
// Validate responder identity located in msg_r2_encrypted
@@ -1612,8 +1600,8 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
16121600
}
16131601

16141602
// Construct msg_R2_Signed and validate the signature in msg_r2_encrypted
1615-
msg_r2_signed_len = TLV::EstimateStructOverhead(sizeof(uint16_t), responderNOC.size(), responderICAC.size(),
1616-
kP256_PublicKey_Length, kP256_PublicKey_Length);
1603+
msg_r2_signed_len = EstimateStructOverhead(sizeof(uint16_t), responderNOC.size(), responderICAC.size(), kP256_PublicKey_Length,
1604+
kP256_PublicKey_Length);
16171605

16181606
VerifyOrExit(msg_R2_Signed.Alloc(msg_r2_signed_len), err = CHIP_ERROR_NO_MEMORY);
16191607

@@ -1630,20 +1618,12 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
16301618
SuccessOrExit(err = responderPublicKey.ECDSA_validate_msg_signature(msg_R2_Signed.Get(), msg_r2_signed_len, tbsData2Signature));
16311619

16321620
// Retrieve session resumption ID
1633-
SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kResumptionID)));
1621+
SuccessOrExit(err = decryptedDataTlvReader.Next(kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kResumptionID)));
16341622
SuccessOrExit(err = decryptedDataTlvReader.GetBytes(mNewResumptionId.data(), mNewResumptionId.size()));
16351623

16361624
// Retrieve peer CASE Authenticated Tags (CATs) from peer's NOC.
16371625
SuccessOrExit(err = ExtractCATsFromOpCert(responderNOC, mPeerCATs));
16381626

1639-
// Retrieve responderMRPParams if present
1640-
if (tlvReader.Next() != CHIP_END_OF_TLV)
1641-
{
1642-
SuccessOrExit(err = DecodeMRPParametersIfPresent(AsTlvContextTag(Sigma2Tags::kResponderSessionParams), tlvReader));
1643-
mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(
1644-
GetRemoteSessionParameters());
1645-
}
1646-
16471627
exit:
16481628
if (err != CHIP_NO_ERROR)
16491629
{
@@ -2378,6 +2358,73 @@ CHIP_ERROR CASESession::ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader,
23782358
return CHIP_NO_ERROR;
23792359
}
23802360

2361+
CHIP_ERROR CASESession::ParseSigma2(ContiguousBufferTLVReader & tlvReader, ParsedSigma2 & outParsedSigma2)
2362+
{
2363+
CHIP_ERROR err = CHIP_NO_ERROR;
2364+
TLVType containerType = kTLVType_Structure;
2365+
2366+
// FIND A SOLUTION TO THIS:
2367+
P256ECDSASignature tbsData2Signature;
2368+
2369+
ReturnErrorOnFailure(err = tlvReader.Next(containerType, AnonymousTag()));
2370+
ReturnErrorOnFailure(err = tlvReader.EnterContainer(containerType));
2371+
2372+
// Retrieve Responder's Random value
2373+
ReturnErrorOnFailure(err = tlvReader.Next(kTLVType_ByteString, AsTlvContextTag(Sigma2Tags::kResponderRandom)));
2374+
ReturnErrorOnFailure(err = tlvReader.GetByteView(outParsedSigma2.responderRandom));
2375+
VerifyOrReturnError(outParsedSigma2.responderRandom.size() == kSigmaParamRandomNumberSize, CHIP_ERROR_INVALID_CASE_PARAMETER);
2376+
2377+
// Assign Session ID
2378+
ReturnErrorOnFailure(err = tlvReader.Next(kTLVType_UnsignedInteger, AsTlvContextTag(Sigma2Tags::kResponderSessionId)));
2379+
ReturnErrorOnFailure(err = tlvReader.Get(outParsedSigma2.responderSessionId));
2380+
2381+
// Retrieve Responder's Ephemeral Pubkey
2382+
ReturnErrorOnFailure(err = tlvReader.Next(kTLVType_ByteString, AsTlvContextTag(Sigma2Tags::kResponderEphPubKey)));
2383+
ReturnErrorOnFailure(tlvReader.GetByteView(outParsedSigma2.responderEphPubKey));
2384+
VerifyOrReturnError(outParsedSigma2.responderEphPubKey.size() == kP256_PublicKey_Length, CHIP_ERROR_INVALID_CASE_PARAMETER);
2385+
2386+
// ReturnErrorOnFailure(err = tlvReader.GetBytes(mRemotePubKey, static_cast<uint32_t>(mRemotePubKey.Length())));
2387+
2388+
// Generate decrypted data
2389+
ReturnErrorOnFailure(err = tlvReader.Next(kTLVType_ByteString, AsTlvContextTag(Sigma2Tags::kEncrypted2)));
2390+
2391+
// TODO find a solution to this
2392+
// size_t msg_r2_encrypted_len = 0;
2393+
2394+
size_t msg_r2_encrypted_len_with_tag = 0;
2395+
2396+
constexpr size_t kCaseOverheadForFutureTbeData = 128;
2397+
2398+
size_t max_msg_r2_signed_enc_len;
2399+
2400+
max_msg_r2_signed_enc_len =
2401+
EstimateStructOverhead(Credentials::kMaxCHIPCertLength, Credentials::kMaxCHIPCertLength, tbsData2Signature.Length(),
2402+
SessionResumptionStorage::kResumptionIdSize, kCaseOverheadForFutureTbeData);
2403+
msg_r2_encrypted_len_with_tag = tlvReader.GetLength();
2404+
2405+
// Validate we did not receive a buffer larger than legal
2406+
// TODO why are comparing this to the "signed one"
2407+
// Maybe it is signed encrypted, but is the estimation calculated well? document it
2408+
VerifyOrReturnError(msg_r2_encrypted_len_with_tag <= max_msg_r2_signed_enc_len, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
2409+
VerifyOrReturnError(msg_r2_encrypted_len_with_tag > CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
2410+
VerifyOrReturnError(outParsedSigma2.msgR2Encrypted.Alloc(msg_r2_encrypted_len_with_tag), err = CHIP_ERROR_NO_MEMORY);
2411+
2412+
// TODO, should I keep this as GetBytes? or should I use GetByteView for consistency and do something else?
2413+
ReturnErrorOnFailure(
2414+
err = tlvReader.GetBytes(outParsedSigma2.msgR2Encrypted.Get(), outParsedSigma2.msgR2Encrypted.AllocatedSize()));
2415+
// msg_r2_encrypted_len = msg_r2_encrypted_len_with_tag - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
2416+
2417+
// Retrieve responderMRPParams if present
2418+
if (tlvReader.Next() != CHIP_END_OF_TLV)
2419+
{
2420+
ReturnErrorOnFailure(err = DecodeMRPParametersIfPresent(AsTlvContextTag(Sigma2Tags::kResponderSessionParams), tlvReader,
2421+
outParsedSigma2.responderSessionParams));
2422+
outParsedSigma2.responderMrpParamsPresent = true;
2423+
}
2424+
2425+
return CHIP_NO_ERROR;
2426+
}
2427+
23812428
CHIP_ERROR CASESession::ValidateReceivedMessage(ExchangeContext * ec, const PayloadHeader & payloadHeader,
23822429
const System::PacketBufferHandle & msg)
23832430
{

src/protocols/secure_channel/CASESession.h

+16
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,20 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
247247
const ReliableMessageProtocolConfig * responderMrpConfig;
248248
};
249249

250+
struct ParsedSigma2
251+
{
252+
// TODO responderRandom is ByteSpan in ParsedSigma2 but is an array in EncodeSigma2Inputs
253+
ByteSpan responderRandom;
254+
uint16_t responderSessionId;
255+
// TODO, If I will inherit, remember that this different from EncodeSigma2Inputs
256+
ByteSpan responderEphPubKey;
257+
258+
Platform::ScopedMemoryBufferWithSize<uint8_t> msgR2Encrypted;
259+
size_t encrypted2Length = 0;
260+
const ReliableMessageProtocolConfig * responderMrpConfig;
261+
bool responderMrpParamsPresent = false;
262+
SessionParameters responderSessionParams;
263+
};
250264
/**
251265
* @brief Encodes a Sigma1 message into TLV format and allocates a buffer for it, which is owned by the PacketBufferHandle
252266
* outparam.
@@ -278,6 +292,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
278292
*/
279293
static CHIP_ERROR ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma1 & parsedMessage);
280294

295+
static CHIP_ERROR ParseSigma2(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma2 & parsedMessage);
296+
281297
/**
282298
* @brief Encodes a Sigma2 message into TLV format and allocates a buffer for it, which is owned by the PacketBufferHandle
283299
* outparam.

0 commit comments

Comments
 (0)