Skip to content

Commit

Permalink
Factor out ParseSigma3 and ParseSigma3TBEData
Browse files Browse the repository at this point in the history
  • Loading branch information
Alami-Amine committed Jan 11, 2025
1 parent 4e033de commit 5c9281b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 67 deletions.
141 changes: 75 additions & 66 deletions src/protocols/secure_channel/CASESession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,25 +372,6 @@ struct CASESession::SendSigma3Data
P256ECDSASignature tbsData3Signature;
};

struct CASESession::HandleSigma3Data
{
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R3_Signed;
size_t msg_r3_signed_len;

ByteSpan initiatorNOC;
ByteSpan initiatorICAC;

uint8_t rootCertBuf[kMaxCHIPCertLength];
ByteSpan fabricRCAC;

P256ECDSASignature tbsData3Signature;

FabricId fabricId;
NodeId initiatorNodeId;

ValidationContext validContext;
};

CASESession::~CASESession()
{
// Let's clear out any security state stored in the object, before destroying it.
Expand Down Expand Up @@ -1947,18 +1928,14 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
MATTER_TRACE_SCOPE("HandleSigma3", "CASESession");
CHIP_ERROR err = CHIP_NO_ERROR;
System::PacketBufferTLVReader tlvReader;
TLV::TLVReader decryptedDataTlvReader;
TLV::ContiguousBufferTLVReader decryptedDataTlvReader;
TLV::TLVType containerType = TLV::kTLVType_Structure;

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

constexpr size_t kCaseOverheadForFutureTbeData = 128;

chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R3_Encrypted;
size_t msg_r3_encrypted_len = 0;
size_t msg_r3_encrypted_len_with_tag = 0;
size_t max_msg_r3_signed_enc_len;
Platform::ScopedMemoryBufferWithSize<uint8_t> msgR3Encrypted;
size_t msgR3EncryptedLen = 0;

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

Expand All @@ -1983,24 +1960,8 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
VerifyOrExit(mEphemeralKey != nullptr, err = CHIP_ERROR_INTERNAL);

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

// Fetch encrypted data
max_msg_r3_signed_enc_len = TLV::EstimateStructOverhead(Credentials::kMaxCHIPCertLength, Credentials::kMaxCHIPCertLength,
data.tbsData3Signature.Length(), kCaseOverheadForFutureTbeData);

SuccessOrExit(err = tlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(Sigma3Tags::kEncrypted3)));

msg_r3_encrypted_len_with_tag = tlvReader.GetLength();

// Validate we did not receive a buffer larger than legal
VerifyOrExit(msg_r3_encrypted_len_with_tag <= max_msg_r3_signed_enc_len, err = CHIP_ERROR_INVALID_TLV_ELEMENT);
VerifyOrExit(msg_r3_encrypted_len_with_tag > CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, err = CHIP_ERROR_INVALID_TLV_ELEMENT);

VerifyOrExit(msg_R3_Encrypted.Alloc(msg_r3_encrypted_len_with_tag), err = CHIP_ERROR_NO_MEMORY);
SuccessOrExit(err = tlvReader.GetBytes(msg_R3_Encrypted.Get(), static_cast<uint32_t>(msg_r3_encrypted_len_with_tag)));
msg_r3_encrypted_len = msg_r3_encrypted_len_with_tag - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;
SuccessOrExit(err = ParseSigma3(tlvReader, msgR3Encrypted));

// Step 1
{
Expand All @@ -2012,27 +1973,17 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
SuccessOrExit(err = mCommissioningHash.AddData(ByteSpan{ buf, bufLen }));

// Step 2 - Decrypt data blob
SuccessOrExit(err = AES_CCM_decrypt(msg_R3_Encrypted.Get(), msg_r3_encrypted_len, nullptr, 0,
msg_R3_Encrypted.Get() + msg_r3_encrypted_len, CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES,
sr3k.KeyHandle(), kTBEData3_Nonce, kTBEDataNonceLength, msg_R3_Encrypted.Get()));
msgR3EncryptedLen = msgR3Encrypted.AllocatedSize() - CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES;

decryptedDataTlvReader.Init(msg_R3_Encrypted.Get(), msg_r3_encrypted_len);
containerType = TLV::kTLVType_Structure;
SuccessOrExit(err = decryptedDataTlvReader.Next(containerType, TLV::AnonymousTag()));
SuccessOrExit(err = decryptedDataTlvReader.EnterContainer(containerType));
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 = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSenderNOC)));
SuccessOrExit(err = decryptedDataTlvReader.Get(data.initiatorNOC));
decryptedDataTlvReader.Init(msgR3Encrypted.Get(), msgR3EncryptedLen);

SuccessOrExit(err = decryptedDataTlvReader.Next());
if (decryptedDataTlvReader.GetTag() == AsTlvContextTag(TBEDataTags::kSenderICAC))
{
VerifyOrExit(decryptedDataTlvReader.GetType() == TLV::kTLVType_ByteString, err = CHIP_ERROR_WRONG_TLV_TYPE);
SuccessOrExit(err = decryptedDataTlvReader.Get(data.initiatorICAC));
SuccessOrExit(err = decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSignature)));
}
SuccessOrExit(err = ParseSigma3TBEData(decryptedDataTlvReader, data));

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

Expand All @@ -2042,12 +1993,7 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()),
data.msg_R3_Signed.Get(), data.msg_r3_signed_len));

