Skip to content

Commit

Permalink
Add key challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
jepenven-silabs committed Oct 6, 2023
1 parent a48805d commit 4b1a171
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ CHIP_ERROR IcdManagementAttributeAccess::ReadRegisteredClients(EndpointId endpoi
return encoder.EncodeList([supported_clients](const auto & subEncoder) -> CHIP_ERROR {
IcdMonitoringEntry e(chip::Server::GetInstance().GetSessionKeystore());

const auto & fabricTable = Server::GetInstance().GetFabricTable();
uint8_t empty_key[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES] = { 0 };
const auto & fabricTable = Server::GetInstance().GetFabricTable();
for (const auto & fabricInfo : fabricTable)
{
PersistentStorageDelegate & storage = chip::Server::GetInstance().GetPersistentStorage();
Expand Down
9 changes: 4 additions & 5 deletions src/app/icd/IcdManagementServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Status IcdManagementServer::RegisterClient(PersistentStorageDelegate & storage,
if (!is_admin)
{
VerifyOrReturnError(verification_key.HasValue(), InteractionModel::Status::Failure);
// TODO Specs issue #7519
// VerifyOrReturnError(verification_key.Value().data_equal(entry.key()), InteractionModel::Status::Failure);
VerifyOrReturnError(entry.IsKeyCompatible(verification_key.Value()) == CHIP_NO_ERROR,
InteractionModel::Status::Failure);
}
}
else if (CHIP_ERROR_NOT_FOUND == err)
Expand All @@ -41,7 +41,7 @@ Status IcdManagementServer::RegisterClient(PersistentStorageDelegate & storage,
// Save
entry.checkInNodeID = node_id;
entry.monitoredSubject = monitored_subject;
err = entry.SetKey(key);
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);
Expand Down Expand Up @@ -73,8 +73,7 @@ Status IcdManagementServer::UnregisterClient(PersistentStorageDelegate & storage
if (!is_admin)
{
VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure);
// TODO Specs issue #7519
// VerifyOrReturnError(verificationKey.Value().data_equal(entry.key), InteractionModel::Status::Failure);
VerifyOrReturnError(entry.IsKeyCompatible(verificationKey.Value()) == CHIP_NO_ERROR, InteractionModel::Status::Failure);
}

err = table.Remove(entry.index);
Expand Down
39 changes: 39 additions & 0 deletions src/app/icd/IcdMonitoringTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "IcdMonitoringTable.h"

#include <crypto/RandUtils.h>

namespace chip {

enum class Fields : uint8_t
Expand Down Expand Up @@ -98,6 +100,10 @@ CHIP_ERROR IcdMonitoringEntry::SetKey(chip::ByteSpan keyData)
{
VerifyOrReturnError(keyData.size() == chip::Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(sessionKeyStore != nullptr, CHIP_ERROR_INTERNAL);

// DeleteKey in case the handle was already used.
DeleteKey();

Crypto::Aes128KeyByteArray keyMaterial;
memcpy(keyMaterial, keyData.data(), keyData.size());

Expand All @@ -113,6 +119,39 @@ CHIP_ERROR IcdMonitoringEntry::DeleteKey()
return CHIP_NO_ERROR;
}

CHIP_ERROR IcdMonitoringEntry::IsKeyCompatible(chip::ByteSpan keyData)
{
VerifyOrReturnError(keyData.size() == chip::Crypto::CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(sessionKeyStore != nullptr, CHIP_ERROR_INTERNAL);
Crypto::Aes128KeyByteArray keyMaterial;
Crypto::Aes128KeyHandle tempKey;
memcpy(keyMaterial, keyData.data(), keyData.size());

ReturnErrorOnFailure(sessionKeyStore->CreateKey(keyMaterial, tempKey));

// Challenge
uint8_t mic[chip::Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES] = { 0 };
uint8_t aead[chip::Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES] = { 0 };

CHIP_ERROR err;

uint64_t data = chip::Crypto::GetRandU64(), validation, encrypted;
validation = data;

err = Crypto::AES_CCM_encrypt((uint8_t *) (&data), sizeof(data), nullptr, 0, tempKey, aead,
chip::Crypto::CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, (uint8_t *) &encrypted, mic,
chip::Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES);

data = 0;
err = Crypto::AES_CCM_decrypt((uint8_t *) &encrypted, sizeof(encrypted), nullptr, 0, mic,
chip::Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, key, aead,
chip::Crypto::CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES, (uint8_t *) &data);

sessionKeyStore->DestroyKey(tempKey);

return (data == validation) ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
}

CHIP_ERROR IcdMonitoringTable::Get(uint16_t index, IcdMonitoringEntry & entry) const
{
entry.fabricIndex = this->mFabric;
Expand Down
1 change: 1 addition & 0 deletions src/app/icd/IcdMonitoringTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct IcdMonitoringEntry : public PersistentData<kIcdMonitoringBufferSize>
void Clear() override;
CHIP_ERROR SetKey(chip::ByteSpan keyData);
CHIP_ERROR DeleteKey(void);
CHIP_ERROR IsKeyCompatible(chip::ByteSpan keyData);

chip::FabricIndex fabricIndex = static_cast<chip::FabricIndex>(0);
chip::NodeId checkInNodeID = static_cast<chip::NodeId>(0);
Expand Down
33 changes: 27 additions & 6 deletions src/app/tests/TestIcdMonitoringTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ 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, CHIP_NO_ERROR != entry.IsKeyCompatible(ByteSpan(kKeyBuffer1a)));

NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.IsKeyCompatible(ByteSpan(kKeyBuffer1b)));

// Test Deleting Key
NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == entry.DeleteKey());
}

void TestSaveAndLoadRegistrationValue(nlTestSuite * aSuite, void * aContext)
{
TestPersistentStorageDelegate storage;
Expand Down Expand Up @@ -388,12 +408,13 @@ int Test_Setup(void * inContext)

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 };

Expand Down

0 comments on commit 4b1a171

Please sign in to comment.