From 069d521beebeee842eedc9688b44c905128dc21b Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Wed, 26 Jun 2024 11:57:55 -0400 Subject: [PATCH 1/6] Add support factory and commissionable data provisioning with the use of librairies --- examples/platform/silabs/BaseApplication.cpp | 13 +- examples/platform/silabs/MatterConfig.cpp | 16 +- examples/platform/silabs/SiWx917/BUILD.gn | 54 +- .../silabs/SilabsTestEventTriggerDelegate.cpp | 4 +- examples/platform/silabs/efr32/BUILD.gn | 56 +- .../provision/ProvisionStorageCustom.cpp | 129 ++++ .../provision/ProvisionStorageDefault.cpp | 731 ++++++++++++++++++ .../provision/ProvisionStorageFlash.cpp | 724 +++++++++++++++++ examples/platform/silabs/silabs_creds.h | 58 +- src/platform/silabs/efr32/BLEManagerImpl.cpp | 15 +- src/platform/silabs/efr32/BUILD.gn | 6 +- .../silabs/platformAbstraction/GsdkSpam.cpp | 14 +- .../platformAbstraction/SilabsPlatform.h | 2 + .../platformAbstraction/SilabsPlatformBase.h | 1 + .../platformAbstraction/WiseMcuSpam.cpp | 6 + .../silabs/provision/AttestationKey.h | 51 ++ src/platform/silabs/provision/BUILD.gn | 38 + .../silabs/provision/ProvisionChannel.h | 44 ++ .../silabs/provision/ProvisionEncoder.h | 191 +++++ .../silabs/provision/ProvisionManager.h | 61 ++ .../silabs/provision/ProvisionProtocol.h | 107 +++ .../silabs/provision/ProvisionStorage.h | 298 +++++++ .../provision/ProvisionStorageGeneric.h | 47 ++ src/test_driver/efr32/BUILD.gn | 15 +- src/test_driver/efr32/src/main.cpp | 19 +- third_party/silabs/SiWx917_sdk.gni | 11 +- third_party/silabs/matter_support | 2 +- 27 files changed, 2548 insertions(+), 165 deletions(-) create mode 100644 examples/platform/silabs/provision/ProvisionStorageCustom.cpp create mode 100644 examples/platform/silabs/provision/ProvisionStorageDefault.cpp create mode 100644 examples/platform/silabs/provision/ProvisionStorageFlash.cpp create mode 100644 src/platform/silabs/provision/AttestationKey.h create mode 100644 src/platform/silabs/provision/BUILD.gn create mode 100644 src/platform/silabs/provision/ProvisionChannel.h create mode 100644 src/platform/silabs/provision/ProvisionEncoder.h create mode 100644 src/platform/silabs/provision/ProvisionManager.h create mode 100644 src/platform/silabs/provision/ProvisionProtocol.h create mode 100644 src/platform/silabs/provision/ProvisionStorage.h create mode 100644 src/platform/silabs/provision/ProvisionStorageGeneric.h diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index f02826f1308c32..21150e2fd52d1a 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -24,9 +24,10 @@ #include "AppConfig.h" #include "AppEvent.h" #include "AppTask.h" - #include +#define APP_ACTION_BUTTON 1 + #ifdef DISPLAY_ENABLED #include "lcd.h" #ifdef QR_CODE_ENABLED @@ -34,7 +35,6 @@ #endif // QR_CODE_ENABLED #endif // DISPLAY_ENABLED -#include "SilabsDeviceDataProvider.h" #if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 #include // nogncheck #endif @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -744,6 +745,11 @@ void BaseApplication::DispatchEvent(AppEvent * aEvent) void BaseApplication::ScheduleFactoryReset() { PlatformMgr().ScheduleWork([](intptr_t) { + // Press both buttons to request provisioning + if (GetPlatform().GetButtonState(APP_ACTION_BUTTON)) + { + Provision::Manager::GetInstance().SetProvisionRequired(true); + } PlatformMgr().HandleServerShuttingDown(); ConfigurationMgr().InitiateFactoryReset(); }); @@ -765,7 +771,8 @@ void BaseApplication::OutputQrCode(bool refreshLCD) char setupPayloadBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1]; chip::MutableCharSpan setupPayload(setupPayloadBuffer); - if (Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider().GetSetupPayload(setupPayload) == CHIP_NO_ERROR) + CHIP_ERROR err = Provision::Manager::GetInstance().GetStorage().GetSetupPayload(setupPayload); + if (CHIP_NO_ERROR == err) { // Print setup info on LCD if available #ifdef QR_CODE_ENABLED diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index 0789c12f37aaac..fd1a7954cbe4b9 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -56,9 +56,9 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeystore; #endif -#include "SilabsDeviceDataProvider.h" #include #include +#include #ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED #include "SilabsTestEventTriggerDelegate.h" // nogncheck @@ -80,8 +80,6 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeys #include #include -#include -#include #include @@ -92,7 +90,7 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeys using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; -using namespace ::chip::Credentials::Silabs; +using namespace ::chip::Credentials; using namespace chip::DeviceLayer::Silabs; #if CHIP_ENABLE_OPENTHREAD @@ -174,7 +172,7 @@ void ApplicationStart(void * unused) chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config - SetDeviceAttestationCredentialsProvider(Credentials::Silabs::GetSilabsDacProvider()); + SetDeviceAttestationCredentialsProvider(&Provision::Manager::GetInstance().GetStorage()); chip::DeviceLayer::PlatformMgr().UnlockChipStack(); SILABS_LOG("Starting App Task"); @@ -190,7 +188,6 @@ void ApplicationStart(void * unused) void SilabsMatterConfig::AppInit() { GetPlatform().Init(); - sMainTaskHandle = osThreadNew(ApplicationStart, nullptr, &kMainTaskAttr); SILABS_LOG("Starting scheduler"); VerifyOrDie(sMainTaskHandle); // We can't proceed if the Main Task creation failed. @@ -257,8 +254,11 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) ReturnErrorOnFailure(PlatformMgr().InitChipStack()); - SetDeviceInstanceInfoProvider(&Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); - SetCommissionableDataProvider(&Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); + // Provision Manager + Silabs::Provision::Manager & provision = Silabs::Provision::Manager::GetInstance(); + ReturnErrorOnFailure(provision.Init()); + SetDeviceInstanceInfoProvider(&provision.GetStorage()); + SetCommissionableDataProvider(&provision.GetStorage()); chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(appName); diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 084339723a0037..6ada4753457fcb 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -86,10 +86,9 @@ source_set("test-event-trigger") { "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.h", ] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] public_configs = [ ":test-event-trigger-config" ] - public_deps = [ - ":silabs-factory-data-provider", "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", @@ -114,46 +113,9 @@ source_set("siwx917-matter-shell") { } } -config("attestation-credentials-config") { - include_dirs = [ "${chip_root}" ] -} - -source_set("siwx917-attestation-credentials") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.cpp", - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/platform:platform_base", - ] - - public_configs = [ ":attestation-credentials-config" ] -} - -source_set("silabs-factory-data-provider") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.cpp", - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/lib/support", - "${chip_root}/src/platform:platform_base", - "${chip_root}/src/setup_payload", - ] - - public_configs = [ ":siwx917-common-config" ] - - if (sl_enable_test_event_trigger) { - public_configs += [ ":test-event-trigger-config" ] - } -} - config("siwx917-common-config") { defines = [ "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout_sec}" ] + libs = [ "${sdk_support_root}/matter/provision/lib/libProvision_si917.a" ] if (!disable_lcd) { include_dirs = [ "${silabs_common_plat_dir}/display" ] @@ -210,7 +172,7 @@ config("silabs-wifi-config") { } source_set("siwx917-common") { - deps = [] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] defines = [] public_deps = [] public_configs = [ @@ -229,6 +191,8 @@ source_set("siwx917-common") { "${silabs_common_plat_dir}/LEDWidget.cpp", "${silabs_common_plat_dir}/MatterConfig.cpp", "${silabs_common_plat_dir}/SoftwareFaultReports.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageCustom.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageFlash.cpp", "${silabs_common_plat_dir}/silabs_utils.cpp", "${silabs_common_plat_dir}/syscalls_stubs.cpp", "${silabs_plat_si91x_wifi_dir}/dhcp_client.cpp", @@ -282,14 +246,6 @@ source_set("siwx917-common") { ] } - # Attestation Credentials - deps += [ ":siwx917-attestation-credentials" ] - - # Factory Data Provider - if (use_efr32_factory_data_provider) { - public_deps += [ ":silabs-factory-data-provider" ] - } - public_deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/lib", diff --git a/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp b/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp index ef42c0d3a9dfd2..cacb60555b6085 100644 --- a/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp +++ b/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp @@ -17,7 +17,7 @@ */ #include "SilabsTestEventTriggerDelegate.h" -#include "SilabsDeviceDataProvider.h" +#include using namespace ::chip::DeviceLayer; @@ -30,7 +30,7 @@ bool SilabsTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableK // Return false if we were not able to get the enableKey VerifyOrReturnValue( - Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider().GetTestEventTriggerKey(enableKeySpan) == CHIP_NO_ERROR, false); + Silabs::Provision::Manager::GetInstance().GetStorage().GetTestEventTriggerKey(enableKeySpan) == CHIP_NO_ERROR, false); return (!enableKeySpan.empty() && enableKeySpan.data_equal(enableKey)); } diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 20180ecb57656a..53f92cdfde99f6 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -103,10 +103,9 @@ source_set("test-event-trigger") { "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.h", ] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] public_configs = [ ":test-event-trigger-config" ] - public_deps = [ - ":silabs-factory-data-provider", "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", @@ -147,44 +146,11 @@ source_set("efr-matter-shell") { } } -config("attestation-credentials-config") { - include_dirs = [ "${chip_root}" ] -} - -source_set("efr32-attestation-credentials") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.cpp", - "${silabs_common_plat_dir}/SilabsDeviceAttestationCreds.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/platform:platform_base", - ] - - public_configs = [ ":attestation-credentials-config" ] -} - -source_set("silabs-factory-data-provider") { - sources = [ - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.cpp", - "${silabs_common_plat_dir}/SilabsDeviceDataProvider.h", - ] - - public_deps = [ - "${chip_root}/src/credentials", - "${chip_root}/src/lib/support", - "${chip_root}/src/platform:platform_base", - "${chip_root}/src/setup_payload", - ] - - if (sl_enable_test_event_trigger) { - public_configs = [ ":test-event-trigger-config" ] - } -} - config("efr32-common-config") { defines = [ "OTA_PERIODIC_TIMEOUT=${ota_periodic_query_timeout_sec}" ] + libs = [ + "${sdk_support_root}/matter/provision/lib/libProvision_${silabs_family}.a", + ] if (!disable_lcd) { include_dirs = [ "${silabs_common_plat_dir}/display" ] @@ -246,13 +212,15 @@ config("silabs-wifi-config") { } source_set("efr32-common") { - deps = [] + deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ] defines = [] public_deps = [] public_configs = [ ":efr32-common-config", "${efr32_sdk_build_root}:silabs_config", ":chip_examples_project_config", + + "${chip_root}/src/platform/silabs/provision:provision-config", ] # DIC @@ -275,6 +243,8 @@ source_set("efr32-common") { "${silabs_common_plat_dir}/LEDWidget.cpp", "${silabs_common_plat_dir}/MatterConfig.cpp", "${silabs_common_plat_dir}/SoftwareFaultReports.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageCustom.cpp", + "${silabs_common_plat_dir}/provision/ProvisionStorageDefault.cpp", "${silabs_common_plat_dir}/silabs_utils.cpp", "${silabs_common_plat_dir}/syscalls_stubs.cpp", ] @@ -339,14 +309,6 @@ source_set("efr32-common") { deps += [ ":efr-matter-shell" ] } - # Attestation Credentials - public_deps += [ ":efr32-attestation-credentials" ] - - # Factory Data Provider - if (use_efr32_factory_data_provider) { - public_deps += [ ":silabs-factory-data-provider" ] - } - public_deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/app/server", diff --git a/examples/platform/silabs/provision/ProvisionStorageCustom.cpp b/examples/platform/silabs/provision/ProvisionStorageCustom.cpp new file mode 100644 index 00000000000000..7efc99027983ac --- /dev/null +++ b/examples/platform/silabs/provision/ProvisionStorageCustom.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#include "ProvisionStorage.h" +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +namespace { +constexpr uint8_t kExample1 = 0x0001; +constexpr uint8_t kExample2 = 0x0002; +uint8_t sExample1 = 0; +uint8_t sExample2[32] = { 0 }; +} // namespace + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint8_t * value) +{ + switch (id) + { + case kExample1: + sExample1 = (nullptr == value) ? 0 : *value; + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint8_t & value) +{ + switch (id) + { + case kExample1: + value = sExample1; + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint16_t * value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint16_t & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint32_t * value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint32_t & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint64_t * value) +{ + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint64_t & value) +{ + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; +} + +CHIP_ERROR CustomStorage::Set(uint16_t id, const uint8_t * value, size_t size) +{ + switch (id) + { + case kExample2: + memset(sExample2, 0x00, sizeof(sExample2)); + if (nullptr != value) + { + memcpy(sExample2, value, std::min(size, sizeof(sExample2))); + } + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR CustomStorage::Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) +{ + VerifyOrReturnError((nullptr != value) && (max_size > 0), CHIP_ERROR_INVALID_ARGUMENT); + switch (id) + { + case kExample2: + size = std::min(max_size, sizeof(sExample2)); + memcpy(value, sExample2, size); + break; + + default: + return CHIP_ERROR_UNKNOWN_RESOURCE_ID; + } + return CHIP_NO_ERROR; +} + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp new file mode 100644 index 00000000000000..661189ef9060ac --- /dev/null +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#include "AttestationKey.h" +#include "ProvisionStorage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef SLI_SI91X_MCU_INTERFACE +#include +#endif + +#ifdef SL_PROVISION_GENERATOR +extern void setNvm3End(uint32_t addr); +#endif + +extern uint8_t linker_nvm_end[]; + +using namespace chip::Credentials; +using namespace chip::DeviceLayer::Internal; + +using SilabsConfig = chip::DeviceLayer::Internal::SilabsConfig; + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +namespace { +// Miss-aligned certificates is a common error, and printing the first few bytes is +// useful to verify proper alignment. Eight bytes is enough for this purpose. +constexpr size_t kDebugLength = 8; +size_t sCredentialsOffset = 0; + +CHIP_ERROR ErasePage(uint32_t addr) +{ +#ifdef SLI_SI91X_MCU_INTERFACE + rsi_flash_erase_sector((uint32_t *) addr); +#else + MSC_ErasePage((uint32_t *) addr); +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR WritePage(uint32_t addr, const uint8_t * data, size_t size) +{ +#ifdef SLI_SI91X_MCU_INTERFACE + rsi_flash_write((uint32_t *) addr, (unsigned char *) data, size); +#else + MSC_WriteWord((uint32_t *) addr, data, size); +#endif + return CHIP_NO_ERROR; +} + +size_t RoundNearest(size_t n, size_t multiple) +{ + return (n % multiple) > 0 ? n + (multiple - n % multiple) : n; +} + +CHIP_ERROR WriteFile(Storage & store, SilabsConfig::Key offset_key, SilabsConfig::Key size_key, const ByteSpan & value) +{ + uint32_t base_addr = 0; + ReturnErrorOnFailure(store.GetBaseAddress(base_addr)); + if (0 == sCredentialsOffset) + { + ReturnErrorOnFailure(ErasePage(base_addr)); + } + + memcpy(Storage::aux_buffer, value.data(), value.size()); + if (value.size() < Storage::kArgumentSizeMax) + { + memset(Storage::aux_buffer + value.size(), 0xff, Storage::kArgumentSizeMax - value.size()); + } + + ChipLogProgress(DeviceLayer, "WriteFile, addr:0x%06x+%03u, size:%u", (unsigned) base_addr, (unsigned) sCredentialsOffset, + (unsigned) value.size()); + // ChipLogByteSpan(DeviceLayer, ByteSpan(value.data(), value.size() < kDebugLength ? value.size() : kDebugLength)); + + ReturnErrorOnFailure(WritePage(base_addr + sCredentialsOffset, Storage::aux_buffer, Storage::kArgumentSizeMax)); + + // Store file offset + ReturnErrorOnFailure(SilabsConfig::WriteConfigValue(offset_key, (uint32_t) sCredentialsOffset)); + // Store file size + ReturnErrorOnFailure(SilabsConfig::WriteConfigValue(size_key, (uint32_t) value.size())); + // Calculate offset for the next file + sCredentialsOffset = RoundNearest(sCredentialsOffset + value.size(), 64); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ReadFileByOffset(Storage & store, const char * description, uint32_t offset, uint32_t size, MutableByteSpan & value) +{ + uint32_t base_addr = 0; + ReturnErrorOnFailure(store.GetBaseAddress(base_addr)); + + uint8_t * address = (uint8_t *) (base_addr + offset); + ByteSpan span(address, size); + ChipLogProgress(DeviceLayer, "%s, addr:0x%06x+%03u, size:%u", description, (unsigned) base_addr, (unsigned) offset, + (unsigned) size); + // ChipLogByteSpan(DeviceLayer, ByteSpan(span.data(), span.size() < kDebugLength ? span.size() : kDebugLength)); + return CopySpanToMutableSpan(span, value); +} + +CHIP_ERROR ReadFileByKey(Storage & store, const char * description, uint32_t offset_key, uint32_t size_key, MutableByteSpan & value) +{ + uint32_t offset = 0; + uint32_t size = 0; + + // Offset + VerifyOrReturnError(SilabsConfig::ConfigValueExists(offset_key), CHIP_ERROR_NOT_FOUND); + ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(offset_key, offset)); + + // Size + VerifyOrReturnError(SilabsConfig::ConfigValueExists(size_key), CHIP_ERROR_NOT_FOUND); + ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(size_key, size)); + + return ReadFileByOffset(store, description, offset, size, value); +} + +} // namespace + +// +// Initialization +// + +CHIP_ERROR Storage::Initialize(uint32_t flash_addr, uint32_t flash_size) +{ + sCredentialsOffset = 0; + + uint32_t base_addr = (uint32_t) linker_nvm_end; + if (flash_size > 0) + { +#ifndef SLI_SI91X_MCU_INTERFACE + base_addr = (flash_addr + flash_size - FLASH_PAGE_SIZE); + MSC_Init(); +#endif // SLI_SI91X_MCU_INTERFACE +#ifdef SL_PROVISION_GENERATOR + setNvm3End(base_addr); +#endif + } + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, base_addr); +} + +CHIP_ERROR Storage::GetBaseAddress(uint32_t & value) +{ + return SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, value); +} + +CHIP_ERROR Storage::Commit() +{ + return CHIP_NO_ERROR; +} + +// +// DeviceInstanceInfoProvider +// + +CHIP_ERROR Storage::SetSerialNumber(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_SerialNum, value, len); +} + +CHIP_ERROR Storage::GetSerialNumber(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_SerialNum, value, max, size); +} + +CHIP_ERROR Storage::SetVendorId(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_VendorId, value); +} + +CHIP_ERROR Storage::GetVendorId(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_VendorId, value); +#if defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetVendorName(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_VendorName, value, len); +} + +CHIP_ERROR Storage::GetVendorName(char * value, size_t max) +{ + size_t name_len = 0; // Without counting null-terminator + + CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_VendorName, value, max, name_len); +#if defined(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductId(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_ProductId, value); +} + +CHIP_ERROR Storage::GetProductId(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_ProductId, value); + +#if defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductName(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_ProductName, value, len); +} + +CHIP_ERROR Storage::GetProductName(char * value, size_t max) +{ + size_t name_len = 0; // Without counting null-terminator + + CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductName, value, max, name_len); +#if defined(CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductLabel(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::KConfigKey_ProductLabel, value, len); +} + +CHIP_ERROR Storage::GetProductLabel(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::KConfigKey_ProductLabel, value, max, size); +} + +CHIP_ERROR Storage::SetProductURL(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_ProductURL, value, len); +} +CHIP_ERROR Storage::GetProductURL(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductURL, value, max, size); +} + +CHIP_ERROR Storage::SetPartNumber(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_PartNumber, value, len); +} + +CHIP_ERROR Storage::GetPartNumber(char * value, size_t max) +{ + size_t size = 0; + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_PartNumber, value, max, size); +} + +CHIP_ERROR Storage::SetHardwareVersion(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_HardwareVersion, value); +} + +CHIP_ERROR Storage::GetHardwareVersion(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_HardwareVersion, value); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetHardwareVersionString(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_HardwareVersionString, value, len); +} + +CHIP_ERROR Storage::GetHardwareVersionString(char * value, size_t max) +{ + size_t hw_version_len = 0; // @ithout counting null-terminator + + CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_HardwareVersionString, value, max, hw_version_len); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetManufacturingDate(const char * value, size_t len) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_ManufacturingDate, value, len); +} + +CHIP_ERROR Storage::GetManufacturingDate(uint8_t * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ManufacturingDate, (char *) value, max, size); +} + +CHIP_ERROR Storage::SetUniqueId(const uint8_t * value, size_t size) +{ + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_UniqueId, value, size); +} + +CHIP_ERROR Storage::GetUniqueId(uint8_t * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_UniqueId, value, max, size); +} + +// +// CommissionableDataProvider +// + +CHIP_ERROR Storage::SetSetupDiscriminator(uint16_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_SetupDiscriminator, value); +} + +CHIP_ERROR Storage::GetSetupDiscriminator(uint16_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_SetupDiscriminator, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; + err = CHIP_NO_ERROR; + } +#endif + ReturnErrorOnFailure(err); + VerifyOrReturnLogError(value <= kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetSpake2pIterationCount(uint32_t value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Spake2pIterationCount, value); +} + +CHIP_ERROR Storage::GetSpake2pIterationCount(uint32_t & value) +{ + CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Spake2pIterationCount, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetSetupPasscode(uint32_t value) +{ + (void) value; + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::GetSetupPasscode(uint32_t & value) +{ + (void) value; + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::SetSpake2pSalt(const char * value, size_t size) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_Spake2pSalt, value, size); +} + +CHIP_ERROR Storage::GetSpake2pSalt(char * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pSalt, value, max, size); +} + +CHIP_ERROR Storage::SetSpake2pVerifier(const char * value, size_t size) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_Spake2pVerifier, value, size); +} + +CHIP_ERROR Storage::GetSpake2pVerifier(char * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pVerifier, value, max, size); +} + +// +// DeviceAttestationCredentialsProvider +// + +CHIP_ERROR Storage::SetFirmwareInformation(const ByteSpan & value) +{ + (void) value; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetFirmwareInformation(MutableByteSpan & value) +{ + // TODO: We need a real example FirmwareInformation to be populated. + value.reduce_size(0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetCertificationDeclaration(const ByteSpan & value) +{ + ReturnErrorOnFailure(WriteFile(*this, SilabsConfig::kConfigKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey(*this, "GetCertificationDeclaration", SilabsConfig::kConfigKey_Creds_CD_Offset, + SilabsConfig::kConfigKey_Creds_CD_Size, value); +#if defined(SL_PROVISION_VERSION_1_0) && SL_PROVISION_VERSION_1_0 + if (CHIP_ERROR_NOT_FOUND == err) + { + // Reading from the old script's location. + err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_CD_OFFSET, SL_CREDENTIALS_CD_SIZE, value); + } +#endif +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_ERROR_NOT_FOUND == err) + { + // Example CD + err = Examples::GetExampleDACProvider()->GetCertificationDeclaration(value); + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductAttestationIntermediateCert(const ByteSpan & value) +{ + ReturnErrorOnFailure( + WriteFile(*this, SilabsConfig::kConfigKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey(*this, "GetProductAttestationIntermediateCert", SilabsConfig::kConfigKey_Creds_PAI_Offset, + SilabsConfig::kConfigKey_Creds_PAI_Size, value); +#if defined(SL_PROVISION_VERSION_1_0) && SL_PROVISION_VERSION_1_0 + if (CHIP_ERROR_NOT_FOUND == err) + { + // Reading from the old script's location. + err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_PAI_OFFSET, SL_CREDENTIALS_PAI_SIZE, value); + } +#endif +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_ERROR_NOT_FOUND == err) + { + // Example PAI + err = Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(value); + } +#endif + return err; +} + +CHIP_ERROR Storage::SetDeviceAttestationCert(const ByteSpan & value) +{ + ReturnErrorOnFailure( + WriteFile(*this, SilabsConfig::kConfigKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetDeviceAttestationCert(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey(*this, "GetDeviceAttestationCert", SilabsConfig::kConfigKey_Creds_DAC_Offset, + SilabsConfig::kConfigKey_Creds_DAC_Size, value); +#if defined(SL_PROVISION_VERSION_1_0) && SL_PROVISION_VERSION_1_0 + if (CHIP_ERROR_NOT_FOUND == err) + { + // Reading from the old script's location. + err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_DAC_OFFSET, SL_CREDENTIALS_DAC_SIZE, value); + } +#endif +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_ERROR_NOT_FOUND == err) + { + // Example DAC + return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(value); + } +#endif + return err; +} + +#ifdef SLI_SI91X_MCU_INTERFACE +CHIP_ERROR Storage::SetDeviceAttestationKey(const ByteSpan & value) +{ + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_Creds_KeyId, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr) +{ + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + ReturnErrorOnFailure(key.GenerateCSR(vid, pid, cn, csr)); + ReturnErrorOnFailure(key.Export(temp, sizeof(temp), size)); + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_Creds_KeyId, temp, size); +} + +CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature) +{ + if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_KeyId)) + { + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + ReturnErrorOnFailure(SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Creds_KeyId, temp, sizeof(temp), size)); + key.Import(temp, size); + return key.SignMessage(message, signature); + } + else + { +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + // Example DAC key + return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); +#else + return CHIP_ERROR_NOT_FOUND; +#endif + } +} + +#else // SLI_SI91X_MCU_INTERFACEX_MCU_INTERFACEX_MCU_INTERFACE + +CHIP_ERROR Storage::SetDeviceAttestationKey(const ByteSpan & value) +{ + AttestationKey key; + ReturnErrorOnFailure(key.Import(value.data(), value.size())); + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, key.GetId()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr) +{ + AttestationKey key; + ReturnErrorOnFailure(key.GenerateCSR(vid, pid, cn, csr)); + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, key.GetId()); +} + +CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_FOUND; + uint32_t kid = 0; + + if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_KeyId)) + { + ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, kid)); + AttestationKey key(kid); + err = key.SignMessage(message, signature); + } +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + else + { + // Example DAC key + err = Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); + } +#endif + ChipLogProgress(DeviceLayer, "SignWithDeviceAttestationKey, kid:%u, msg_size:%u, sig_size:%u, err:0x%02x", (unsigned) kid, + (unsigned) message.size(), (unsigned) signature.size(), (unsigned) err.AsInteger()); + // ChipLogByteSpan(DeviceLayer, ByteSpan(signature.data(), signature.size() < kDebugLength ? signature.size() : kDebugLength)); + return err; +} +#endif // SLI_SI91X_MCU_INTERFACE + +// +// Other +// + +CHIP_ERROR Storage::SetProvisionVersion(const char * value, size_t size) +{ + return SilabsConfig::WriteConfigValueStr(SilabsConfig::kConfigKey_Provision_Version, value, size); +} + +CHIP_ERROR Storage::GetProvisionVersion(char * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Provision_Version, value, max, size); +} + +CHIP_ERROR Storage::SetSetupPayload(const uint8_t * value, size_t size) +{ + return SilabsConfig::WriteConfigValueBin(SilabsConfig::kConfigKey_SetupPayloadBitSet, value, size); +} + +CHIP_ERROR Storage::GetSetupPayload(uint8_t * value, size_t max, size_t & size) +{ + return SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_SetupPayloadBitSet, value, max, size); +} + +CHIP_ERROR Storage::SetProvisionRequest(bool value) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Provision_Request, value); +} + +CHIP_ERROR Storage::GetProvisionRequest(bool & value) +{ + return SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Provision_Request, value); +} + +#if OTA_ENCRYPTION_ENABLE +CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) +{ + chip::DeviceLayer::Silabs::OtaTlvEncryptionKey::OtaTlvEncryptionKey key; + ReturnErrorOnFailure(key.Import(value.data(), value.size())); + return SilabsConfig::WriteConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, key.GetId()); +} +#endif + +/** + * @brief Reads the test event trigger key from NVM. If the key isn't present, returns default value if defined. + * + * @param[out] keySpan output buffer. Must be at least large enough for 16 bytes (ken length) + * @return CHIP_ERROR + */ +CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) +{ + constexpr size_t kEnableKeyLength = 16; // Expected byte size of the EnableKey + CHIP_ERROR err = CHIP_NO_ERROR; + size_t keyLength = 0; + + VerifyOrReturnError(keySpan.size() >= kEnableKeyLength, CHIP_ERROR_BUFFER_TOO_SMALL); + + err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Test_Event_Trigger_Key, keySpan.data(), kEnableKeyLength, + keyLength); +#ifndef NDEBUG +#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + + constexpr char enableKey[] = SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY; + if (Encoding::HexToBytes(enableKey, strlen(enableKey), keySpan.data(), kEnableKeyLength) != kEnableKeyLength) + { + // enableKey Hex String doesn't have the correct length + memset(keySpan.data(), 0, keySpan.size()); + return CHIP_ERROR_INTERNAL; + } + err = CHIP_NO_ERROR; + } +#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED +#endif // NDEBUG + + keySpan.reduce_size(kEnableKeyLength); + return err; +} + +} // namespace Provision + +void MigrateUint32(uint32_t old_key, uint32_t new_key) +{ + uint32_t value = 0; + if (SilabsConfig::ConfigValueExists(old_key) && (CHIP_NO_ERROR == SilabsConfig::ReadConfigValue(old_key, value))) + { + SilabsConfig::WriteConfigValue(new_key, value); + } +} + +void MigrateDacProvider(void) +{ + constexpr uint32_t kOldKey_Creds_KeyId = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x21); + constexpr uint32_t kOldKey_Creds_Base_Addr = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x22); + constexpr uint32_t kOldKey_Creds_DAC_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x23); + constexpr uint32_t kOldKey_Creds_DAC_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x24); + constexpr uint32_t kOldKey_Creds_PAI_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x26); + constexpr uint32_t kOldKey_Creds_PAI_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x25); + constexpr uint32_t kOldKey_Creds_CD_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x27); + constexpr uint32_t kOldKey_Creds_CD_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x28); + + MigrateUint32(kOldKey_Creds_KeyId, SilabsConfig::kConfigKey_Creds_KeyId); + MigrateUint32(kOldKey_Creds_Base_Addr, SilabsConfig::kConfigKey_Creds_Base_Addr); + MigrateUint32(kOldKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Offset); + MigrateUint32(kOldKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_DAC_Size); + MigrateUint32(kOldKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Offset); + MigrateUint32(kOldKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_PAI_Size); + MigrateUint32(kOldKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Offset); + MigrateUint32(kOldKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD_Size); +} + +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp new file mode 100644 index 00000000000000..5bd11108bd9cc6 --- /dev/null +++ b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#include "AttestationKey.h" +#include "ProvisionEncoder.h" +#include "ProvisionStorage.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip::Credentials; + +#if SLI_SI91X_MCU_INTERFACE +// TODO: Remove this once the flash header integrates these definitions +#define FLASH_ERASE 1 // flash_sector_erase_enable value for erase operation +#define FLASH_WRITE 0 // flash_sector_erase_enable value for write operation + +#define NWP_FLASH_ADDRESS (0x0000000) +#define NWP_FLASH_SIZE (0x0004E20) + +#include +extern "C" { +#include +#include +#include +#include +} + +#else // SLI_SI91X_MCU_INTERFACE +#include +extern uint8_t linker_nvm_end[]; +#endif // SLI_SI91X_MCU_INTERFACE + +namespace { +constexpr size_t kPageSize = FLASH_PAGE_SIZE; +constexpr size_t kMaxBinaryValue = 1024; +constexpr size_t kArgumentBufferSize = 2 * sizeof(uint16_t) + kMaxBinaryValue; // ID(2) + Size(2) + Value(n) +} // namespace + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { +namespace Flash { + +#if SLI_SI91X_MCU_INTERFACE +static uint8_t * sReadOnlyPage = reinterpret_cast(NWP_FLASH_ADDRESS); +#else +static uint8_t * sReadOnlyPage = reinterpret_cast(linker_nvm_end); +#endif // SLI_SI91X_MCU_INTERFACE +uint8_t sTemporaryPage[kPageSize] = { 0 }; +uint8_t * sActivePage = sReadOnlyPage; + +CHIP_ERROR DecodeTotal(Encoding::Buffer & reader, uint16_t & total) +{ + uint16_t sz = 0; + ReturnErrorOnFailure(reader.Get(sz)); + total = (0xffff == sz) ? sizeof(uint16_t) : sz; + reader.in = reader.begin + total; + ReturnErrorCodeIf(reader.in > reader.end, CHIP_ERROR_INTERNAL); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ActivateWrite(uint8_t *& active) +{ +#if !(SLI_SI91X_MCU_INTERFACE) + if (sActivePage == sReadOnlyPage) + { + memcpy(sTemporaryPage, sReadOnlyPage, sizeof(sTemporaryPage)); + } + active = sActivePage = sTemporaryPage; +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, Encoding::Buffer & in) +{ + uint8_t * page = sActivePage; + uint16_t total = 0; + Encoding::Buffer reader(page, kPageSize, true); + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument found(temp, sizeof(temp)); + + // Decode total + ReturnErrorOnFailure(DecodeTotal(reader, total)); + // Search entry + CHIP_ERROR err = Encoding::Version2::Find(reader, id, found); + if ((CHIP_ERROR_NOT_FOUND != err) && (CHIP_NO_ERROR != err)) + { + // Memory corruption, write at the last correct address + return err; + } + ReturnErrorOnFailure(ActivateWrite(page)); + + Encoding::Buffer writer(page, kPageSize); + if (CHIP_ERROR_NOT_FOUND == err) + { + // New entry + size_t temp_total = found.offset; + ReturnErrorCodeIf(temp_total + in.Size() > kPageSize, CHIP_ERROR_INVALID_ARGUMENT); + // Copy entry + ReturnErrorOnFailure(in.Get(page + temp_total, in.Size())); + // Update total + total = temp_total + in.Size(); + ReturnErrorOnFailure(writer.Add(total)); + } + else + { + // Existing entry + if (in.Size() == found.encoded_size) + { + // Same size, keep in place + memset(page + found.offset, 0xff, found.encoded_size); + ReturnErrorOnFailure(in.Get(page + found.offset, in.Size())); + } + else + { + // Size change, move to the end + uint16_t temp_total = total - found.encoded_size; + ReturnErrorCodeIf(temp_total + in.Size() > kPageSize, CHIP_ERROR_INVALID_ARGUMENT); + // Remove the entry + memmove(page + found.offset, page + found.offset + found.encoded_size, temp_total); + // Add the entry + ReturnErrorOnFailure(in.Get(page + temp_total, in.Size())); + // Update total + total = temp_total + in.Size(); + ReturnErrorOnFailure(writer.Add(total)); + } + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR Get(uint16_t id, Encoding::Version2::Argument & arg) +{ + uint16_t total = 0; + + Encoding::Buffer reader(sActivePage, kPageSize, true); + ReturnErrorOnFailure(DecodeTotal(reader, total)); + CHIP_ERROR err = Encoding::Version2::Find(reader, id, arg); + // ProvisionStorage expects CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND + VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + return err; +} + +CHIP_ERROR Set(uint16_t id, uint8_t value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, &value, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint8_t & value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Int8u == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + value = arg.value.u8; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, uint16_t value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, &value, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint16_t & value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Int16u == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + value = arg.value.u16; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, uint32_t value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, &value, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint32_t & value) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Int32u == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + value = arg.value.u32; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) +{ + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Encoding::Version2::Encode(id, value, size, arg)); + return Set(id, arg); +} + +CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) +{ + + uint8_t temp[kArgumentBufferSize] = { 0 }; + Encoding::Version2::Argument arg(temp, sizeof(temp)); + ReturnErrorOnFailure(Get(id, arg)); + VerifyOrReturnError(Encoding::Version2::Type_Binary == arg.type, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(arg.size <= max_size, CHIP_ERROR_INTERNAL); + memcpy(value, arg.value.b, arg.size); + size = arg.size; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Set(uint16_t id, const char * value, size_t size) +{ + return Set(id, (const uint8_t *) value, size); +} + +CHIP_ERROR Get(uint16_t id, char * value, size_t max_size, size_t & size) +{ + return Get(id, (uint8_t *) value, max_size - 1, size); +} + +} // namespace Flash + +// +// Initialization +// + +CHIP_ERROR Storage::Initialize(uint32_t flash_addr, uint32_t flash_size) +{ +#if SLI_SI91X_MCU_INTERFACE + sl_status_t status = sl_si91x_command_to_read_common_flash((uint32_t) (Flash::sReadOnlyPage), sizeof(Flash::sTemporaryPage), + Flash::sTemporaryPage); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_INVALID_ARGUMENT); + Flash::sActivePage = Flash::sTemporaryPage; + +#else // SLI_SI91X_MCU_INTERFACE + if (flash_size > 0) + { + Flash::sReadOnlyPage = (uint8_t *) (flash_addr + flash_size - kPageSize); + } + Flash::sActivePage = Flash::sReadOnlyPage; + MSC_Init(); +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::Commit() +{ + if (Flash::sActivePage == Flash::sTemporaryPage) + { +#if SLI_SI91X_MCU_INTERFACE + // Erase page + sl_status_t status = sl_si91x_command_to_write_common_flash((uint32_t) (Flash::sReadOnlyPage), Flash::sTemporaryPage, + kPageSize, FLASH_ERASE); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_WRITE_FAILED); + // Write to flash + status = sl_si91x_command_to_write_common_flash((uint32_t) (Flash::sReadOnlyPage), Flash::sTemporaryPage, kPageSize, + FLASH_WRITE); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_WRITE_FAILED); +#else + // Erase page + MSC_ErasePage((uint32_t *) Flash::sReadOnlyPage); + // Write to flash + MSC_WriteWord((uint32_t *) Flash::sReadOnlyPage, Flash::sTemporaryPage, kPageSize); +#endif // SLI_SI91X_MCU_INTERFACE + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetBaseAddress(uint32_t & value) +{ + value = (uint32_t) Flash::sReadOnlyPage; + return CHIP_NO_ERROR; +} + +// +// DeviceInstanceInfoProvider +// + +CHIP_ERROR Storage::SetSerialNumber(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kSerialNumber, value, len); +} + +CHIP_ERROR Storage::GetSerialNumber(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kSerialNumber, value, max, size); +} + +CHIP_ERROR Storage::SetVendorId(uint16_t value) +{ + return Flash::Set(Parameters::ID::kVendorId, value); +} + +CHIP_ERROR Storage::GetVendorId(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kVendorId, value); +#if defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetVendorName(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kVendorName, value, len); +} + +CHIP_ERROR Storage::GetVendorName(char * value, size_t max) +{ + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kVendorName, value, max, size); +#if defined(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductId(uint16_t value) +{ + return Flash::Set(Parameters::ID::kProductId, value); +} + +CHIP_ERROR Storage::GetProductId(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kProductId, value); +#if defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductName(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kProductName, value, len); +} + +CHIP_ERROR Storage::GetProductName(char * value, size_t max) +{ + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kProductName, value, max, size); +#if defined(CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME); + err = CHIP_NO_ERROR; + } +#endif + return err; +} + +CHIP_ERROR Storage::SetProductLabel(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kProductLabel, value, len); +} + +CHIP_ERROR Storage::GetProductLabel(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kProductLabel, value, max, size); +} + +CHIP_ERROR Storage::SetProductURL(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kProductUrl, value, len); +} +CHIP_ERROR Storage::GetProductURL(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kProductUrl, value, max, size); +} + +CHIP_ERROR Storage::SetPartNumber(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kPartNumber, value, len); +} + +CHIP_ERROR Storage::GetPartNumber(char * value, size_t max) +{ + size_t size = 0; + return Flash::Get(Parameters::ID::kPartNumber, value, max, size); +} + +CHIP_ERROR Storage::SetHardwareVersion(uint16_t value) +{ + return Flash::Set(Parameters::ID::kHwVersion, value); +} + +CHIP_ERROR Storage::GetHardwareVersion(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kHwVersion, value); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION; + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION + return err; +} + +CHIP_ERROR Storage::SetHardwareVersionString(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kHwVersionStr, value, len); +} + +CHIP_ERROR Storage::GetHardwareVersionString(char * value, size_t max) +{ + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kHwVersionStr, value, max, size); +#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING) + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + VerifyOrReturnError(value != nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(max > strlen(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + Platform::CopyString(value, max, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING + return err; +} + +CHIP_ERROR Storage::SetManufacturingDate(const char * value, size_t len) +{ + return Flash::Set(Parameters::ID::kManufacturingDate, value, len); +} + +CHIP_ERROR Storage::GetManufacturingDate(uint8_t * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kManufacturingDate, value, max, size); +} + +CHIP_ERROR Storage::SetUniqueId(const uint8_t * value, size_t size) +{ + return Flash::Set(Parameters::ID::kUniqueId, value, size); +} + +CHIP_ERROR Storage::GetUniqueId(uint8_t * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kUniqueId, value, max, size); +} + +// +// CommissionableDataProvider +// + +CHIP_ERROR Storage::SetSetupDiscriminator(uint16_t value) +{ + return Flash::Set(Parameters::ID::kDiscriminator, value); +} + +CHIP_ERROR Storage::GetSetupDiscriminator(uint16_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kDiscriminator, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR + ReturnErrorOnFailure(err); + VerifyOrReturnLogError(value <= kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetSpake2pIterationCount(uint32_t value) +{ + return Flash::Set(Parameters::ID::kSpake2pIterations, value); +} + +CHIP_ERROR Storage::GetSpake2pIterationCount(uint32_t & value) +{ + CHIP_ERROR err = Flash::Get(Parameters::ID::kSpake2pIterations, value); +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + value = CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT; + err = CHIP_NO_ERROR; + } +#endif // CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT + return err; +} + +CHIP_ERROR Storage::SetSetupPasscode(uint32_t value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::GetSetupPasscode(uint32_t & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::SetSpake2pSalt(const char * value, size_t size) +{ + return Flash::Set(Parameters::ID::kSpake2pSalt, value, size); +} + +CHIP_ERROR Storage::GetSpake2pSalt(char * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kSpake2pSalt, value, max, size); +} + +CHIP_ERROR Storage::SetSpake2pVerifier(const char * value, size_t size) +{ + return Flash::Set(Parameters::ID::kSpake2pVerifier, value, size); +} + +CHIP_ERROR Storage::GetSpake2pVerifier(char * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kSpake2pVerifier, value, max, size); +} + +// +// DeviceAttestationCredentialsProvider +// + +CHIP_ERROR Storage::SetFirmwareInformation(const ByteSpan & value) +{ + (void) value; + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::GetFirmwareInformation(MutableByteSpan & value) +{ + // TODO: We need a real example FirmwareInformation to be populated. + value.reduce_size(0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetCertificationDeclaration(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kCertification, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) +{ + size_t size = 0; + CHIP_ERROR err = (Flash::Get(Parameters::ID::kCertification, value.data(), value.size(), size)); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example CD + return Examples::GetExampleDACProvider()->GetCertificationDeclaration(value); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + value.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetProductAttestationIntermediateCert(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kPaiCert, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & value) +{ + size_t size = 0; + CHIP_ERROR err = (Flash::Get(Parameters::ID::kPaiCert, value.data(), value.size(), size)); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example PAI + return Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(value); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + value.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetDeviceAttestationCert(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kDacCert, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCert(MutableByteSpan & value) +{ + size_t size = 0; + CHIP_ERROR err = (Flash::Get(Parameters::ID::kDacCert, value.data(), value.size(), size)); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example DAC + return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(value); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + value.reduce_size(size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR Storage::SetDeviceAttestationKey(const ByteSpan & value) +{ + return Flash::Set(Parameters::ID::kDacKey, value.data(), value.size()); +} + +CHIP_ERROR Storage::GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr) +{ + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + ReturnErrorOnFailure(key.GenerateCSR(vid, pid, cn, csr)); + ReturnErrorOnFailure(key.Export(temp, sizeof(temp), size)); + return Flash::Set(Parameters::ID::kDacKey, temp, size); +} + +CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature) +{ + AttestationKey key; + uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; + size_t size = 0; + CHIP_ERROR err = Flash::Get(Parameters::ID::kDacKey, temp, sizeof(temp), size); +#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + // Example DAC key + return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(key.Import(temp, size)); + return key.SignMessage(message, signature); +} + +// +// Other +// + +CHIP_ERROR Storage::SetProvisionVersion(const char * value, size_t size) +{ + return Flash::Set(Parameters::ID::kVersion, value, size); +} + +CHIP_ERROR Storage::GetProvisionVersion(char * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kVersion, value, max, size); +} + +CHIP_ERROR Storage::SetSetupPayload(const uint8_t * value, size_t size) +{ + return Flash::Set(Parameters::ID::kSetupPayload, value, size); +} + +CHIP_ERROR Storage::GetSetupPayload(uint8_t * value, size_t max, size_t & size) +{ + return Flash::Get(Parameters::ID::kSetupPayload, value, max, size); +} + +CHIP_ERROR Storage::SetProvisionRequest(bool value) +{ + // return Flash::Set(Parameters::ID::kProvisionRequest, value); + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR Storage::GetProvisionRequest(bool & value) +{ + // return Flash::Set(Parameters::ID::kProvisionRequest, value); + return CHIP_ERROR_NOT_IMPLEMENTED; +} +#if OTA_ENCRYPTION_ENABLE +CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} +#endif + +CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace Provision + +void MigrateDacProvider(void) {} + +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/examples/platform/silabs/silabs_creds.h b/examples/platform/silabs/silabs_creds.h index 792c7b2238afaa..bd6c3377006945 100644 --- a/examples/platform/silabs/silabs_creds.h +++ b/examples/platform/silabs/silabs_creds.h @@ -1,41 +1,49 @@ -/** - * This is a boilerplat header to define the SILABS authentication credentials. - * Applications must provide their own version of this header, and include: - * - The content of the CSA-provided Certification Declaration - * - The location and size of the PAI, and DAC - * - The key ID of the key-pair associated with the DAC +/* + * + * Copyright (c) 2024 Project CHIP Authors + * 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 * - * These credentials MUST be provided if the build variable "chip_build_device_attestation_credentials" is set to true. + * 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. + */ +/** + * To enable these credentias, compile the app with option + * "chip_build_device_attestation_credentials=true". */ -#ifndef SILABS_DEVICE_CREDENTIALS -#define SILABS_DEVICE_CREDENTIALS -#ifndef SILABS_CREDENTIALS_DAC_KEY_ID -#define SILABS_CREDENTIALS_DAC_KEY_ID 0x0002 +#ifndef SL_PROVISION_VERSION_1_0 +#define SL_PROVISION_VERSION_1_0 0 #endif -#ifndef SILABS_CREDENTIALS_DAC_OFFSET -#define SILABS_CREDENTIALS_DAC_OFFSET 0x0000 +#ifndef SL_CREDENTIALS_DAC_OFFSET +#define SL_CREDENTIALS_DAC_OFFSET 0x0000 #endif -#ifndef SILABS_CREDENTIALS_DAC_SIZE -#define SILABS_CREDENTIALS_DAC_SIZE 0 +#ifndef SL_CREDENTIALS_DAC_SIZE +#define SL_CREDENTIALS_DAC_SIZE 0 #endif -#ifndef SILABS_CREDENTIALS_PAI_OFFSET -#define SILABS_CREDENTIALS_PAI_OFFSET 0x0200 +#ifndef SL_CREDENTIALS_PAI_OFFSET +#define SL_CREDENTIALS_PAI_OFFSET 0x0200 #endif -#ifndef SILABS_CREDENTIALS_PAI_SIZE -#define SILABS_CREDENTIALS_PAI_SIZE 0 +#ifndef SL_CREDENTIALS_PAI_SIZE +#define SL_CREDENTIALS_PAI_SIZE 0 #endif -#ifndef SILABS_CREDENTIALS_CD_OFFSET -#define SILABS_CREDENTIALS_CD_OFFSET 0x0400 +#ifndef SL_CREDENTIALS_CD_OFFSET +#define SL_CREDENTIALS_CD_OFFSET 0x0400 #endif -#ifndef SILABS_CREDENTIALS_CD_SIZE -#define SILABS_CREDENTIALS_CD_SIZE 0 +#ifndef SL_CREDENTIALS_CD_SIZE +#define SL_CREDENTIALS_CD_SIZE 0 #endif - -#endif // SILABS_DEVICE_CREDENTIALS diff --git a/src/platform/silabs/efr32/BLEManagerImpl.cpp b/src/platform/silabs/efr32/BLEManagerImpl.cpp index 000ddbea63c4ed..78bd13d061ef45 100644 --- a/src/platform/silabs/efr32/BLEManagerImpl.cpp +++ b/src/platform/silabs/efr32/BLEManagerImpl.cpp @@ -52,6 +52,9 @@ extern "C" { #include #endif +#include +#include + using namespace ::chip; using namespace ::chip::Ble; @@ -725,12 +728,20 @@ void BLEManagerImpl::HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt) void BLEManagerImpl::HandleWriteEvent(volatile sl_bt_msg_t * evt) { uint16_t attribute = evt->data.evt_gatt_server_user_write_request.characteristic; - + bool do_provision = chip::DeviceLayer::Silabs::Provision::Manager::GetInstance().IsProvisionRequired(); ChipLogProgress(DeviceLayer, "Char Write Req, char : %d", attribute); if (gattdb_CHIPoBLEChar_Rx == attribute) { - HandleRXCharWrite(evt); + if (do_provision) + { + chip::DeviceLayer::Silabs::Provision::Channel::Update(attribute); + chip::DeviceLayer::Silabs::Provision::Manager::GetInstance().Step(); + } + else + { + HandleRXCharWrite(evt); + } } } diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn index 3d1510d5029d9e..01027e0371a5b7 100644 --- a/src/platform/silabs/efr32/BUILD.gn +++ b/src/platform/silabs/efr32/BUILD.gn @@ -98,7 +98,7 @@ static_library("efr32") { "${chip_root}/src/platform:platform_base", "${chip_root}/src/platform/logging:headers", ] - deps = [] + deps = [ "${silabs_platform_dir}/provision:provision-headers" ] # Add platform crypto implementation if (chip_crypto == "platform") { @@ -136,8 +136,6 @@ static_library("efr32") { ] deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] } - - public_configs = [] } if (chip_enable_wifi) { @@ -160,7 +158,7 @@ static_library("efr32") { ] } - public_configs = [ ":efr32-platform-wifi-config" ] + public_configs += [ ":efr32-platform-wifi-config" ] } } diff --git a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp index 76673b001a9c6b..0881bea848112b 100644 --- a/src/platform/silabs/platformAbstraction/GsdkSpam.cpp +++ b/src/platform/silabs/platformAbstraction/GsdkSpam.cpp @@ -159,7 +159,19 @@ void sl_button_on_change(const sl_button_t * handle) } } } -#endif + +uint8_t SilabsPlatform::GetButtonState(uint8_t button) +{ + const sl_button_t * handle = SL_SIMPLE_BUTTON_INSTANCE(button); + return nullptr == handle ? 0 : sl_button_get_state(handle); +} + +#else +uint8_t SilabsPlatform::GetButtonState(uint8_t button) +{ + return 0; +} +#endif // SL_CATALOG_SIMPLE_BUTTON_PRESENT } // namespace Silabs } // namespace DeviceLayer diff --git a/src/platform/silabs/platformAbstraction/SilabsPlatform.h b/src/platform/silabs/platformAbstraction/SilabsPlatform.h index 4c42a79996b3f0..49f5264cac0550 100644 --- a/src/platform/silabs/platformAbstraction/SilabsPlatform.h +++ b/src/platform/silabs/platformAbstraction/SilabsPlatform.h @@ -48,10 +48,12 @@ class SilabsPlatform : virtual public SilabsPlatformAbstractionBase CHIP_ERROR ToggleLed(uint8_t led) override; #endif + // Buttons inline void SetButtonsCb(SilabsButtonCb callback) override { mButtonCallback = callback; } inline uint32_t GetRebootCause() { return mRebootCause; } static SilabsButtonCb mButtonCallback; + uint8_t GetButtonState(uint8_t button) override; void StartScheduler(void) override; diff --git a/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h b/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h index fa387228ab2885..12f87c07ea7e0d 100644 --- a/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h +++ b/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h @@ -43,6 +43,7 @@ class SilabsPlatformAbstractionBase // Buttons typedef void (*SilabsButtonCb)(uint8_t, uint8_t); virtual void SetButtonsCb(SilabsButtonCb callback) {} + virtual uint8_t GetButtonState(uint8_t button) { return 0; } // LEDS virtual void InitLed(void) {} diff --git a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp index 1d4456a53868d3..0bddafd96506f9 100644 --- a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp +++ b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -153,6 +154,11 @@ void sl_button_on_change(uint8_t btn, uint8_t btnAction) } } +uint8_t SilabsPlatform::GetButtonState(uint8_t button) +{ + return (button < SL_SI91x_BUTTON_COUNT) ? sButtonStates[button] : 0; +} + } // namespace Silabs } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/silabs/provision/AttestationKey.h b/src/platform/silabs/provision/AttestationKey.h new file mode 100644 index 00000000000000..5f7930bb0528e1 --- /dev/null +++ b/src/platform/silabs/provision/AttestationKey.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +static constexpr uint32_t kCreds_KeyId_Default = 2; //(PSA_KEY_ID_USER_MIN + 1); + +class AttestationKey +{ +public: + AttestationKey(uint32_t id = 0) { mId = (id > 0) ? id : kCreds_KeyId_Default; } + ~AttestationKey() = default; + + uint32_t GetId() { return mId; } + CHIP_ERROR Import(const uint8_t * asn1, size_t size); + CHIP_ERROR Export(uint8_t * asn1, size_t max, size_t & size); + CHIP_ERROR GenerateCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr); + CHIP_ERROR SignMessage(const ByteSpan & message, MutableByteSpan & out_span); + +protected: + uint32_t mId = 0; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/BUILD.gn b/src/platform/silabs/provision/BUILD.gn new file mode 100644 index 00000000000000..ea5d4b072a03ac --- /dev/null +++ b/src/platform/silabs/provision/BUILD.gn @@ -0,0 +1,38 @@ +# 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. + +import("//build_overrides/chip.gni") +import("//build_overrides/efr32_sdk.gni") +import("${efr32_sdk_build_root}/silabs_board.gni") + +config("provision-config") { + include_dirs = [ "." ] + + defines = [ "CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS=1" ] + if (use_provision_channel) { + defines += [ "SL_MATTER_PROVISION_CHANNEL_ENABLED=1" ] + } +} + +source_set("provision-headers") { + sources = [ + "AttestationKey.h", + "ProvisionChannel.h", + "ProvisionEncoder.h", + "ProvisionManager.h", + "ProvisionProtocol.h", + "ProvisionStorage.h", + ] + public_configs = [ ":provision-config" ] +} diff --git a/src/platform/silabs/provision/ProvisionChannel.h b/src/platform/silabs/provision/ProvisionChannel.h new file mode 100644 index 00000000000000..a15b4364a88092 --- /dev/null +++ b/src/platform/silabs/provision/ProvisionChannel.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#pragma once + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +class Channel +{ +public: + Channel() = default; + ~Channel() = default; + + CHIP_ERROR Init(); + CHIP_ERROR Read(uint8_t * buffer, size_t buffer_length, size_t & bytes_read); + CHIP_ERROR Write(const uint8_t * buffer, size_t buffer_length); + + static CHIP_ERROR Update(uint16_t handle); +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionEncoder.h b/src/platform/silabs/provision/ProvisionEncoder.h new file mode 100644 index 00000000000000..0c5a5e2bfe22ca --- /dev/null +++ b/src/platform/silabs/provision/ProvisionEncoder.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { +namespace Encoding { + +struct Buffer +{ + Buffer(uint8_t * ptr, size_t size, bool at_end = false) { Init(ptr, size, at_end); } + + void Init(uint8_t * ptr, size_t size, bool at_end = false) + { + this->begin = ptr; + this->end = ptr + size; + this->in = at_end ? end : begin; + this->out = ptr; + } + + void Clear() { this->in = this->out = this->begin; } + size_t Limit() { return (this->end > this->begin) ? (this->end - this->begin) : 0; } + size_t Size() { return (this->in > this->begin) ? (this->in - this->begin) : 0; } + size_t Offset() { return (this->out > this->begin) ? (this->out - this->begin) : 0; } + size_t Left() { return this->Size() - this->Offset(); } + size_t Spare() { return this->Limit() - this->Size(); } + + CHIP_ERROR Add(uint8_t in); + CHIP_ERROR Add(uint16_t in); + CHIP_ERROR Add(uint32_t in); + CHIP_ERROR Add(int32_t in); + CHIP_ERROR Add(const uint8_t * in, size_t size); + CHIP_ERROR Add(Buffer & from, size_t size); + CHIP_ERROR Get(uint8_t & out); + CHIP_ERROR Get(uint16_t & out); + CHIP_ERROR Get(uint32_t & out); + CHIP_ERROR Get(uint8_t * out, size_t size); + CHIP_ERROR Get(Buffer & into, size_t size); + + uint8_t * begin = nullptr; + uint8_t * end = nullptr; + uint8_t * in = nullptr; + uint8_t * out = nullptr; +}; + +//------------------------------------------------------------------------------ +// Version 1 +//------------------------------------------------------------------------------ +#ifdef SILABS_PROVISION_PROTOCOL_V1 + +namespace Version1 { + +enum Types : uint8_t +{ + Type_None = 0x00, + Type_Int8u = 0x01, + Type_Int16u = 0x02, + Type_Int32u = 0x03, + Type_Array = 0x04, +}; + +CHIP_ERROR Encode(Buffer & arg, uint8_t in); +CHIP_ERROR Encode(Buffer & arg, uint16_t in); +CHIP_ERROR Encode(Buffer & arg, int32_t in); +CHIP_ERROR Encode(Buffer & arg, uint32_t in); +CHIP_ERROR Encode(Buffer & arg, const uint8_t * in, size_t size); +CHIP_ERROR Encode(Buffer & arg, const char * in); + +CHIP_ERROR Decode(Buffer & arg, uint8_t & out); +CHIP_ERROR Decode(Buffer & arg, uint16_t & out); +CHIP_ERROR Decode(Buffer & arg, uint32_t & out); +CHIP_ERROR Decode(Buffer & arg, uint8_t * out, size_t limit, size_t & size); +CHIP_ERROR Decode(Buffer & arg, char * out, size_t limit, size_t & size); + +namespace Legacy { +CHIP_ERROR DecodeInt8u(Encoding::Buffer & in, uint8_t & out); +CHIP_ERROR DecodeInt16u(Encoding::Buffer & in, uint16_t & out); +CHIP_ERROR DecodeInt32u(Encoding::Buffer & in, uint32_t & out); +} // namespace Legacy + +} // namespace Version1 + +#endif // SILABS_PROVISION_PROTOCOL_V1 + +//------------------------------------------------------------------------------ +// Version 2 +//------------------------------------------------------------------------------ + +namespace Version2 { + +enum Types : uint8_t +{ + Type_Binary = 0x00, + Type_Int8u = 0x01, + Type_Int16u = 0x02, + Type_Int32u = 0x03, + Type_Int64u = 0x04, + Type_String = 0x08, + Type_Int8s = 0x09, + Type_Int16s = 0x0a, + Type_Int32s = 0x0b, + Type_Int64s = 0x0c, +}; + +union Value +{ + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint32_t u64; + uint8_t * b; +}; + +struct Argument : public Buffer +{ + enum States : uint8_t + { + State_Flags = 1, + State_Size = 3, + State_Data = 4, + State_Ready = 5, + }; + + Argument(uint8_t * ptr, size_t size) : Buffer(ptr, size) { Reset(); } + + void Reset() + { + this->Clear(); + this->state = State_Flags; + this->id = 0; + this->type = 0; + this->size = 0; + this->size_len = 0; + this->encoded_size = 0; + this->is_null = false; + this->is_binary = false; + this->is_known = false; + this->feedback = false; + this->offset = 0; + memset(&this->value, 0x00, sizeof(Value)); + } + + States state = State_Flags; + uint16_t id = 0; + uint8_t type = 0; + size_t size = 0; + uint8_t size_len = 0; + size_t encoded_size = 0; + bool is_null = false; + bool is_binary = false; + bool is_known = false; + bool feedback = false; + size_t offset = 0; + Value value; +}; + +CHIP_ERROR Encode(uint16_t id, uint8_t * value, Buffer & out); +CHIP_ERROR Encode(uint16_t id, uint16_t * value, Buffer & out); +CHIP_ERROR Encode(uint16_t id, uint32_t * value, Buffer & out); +CHIP_ERROR Encode(uint16_t id, const uint8_t * value, size_t size, Buffer & out); +CHIP_ERROR Decode(Buffer & in, Argument & arg); +CHIP_ERROR Find(Buffer & in, uint16_t id, Argument & arg); + +} // namespace Version2 + +} // namespace Encoding +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionManager.h b/src/platform/silabs/provision/ProvisionManager.h new file mode 100644 index 00000000000000..c73e920c345ce1 --- /dev/null +++ b/src/platform/silabs/provision/ProvisionManager.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#pragma once + +#include "ProvisionChannel.h" +#include "ProvisionProtocol.h" +#include "ProvisionStorage.h" +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +class Manager +{ +public: + Manager() : +#ifdef SILABS_PROVISION_PROTOCOL_V1 + mProtocol1(mStore), +#endif + mProtocol2(mStore) + {} + + CHIP_ERROR Init(); + bool Step(); + bool IsProvisionRequired(); + CHIP_ERROR SetProvisionRequired(bool required); + Storage & GetStorage() { return mStore; } + static Manager & GetInstance(); + +private: + bool ProcessCommand(ByteSpan & request, MutableByteSpan & response); + + Storage mStore; + Channel mChannel; +#ifdef SILABS_PROVISION_PROTOCOL_V1 + Protocol1 mProtocol1; +#endif + Protocol2 mProtocol2; + bool mProvisionRequested = true; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionProtocol.h b/src/platform/silabs/provision/ProvisionProtocol.h new file mode 100644 index 00000000000000..03182b59af0468 --- /dev/null +++ b/src/platform/silabs/provision/ProvisionProtocol.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#pragma once + +#include "ProvisionEncoder.h" +#include "ProvisionStorage.h" +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +//------------------------------------------------------------------------------ +// Common +//------------------------------------------------------------------------------ + +class Protocol +{ +public: + /** + * Must hold the header plus complete argument value + */ + Protocol(Storage & store) : mStore(store) {} + virtual ~Protocol() = default; + virtual bool Execute(ByteSpan & request, MutableByteSpan & response) = 0; + +protected: + Storage & mStore; +}; + +//------------------------------------------------------------------------------ +// Version 1 +//------------------------------------------------------------------------------ +#ifdef SILABS_PROVISION_PROTOCOL_V1 + +class Protocol1 : public Protocol +{ +public: + static constexpr size_t kVersion = 1; + + Protocol1(Storage & store) : Protocol(store) {} + virtual bool Execute(ByteSpan & request, MutableByteSpan & response); + +private: + CHIP_ERROR Init(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR GenerateCSR(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR Import(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR Setup(Encoding::Buffer & in, Encoding::Buffer & out); + CHIP_ERROR Read(Encoding::Buffer & in, Encoding::Buffer & out); +}; + +#endif // SILABS_PROVISION_PROTOCOL_V1 + +//------------------------------------------------------------------------------ +// Version 2 +//------------------------------------------------------------------------------ + +class Protocol2 : public Protocol +{ +public: + static constexpr uint8_t kVersion = 2; + // Command flags + static constexpr uint16_t kResponseFlag = 0x80; + // Payload flags + static constexpr uint16_t kCustomIdMin = 0x0000; + static constexpr uint16_t kCustomIdMax = 0x00ff; + static constexpr uint16_t kKnownIdMin = 0x0100; + static constexpr uint16_t kKnownIdMax = 0x01ff; + static constexpr uint16_t kIdMask = 0x01ff; + static constexpr uint16_t kWellKnownMask = 0x0100; + static constexpr uint16_t kSizeBit = 10; + static constexpr uint16_t kSizeMask = 0x0c00; + static constexpr uint16_t kFeedbackMask = 0x0200; + static constexpr uint16_t kTypeBit = 12; + static constexpr uint16_t kTypeMask = 0xf000; + // Limits + static constexpr size_t kPackageSizeMax = 128; + static constexpr size_t kChecksumSize = 2; + static constexpr size_t kRequestHeaderSize = 4; + static constexpr size_t kResponseHeaderSize = 8; + static_assert(kPackageSizeMax > (kResponseHeaderSize + kChecksumSize)); + + Protocol2(Storage & store) : Protocol(store) {} + virtual bool Execute(ByteSpan & request, MutableByteSpan & response); +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionStorage.h b/src/platform/silabs/provision/ProvisionStorage.h new file mode 100644 index 00000000000000..3dbc78076442a7 --- /dev/null +++ b/src/platform/silabs/provision/ProvisionStorage.h @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#pragma once + +#include "ProvisionStorageGeneric.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +namespace Parameters { + +enum ID : uint16_t +{ + // Internal, + kFlashAddress = 0x0101, + kFlashSize = 0x0102, + kFlashPageSize = 0x0103, + kBaseAddress = 0x0104, + kCsrFile = 0x0105, + // Options, + kVersion = 0x0111, + kAction = 0x0112, + kExtra = 0x0113, + kStop = 0x0114, + kParamsPath = 0x0121, + kInputsPath = 0x0122, + kOutputPath = 0x0123, + kTemporaryDir = 0x0124, + kTargetDevice = 0x0131, + kChannel = 0x0132, + kGenerateCreds = 0x0133, + kCsrMode = 0x0134, + kGeneratorFW = 0x0135, + kProductionFW = 0x0136, + kCertToolPath = 0x0137, + kPylinkLib = 0x0138, + // Instance Info, + kSerialNumber = 0x0141, + kVendorId = 0x0142, + kVendorName = 0x0143, + kProductId = 0x0144, + kProductName = 0x0145, + kProductLabel = 0x0146, + kProductUrl = 0x0147, + kPartNumber = 0x0148, + kHwVersion = 0x0151, + kHwVersionStr = 0x0152, + kManufacturingDate = 0x0153, + kUniqueId = 0x0154, + // Commissionable Data, + kDiscriminator = 0x0161, + kSpake2pPasscode = 0x0162, + kSpake2pIterations = 0x0163, + kSpake2pSalt = 0x0164, + kSpake2pVerifier = 0x0165, + kSetupPayload = 0x0166, + kCommissioningFlow = 0x0167, + kRendezvousFlags = 0x0168, + // Attestation Credentials, + kFirmwareInfo = 0x0181, + kCertification = 0x0182, + kCdCert = 0x0183, + kCdKey = 0x0184, + kPaaCert = 0x0191, + kPaaKey = 0x0192, + kPaiCert = 0x0193, + kPaiKey = 0x0194, + kDacCert = 0x0195, + kDacKey = 0x0196, + kKeyId = 0x0197, + kKeyPass = 0x0198, + kPKCS12 = 0x0199, + kCommonName = 0x01a1, + kOtaTlvEncryptionKey = 0x01a2, +}; + +} // namespace Parameters + +struct CustomStorage : public GenericStorage +{ + CHIP_ERROR Set(uint16_t id, const uint8_t * value) override; + CHIP_ERROR Get(uint16_t id, uint8_t & value) override; + CHIP_ERROR Set(uint16_t id, const uint16_t * value) override; + CHIP_ERROR Get(uint16_t id, uint16_t & value) override; + CHIP_ERROR Set(uint16_t id, const uint32_t * value) override; + CHIP_ERROR Get(uint16_t id, uint32_t & value) override; + CHIP_ERROR Set(uint16_t id, const uint64_t * value) override; + CHIP_ERROR Get(uint16_t id, uint64_t & value) override; + CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) override; + CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) override; +}; + +namespace { +constexpr size_t kVersionFieldLengthInBits = 3; +constexpr size_t kVendorIDFieldLengthInBits = 16; +constexpr size_t kProductIDFieldLengthInBits = 16; +constexpr size_t kCommissioningFlowFieldLengthInBits = 2; +constexpr size_t kRendezvousInfoFieldLengthInBits = 8; +constexpr size_t kPayloadDiscriminatorFieldLengthInBits = 12; +constexpr size_t kSetupPINCodeFieldLengthInBits = 27; +constexpr size_t kPaddingFieldLengthInBits = 4; +} // namespace + +struct Storage : public GenericStorage, + public chip::DeviceLayer::DeviceInstanceInfoProvider, + public chip::DeviceLayer::CommissionableDataProvider, + public chip::Credentials::DeviceAttestationCredentialsProvider +{ + static constexpr size_t kArgumentSizeMax = 512; + static constexpr size_t kVersionLengthMax = 16; + static constexpr size_t kSerialNumberLengthMax = 32; + static constexpr size_t kVendorNameLengthMax = 32; + static constexpr size_t kProductNameLengthMax = 32; + static constexpr size_t kProductLabelLengthMax = 32; + static constexpr size_t kProductUrlLengthMax = 32; + static constexpr size_t kPartNumberLengthMax = 32; + static constexpr size_t kHardwareVersionStrLengthMax = 32; + static constexpr size_t kManufacturingDateLengthMax = 11; // yyyy-mm-dd + \0 + static constexpr size_t kUniqueIdLengthMax = 16; + static constexpr size_t kSpake2pVerifierB64LengthMax = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; + static constexpr size_t kSpake2pSaltB64LengthMax = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; + static constexpr size_t kFirmwareInfoSizeMax = 32; + static constexpr size_t kCertificationSizeMax = 350; + static constexpr size_t kCertificateSizeMax = kArgumentSizeMax; + static constexpr size_t kDeviceAttestationKeySizeMax = 128; + static constexpr size_t kSetupPayloadSizeMax = 32; + static constexpr size_t kCsrLengthMax = 512; + static constexpr size_t kCommonNameMax = 128; + static constexpr size_t kTotalPayloadDataSizeInBits = + (kVersionFieldLengthInBits + kVendorIDFieldLengthInBits + kProductIDFieldLengthInBits + + kCommissioningFlowFieldLengthInBits + kRendezvousInfoFieldLengthInBits + kPayloadDiscriminatorFieldLengthInBits + + kSetupPINCodeFieldLengthInBits + kPaddingFieldLengthInBits); + static constexpr size_t kTotalPayloadDataSize = kTotalPayloadDataSizeInBits / 8; + +public: + static uint8_t aux_buffer[Storage::kArgumentSizeMax]; + + friend class Manager; + friend class Protocol1; + friend class Command; + friend class CsrCommand; + friend class ReadCommand; + friend class WriteCommand; + + // + // Initialization + // + + CHIP_ERROR Initialize(uint32_t flash_addr = 0, uint32_t flash_size = 0); + CHIP_ERROR Commit(); + CHIP_ERROR GetBaseAddress(uint32_t & value); + + // + // Generic Interface + // + + CHIP_ERROR Get(uint16_t id, uint8_t & value) override; + CHIP_ERROR Get(uint16_t id, uint16_t & value) override; + CHIP_ERROR Get(uint16_t id, uint32_t & value) override; + CHIP_ERROR Get(uint16_t id, uint64_t & value) override; + CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) override; + + // + // DeviceInstanceInfoProvider + // + + CHIP_ERROR GetSerialNumber(char * value, size_t max); + CHIP_ERROR GetVendorId(uint16_t & value); + CHIP_ERROR GetVendorName(char * value, size_t max); + CHIP_ERROR GetProductId(uint16_t & productId); + CHIP_ERROR GetProductName(char * value, size_t max); + CHIP_ERROR GetProductLabel(char * value, size_t max); + CHIP_ERROR GetProductURL(char * value, size_t max); + CHIP_ERROR GetPartNumber(char * value, size_t max); + CHIP_ERROR GetHardwareVersion(uint16_t & value); + CHIP_ERROR GetHardwareVersionString(char * value, size_t max); + CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day); + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & value); + + // + // CommissionableDataProvider + // + + CHIP_ERROR GetSetupDiscriminator(uint16_t & value); + CHIP_ERROR GetSpake2pIterationCount(uint32_t & value); + CHIP_ERROR GetSetupPasscode(uint32_t & value); + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & value); + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & value, size_t & size); + + // + // DeviceAttestationCredentialsProvider + // + + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & value); + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & value); + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & value); + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & value); + CHIP_ERROR GetDeviceAttestationCSR(uint16_t vid, uint16_t pid, const CharSpan & cn, MutableCharSpan & csr); + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message, MutableByteSpan & signature); + + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & value); + CHIP_ERROR SetProductAttestationIntermediateCert(const ByteSpan & value); + CHIP_ERROR SetDeviceAttestationCert(const ByteSpan & value); + CHIP_ERROR SetDeviceAttestationKey(const ByteSpan & value); + // + // Other + // + + CHIP_ERROR GetSetupPayload(chip::MutableCharSpan & value); + CHIP_ERROR SetProvisionRequest(bool value); + CHIP_ERROR GetProvisionRequest(bool & value); + CHIP_ERROR GetTestEventTriggerKey(MutableByteSpan & keySpan); + +private: + // Generic Interface + CHIP_ERROR Set(uint16_t id, const uint8_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint16_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint32_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint64_t * value) override; + CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) override; + // DeviceInstanceInfoProvider + CHIP_ERROR SetSerialNumber(const char * value, size_t len); + CHIP_ERROR SetVendorId(uint16_t value); + CHIP_ERROR SetVendorName(const char * value, size_t len); + CHIP_ERROR SetProductId(uint16_t productId); + CHIP_ERROR SetProductName(const char * value, size_t len); + CHIP_ERROR SetProductLabel(const char * value, size_t len); + CHIP_ERROR SetProductURL(const char * value, size_t len); + CHIP_ERROR SetPartNumber(const char * value, size_t len); + CHIP_ERROR SetHardwareVersion(uint16_t value); + CHIP_ERROR SetHardwareVersionString(const char * value, size_t len); + CHIP_ERROR SetManufacturingDate(const char * value, size_t len); + CHIP_ERROR GetManufacturingDate(uint8_t * value, size_t max, size_t & size); + CHIP_ERROR SetUniqueId(const uint8_t * value, size_t size); + CHIP_ERROR GetUniqueId(uint8_t * value, size_t max, size_t & size); + // CommissionableDataProvider + CHIP_ERROR SetSetupDiscriminator(uint16_t value); + CHIP_ERROR SetSpake2pIterationCount(uint32_t value); + CHIP_ERROR SetSetupPasscode(uint32_t value); + CHIP_ERROR SetSpake2pSalt(const char * value, size_t size); + CHIP_ERROR GetSpake2pSalt(char * value, size_t max, size_t & size); + CHIP_ERROR SetSpake2pVerifier(const char * value, size_t size); + CHIP_ERROR GetSpake2pVerifier(char * value, size_t max, size_t & size); + // DeviceAttestationCredentialsProvider + CHIP_ERROR SetFirmwareInformation(const ByteSpan & value); + + // Other + CHIP_ERROR SetProvisionVersion(const char * value, size_t len); + CHIP_ERROR GetProvisionVersion(char * value, size_t max, size_t & size); + CHIP_ERROR SetSetupPayload(const uint8_t * value, size_t size); + CHIP_ERROR GetSetupPayload(uint8_t * value, size_t max, size_t & size); +#if OTA_ENCRYPTION_ENABLE + CHIP_ERROR SetOtaTlvEncryptionKey(const ByteSpan & value); +#endif + + uint16_t mVendorId = 0; + uint16_t mProductId = 0; + uint16_t mHwVersion = 0; + uint16_t mDiscriminator = 0; // 12-bit + uint32_t mCommissioningFlow = 0; + uint32_t mRendezvousFlags = 0; + uint32_t mPasscode = 0; + uint32_t mKeyId = 0; + char mCommonName[kCommonNameMax] = { 0 }; + CustomStorage mCustom; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/provision/ProvisionStorageGeneric.h b/src/platform/silabs/provision/ProvisionStorageGeneric.h new file mode 100644 index 00000000000000..6c3cdc2c42a39f --- /dev/null +++ b/src/platform/silabs/provision/ProvisionStorageGeneric.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * 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. + */ +#pragma once + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace Provision { + +struct GenericStorage +{ + virtual ~GenericStorage() = default; + + virtual CHIP_ERROR Set(uint16_t id, const uint8_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint8_t & value) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint16_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint16_t & value) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint32_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint32_t & value) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint64_t * value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint64_t & value) = 0; + virtual CHIP_ERROR Get(uint16_t id, uint8_t * value, size_t max_size, size_t & size) = 0; + virtual CHIP_ERROR Set(uint16_t id, const uint8_t * value, size_t size) = 0; +}; + +} // namespace Provision +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index ad0c1a22d270d3..947ed482f4622e 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -70,6 +70,8 @@ silabs_executable("efr32_device_tests") { "${chip_root}/examples/common/pigweed/RpcService.cpp", "${chip_root}/examples/common/pigweed/efr32/PigweedLoggerMutex.cpp", "${examples_common_plat_dir}/PigweedLogger.cpp", + "${examples_common_plat_dir}/provision/ProvisionStorageCustom.cpp", + "${examples_common_plat_dir}/provision/ProvisionStorageDefault.cpp", "${examples_common_plat_dir}/syscalls_stubs.cpp", "${examples_plat_dir}/uart.cpp", "src/main.cpp", @@ -84,6 +86,7 @@ silabs_executable("efr32_device_tests") { "${chip_root}/src:tests", "${chip_root}/src/lib", "${chip_root}/src/lib/support:pw_tests_wrapper", + "${chip_root}/src/platform/silabs/provision:provision-headers", "${examples_common_plat_dir}/pw_sys_io:pw_sys_io_silabs", ] @@ -96,16 +99,12 @@ silabs_executable("efr32_device_tests") { ] } - # Attestation Credentials - deps += [ "${examples_plat_dir}:efr32-attestation-credentials" ] - - # Factory Data Provider - if (use_efr32_factory_data_provider) { - deps += [ "${examples_plat_dir}:silabs-factory-data-provider" ] - } - deps += pw_build_LINK_DEPS + libs = [ + "${sdk_support_root}/matter/provision/lib/libProvision_${silabs_family}.a", + ] + include_dirs = [ "${chip_root}/examples/common/pigweed/efr32" ] ldscript = "${examples_common_plat_dir}/ldscripts/${silabs_family}.ld" diff --git a/src/test_driver/efr32/src/main.cpp b/src/test_driver/efr32/src/main.cpp index 010d6b4bc0639b..088dc4e8703664 100644 --- a/src/test_driver/efr32/src/main.cpp +++ b/src/test_driver/efr32/src/main.cpp @@ -22,9 +22,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -38,7 +38,8 @@ #include #include -#include "SilabsDeviceDataProvider.h" +using namespace chip; +using namespace chip::DeviceLayer; extern "C" int printf(const char * format, ...) { @@ -91,16 +92,18 @@ void RunRpcService(void *) int main(void) { sl_system_init(); - chip::DeviceLayer::Silabs::GetPlatform().Init(); + Silabs::GetPlatform().Init(); PigweedLogger::init(); mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); - chip::Platform::MemoryInit(); + Platform::MemoryInit(); + PlatformMgr().InitChipStack(); - chip::DeviceLayer::PlatformMgr().InitChipStack(); - // required for inits tied to the event loop - chip::DeviceLayer::SetDeviceInstanceInfoProvider(&chip::DeviceLayer::Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); - chip::DeviceLayer::SetCommissionableDataProvider(&chip::DeviceLayer::Silabs::SilabsDeviceDataProvider::GetDeviceDataProvider()); + // Init Provision Manager and provider instanaces. Required for inits tied to the event loop + Silabs::Provision::Manager & provision = Silabs::Provision::Manager::GetInstance(); + provision.Init(); + SetDeviceInstanceInfoProvider(&provision.GetStorage()); + SetCommissionableDataProvider(&provision.GetStorage()); SILABS_LOG("***** CHIP EFR32 device tests *****\r\n"); diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index 2862f9bc9d09f6..ddda1e68b7f4b7 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -491,6 +491,7 @@ template("siwx917_sdk") { "${chip_root}/third_party/mbedtls/repo/library/aes.c", "${chip_root}/third_party/mbedtls/repo/library/asn1parse.c", "${chip_root}/third_party/mbedtls/repo/library/asn1write.c", + "${chip_root}/third_party/mbedtls/repo/library/base64.c", "${chip_root}/third_party/mbedtls/repo/library/bignum.c", "${chip_root}/third_party/mbedtls/repo/library/ccm.c", "${chip_root}/third_party/mbedtls/repo/library/cipher.c", @@ -505,10 +506,12 @@ template("siwx917_sdk") { "${chip_root}/third_party/mbedtls/repo/library/hkdf.c", "${chip_root}/third_party/mbedtls/repo/library/hmac_drbg.c", "${chip_root}/third_party/mbedtls/repo/library/md.c", + "${chip_root}/third_party/mbedtls/repo/library/pem.c", "${chip_root}/third_party/mbedtls/repo/library/pkcs5.c", "${chip_root}/third_party/mbedtls/repo/library/platform.c", "${chip_root}/third_party/mbedtls/repo/library/sha256.c", "${chip_root}/third_party/mbedtls/repo/library/sha512.c", + "${chip_root}/third_party/mbedtls/repo/library/x509.c", "${chip_root}/third_party/mbedtls/repo/library/x509_create.c", "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream.c", "${efr32_sdk_root}/platform/service/iostream/src/sl_iostream_rtt.c", @@ -588,10 +591,8 @@ template("siwx917_sdk") { } if (invoker.enable_dic) { sources += [ - "${chip_root}/third_party/mbedtls/repo/library/base64.c", "${chip_root}/third_party/mbedtls/repo/library/debug.c", "${chip_root}/third_party/mbedtls/repo/library/ecjpake.c", - "${chip_root}/third_party/mbedtls/repo/library/pem.c", "${chip_root}/third_party/mbedtls/repo/library/rsa.c", "${chip_root}/third_party/mbedtls/repo/library/rsa_internal.c", "${chip_root}/third_party/mbedtls/repo/library/sha1.c", @@ -600,14 +601,10 @@ template("siwx917_sdk") { "${chip_root}/third_party/mbedtls/repo/library/ssl_msg.c", "${chip_root}/third_party/mbedtls/repo/library/ssl_srv.c", "${chip_root}/third_party/mbedtls/repo/library/ssl_tls.c", - "${chip_root}/third_party/mbedtls/repo/library/x509.c", "${chip_root}/third_party/silabs/mqtt/stack/mqtt.c", ] } - public_configs = [ - ":${sdk_target_name}_config", - "${examples_plat_dir}:siwx917-common-config", - ] + public_configs = [ ":${sdk_target_name}_config" ] } } diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index a1fdd62cb16804..96fc0a37ecb2e6 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit a1fdd62cb168049f946f7e1b5399c39353bcd7b4 +Subproject commit 96fc0a37ecb2e6791f57d62d5619db65d870ae4a From 7a9eed6296c7f2115a277f9d30301d7dc0332651 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 26 Jun 2024 17:36:48 +0000 Subject: [PATCH 2/6] Restyled by clang-format --- examples/platform/silabs/BaseApplication.cpp | 2 +- examples/platform/silabs/MatterConfig.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index 21150e2fd52d1a..fd22a7ea3a48fc 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -38,12 +38,12 @@ #if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 #include // nogncheck #endif +#include #include #include #include #include #include -#include #include #include #include diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index fd1a7954cbe4b9..70f759c0e35903 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -56,9 +56,9 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeystore; #endif +#include #include #include -#include #ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED #include "SilabsTestEventTriggerDelegate.h" // nogncheck From c5690e8116585bfb7710cd219424e97f402c5309 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:50:30 -0400 Subject: [PATCH 3/6] remove files that are now used --- .../silabs/SilabsDeviceAttestationCreds.cpp | 199 --------- .../silabs/SilabsDeviceAttestationCreds.h | 38 -- .../silabs/SilabsDeviceDataProvider.cpp | 416 ------------------ .../silabs/SilabsDeviceDataProvider.h | 72 --- 4 files changed, 725 deletions(-) delete mode 100644 examples/platform/silabs/SilabsDeviceAttestationCreds.cpp delete mode 100644 examples/platform/silabs/SilabsDeviceAttestationCreds.h delete mode 100644 examples/platform/silabs/SilabsDeviceDataProvider.cpp delete mode 100644 examples/platform/silabs/SilabsDeviceDataProvider.h diff --git a/examples/platform/silabs/SilabsDeviceAttestationCreds.cpp b/examples/platform/silabs/SilabsDeviceAttestationCreds.cpp deleted file mode 100644 index 60785413070382..00000000000000 --- a/examples/platform/silabs/SilabsDeviceAttestationCreds.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * - * Copyright (c) 2022 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 "SilabsDeviceAttestationCreds.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "silabs_creds.h" - -using namespace chip::DeviceLayer::Internal; - -using chip::DeviceLayer::Internal::SilabsConfig; - -namespace chip { -namespace Credentials { -namespace Silabs { - -namespace { - -class DeviceAttestationCredsSilabs : public DeviceAttestationCredentialsProvider -{ - // Miss-aligned certificates is a common error, and printing the first few bytes is - // useful to verify proper alignment. Eight bytes is enough for this purpose. - static constexpr size_t kDebugLength = 8; - -public: - CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_Base_Addr)) - { - // Provisioned CD - return GetFile("GetCertificationDeclaration", SilabsConfig::kConfigKey_Creds_CD_Offset, SILABS_CREDENTIALS_CD_OFFSET, - SilabsConfig::kConfigKey_Creds_CD_Size, SILABS_CREDENTIALS_CD_SIZE, out_span); - } - else - { - // Example CD - return Examples::GetExampleDACProvider()->GetCertificationDeclaration(out_span); - } - } - - CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override - { - // TODO: We need a real example FirmwareInformation to be populated. - out_firmware_info_buffer.reduce_size(0); - return CHIP_NO_ERROR; - } - - CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_Base_Addr)) - { - // Provisioned DAC - return GetFile("GetDeviceAttestationCert", SilabsConfig::kConfigKey_Creds_DAC_Offset, SILABS_CREDENTIALS_DAC_OFFSET, - SilabsConfig::kConfigKey_Creds_DAC_Size, SILABS_CREDENTIALS_DAC_SIZE, out_span); - } - else - { - // Example DAC - return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(out_span); - } - } - - CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_Base_Addr)) - { - // Provisioned PAI - return GetFile("GetProductAttestationIntermediateCert", SilabsConfig::kConfigKey_Creds_PAI_Offset, - SILABS_CREDENTIALS_PAI_OFFSET, SilabsConfig::kConfigKey_Creds_PAI_Size, SILABS_CREDENTIALS_PAI_SIZE, - out_span); - } - else - { - // Example PAI - return Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(out_span); - } - } - - CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_span) override - { - if (SilabsConfig::ConfigValueExists(SilabsConfig::kConfigKey_Creds_KeyId)) - { - // Provisioned DAC key -#ifdef SLI_SI91X_MCU_INTERFACE - return CHIP_ERROR_NOT_IMPLEMENTED; -#else - uint32_t key_id = SILABS_CREDENTIALS_DAC_KEY_ID; - uint8_t signature[64] = { 0 }; - size_t signature_size = sizeof(signature); - - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_KeyId, key_id)); - - ChipLogProgress(DeviceLayer, "SignWithDeviceAttestationKey, key:%lu", key_id); - - psa_status_t err = - psa_sign_message(static_cast(key_id), PSA_ALG_ECDSA(PSA_ALG_SHA_256), message_to_sign.data(), - message_to_sign.size(), signature, signature_size, &signature_size); - VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL); - - return CopySpanToMutableSpan(ByteSpan(signature, signature_size), out_span); -#endif - } - else - { - // Example DAC key - return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message_to_sign, out_span); - } - } - -private: - CHIP_ERROR GetFile(const char * description, uint32_t offset_key, uint32_t offset_default, uint32_t size_key, - uint32_t size_default, MutableByteSpan & out_span) - { - uint32_t base_addr = 0; - uint8_t * address = nullptr; - uint32_t offset = offset_default; - uint32_t size = size_default; - - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, base_addr)); - - // Offset - if (SilabsConfig::ConfigValueExists(offset_key)) - { - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(offset_key, offset)); - } - address = (uint8_t *) (base_addr + offset); - - // Size - if (SilabsConfig::ConfigValueExists(size_key)) - { - ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(size_key, size)); - } - - ByteSpan span(address, size); - ChipLogProgress(DeviceLayer, "%s, addr:%p, size:%lu", description, address, size); - ChipLogByteSpan(DeviceLayer, ByteSpan(span.data(), kDebugLength > span.size() ? span.size() : kDebugLength)); - return CopySpanToMutableSpan(span, out_span); - } -}; - -} // namespace - -DeviceAttestationCredentialsProvider * GetSilabsDacProvider() -{ - static DeviceAttestationCredsSilabs dac_provider; - return &dac_provider; -} - -} // namespace Silabs -} // namespace Credentials - -namespace DeviceLayer { -namespace Silabs { - -void MigrateDacProvider(void) -{ - constexpr uint32_t kOldKey_Creds_KeyId = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x21); - constexpr uint32_t kOldKey_Creds_Base_Addr = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x22); - constexpr uint32_t kOldKey_Creds_DAC_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x23); - constexpr uint32_t kOldKey_Creds_DAC_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x24); - constexpr uint32_t kOldKey_Creds_PAI_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x25); - constexpr uint32_t kOldKey_Creds_PAI_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x26); - constexpr uint32_t kOldKey_Creds_CD_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x27); - constexpr uint32_t kOldKey_Creds_CD_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x28); - - MigrationManager::MigrateUint32(kOldKey_Creds_KeyId, SilabsConfig::kConfigKey_Creds_KeyId); - MigrationManager::MigrateUint32(kOldKey_Creds_Base_Addr, SilabsConfig::kConfigKey_Creds_Base_Addr); - MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_DAC_Size); - MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_PAI_Size); - MigrationManager::MigrateUint32(kOldKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD_Size); -} - -} // namespace Silabs -} // namespace DeviceLayer -} // namespace chip diff --git a/examples/platform/silabs/SilabsDeviceAttestationCreds.h b/examples/platform/silabs/SilabsDeviceAttestationCreds.h deleted file mode 100644 index 79f8f8df042aa8..00000000000000 --- a/examples/platform/silabs/SilabsDeviceAttestationCreds.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Copyright (c) 2022 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 - -namespace chip { -namespace Credentials { -namespace Silabs { - -/** - * @brief Get implementation of a sample DAC provider to validate device - * attestation procedure. - * - * @returns a singleton DeviceAttestationCredentialsProvider that relies on no - * storage abstractions. - */ -DeviceAttestationCredentialsProvider * GetSilabsDacProvider(); - -void SilabsDacProviderMigration(void); - -} // namespace Silabs -} // namespace Credentials -} // namespace chip diff --git a/examples/platform/silabs/SilabsDeviceDataProvider.cpp b/examples/platform/silabs/SilabsDeviceDataProvider.cpp deleted file mode 100644 index 7d80eaaafda2bd..00000000000000 --- a/examples/platform/silabs/SilabsDeviceDataProvider.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/* - * - * Copyright (c) 2022 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 "SilabsDeviceDataProvider.h" -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace chip { -namespace DeviceLayer { -namespace Silabs { - -// using namespace chip::Credentials; -using namespace chip::DeviceLayer::Internal; - -CHIP_ERROR SilabsDeviceDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) -{ - CHIP_ERROR err; - uint32_t setupDiscriminator32; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_SetupDiscriminator, setupDiscriminator32); -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - setupDiscriminator32 = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR - - VerifyOrReturnLogError(setupDiscriminator32 <= kMaxDiscriminatorValue, CHIP_ERROR_INVALID_ARGUMENT); - setupDiscriminator = static_cast(setupDiscriminator32); - return CHIP_NO_ERROR; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) -{ - CHIP_ERROR err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Spake2pIterationCount, iterationCount); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - iterationCount = CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT) && CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_ITERATION_COUNT - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) -{ - static constexpr size_t kSpake2pSalt_MaxBase64Len = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; - - CHIP_ERROR err = CHIP_NO_ERROR; - char saltB64[kSpake2pSalt_MaxBase64Len] = { 0 }; - size_t saltB64Len = 0; - - err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pSalt, saltB64, sizeof(saltB64), saltB64Len); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - saltB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT); - ReturnErrorCodeIf(saltB64Len > sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(saltB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT, saltB64Len); - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT) - - ReturnErrorOnFailure(err); - - uint8_t saltByteArray[kSpake2pSalt_MaxBase64Len] = { 0 }; - size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, saltByteArray); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - - memcpy(saltBuf.data(), saltByteArray, saltLen); - saltBuf.reduce_size(saltLen); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) -{ - static constexpr size_t kSpake2pSerializedVerifier_MaxBase64Len = - BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_VerifierSerialized_Length) + 1; - - CHIP_ERROR err = CHIP_NO_ERROR; - char verifierB64[kSpake2pSerializedVerifier_MaxBase64Len] = { 0 }; - size_t verifierB64Len = 0; - - err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_Spake2pVerifier, verifierB64, sizeof(verifierB64), - verifierB64Len); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - verifierB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER); - ReturnErrorCodeIf(verifierB64Len > sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(verifierB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER, verifierB64Len); - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) - - ReturnErrorOnFailure(err); - - verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - - memcpy(verifierBuf.data(), verifierB64, verifierLen); - verifierBuf.reduce_size(verifierLen); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSetupPayload(MutableCharSpan & payloadBuf) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - uint8_t payloadBitSet[kTotalPayloadDataSizeInBytes] = { 0 }; - size_t bitSetLen = 0; - - err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_SetupPayloadBitSet, payloadBitSet, kTotalPayloadDataSizeInBytes, - bitSetLen); - -#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - static constexpr uint8_t kTestSetupPayloadBitset[] = { 0x88, 0xFF, 0x2F, 0x00, 0x44, 0x00, 0xE0, 0x4B, 0x84, 0x68, 0x02 }; - bitSetLen = sizeof(kTestSetupPayloadBitset); - ReturnErrorCodeIf(bitSetLen > kTotalPayloadDataSizeInBytes, CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(payloadBitSet, kTestSetupPayloadBitset, bitSetLen); - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) - - ReturnErrorOnFailure(err); - - size_t prefixLen = strlen(kQRCodePrefix); - - if (payloadBuf.size() < prefixLen + 1) - { - err = CHIP_ERROR_BUFFER_TOO_SMALL; - } - else - { - MutableCharSpan subSpan = payloadBuf.SubSpan(prefixLen, payloadBuf.size() - prefixLen); - memcpy(payloadBuf.data(), kQRCodePrefix, prefixLen); - err = base38Encode(MutableByteSpan(payloadBitSet), subSpan); - // Reduce output span size to be the size of written data - payloadBuf.reduce_size(subSpan.size() + prefixLen); - } - - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetVendorName(char * buf, size_t bufSize) -{ - size_t vendorNameLen = 0; // without counting null-terminator - CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_VendorName, buf, bufSize, vendorNameLen); -#if defined(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - VerifyOrReturnError(buf != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(bufSize > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); - Platform::CopyString(buf, bufSize, CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME); - err = CHIP_NO_ERROR; - } -#endif - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetVendorId(uint16_t & vendorId) -{ - ChipError err = CHIP_NO_ERROR; - uint32_t vendorId32 = 0; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_VendorId, vendorId32); - -#if defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - vendorId32 = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID) && CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID - - ReturnErrorOnFailure(err); - vendorId = static_cast(vendorId32); - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductName(char * buf, size_t bufSize) -{ - size_t productNameLen = 0; // without counting null-terminator - CHIP_ERROR err = SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductName, buf, bufSize, productNameLen); -#if defined(CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - VerifyOrReturnError(buf != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(bufSize > strlen(CHIP_DEVICE_CONFIG_TEST_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); - Platform::CopyString(buf, bufSize, CHIP_DEVICE_CONFIG_TEST_PRODUCT_NAME); - err = CHIP_NO_ERROR; - } -#endif - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductId(uint16_t & productId) -{ - ChipError err = CHIP_NO_ERROR; - uint32_t productId32 = 0; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_ProductId, productId32); - -#if defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - productId32 = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID) && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID - ReturnErrorOnFailure(err); - - productId = static_cast(productId32); - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) -{ - size_t hardwareVersionStringLen = 0; // without counting null-terminator - CHIP_ERROR err = - SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_HardwareVersionString, buf, bufSize, hardwareVersionStringLen); -#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - VerifyOrReturnError(buf != nullptr, CHIP_ERROR_NO_MEMORY); - VerifyOrReturnError(bufSize > strlen(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), - CHIP_ERROR_BUFFER_TOO_SMALL); - Platform::CopyString(buf, bufSize, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); - err = CHIP_NO_ERROR; - } -#endif // CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) -{ - CHIP_ERROR err; - uint32_t hardwareVersion32; - - err = SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_HardwareVersion, hardwareVersion32); -#if defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - hardwareVersion32 = CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION; - err = CHIP_NO_ERROR; - } -#endif // defined(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION) - - hardwareVersion = static_cast(hardwareVersion32); - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) -{ - ChipError err = CHIP_ERROR_WRONG_KEY_TYPE; -#if CHIP_ENABLE_ROTATING_DEVICE_ID - static_assert(ConfigurationManager::kRotatingDeviceIDUniqueIDLength >= ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength, - "Length of unique ID for rotating device ID is smaller than minimum."); - - size_t uniqueIdLen = 0; - err = - SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_UniqueId, uniqueIdSpan.data(), uniqueIdSpan.size(), uniqueIdLen); -#ifdef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); - uniqueIdLen = sizeof(uniqueId); - } -#endif // CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID - - ReturnErrorOnFailure(err); - uniqueIdSpan.reduce_size(uniqueIdLen); - -#endif // CHIP_ENABLE_ROTATING_DEVICE_ID - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetSerialNumber(char * buf, size_t bufSize) -{ - size_t serialNumberLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_SerialNum, buf, bufSize, serialNumberLen); -} - -CHIP_ERROR SilabsDeviceDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) -{ - CHIP_ERROR err; - constexpr uint8_t kDateStringLength = 10; // YYYY-MM-DD - char dateStr[kDateStringLength + 1]; - size_t dateLen; - char * parseEnd; - - err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_ManufacturingDate, reinterpret_cast(dateStr), - sizeof(dateStr), dateLen); - SuccessOrExit(err); - - VerifyOrExit(dateLen == kDateStringLength, err = CHIP_ERROR_INVALID_ARGUMENT); - - // Cast does not lose information, because we then check that we only parsed - // 4 digits, so our number can't be bigger than 9999. - year = static_cast(strtoul(dateStr, &parseEnd, 10)); - VerifyOrExit(parseEnd == dateStr + 4, err = CHIP_ERROR_INVALID_ARGUMENT); - - // Cast does not lose information, because we then check that we only parsed - // 2 digits, so our number can't be bigger than 99. - month = static_cast(strtoul(dateStr + 5, &parseEnd, 10)); - VerifyOrExit(parseEnd == dateStr + 7, err = CHIP_ERROR_INVALID_ARGUMENT); - - // Cast does not lose information, because we then check that we only parsed - // 2 digits, so our number can't be bigger than 99. - day = static_cast(strtoul(dateStr + 8, &parseEnd, 10)); - VerifyOrExit(parseEnd == dateStr + 10, err = CHIP_ERROR_INVALID_ARGUMENT); - -exit: - if (err != CHIP_NO_ERROR && err != CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - ChipLogError(DeviceLayer, "Invalid manufacturing date: %s", dateStr); - } - return err; -} - -CHIP_ERROR SilabsDeviceDataProvider::GetPartNumber(char * buf, size_t bufSize) -{ - size_t partNumberLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_PartNumber, buf, bufSize, partNumberLen); -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductURL(char * buf, size_t bufSize) -{ - size_t productUrlLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::kConfigKey_ProductURL, buf, bufSize, productUrlLen); -} - -CHIP_ERROR SilabsDeviceDataProvider::GetProductLabel(char * buf, size_t bufSize) -{ - size_t productLabelLen = 0; // without counting null-terminator - return SilabsConfig::ReadConfigValueStr(SilabsConfig::KConfigKey_ProductLabel, buf, bufSize, productLabelLen); -} - -#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED -/** - * @brief Reads the test event trigger key from NVM. If the key isn't present, returns default value if defined. - * - * @param[out] keySpan output buffer. Must be at least large enough for 16 bytes (ken length) - * @return CHIP_ERROR - */ -CHIP_ERROR SilabsDeviceDataProvider::GetTestEventTriggerKey(MutableByteSpan & keySpan) -{ - constexpr size_t kEnableKeyLength = 16; // Expected byte size of the EnableKey - CHIP_ERROR err = CHIP_NO_ERROR; - size_t keyLength = 0; - - VerifyOrReturnError(keySpan.size() >= kEnableKeyLength, CHIP_ERROR_BUFFER_TOO_SMALL); - - err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Test_Event_Trigger_Key, keySpan.data(), kEnableKeyLength, - keyLength); -#ifndef NDEBUG - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - - constexpr char enableKey[] = SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY; - if (Encoding::HexToBytes(enableKey, strlen(enableKey), keySpan.data(), kEnableKeyLength) != kEnableKeyLength) - { - // enableKey Hex String doesn't have the correct length - memset(keySpan.data(), 0, keySpan.size()); - return CHIP_ERROR_INTERNAL; - } - err = CHIP_NO_ERROR; - } -#endif // NDEBUG - - keySpan.reduce_size(kEnableKeyLength); - return err; -} -#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED - -SilabsDeviceDataProvider & SilabsDeviceDataProvider::GetDeviceDataProvider() -{ - static SilabsDeviceDataProvider sDataProvider; - return sDataProvider; -} - -} // namespace Silabs -} // namespace DeviceLayer -} // namespace chip diff --git a/examples/platform/silabs/SilabsDeviceDataProvider.h b/examples/platform/silabs/SilabsDeviceDataProvider.h deleted file mode 100644 index 76caac04bd60b8..00000000000000 --- a/examples/platform/silabs/SilabsDeviceDataProvider.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Copyright (c) 2022 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 - -namespace chip { -namespace DeviceLayer { -namespace Silabs { - -/** - * @brief This class provides Commissionable data, Device Attestation Credentials, - * and Device Instance Info. - */ - -class SilabsDeviceDataProvider : public CommissionableDataProvider, - public Internal::GenericDeviceInstanceInfoProvider -{ -public: - SilabsDeviceDataProvider() : - CommissionableDataProvider(), - Internal::GenericDeviceInstanceInfoProvider(ConfigurationManagerImpl::GetDefaultInstance()) - {} - - static SilabsDeviceDataProvider & GetDeviceDataProvider(); - CHIP_ERROR GetSetupPayload(MutableCharSpan & payloadBuf); - // ===== Members functions that implement the CommissionableDataProvider - CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; - CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override { return CHIP_ERROR_NOT_IMPLEMENTED; } - CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; - CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; - CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; - // Per spec 5.1.7. Passcode cannot be stored on the device - CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override { return CHIP_ERROR_NOT_IMPLEMENTED; }; - CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override { return CHIP_ERROR_NOT_IMPLEMENTED; } - - // ===== Members functions that implement the GenericDeviceInstanceInfoProvider - CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; - CHIP_ERROR GetVendorId(uint16_t & vendorId) override; - CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; - CHIP_ERROR GetProductId(uint16_t & productId) override; - CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; - CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; - CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; - CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; - CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; - CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; - CHIP_ERROR GetProductURL(char * buf, size_t bufSzie) override; - CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; - - // ===== Member functions that are Silabs Specific - CHIP_ERROR GetTestEventTriggerKey(MutableByteSpan & keySpan); -}; - -} // namespace Silabs -} // namespace DeviceLayer -} // namespace chip From 31003db850e0f812b52e5f3f8cbb8a075986e7bc Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:52:16 -0400 Subject: [PATCH 4/6] fix for wifi ncp build --- src/platform/silabs/efr32/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn index 01027e0371a5b7..5d661886d54f21 100644 --- a/src/platform/silabs/efr32/BUILD.gn +++ b/src/platform/silabs/efr32/BUILD.gn @@ -99,6 +99,7 @@ static_library("efr32") { "${chip_root}/src/platform/logging:headers", ] deps = [ "${silabs_platform_dir}/provision:provision-headers" ] + public_configs = [] # Add platform crypto implementation if (chip_crypto == "platform") { From bc70534d22efc017801fa5e433f9a2406caaffe2 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:57:33 -0400 Subject: [PATCH 5/6] address comments --- examples/platform/silabs/BaseApplication.cpp | 2 +- examples/platform/silabs/efr32/BUILD.gn | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index fd22a7ea3a48fc..b9cf8d08aa4740 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -38,12 +38,12 @@ #if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 #include // nogncheck #endif -#include #include #include #include #include #include +#include #include #include #include diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 53f92cdfde99f6..6cf43897f43b10 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -219,8 +219,6 @@ source_set("efr32-common") { ":efr32-common-config", "${efr32_sdk_build_root}:silabs_config", ":chip_examples_project_config", - - "${chip_root}/src/platform/silabs/provision:provision-config", ] # DIC From dfff15e58fa7a1cb0cf244dd1c1ad77e49363aa9 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:17:55 -0400 Subject: [PATCH 6/6] fixup include path --- examples/platform/silabs/BaseApplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index b9cf8d08aa4740..fd22a7ea3a48fc 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -38,12 +38,12 @@ #if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 #include // nogncheck #endif +#include #include #include #include #include #include -#include #include #include #include