diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index 29a5873ff5b..403b47f8e63 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -268,8 +268,6 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) #endif // CHIP_CONFIG_ENABLE_ICD_SERVER #endif // SL_WIFI - ReturnErrorOnFailure(PlatformMgr().InitChipStack()); - chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(appName); // Provision Manager @@ -279,6 +277,8 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) SetCommissionableDataProvider(&provision.GetStorage()); ChipLogProgress(DeviceLayer, "Provision mode %s", provision.IsProvisionRequired() ? "ENABLED" : "disabled"); + ReturnErrorOnFailure(PlatformMgr().InitChipStack()); + #if CHIP_ENABLE_OPENTHREAD ReturnErrorOnFailure(InitOpenThread()); #endif diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp index 9682ede2cc0..d3c072b7cbf 100644 --- a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -21,13 +21,20 @@ #include #include #include -#include -#include -#include #include #include +#include #include #include + +#ifdef SL_TOKEN_MANAGER_DEFINES_H +#include +#else +#include +#include +#include +#endif + #ifndef NDEBUG #if defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && SL_MATTER_TEST_EVENT_TRIGGER_ENABLED && (SL_MATTER_GN_BUILD == 0) #include @@ -58,12 +65,26 @@ namespace DeviceLayer { namespace Silabs { namespace Provision { -namespace { +namespace Migration { // 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; +// Single buffers for old and new credentials +uint8_t old_cred_buf[512]; +uint8_t new_cred_buf[512]; + +CHIP_ERROR SetCredentialsBaseAddress(uint32_t addr) +{ + return SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, addr); +} + +CHIP_ERROR GetCredentialsBaseAddress(uint32_t & addr) +{ + return SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Creds_Base_Addr, addr); +} + CHIP_ERROR ErasePage(uint32_t addr) { return chip::DeviceLayer::Silabs::GetPlatform().FlashErasePage(addr); @@ -103,7 +124,7 @@ CHIP_ERROR WritePage(uint32_t addr, const uint8_t * data, size_t size) CHIP_ERROR WriteFile(Storage & store, SilabsConfig::Key offset_key, SilabsConfig::Key size_key, const ByteSpan & value) { uint32_t base_addr = 0; - ReturnErrorOnFailure(store.GetCredentialsBaseAddress(base_addr)); + ReturnErrorOnFailure(GetCredentialsBaseAddress(base_addr)); if (0 == sCredentialsOffset) { ReturnErrorOnFailure(ErasePage(base_addr)); @@ -120,10 +141,10 @@ CHIP_ERROR WriteFile(Storage & store, SilabsConfig::Key offset_key, SilabsConfig return CHIP_NO_ERROR; } -CHIP_ERROR ReadFileByOffset(Storage & store, const char * description, uint32_t offset, uint32_t size, MutableByteSpan & value) +CHIP_ERROR ReadFileByOffset(const char * description, uint32_t offset, uint32_t size, MutableByteSpan & value) { uint32_t base_addr = 0; - ReturnErrorOnFailure(store.GetCredentialsBaseAddress(base_addr)); + ReturnErrorOnFailure(GetCredentialsBaseAddress(base_addr)); uint8_t * address = (uint8_t *) (base_addr + offset); ByteSpan span(address, size); @@ -132,7 +153,7 @@ CHIP_ERROR ReadFileByOffset(Storage & store, const char * description, uint32_t return CopySpanToMutableSpan(span, value); } -CHIP_ERROR ReadFileByKey(Storage & store, const char * description, uint32_t offset_key, uint32_t size_key, MutableByteSpan & value) +CHIP_ERROR ReadFileByKey(const char * description, uint32_t offset_key, uint32_t size_key, MutableByteSpan & value) { uint32_t offset = 0; uint32_t size = 0; @@ -145,10 +166,93 @@ CHIP_ERROR ReadFileByKey(Storage & store, const char * description, uint32_t off VerifyOrReturnError(SilabsConfig::ConfigValueExists(size_key), CHIP_ERROR_NOT_FOUND); ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(size_key, size)); - return ReadFileByOffset(store, description, offset, size, value); + return ReadFileByOffset(description, offset, size, value); +} + +CHIP_ERROR SetCertificationDeclaration(Storage & store, const ByteSpan & value) +{ + ReturnErrorOnFailure(WriteFile(store, SilabsConfig::kConfigKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR SetProductAttestationIntermediateCert(Storage & store, const ByteSpan & value) +{ + ReturnErrorOnFailure( + WriteFile(store, SilabsConfig::kConfigKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR SetDeviceAttestationCert(Storage & store, const ByteSpan & value) +{ + ReturnErrorOnFailure( + WriteFile(store, SilabsConfig::kConfigKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Size, value)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey("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("GetCertificationDeclaration", 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 GetProductAttestationIntermediateCert(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey("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("GetProductAttestationIntermediateCert", 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 GetDeviceAttestationCert(MutableByteSpan & value) +{ + CHIP_ERROR err = ReadFileByKey("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("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; } -} // namespace +} // namespace Migration // // Initialization @@ -156,7 +260,7 @@ CHIP_ERROR ReadFileByKey(Storage & store, const char * description, uint32_t off CHIP_ERROR Storage::Initialize(uint32_t flash_addr, uint32_t flash_size) { - sCredentialsOffset = 0; + Migration::sCredentialsOffset = 0; uint32_t base_addr = (uint32_t) linker_nvm_end; if (flash_size > 0) @@ -478,87 +582,64 @@ CHIP_ERROR Storage::GetFirmwareInformation(MutableByteSpan & value) return CHIP_NO_ERROR; } -CHIP_ERROR Storage::SetCertificationDeclaration(const ByteSpan & value) +// Helper function to set credential data using token manager +static CHIP_ERROR SetCredentialData(SilabsConfig::Key size_key, SilabsConfig::Key token_key, const ByteSpan & value) +{ + ReturnErrorOnFailure(SilabsConfig::WriteConfigValue(size_key, (uint32_t) value.size())); +#ifdef SL_TOKEN_MANAGER_DEFINES_H + sl_status_t status = sl_token_manager_set_data(token_key, const_cast(value.data()), value.size()); +#else + sl_status_t status = nvm3_writeData(nvm3_defaultHandle, token_key, const_cast(value.data()), value.size()); +#endif // SL_TOKEN_MANAGER_DEFINES_H + return MapNvm3Error(status); +} + +// Helper function to get credential data using token manager +static CHIP_ERROR GetCredentialData(SilabsConfig::Key size_key, SilabsConfig::Key token_key, MutableByteSpan & value) { - ReturnErrorOnFailure(WriteFile(*this, SilabsConfig::kConfigKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Size, value)); + uint32_t key_size = 0; + + VerifyOrReturnError(SilabsConfig::ConfigValueExists(size_key), CHIP_ERROR_NOT_FOUND); + ReturnErrorOnFailure(SilabsConfig::ReadConfigValue(size_key, key_size)); + VerifyOrReturnError(value.size() >= key_size, CHIP_ERROR_BUFFER_TOO_SMALL); +#ifdef SL_TOKEN_MANAGER_DEFINES_H + sl_status_t status = sl_token_manager_get_data(token_key, value.data(), key_size); +#else + sl_status_t status = nvm3_readData(nvm3_defaultHandle, token_key, value.data(), key_size); +#endif // SL_TOKEN_MANAGER_DEFINES_H + ReturnErrorOnFailure(MapNvm3Error(status)); + value.reduce_size(key_size); return CHIP_NO_ERROR; } -CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) +CHIP_ERROR Storage::SetCertificationDeclaration(const ByteSpan & 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 SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS - if (CHIP_ERROR_NOT_FOUND == err) - { - // Example CD - err = Examples::GetExampleDACProvider()->GetCertificationDeclaration(value); - } -#endif - return err; + return SetCredentialData(SilabsConfig::kConfigKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD, value); } 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; + return SetCredentialData(SilabsConfig::kConfigKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_Pai, value); } -CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & value) +CHIP_ERROR Storage::SetDeviceAttestationCert(const ByteSpan & 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 SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS - if (CHIP_ERROR_NOT_FOUND == err) - { - // Example PAI - err = Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(value); - } -#endif - return err; + return SetCredentialData(SilabsConfig::kConfigKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_Dac, value); } -CHIP_ERROR Storage::SetDeviceAttestationCert(const ByteSpan & value) +CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) { - ReturnErrorOnFailure( - WriteFile(*this, SilabsConfig::kConfigKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Size, value)); - return CHIP_NO_ERROR; + return GetCredentialData(SilabsConfig::kConfigKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD, value); +} + +CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & value) +{ + return GetCredentialData(SilabsConfig::kConfigKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_Pai, value); } 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 SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS - if (CHIP_ERROR_NOT_FOUND == err) - { - // Example DAC - return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(value); - } -#endif - return err; + return GetCredentialData(SilabsConfig::kConfigKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_Dac, value); } #if defined(SLI_SI91X_MCU_INTERFACE) && defined(SL_MBEDTLS_USE_TINYCRYPT) @@ -803,6 +884,57 @@ CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) #endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED +// +// Migration and test helpers for attestation credential API migration +// + +CHIP_ERROR Storage::MigrateAttestationCredentialAPI() +{ + MutableByteSpan old_cred_span(Migration::old_cred_buf, sizeof(Migration::old_cred_buf)); + MutableByteSpan new_cred_span(Migration::new_cred_buf, sizeof(Migration::new_cred_buf)); + + // Migrate DAC (Device Attestation Certificate) first + ReturnLogErrorOnFailure(Migration::GetDeviceAttestationCert(old_cred_span)); + ReturnLogErrorOnFailure(SetDeviceAttestationCert(ByteSpan(old_cred_span.data(), old_cred_span.size()))); + + // Verify DAC migration + ReturnLogErrorOnFailure(GetDeviceAttestationCert(new_cred_span)); + VerifyOrReturnError(old_cred_span.size() == new_cred_span.size() && + memcmp(old_cred_span.data(), new_cred_span.data(), old_cred_span.size()) == 0, + CHIP_ERROR_INCORRECT_STATE); + ChipLogProgress(DeviceLayer, "DAC migration verified successfully."); + + // Migrate PAI (Product Attestation Intermediate Certificate) + old_cred_span = MutableByteSpan(Migration::old_cred_buf, sizeof(Migration::old_cred_buf)); + ReturnLogErrorOnFailure(Migration::GetProductAttestationIntermediateCert(old_cred_span)); + ReturnLogErrorOnFailure(SetProductAttestationIntermediateCert(ByteSpan(old_cred_span.data(), old_cred_span.size()))); + + // Verify PAI migration + new_cred_span = MutableByteSpan(Migration::new_cred_buf, sizeof(Migration::new_cred_buf)); + ReturnLogErrorOnFailure(GetProductAttestationIntermediateCert(new_cred_span)); + VerifyOrReturnError(old_cred_span.size() == new_cred_span.size() && + memcmp(old_cred_span.data(), new_cred_span.data(), old_cred_span.size()) == 0, + CHIP_ERROR_INCORRECT_STATE); + ChipLogProgress(DeviceLayer, "PAI migration verified successfully."); + + // Migrate CD (Certification Declaration) + old_cred_span = MutableByteSpan(Migration::old_cred_buf, sizeof(Migration::old_cred_buf)); + ReturnLogErrorOnFailure(Migration::GetCertificationDeclaration(old_cred_span)); + ReturnLogErrorOnFailure(SetCertificationDeclaration(ByteSpan(old_cred_span.data(), old_cred_span.size()))); + + // Verify CD migration + new_cred_span = MutableByteSpan(Migration::new_cred_buf, sizeof(Migration::new_cred_buf)); + ReturnLogErrorOnFailure(GetCertificationDeclaration(new_cred_span)); + VerifyOrReturnError(old_cred_span.size() == new_cred_span.size() && + memcmp(old_cred_span.data(), new_cred_span.data(), old_cred_span.size()) == 0, + CHIP_ERROR_INCORRECT_STATE); + ChipLogProgress(DeviceLayer, "CD migration verified successfully."); + + // Log successful migration + ChipLogProgress(DeviceLayer, "Attestation credential API migration succeeded."); + return CHIP_NO_ERROR; +} + } // namespace Provision } // namespace Silabs } // namespace DeviceLayer diff --git a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp index 6cce27e32a7..53a9a02506d 100644 --- a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp @@ -817,6 +817,12 @@ CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) return CHIP_ERROR_NOT_IMPLEMENTED; } +CHIP_ERROR Storage::MigrateAttestationCredentialAPI() +{ + // Not implemented for the ProvisionStorageFlash. + return CHIP_NO_ERROR; +} + } // namespace Provision } // namespace Silabs } // namespace DeviceLayer diff --git a/src/platform/silabs/MigrationManager.cpp b/src/platform/silabs/MigrationManager.cpp index a7cbcb141b9..10fc26e8ad8 100644 --- a/src/platform/silabs/MigrationManager.cpp +++ b/src/platform/silabs/MigrationManager.cpp @@ -16,6 +16,8 @@ */ #include "MigrationManager.h" +#include +#include #include #include #include @@ -41,6 +43,7 @@ static migrationData_t migrationTable[] = { { .migrationGroup = 2, .migrationFunc = MigrateDacProvider }, { .migrationGroup = 3, .migrationFunc = MigrateCounterConfigs }, { .migrationGroup = 4, .migrationFunc = MigrateHardwareVersion }, + { .migrationGroup = 5, .migrationFunc = MigrateCTM }, // add any additional migration neccesary. migrationGroup should stay equal if done in the same commit or increment by 1 for // each new entry. }; @@ -132,6 +135,15 @@ void MigrateHardwareVersion(void) MigrationManager::MigrateUint16(kOldKey_HardwareVersion, SilabsConfig::kConfigKey_HardwareVersion); } +void MigrateCTM(void) +{ + CHIP_ERROR err = Provision::Manager::GetInstance().GetStorage().MigrateAttestationCredentialAPI(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to migrate CTM: %s", ErrorStr(err)); + } +} + } // namespace Silabs } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/silabs/MigrationManager.h b/src/platform/silabs/MigrationManager.h index 155cb7e3b78..379c4ce61df 100644 --- a/src/platform/silabs/MigrationManager.h +++ b/src/platform/silabs/MigrationManager.h @@ -47,6 +47,7 @@ void MigrateKvsMap(void); void MigrateDacProvider(void); void MigrateCounterConfigs(void); void MigrateHardwareVersion(void); +void MigrateCTM(void); } // namespace Silabs } // namespace DeviceLayer diff --git a/src/platform/silabs/SiWx917/BUILD.gn b/src/platform/silabs/SiWx917/BUILD.gn index 70583a79cdb..474a089754f 100644 --- a/src/platform/silabs/SiWx917/BUILD.gn +++ b/src/platform/silabs/SiWx917/BUILD.gn @@ -63,6 +63,8 @@ static_library("SiWx917") { "${silabs_platform_dir}/PlatformManagerImpl.h", "${silabs_platform_dir}/SilabsConfig.cpp", "${silabs_platform_dir}/SilabsConfig.h", + "${silabs_platform_dir}/SilabsConfigUtils.cpp", + "${silabs_platform_dir}/SilabsConfigUtils.h", "${silabs_platform_dir}/SystemPlatformConfig.h", "../../FreeRTOS/SystemTimeSupport.cpp", "../../SingletonConfigurationManager.cpp", diff --git a/src/platform/silabs/SilabsConfig.cpp b/src/platform/silabs/SilabsConfig.cpp index 4f7a3d65e64..9975d79d15e 100644 --- a/src/platform/silabs/SilabsConfig.cpp +++ b/src/platform/silabs/SilabsConfig.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -63,25 +64,6 @@ namespace DeviceLayer { namespace Internal { namespace { -CHIP_ERROR MapNvm3Error(sl_status_t nvm3Res) -{ - CHIP_ERROR err; - - switch (nvm3Res) - { - case SL_STATUS_OK: - err = CHIP_NO_ERROR; - break; - case SL_STATUS_NOT_FOUND: - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - break; - default: - err = CHIP_ERROR(ChipError::Range::kPlatform, (nvm3Res & 0xFF) + CHIP_DEVICE_CONFIG_SILABS_NVM3_ERROR_MIN); - break; - } - - return err; -} template CHIP_ERROR ReadConfigValueHelper(SilabsConfig::Key key, T & val) diff --git a/src/platform/silabs/SilabsConfig.h b/src/platform/silabs/SilabsConfig.h index 41f8b7ec2e0..154d43e600c 100644 --- a/src/platform/silabs/SilabsConfig.h +++ b/src/platform/silabs/SilabsConfig.h @@ -27,11 +27,11 @@ #include #include -#ifndef SL_COMMON_TOKEN_MANAGER_ENABLE_DYNAMIC_TOKENS +#ifdef SL_TOKEN_MANAGER_DEFINES_H +#include +#else #include "nvm3.h" #include "nvm3_hal_flash.h" -#else -#include #endif #ifndef KVS_MAX_ENTRIES @@ -61,7 +61,20 @@ namespace Internal { * the template class (e.g. the ReadConfigValue() method). */ -#ifndef SL_COMMON_TOKEN_MANAGER_ENABLE_DYNAMIC_TOKENS +#ifdef SL_TOKEN_MANAGER_DEFINES_H +inline constexpr uint32_t kUserNvm3KeyDomainLoLimit = SL_TOKEN_NVM3_REGION_USER; +inline constexpr uint32_t kUserNvm3KeyDomainHiLimit = SL_TOKEN_NVM3_REGION_ZIGBEE - 1; + +// Only keep the MSBs of the Matter Region. The LSB of the region is determined by the keyBaseOffset. +// with SilabsConfigKey Helper function. +inline constexpr uint32_t kMatterNvm3KeyDomain = (SL_TOKEN_NVM3_REGION_MATTER & 0xFFFF000); + +constexpr inline uint32_t SilabsConfigKey(uint8_t keyBaseOffset, uint8_t id) +{ + return SL_TOKEN_TYPE_NVM3 | kMatterNvm3KeyDomain | static_cast(keyBaseOffset) << 8 | id; +} + +#else // Silabs NVM3 objects use a 20-bit number, // NVM3 Key 19:16 Stack region // NVM3 Key 15:0 Available NVM3 keys 0x0000 -> 0xFFFF. @@ -77,24 +90,6 @@ constexpr inline uint32_t SilabsConfigKey(uint8_t keyBaseOffset, uint8_t id) { return kMatterNvm3KeyDomain | static_cast(keyBaseOffset) << 8 | id; } -#else - -inline constexpr uint32_t kUserNvm3KeyDomainLoLimit = SL_TOKEN_NVM3_REGION_USER; -inline constexpr uint32_t kUserNvm3KeyDomainHiLimit = SL_TOKEN_NVM3_REGION_ZIGBEE - 1; - -// Only keep the MSBs of the Matter Region. The LSB of the region is determined by the keyBaseOffset. -// with SilabsConfigKey Helper function. -inline constexpr uint32_t kMatterNvm3KeyDomain = (SL_TOKEN_NVM3_REGION_MATTER & 0xFFFF000); - -constexpr inline uint32_t SilabsConfigKey(uint8_t keyBaseOffset, uint8_t id) -{ - return SL_TOKEN_TYPE_NVM3 | kMatterNvm3KeyDomain | static_cast(keyBaseOffset) << 8 | id; -} - -constexpr inline uint32_t SilabsSecureTokenKey(uint8_t keyBaseOffset, uint8_t id) -{ - return SL_TOKEN_TYPE_STATIC_SECURE | static_cast(keyBaseOffset) << 8 | id; -} #endif inline constexpr uint32_t kMatterNvm3KeyLoLimit = 0x087200U; // Do not modify without Silabs GSDK team approval @@ -151,16 +146,23 @@ class SilabsConfig // SHALL NOT be the same as the UniqueID attribute exposed in the Basic Information cluster. static constexpr Key kConfigKey_PersistentUniqueId = SilabsConfigKey(kMatterFactory_KeyBase, 0x1F); static constexpr Key kConfigKey_Creds_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x20); - static constexpr Key kConfigKey_Creds_Base_Addr = SilabsConfigKey(kMatterFactory_KeyBase, 0x21); - static constexpr Key kConfigKey_Creds_DAC_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x22); - static constexpr Key kConfigKey_Creds_DAC_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x23); - static constexpr Key kConfigKey_Creds_PAI_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x24); - static constexpr Key kConfigKey_Creds_PAI_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x25); - static constexpr Key kConfigKey_Creds_CD_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x26); - static constexpr Key kConfigKey_Creds_CD_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x27); - static constexpr Key kConfigKey_Provision_Request = SilabsConfigKey(kMatterFactory_KeyBase, 0x28); - static constexpr Key kConfigKey_Provision_Version = SilabsConfigKey(kMatterFactory_KeyBase, 0x29); - static constexpr Key kOtaTlvEncryption_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x30); + + // DEPRECATED KEYS : BEGIN + static constexpr Key kConfigKey_Creds_Base_Addr = SilabsConfigKey(kMatterFactory_KeyBase, 0x21); + static constexpr Key kConfigKey_Creds_DAC_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x22); + static constexpr Key kConfigKey_Creds_PAI_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x24); + static constexpr Key kConfigKey_Creds_CD_Offset = SilabsConfigKey(kMatterFactory_KeyBase, 0x26); + // DEPRECATED KEYS : END + + static constexpr Key kConfigKey_Creds_DAC_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x23); + static constexpr Key kConfigKey_Creds_PAI_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x25); + static constexpr Key kConfigKey_Creds_CD_Size = SilabsConfigKey(kMatterFactory_KeyBase, 0x27); + static constexpr Key kConfigKey_Provision_Request = SilabsConfigKey(kMatterFactory_KeyBase, 0x28); + static constexpr Key kConfigKey_Provision_Version = SilabsConfigKey(kMatterFactory_KeyBase, 0x29); + static constexpr Key kOtaTlvEncryption_KeyId = SilabsConfigKey(kMatterFactory_KeyBase, 0x30); + static constexpr Key kConfigKey_Creds_Dac = SilabsConfigKey(kMatterFactory_KeyBase, 0x31); + static constexpr Key kConfigKey_Creds_Pai = SilabsConfigKey(kMatterFactory_KeyBase, 0x32); + static constexpr Key kConfigKey_Creds_CD = SilabsConfigKey(kMatterFactory_KeyBase, 0x33); // Matter Config Keys static constexpr Key kConfigKey_ServiceConfig = SilabsConfigKey(kMatterConfig_KeyBase, 0x01); diff --git a/src/platform/silabs/SilabsConfigCTM.cpp b/src/platform/silabs/SilabsConfigCTM.cpp index 982d962b8a2..1f88afcb459 100644 --- a/src/platform/silabs/SilabsConfigCTM.cpp +++ b/src/platform/silabs/SilabsConfigCTM.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "uart.h" #include @@ -35,7 +36,7 @@ #include #include #include -#include +#include // Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd // for an application controlled re-entrance protection static SemaphoreHandle_t nvm3_Sem; @@ -63,25 +64,6 @@ namespace chip { namespace DeviceLayer { namespace Internal { namespace { -CHIP_ERROR MapNvm3Error(sl_status_t nvm3Res) -{ - CHIP_ERROR err; - - switch (nvm3Res) - { - case SL_STATUS_OK: - err = CHIP_NO_ERROR; - break; - case SL_STATUS_NOT_FOUND: - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - break; - default: - err = CHIP_ERROR(ChipError::Range::kPlatform, (nvm3Res & 0xFF) + CHIP_DEVICE_CONFIG_SILABS_NVM3_ERROR_MIN); - break; - } - - return err; -} template CHIP_ERROR ReadConfigValueHelper(SilabsConfig::Key key, T & val) @@ -98,9 +80,7 @@ CHIP_ERROR ReadConfigValueHelper(SilabsConfig::Key key, T & val) // Ensure the data size matches the expected size VerifyOrReturnError(dataLen == sizeof(T), CHIP_ERROR_INVALID_ARGUMENT); - // TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated - uint32_t unusedSizeOut; - ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, dataLen, &unusedSizeOut))); + ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, dataLen))); val = tmpVal; return CHIP_NO_ERROR; @@ -177,9 +157,7 @@ CHIP_ERROR SilabsConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, // terminator char). VerifyOrExit((bufSize > dataLen), err = CHIP_ERROR_BUFFER_TOO_SMALL); - // TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated - uint32_t unusedSizeOut; - err = MapNvm3Error(sl_token_manager_get_data(key, buf, dataLen, &unusedSizeOut)); + err = MapNvm3Error(sl_token_manager_get_data(key, buf, dataLen)); SuccessOrExit(err); outLen = ((dataLen == 1) && (buf[0] == 0)) ? 0 : dataLen; @@ -195,9 +173,7 @@ CHIP_ERROR SilabsConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, { // Read the first byte of the nvm3 string into a tmp var. char firstByte; - // TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated - uint32_t unusedSizeOut; - err = MapNvm3Error(sl_token_manager_get_data(key, &firstByte, 1, &unusedSizeOut)); + err = MapNvm3Error(sl_token_manager_get_data(key, &firstByte, 1)); SuccessOrExit(err); outLen = (firstByte == 0) ? 0 : dataLen; @@ -225,14 +201,12 @@ CHIP_ERROR SilabsConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSi size_t maxReadLength = dataLen - offset; if (bufSize >= maxReadLength) { - // TODO: No API currently exist for partial reads in sl_token_manager_interface, replace this when available - ReturnErrorOnFailure(MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, maxReadLength))); + ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_partial_data(key, buf, offset, maxReadLength))); outLen = maxReadLength; } else { - // TODO: No API currently exist for partial reads in sl_token_manager_interface, replace this when available - ReturnErrorOnFailure(MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, bufSize))); + ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_partial_data(key, buf, offset, bufSize))); // read was successful, but we did not read all the data from the object. outLen = bufSize; return CHIP_ERROR_BUFFER_TOO_SMALL; @@ -248,9 +222,7 @@ CHIP_ERROR SilabsConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & v VerifyOrReturnError(ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // TODO: size_out from sl_token_manager_get_data is not used nor useful, remove once the API gets updated - uint32_t unusedSizeOut; - ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, sizeof(tmpVal), &unusedSizeOut))); + ReturnErrorOnFailure(MapNvm3Error(sl_token_manager_get_data(key, &tmpVal, sizeof(tmpVal)))); val = tmpVal; return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/SilabsConfigUtils.cpp b/src/platform/silabs/SilabsConfigUtils.cpp new file mode 100644 index 00000000000..abc920cbb0c --- /dev/null +++ b/src/platform/silabs/SilabsConfigUtils.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 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. + */ + +/** + * @file + * Utility functions for Silicon Labs platform error handling + * and common operations. + */ + +#include + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +CHIP_ERROR MapNvm3Error(sl_status_t nvm3Res) +{ + CHIP_ERROR err; + + switch (nvm3Res) + { + case SL_STATUS_OK: + err = CHIP_NO_ERROR; + break; + case SL_STATUS_NOT_FOUND: + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + break; + default: + err = CHIP_ERROR(ChipError::Range::kPlatform, (nvm3Res & 0xFF) + CHIP_DEVICE_CONFIG_SILABS_NVM3_ERROR_MIN); + break; + } + + return err; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/SilabsConfigUtils.h b/src/platform/silabs/SilabsConfigUtils.h new file mode 100644 index 00000000000..e925ef1f032 --- /dev/null +++ b/src/platform/silabs/SilabsConfigUtils.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 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. + */ + +/** + * @file + * Utility functions for Silicon Labs platform error handling + * and common operations. + */ + +#pragma once + +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/** + * Maps a Silicon Labs NVM3/Token Manager status code to a CHIP error. + * + * @param[in] nvm3Res The Silicon Labs status code to map. + * @return CHIP_ERROR corresponding to the status code. + */ +CHIP_ERROR MapNvm3Error(sl_status_t nvm3Res); + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn index 74b4ea46a4b..e7bc7b4d526 100644 --- a/src/platform/silabs/efr32/BUILD.gn +++ b/src/platform/silabs/efr32/BUILD.gn @@ -61,6 +61,8 @@ static_library("efr32") { "${silabs_platform_dir}/PlatformManagerImpl.h", "${silabs_platform_dir}/SilabsConfig.cpp", "${silabs_platform_dir}/SilabsConfig.h", + "${silabs_platform_dir}/SilabsConfigUtils.cpp", + "${silabs_platform_dir}/SilabsConfigUtils.h", "${silabs_platform_dir}/SystemPlatformConfig.h", "../../FreeRTOS/SystemTimeSupport.cpp", "../../SingletonConfigurationManager.cpp", diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index 9183ee832ff..487812e7860 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit 9183ee832ff081f5682b47ade181c76eaf03706d +Subproject commit 487812e786016989457aeede30605bcdd03fc659