Skip to content

Commit

Permalink
Integrating Comments and Adding comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Alami-Amine committed Jan 14, 2025
1 parent 6723bd3 commit a68f2c0
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 51 deletions.
87 changes: 46 additions & 41 deletions src/protocols/secure_channel/CASESession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ constexpr chip::TLV::Tag AsTlvContextTag(Enum e)
return chip::TLV::ContextTag(chip::to_underlying(e));
}

constexpr size_t kCaseOverheadForFutureTbeData = 128;

} // namespace

namespace chip {
Expand Down Expand Up @@ -1520,15 +1522,12 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg)
GetRemoteSessionParameters());
}

size_t msgR2EncryptedLen = parsedSigma2.msgR2Encrypted.AllocatedSize() - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;

ReturnErrorOnFailure(AES_CCM_decrypt(parsedSigma2.msgR2Encrypted.Get(), msgR2EncryptedLen, nullptr, 0,
parsedSigma2.msgR2Encrypted.Get() + msgR2EncryptedLen, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES,
sr2k.KeyHandle(), kTBEData2_Nonce, kTBEDataNonceLength,
parsedSigma2.msgR2Encrypted.Get()));
ReturnErrorOnFailure(AES_CCM_decrypt(parsedSigma2.msgR2EncryptedPayload.data(), parsedSigma2.msgR2EncryptedPayload.size(),
nullptr, 0, parsedSigma2.msgR2Mic.data(), parsedSigma2.msgR2Mic.size(), sr2k.KeyHandle(),
kTBEData2_Nonce, kTBEDataNonceLength, parsedSigma2.msgR2EncryptedPayload.data()));

ContiguousBufferTLVReader decryptedDataTlvReader;
decryptedDataTlvReader.Init(parsedSigma2.msgR2Encrypted.Get(), msgR2EncryptedLen);
decryptedDataTlvReader.Init(parsedSigma2.msgR2EncryptedPayload.data(), parsedSigma2.msgR2EncryptedPayload.size());
ParsedSigma2TBEData parsedSigma2TBEData;
ReturnErrorOnFailure(ParseSigma2TBEData(decryptedDataTlvReader, parsedSigma2TBEData));

