Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CASE session to match latest specifications #9904

Merged
merged 7 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions src/protocols/secure_channel/CASESession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void CASESession::Clear()
// This function zeroes out and resets the memory used by the object.
// It's done so that no security related information will be leaked.
mCommissioningHash.Clear();
mPairingComplete = false;
mCASESessionEstablished = false;
PairingSession::Clear();

mState = kInitialized;
Expand Down Expand Up @@ -167,36 +167,34 @@ CHIP_ERROR CASESession::Deserialize(CASESessionSerialized & input)

CHIP_ERROR CASESession::ToSerializable(CASESessionSerializable & serializable)
{
// TODO: IPK should not be serialized/deserialized. Remove it from the stored session state.
const NodeId peerNodeId = GetPeerNodeId();
VerifyOrReturnError(CanCastTo<uint16_t>(mSharedSecret.Length()), CHIP_ERROR_INTERNAL);
VerifyOrReturnError(CanCastTo<uint16_t>(sizeof(mMessageDigest)), CHIP_ERROR_INTERNAL);
VerifyOrReturnError(CanCastTo<uint16_t>(sizeof(mIPK)), CHIP_ERROR_INTERNAL);
VerifyOrReturnError(CanCastTo<uint64_t>(peerNodeId), CHIP_ERROR_INTERNAL);

memset(&serializable, 0, sizeof(serializable));
pan-apple marked this conversation as resolved.
Show resolved Hide resolved
serializable.mSharedSecretLen = LittleEndian::HostSwap16(static_cast<uint16_t>(mSharedSecret.Length()));
serializable.mMessageDigestLen = LittleEndian::HostSwap16(static_cast<uint16_t>(sizeof(mMessageDigest)));
serializable.mIPKLen = LittleEndian::HostSwap16(static_cast<uint16_t>(sizeof(mIPK)));
serializable.mPairingComplete = (mPairingComplete) ? 1 : 0;
serializable.mVersion = kCASESessionVersion;
serializable.mPeerNodeId = LittleEndian::HostSwap64(peerNodeId);
serializable.mLocalSessionId = LittleEndian::HostSwap16(GetLocalSessionId());
serializable.mPeerSessionId = LittleEndian::HostSwap16(GetPeerSessionId());

serializable.mCASESessionWasEstablished = (mCASESessionEstablished) ? 1 : 0;
pan-apple marked this conversation as resolved.
Show resolved Hide resolved

memcpy(serializable.mResumptionId, mResumptionId, sizeof(mResumptionId));
memcpy(serializable.mSharedSecret, mSharedSecret, mSharedSecret.Length());
memcpy(serializable.mMessageDigest, mMessageDigest, sizeof(mMessageDigest));
memcpy(serializable.mIPK, mIPK, sizeof(mIPK));

return CHIP_NO_ERROR;
}

