diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index 6321a838f2c689..3a50001c1ce3fb 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -48,6 +48,9 @@ source_set("chip-all-clusters-common") { deps = [ "${chip_root}/examples/all-clusters-app/all-clusters-common", "${chip_root}/examples/platform/linux:app-main", + + # Issue 29397 for the icd:cluster dep + "${chip_root}/src/app/icd:cluster", "${chip_root}/src/app/tests/suites/credentials:dac_provider", "${chip_root}/src/lib", "${chip_root}/third_party/jsoncpp", diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index 3315f6c84297fe..a6deafde128983 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -46,6 +46,8 @@ #include #include +#include + #include using namespace chip; @@ -215,6 +217,11 @@ void ApplicationInit() #endif Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); + // Issue 29397 + // Somehow All-cluster-app test the ICDManagementServer cluster without having + // CHIP_CONFIG_ENABLE_ICD_SERVER set to 1. + ICDManagementServer::GetInstance().SetSymmetricKeystore(Server::GetInstance().GetSessionKeystore()); + SetTagList(/* endpoint= */ 0, Span(gEp0TagList)); SetTagList(/* endpoint= */ 1, Span(gEp1TagList)); SetTagList(/* endpoint= */ 2, Span(gEp2TagList)); diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 550c8fbf9ccb1b..7490e395eec930 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -288,7 +288,6 @@ template("chip_data_model") { ] } else if (cluster == "icd-management-server") { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ] - deps += [ "${chip_root}/src/app/icd:cluster" ] } else if (cluster == "resource-monitoring-server") { sources += [ diff --git a/src/app/clusters/icd-management-server/icd-management-server.cpp b/src/app/clusters/icd-management-server/icd-management-server.cpp index be5be9be59e6aa..39bf34c373667e 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.cpp +++ b/src/app/clusters/icd-management-server/icd-management-server.cpp @@ -107,13 +107,14 @@ CHIP_ERROR IcdManagementAttributeAccess::ReadRegisteredClients(EndpointId endpoi uint16_t supported_clients = ICDManagementServer::GetInstance().GetClientsSupportedPerFabric(); return encoder.EncodeList([supported_clients](const auto & subEncoder) -> CHIP_ERROR { - ICDMonitoringEntry e; + Crypto::SessionKeystore * keyStore = Server::GetInstance().GetSessionKeystore(); + ICDMonitoringEntry e(keyStore); - const auto & fabricTable = Server::GetInstance().GetFabricTable(); + const auto & fabricTable = Server::GetInstance().GetFabricTable(); + PersistentStorageDelegate & storage = Server::GetInstance().GetPersistentStorage(); for (const auto & fabricInfo : fabricTable) { - PersistentStorageDelegate & storage = chip::Server::GetInstance().GetPersistentStorage(); - ICDMonitoringTable table(storage, fabricInfo.GetFabricIndex(), supported_clients); + ICDMonitoringTable table(storage, fabricInfo.GetFabricIndex(), supported_clients, keyStore); for (uint16_t i = 0; i < table.Limit(); ++i) { CHIP_ERROR err = table.Get(i, e); @@ -165,7 +166,8 @@ class IcdManagementFabricDelegate : public chip::FabricTable::Delegate void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override { uint16_t supported_clients = ICDManagementServer::GetInstance().GetClientsSupportedPerFabric(); - ICDMonitoringTable table(chip::Server::GetInstance().GetPersistentStorage(), fabricIndex, supported_clients); + ICDMonitoringTable table(Server::GetInstance().GetPersistentStorage(), fabricIndex, supported_clients, + Server::GetInstance().GetSessionKeystore()); table.RemoveAll(); } }; diff --git a/src/app/icd/ICDManagementServer.cpp b/src/app/icd/ICDManagementServer.cpp index c93056f8041c82..0f7cc7ebf5275a 100644 --- a/src/app/icd/ICDManagementServer.cpp +++ b/src/app/icd/ICDManagementServer.cpp @@ -1,5 +1,4 @@ #include "ICDManagementServer.h" -#include using namespace chip; using namespace chip::Protocols; @@ -12,10 +11,10 @@ Status ICDManagementServer::RegisterClient(PersistentStorageDelegate & storage, uint64_t monitored_subject, chip::ByteSpan key, Optional verification_key, bool is_admin) { - ICDMonitoringTable table(storage, fabric_index, GetClientsSupportedPerFabric()); + ICDMonitoringTable table(storage, fabric_index, GetClientsSupportedPerFabric(), mSymmetricKeystore); // Get current entry, if exists - ICDMonitoringEntry entry; + ICDMonitoringEntry entry(mSymmetricKeystore); CHIP_ERROR err = table.Find(node_id, entry); if (CHIP_NO_ERROR == err) { @@ -23,7 +22,7 @@ Status ICDManagementServer::RegisterClient(PersistentStorageDelegate & storage, if (!is_admin) { VerifyOrReturnError(verification_key.HasValue(), InteractionModel::Status::Failure); - VerifyOrReturnError(verification_key.Value().data_equal(entry.key), InteractionModel::Status::Failure); + VerifyOrReturnError(entry.IsKeyEquivalent(verification_key.Value()), InteractionModel::Status::Failure); } } else if (CHIP_ERROR_NOT_FOUND == err) @@ -40,8 +39,17 @@ Status ICDManagementServer::RegisterClient(PersistentStorageDelegate & storage, // Save entry.checkInNodeID = node_id; entry.monitoredSubject = monitored_subject; - entry.key = key; - err = table.Set(entry.index, entry); + err = entry.SetKey(key); + VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, InteractionModel::Status::ConstraintError); + VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + err = table.Set(entry.index, entry); + + // Delete key upon failure to prevent key storage leakage. + if (err != CHIP_NO_ERROR) + { + entry.DeleteKey(); + } + VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, InteractionModel::Status::ConstraintError); VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); @@ -51,10 +59,10 @@ Status ICDManagementServer::RegisterClient(PersistentStorageDelegate & storage, Status ICDManagementServer::UnregisterClient(PersistentStorageDelegate & storage, FabricIndex fabric_index, chip::NodeId node_id, Optional verificationKey, bool is_admin) { - ICDMonitoringTable table(storage, fabric_index, GetClientsSupportedPerFabric()); + ICDMonitoringTable table(storage, fabric_index, GetClientsSupportedPerFabric(), mSymmetricKeystore); // Get current entry, if exists - ICDMonitoringEntry entry; + ICDMonitoringEntry entry(mSymmetricKeystore); CHIP_ERROR err = table.Find(node_id, entry); VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, InteractionModel::Status::NotFound); VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); @@ -63,7 +71,7 @@ Status ICDManagementServer::UnregisterClient(PersistentStorageDelegate & storage if (!is_admin) { VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure); - VerifyOrReturnError(verificationKey.Value().data_equal(entry.key), InteractionModel::Status::Failure); + VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), InteractionModel::Status::Failure); } err = table.Remove(entry.index); diff --git a/src/app/icd/ICDManagementServer.h b/src/app/icd/ICDManagementServer.h index 30a38126f86fb9..d3debe94aa066f 100644 --- a/src/app/icd/ICDManagementServer.h +++ b/src/app/icd/ICDManagementServer.h @@ -18,11 +18,14 @@ #pragma once #include +#include #include #include #include #include +#include + namespace chip { using chip::Protocols::InteractionModel::Status; @@ -34,6 +37,8 @@ class ICDManagementServer uint32_t GetActiveModeIntervalMs() { return mActiveInterval_ms; } + void SetSymmetricKeystore(Crypto::SymmetricKeystore * keyStore) { mSymmetricKeystore = keyStore; } + uint16_t GetActiveModeThresholdMs() { return mActiveThreshold_ms; } uint32_t GetICDCounter() { return mICDCounter; } @@ -56,6 +61,7 @@ class ICDManagementServer ICDManagementServer() = default; static ICDManagementServer mInstance; + Crypto::SymmetricKeystore * mSymmetricKeystore = nullptr; static_assert((CHIP_CONFIG_ICD_IDLE_MODE_INTERVAL_SEC) <= 64800, "Spec requires the IdleModeInterval to be equal or inferior to 64800s."); diff --git a/src/app/icd/ICDManager.cpp b/src/app/icd/ICDManager.cpp index 1d7199cb813b55..b4a48a879dc2d9 100644 --- a/src/app/icd/ICDManager.cpp +++ b/src/app/icd/ICDManager.cpp @@ -44,18 +44,24 @@ uint8_t ICDManager::OpenExchangeContextCount = 0; static_assert(UINT8_MAX >= CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS, "ICDManager::OpenExchangeContextCount cannot hold count for the max exchange count"); -void ICDManager::Init(PersistentStorageDelegate * storage, FabricTable * fabricTable, ICDStateObserver * stateObserver) +void ICDManager::Init(PersistentStorageDelegate * storage, FabricTable * fabricTable, ICDStateObserver * stateObserver, + Crypto::SymmetricKeystore * symmetricKeystore) { VerifyOrDie(storage != nullptr); VerifyOrDie(fabricTable != nullptr); VerifyOrDie(stateObserver != nullptr); + VerifyOrDie(symmetricKeystore != nullptr); mStorage = storage; mFabricTable = fabricTable; mStateObserver = stateObserver; VerifyOrDie(ICDNotifier::GetInstance().Subscribe(this) == CHIP_NO_ERROR); + mSymmetricKeystore = symmetricKeystore; uint32_t activeModeInterval = ICDManagementServer::GetInstance().GetActiveModeIntervalMs(); + + ICDManagementServer::GetInstance().SetSymmetricKeystore(mSymmetricKeystore); + VerifyOrDie(kFastPollingInterval.count() < activeModeInterval); UpdateICDMode(); @@ -102,7 +108,7 @@ void ICDManager::UpdateICDMode() for (const auto & fabricInfo : *mFabricTable) { // We only need 1 valid entry to ensure LIT compliance - ICDMonitoringTable table(*mStorage, fabricInfo.GetFabricIndex(), 1 /*Table entry limit*/); + ICDMonitoringTable table(*mStorage, fabricInfo.GetFabricIndex(), 1 /*Table entry limit*/, mSymmetricKeystore); if (!table.IsEmpty()) { tempMode = ICDMode::LIT; diff --git a/src/app/icd/ICDManager.h b/src/app/icd/ICDManager.h index 8eb62d6f17066b..eac58a17c94d9f 100644 --- a/src/app/icd/ICDManager.h +++ b/src/app/icd/ICDManager.h @@ -16,6 +16,7 @@ */ #pragma once +#include #include #include #include @@ -50,7 +51,8 @@ class ICDManager : public ICDListener }; ICDManager() {} - void Init(PersistentStorageDelegate * storage, FabricTable * fabricTable, ICDStateObserver * stateObserver); + void Init(PersistentStorageDelegate * storage, FabricTable * fabricTable, ICDStateObserver * stateObserver, + Crypto::SymmetricKeystore * symmetricKeyStore); void Shutdown(); void UpdateICDMode(); void UpdateOperationState(OperationalState state); @@ -99,12 +101,13 @@ class ICDManager : public ICDListener BitFlags mKeepActiveFlags{ 0 }; - OperationalState mOperationalState = OperationalState::IdleMode; - ICDMode mICDMode = ICDMode::SIT; - PersistentStorageDelegate * mStorage = nullptr; - FabricTable * mFabricTable = nullptr; - ICDStateObserver * mStateObserver = nullptr; - bool mTransitionToIdleCalled = false; + OperationalState mOperationalState = OperationalState::IdleMode; + ICDMode mICDMode = ICDMode::SIT; + PersistentStorageDelegate * mStorage = nullptr; + FabricTable * mFabricTable = nullptr; + ICDStateObserver * mStateObserver = nullptr; + bool mTransitionToIdleCalled = false; + Crypto::SymmetricKeystore * mSymmetricKeystore = nullptr; }; } // namespace app diff --git a/src/app/icd/ICDMonitoringTable.cpp b/src/app/icd/ICDMonitoringTable.cpp index 821cf133060266..cb161a1926b0fe 100644 --- a/src/app/icd/ICDMonitoringTable.cpp +++ b/src/app/icd/ICDMonitoringTable.cpp @@ -1,5 +1,23 @@ +/** + * + * Copyright (c) 2023 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. + */ + #include "ICDMonitoringTable.h" -#include + +#include namespace chip { @@ -23,7 +41,9 @@ CHIP_ERROR ICDMonitoringEntry::Serialize(TLV::TLVWriter & writer) const ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outer)); ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kCheckInNodeID), checkInNodeID)); ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kMonitoredSubject), monitoredSubject)); - ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kKey), key)); + + ByteSpan buf(key.As()); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kKey), buf)); ReturnErrorOnFailure(writer.EndContainer(outer)); return CHIP_NO_ERROR; } @@ -49,9 +69,12 @@ CHIP_ERROR ICDMonitoringEntry::Deserialize(TLV::TLVReader & reader) case to_underlying(Fields::kMonitoredSubject): ReturnErrorOnFailure(reader.Get(monitoredSubject)); break; - case to_underlying(Fields::kKey): - ReturnErrorOnFailure(reader.Get(key)); - break; + case to_underlying(Fields::kKey): { + ByteSpan buf(key.AsMutable()); + ReturnErrorOnFailure(reader.Get(buf)); + ReturnErrorOnFailure(this->SetKey(buf)); + } + break; default: break; } @@ -67,7 +90,72 @@ void ICDMonitoringEntry::Clear() { this->checkInNodeID = kUndefinedNodeId; this->monitoredSubject = kUndefinedNodeId; - this->key = ByteSpan(); + if (symmetricKeystore != nullptr) + { + symmetricKeystore->DestroyKey(this->key); + } +} + +CHIP_ERROR ICDMonitoringEntry::SetKey(ByteSpan keyData) +{ + VerifyOrReturnError(keyData.size() == sizeof(Crypto::Aes128KeyByteArray), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(symmetricKeystore != nullptr, CHIP_ERROR_INTERNAL); + + // DeleteKey in case the handle was already used. + DeleteKey(); + + Crypto::Aes128KeyByteArray keyMaterial; + memcpy(keyMaterial, keyData.data(), sizeof(Crypto::Aes128KeyByteArray)); + + ReturnErrorOnFailure(symmetricKeystore->CreateKey(keyMaterial, key)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ICDMonitoringEntry::DeleteKey() +{ + VerifyOrReturnError(symmetricKeystore != nullptr, CHIP_ERROR_INTERNAL); + symmetricKeystore->DestroyKey(this->key); + return CHIP_NO_ERROR; +} + +bool ICDMonitoringEntry::IsKeyEquivalent(ByteSpan keyData) +{ + VerifyOrReturnValue(keyData.size() == Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES, false); + VerifyOrReturnValue(symmetricKeystore != nullptr, false); + + ICDMonitoringEntry tempEntry(symmetricKeystore); + + VerifyOrReturnValue(tempEntry.SetKey(keyData) == CHIP_NO_ERROR, false); + + // Challenge + uint8_t mic[Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES] = { 0 }; + uint8_t aead[Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES] = { 0 }; + + CHIP_ERROR err; + + uint64_t data = Crypto::GetRandU64(), validation, encrypted; + validation = data; + + err = Crypto::AES_CCM_encrypt(reinterpret_cast(&data), sizeof(data), nullptr, 0, tempEntry.key, aead, + Crypto::CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, reinterpret_cast(&encrypted), mic, + Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES); + + data = 0; + if (err == CHIP_NO_ERROR) + { + err = Crypto::AES_CCM_decrypt(reinterpret_cast(&encrypted), sizeof(encrypted), nullptr, 0, mic, + Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, key, aead, + Crypto::CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, reinterpret_cast(&data)); + } + tempEntry.DeleteKey(); + + if (err != CHIP_NO_ERROR) + { + return false; + } + + return (data == validation) ? true : false; } CHIP_ERROR ICDMonitoringTable::Get(uint16_t index, ICDMonitoringEntry & entry) const @@ -99,37 +187,42 @@ CHIP_ERROR ICDMonitoringTable::Set(uint16_t index, const ICDMonitoringEntry & en VerifyOrReturnError(index < this->Limit(), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(kUndefinedNodeId != entry.checkInNodeID, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(kUndefinedNodeId != entry.monitoredSubject, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(entry.key.size() == ICDMonitoringEntry::kKeyMaxSize, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(nullptr != entry.key.data(), CHIP_ERROR_INVALID_ARGUMENT); ICDMonitoringEntry e(this->mFabric, index); e.checkInNodeID = entry.checkInNodeID; e.monitoredSubject = entry.monitoredSubject; - e.key = entry.key; e.index = index; + memcpy(e.key.AsMutable(), entry.key.As(), + sizeof(Crypto::Aes128KeyByteArray)); + return e.Save(this->mStorage); } CHIP_ERROR ICDMonitoringTable::Remove(uint16_t index) { - ICDMonitoringEntry entry(this->mFabric, index); + ICDMonitoringEntry entry(mSymmetricKeystore, this->mFabric); + + // Retrieve entry and delete the key first as to not + // cause any key leakage. + this->Get(index, entry); + ReturnErrorOnFailure(entry.DeleteKey()); // Shift remaining entries down one position while (CHIP_NO_ERROR == this->Get(static_cast(index + 1), entry)) { - // WARNING: The key data is held in the entry's serializing buffer - ICDMonitoringEntry copy = entry; - this->Set(index++, copy); + this->Set(index++, entry); } // Remove last entry entry.fabricIndex = this->mFabric; entry.index = index; + + // entry.Delete() doesn't delete the key from the AES128KeyHandle return entry.Delete(this->mStorage); } CHIP_ERROR ICDMonitoringTable::RemoveAll() { - ICDMonitoringEntry entry(this->mFabric); + ICDMonitoringEntry entry(mSymmetricKeystore, this->mFabric); uint16_t index = 0; while (index < this->Limit()) { @@ -140,14 +233,15 @@ CHIP_ERROR ICDMonitoringTable::RemoveAll() } ReturnErrorOnFailure(err); entry.fabricIndex = this->mFabric; - entry.Delete(this->mStorage); + ReturnErrorOnFailure(entry.DeleteKey()); + ReturnErrorOnFailure(entry.Delete(this->mStorage)); } return CHIP_NO_ERROR; } bool ICDMonitoringTable::IsEmpty() { - ICDMonitoringEntry entry(this->mFabric); + ICDMonitoringEntry entry(mSymmetricKeystore, this->mFabric); return (this->Get(0, entry) == CHIP_ERROR_NOT_FOUND); } diff --git a/src/app/icd/ICDMonitoringTable.h b/src/app/icd/ICDMonitoringTable.h index de97610dd01f30..4bfd70c772fa65 100644 --- a/src/app/icd/ICDMonitoringTable.h +++ b/src/app/icd/ICDMonitoringTable.h @@ -16,6 +16,8 @@ */ #pragma once +#include +#include #include #include #include @@ -23,13 +25,18 @@ #include #include +namespace chip { +namespace Crypto { +using SymmetricKeystore = SessionKeystore; +} +} // namespace chip + namespace chip { inline constexpr size_t kICDMonitoringBufferSize = 40; struct ICDMonitoringEntry : public PersistentData { - static constexpr size_t kKeyMaxSize = 16; ICDMonitoringEntry(FabricIndex fabric = kUndefinedFabricIndex, NodeId nodeId = kUndefinedNodeId) { @@ -37,17 +44,47 @@ struct ICDMonitoringEntry : public PersistentData this->checkInNodeID = nodeId; this->monitoredSubject = nodeId; } + + ICDMonitoringEntry(Crypto::SymmetricKeystore * keyStore, FabricIndex fabric = kUndefinedFabricIndex, + NodeId nodeId = kUndefinedNodeId) + { + this->fabricIndex = fabric; + this->checkInNodeID = nodeId; + this->monitoredSubject = nodeId; + this->symmetricKeystore = keyStore; + } + bool IsValid() { return this->checkInNodeID != kUndefinedNodeId && this->fabricIndex != kUndefinedFabricIndex; } CHIP_ERROR UpdateKey(StorageKeyName & key) override; CHIP_ERROR Serialize(TLV::TLVWriter & writer) const override; CHIP_ERROR Deserialize(TLV::TLVReader & reader) override; void Clear() override; + CHIP_ERROR SetKey(ByteSpan keyData); + CHIP_ERROR DeleteKey(void); - chip::FabricIndex fabricIndex = static_cast(0); - chip::NodeId checkInNodeID = static_cast(0); - uint64_t monitoredSubject = static_cast(0); - chip::ByteSpan key; - uint16_t index = 0; + /** + * @brief Implement the key verification needed by the ICDManagement Server. + * Since for some key implementations we cannot retrieve the key from the AES128KeyHandle + * we must implement a way to deduce whether the verification key + * received is the same or at least works as the same way as the one stored. + * + * This method will produce a random number and then encrypt it with the keyData. + * It will then decrypt it with the key stored in the entry. If the resulting decrypted + * challenge matches the randomly generated number, then we can safely assume that both key are interchangeable. + * This method cannot guarantee a perfect match since the probability of two keys generating the same output in AES128 is + * not 0 but 1/2^128 which is small enough for our purposes. + * + * @param keyData + * @return bool True if the key is equivalent to the one stored, otherwise false + */ + bool IsKeyEquivalent(ByteSpan keyData); + + chip::FabricIndex fabricIndex = kUndefinedFabricIndex; + chip::NodeId checkInNodeID = kUndefinedNodeId; + uint64_t monitoredSubject = static_cast(0); + Crypto::Aes128KeyHandle key = Crypto::Aes128KeyHandle(); + uint16_t index = 0; + Crypto::SymmetricKeystore * symmetricKeystore = nullptr; }; /** @@ -64,8 +101,10 @@ struct ICDMonitoringEntry : public PersistentData struct ICDMonitoringTable { - ICDMonitoringTable(PersistentStorageDelegate & storage, FabricIndex fabric, uint16_t limit) : - mStorage(&storage), mFabric(fabric), mLimit(limit) + ICDMonitoringTable(PersistentStorageDelegate & storage, FabricIndex fabric, uint16_t limit, + Crypto::SymmetricKeystore * symmetricKeystore) : + mStorage(&storage), + mFabric(fabric), mLimit(limit), mSymmetricKeystore(symmetricKeystore) {} /** @@ -124,7 +163,8 @@ struct ICDMonitoringTable private: PersistentStorageDelegate * mStorage; FabricIndex mFabric; - uint16_t mLimit = 0; + uint16_t mLimit = 0; + Crypto::SymmetricKeystore * mSymmetricKeystore = nullptr; }; } // namespace chip diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index cdeb7672491730..20846078baa64a 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -257,7 +257,7 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) // ICD Init needs to be after data model init #if CHIP_CONFIG_ENABLE_ICD_SERVER - mICDManager.Init(mDeviceStorage, &GetFabricTable(), mReportScheduler); + mICDManager.Init(mDeviceStorage, &GetFabricTable(), mReportScheduler, mSessionKeystore); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER #if defined(CHIP_APP_USE_ECHO) diff --git a/src/app/tests/TestICDManager.cpp b/src/app/tests/TestICDManager.cpp index 76c8cd345cb0c4..960059040ae75c 100644 --- a/src/app/tests/TestICDManager.cpp +++ b/src/app/tests/TestICDManager.cpp @@ -28,10 +28,14 @@ #include #include +#include + using namespace chip; using namespace chip::app; using namespace chip::System; +using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore; + namespace { class TestICDStateObserver : public app::ICDStateObserver @@ -63,8 +67,8 @@ class TestContext : public Test::AppContext { return FAILURE; } - - ctx->mICDManager.Init(&ctx->testStorage, &ctx->GetFabricTable(), &mICDStateObserver); + TestSessionKeystoreImpl keystore; + ctx->mICDManager.Init(&ctx->testStorage, &ctx->GetFabricTable(), &mICDStateObserver, &keystore); return SUCCESS; } diff --git a/src/app/tests/TestICDMonitoringTable.cpp b/src/app/tests/TestICDMonitoringTable.cpp index 4aca4ff4e1d7c6..867592f4fa2f9a 100644 --- a/src/app/tests/TestICDMonitoringTable.cpp +++ b/src/app/tests/TestICDMonitoringTable.cpp @@ -16,14 +16,19 @@ */ #include +#include #include #include #include #include #include +#include + using namespace chip; +using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore; + namespace { constexpr uint16_t kMaxTestClients1 = 2; @@ -58,33 +63,54 @@ constexpr uint8_t kKeyBuffer3a[] = { // constexpr uint8_t kKeyBuffer3b[] = { 0xf3, 0xe3, 0xd3, 0xc3, 0xb3, 0xa3, 0x93, 0x83, 0x73, 0x63, 0x53, 0x14, 0x33, 0x23, 0x13, // 0x03 }; +void TestEntryKeyFunctions(nlTestSuite * aSuite, void * aContext) +{ + TestSessionKeystoreImpl keystore; + ICDMonitoringEntry entry(&keystore); + + // Test Setting Key + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a))); + + // Test Setting Key again + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1b))); + + // Test Comparing Key + NL_TEST_ASSERT(aSuite, !entry.IsKeyEquivalent(ByteSpan(kKeyBuffer1a))); + + NL_TEST_ASSERT(aSuite, entry.IsKeyEquivalent(ByteSpan(kKeyBuffer1b))); + + // Test Deleting Key + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.DeleteKey()); +} + void TestSaveAndLoadRegistrationValue(nlTestSuite * aSuite, void * aContext) { TestPersistentStorageDelegate storage; - ICDMonitoringTable saving(storage, kTestFabricIndex1, kMaxTestClients1); - ICDMonitoringTable loading(storage, kTestFabricIndex1, kMaxTestClients1); - ICDMonitoringEntry entry; + TestSessionKeystoreImpl keystore; + ICDMonitoringTable saving(storage, kTestFabricIndex1, kMaxTestClients1, &keystore); + ICDMonitoringTable loading(storage, kTestFabricIndex1, kMaxTestClients1, &keystore); + ICDMonitoringEntry entry(&keystore); CHIP_ERROR err; // Insert first entry entry.checkInNodeID = kClientNodeId11; entry.monitoredSubject = kClientNodeId12; - entry.key = ByteSpan(kKeyBuffer1a); - err = saving.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a))); + err = saving.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Insert second entry entry.checkInNodeID = kClientNodeId12; entry.monitoredSubject = kClientNodeId11; - entry.key = ByteSpan(kKeyBuffer2a); - err = saving.Set(1, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer2a))); + err = saving.Set(1, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Insert one too many entry.checkInNodeID = kClientNodeId13; entry.monitoredSubject = kClientNodeId13; - entry.key = ByteSpan(kKeyBuffer3a); - err = saving.Set(2, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer3a))); + err = saving.Set(2, entry); NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == err); // Retrieve first entry @@ -93,8 +119,11 @@ void TestSaveAndLoadRegistrationValue(nlTestSuite * aSuite, void * aContext) NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer1a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer1a, entry.key.size())); + +// Cannot compare nor retrieve Data if using PSA crypto +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer1a, sizeof(kKeyBuffer1a))); +#endif // Retrieve second entry err = loading.Get(1, entry); @@ -102,8 +131,11 @@ void TestSaveAndLoadRegistrationValue(nlTestSuite * aSuite, void * aContext) NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer2a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer2a, entry.key.size())); + +// Cannot compare nor retrieve Data if using PSA crypto +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer2a, sizeof(kKeyBuffer2a))); +#endif // No more entries err = loading.Get(2, entry); @@ -113,8 +145,8 @@ void TestSaveAndLoadRegistrationValue(nlTestSuite * aSuite, void * aContext) // Overwrite first entry entry.checkInNodeID = kClientNodeId13; entry.monitoredSubject = kClientNodeId11; - entry.key = ByteSpan(kKeyBuffer1b); - err = saving.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1b))); + err = saving.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Retrieve first entry (modified) @@ -123,8 +155,11 @@ void TestSaveAndLoadRegistrationValue(nlTestSuite * aSuite, void * aContext) NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId13 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer1b) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer1b, entry.key.size())); + +// Cannot compare nor retrieve Data if using PSA crypto +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer1b, sizeof(kKeyBuffer1b))); +#endif // Retrieve second entry (not modified) err = loading.Get(1, entry); @@ -132,87 +167,88 @@ void TestSaveAndLoadRegistrationValue(nlTestSuite * aSuite, void * aContext) NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer2a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer2a, entry.key.size())); + +// Cannot compare nor retrieve Data if using PSA crypto +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer2a, sizeof(kKeyBuffer2a))); +#endif } void TestSaveAllInvalidRegistrationValues(nlTestSuite * aSuite, void * aContext) { TestPersistentStorageDelegate storage; - ICDMonitoringTable table(storage, kTestFabricIndex1, kMaxTestClients1); - ICDMonitoringEntry entry; + TestSessionKeystoreImpl keystore; + ICDMonitoringTable table(storage, kTestFabricIndex1, kMaxTestClients1, &keystore); + ICDMonitoringEntry entry(&keystore); CHIP_ERROR err; // Invalid checkInNodeID entry.checkInNodeID = kUndefinedNodeId; entry.monitoredSubject = kClientNodeId12; - entry.key = ByteSpan(kKeyBuffer1a); - err = table.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a))); + err = table.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == err); // Invalid monitoredSubject entry.checkInNodeID = kClientNodeId11; entry.monitoredSubject = kUndefinedNodeId; - entry.key = ByteSpan(kKeyBuffer1a); - err = table.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a))); + err = table.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == err); // Invalid key (empty) entry.checkInNodeID = kClientNodeId11; entry.monitoredSubject = kClientNodeId12; - entry.key = ByteSpan(); - err = table.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == entry.SetKey(ByteSpan())); + err = table.Set(0, entry); - NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == err); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Invalid key (too short) entry.checkInNodeID = kClientNodeId11; entry.monitoredSubject = kClientNodeId12; - entry.key = ByteSpan(kKeyBuffer0a); - err = table.Set(0, entry); - NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == err); + NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == entry.SetKey(ByteSpan(kKeyBuffer0a))); // Invalid key (too long) entry.checkInNodeID = kClientNodeId11; entry.monitoredSubject = kClientNodeId12; - entry.key = ByteSpan(kKeyBuffer0b); - err = table.Set(0, entry); - NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == err); + NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == entry.SetKey(ByteSpan(kKeyBuffer0b))); } void TestSaveLoadRegistrationValueForMultipleFabrics(nlTestSuite * aSuite, void * aContext) { TestPersistentStorageDelegate storage; - ICDMonitoringTable table1(storage, kTestFabricIndex1, kMaxTestClients1); - ICDMonitoringTable table2(storage, kTestFabricIndex2, kMaxTestClients2); - ICDMonitoringEntry entry; + TestSessionKeystoreImpl keystore; + ICDMonitoringTable table1(storage, kTestFabricIndex1, kMaxTestClients1, &keystore); + ICDMonitoringTable table2(storage, kTestFabricIndex2, kMaxTestClients2, &keystore); + ICDMonitoringEntry entry(&keystore); CHIP_ERROR err; // Insert in first fabric entry.checkInNodeID = kClientNodeId11; entry.monitoredSubject = kClientNodeId12; - entry.key = ByteSpan(kKeyBuffer1a); - err = table1.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a))); + err = table1.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Insert in first fabric entry.checkInNodeID = kClientNodeId12; entry.monitoredSubject = kClientNodeId11; - entry.key = ByteSpan(kKeyBuffer1b); - err = table1.Set(1, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1b))); + err = table1.Set(1, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Insert in second fabric entry.checkInNodeID = kClientNodeId21; entry.monitoredSubject = kClientNodeId22; - entry.key = ByteSpan(kKeyBuffer2a); - err = table2.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer2a))); + err = table2.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Insert in second fabric (one too many) entry.checkInNodeID = kClientNodeId22; entry.monitoredSubject = kClientNodeId21; - entry.key = ByteSpan(kKeyBuffer2b); - err = table2.Set(1, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer2b))); + err = table2.Set(1, entry); NL_TEST_ASSERT(aSuite, CHIP_ERROR_INVALID_ARGUMENT == err); // Retrieve fabric1, first entry @@ -221,8 +257,10 @@ void TestSaveLoadRegistrationValueForMultipleFabrics(nlTestSuite * aSuite, void NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer1a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer1a, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer1a, sizeof(kKeyBuffer1a))); +#endif // Retrieve fabric2, second entry err = table1.Get(1, entry); @@ -230,8 +268,10 @@ void TestSaveLoadRegistrationValueForMultipleFabrics(nlTestSuite * aSuite, void NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer1b) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer1b, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer1b, sizeof(kKeyBuffer1b))); +#endif // Retrieve fabric2, first entry err = table2.Get(0, entry); @@ -239,37 +279,40 @@ void TestSaveLoadRegistrationValueForMultipleFabrics(nlTestSuite * aSuite, void NL_TEST_ASSERT(aSuite, kTestFabricIndex2 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId21 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId22 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer2a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer2a, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer2a, sizeof(kKeyBuffer2a))); +#endif } void TestDeleteValidEntryFromStorage(nlTestSuite * aSuite, void * context) { TestPersistentStorageDelegate storage; - ICDMonitoringTable table1(storage, kTestFabricIndex1, kMaxTestClients1); - ICDMonitoringTable table2(storage, kTestFabricIndex2, kMaxTestClients2); - ICDMonitoringEntry entry; + TestSessionKeystoreImpl keystore; + ICDMonitoringTable table1(storage, kTestFabricIndex1, kMaxTestClients1, &keystore); + ICDMonitoringTable table2(storage, kTestFabricIndex2, kMaxTestClients2, &keystore); + ICDMonitoringEntry entry(&keystore); CHIP_ERROR err; // Insert first entry entry.checkInNodeID = kClientNodeId11; entry.monitoredSubject = kClientNodeId12; - entry.key = ByteSpan(kKeyBuffer1a); - err = table1.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer1a))); + err = table1.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Insert second entry entry.checkInNodeID = kClientNodeId12; entry.monitoredSubject = kClientNodeId11; - entry.key = ByteSpan(kKeyBuffer2a); - err = table1.Set(1, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer2a))); + err = table1.Set(1, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Insert in second fabric entry.checkInNodeID = kClientNodeId21; entry.monitoredSubject = kClientNodeId22; - entry.key = ByteSpan(kKeyBuffer2a); - err = table2.Set(0, entry); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.SetKey(ByteSpan(kKeyBuffer2a))); + err = table2.Set(0, entry); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == err); // Remove (invalid) @@ -282,8 +325,10 @@ void TestDeleteValidEntryFromStorage(nlTestSuite * aSuite, void * context) NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer1a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer1a, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer1a, sizeof(kKeyBuffer1a))); +#endif // Retrieve second entry (not modified) err = table1.Get(1, entry); @@ -291,8 +336,10 @@ void TestDeleteValidEntryFromStorage(nlTestSuite * aSuite, void * context) NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer2a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer2a, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer2a, sizeof(kKeyBuffer2a))); +#endif // Remove (existing) err = table1.Remove(0); @@ -307,8 +354,10 @@ void TestDeleteValidEntryFromStorage(nlTestSuite * aSuite, void * context) NL_TEST_ASSERT(aSuite, kTestFabricIndex1 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId12 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId11 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer2a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer2a, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer2a, sizeof(kKeyBuffer2a))); +#endif // Retrieve fabric2, first entry err = table2.Get(0, entry); @@ -316,8 +365,10 @@ void TestDeleteValidEntryFromStorage(nlTestSuite * aSuite, void * context) NL_TEST_ASSERT(aSuite, kTestFabricIndex2 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId21 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId22 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer2a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer2a, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer2a, sizeof(kKeyBuffer2a))); +#endif // Remove all (fabric 1) err = table1.RemoveAll(); @@ -332,8 +383,10 @@ void TestDeleteValidEntryFromStorage(nlTestSuite * aSuite, void * context) NL_TEST_ASSERT(aSuite, kTestFabricIndex2 == entry.fabricIndex); NL_TEST_ASSERT(aSuite, kClientNodeId21 == entry.checkInNodeID); NL_TEST_ASSERT(aSuite, kClientNodeId22 == entry.monitoredSubject); - NL_TEST_ASSERT(aSuite, sizeof(kKeyBuffer2a) == entry.key.size()); - NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.data(), kKeyBuffer2a, entry.key.size())); + +#if !CHIP_CRYPTO_PSA + NL_TEST_ASSERT(aSuite, 0 == memcmp(entry.key.As(), kKeyBuffer2a, sizeof(kKeyBuffer2a))); +#endif // Remove all (fabric 2) err = table2.RemoveAll(); @@ -350,18 +403,18 @@ void TestDeleteValidEntryFromStorage(nlTestSuite * aSuite, void * context) */ int Test_Setup(void * inContext) { - return SUCCESS; } int TestClientMonitoringRegistrationTable() { - static nlTest sTests[] = { - NL_TEST_DEF("TestSaveAndLoadRegistrationValue", TestSaveAndLoadRegistrationValue), - NL_TEST_DEF("TestSaveAllInvalidRegistrationValues", TestSaveAllInvalidRegistrationValues), - NL_TEST_DEF("TestSaveLoadRegistrationValueForMultipleFabrics", TestSaveLoadRegistrationValueForMultipleFabrics), - NL_TEST_DEF("TestDeleteValidEntryFromStorage", TestDeleteValidEntryFromStorage), NL_TEST_SENTINEL() - }; + static nlTest sTests[] = { NL_TEST_DEF("TestEntryKeyFunctions", TestEntryKeyFunctions), + NL_TEST_DEF("TestSaveAndLoadRegistrationValue", TestSaveAndLoadRegistrationValue), + NL_TEST_DEF("TestSaveAllInvalidRegistrationValues", TestSaveAllInvalidRegistrationValues), + NL_TEST_DEF("TestSaveLoadRegistrationValueForMultipleFabrics", + TestSaveLoadRegistrationValueForMultipleFabrics), + NL_TEST_DEF("TestDeleteValidEntryFromStorage", TestDeleteValidEntryFromStorage), + NL_TEST_SENTINEL() }; nlTestSuite cmSuite = { "TestClientMonitoringRegistrationTable", &sTests[0], &Test_Setup, nullptr }; diff --git a/src/app/tests/suites/TestIcdManagementCluster.yaml b/src/app/tests/suites/TestIcdManagementCluster.yaml index 3b62c6837bb9c2..d04facefdadeb4 100644 --- a/src/app/tests/suites/TestIcdManagementCluster.yaml +++ b/src/app/tests/suites/TestIcdManagementCluster.yaml @@ -171,7 +171,7 @@ tests: { CheckInNodeID: 201, MonitoredSubject: 2001 }, ] - - label: "Register 1.1" + - label: "Register 1.1 (update)" command: "RegisterClient" arguments: values: diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index 88da0ea3ab8aaa..33fdf67d4a080f 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -40744,8 +40744,8 @@ class TestIcdManagementCluster : public TestCommandBridge { err = TestReadRegisteredClients_15(); break; case 16: - ChipLogProgress(chipTool, " ***** Test Step 16 : Register 1.1\n"); - err = TestRegister11_16(); + ChipLogProgress(chipTool, " ***** Test Step 16 : Register 1.1 (update)\n"); + err = TestRegister11Update_16(); break; case 17: ChipLogProgress(chipTool, " ***** Test Step 17 : Read RegisteredClients\n"); @@ -41266,7 +41266,7 @@ class TestIcdManagementCluster : public TestCommandBridge { return CHIP_NO_ERROR; } - CHIP_ERROR TestRegister11_16() + CHIP_ERROR TestRegister11Update_16() { MTRBaseDevice * device = GetDevice("alpha"); @@ -41282,7 +41282,7 @@ class TestIcdManagementCluster : public TestCommandBridge { [[NSData alloc] initWithBytes:"\001\021!1AQaq\201\221\241\261\301\321\341\361" length:16]; [cluster registerClientWithParams:params completion: ^(MTRICDManagementClusterRegisterClientResponseParams * _Nullable values, NSError * _Nullable err) { - NSLog(@"Register 1.1 Error: %@", err); + NSLog(@"Register 1.1 (update) Error: %@", err); VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0));