From e071bd6025a69151761fbd8ddae4cd22615e4936 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Thu, 2 Sep 2021 15:18:16 +0800 Subject: [PATCH 1/3] Fix GetRand due to that InitEntropy (srand) is not called. --- .../internal/GenericPlatformManagerImpl.cpp | 7 +- src/platform/BUILD.gn | 2 + src/platform/EFR32/Entropy.cpp | 124 ------------------ src/platform/ESP32/Entropy.cpp | 90 ------------- src/platform/ESP32/PlatformManagerImpl.cpp | 4 +- src/platform/{Linux => }/Entropy.cpp | 22 +--- src/platform/K32W/Entropy.cpp | 102 -------------- src/platform/K32W/PlatformManagerImpl.cpp | 6 +- src/platform/P6/Entropy.cpp | 80 ----------- .../cc13x2_26x2/PlatformManagerImpl.cpp | 8 +- src/platform/qpg/Entropy.cpp | 123 ----------------- 11 files changed, 20 insertions(+), 548 deletions(-) delete mode 100644 src/platform/EFR32/Entropy.cpp delete mode 100644 src/platform/ESP32/Entropy.cpp rename src/platform/{Linux => }/Entropy.cpp (61%) delete mode 100644 src/platform/K32W/Entropy.cpp delete mode 100644 src/platform/P6/Entropy.cpp delete mode 100644 src/platform/qpg/Entropy.cpp diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp index a3dae088107964..1dbf66559e1de4 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp +++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp @@ -56,7 +56,12 @@ CHIP_ERROR GenericPlatformManagerImpl::_InitChipStack() // Arrange for Device Layer errors to be translated to text. RegisterDeviceLayerErrorFormatter(); - // TODO Initialize the source used by CHIP to get secure random data. + err = InitEntropy(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Entropy initialization failed: %s", ErrorStr(err)); + } + SuccessOrExit(err); err = ConfigurationMgr().Init(); if (err != CHIP_NO_ERROR) diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 3ae2405e49288d..922d501fe6212b 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -258,6 +258,7 @@ if (chip_device_platform != "none") { "../include/platform/internal/GenericSoftwareUpdateManagerImpl_BDX.h", "../include/platform/internal/testing/ConfigUnitTest.h", "DeviceControlServer.cpp", + "Entropy.cpp", "GeneralUtils.cpp", "Globals.cpp", "LockTracker.cpp", @@ -270,6 +271,7 @@ if (chip_device_platform != "none") { public_deps = [ ":platform_base", + "${chip_root}/src/crypto", "${chip_root}/src/lib/support", ] diff --git a/src/platform/EFR32/Entropy.cpp b/src/platform/EFR32/Entropy.cpp deleted file mode 100644 index 91d41bafe79161..00000000000000 --- a/src/platform/EFR32/Entropy.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Nest Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Provides implementations for the Chip entropy sourcing functions - * on the Silcon Labs EFR32 platforms. - */ -/* this file behaves like a config.h, comes first */ -#include - -#include - -#include - -#include - -#if defined(_SILICON_LABS_32B_SERIES_1) -#include -#elif defined(_SILICON_LABS_32B_SERIES_2) -extern "C" int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen); -#else // !defined(_SILICON_LABS_32B_SERIES_1) && !defined(_SILICON_LABS_32B_SERIES_2) -#error "Unsupported EFR32 series" -#endif - -using namespace ::chip; - -#if !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG -#error "CHIP DRBG implementation must be enabled on EFR32 platforms" -#endif // !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -/** - * Retrieve entropy from the underlying RNG source. - * - * This function is called by the CHIP DRBG to acquire entropy. - */ -int GetEntropy_EFR32(uint8_t * buf, size_t count) -{ - int res = 0; - - VerifyOrDie(count <= UINT16_MAX); - -#if defined(_SILICON_LABS_32B_SERIES_1) -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - if (ThreadStackManagerImpl::IsInitialized()) - { - ThreadStackMgr().LockThreadStack(); - } -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD - - otError otErr = otPlatEntropyGet(buf, (uint16_t) count); - if (otErr != OT_ERROR_NONE) - { - res = CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED; - } - -#elif defined(_SILICON_LABS_32B_SERIES_2) - size_t entropy_len = 0; - size_t olen = 0; - - while (entropy_len < count) - { - res = mbedtls_hardware_poll(NULL, buf + entropy_len, count - entropy_len, &olen); - if (res != 0) - { - res = CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED; - break; - } - - entropy_len += olen; - } -#else // !defined(_SILICON_LABS_32B_SERIES_1) && !defined(_SILICON_LABS_32B_SERIES_2) -#error "Unsupported EFR32 series" -#endif - - return res; -} - -CHIP_ERROR InitEntropy() -{ - CHIP_ERROR err; - - // Initialize the CHIP DRBG. - err = Platform::Security::InitSecureRandomDataSource(GetEntropy_EFR32, 64, NULL, 0); - SuccessOrExit(err); - - // Seed the standard rand() pseudo-random generator with data from the secure random source. - { - unsigned int seed; - err = Platform::Security::GetSecureRandomData((uint8_t *) &seed, sizeof(seed)); - SuccessOrExit(err); - srand(seed); - } - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Crypto, "InitEntropy() failed: 0x%08" PRIX32, err); - } - return err; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/ESP32/Entropy.cpp b/src/platform/ESP32/Entropy.cpp deleted file mode 100644 index 17ffb57faff46b..00000000000000 --- a/src/platform/ESP32/Entropy.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2018 Nest Labs, Inc. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Provides implementations for the CHIP entropy sourcing functions - * on the ESP32 platform. - */ -/* this file behaves like a config.h, comes first */ -#include - -#include - -#include "esp_log.h" - -using namespace ::chip; - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -namespace { - -int GetEntropy_ESP32(uint8_t * buf, size_t bufSize) -{ - while (bufSize > 0) - { - union - { - uint32_t asInt; - uint8_t asBytes[sizeof(asInt)]; - } rnd; - - rnd.asInt = esp_random(); - - size_t n = chip::min(bufSize, sizeof(rnd.asBytes)); - - memcpy(buf, rnd.asBytes, n); - - buf += n; - bufSize -= n; - } - - return 0; -} - -} // unnamed namespace - -CHIP_ERROR InitEntropy() -{ - CHIP_ERROR err; - unsigned int seed; - - // Initialize the source used by Chip to get secure random data. - err = ::chip::Platform::Security::InitSecureRandomDataSource(GetEntropy_ESP32, 64, NULL, 0); - SuccessOrExit(err); - - // Seed the standard rand() pseudo-random generator with data from the secure random source. - err = ::chip::Platform::Security::GetSecureRandomData((uint8_t *) &seed, sizeof(seed)); - SuccessOrExit(err); - srand(seed); - ESP_LOGI(TAG, "srand seed set: %u", seed); - -exit: - if (err != CHIP_NO_ERROR) - { - ESP_LOGE(TAG, "InitEntropy() failed: %s", ErrorStr(err)); - } - return err; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/ESP32/PlatformManagerImpl.cpp b/src/platform/ESP32/PlatformManagerImpl.cpp index f96517b2069fba..f6e7ef64bbf216 100644 --- a/src/platform/ESP32/PlatformManagerImpl.cpp +++ b/src/platform/ESP32/PlatformManagerImpl.cpp @@ -107,12 +107,12 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) } } + ReturnErrorOnFailure(chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16)); + // Call _InitChipStack() on the generic implementation base class // to finish the initialization process. ReturnErrorOnFailure(Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack()); - ReturnErrorOnFailure(chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16)); - exit: return chip::DeviceLayer::Internal::ESP32Utils::MapError(err); } diff --git a/src/platform/Linux/Entropy.cpp b/src/platform/Entropy.cpp similarity index 61% rename from src/platform/Linux/Entropy.cpp rename to src/platform/Entropy.cpp index f1b23e4506c30c..08225c4440c71f 100644 --- a/src/platform/Linux/Entropy.cpp +++ b/src/platform/Entropy.cpp @@ -22,10 +22,7 @@ * on the Linux platforms. */ -#include -#include - -using namespace ::chip; +#include namespace chip { namespace DeviceLayer { @@ -33,23 +30,10 @@ namespace Internal { CHIP_ERROR InitEntropy() { - CHIP_ERROR err; unsigned int seed; - - // Initialize the source used by CHIP to get secure random data. - err = Platform::Security::InitSecureRandomDataSource(getentropy, 64, NULL, 0); - SuccessOrExit(err); - - // Seed the standard rand() pseudo-random generator with data from the secure random source. - err = Platform::Security::GetSecureRandomData((uint8_t *) &seed, sizeof(seed)); - SuccessOrExit(err); + ReturnErrorOnFailure(chip::Crypto::DRBG_get_bytes((uint8_t *) &seed, sizeof(seed))); srand(seed); -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Crypto, "InitEntropy() failed: %d" err); - } - return err; + return CHIP_NO_ERROR; } } // namespace Internal diff --git a/src/platform/K32W/Entropy.cpp b/src/platform/K32W/Entropy.cpp deleted file mode 100644 index 7c6ec340a45b09..00000000000000 --- a/src/platform/K32W/Entropy.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2020 Nest Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Provides implementations for the Chip entropy sourcing functions - * on the NXP K32W platforms. - */ -/* this file behaves like a config.h, comes first */ -#include - -#include - -#include -#include - -using namespace ::chip; - -#if !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG -#error "CHIP DRBG implementation must be enabled on K32W platforms" -#endif // !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -/** - * Retrieve entropy from the underlying RNG source. - * - * This function is called by the CHIP DRBG to acquire entropy. - */ -int GetEntropy_K32W(uint8_t * buf, size_t count) -{ - int res = 0; - - VerifyOrDie(count <= UINT16_MAX); - -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - if (ThreadStackManagerImpl::IsInitialized()) - { - ThreadStackMgr().LockThreadStack(); - } -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD - - otError otErr = otPlatEntropyGet(buf, (uint16_t) count); - if (otErr != OT_ERROR_NONE) - { - res = CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED; - } - -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - if (ThreadStackManagerImpl::IsInitialized()) - { - ThreadStackMgr().UnlockThreadStack(); - } -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD - - return res; -} - -CHIP_ERROR InitEntropy() -{ - CHIP_ERROR err; - - // Initialize the CHIP DRBG. - err = Platform::Security::InitSecureRandomDataSource(GetEntropy_K32W, 64, NULL, 0); - SuccessOrExit(err); - - // Seed the standard rand() pseudo-random generator with data from the secure random source. - { - unsigned int seed; - err = Platform::Security::GetSecureRandomData((uint8_t *) &seed, sizeof(seed)); - SuccessOrExit(err); - srand(seed); - } - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Crypto, "InitEntropy() failed: 0x%08" PRIX32, err); - } - return err; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/K32W/PlatformManagerImpl.cpp b/src/platform/K32W/PlatformManagerImpl.cpp index be259f570da75c..34981331f7f4fa 100644 --- a/src/platform/K32W/PlatformManagerImpl.cpp +++ b/src/platform/K32W/PlatformManagerImpl.cpp @@ -62,14 +62,14 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) // Initialize LwIP. tcpip_init(NULL, NULL); + err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16); + SuccessOrExit(err); + // Call _InitChipStack() on the generic implementation base class // to finish the initialization process. err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); SuccessOrExit(err); - err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16); - SuccessOrExit(err); - exit: return err; } diff --git a/src/platform/P6/Entropy.cpp b/src/platform/P6/Entropy.cpp deleted file mode 100644 index a87488c79a11df..00000000000000 --- a/src/platform/P6/Entropy.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * Copyright (c) 2018 Nest Labs, Inc. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Provides implementations for the CHIP entropy sourcing functions - * on the PSoC6 platform. - */ -/* this file behaves like a config.h, comes first */ -#include - -#include "cyhal_trng.h" - -using namespace ::chip; - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -namespace { - -cyhal_trng_t trng; - -int GetEntropy_P6(uint8_t * buf, size_t bufSize) -{ - while (bufSize > 0) - { - uint32_t val = cyhal_trng_generate(&trng); - size_t n = chip::min(bufSize, sizeof(uint32_t)); - memcpy(buf, static_cast(&val), n); - - buf += n; - bufSize -= n; - } - - return 0; -} - -} // unnamed namespace - -CHIP_ERROR InitEntropy() -{ - CHIP_ERROR err; - - err = (cyhal_trng_init(&trng) == CY_RSLT_SUCCESS) ? CHIP_NO_ERROR : CHIP_ERROR_DRBG_ENTROPY_SOURCE_FAILED; - SuccessOrExit(err); - - // Initialize the source used by Chip to get secure random data. - err = ::chip::Platform::Security::InitSecureRandomDataSource(GetEntropy_P6, 64, NULL, 0); - SuccessOrExit(err); - - // Seed the standard rand() pseudo-random generator with data from the secure random source. - unsigned int seed; - err = ::chip::Platform::Security::GetSecureRandomData((uint8_t *) &seed, sizeof(seed)); - SuccessOrExit(err); - srand(seed); - -exit: - return err; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip diff --git a/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp b/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp index 7f82d25f10168c..dea57bed5800b5 100644 --- a/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp +++ b/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp @@ -132,15 +132,15 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) // Initialize LwIP. tcpip_init(NULL, NULL); + app_random_init(); + err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16); + SuccessOrExit(err); + // Call _InitChipStack() on the generic implementation base class // to finish the initialization process. err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); SuccessOrExit(err); - app_random_init(); - err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16); - SuccessOrExit(err); - exit: return err; } diff --git a/src/platform/qpg/Entropy.cpp b/src/platform/qpg/Entropy.cpp deleted file mode 100644 index 0851593ba2abd2..00000000000000 --- a/src/platform/qpg/Entropy.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Provides implementations for the chip entropy sourcing functions - * on Qorvo QPG platforms. - */ - -// -// !!!TEMPORARY CODE!!! -// -// The following code is a temporary implementation of the CHIP Entropy APIs -// that has been specially designed to work around the lack of thread-safety in the -// Nordic port of OpenThread. -// -// In Nordic's OpenThread platform implementation, the code assumes it has exclusive -// access to the underlying entropy source. In a multi-threaded environment such as -// an CHIP application this precludes code running in other threads from directly -// sourcing entropy. -// -// To work around this, the code here acquires the OpenThread stack lock before interacting -// with the entropy source, effectively blocking all OpenThread activity until CHIP -// has acquired its entropy. Because the entropy is being fed into a DRBG, which then feeds -// the application, this should happen extremely rarely. -// -// Ultimately this code will be revised to use a new thread-safe entropy sourcing API -// provided by Nordic. -// - -#include -#include - -#include - -using namespace ::chip; - -#if !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG -#error "CHIP DRBG implementation must be enabled on Qorvo QPG platforms" -#endif // !CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG - -namespace chip { -namespace DeviceLayer { -namespace Internal { - -/** - * Retrieve entropy from the underlying RNG source. - * - * This function is called by the CHIP DRBG to acquire entropy. - */ -int GetEntropy(uint8_t * buf, size_t count) -{ - int res; - - VerifyOrDie(count <= UINT16_MAX); - -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - // If OpenThread is active, acquire the stack lock to prevent the - // OpenThread task from interacting with the entropy source. - - if (ThreadStackManagerImpl::IsInitialized()) - { - ThreadStackMgr().LockThreadStack(); - } - - // FIXME - use available HW based API - // Call the OpenThread platform API for retrieving entropy. - otError otErr = otPlatRandomGetTrue(buf, (uint16_t) count); - res = (otErr == OT_ERROR_NONE); - - if (ThreadStackManagerImpl::IsInitialized()) - { - ThreadStackMgr().UnlockThreadStack(); - } -#else - // FIXME - use available HW based API - No OT needed in essence - res = -1; -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD - - return res; -} - -CHIP_ERROR InitEntropy() -{ - CHIP_ERROR err; - - // Initialize the CHIP DRBG. - err = Platform::Security::InitSecureRandomDataSource(GetEntropy, 64, NULL, 0); - SuccessOrExit(err); - - // Seed the standard rand() pseudo-random generator with data from the secure random source. - { - unsigned int seed; - err = Platform::Security::GetSecureRandomData((uint8_t *) &seed, sizeof(seed)); - SuccessOrExit(err); - srand(seed); - } - -exit: - if (err != CHIP_NO_ERROR) - { - ChipLogError(Crypto, "InitEntropy() failed: 0x%08" PRIX32, err); - } - return err; -} - -} // namespace Internal -} // namespace DeviceLayer -} // namespace chip From 030f20d639d7f97feaba572376d5900da311c45e Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Thu, 8 Jul 2021 10:53:57 +0800 Subject: [PATCH 2/3] unauthenticated-session --- src/app/server/RendezvousServer.cpp | 3 +- src/channel/ChannelContext.cpp | 17 +- src/controller/CHIPDevice.cpp | 13 +- src/controller/CHIPDeviceController.cpp | 9 +- src/lib/core/CHIPConfig.h | 12 ++ src/lib/core/CHIPError.cpp | 3 + src/lib/core/CHIPError.h | 8 + src/lib/core/InPlace.h | 4 - src/lib/support/Pool.h | 17 +- src/lib/support/ReferenceCountedHandle.h | 9 +- src/messaging/ApplicationExchangeDispatch.cpp | 2 +- src/messaging/ExchangeMessageDispatch.h | 3 + src/messaging/ReliableMessageMgr.cpp | 2 +- src/messaging/tests/MessagingContext.cpp | 19 +- src/messaging/tests/MessagingContext.h | 9 +- .../tests/TestReliableMessageProtocol.cpp | 55 ++--- src/protocols/secure_channel/CASEServer.cpp | 2 +- src/protocols/secure_channel/CASESession.cpp | 2 - src/protocols/secure_channel/PASESession.cpp | 2 - .../SessionEstablishmentExchangeDispatch.cpp | 11 +- .../SessionEstablishmentExchangeDispatch.h | 19 +- .../secure_channel/tests/TestCASESession.cpp | 33 +-- .../secure_channel/tests/TestPASESession.cpp | 34 +-- src/transport/PeerMessageCounter.h | 32 ++- src/transport/SecureSessionMgr.cpp | 154 ++++++++----- src/transport/SecureSessionMgr.h | 15 +- src/transport/SessionHandle.h | 19 +- src/transport/UnauthenticatedSessionTable.h | 202 ++++++++++++++++++ src/transport/tests/TestSecureSessionMgr.cpp | 12 +- 29 files changed, 532 insertions(+), 190 deletions(-) create mode 100644 src/transport/UnauthenticatedSessionTable.h diff --git a/src/app/server/RendezvousServer.cpp b/src/app/server/RendezvousServer.cpp index 2e72b07fc46530..67a43545f64e80 100644 --- a/src/app/server/RendezvousServer.cpp +++ b/src/app/server/RendezvousServer.cpp @@ -118,8 +118,7 @@ CHIP_ERROR RendezvousServer::WaitForPairing(const RendezvousParameters & params, ReturnErrorOnFailure(mPairingSession.WaitForPairing(params.GetSetupPINCode(), pbkdf2IterCount, salt, keyID, this)); } - ReturnErrorOnFailure(mPairingSession.MessageDispatch().Init(transportMgr)); - mPairingSession.MessageDispatch().SetPeerAddress(params.GetPeerAddress()); + ReturnErrorOnFailure(mPairingSession.MessageDispatch().Init(mSessionMgr)); return CHIP_NO_ERROR; } diff --git a/src/channel/ChannelContext.cpp b/src/channel/ChannelContext.cpp index 72523b7c019f75..800b24c380ccf2 100644 --- a/src/channel/ChannelContext.cpp +++ b/src/channel/ChannelContext.cpp @@ -258,13 +258,22 @@ void ChannelContext::EnterCasePairingState() auto & prepare = GetPrepareVars(); prepare.mCasePairingSession = Platform::New(); - ExchangeContext * ctxt = - mExchangeManager->NewContext(SessionHandle::TemporaryUnauthenticatedSession(), prepare.mCasePairingSession); - VerifyOrReturn(ctxt != nullptr); - // TODO: currently only supports IP/UDP paring Transport::PeerAddress addr; addr.SetTransportType(Transport::Type::kUdp).SetIPAddress(prepare.mAddress); + + auto session = mExchangeManager->GetSessionMgr()->CreateUnauthenticatedSession(addr); + if (!session.HasValue()) + { + ExitCasePairingState(); + ExitPreparingState(); + EnterFailedState(CHIP_ERROR_NO_MEMORY); + return; + } + + ExchangeContext * ctxt = mExchangeManager->NewContext(session.Value(), prepare.mCasePairingSession); + VerifyOrReturn(ctxt != nullptr); + Transport::FabricInfo * fabric = mFabricsTable->FindFabricWithIndex(mFabricIndex); VerifyOrReturn(fabric != nullptr); CHIP_ERROR err = prepare.mCasePairingSession->EstablishSession(addr, fabric, prepare.mBuilder.GetPeerNodeId(), diff --git a/src/controller/CHIPDevice.cpp b/src/controller/CHIPDevice.cpp index 78b906912ee01e..72f8a03eb6e099 100644 --- a/src/controller/CHIPDevice.cpp +++ b/src/controller/CHIPDevice.cpp @@ -559,12 +559,17 @@ CHIP_ERROR Device::WarmupCASESession() VerifyOrReturnError(mDeviceOperationalCertProvisioned, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mState == ConnectionState::NotConnected, CHIP_NO_ERROR); - Messaging::ExchangeContext * exchange = - mExchangeMgr->NewContext(SessionHandle::TemporaryUnauthenticatedSession(), &mCASESession); + // Create a UnauthenticatedSession for CASE pairing. + // Don't use mSecureSession here, because mSecureSession is the secure session. + Optional session = mSessionManager->CreateUnauthenticatedSession(mDeviceAddress); + if (!session.HasValue()) + { + return CHIP_ERROR_NO_MEMORY; + } + Messaging::ExchangeContext * exchange = mExchangeMgr->NewContext(session.Value(), &mCASESession); VerifyOrReturnError(exchange != nullptr, CHIP_ERROR_INTERNAL); - ReturnErrorOnFailure(mCASESession.MessageDispatch().Init(mSessionManager->GetTransportManager())); - mCASESession.MessageDispatch().SetPeerAddress(mDeviceAddress); + ReturnErrorOnFailure(mCASESession.MessageDispatch().Init(mSessionManager)); uint16_t keyID = 0; ReturnErrorOnFailure(mIDAllocator->Allocate(keyID)); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index eb7c466c6ac10c..f370e408d7a226 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -803,6 +803,7 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam Transport::PeerAddress peerAddress = Transport::PeerAddress::UDP(Inet::IPAddress::Any); Messaging::ExchangeContext * exchangeCtxt = nullptr; + Optional session; uint16_t keyID = 0; @@ -855,9 +856,8 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam mIsIPRendezvous = (params.GetPeerAddress().GetTransportType() != Transport::Type::kBle); - err = mPairingSession.MessageDispatch().Init(mTransportMgr); + err = mPairingSession.MessageDispatch().Init(mSessionMgr); SuccessOrExit(err); - mPairingSession.MessageDispatch().SetPeerAddress(params.GetPeerAddress()); device->Init(GetControllerDeviceInitParams(), mListenPort, remoteDeviceId, peerAddress, fabric->GetFabricIndex()); @@ -883,7 +883,10 @@ CHIP_ERROR DeviceCommissioner::PairDevice(NodeId remoteDeviceId, RendezvousParam } } #endif - exchangeCtxt = mExchangeMgr->NewContext(SessionHandle::TemporaryUnauthenticatedSession(), &mPairingSession); + session = mSessionMgr->CreateUnauthenticatedSession(params.GetPeerAddress()); + VerifyOrExit(session.HasValue(), CHIP_ERROR_NO_MEMORY); + + exchangeCtxt = mExchangeMgr->NewContext(session.Value(), &mPairingSession); VerifyOrExit(exchangeCtxt != nullptr, err = CHIP_ERROR_INTERNAL); err = mIDAllocator.Allocate(keyID); diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h index 22ef9296da7010..d509c179903f12 100644 --- a/src/lib/core/CHIPConfig.h +++ b/src/lib/core/CHIPConfig.h @@ -2262,6 +2262,18 @@ #define CHIP_CONFIG_ENABLE_IFJ_SERVICE_FABRIC_JOIN 0 #endif // CHIP_CONFIG_ENABLE_IFJ_SERVICE_FABRIC_JOIN +/** + * @def CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE + * + * @brief Define the size of the pool used for tracking CHIP unauthenticated + * states. The entries in the pool are automatically rotated by LRU. The size + * of the pool limits how many PASE and CASE pairing sessions can be processed + * simultaneously. + */ +#ifndef CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE +#define CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE 4 +#endif // CHIP_CONFIG_UNAUTHENTICATED_CONNECTION_POOL_SIZE + /** * @def CHIP_CONFIG_PEER_CONNECTION_POOL_SIZE * diff --git a/src/lib/core/CHIPError.cpp b/src/lib/core/CHIPError.cpp index 6b2d7157990557..c3356f200b91be 100644 --- a/src/lib/core/CHIPError.cpp +++ b/src/lib/core/CHIPError.cpp @@ -644,6 +644,9 @@ bool FormatCHIPError(char * buf, uint16_t bufSize, CHIP_ERROR err) case CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED.AsInteger(): desc = "Duplicate message received"; break; + case CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW.AsInteger(): + desc = "Message id out of window"; + break; } #endif // !CHIP_CONFIG_SHORT_ERROR_STR diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index 295a41b7a13395..600fc739c16d6f 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -2172,6 +2172,14 @@ using CHIP_ERROR = ::chip::ChipError; */ #define CHIP_ERROR_FABRIC_MISMATCH_ON_ICA CHIP_CORE_ERROR(0xc6) +/** + * @def CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW + * + * @brief + * The message id of the received message is out of receiving window + */ +#define CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW CHIP_CORE_ERROR(0xc7) + /** * @} */ diff --git a/src/lib/core/InPlace.h b/src/lib/core/InPlace.h index c74f24b8b817de..647fc51c6e87d1 100644 --- a/src/lib/core/InPlace.h +++ b/src/lib/core/InPlace.h @@ -23,10 +23,6 @@ */ #pragma once -#include -#include -#include - namespace chip { /// InPlace is disambiguation tags that can be passed to the constructors to indicate that the contained object should be diff --git a/src/lib/support/Pool.h b/src/lib/support/Pool.h index 2158929ca216ee..f9fe67aaa8d735 100644 --- a/src/lib/support/Pool.h +++ b/src/lib/support/Pool.h @@ -87,7 +87,7 @@ template class BitMapObjectPool : public StaticAllocatorBitmap { public: - BitMapObjectPool() : StaticAllocatorBitmap(mMemory, mUsage, N, sizeof(T)) {} + BitMapObjectPool() : StaticAllocatorBitmap(mData.mMemory, mUsage, N, sizeof(T)) {} static size_t Size() { return N; } @@ -110,6 +110,13 @@ class BitMapObjectPool : public StaticAllocatorBitmap Deallocate(element); } + template + void ResetObject(T * element, Args &&... args) + { + element->~T(); + new (element) T(std::forward(args)...); + } + /** * @brief * Run a functor for each active object in the pool @@ -144,7 +151,13 @@ class BitMapObjectPool : public StaticAllocatorBitmap }; std::atomic mUsage[(N + kBitChunkSize - 1) / kBitChunkSize]; - alignas(alignof(T)) uint8_t mMemory[N * sizeof(T)]; + union Data + { + Data() {} + ~Data() {} + alignas(alignof(T)) uint8_t mMemory[N * sizeof(T)]; + T mMemoryViewForDebug[N]; // Just for debugger + } mData; }; } // namespace chip diff --git a/src/lib/support/ReferenceCountedHandle.h b/src/lib/support/ReferenceCountedHandle.h index 637fe514405c31..c433a639db8d7a 100644 --- a/src/lib/support/ReferenceCountedHandle.h +++ b/src/lib/support/ReferenceCountedHandle.h @@ -28,14 +28,19 @@ class ReferenceCountedHandle explicit ReferenceCountedHandle(Target & target) : mTarget(target) { mTarget.Retain(); } ~ReferenceCountedHandle() { mTarget.Release(); } - ReferenceCountedHandle(const ReferenceCountedHandle & that) = delete; + ReferenceCountedHandle(const ReferenceCountedHandle & that) : mTarget(that.mTarget) { mTarget.Retain(); } + + ReferenceCountedHandle(ReferenceCountedHandle && that) : mTarget(that.mTarget) { mTarget.Retain(); } + ReferenceCountedHandle & operator=(const ReferenceCountedHandle & that) = delete; - ReferenceCountedHandle(ReferenceCountedHandle && that) = delete; ReferenceCountedHandle & operator=(ReferenceCountedHandle && that) = delete; bool operator==(const ReferenceCountedHandle & that) const { return &mTarget == &that.mTarget; } bool operator!=(const ReferenceCountedHandle & that) const { return !(*this == that); } + Target * operator->() { return &mTarget; } + Target & Get() const { return mTarget; } + private: Target & mTarget; }; diff --git a/src/messaging/ApplicationExchangeDispatch.cpp b/src/messaging/ApplicationExchangeDispatch.cpp index 02e7ff3ad131b7..a37a527c224825 100644 --- a/src/messaging/ApplicationExchangeDispatch.cpp +++ b/src/messaging/ApplicationExchangeDispatch.cpp @@ -30,7 +30,7 @@ CHIP_ERROR ApplicationExchangeDispatch::PrepareMessage(SessionHandle session, Pa System::PacketBufferHandle && message, EncryptedPacketBufferHandle & preparedMessage) { - return mSessionMgr->BuildEncryptedMessagePayload(session, payloadHeader, std::move(message), preparedMessage); + return mSessionMgr->PrepareMessage(session, payloadHeader, std::move(message), preparedMessage); } CHIP_ERROR ApplicationExchangeDispatch::SendPreparedMessage(SessionHandle session, diff --git a/src/messaging/ExchangeMessageDispatch.h b/src/messaging/ExchangeMessageDispatch.h index f9a315ce8474df..c9fa46ca8efb79 100644 --- a/src/messaging/ExchangeMessageDispatch.h +++ b/src/messaging/ExchangeMessageDispatch.h @@ -64,7 +64,10 @@ class ExchangeMessageDispatch : public ReferenceCounted protected: virtual bool MessagePermitted(uint16_t protocol, uint8_t type) = 0; + + // TODO: remove IsReliableTransmissionAllowed, this function should be provided over session. virtual bool IsReliableTransmissionAllowed() const { return true; } + virtual bool IsEncryptionRequired() const { return true; } }; diff --git a/src/messaging/ReliableMessageMgr.cpp b/src/messaging/ReliableMessageMgr.cpp index aa233ebb654f01..f6bb51814c36bb 100644 --- a/src/messaging/ReliableMessageMgr.cpp +++ b/src/messaging/ReliableMessageMgr.cpp @@ -406,8 +406,8 @@ void ReliableMessageMgr::ClearRetransTable(RetransTableEntry & rEntry) // Expire any virtual ticks that have expired so all wakeup sources reflect the current time ExpireTicks(); - rEntry.rc->ReleaseContext(); rEntry.rc->SetOccupied(false); + rEntry.rc->ReleaseContext(); rEntry.rc = nullptr; // Clear all other fields diff --git a/src/messaging/tests/MessagingContext.cpp b/src/messaging/tests/MessagingContext.cpp index 26f65791ad6112..e7b2659e525330 100644 --- a/src/messaging/tests/MessagingContext.cpp +++ b/src/messaging/tests/MessagingContext.cpp @@ -37,11 +37,12 @@ CHIP_ERROR MessagingContext::Init(nlTestSuite * suite, TransportMgrBase * transp ReturnErrorOnFailure(mExchangeManager.Init(&mSecureSessionMgr)); ReturnErrorOnFailure(mMessageCounterManager.Init(&mExchangeManager)); - ReturnErrorOnFailure(mSecureSessionMgr.NewPairing(mPeer, GetDestinationNodeId(), &mPairingLocalToPeer, - SecureSession::SessionRole::kInitiator, mSrcFabricIndex)); + ReturnErrorOnFailure(mSecureSessionMgr.NewPairing(Optional::Value(mPeerAddress), GetDestinationNodeId(), + &mPairingLocalToPeer, SecureSession::SessionRole::kInitiator, + mSrcFabricIndex)); - return mSecureSessionMgr.NewPairing(mPeer, GetSourceNodeId(), &mPairingPeerToLocal, SecureSession::SessionRole::kResponder, - mDestFabricIndex); + return mSecureSessionMgr.NewPairing(Optional::Value(mLocalAddress), GetSourceNodeId(), + &mPairingPeerToLocal, SecureSession::SessionRole::kResponder, mDestFabricIndex); } // Shutdown all layers, finalize operations @@ -67,6 +68,16 @@ SessionHandle MessagingContext::GetSessionPeerToLocal() return SessionHandle(GetSourceNodeId(), GetPeerKeyId(), GetLocalKeyId(), mDestFabricIndex); } +Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToPeer(Messaging::ExchangeDelegate * delegate) +{ + return mExchangeManager.NewContext(mSecureSessionMgr.CreateUnauthenticatedSession(mPeerAddress).Value(), delegate); +} + +Messaging::ExchangeContext * MessagingContext::NewUnauthenticatedExchangeToLocal(Messaging::ExchangeDelegate * delegate) +{ + return mExchangeManager.NewContext(mSecureSessionMgr.CreateUnauthenticatedSession(mLocalAddress).Value(), delegate); +} + Messaging::ExchangeContext * MessagingContext::NewExchangeToPeer(Messaging::ExchangeDelegate * delegate) { // TODO: temprary create a SessionHandle from node id, will be fix in PR 3602 diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index fc441646d8d041..b17f1f48680560 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -37,7 +37,8 @@ class MessagingContext { public: MessagingContext() : - mInitialized(false), mPeer(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)), + mInitialized(false), mLocalAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)), + mPeerAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT + 1)), mPairingPeerToLocal(GetLocalKeyId(), GetPeerKeyId()), mPairingLocalToPeer(GetPeerKeyId(), GetLocalKeyId()) {} ~MessagingContext() { VerifyOrDie(mInitialized == false); } @@ -80,6 +81,9 @@ class MessagingContext SessionHandle GetSessionLocalToPeer(); SessionHandle GetSessionPeerToLocal(); + Messaging::ExchangeContext * NewUnauthenticatedExchangeToPeer(Messaging::ExchangeDelegate * delegate); + Messaging::ExchangeContext * NewUnauthenticatedExchangeToLocal(Messaging::ExchangeDelegate * delegate); + Messaging::ExchangeContext * NewExchangeToPeer(Messaging::ExchangeDelegate * delegate); Messaging::ExchangeContext * NewExchangeToLocal(Messaging::ExchangeDelegate * delegate); @@ -98,7 +102,8 @@ class MessagingContext NodeId mDestinationNodeId = 111222333; uint16_t mLocalKeyId = 1; uint16_t mPeerKeyId = 2; - Optional mPeer; + Transport::PeerAddress mLocalAddress; + Transport::PeerAddress mPeerAddress; SecurePairingUsingTestSecret mPairingPeerToLocal; SecurePairingUsingTestSecret mPairingLocalToPeer; Transport::FabricTable mFabrics; diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index f343e299507595..062dae89dfd1cf 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -124,26 +124,9 @@ class MockAppDelegate : public ExchangeDelegate nlTestSuite * mTestSuite = nullptr; }; -class MockSessionEstablishmentExchangeDispatch : public Messaging::ExchangeMessageDispatch +class MockSessionEstablishmentExchangeDispatch : public Messaging::ApplicationExchangeDispatch { public: - CHIP_ERROR PrepareMessage(SessionHandle session, PayloadHeader & payloadHeader, System::PacketBufferHandle && message, - EncryptedPacketBufferHandle & preparedMessage) override - { - PacketHeader packetHeader; - - ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message)); - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); - - preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); - return CHIP_NO_ERROR; - } - - CHIP_ERROR SendPreparedMessage(SessionHandle session, const EncryptedPacketBufferHandle & preparedMessage) const override - { - return gTransportMgr.SendMessage(Transport::PeerAddress(), preparedMessage.CastToWritable()); - } - bool IsReliableTransmissionAllowed() const override { return mRetainMessageOnSend; } bool MessagePermitted(uint16_t protocol, uint8_t type) override { return true; } @@ -367,6 +350,9 @@ void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) CHIP_ERROR err = CHIP_NO_ERROR; MockSessionEstablishmentDelegate mockSender; + err = mockSender.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); @@ -380,9 +366,6 @@ void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) 1, // CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL }); - err = mockSender.mMessageDispatch.Init(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - mockSender.mMessageDispatch.mRetainMessageOnSend = false; // Let's drop the initial message @@ -414,14 +397,20 @@ void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inConte NL_TEST_ASSERT(inSuite, !buffer.IsNull()); MockSessionEstablishmentDelegate mockReceiver; - CHIP_ERROR err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); + CHIP_ERROR err = mockReceiver.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); // Expect the received messages to be encrypted mockReceiver.mMessageDispatch.mRequireEncryption = true; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + err = mockSender.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToPeer(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -429,9 +418,6 @@ void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inConte NL_TEST_ASSERT(inSuite, rm != nullptr); NL_TEST_ASSERT(inSuite, rc != nullptr); - err = mockSender.mMessageDispatch.Init(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - gLoopback.mSentMessageCount = 0; gLoopback.mNumMessagesToDrop = 0; gLoopback.mDroppedMessageCount = 0; @@ -584,23 +570,23 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit CHIP_ERROR err = ctx.Init(inSuite, &gTransportMgr, &gIOContext); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.SetSourceNodeId(kPlaceholderNodeId); - ctx.SetDestinationNodeId(kPlaceholderNodeId); - ctx.SetLocalKeyId(0); - ctx.SetPeerKeyId(0); - ctx.SetFabricIndex(kUndefinedFabricIndex); - chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); NL_TEST_ASSERT(inSuite, !buffer.IsNull()); MockSessionEstablishmentDelegate mockReceiver; + err = mockReceiver.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); mockReceiver.mTestSuite = inSuite; MockSessionEstablishmentDelegate mockSender; - ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockSender); + err = mockSender.mMessageDispatch.Init(&ctx.GetSecureSessionManager()); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + + ExchangeContext * exchange = ctx.NewUnauthenticatedExchangeToPeer(&mockSender); NL_TEST_ASSERT(inSuite, exchange != nullptr); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); @@ -613,9 +599,6 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit 1, // CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL }); - err = mockSender.mMessageDispatch.Init(); - NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - // Let's drop the initial message gLoopback.mSentMessageCount = 0; gLoopback.mNumMessagesToDrop = 1; diff --git a/src/protocols/secure_channel/CASEServer.cpp b/src/protocols/secure_channel/CASEServer.cpp index 168d19bfafb22c..834f64c8188e8d 100644 --- a/src/protocols/secure_channel/CASEServer.cpp +++ b/src/protocols/secure_channel/CASEServer.cpp @@ -46,7 +46,7 @@ CHIP_ERROR CASEServer::ListenForSessionEstablishment(Messaging::ExchangeManager Cleanup(); - ReturnErrorOnFailure(GetSession().MessageDispatch().Init(transportMgr)); + ReturnErrorOnFailure(GetSession().MessageDispatch().Init(sessionMgr)); return CHIP_NO_ERROR; } diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index be7f738ee04e2c..58a8f4c4de17c7 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -1220,8 +1220,6 @@ CHIP_ERROR CASESession::OnMessageReceived(ExchangeContext * ec, const PacketHead CHIP_ERROR err = ValidateReceivedMessage(ec, packetHeader, payloadHeader, msg); SuccessOrExit(err); - SetPeerAddress(mMessageDispatch.GetPeerAddress()); - switch (static_cast(payloadHeader.GetMessageType())) { case Protocols::SecureChannel::MsgType::CASE_SigmaR1: diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index 157e2e71ee6ba1..c845a7d620048c 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -789,8 +789,6 @@ CHIP_ERROR PASESession::OnMessageReceived(ExchangeContext * exchange, const Pack CHIP_ERROR err = ValidateReceivedMessage(exchange, packetHeader, payloadHeader, std::move(msg)); SuccessOrExit(err); - SetPeerAddress(mMessageDispatch.GetPeerAddress()); - switch (static_cast(payloadHeader.GetMessageType())) { case Protocols::SecureChannel::MsgType::PBKDFParamRequest: diff --git a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp index 13f7bd728ea784..0d3b28c7093b82 100644 --- a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp +++ b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.cpp @@ -32,19 +32,13 @@ CHIP_ERROR SessionEstablishmentExchangeDispatch::PrepareMessage(SessionHandle se System::PacketBufferHandle && message, EncryptedPacketBufferHandle & preparedMessage) { - PacketHeader packetHeader; - ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message)); - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); - - preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); - return CHIP_NO_ERROR; + return mSessionMgr->PrepareMessage(session, payloadHeader, std::move(message), preparedMessage); } CHIP_ERROR SessionEstablishmentExchangeDispatch::SendPreparedMessage(SessionHandle session, const EncryptedPacketBufferHandle & preparedMessage) const { - ReturnErrorCodeIf(mTransportMgr == nullptr, CHIP_ERROR_INCORRECT_STATE); - return mTransportMgr->SendMessage(mPeerAddress, preparedMessage.CastToWritable()); + return mSessionMgr->SendPreparedMessage(session, preparedMessage); } CHIP_ERROR SessionEstablishmentExchangeDispatch::OnMessageReceived(const Header::Flags & headerFlags, @@ -53,7 +47,6 @@ CHIP_ERROR SessionEstablishmentExchangeDispatch::OnMessageReceived(const Header: Messaging::MessageFlags msgFlags, ReliableMessageContext * reliableMessageContext) { - mPeerAddress = peerAddress; return ExchangeMessageDispatch::OnMessageReceived(headerFlags, payloadHeader, messageId, peerAddress, msgFlags, reliableMessageContext); } diff --git a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h index 17c4066bf761b2..9729396483efcb 100644 --- a/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h +++ b/src/protocols/secure_channel/SessionEstablishmentExchangeDispatch.h @@ -36,10 +36,10 @@ class SessionEstablishmentExchangeDispatch : public Messaging::ExchangeMessageDi virtual ~SessionEstablishmentExchangeDispatch() {} - CHIP_ERROR Init(TransportMgrBase * transportMgr) + CHIP_ERROR Init(SecureSessionMgr * sessionMgr) { - ReturnErrorCodeIf(transportMgr == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - mTransportMgr = transportMgr; + ReturnErrorCodeIf(sessionMgr == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + mSessionMgr = sessionMgr; return ExchangeMessageDispatch::Init(); } @@ -51,24 +51,13 @@ class SessionEstablishmentExchangeDispatch : public Messaging::ExchangeMessageDi const Transport::PeerAddress & peerAddress, Messaging::MessageFlags msgFlags, Messaging::ReliableMessageContext * reliableMessageContext) override; - const Transport::PeerAddress & GetPeerAddress() const { return mPeerAddress; } - - void SetPeerAddress(const Transport::PeerAddress & address) { mPeerAddress = address; } - protected: bool MessagePermitted(uint16_t protocol, uint8_t type) override; - bool IsReliableTransmissionAllowed() const override - { - // If the underlying transport is UDP. - return (mPeerAddress.GetTransportType() == Transport::Type::kUdp); - } - bool IsEncryptionRequired() const override { return false; } private: - TransportMgrBase * mTransportMgr = nullptr; - Transport::PeerAddress mPeerAddress; + SecureSessionMgr * mSessionMgr = nullptr; }; } // namespace chip diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index f637f4a0c5faab..758565f3790afa 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -176,8 +176,8 @@ void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); - NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context = ctx.NewExchangeToLocal(&pairing); + NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * context = ctx.NewUnauthenticatedExchangeToLocal(&pairing); NL_TEST_ASSERT(inSuite, pairing.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), nullptr, Node01_01, 0, nullptr, @@ -191,14 +191,19 @@ void CASE_SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); + // Clear pending packet in CRMP + ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageContext * rc = context->GetReliableMessageContext(); + rm->ClearRetransTable(rc); + gLoopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; CASESession pairing1; - NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); gLoopback.mSentMessageCount = 0; gLoopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; - ExchangeContext * context1 = ctx.NewExchangeToLocal(&pairing1); + ExchangeContext * context1 = ctx.NewUnauthenticatedExchangeToLocal(&pairing1); NL_TEST_ASSERT(inSuite, pairing1.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, context1, @@ -218,14 +223,14 @@ void CASE_SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inConte CASESessionSerializable serializableAccessory; gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForType( Protocols::SecureChannel::MsgType::CASE_SigmaR1, &pairingAccessory) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(&pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToLocal(&pairingCommissioner); FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); @@ -236,7 +241,7 @@ void CASE_SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inConte pairingCommissioner.EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, contextCommissioner, &delegateCommissioner) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 3); + NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 4); NL_TEST_ASSERT(inSuite, delegateAccessory.mNumPairingComplete == 1); NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); @@ -343,8 +348,8 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte TestContext & ctx = *reinterpret_cast(inContext); gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner->MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, gPairingServer.GetSession().MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingCommissioner->MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, gPairingServer.GetSession().MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); SessionIDAllocator idAllocator; @@ -353,7 +358,7 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte &ctx.GetSecureSessionManager(), &gDeviceFabrics, &idAllocator) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToLocal(pairingCommissioner); FabricInfo * fabric = gCommissionerFabrics.FindFabricWithIndex(gCommissionerFabricIndex); NL_TEST_ASSERT(inSuite, fabric != nullptr); @@ -362,12 +367,12 @@ void CASE_SecurePairingHandshakeServerTest(nlTestSuite * inSuite, void * inConte pairingCommissioner->EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, contextCommissioner, &delegateCommissioner) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 3); + NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 4); NL_TEST_ASSERT(inSuite, delegateCommissioner.mNumPairingComplete == 1); auto * pairingCommissioner1 = chip::Platform::New(); - NL_TEST_ASSERT(inSuite, pairingCommissioner1->MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner1 = ctx.NewExchangeToLocal(pairingCommissioner1); + NL_TEST_ASSERT(inSuite, pairingCommissioner1->MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * contextCommissioner1 = ctx.NewUnauthenticatedExchangeToLocal(pairingCommissioner1); NL_TEST_ASSERT(inSuite, pairingCommissioner1->EstablishSession(Transport::PeerAddress(Transport::Type::kBle), fabric, Node01_01, 0, diff --git a/src/protocols/secure_channel/tests/TestPASESession.cpp b/src/protocols/secure_channel/tests/TestPASESession.cpp index 6db19a13cd041c..b915988563c744 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -122,8 +122,8 @@ void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) gLoopback.Reset(); - NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context = ctx.NewExchangeToLocal(&pairing); + NL_TEST_ASSERT(inSuite, pairing.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * context = ctx.NewUnauthenticatedExchangeToLocal(&pairing); NL_TEST_ASSERT(inSuite, pairing.Pair(Transport::PeerAddress(Transport::Type::kBle), 1234, 0, nullptr, nullptr) != CHIP_NO_ERROR); @@ -134,13 +134,18 @@ void SecurePairingStartTest(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); + // Clear pending packet in CRMP + ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); + ReliableMessageContext * rc = context->GetReliableMessageContext(); + rm->ClearRetransTable(rc); + gLoopback.Reset(); gLoopback.mSentMessageCount = 0; gLoopback.mMessageSendError = CHIP_ERROR_BAD_REQUEST; PASESession pairing1; - NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - ExchangeContext * context1 = ctx.NewExchangeToLocal(&pairing1); + NL_TEST_ASSERT(inSuite, pairing1.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + ExchangeContext * context1 = ctx.NewUnauthenticatedExchangeToLocal(&pairing1); NL_TEST_ASSERT(inSuite, pairing1.Pair(Transport::PeerAddress(Transport::Type::kBle), 1234, 0, context1, &delegate) == CHIP_ERROR_BAD_REQUEST); @@ -157,16 +162,13 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, P gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(&pairingCommissioner); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToLocal(&pairingCommissioner); if (gLoopback.mNumMessagesToDrop != 0) { - pairingCommissioner.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); - pairingAccessory.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); - ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = contextCommissioner->GetReliableMessageContext(); NL_TEST_ASSERT(inSuite, rm != nullptr); @@ -221,6 +223,8 @@ void SecurePairingHandshakeWithPacketLossTest(nlTestSuite * inSuite, void * inCo void SecurePairingFailedHandshake(nlTestSuite * inSuite, void * inContext) { + TestContext & ctx = *reinterpret_cast(inContext); + TestSecurePairingDelegate delegateCommissioner; PASESession pairingCommissioner; @@ -230,14 +234,10 @@ void SecurePairingFailedHandshake(nlTestSuite * inSuite, void * inContext) gLoopback.Reset(); gLoopback.mSentMessageCount = 0; - NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&gTransportMgr) == CHIP_NO_ERROR); - - TestContext & ctx = *reinterpret_cast(inContext); - ExchangeContext * contextCommissioner = ctx.NewExchangeToLocal(&pairingCommissioner); + NL_TEST_ASSERT(inSuite, pairingCommissioner.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, pairingAccessory.MessageDispatch().Init(&ctx.GetSecureSessionManager()) == CHIP_NO_ERROR); - pairingCommissioner.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); - pairingAccessory.MessageDispatch().SetPeerAddress(PeerAddress(Type::kUdp)); + ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToLocal(&pairingCommissioner); ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); ReliableMessageContext * rc = contextCommissioner->GetReliableMessageContext(); diff --git a/src/transport/PeerMessageCounter.h b/src/transport/PeerMessageCounter.h index d423cdda2ea355..e13da508183276 100644 --- a/src/transport/PeerMessageCounter.h +++ b/src/transport/PeerMessageCounter.h @@ -97,7 +97,7 @@ class PeerMessageCounter uint32_t offset = mSynced.mMaxCounter - counter; if (offset >= CHIP_CONFIG_MESSAGE_COUNTER_WINDOW_SIZE) { - return CHIP_ERROR_INVALID_ARGUMENT; // outside valid range + return CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW; // outside valid range } if (mSynced.mWindow.test(offset)) { @@ -108,6 +108,36 @@ class PeerMessageCounter return CHIP_NO_ERROR; } + CHIP_ERROR VerifyOrTrustFirst(uint32_t counter) + { + switch (mStatus) + { + case Status::NotSynced: + // Trust and set the counter when not synced + SetCounter(counter); + return CHIP_NO_ERROR; + case Status::SyncInProcess: + VerifyOrDie(false); + return CHIP_ERROR_INTERNAL; + case Status::Synced: { + CHIP_ERROR err = Verify(counter); + if (err == CHIP_ERROR_MESSAGE_ID_OUT_OF_WINDOW) + { + // According to chip spec, when global unencrypted message + // counter is out of window, the peer may have reset and is + // using another randomize initial value. Trust the new + // counter here. + SetCounter(counter); + err = CHIP_NO_ERROR; + } + return err; + } + default: + VerifyOrDie(false); + return CHIP_ERROR_INTERNAL; + } + } + /** * @brief * With the counter verified and the packet MIC also verified by the secure key, we can trust the packet and adjust diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index d5ffcb2d57ff81..5d1061d7c03860 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -102,9 +102,8 @@ void SecureSessionMgr::Shutdown() mCB = nullptr; } -CHIP_ERROR SecureSessionMgr::BuildEncryptedMessagePayload(SessionHandle session, PayloadHeader & payloadHeader, - System::PacketBufferHandle && msgBuf, - EncryptedPacketBufferHandle & encryptedMessage) +CHIP_ERROR SecureSessionMgr::PrepareMessage(SessionHandle session, PayloadHeader & payloadHeader, + System::PacketBufferHandle && message, EncryptedPacketBufferHandle & preparedMessage) { PacketHeader packetHeader; if (IsControlMessage(payloadHeader)) @@ -112,71 +111,91 @@ CHIP_ERROR SecureSessionMgr::BuildEncryptedMessagePayload(SessionHandle session, packetHeader.SetSecureSessionControlMsg(true); } - PeerConnectionState * state = GetPeerConnectionState(session); - if (state == nullptr) + if (session.IsSecure()) { - return CHIP_ERROR_NOT_CONNECTED; + PeerConnectionState * state = GetPeerConnectionState(session); + if (state == nullptr) + { + return CHIP_ERROR_NOT_CONNECTED; + } + + MessageCounter & counter = GetSendCounterForPacket(payloadHeader, *state); + ReturnErrorOnFailure(SecureMessageCodec::Encode(state, payloadHeader, packetHeader, message, counter)); + + ChipLogProgress(Inet, "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 " on exchange %d with MessageId %" PRIu32 ".", + "encrypted", &preparedMessage, ChipLogValueX64(state->GetPeerNodeId()), payloadHeader.GetMessageType(), + payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), packetHeader.GetMessageId()); } + else + { + ReturnErrorOnFailure(payloadHeader.EncodeBeforeData(message)); + + MessageCounter & counter = session.GetUnauthenticatedSession()->GetLocalMessageCounter(); + uint32_t messageId = counter.Value(); + ReturnErrorOnFailure(counter.Advance()); - MessageCounter & counter = GetSendCounterForPacket(payloadHeader, *state); - ReturnErrorOnFailure(SecureMessageCodec::Encode(state, payloadHeader, packetHeader, msgBuf, counter)); + packetHeader.SetMessageId(messageId); - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(msgBuf)); + ChipLogProgress(Inet, "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 " on exchange %d with MessageId %" PRIu32 ".", + "plaintext", &preparedMessage, ChipLogValueX64(kUndefinedNodeId), payloadHeader.GetMessageType(), + payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), packetHeader.GetMessageId()); + } - encryptedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(msgBuf)); - ChipLogProgress(Inet, "Encrypted message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 " on exchange %d.", - &encryptedMessage, ChipLogValueX64(state->GetPeerNodeId()), payloadHeader.GetMessageType(), - payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID()); + ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); + preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); return CHIP_NO_ERROR; } CHIP_ERROR SecureSessionMgr::SendPreparedMessage(SessionHandle session, const EncryptedPacketBufferHandle & preparedMessage) { - CHIP_ERROR err = CHIP_NO_ERROR; - PeerConnectionState * state = nullptr; - PacketBufferHandle msgBuf; + VerifyOrReturnError(mState == State::kInitialized, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!preparedMessage.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(mState == State::kInitialized, err = CHIP_ERROR_INCORRECT_STATE); - VerifyOrExit(!preparedMessage.IsNull(), err = CHIP_ERROR_INVALID_ARGUMENT); - msgBuf = preparedMessage.CastToWritable(); - VerifyOrExit(!msgBuf.IsNull(), err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(!msgBuf->HasChainedBuffer(), err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + const Transport::PeerAddress * destination; - // Find an active connection to the specified peer node - state = GetPeerConnectionState(session); - VerifyOrExit(state != nullptr, err = CHIP_ERROR_NOT_CONNECTED); + if (session.IsSecure()) + { + // Find an active connection to the specified peer node + PeerConnectionState * state = GetPeerConnectionState(session); + if (state == nullptr) + { + ChipLogError(Inet, "Secure transport could not find a valid PeerConnection"); + return CHIP_ERROR_NOT_CONNECTED; + } - // This marks any connection where we send data to as 'active' - mPeerConnections.MarkConnectionActive(state); + // This marks any connection where we send data to as 'active' + mPeerConnections.MarkConnectionActive(state); - ChipLogProgress(Inet, "Sending msg %p to 0x" ChipLogFormatX64 " at utc time: %" PRId64 " msec", &preparedMessage, - ChipLogValueX64(state->GetPeerNodeId()), System::Clock::GetMonotonicMilliseconds()); + destination = &state->GetPeerAddress(); - if (mTransportMgr != nullptr) - { - ChipLogProgress(Inet, "Sending secure msg on generic transport"); - err = mTransportMgr->SendMessage(state->GetPeerAddress(), std::move(msgBuf)); + ChipLogProgress(Inet, "Sending %s msg %p to 0x" ChipLogFormatX64 " at utc time: %" PRId64 " msec", "encrypted", + &preparedMessage, ChipLogValueX64(state->GetPeerNodeId()), System::Clock::GetMonotonicMilliseconds()); } else { - ChipLogError(Inet, "The transport manager is not initialized. Unable to send the message"); - err = CHIP_ERROR_INCORRECT_STATE; + auto unauthenticated = session.GetUnauthenticatedSession(); + mUnauthenticatedSessions.MarkSessionActive(unauthenticated.Get()); + destination = &unauthenticated->GetPeerAddress(); + + ChipLogProgress(Inet, "Sending %s msg %p to 0x" ChipLogFormatX64 " at utc time: %" PRId64 " msec", "plaintext", + &preparedMessage, ChipLogValueX64(kUndefinedNodeId), System::Clock::GetMonotonicMilliseconds()); } - ChipLogProgress(Inet, "Secure msg send status %s", ErrorStr(err)); - SuccessOrExit(err); -exit: - if (!msgBuf.IsNull()) + PacketBufferHandle msgBuf = preparedMessage.CastToWritable(); + VerifyOrReturnError(!msgBuf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!msgBuf->HasChainedBuffer(), CHIP_ERROR_INVALID_MESSAGE_LENGTH); + + if (mTransportMgr != nullptr) { - const char * errStr = ErrorStr(err); - if (state == nullptr) - { - ChipLogError(Inet, "Secure transport could not find a valid PeerConnection: %s", errStr); - } + ChipLogProgress(Inet, "Sending msg on generic transport"); + return mTransportMgr->SendMessage(*destination, std::move(msgBuf)); + } + else + { + ChipLogError(Inet, "The transport manager is not initialized. Unable to send the message"); + return CHIP_ERROR_INCORRECT_STATE; } - - return err; } void SecureSessionMgr::ExpirePairing(SessionHandle session) @@ -292,12 +311,47 @@ void SecureSessionMgr::OnMessageReceived(const PeerAddress & peerAddress, System void SecureSessionMgr::MessageDispatch(const PacketHeader & packetHeader, const Transport::PeerAddress & peerAddress, System::PacketBufferHandle && msg) { + Transport::UnauthenticatedSession * session = mUnauthenticatedSessions.FindOrAllocateEntry(peerAddress); + if (session == nullptr) + { + ChipLogError(Inet, "UnauthenticatedSession exhausted"); + return; + } + + SecureSessionMgrDelegate::DuplicateMessage isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::No; + + // Verify message counter + CHIP_ERROR err = session->GetPeerMessageCounter().VerifyOrTrustFirst(packetHeader.GetMessageId()); + if (err == CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED) + { + ChipLogDetail(Inet, "Received a duplicate message with MessageId: %" PRIu32, packetHeader.GetMessageId()); + isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::Yes; + err = CHIP_NO_ERROR; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Inet, "Message counter verify failed, err = %" CHIP_ERROR_FORMAT, err.Format()); + return; + } + + mUnauthenticatedSessions.MarkSessionActive(*session); + + PayloadHeader payloadHeader; + ReturnOnFailure(payloadHeader.DecodeAndConsume(msg)); + + if (isDuplicate == SecureSessionMgrDelegate::DuplicateMessage::Yes && !payloadHeader.NeedsAck()) + { + // If it's a duplicate message, but doesn't require an ack, let's drop it right here to save CPU + // cycles on further message processing. + return; + } + + session->GetPeerMessageCounter().Commit(packetHeader.GetMessageId()); + if (mCB != nullptr) { - PayloadHeader payloadHeader; - ReturnOnFailure(payloadHeader.DecodeAndConsume(msg)); - mCB->OnMessageReceived(packetHeader, payloadHeader, SessionHandle::TemporaryUnauthenticatedSession(), peerAddress, - SecureSessionMgrDelegate::DuplicateMessage::No, std::move(msg)); + mCB->OnMessageReceived(packetHeader, payloadHeader, SessionHandle(Transport::UnauthenticatedSessionHandle(*session)), + peerAddress, isDuplicate, std::move(msg)); } } @@ -353,7 +407,7 @@ void SecureSessionMgr::SecureMessageDispatch(const PacketHeader & packetHeader, err = state->GetSessionMessageCounter().GetPeerMessageCounter().Verify(packetHeader.GetMessageId()); if (err == CHIP_ERROR_DUPLICATE_MESSAGE_RECEIVED) { - ChipLogDetail(Inet, "Received a duplicate message"); + ChipLogDetail(Inet, "Received a duplicate message with MessageId: %" PRIu32, packetHeader.GetMessageId()); isDuplicate = SecureSessionMgrDelegate::DuplicateMessage::Yes; err = CHIP_NO_ERROR; } diff --git a/src/transport/SecureSessionMgr.h b/src/transport/SecureSessionMgr.h index 9c2740ac825293..38940a9b47467d 100644 --- a/src/transport/SecureSessionMgr.h +++ b/src/transport/SecureSessionMgr.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -191,8 +192,8 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate * 3. Encode the packet header and prepend it to message. * Returns a encrypted message in encryptedMessage. */ - CHIP_ERROR BuildEncryptedMessagePayload(SessionHandle session, PayloadHeader & payloadHeader, - System::PacketBufferHandle && msgBuf, EncryptedPacketBufferHandle & encryptedMessage); + CHIP_ERROR PrepareMessage(SessionHandle session, PayloadHeader & payloadHeader, System::PacketBufferHandle && msgBuf, + EncryptedPacketBufferHandle & encryptedMessage); /** * @brief @@ -262,6 +263,15 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate */ void OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msgBuf) override; + Optional CreateUnauthenticatedSession(const Transport::PeerAddress & peerAddress) + { + Transport::UnauthenticatedSession * session = mUnauthenticatedSessions.FindOrAllocateEntry(peerAddress); + if (session == nullptr) + return Optional::Missing(); + + return Optional::Value(SessionHandle(Transport::UnauthenticatedSessionHandle(*session))); + } + private: /** * The State of a secure transport object. @@ -279,6 +289,7 @@ class DLL_EXPORT SecureSessionMgr : public TransportMgrDelegate }; System::Layer * mSystemLayer = nullptr; + Transport::UnauthenticatedSessionTable mUnauthenticatedSessions; Transport::PeerConnections mPeerConnections; // < Active connections to other peers State mState; // < Initialization state of the object diff --git a/src/transport/SessionHandle.h b/src/transport/SessionHandle.h index fe9f0cadf26a5e..2fe7bfe6fde830 100644 --- a/src/transport/SessionHandle.h +++ b/src/transport/SessionHandle.h @@ -17,6 +17,8 @@ #pragma once +#include + namespace chip { class SecureSessionMgr; @@ -26,6 +28,10 @@ class SessionHandle public: SessionHandle(NodeId peerNodeId, FabricIndex fabric) : mPeerNodeId(peerNodeId), mFabric(fabric) {} + SessionHandle(Transport::UnauthenticatedSessionHandle session) : + mPeerNodeId(kPlaceholderNodeId), mFabric(Transport::kUndefinedFabricIndex), mUnauthenticatedSessionHandle(session) + {} + SessionHandle(NodeId peerNodeId, uint16_t localKeyId, uint16_t peerKeyId, FabricIndex fabric) : mPeerNodeId(peerNodeId), mFabric(fabric) { @@ -33,6 +39,8 @@ class SessionHandle mPeerKeyId.SetValue(peerKeyId); } + bool IsSecure() { return !mUnauthenticatedSessionHandle.HasValue(); } + bool HasFabricIndex() const { return (mFabric != Transport::kUndefinedFabricIndex); } FabricIndex GetFabricIndex() const { return mFabric; } void SetFabricIndex(FabricIndex fabricId) { mFabric = fabricId; } @@ -62,14 +70,12 @@ class SessionHandle const Optional & GetPeerKeyId() const { return mPeerKeyId; } const Optional & GetLocalKeyId() const { return mLocalKeyId; } - // TODO: currently SessionHandle is not able to identify a unauthenticated session, create an empty handle for it - static SessionHandle TemporaryUnauthenticatedSession() - { - return SessionHandle(kPlaceholderNodeId, Transport::kUndefinedFabricIndex); - } + Transport::UnauthenticatedSessionHandle GetUnauthenticatedSession() { return mUnauthenticatedSessionHandle.Value(); } private: friend class SecureSessionMgr; + + // Fields for secure session NodeId mPeerNodeId; Optional mLocalKeyId; Optional mPeerKeyId; @@ -78,6 +84,9 @@ class SessionHandle // to identify an approach that'll allow looking up the corresponding information for // such sessions. FabricIndex mFabric; + + // Fields for unauthenticated session + Optional mUnauthenticatedSessionHandle; }; } // namespace chip diff --git a/src/transport/UnauthenticatedSessionTable.h b/src/transport/UnauthenticatedSessionTable.h new file mode 100644 index 00000000000000..6f6c0f7acf64c1 --- /dev/null +++ b/src/transport/UnauthenticatedSessionTable.h @@ -0,0 +1,202 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace Transport { + +class UnauthenticatedSession; +using UnauthenticatedSessionHandle = ReferenceCountedHandle; + +class UnauthenticatedSessionDeleter +{ +public: + // This is a no-op because life-cycle of UnauthenticatedSessionTable is rotated by LRU + static void Release(UnauthenticatedSession * entry) {} +}; + +/** + * @brief + * An UnauthenticatedSession stores the binding of TransportAddress, and message counters. + * + * The entries are rotated using LRU, but entry can be hold by using UnauthenticatedSessionHandle, which increase the reference + * count by 1. If the reference count is not 0, the entry won't be pruned. + */ +class UnauthenticatedSession : public ReferenceCounted +{ +public: + UnauthenticatedSession(const PeerAddress & address) : mPeerAddress(address) {} + + UnauthenticatedSession(const UnauthenticatedSession &) = delete; + UnauthenticatedSession & operator=(const UnauthenticatedSession &) = delete; + UnauthenticatedSession(UnauthenticatedSession &&) = delete; + UnauthenticatedSession & operator=(UnauthenticatedSession &&) = delete; + + uint64_t GetLastActivityTimeMs() const { return mLastActivityTimeMs; } + void SetLastActivityTimeMs(uint64_t value) { mLastActivityTimeMs = value; } + + const PeerAddress & GetPeerAddress() const { return mPeerAddress; } + + MessageCounter & GetLocalMessageCounter() { return mLocalMessageCounter; } + PeerMessageCounter & GetPeerMessageCounter() { return mPeerMessageCounter; } + +private: + uint64_t mLastActivityTimeMs = 0; + + const PeerAddress mPeerAddress; + GlobalUnencryptedMessageCounter mLocalMessageCounter; + PeerMessageCounter mPeerMessageCounter; +}; + +template +class UnauthenticatedSessionTable +{ +public: + /** + * Allocates a new session out of the internal resource pool. + * + * @returns CHIP_NO_ERROR if new session created. May fail if maximum connection count has been reached (with + * CHIP_ERROR_NO_MEMORY). + */ + CHECK_RETURN_VALUE + CHIP_ERROR AllocEntry(const PeerAddress & address, UnauthenticatedSession *& entry) + { + entry = mEntries.CreateObject(address); + if (entry != nullptr) + return CHIP_NO_ERROR; + + entry = FindLeastRecentUsedEntry(); + if (entry == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + + const uint64_t currentTime = mTimeSource.GetCurrentMonotonicTimeMs(); + if (currentTime - entry->GetLastActivityTimeMs() < kMinimalActivityTimeMs) + { + // Protect the entry for a short period to prevent from rotating too fast. + entry = nullptr; + return CHIP_ERROR_NO_MEMORY; + } + + mEntries.ResetObject(entry, address); + return CHIP_NO_ERROR; + } + + /** + * Get a session using given address + * + * @return the peer found, nullptr if not found + */ + CHECK_RETURN_VALUE + UnauthenticatedSession * FindEntry(const PeerAddress & address) + { + UnauthenticatedSession * result = nullptr; + mEntries.ForEachActiveObject([&](UnauthenticatedSession * entry) { + if (MatchPeerAddress(entry->GetPeerAddress(), address)) + { + result = entry; + return false; + } + return true; + }); + return result; + } + + /** + * Get a peer given the peer id. If the peer doesn't exist in the cache, allocate a new entry for it. + * + * @return the peer found or allocated, nullptr if not found and allocate failed. + */ + CHECK_RETURN_VALUE + UnauthenticatedSession * FindOrAllocateEntry(const PeerAddress & address) + { + UnauthenticatedSession * result = FindEntry(address); + if (result != nullptr) + return result; + + CHIP_ERROR err = AllocEntry(address, result); + if (err == CHIP_NO_ERROR) + { + return result; + } + else + { + return nullptr; + } + } + + /// Mark a session as active + void MarkSessionActive(UnauthenticatedSession & entry) { entry.SetLastActivityTimeMs(mTimeSource.GetCurrentMonotonicTimeMs()); } + + /// Allows access to the underlying time source used for keeping track of connection active time + Time::TimeSource & GetTimeSource() { return mTimeSource; } + +private: + UnauthenticatedSession * FindLeastRecentUsedEntry() + { + UnauthenticatedSession * result = nullptr; + uint64_t oldestTimeMs = std::numeric_limits::max(); + + mEntries.ForEachActiveObject([&](UnauthenticatedSession * entry) { + if (entry->GetReferenceCount() == 0 && entry->GetLastActivityTimeMs() < oldestTimeMs) + { + result = entry; + oldestTimeMs = entry->GetLastActivityTimeMs(); + } + return true; + }); + + return result; + } + + static bool MatchPeerAddress(const PeerAddress & a1, const PeerAddress & a2) + { + if (a1.GetTransportType() != a2.GetTransportType()) return false; + + switch (a1.GetTransportType()) + { + case Transport::Type::kUndefined: + return false; + case Transport::Type::kUdp: + case Transport::Type::kTcp: + // Ingore interface in the address + return a1.GetIPAddress() == a2.GetIPAddress() && a1.GetPort() == a2.GetPort(); + case Transport::Type::kBle: + // TODO: complete BLE address comparation + return true; + } + + return false; + } + + static constexpr uint64_t kMinimalActivityTimeMs = 30000; + Time::TimeSource mTimeSource; + BitMapObjectPool mEntries; +}; + +} // namespace Transport +} // namespace chip diff --git a/src/transport/tests/TestSecureSessionMgr.cpp b/src/transport/tests/TestSecureSessionMgr.cpp index 23b43774826a7d..dffb3b9b196c7b 100644 --- a/src/transport/tests/TestSecureSessionMgr.cpp +++ b/src/transport/tests/TestSecureSessionMgr.cpp @@ -180,7 +180,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) payloadHeader.SetMessageType(chip::Protocols::Echo::MsgType::EchoRequest); EncryptedPacketBufferHandle preparedMessage; - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); @@ -194,8 +194,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) callback.LargeMessageSent = true; - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(large_buffer), - preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(large_buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); @@ -211,8 +210,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) callback.LargeMessageSent = true; - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(extra_large_buffer), - preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(extra_large_buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_MESSAGE_TOO_LONG); } @@ -272,7 +270,7 @@ void SendEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) payloadHeader.SetInitiator(true); - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); @@ -346,7 +344,7 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) payloadHeader.SetInitiator(true); - err = secureSessionMgr.BuildEncryptedMessagePayload(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); + err = secureSessionMgr.PrepareMessage(localToRemoteSession, payloadHeader, std::move(buffer), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); err = secureSessionMgr.SendPreparedMessage(localToRemoteSession, preparedMessage); From b7f04924d36b3fbb54a6a92736758654c48c78cd Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Thu, 2 Sep 2021 09:25:46 +0000 Subject: [PATCH 3/3] Restyled by clang-format --- src/transport/SecureSessionMgr.cpp | 14 ++++++++++---- src/transport/UnauthenticatedSessionTable.h | 21 +++++++++++---------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/transport/SecureSessionMgr.cpp b/src/transport/SecureSessionMgr.cpp index 5d1061d7c03860..006ad3396e937f 100644 --- a/src/transport/SecureSessionMgr.cpp +++ b/src/transport/SecureSessionMgr.cpp @@ -122,9 +122,12 @@ CHIP_ERROR SecureSessionMgr::PrepareMessage(SessionHandle session, PayloadHeader MessageCounter & counter = GetSendCounterForPacket(payloadHeader, *state); ReturnErrorOnFailure(SecureMessageCodec::Encode(state, payloadHeader, packetHeader, message, counter)); - ChipLogProgress(Inet, "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 " on exchange %d with MessageId %" PRIu32 ".", + ChipLogProgress(Inet, + "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 + " on exchange %d with MessageId %" PRIu32 ".", "encrypted", &preparedMessage, ChipLogValueX64(state->GetPeerNodeId()), payloadHeader.GetMessageType(), - payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), packetHeader.GetMessageId()); + payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), + packetHeader.GetMessageId()); } else { @@ -136,9 +139,12 @@ CHIP_ERROR SecureSessionMgr::PrepareMessage(SessionHandle session, PayloadHeader packetHeader.SetMessageId(messageId); - ChipLogProgress(Inet, "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 " on exchange %d with MessageId %" PRIu32 ".", + ChipLogProgress(Inet, + "Build %s message %p to 0x" ChipLogFormatX64 " of type %d and protocolId %" PRIu32 + " on exchange %d with MessageId %" PRIu32 ".", "plaintext", &preparedMessage, ChipLogValueX64(kUndefinedNodeId), payloadHeader.GetMessageType(), - payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), packetHeader.GetMessageId()); + payloadHeader.GetProtocolID().ToFullyQualifiedSpecForm(), payloadHeader.GetExchangeID(), + packetHeader.GetMessageId()); } ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); diff --git a/src/transport/UnauthenticatedSessionTable.h b/src/transport/UnauthenticatedSessionTable.h index 6f6c0f7acf64c1..2216b1f452ba5d 100644 --- a/src/transport/UnauthenticatedSessionTable.h +++ b/src/transport/UnauthenticatedSessionTable.h @@ -175,19 +175,20 @@ class UnauthenticatedSessionTable static bool MatchPeerAddress(const PeerAddress & a1, const PeerAddress & a2) { - if (a1.GetTransportType() != a2.GetTransportType()) return false; + if (a1.GetTransportType() != a2.GetTransportType()) + return false; switch (a1.GetTransportType()) { - case Transport::Type::kUndefined: - return false; - case Transport::Type::kUdp: - case Transport::Type::kTcp: - // Ingore interface in the address - return a1.GetIPAddress() == a2.GetIPAddress() && a1.GetPort() == a2.GetPort(); - case Transport::Type::kBle: - // TODO: complete BLE address comparation - return true; + case Transport::Type::kUndefined: + return false; + case Transport::Type::kUdp: + case Transport::Type::kTcp: + // Ingore interface in the address + return a1.GetIPAddress() == a2.GetIPAddress() && a1.GetPort() == a2.GetPort(); + case Transport::Type::kBle: + // TODO: complete BLE address comparation + return true; } return false;