Skip to content

Commit

Permalink
Merge branch 'master' into feature/electrical_energy_measurement
Browse files Browse the repository at this point in the history
  • Loading branch information
andreilitvin committed Dec 8, 2023
2 parents 2121ea2 + ba8ab24 commit 8c132a2
Show file tree
Hide file tree
Showing 25 changed files with 379 additions and 281 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ cluster OnOff = 6 {
}

/** Attributes and commands for configuring On/Off switching devices. */
cluster OnOffSwitchConfiguration = 7 {
deprecated cluster OnOffSwitchConfiguration = 7 {
revision 1; // NOTE: Default/not specifically set

readonly attribute enum8 switchType = 0;
Expand Down Expand Up @@ -605,7 +605,7 @@ cluster LevelControl = 8 {
}

/** An interface for reading the value of a binary measurement and accessing various characteristics of that measurement. */
cluster BinaryInputBasic = 15 {
deprecated cluster BinaryInputBasic = 15 {
revision 1; // NOTE: Default/not specifically set

attribute optional char_string<16> activeText = 4;
Expand Down Expand Up @@ -3871,7 +3871,7 @@ cluster WindowCovering = 258 {
}

/** This cluster provides control of a barrier (garage door). */
cluster BarrierControl = 259 {
deprecated cluster BarrierControl = 259 {
revision 1; // NOTE: Default/not specifically set

bitmap BarrierControlCapabilities : bitmap8 {
Expand Down Expand Up @@ -5494,7 +5494,7 @@ cluster LowPower = 1288 {
}

/** Attributes related to the electrical properties of a device. This cluster is used by power outlets and other devices that need to provide instantaneous data as opposed to metrology data which should be retrieved from the metering cluster.. */
cluster ElectricalMeasurement = 2820 {
deprecated cluster ElectricalMeasurement = 2820 {
revision 3;

readonly attribute optional bitmap32 measurementType = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ cluster LevelControl = 8 {
}

/** An interface for reading the value of a binary measurement and accessing various characteristics of that measurement. */
cluster BinaryInputBasic = 15 {
deprecated cluster BinaryInputBasic = 15 {
revision 1; // NOTE: Default/not specifically set

attribute optional char_string<16> activeText = 4;
Expand Down
6 changes: 3 additions & 3 deletions src/app/icd/ICDCheckInSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ CHIP_ERROR ICDCheckInSender::SendCheckInMsg(const Transport::PeerAddress & addr)
VerifyOrReturnError(!buffer.IsNull(), CHIP_ERROR_NO_MEMORY);
MutableByteSpan output{ buffer->Start(), buffer->MaxDataLength() };

ReturnErrorOnFailure(CheckinMessage::GenerateCheckinMessagePayload(mKey, mICDCounter, ByteSpan(), output));
ReturnErrorOnFailure(CheckinMessage::GenerateCheckinMessagePayload(mAesKeyHandle, mICDCounter, ByteSpan(), output));
buffer->SetDataLength(static_cast<uint16_t>(output.size()));

VerifyOrReturnError(mExchangeManager->GetSessionManager() != nullptr, CHIP_ERROR_INTERNAL);
Expand Down Expand Up @@ -89,8 +89,8 @@ CHIP_ERROR ICDCheckInSender::RequestResolve(ICDMonitoringEntry & entry, FabricTa

AddressResolve::NodeLookupRequest request(peerId);

memcpy(mKey.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), entry.key.As<Crypto::Symmetric128BitsKeyByteArray>(),
sizeof(Crypto::Symmetric128BitsKeyByteArray));
memcpy(mAesKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(),
entry.aesKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(), sizeof(Crypto::Symmetric128BitsKeyByteArray));

CHIP_ERROR err = AddressResolve::Resolver::Instance().LookupNode(request, mAddressLookupHandle);

Expand Down
2 changes: 1 addition & 1 deletion src/app/icd/ICDCheckInSender.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class ICDCheckInSender : public AddressResolve::NodeListener

Messaging::ExchangeManager * mExchangeManager = nullptr;

Crypto::Aes128KeyHandle mKey = Crypto::Aes128KeyHandle();
Crypto::Aes128KeyHandle mAesKeyHandle = Crypto::Aes128KeyHandle();

uint32_t mICDCounter = 0;
};
Expand Down
84 changes: 65 additions & 19 deletions src/app/icd/ICDMonitoringTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ enum class Fields : uint8_t
{
kCheckInNodeID = 1,
kMonitoredSubject = 2,
kKey = 3,
kAesKeyHandle = 3,
kHmacKeyHandle = 4,
};

CHIP_ERROR ICDMonitoringEntry::UpdateKey(StorageKeyName & skey)
Expand All @@ -42,8 +43,12 @@ CHIP_ERROR ICDMonitoringEntry::Serialize(TLV::TLVWriter & writer) const
ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kCheckInNodeID), checkInNodeID));
ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kMonitoredSubject), monitoredSubject));

ByteSpan buf(key.As<Crypto::Symmetric128BitsKeyByteArray>());
ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kKey), buf));
ByteSpan aesKeybuf(aesKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>());
ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kAesKeyHandle), aesKeybuf));