Expand Down Expand Up @@ -1600,8 +1599,6 @@ CHIP_ERROR CASESession::ParseSigma2(ContiguousBufferTLVReader & tlvReader, Parse
// Generate decrypted data
ReturnErrorOnFailure(tlvReader.Next(AsTlvContextTag(Sigma2Tags::kEncrypted2)));

constexpr size_t kCaseOverheadForFutureTbeData = 128;

size_t maxMsgR2SignedEncLen = EstimateStructOverhead(kMaxCHIPCertLength, // responderNOC
kMaxCHIPCertLength, // responderICAC
kMax_ECDSA_Signature_Length, // signature
Expand All @@ -1615,9 +1612,13 @@ CHIP_ERROR CASESession::ParseSigma2(ContiguousBufferTLVReader & tlvReader, Parse
VerifyOrReturnError(msgR2EncryptedLenWithTag <= maxMsgR2SignedEncLen, CHIP_ERROR_INVALID_TLV_ELEMENT);
VerifyOrReturnError(msgR2EncryptedLenWithTag > CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, CHIP_ERROR_INVALID_TLV_ELEMENT);
VerifyOrReturnError(outParsedSigma2.msgR2Encrypted.Alloc(msgR2EncryptedLenWithTag), CHIP_ERROR_NO_MEMORY);

ReturnErrorOnFailure(tlvReader.GetBytes(outParsedSigma2.msgR2Encrypted.Get(), outParsedSigma2.msgR2Encrypted.AllocatedSize()));

size_t msgR2EncryptedPayloadLen = msgR2EncryptedLenWithTag - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
outParsedSigma2.msgR2EncryptedPayload = MutableByteSpan(outParsedSigma2.msgR2Encrypted.Get(), msgR2EncryptedPayloadLen);
outParsedSigma2.msgR2Mic =
ByteSpan(outParsedSigma2.msgR2Encrypted.Get() + msgR2EncryptedPayloadLen, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES);

// Retrieve responderSessionParams if present
CHIP_ERROR err = tlvReader.Next();
if (err == CHIP_NO_ERROR && tlvReader.GetTag() == AsTlvContextTag(Sigma2Tags::kResponderSessionParams))
Expand Down Expand Up @@ -1662,11 +1663,10 @@ CHIP_ERROR CASESession::ParseSigma2TBEData(ContiguousBufferTLVReader & decrypted
}

VerifyOrReturnError(decryptedDataTlvReader.GetTag() == AsTlvContextTag(TBEDataTags::kSignature), CHIP_ERROR_INVALID_TLV_TAG);
// TODO verify if the below modification in the check is correct (also for Sigma 3)
// tbsData2Signature's length should equal kMax_ECDSA_Signature_Length as per the Specification
VerifyOrReturnError(outParsedSigma2TBE.tbsData2Signature.Capacity() == decryptedDataTlvReader.GetLength(),
CHIP_ERROR_INVALID_TLV_ELEMENT);
outParsedSigma2TBE.tbsData2Signature.SetLength(decryptedDataTlvReader.GetLength());
size_t signatureLen = decryptedDataTlvReader.GetLength();
VerifyOrReturnError(outParsedSigma2TBE.tbsData2Signature.Capacity() == signatureLen, CHIP_ERROR_INVALID_TLV_ELEMENT);
outParsedSigma2TBE.tbsData2Signature.SetLength(signatureLen);
ReturnErrorOnFailure(decryptedDataTlvReader.GetBytes(outParsedSigma2TBE.tbsData2Signature.Bytes(),
outParsedSigma2TBE.tbsData2Signature.Length()));

Expand Down Expand Up @@ -1893,16 +1893,12 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
{
MATTER_TRACE_SCOPE("HandleSigma3", "CASESession");
CHIP_ERROR err = CHIP_NO_ERROR;
System::PacketBufferTLVReader tlvReader;
ContiguousBufferTLVReader decryptedDataTlvReader;
TLVType containerType = kTLVType_Structure;

const uint8_t * buf = msg->Start();
const size_t bufLen = msg->DataLength();

Platform::ScopedMemoryBufferWithSize<uint8_t> msgR3Encrypted;
size_t msgR3EncryptedLen = 0;

AutoReleaseSessionKey sr3k(*mSessionManager->GetSessionKeystore());

uint8_t msg_salt[kIPKSize + kSHA256_Hash_Length];
Expand All @@ -1925,32 +1921,39 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)

VerifyOrExit(mEphemeralKey != nullptr, err = CHIP_ERROR_INTERNAL);

tlvReader.Init(std::move(msg));

SuccessOrExit(err = ParseSigma3(tlvReader, msgR3Encrypted));

// Step 1
// msgR3Encrypted will be allocated and initialised within ParseSigma3()
Platform::ScopedMemoryBufferWithSize<uint8_t> msgR3Encrypted;
// both msgR3EncryptedPayload and msgR3Mic will become backed by msgR3Encrypted in ParseSigma3()
MutableByteSpan msgR3EncryptedPayload;
ByteSpan msgR3Mic;
{
System::PacketBufferTLVReader tlvReader;
tlvReader.Init(std::move(msg));
SuccessOrExit(err = ParseSigma3(tlvReader, msgR3Encrypted, msgR3EncryptedPayload, msgR3Mic));

// Generate the S3K key
MutableByteSpan saltSpan(msg_salt);
SuccessOrExit(err = ConstructSaltSigma3(ByteSpan(mIPK), saltSpan));
SuccessOrExit(err = DeriveSigmaKey(saltSpan, ByteSpan(kKDFSR3Info), sr3k));
}

SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ buf, bufLen }));

// Add Sigma3 to the TranscriptHash which will be used to generate the Session Encryption Keys
SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ buf, bufLen }));
}
// Step 2 - Decrypt data blob
msgR3EncryptedLen = msgR3Encrypted.AllocatedSize() - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;

SuccessOrExit(err = AES_CCM_decrypt(msgR3Encrypted.Get(), msgR3EncryptedLen, nullptr, 0,
msgR3Encrypted.Get() + msgR3EncryptedLen, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES,
sr3k.KeyHandle(), kTBEData3_Nonce, kTBEDataNonceLength, msgR3Encrypted.Get()));
SuccessOrExit(err = AES_CCM_decrypt(msgR3EncryptedPayload.data(), msgR3EncryptedPayload.size(), nullptr, 0, msgR3Mic.data(),
msgR3Mic.size(), sr3k.KeyHandle(), kTBEData3_Nonce, kTBEDataNonceLength,
msgR3EncryptedPayload.data()));

