Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Silabs] Add support for factory and commissionable data provisioning with the use… #34087

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions examples/platform/silabs/BaseApplication.cpp
Original file line number Diff line number Diff line change
@@ -24,20 +24,21 @@
#include "AppConfig.h"
#include "AppEvent.h"
#include "AppTask.h"

#include <app/server/Server.h>

#define APP_ACTION_BUTTON 1

#ifdef DISPLAY_ENABLED
#include "lcd.h"
#ifdef QR_CODE_ENABLED
#include "qrcodegen.h"
#endif // QR_CODE_ENABLED
#endif // DISPLAY_ENABLED

#include "SilabsDeviceDataProvider.h"
#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1
#include <app/icd/server/ICDNotifier.h> // nogncheck
#endif
#include <ProvisionManager.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/util/attribute-storage.h>
#include <assert.h>
@@ -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
16 changes: 8 additions & 8 deletions examples/platform/silabs/MatterConfig.cpp
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@
static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeystore;
#endif

#include "SilabsDeviceDataProvider.h"
#include <ProvisionManager.h>
#include <app/InteractionModelEngine.h>
#include <app/TimerDelegates.h>

@@ -80,8 +80,6 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeys

#include <DeviceInfoProviderImpl.h>
#include <app/server/Server.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <examples/platform/silabs/SilabsDeviceAttestationCreds.h>

#include <platform/silabs/platformAbstraction/SilabsPlatform.h>

@@ -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);

54 changes: 5 additions & 49 deletions examples/platform/silabs/SiWx917/BUILD.gn
Original file line number Diff line number Diff line change
@@ -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",
199 changes: 0 additions & 199 deletions examples/platform/silabs/SilabsDeviceAttestationCreds.cpp

This file was deleted.

416 changes: 0 additions & 416 deletions examples/platform/silabs/SilabsDeviceDataProvider.cpp

This file was deleted.

72 changes: 0 additions & 72 deletions examples/platform/silabs/SilabsDeviceDataProvider.h

This file was deleted.

4 changes: 2 additions & 2 deletions examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
*/

#include "SilabsTestEventTriggerDelegate.h"
#include "SilabsDeviceDataProvider.h"
#include <ProvisionManager.h>

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));
}
54 changes: 7 additions & 47 deletions examples/platform/silabs/efr32/BUILD.gn
Original file line number Diff line number Diff line change
@@ -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,7 +212,7 @@ config("silabs-wifi-config") {
}

source_set("efr32-common") {
deps = []
deps = [ "${chip_root}/src/platform/silabs/provision:provision-headers" ]
defines = []
public_deps = []
public_configs = [
@@ -275,6 +241,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 +307,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",
129 changes: 129 additions & 0 deletions examples/platform/silabs/provision/ProvisionStorageCustom.cpp
Original file line number Diff line number Diff line change
@@ -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 <algorithm>
#include <lib/support/CodeUtils.h>
#include <string.h>

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
731 changes: 731 additions & 0 deletions examples/platform/silabs/provision/ProvisionStorageDefault.cpp

Large diffs are not rendered by default.

724 changes: 724 additions & 0 deletions examples/platform/silabs/provision/ProvisionStorageFlash.cpp

Large diffs are not rendered by default.

58 changes: 33 additions & 25 deletions examples/platform/silabs/silabs_creds.h
Original file line number Diff line number Diff line change
@@ -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
15 changes: 13 additions & 2 deletions src/platform/silabs/efr32/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
@@ -52,6 +52,9 @@ extern "C" {
#include <setup_payload/AdditionalDataPayloadGenerator.h>
#endif

#include <ProvisionChannel.h>
#include <ProvisionManager.h>

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

7 changes: 3 additions & 4 deletions src/platform/silabs/efr32/BUILD.gn
Original file line number Diff line number Diff line change
@@ -98,7 +98,8 @@ static_library("efr32") {
"${chip_root}/src/platform:platform_base",
"${chip_root}/src/platform/logging:headers",
]
deps = []
deps = [ "${silabs_platform_dir}/provision:provision-headers" ]
public_configs = []

# Add platform crypto implementation
if (chip_crypto == "platform") {
@@ -136,8 +137,6 @@ static_library("efr32") {
]
deps += [ "${chip_root}/src/lib/dnssd:platform_header" ]
}

public_configs = []
}

if (chip_enable_wifi) {
@@ -160,7 +159,7 @@ static_library("efr32") {
]
}

public_configs = [ ":efr32-platform-wifi-config" ]
public_configs += [ ":efr32-platform-wifi-config" ]
}
}