ByteSpan hmacKeybuf(hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>());
ReturnErrorOnFailure(writer.Put(TLV::ContextTag(Fields::kHmacKeyHandle), hmacKeybuf));

ReturnErrorOnFailure(writer.EndContainer(outer));
return CHIP_NO_ERROR;
}
Expand All @@ -69,18 +74,38 @@ CHIP_ERROR ICDMonitoringEntry::Deserialize(TLV::TLVReader & reader)
case to_underlying(Fields::kMonitoredSubject):
ReturnErrorOnFailure(reader.Get(monitoredSubject));
break;
case to_underlying(Fields::kKey): {
ByteSpan buf(key.AsMutable<Crypto::Symmetric128BitsKeyByteArray>());
case to_underlying(Fields::kAesKeyHandle): {
ByteSpan buf;
ReturnErrorOnFailure(reader.Get(buf));
// Since we are storing either the raw key or a key ID, we must
// simply copy the data as is in the keyHandle.
// Calling SetKey here would create another key in storage and will cause
// key leakage in some implementation.
memcpy(key.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), buf.data(),
// Calling SetKey here would create another keyHandle in storage and will cause
// key leaks in some implementations.
memcpy(aesKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), buf.data(),
sizeof(Crypto::Symmetric128BitsKeyByteArray));
keyHandleValid = true;
}
break;
case to_underlying(Fields::kHmacKeyHandle): {
ByteSpan buf;
CHIP_ERROR error = reader.Get(buf);

if (error != CHIP_NO_ERROR)
{
// If retreiving the hmac key handle failed, we need to set an invalid key handle
// even if the AesKeyHandle is valid.
keyHandleValid = false;
return error;
}

// Since we are storing either the raw key or a key ID, we must
// simply copy the data as is in the keyHandle.
// Calling SetKey here would create another keyHandle in storage and will cause
// key leaks in some implementations.
memcpy(hmacKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), buf.data(),
sizeof(Crypto::Symmetric128BitsKeyByteArray));
}
break;
default:
break;
}
Expand Down Expand Up @@ -108,16 +133,29 @@ CHIP_ERROR ICDMonitoringEntry::SetKey(ByteSpan keyData)
Crypto::Symmetric128BitsKeyByteArray keyMaterial;
memcpy(keyMaterial, keyData.data(), sizeof(Crypto::Symmetric128BitsKeyByteArray));

ReturnErrorOnFailure(symmetricKeystore->CreateKey(keyMaterial, key));
keyHandleValid = true;
// TODO - Add function to set PSA key lifetime
ReturnErrorOnFailure(symmetricKeystore->CreateKey(keyMaterial, aesKeyHandle));
CHIP_ERROR error = symmetricKeystore->CreateKey(keyMaterial, hmacKeyHandle);

return CHIP_NO_ERROR;
if (error == CHIP_NO_ERROR)
{
// If the creation of the HmacKeyHandle succeeds, both key handles are valid
keyHandleValid = true;
}
else
{
// Creation of the HmacKeyHandle failed, we need to delete the AesKeyHandle to avoid a key leak
symmetricKeystore->DestroyKey(this->aesKeyHandle);
}

return error;
}

CHIP_ERROR ICDMonitoringEntry::DeleteKey()
{
VerifyOrReturnError(symmetricKeystore != nullptr, CHIP_ERROR_INTERNAL);
symmetricKeystore->DestroyKey(this->key);
symmetricKeystore->DestroyKey(this->aesKeyHandle);
symmetricKeystore->DestroyKey(this->hmacKeyHandle);
keyHandleValid = false;
return CHIP_NO_ERROR;
}
Expand All @@ -141,15 +179,15 @@ bool ICDMonitoringEntry::IsKeyEquivalent(ByteSpan keyData)
uint64_t data = Crypto::GetRandU64(), validation, encrypted;
validation = data;