decryptedDataTlvReader.Init(msgR3Encrypted.Get(), msgR3EncryptedLen);
decryptedDataTlvReader.Init(msgR3EncryptedPayload.data(), msgR3EncryptedPayload.size());
SuccessOrExit(err = ParseSigma3TBEData(decryptedDataTlvReader, data));

// Step 3 - Construct Sigma3 TBS Data
data.msgR3SignedLen = TLV::EstimateStructOverhead(data.initiatorNOC.size(), data.initiatorICAC.size(),
kP256_PublicKey_Length, kP256_PublicKey_Length);
data.msgR3SignedLen = TLV::EstimateStructOverhead(data.initiatorNOC.size(), // initiatorNOC
data.initiatorICAC.size(), // initiatorICAC
kP256_PublicKey_Length, // initiatorEphPubKey
kP256_PublicKey_Length // responderEphPubKey
);

VerifyOrExit(data.msgR3Signed.Alloc(data.msgR3SignedLen), err = CHIP_ERROR_NO_MEMORY);

Expand Down Expand Up @@ -2007,7 +2010,8 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
}

CHIP_ERROR CASESession::ParseSigma3(ContiguousBufferTLVReader & tlvReader,
Platform::ScopedMemoryBufferWithSize<uint8_t> & msgR3Encrypted)
Platform::ScopedMemoryBufferWithSize<uint8_t> & outMsgR3Encrypted,
MutableByteSpan & outMsgR3EncryptedPayload, ByteSpan & outMsgR3Mic)
{
TLVType containerType = kTLVType_Structure;

Expand All @@ -2017,8 +2021,6 @@ CHIP_ERROR CASESession::ParseSigma3(ContiguousBufferTLVReader & tlvReader,
// Fetch encrypted data
ReturnErrorOnFailure(tlvReader.Next(AsTlvContextTag(Sigma3Tags::kEncrypted3)));

constexpr size_t kCaseOverheadForFutureTbeData = 128;

size_t maxMsgR3SignedEncLen = EstimateStructOverhead(kMaxCHIPCertLength, // initiatorNOC
kMaxCHIPCertLength, // initiatorICAC
kMax_ECDSA_Signature_Length, // signature
Expand All @@ -2030,9 +2032,12 @@ CHIP_ERROR CASESession::ParseSigma3(ContiguousBufferTLVReader & tlvReader,
// Validate we did not receive a buffer larger than legal
VerifyOrReturnError(msgR3EncryptedLenWithTag <= maxMsgR3SignedEncLen, CHIP_ERROR_INVALID_TLV_ELEMENT);
VerifyOrReturnError(msgR3EncryptedLenWithTag > CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, CHIP_ERROR_INVALID_TLV_ELEMENT);
VerifyOrReturnError(msgR3Encrypted.Alloc(msgR3EncryptedLenWithTag), CHIP_ERROR_NO_MEMORY);
VerifyOrReturnError(outMsgR3Encrypted.Alloc(msgR3EncryptedLenWithTag), CHIP_ERROR_NO_MEMORY);
ReturnErrorOnFailure(tlvReader.GetBytes(outMsgR3Encrypted.Get(), outMsgR3Encrypted.AllocatedSize()));

ReturnErrorOnFailure(tlvReader.GetBytes(msgR3Encrypted.Get(), msgR3Encrypted.AllocatedSize()));
size_t msgR3EncryptedPayloadLen = msgR3EncryptedLenWithTag - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
outMsgR3EncryptedPayload = MutableByteSpan(outMsgR3Encrypted.Get(), msgR3EncryptedPayloadLen);
outMsgR3Mic = ByteSpan(outMsgR3Encrypted.Get() + msgR3EncryptedPayloadLen, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES);

ReturnErrorOnFailure(tlvReader.ExitContainer(containerType));

Expand Down Expand Up @@ -2060,9 +2065,9 @@ CHIP_ERROR CASESession::ParseSigma3TBEData(ContiguousBufferTLVReader & decrypted
}

VerifyOrReturnError(decryptedDataTlvReader.GetTag() == AsTlvContextTag(TBEDataTags::kSignature), CHIP_ERROR_INVALID_TLV_TAG);
VerifyOrReturnError(outHandleSigma3TBEData.tbsData3Signature.Capacity() == decryptedDataTlvReader.GetLength(),
CHIP_ERROR_INVALID_TLV_ELEMENT);
outHandleSigma3TBEData.tbsData3Signature.SetLength(decryptedDataTlvReader.GetLength());
size_t signatureLen = decryptedDataTlvReader.GetLength();
VerifyOrReturnError(outHandleSigma3TBEData.tbsData3Signature.Capacity() == signatureLen, CHIP_ERROR_INVALID_TLV_ELEMENT);
outHandleSigma3TBEData.tbsData3Signature.SetLength(signatureLen);
ReturnErrorOnFailure(decryptedDataTlvReader.GetBytes(outHandleSigma3TBEData.tbsData3Signature.Bytes(),
outHandleSigma3TBEData.tbsData3Signature.Length()));

Expand Down
90 changes: 83 additions & 7 deletions src/protocols/secure_channel/CASESession.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,

struct ParsedSigma1 : Sigma1Param
{
// Backed by: Sigma1 PacketBuffer passed to the method HandleSigma1()
// Lifetime: Valid for the lifetime of the tlvReader, which takes ownership of the Sigma1 PacketBuffer in the HandleSigma1()
// method.
ByteSpan initiatorEphPubKey;
bool initiatorSessionParamStructPresent = false;
SessionParameters initiatorSessionParams;
Expand All @@ -239,20 +242,30 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
};
struct ParsedSigma2
{
// Below ByteSpans are Backed by: Sigma2 PacketBuffer passed to the method HandleSigma2()
// Lifetime: Valid for the lifetime of the tlvReader, which takes ownership of the Sigma2 PacketBuffer in the HandleSigma2()
// method.
ByteSpan responderRandom;
uint16_t responderSessionId;
ByteSpan responderEphPubKey;

Platform::ScopedMemoryBufferWithSize<uint8_t> msgR2Encrypted;
bool responderSessionParamStructPresent = false;
// Below ByteSpans are Backed by: msgR2Encrypted buffer
// Lifetime: Valid as long as msgR2Encrypted is not released
MutableByteSpan msgR2EncryptedPayload;
ByteSpan msgR2Mic;
SessionParameters responderSessionParams;
uint16_t responderSessionId;
bool responderSessionParamStructPresent = false;
};

struct ParsedSigma2TBEData
{
// Below ByteSpans are Backed by: msgR2Encrypted Buffer, member of ParsedSigma2 struct
// Lifetime: Valid for the lifetime of the instance of ParsedSigma2 that contains the msgR2Encrypted Buffer.
ByteSpan responderNOC;
ByteSpan responderICAC;
Crypto::P256ECDSASignature tbsData2Signature;
ByteSpan resumptionId;
Crypto::P256ECDSASignature tbsData2Signature;
};

struct EncodeSigma2ResumeInputs
Expand All @@ -266,10 +279,13 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,

struct ParsedSigma2Resume
{
// Below ByteSpans are Backed by: Sigma2Resume PacketBuffer passed to the method HandleSigma2Resume()
// Lifetime: Valid for the lifetime of the tlvReader, which takes ownership of the Sigma2Resume PacketBuffer in the
// HandleSigma2Resume() method.
ByteSpan resumptionId;
ByteSpan sigma2ResumeMIC;
uint16_t responderSessionId;
SessionParameters responderSessionParams;
uint16_t responderSessionId;
bool responderSessionParamStructPresent = false;
};

Expand Down Expand Up @@ -301,6 +317,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
chip::Platform::ScopedMemoryBuffer<uint8_t> msgR3Signed;
size_t msgR3SignedLen;

// Below ByteSpans are Backed by: msgR3Encrypted Buffer, local to the HandleSigma3a() method,
// The Spans are later modified to point to the msgR3Signed member of this struct.
ByteSpan initiatorNOC;
ByteSpan initiatorICAC;

Expand Down Expand Up @@ -348,10 +366,40 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
*/
static CHIP_ERROR ParseSigma1(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma1 & parsedMessage);

static CHIP_ERROR ParseSigma2(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma2 & parsedMessage);
/**
* Parse a Sigma2 message. This function will return success only if the
* message passes schema checks.
*
* @param tlvReader a reference to the TLVReader that has ownership of the Sigma2 PacketBuffer.
* @param outParsedSigma2 a reference to ParsedSigma2. All members of parsedMessage will stay valid as long as tlvReader is
* valid.
*
* @note Calls to this function must always be made with a newly created and fresh ParsedSigma2 parameter.
**/
static CHIP_ERROR ParseSigma2(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma2 & outParsedSigma2);

static CHIP_ERROR ParseSigma2TBEData(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma2TBEData & parsedMessage);
/**
* Parse a decrypted TBEData2Encrypted message. This function will return success only if the message passes schema checks.
*
* @param tlvReader a reference to the TLVReader that points to the decrypted TBEData2Encrypted buffer (i.e.
* msgR2Encrypted member of ParsedSigma2 struct)
* @param outParsedSigma2TBEData a reference to ParsedSigma2TBEData. All members of parsedMessage will stay valid as long
* as the msgR2Encrypted member of ParsedSigma2 is valid
*
* @note Calls to this function must always be made with a newly created and fresh ParsedSigma2TBEData parameter.
**/
static CHIP_ERROR ParseSigma2TBEData(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma2TBEData & outParsedSigma2TBEData);

/**
* Parse a Sigma2Resume message. This function will return success only if the
* message passes schema checks.
*
* @param tlvReader a reference to the TLVReader that has ownership of the Sigma2Resume PacketBuffer.
* @param outParsedSigma2Resume a reference to ParsedSigma2Resume. All members of parsedMessage will stay valid as long
* as tlvReader is valid.
*
* @note Calls to this function must always be made with a newly created and fresh ParsedSigma2Resume parameter.
**/
static CHIP_ERROR ParseSigma2Resume(TLV::ContiguousBufferTLVReader & tlvReader, ParsedSigma2Resume & outParsedSigma2Resume);

/**
Expand Down Expand Up @@ -380,9 +428,37 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
**/
static CHIP_ERROR EncodeSigma2Resume(System::PacketBufferHandle & outMsg, EncodeSigma2ResumeInputs & inParam);

/**
* Parse a Sigma3 message. This function will return success only if the
* message passes schema checks.
*
* @param tlvReader a reference to the TLVReader that has ownership of the Sigma3 PacketBuffer.
*
* @param outMsgR3Encrypted The encrypted3 (TBEData3Encrypted) TLV element. This will be a buffer that is owned by the caller
* but is allocated and initialised within ParseSigma3. Calls to this function must always be made with
* a newly created and fresh outMsgR3Encrypted
*
* @param outMsgR3EncryptedPayload reference to a span that will be set to point to the payload of outMsgR3Encrypted within
* ParseSigma3. Calls to this function must always be made with a newly created and fresh
* outMsgR3Mic
*
* @param outMsgR3Mic reference to a span that will be set to point to the MIC of outMsgR3Encrypted within ParseSigma3.
* Calls to this function must always be made with a newly created and fresh outMsgR3Mic
*
* @note all out parameters will be valid as long the Buffer outMsgR3Encrypted is valid.
**/
static CHIP_ERROR ParseSigma3(TLV::ContiguousBufferTLVReader & tlvReader,
Platform::ScopedMemoryBufferWithSize<uint8_t> & msgR3Encrypted);
Platform::ScopedMemoryBufferWithSize<uint8_t> & outMsgR3Encrypted,
MutableByteSpan & outMsgR3EncryptedPayload, ByteSpan & outMsgR3Mic);

/**
* Parse a decrypted TBEData3Encrypted message. This function will return success only if the
* message passes schema checks.
*
* @param tlvReader a reference to the TLVReader that points to the decrypted TBEData3Encrypted buffer.
* @param data a reference to HandleSigma3Data.
*
**/
static CHIP_ERROR ParseSigma3TBEData(TLV::ContiguousBufferTLVReader & tlvReader, HandleSigma3Data & data);

private:
Expand Down
Loading

0 comments on commit a68f2c0

Please sign in to comment.