CHIP_ERROR CASESession::FromSerializable(const CASESessionSerializable & serializable)
{
VerifyOrReturnError(serializable.mVersion == kCASESessionVersion, CHIP_ERROR_VERSION_MISMATCH);
mPairingComplete = (serializable.mPairingComplete == 1);
uint16_t length = LittleEndian::HostSwap16(serializable.mSharedSecretLen);
mCASESessionEstablished = (serializable.mCASESessionWasEstablished == 1);

uint16_t length = LittleEndian::HostSwap16(serializable.mSharedSecretLen);
ReturnErrorOnFailure(mSharedSecret.SetLength(static_cast<size_t>(length)));
memset(mSharedSecret, 0, sizeof(mSharedSecret.Capacity()));
memcpy(mSharedSecret, serializable.mSharedSecret, length);
Expand All @@ -205,16 +203,14 @@ CHIP_ERROR CASESession::FromSerializable(const CASESessionSerializable & seriali
VerifyOrReturnError(length <= sizeof(mMessageDigest), CHIP_ERROR_INVALID_ARGUMENT);
memcpy(mMessageDigest, serializable.mMessageDigest, length);

length = LittleEndian::HostSwap16(serializable.mIPKLen);
VerifyOrReturnError(length <= sizeof(mIPK), CHIP_ERROR_INVALID_ARGUMENT);
memcpy(mIPK, serializable.mIPK, length);

SetPeerNodeId(LittleEndian::HostSwap64(serializable.mPeerNodeId));
SetLocalSessionId(LittleEndian::HostSwap16(serializable.mLocalSessionId));
SetPeerSessionId(LittleEndian::HostSwap16(serializable.mPeerSessionId));

memcpy(mResumptionId, serializable.mResumptionId, sizeof(mResumptionId));

memcpy(mIPK, GetIPKList()->data(), sizeof(mIPK));
pan-apple marked this conversation as resolved.
Show resolved Hide resolved

return CHIP_NO_ERROR;
}

Expand Down Expand Up @@ -243,8 +239,9 @@ CASESession::ListenForSessionEstablishment(uint16_t localSessionId, Transport::F
VerifyOrReturnError(fabrics != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
ReturnErrorOnFailure(Init(localSessionId, delegate));

mFabricsTable = fabrics;
mPairingComplete = false;
mFabricsTable = fabrics;

mCASESessionEstablished = false;

ChipLogDetail(SecureChannel, "Waiting for Sigma1 msg");

Expand Down Expand Up @@ -308,7 +305,7 @@ CHIP_ERROR CASESession::DeriveSecureSession(CryptoContext & session, CryptoConte
(void) kKDFSEInfo;
(void) kKDFSEInfoLength;

VerifyOrReturnError(mPairingComplete, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(mCASESessionEstablished, CHIP_ERROR_INCORRECT_STATE);

// Generate Salt for Encryption keys
saltlen = sizeof(mIPK) + kSHA256_Hash_Length;
Expand Down Expand Up @@ -375,7 +372,7 @@ CHIP_ERROR CASESession::SendSigma1()
// If CASE session was previously established using the current state information, let's fill in the session resumption
// information in the the Sigma1 request. It'll speed up the session establishment process if the peer can resume the old
// session, since no certificate chains will have to be verified.
if (mPairingComplete)
if (mCASESessionEstablished)
{
ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(6), mResumptionId, kCASEResumptionIDSize));

Expand Down Expand Up @@ -721,7 +718,7 @@ CHIP_ERROR CASESession::HandleSigma2Resume(System::PacketBufferHandle && msg)
// TODO: Set timestamp on the new session, to allow selecting a least-recently-used session for eviction
// on running out of session contexts.

mPairingComplete = true;
mCASESessionEstablished = true;

// Forget our exchange, as no additional messages are expected from the peer
mExchangeCtxt = nullptr;
Expand Down Expand Up @@ -1136,7 +1133,7 @@ CHIP_ERROR CASESession::HandleSigma3(System::PacketBufferHandle && msg)
// TODO: Set timestamp on the new session, to allow selecting a least-recently-used session for eviction
// on running out of session contexts.

mPairingComplete = true;
mCASESessionEstablished = true;

// Forget our exchange, as no additional messages are expected from the peer
mExchangeCtxt = nullptr;
Expand Down Expand Up @@ -1320,7 +1317,7 @@ CHIP_ERROR CASESession::SetEffectiveTime(void)
void CASESession::OnSuccessStatusReport()
{
ChipLogProgress(SecureChannel, "Success status report received. Session was established");
pan-apple marked this conversation as resolved.
Show resolved Hide resolved
mPairingComplete = true;
mCASESessionEstablished = true;

// Forget our exchange, as no additional messages are expected from the peer
mExchangeCtxt = nullptr;
Expand Down
6 changes: 2 additions & 4 deletions src/protocols/secure_channel/CASESession.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,11 @@ struct CASESessionSerialized;
struct CASESessionSerializable
{
uint8_t mVersion;
uint8_t mPairingComplete;
uint8_t mCASESessionWasEstablished;
uint16_t mSharedSecretLen;
uint8_t mSharedSecret[Crypto::kMax_ECDH_Secret_Length];
uint16_t mMessageDigestLen;
uint8_t mMessageDigest[Crypto::kSHA256_Hash_Length];
uint16_t mIPKLen;
uint8_t mIPK[kIPKSize];
NodeId mPeerNodeId;
uint16_t mLocalSessionId;
uint16_t mPeerSessionId;
Expand Down Expand Up @@ -280,7 +278,7 @@ class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public Pairin
State mState;

protected:
bool mPairingComplete = false;
bool mCASESessionEstablished = false;

virtual ByteSpan * GetIPKList() const
{
Expand Down
3 changes: 2 additions & 1 deletion src/transport/PairingSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ class DLL_EXPORT PairingSession
: Protocols::SecureChannel::GeneralStatusCode::kFailure;
uint32_t protocolId = Protocols::SecureChannel::Id.ToFullyQualifiedSpecForm();

ChipLogDetail(SecureChannel, "Sending status report");
ChipLogDetail(SecureChannel, "Sending status report. Protocol code %d, exchange %d", protocolCode,
exchangeCtxt->GetExchangeId());

Protocols::SecureChannel::StatusReport statusReport(generalCode, protocolId, protocolCode);

Expand Down