err = Crypto::AES_CCM_encrypt(reinterpret_cast<uint8_t *>(&data), sizeof(data), nullptr, 0, tempEntry.key, aead,
err = Crypto::AES_CCM_encrypt(reinterpret_cast<uint8_t *>(&data), sizeof(data), nullptr, 0, tempEntry.aesKeyHandle, aead,
Crypto::CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, reinterpret_cast<uint8_t *>(&encrypted), mic,
Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES);

data = 0;
if (err == CHIP_NO_ERROR)
{
err = Crypto::AES_CCM_decrypt(reinterpret_cast<uint8_t *>(&encrypted), sizeof(encrypted), nullptr, 0, mic,
Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, key, aead,
Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, aesKeyHandle, aead,
Crypto::CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, reinterpret_cast<uint8_t *>(&data));
}
tempEntry.DeleteKey();
Expand All @@ -175,7 +213,11 @@ ICDMonitoringEntry & ICDMonitoringEntry::operator=(const ICDMonitoringEntry & ic
index = icdMonitoringEntry.index;
keyHandleValid = icdMonitoringEntry.keyHandleValid;
symmetricKeystore = icdMonitoringEntry.symmetricKeystore;
memcpy(key.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), icdMonitoringEntry.key.As<Crypto::Symmetric128BitsKeyByteArray>(),
memcpy(aesKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(),
icdMonitoringEntry.aesKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(),
sizeof(Crypto::Symmetric128BitsKeyByteArray));
memcpy(hmacKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(),
icdMonitoringEntry.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(),
sizeof(Crypto::Symmetric128BitsKeyByteArray));

return *this;
Expand Down Expand Up @@ -211,12 +253,16 @@ CHIP_ERROR ICDMonitoringTable::Set(uint16_t index, const ICDMonitoringEntry & en
VerifyOrReturnError(kUndefinedNodeId != entry.checkInNodeID, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(kUndefinedNodeId != entry.monitoredSubject, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(entry.keyHandleValid, CHIP_ERROR_INVALID_ARGUMENT);

ICDMonitoringEntry e(this->mFabric, index);
e.checkInNodeID = entry.checkInNodeID;
e.monitoredSubject = entry.monitoredSubject;
e.index = index;
memcpy(e.key.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(), entry.key.As<Crypto::Symmetric128BitsKeyByteArray>(),
sizeof(Crypto::Symmetric128BitsKeyByteArray));

memcpy(e.aesKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(),
entry.aesKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(), sizeof(Crypto::Symmetric128BitsKeyByteArray));
memcpy(e.hmacKeyHandle.AsMutable<Crypto::Symmetric128BitsKeyByteArray>(),
entry.hmacKeyHandle.As<Crypto::Symmetric128BitsKeyByteArray>(), sizeof(Crypto::Symmetric128BitsKeyByteArray));

return e.Save(this->mStorage);
}
Expand All @@ -225,8 +271,8 @@ CHIP_ERROR ICDMonitoringTable::Remove(uint16_t index)
{
ICDMonitoringEntry entry(mSymmetricKeystore, this->mFabric);

// Retrieve entry and delete the key first as to not
// cause any key leakage.
// Retrieve entry and delete the keyHandle first as to not
// cause any key leaks.
this->Get(index, entry);
ReturnErrorOnFailure(entry.DeleteKey());

Expand Down
5 changes: 3 additions & 2 deletions src/app/icd/ICDMonitoringTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ using SymmetricKeystore = SessionKeystore;

namespace chip {

inline constexpr size_t kICDMonitoringBufferSize = 40;
inline constexpr size_t kICDMonitoringBufferSize = 60;

struct ICDMonitoringEntry : public PersistentData<kICDMonitoringBufferSize>
{
Expand Down Expand Up @@ -104,7 +104,8 @@ struct ICDMonitoringEntry : public PersistentData<kICDMonitoringBufferSize>
chip::FabricIndex fabricIndex = kUndefinedFabricIndex;
chip::NodeId checkInNodeID = kUndefinedNodeId;
uint64_t monitoredSubject = static_cast<uint64_t>(0);
Crypto::Aes128KeyHandle key = Crypto::Aes128KeyHandle();
Crypto::Aes128KeyHandle aesKeyHandle = Crypto::Aes128KeyHandle();
Crypto::Hmac128KeyHandle hmacKeyHandle = Crypto::Hmac128KeyHandle();
bool keyHandleValid = false;
uint16_t index = 0;
Crypto::SymmetricKeystore * symmetricKeystore = nullptr;
Expand Down
15 changes: 6 additions & 9 deletions src/app/tests/AppTestContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,8 @@ namespace Test {
CHIP_ERROR AppContext::SetUpTestSuite()
{
CHIP_ERROR err = CHIP_NO_ERROR;
VerifyOrExit((err = chip::Platform::MemoryInit()) == CHIP_NO_ERROR,
ChipLogError(AppServer, "Init CHIP memory failed: %" CHIP_ERROR_FORMAT, err.Format()));
VerifyOrExit((err = LoopbackTransportManager::Init()) == CHIP_NO_ERROR,
ChipLogError(AppServer, "Init LoopbackTransportManager failed: %" CHIP_ERROR_FORMAT, err.Format()));
VerifyOrExit((err = LoopbackMessagingContext::SetUpTestSuite()) == CHIP_NO_ERROR,
ChipLogError(AppServer, "SetUpTestSuite lo messaging context failed: %" CHIP_ERROR_FORMAT, err.Format()));
VerifyOrExit((err = chip::DeviceLayer::PlatformMgr().InitChipStack()) == CHIP_NO_ERROR,
ChipLogError(AppServer, "Init CHIP stack failed: %" CHIP_ERROR_FORMAT, err.Format()));
exit:
Expand All @@ -54,15 +52,14 @@ CHIP_ERROR AppContext::SetUpTestSuite()
void AppContext::TearDownTestSuite()
{
chip::DeviceLayer::PlatformMgr().Shutdown();
LoopbackTransportManager::Shutdown();
chip::Platform::MemoryShutdown();
LoopbackMessagingContext::TearDownTestSuite();
}

CHIP_ERROR AppContext::SetUp()
{
CHIP_ERROR err = CHIP_NO_ERROR;
VerifyOrExit((err = MessagingContext::Init(&GetTransportMgr(), &GetIOContext())) == CHIP_NO_ERROR,
ChipLogError(AppServer, "Init MessagingContext failed: %" CHIP_ERROR_FORMAT, err.Format()));
VerifyOrExit((err = LoopbackMessagingContext::SetUp()) == CHIP_NO_ERROR,
ChipLogError(AppServer, "SetUp lo messaging context failed: %" CHIP_ERROR_FORMAT, err.Format()));
VerifyOrExit((err = app::InteractionModelEngine::GetInstance()->Init(
&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler())) == CHIP_NO_ERROR,
ChipLogError(AppServer, "Init InteractionModelEngine failed: %" CHIP_ERROR_FORMAT, err.Format()));
Expand All @@ -79,7 +76,7 @@ void AppContext::TearDown()
Access::GetAccessControl().Finish();
Access::ResetAccessControlToDefault();
chip::app::InteractionModelEngine::GetInstance()->Shutdown();
MessagingContext::Shutdown();
LoopbackMessagingContext::TearDown();
}

} // namespace Test
Expand Down
34 changes: 4 additions & 30 deletions src/app/tests/AppTestContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,39 +28,13 @@ class AppContext : public LoopbackMessagingContext
{
public:
// Performs shared setup for all tests in the test suite
virtual CHIP_ERROR SetUpTestSuite();
CHIP_ERROR SetUpTestSuite() override;
// Performs shared teardown for all tests in the test suite
virtual void TearDownTestSuite();
void TearDownTestSuite() override;
// Performs setup for each individual test in the test suite
virtual CHIP_ERROR SetUp();
CHIP_ERROR SetUp() override;
// Performs teardown for each individual test in the test suite
virtual void TearDown();

// Helpers that can be used directly by the nlTestSuite

static int nlTestSetUpTestSuite(void * context)
{
auto err = static_cast<AppContext *>(context)->SetUpTestSuite();
return err == CHIP_NO_ERROR ? SUCCESS : FAILURE;
}

static int nlTestTearDownTestSuite(void * context)
{
static_cast<AppContext *>(context)->TearDownTestSuite();
return SUCCESS;
}

static int nlTestSetUp(void * context)
{
auto err = static_cast<AppContext *>(context)->SetUp();
return err == CHIP_NO_ERROR ? SUCCESS : FAILURE;
}

static int nlTestTearDown(void * context)
{
static_cast<AppContext *>(context)->TearDown();
return SUCCESS;
}
void TearDown() override;
};

} // namespace Test
Expand Down
Loading

0 comments on commit 8c132a2

Please sign in to comment.