14 changes: 13 additions & 1 deletion src/platform/silabs/platformAbstraction/GsdkSpam.cpp
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions src/platform/silabs/platformAbstraction/SilabsPlatform.h
Original file line number Diff line number Diff line change
@@ -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;

Original file line number Diff line number Diff line change
@@ -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) {}
6 changes: 6 additions & 0 deletions src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
*/

#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
#include <sl_si91x_button_pin_config.h>

#include <FreeRTOS.h>
#include <task.h>
@@ -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
51 changes: 51 additions & 0 deletions src/platform/silabs/provision/AttestationKey.h
Original file line number Diff line number Diff line change
@@ -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 <lib/core/CHIPError.h>
#include <lib/support/Span.h>
#include <stddef.h>
#include <stdint.h>

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
38 changes: 38 additions & 0 deletions src/platform/silabs/provision/BUILD.gn
Original file line number Diff line number Diff line change
@@ -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" ]
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* 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.
@@ -16,23 +16,29 @@
*/
#pragma once

#include <credentials/DeviceAttestationCredsProvider.h>
#include <lib/core/CHIPError.h>
#include <stddef.h>
#include <stdint.h>

namespace chip {
namespace Credentials {
namespace DeviceLayer {
namespace Silabs {
namespace Provision {

/**
* @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();
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);

void SilabsDacProviderMigration(void);
static CHIP_ERROR Update(uint16_t handle);
};

} // namespace Provision
} // namespace Silabs
} // namespace Credentials
} // namespace DeviceLayer
} // namespace chip
191 changes: 191 additions & 0 deletions src/platform/silabs/provision/ProvisionEncoder.h
Original file line number Diff line number Diff line change
@@ -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 <lib/core/CHIPEncoding.h>
#include <lib/core/CHIPError.h>
#include <stddef.h>
#include <stdint.h>

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
61 changes: 61 additions & 0 deletions src/platform/silabs/provision/ProvisionManager.h
Original file line number Diff line number Diff line change
@@ -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 <lib/core/CHIPError.h>

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
107 changes: 107 additions & 0 deletions src/platform/silabs/provision/ProvisionProtocol.h
Original file line number Diff line number Diff line change
@@ -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 <lib/support/Span.h>
#include <stddef.h>
#include <stdint.h>

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
298 changes: 298 additions & 0 deletions src/platform/silabs/provision/ProvisionStorage.h
Original file line number Diff line number Diff line change
@@ -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 <credentials/DeviceAttestationCredsProvider.h>
#include <platform/CommissionableDataProvider.h>
#include <platform/DeviceInstanceInfoProvider.h>

#include <app/data-model/Nullable.h>
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/support/Base64.h>
#include <lib/support/Span.h>
#include <stddef.h>
#include <stdint.h>

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
47 changes: 47 additions & 0 deletions src/platform/silabs/provision/ProvisionStorageGeneric.h
Original file line number Diff line number Diff line change
@@ -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 <lib/core/CHIPError.h>
#include <stddef.h>
#include <stdint.h>

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
15 changes: 7 additions & 8 deletions src/test_driver/efr32/BUILD.gn
Original file line number Diff line number Diff line change
@@ -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"
19 changes: 11 additions & 8 deletions src/test_driver/efr32/src/main.cpp
Original file line number Diff line number Diff line change
@@ -22,9 +22,9 @@
#include <FreeRTOS.h>
#include <PigweedLogger.h>
#include <PigweedLoggerMutex.h>
#include <ProvisionManager.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <cstring>
#include <examples/platform/silabs/SilabsDeviceAttestationCreds.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPPlatformMemory.h>
#include <lib/support/UnitTest.h>
@@ -38,7 +38,8 @@
#include <sl_system_kernel.h>
#include <task.h>

#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");

11 changes: 4 additions & 7 deletions third_party/silabs/SiWx917_sdk.gni
Original file line number Diff line number Diff line change
@@ -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" ]
}
}