VerifyOrExit(decryptedDataTlvReader.GetTag() == AsTlvContextTag(TBEDataTags::kSignature), err = CHIP_ERROR_INVALID_TLV_TAG);
VerifyOrExit(data.tbsData3Signature.Capacity() >= decryptedDataTlvReader.GetLength(), err = CHIP_ERROR_INVALID_TLV_ELEMENT);
data.tbsData3Signature.SetLength(decryptedDataTlvReader.GetLength());
SuccessOrExit(err = decryptedDataTlvReader.GetBytes(data.tbsData3Signature.Bytes(), data.tbsData3Signature.Length()));

// Prepare for Step 5/6
// Prepare for Step 4/5
{
MutableByteSpan fabricRCAC{ data.rootCertBuf };
SuccessOrExit(err = mFabricsTable->FetchRootCert(mFabricIndex, fabricRCAC));
Expand Down Expand Up @@ -2093,6 +2039,69 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg)
return err;
}

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

ReturnErrorOnFailure(tlvReader.Next(containerType, AnonymousTag()));
ReturnErrorOnFailure(tlvReader.EnterContainer(containerType));

// Fetch encrypted data
size_t maxMsgR3SignedEncLen;
constexpr size_t kCaseOverheadForFutureTbeData = 128;

maxMsgR3SignedEncLen = EstimateStructOverhead(Credentials::kMaxCHIPCertLength, // initiatorNOC
Credentials::kMaxCHIPCertLength, // initiatorICAC
kMax_ECDSA_Signature_Length, // signature
kCaseOverheadForFutureTbeData // extra bytes for future-proofing
);

ReturnErrorOnFailure(tlvReader.Next(kTLVType_ByteString, AsTlvContextTag(Sigma3Tags::kEncrypted3)));

size_t msgR3EncryptedLenWithTag = 0;
msgR3EncryptedLenWithTag = tlvReader.GetLength();

// 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);
ReturnErrorOnFailure(tlvReader.GetBytes(msgR3Encrypted.Get(), static_cast<uint32_t>(msgR3EncryptedLenWithTag)));

ReturnErrorOnFailure(tlvReader.ExitContainer(containerType));

return CHIP_NO_ERROR;
}

CHIP_ERROR CASESession::ParseSigma3TBEData(ContiguousBufferTLVReader & decryptedDataTlvReader, HandleSigma3Data & data)
{

TLVType containerType = kTLVType_Structure;
ReturnErrorOnFailure(decryptedDataTlvReader.Next(containerType, TLV::AnonymousTag()));
ReturnErrorOnFailure(decryptedDataTlvReader.EnterContainer(containerType));

ReturnErrorOnFailure(decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSenderNOC)));
ReturnErrorOnFailure(decryptedDataTlvReader.Get(data.initiatorNOC));

ReturnErrorOnFailure(decryptedDataTlvReader.Next());
if (decryptedDataTlvReader.GetTag() == AsTlvContextTag(TBEDataTags::kSenderICAC))
{
VerifyOrReturnError(decryptedDataTlvReader.GetType() == TLV::kTLVType_ByteString, CHIP_ERROR_WRONG_TLV_TYPE);
ReturnErrorOnFailure(decryptedDataTlvReader.Get(data.initiatorICAC));
ReturnErrorOnFailure(decryptedDataTlvReader.Next(TLV::kTLVType_ByteString, AsTlvContextTag(TBEDataTags::kSignature)));
}

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

ReturnErrorOnFailure(decryptedDataTlvReader.ExitContainer(containerType));

return CHIP_NO_ERROR;
}

CHIP_ERROR CASESession::HandleSigma3b(HandleSigma3Data & data, bool & cancel)
{
// Step 5/6
Expand Down
26 changes: 25 additions & 1 deletion src/protocols/secure_channel/CASESession.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,25 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
bool responderSessionParamStructPresent = false;
};

struct HandleSigma3Data
{
chip::Platform::ScopedMemoryBuffer<uint8_t> msg_R3_Signed;
size_t msg_r3_signed_len;

ByteSpan initiatorNOC;
ByteSpan initiatorICAC;

uint8_t rootCertBuf[Credentials::kMaxCHIPCertLength];
ByteSpan fabricRCAC;

Crypto::P256ECDSASignature tbsData3Signature;

FabricId fabricId;
NodeId initiatorNodeId;

Credentials::ValidationContext validContext;
};

/**
* @brief Encodes a Sigma1 message into TLV format and allocates a buffer for it, which is owned by the PacketBufferHandle
* outparam.
Expand Down Expand Up @@ -342,6 +361,11 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
**/
static CHIP_ERROR EncodeSigma2Resume(System::PacketBufferHandle & outMsg, EncodeSigma2ResumeInputs & inParam);

static CHIP_ERROR ParseSigma3(TLV::ContiguousBufferTLVReader & tlvReader,
Platform::ScopedMemoryBufferWithSize<uint8_t> & msgR3Encrypted);

CHIP_ERROR ParseSigma3TBEData(TLV::ContiguousBufferTLVReader & tlvReader, HandleSigma3Data & data);

private:
friend class TestCASESession;

Expand Down Expand Up @@ -385,7 +409,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
static CHIP_ERROR SendSigma3b(SendSigma3Data & data, bool & cancel);
CHIP_ERROR SendSigma3c(SendSigma3Data & data, CHIP_ERROR status);

struct HandleSigma3Data;
// struct HandleSigma3Data;
CHIP_ERROR HandleSigma3a(System::PacketBufferHandle && msg);
static CHIP_ERROR HandleSigma3b(HandleSigma3Data & data, bool & cancel);
CHIP_ERROR HandleSigma3c(HandleSigma3Data & data, CHIP_ERROR status);
Expand Down

0 comments on commit 5c9281b

Please sign in to comment.