From 680acc0765172c18b92ee9d9cd6c02a471a73340 Mon Sep 17 00:00:00 2001 From: Sid Hsu Date: Thu, 23 May 2024 22:32:20 +0800 Subject: [PATCH] [Infineon] CYW30739 supports using provisioned data from Optiga Trust M. (#33564) * Update CYW30739 README files. * Add OptigaFactoryDataProvider class to support using provisioned data from Optiga Trust M. * Add UnprovisionedOptigaFactoryDataProvider class to support updating factory data to an unprovisioned Optiga Trust M. --- .../infineon/cyw30739/README.md | 24 +++ .../lighting-app/infineon/cyw30739/README.md | 24 +++ examples/lock-app/infineon/cyw30739/README.md | 24 +++ .../infineon/cyw30739/matter_config.cpp | 27 ++- .../thermostat/infineon/cyw30739/README.md | 24 +++ scripts/setup/requirements.infineon.txt | 1 + src/platform/Infineon/CYW30739/BUILD.gn | 4 +- .../Infineon/CYW30739/CYW30739Config.h | 46 +++-- .../Infineon/CYW30739/FactoryDataProvider.cpp | 5 + .../Infineon/CYW30739/FactoryDataProvider.h | 2 + .../CYW30739/OptigaFactoryDataProvider.cpp | 93 +++++++++ .../CYW30739/OptigaFactoryDataProvider.h | 38 ++++ ...UnprovisionedOptigaFactoryDataProvider.cpp | 193 ++++++++++++++++++ .../UnprovisionedOptigaFactoryDataProvider.h | 43 ++++ src/platform/Infineon/CYW30739/args.gni | 2 + .../CYW30739/cyw30739-chip-mbedtls-config.h | 33 +++ .../Infineon/CYW30739/cyw30739_platform.gni | 13 +- third_party/infineon/repos/matter-wpan-sdk | 2 +- 18 files changed, 568 insertions(+), 30 deletions(-) create mode 100644 src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.cpp create mode 100644 src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.h create mode 100644 src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.cpp create mode 100644 src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.h diff --git a/examples/light-switch-app/infineon/cyw30739/README.md b/examples/light-switch-app/infineon/cyw30739/README.md index 530cfde2501498..70d650cfef97a3 100644 --- a/examples/light-switch-app/infineon/cyw30739/README.md +++ b/examples/light-switch-app/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/light-switch-app/infineon/cyw30739 out/cyw30739-light-switch \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode diff --git a/examples/lighting-app/infineon/cyw30739/README.md b/examples/lighting-app/infineon/cyw30739/README.md index 9dbfc23fe9e52f..46589b1f1302e6 100644 --- a/examples/lighting-app/infineon/cyw30739/README.md +++ b/examples/lighting-app/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/lighting-app/infineon/cyw30739 out/cyw30739-light \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode diff --git a/examples/lock-app/infineon/cyw30739/README.md b/examples/lock-app/infineon/cyw30739/README.md index 6623f77c88c1c4..7f87af8792e6bc 100644 --- a/examples/lock-app/infineon/cyw30739/README.md +++ b/examples/lock-app/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/lock-app/infineon/cyw30739 out/cyw30739-lock \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode diff --git a/examples/platform/infineon/cyw30739/matter_config.cpp b/examples/platform/infineon/cyw30739/matter_config.cpp index 6b0b56730edecd..16d2517affe788 100644 --- a/examples/platform/infineon/cyw30739/matter_config.cpp +++ b/examples/platform/infineon/cyw30739/matter_config.cpp @@ -44,14 +44,21 @@ #include #include #include -#include #include #include -#ifdef BOARD_ENABLE_OPTIGA -#include "wiced_optiga.h" -#endif #include +#ifdef BOARD_USE_OPTIGA +#include "wiced_optiga.h" +#ifdef USE_PROVISIONED_OPTIGA +#include +#else /* !USE_PROVISIONED_OPTIGA */ +#include +#endif /* USE_PROVISIONED_OPTIGA */ +#else /* !BOARD_USE_OPTIGA */ +#include +#endif /* BOARD_USE_OPTIGA */ + using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::Credentials; @@ -60,7 +67,15 @@ using namespace ::chip::Shell; using namespace ::chip::app; static DeviceInfoProviderImpl sExampleDeviceInfoProvider; +#ifdef BOARD_USE_OPTIGA +#ifdef USE_PROVISIONED_OPTIGA +static OptigaFactoryDataProvider sFactoryDataProvider; +#else /* !USE_PROVISIONED_OPTIGA */ +static UnprovisionedOptigaFactoryDataProvider sFactoryDataProvider; +#endif /* USE_PROVISIONED_OPTIGA */ +#else /* !BOARD_USE_OPTIGA */ static FactoryDataProvider sFactoryDataProvider; +#endif /* BOARD_USE_OPTIGA */ // NOTE! This key is for test/certification only and should not be available in production devices! uint8_t sTestEventTriggerEnableKey[chip::TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, @@ -135,7 +150,7 @@ void CYW30739MatterConfig::InitBoard(void) #ifdef BOARD_ENABLE_DISPLAY GUI_Init(); #endif -#ifdef BOARD_ENABLE_OPTIGA +#ifdef BOARD_USE_OPTIGA wiced_optiga_init(); #endif } @@ -186,6 +201,8 @@ void CYW30739MatterConfig::InitApp(void) LogAppInit(); ConfigurationMgr().LogDeviceConfig(); + sFactoryDataProvider.Init(); + // Print QR Code URL PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); /* Start CHIP datamodel server */ diff --git a/examples/thermostat/infineon/cyw30739/README.md b/examples/thermostat/infineon/cyw30739/README.md index 44052add4d0ed4..6d37d24eb920ef 100644 --- a/examples/thermostat/infineon/cyw30739/README.md +++ b/examples/thermostat/infineon/cyw30739/README.md @@ -18,6 +18,7 @@ An example showing the use of Matter on the Infineon CYW30739 platform. - [Commissionable Data](#commissionable-data) - [Device Information](#device-information) - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Use Provisioned Optiga Trust M](#use-provisioned-optiga-trust-m) - [Flashing the Application](#flashing-the-application) - [Enter Recovery Mode](#enter-recovery-mode) - [Run Flash Script](#run-flash-script) @@ -163,6 +164,29 @@ keys, and CD by the following arguments: 'matter_cd="/path/to/cd.der"' ``` +### Use Provisioned Optiga Trust M + +For boards supported by Optiga Trust M, CYW30739 will provision factory data to +the Optiga Trust M by default for easy development. + +The Optiga Trust M on a production board should come with provisioned factory +data. To ensure its optimal use, please configure the Optiga using the following +arguments: + +- `use_provisioned_optiga`, `optiga_dac_object_id`, + `optiga_dac_key_object_id`, `optiga_pai_cert_object_id` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/thermostat/infineon/cyw30739 out/cyw30739-thermostat \ + 'optiga_dac_object_id="0xe0e0"' \ + 'optiga_dac_key_object_id="0xe0f0"' \ + 'optiga_pai_cert_object_id="0xe0e8"' + ``` + +The developer must set the object IDs to corresponding values matching the +configurations used in the Optiga provisioning procedure. + ## Flashing the Application ### Enter Recovery Mode diff --git a/scripts/setup/requirements.infineon.txt b/scripts/setup/requirements.infineon.txt index bba66165a7654c..0a79ce1f3bfa63 100644 --- a/scripts/setup/requirements.infineon.txt +++ b/scripts/setup/requirements.infineon.txt @@ -1 +1,2 @@ leb128 +zcbor diff --git a/src/platform/Infineon/CYW30739/BUILD.gn b/src/platform/Infineon/CYW30739/BUILD.gn index 7613847e0f134c..433b8dcdc49d9d 100644 --- a/src/platform/Infineon/CYW30739/BUILD.gn +++ b/src/platform/Infineon/CYW30739/BUILD.gn @@ -34,8 +34,6 @@ static_library("CYW30739") { "ConfigurationManagerImpl.h", "ConnectivityManagerImpl.cpp", "ConnectivityManagerImpl.h", - "FactoryDataProvider.cpp", - "FactoryDataProvider.h", "InetPlatformConfig.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", @@ -57,6 +55,8 @@ static_library("CYW30739") { "EventFlags.h", "FactoryDataProvider.h", "OTAImageProcessorImpl.h", + "OptigaFactoryDataProvider.h", + "UnprovisionedOptigaFactoryDataProvider.h", "cycfg_gatt_db.h", ] diff --git a/src/platform/Infineon/CYW30739/CYW30739Config.h b/src/platform/Infineon/CYW30739/CYW30739Config.h index f5e56f0fee42cc..24b074689d0ecf 100644 --- a/src/platform/Infineon/CYW30739/CYW30739Config.h +++ b/src/platform/Infineon/CYW30739/CYW30739Config.h @@ -72,25 +72,33 @@ class CYW30739Config static constexpr Key kConfigKey_PAICert = CYW30739ConfigKey(kChipFactory_KeyBase, 0x22); static constexpr Key kConfigKey_CertDeclaration = CYW30739ConfigKey(kChipFactory_KeyBase, 0x23); // CHIP Config Keys - static constexpr Key kConfigKey_ServiceConfig = CYW30739ConfigKey(kChipConfig_KeyBase, 0x00); - static constexpr Key kConfigKey_PairedAccountId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x01); - static constexpr Key kConfigKey_ServiceId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x02); - static constexpr Key kConfigKey_LastUsedEpochKeyId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x03); - static constexpr Key kConfigKey_FailSafeArmed = CYW30739ConfigKey(kChipConfig_KeyBase, 0x04); - static constexpr Key kConfigKey_GroupKey = CYW30739ConfigKey(kChipConfig_KeyBase, 0x05); - static constexpr Key kConfigKey_RegulatoryLocation = CYW30739ConfigKey(kChipConfig_KeyBase, 0x07); - static constexpr Key kConfigKey_CountryCode = CYW30739ConfigKey(kChipConfig_KeyBase, 0x08); - static constexpr Key kConfigKey_RebootCount = CYW30739ConfigKey(kChipConfig_KeyBase, 0x09); - static constexpr Key kConfigKey_UniqueId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0a); - static constexpr Key kConfigKey_LockUser = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0b); - static constexpr Key kConfigKey_Credential = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0c); - static constexpr Key kConfigKey_LockUserName = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0d); - static constexpr Key kConfigKey_CredentialData = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0e); - static constexpr Key kConfigKey_UserCredentials = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0f); - static constexpr Key kConfigKey_WeekDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x10); - static constexpr Key kConfigKey_YearDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x11); - static constexpr Key kConfigKey_HolidaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x12); - static constexpr Key kConfigKey_BootReason = CYW30739ConfigKey(kChipConfig_KeyBase, 0x13); + static constexpr Key kConfigKey_ServiceConfig = CYW30739ConfigKey(kChipConfig_KeyBase, 0x00); + static constexpr Key kConfigKey_PairedAccountId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x01); + static constexpr Key kConfigKey_ServiceId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x02); + static constexpr Key kConfigKey_LastUsedEpochKeyId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x03); + static constexpr Key kConfigKey_FailSafeArmed = CYW30739ConfigKey(kChipConfig_KeyBase, 0x04); + static constexpr Key kConfigKey_GroupKey = CYW30739ConfigKey(kChipConfig_KeyBase, 0x05); + static constexpr Key kConfigKey_RegulatoryLocation = CYW30739ConfigKey(kChipConfig_KeyBase, 0x07); + static constexpr Key kConfigKey_CountryCode = CYW30739ConfigKey(kChipConfig_KeyBase, 0x08); + static constexpr Key kConfigKey_RebootCount = CYW30739ConfigKey(kChipConfig_KeyBase, 0x09); + static constexpr Key kConfigKey_UniqueId = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0a); + static constexpr Key kConfigKey_LockUser = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0b); + static constexpr Key kConfigKey_Credential = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0c); + static constexpr Key kConfigKey_LockUserName = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0d); + static constexpr Key kConfigKey_CredentialData = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0e); + static constexpr Key kConfigKey_UserCredentials = CYW30739ConfigKey(kChipConfig_KeyBase, 0x0f); + static constexpr Key kConfigKey_WeekDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x10); + static constexpr Key kConfigKey_YearDaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x11); + static constexpr Key kConfigKey_HolidaySchedules = CYW30739ConfigKey(kChipConfig_KeyBase, 0x12); + static constexpr Key kConfigKey_BootReason = CYW30739ConfigKey(kChipConfig_KeyBase, 0x13); + static constexpr Key kConfigKey_ProvisioningDAC = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe0); + static constexpr Key kConfigKey_ProvisioningPAICert = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe1); + static constexpr Key kConfigKey_ProvisioningSecret = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe2); + static constexpr Key kConfigKey_ProvisioningSecretMetaData = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe3); + static constexpr Key kConfigKey_ProvisioningDACMetaData = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe4); + static constexpr Key kConfigKey_ProvisioningDACKeyMetaData = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe5); + static constexpr Key kConfigKey_ProvisioningManifest = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe6); + static constexpr Key kConfigKey_ProvisioningFragment = CYW30739ConfigKey(kChipConfig_KeyBase, 0xe7); // Set key id limits for each group. static constexpr Key kMinConfigKey_ChipFactory = CYW30739ConfigKey(kChipFactory_KeyBase, 0x00); diff --git a/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp b/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp index 0ece03d3c19c83..412259bda75013 100644 --- a/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp +++ b/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp @@ -25,6 +25,11 @@ namespace DeviceLayer { using namespace chip::DeviceLayer::Internal; +CHIP_ERROR FactoryDataProvider::Init() +{ + return CHIP_NO_ERROR; +} + /* * Members functions that implement the CommissionableDataProvider */ diff --git a/src/platform/Infineon/CYW30739/FactoryDataProvider.h b/src/platform/Infineon/CYW30739/FactoryDataProvider.h index def69734e1dc22..07228520f8ceb6 100644 --- a/src/platform/Infineon/CYW30739/FactoryDataProvider.h +++ b/src/platform/Infineon/CYW30739/FactoryDataProvider.h @@ -30,6 +30,8 @@ class FactoryDataProvider : public CommissionableDataProvider, public DeviceInstanceInfoProvider { public: + CHIP_ERROR Init(); + // ===== Members functions that implement the CommissionableDataProvider CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator); CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator); diff --git a/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.cpp b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.cpp new file mode 100644 index 00000000000000..5febc46f7170c3 --- /dev/null +++ b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.cpp @@ -0,0 +1,93 @@ +/* + * + * Copyright (c) 2024 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 "OptigaFactoryDataProvider.h" + +#include +#include + +namespace chip { +namespace DeviceLayer { + +using namespace chip::DeviceLayer::Internal; + +/* + * Members functions that implement the DeviceAttestationCredentialsProvider + */ +CHIP_ERROR OptigaFactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) +{ + uint16_t length = out_dac_buffer.size(); + VerifyOrReturnError(wiced_optiga_read_data(OPTIGA_DAC_OBJECT_ID, OPTIGA_OBJECT_DATA, out_dac_buffer.data(), &length) == + WICED_SUCCESS, + CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + out_dac_buffer.reduce_size(length); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OptigaFactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) +{ + uint16_t length = out_pai_buffer.size(); + VerifyOrReturnError(wiced_optiga_read_data(OPTIGA_PAI_CERT_OBJECT_ID, OPTIGA_OBJECT_DATA, out_pai_buffer.data(), &length) == + WICED_SUCCESS, + CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + out_pai_buffer.reduce_size(length); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OptigaFactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, + MutableByteSpan & out_signature_buffer) +{ + VerifyOrReturnError(!out_signature_buffer.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!message_to_sign.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_signature_buffer.size() >= Crypto::kMax_ECDSA_Signature_Length, CHIP_ERROR_BUFFER_TOO_SMALL); + + uint8_t digest[Crypto::kSHA256_Hash_Length]; + ReturnErrorOnFailure(Crypto::Hash_SHA256(message_to_sign.data(), message_to_sign.size(), digest)); + ByteSpan digest_span(digest); + + constexpr uint8_t kAsn1HeaderLength = 2u; + constexpr uint8_t kSeqTag = 0x30u; + + uint8_t asn1_sigature_buffer[Crypto::kMax_ECDSA_Signature_Length_Der]; + MutableByteSpan asn1_signature_span(asn1_sigature_buffer); + + MutableByteSpan optiga_signature_span(asn1_signature_span.SubSpan(kAsn1HeaderLength)); + ReturnErrorOnFailure(SignWithOptigaDeviceAttestationKey(digest_span, optiga_signature_span)); + + asn1_signature_span[0] = kSeqTag; + asn1_signature_span[1] = optiga_signature_span.size(); + asn1_signature_span.reduce_size(kAsn1HeaderLength + optiga_signature_span.size()); + ReturnErrorOnFailure(Crypto::EcdsaAsn1SignatureToRaw(Crypto::kP256_FE_Length, asn1_signature_span, out_signature_buffer)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OptigaFactoryDataProvider::SignWithOptigaDeviceAttestationKey(const ByteSpan & digest, MutableByteSpan & signature) +{ + uint16_t signature_length = signature.size(); + VerifyOrReturnError(wiced_optiga_ecdsa_sign(digest.data(), digest.size(), OPTIGA_DAC_KEY_OBJECT_ID, signature.data(), + &signature_length) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + signature.reduce_size(signature_length); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.h b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.h new file mode 100644 index 00000000000000..a11074632c9ba5 --- /dev/null +++ b/src/platform/Infineon/CYW30739/OptigaFactoryDataProvider.h @@ -0,0 +1,38 @@ +/* + * + * Copyright (c) 2024 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 "FactoryDataProvider.h" + +namespace chip { +namespace DeviceLayer { + +class OptigaFactoryDataProvider : public FactoryDataProvider +{ +public: + // ===== Members functions that implement the DeviceAttestationCredentialsProvider + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_dac_buffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_signature_buffer) override; + +protected: + CHIP_ERROR SignWithOptigaDeviceAttestationKey(const ByteSpan & digest, MutableByteSpan & signature); +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.cpp b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.cpp new file mode 100644 index 00000000000000..9d56181d6bd79b --- /dev/null +++ b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.cpp @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2024 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 "UnprovisionedOptigaFactoryDataProvider.h" + +#include +#include + +using namespace chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::Init() +{ + ReturnErrorOnFailure(OptigaFactoryDataProvider::Init()); + + if (CYW30739Config::ConfigValueExists(CYW30739Config::kConfigKey_ProvisioningDAC)) + { + if (!ChipError::IsSuccess(CheckProvisionedDataValidity())) + { + ReturnErrorOnFailure(ProvisionDataOnce()); + } + + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningDAC); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningPAICert); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningSecret); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningSecretMetaData); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningDACMetaData); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningDACKeyMetaData); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningManifest); + CYW30739Config::ClearConfigValue(CYW30739Config::kConfigKey_ProvisioningFragment); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::ProvisionDataOnce() +{ + constexpr struct + { + CYW30739Config::Key key; + uint16_t object_id; + uint8_t object_type; + } configs[] = { + { CYW30739Config::kConfigKey_ProvisioningDAC, OPTIGA_DAC_OBJECT_ID, OPTIGA_OBJECT_DATA }, + { CYW30739Config::kConfigKey_ProvisioningPAICert, OPTIGA_PAI_CERT_OBJECT_ID, OPTIGA_OBJECT_DATA }, + { CYW30739Config::kConfigKey_ProvisioningSecret, OPTIGA_SECRET_OBJECT_ID, OPTIGA_OBJECT_DATA }, + { CYW30739Config::kConfigKey_ProvisioningSecretMetaData, OPTIGA_SECRET_OBJECT_ID, OPTIGA_OBJECT_METADATA }, + { CYW30739Config::kConfigKey_ProvisioningDACMetaData, OPTIGA_DAC_OBJECT_ID, OPTIGA_OBJECT_METADATA }, + { CYW30739Config::kConfigKey_ProvisioningDACKeyMetaData, OPTIGA_DAC_KEY_OBJECT_ID, OPTIGA_OBJECT_METADATA }, + }; + + ChipLogProgress(DeviceLayer, "Provisioning Optiga data"); + + for (size_t i = 0; i < ArraySize(configs); i++) + { + ProvisionDataFromConfig(configs[i].key, configs[i].object_id, configs[i].object_type); + } + + ProvisionProtectedData(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::ProvisionDataFromConfig(CYW30739Config::Key key, uint16_t object_id, + uint8_t object_type) +{ + size_t read_size; + uint8_t buf[Credentials::kMaxDERCertLength]; + MutableByteSpan buf_span(buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(key, buf_span.data(), buf_span.size(), read_size)); + buf_span.reduce_size(read_size); + + VerifyOrReturnError(wiced_optiga_write_data(object_id, object_type, buf_span.data(), buf_span.size()) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::CheckProvisionedDataValidity() +{ + uint8_t digest_buf[Crypto::kSHA256_Hash_Length]; + MutableByteSpan digest_span(digest_buf); + ReturnErrorOnFailure(Crypto::DRBG_get_bytes(digest_span.data(), digest_span.size())); + + uint8_t signature_buffer[Crypto::kMax_ECDSA_Signature_Length_Der]; + MutableByteSpan signature_span(signature_buffer); + ReturnErrorOnFailure(SignWithOptigaDeviceAttestationKey(digest_span, signature_span)); + + ReturnErrorOnFailure(VerifyOptigaSignature(digest_span, signature_span, OPTIGA_DAC_OBJECT_ID)); + + Crypto::P256PublicKey dac_public_key; + ReturnErrorOnFailure(GetDeviceAttestationCertPublicKey(dac_public_key)); + ReturnErrorOnFailure(VerifyOptigaSignature(digest_span, signature_span, dac_public_key)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::ProvisionProtectedData() +{ + constexpr size_t kMaxManifestLength = 256; + uint8_t buf[kMaxManifestLength]; + size_t read_size; + + /* Update the manifest */ + MutableByteSpan manifest_span(buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_ProvisioningManifest, manifest_span.data(), + manifest_span.size(), read_size)); + manifest_span.reduce_size(read_size); + + VerifyOrReturnError(wiced_optiga_protected_update_start(1, manifest_span.data(), manifest_span.size()) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + + /* Update the fragment */ + MutableByteSpan fragment_span(buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_ProvisioningFragment, fragment_span.data(), + fragment_span.size(), read_size)); + fragment_span.reduce_size(read_size); + + VerifyOrReturnError(wiced_optiga_protected_update_final(fragment_span.data(), fragment_span.size()) == WICED_SUCCESS, + CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, + uint16_t public_key) +{ + VerifyOrReturnError(wiced_optiga_ecdsa_verify(digest.data(), digest.size(), signature.data(), signature.size(), + OPTIGA_CRYPT_OID_DATA, &public_key) == WICED_SUCCESS, + CHIP_ERROR_INVALID_SIGNATURE); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, + Crypto::P256PublicKey & public_key) +{ + VerifyOrReturnError(public_key.Length() == Crypto::kP256_PublicKey_Length, CHIP_ERROR_INVALID_PUBLIC_KEY); + + constexpr uint8_t kOptigaDerBitstringTag = 0x03; + constexpr uint8_t kOptigaDerAdditionalLength = 0x01; + constexpr uint8_t kOptigaDerNumUnusedBits = 0x00; + constexpr size_t kOptigaPublicKeyHeaderLength = 3; + static uint8_t host_public_key[kOptigaPublicKeyHeaderLength + Crypto::kP256_PublicKey_Length] = { + [0] = kOptigaDerBitstringTag, + [1] = kOptigaDerAdditionalLength + Crypto::kP256_PublicKey_Length, + [2] = kOptigaDerNumUnusedBits, + }; + memcpy(host_public_key + kOptigaPublicKeyHeaderLength, public_key, public_key.Length()); + const public_key_from_host_t public_key_from_host = { + .public_key = host_public_key, + .length = sizeof(host_public_key), + .key_type = OPTIGA_ECC_CURVE_NIST_P_256, + }; + VerifyOrReturnError(wiced_optiga_ecdsa_verify(digest.data(), digest.size(), signature.data(), signature.size(), + OPTIGA_CRYPT_HOST_DATA, &public_key_from_host) == WICED_SUCCESS, + CHIP_ERROR_INVALID_SIGNATURE); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR UnprovisionedOptigaFactoryDataProvider::GetDeviceAttestationCertPublicKey(Crypto::P256PublicKey & public_key) +{ + size_t read_size; + uint8_t dac_buf[Credentials::kMaxDERCertLength]; + MutableByteSpan dac_span(dac_buf); + ReturnErrorOnFailure(CYW30739Config::ReadConfigValueBin(CYW30739Config::kConfigKey_ProvisioningDAC, dac_span.data(), + dac_span.size(), read_size)); + dac_span.reduce_size(read_size); + + ReturnErrorOnFailure(ExtractPubkeyFromX509Cert(dac_span, public_key)); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.h b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.h new file mode 100644 index 00000000000000..8c746ee0210aac --- /dev/null +++ b/src/platform/Infineon/CYW30739/UnprovisionedOptigaFactoryDataProvider.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2024 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 "OptigaFactoryDataProvider.h" + +#include + +namespace chip { +namespace DeviceLayer { + +class UnprovisionedOptigaFactoryDataProvider : public OptigaFactoryDataProvider +{ +public: + CHIP_ERROR Init(); + +private: + CHIP_ERROR ProvisionDataOnce(); + CHIP_ERROR ProvisionDataFromConfig(Internal::CYW30739Config::Key key, uint16_t object_id, uint8_t object_type); + CHIP_ERROR CheckProvisionedDataValidity(); + CHIP_ERROR ProvisionProtectedData(); + CHIP_ERROR VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, uint16_t public_key); + CHIP_ERROR VerifyOptigaSignature(MutableByteSpan & digest, MutableByteSpan & signature, Crypto::P256PublicKey & public_key); + CHIP_ERROR GetDeviceAttestationCertPublicKey(Crypto::P256PublicKey & public_key); +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Infineon/CYW30739/args.gni b/src/platform/Infineon/CYW30739/args.gni index 11bfab9379ff68..84a72321b420bd 100644 --- a/src/platform/Infineon/CYW30739/args.gni +++ b/src/platform/Infineon/CYW30739/args.gni @@ -65,3 +65,5 @@ openthread_config_ip6_slaac_enable = true openthread_config_joiner_enable = true openthread_config_log_output = "platform_defined" openthread_config_srp_client_enable = true + +optiga_trust_m_dir = "${chip_root}/third_party/infineon/trustm/optiga-trust-m" diff --git a/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h b/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h index 1446a2d3d7b3a9..c6e275d4521f69 100644 --- a/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h +++ b/src/platform/Infineon/CYW30739/cyw30739-chip-mbedtls-config.h @@ -188,6 +188,39 @@ */ #define MBEDTLS_PKCS5_C +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, + * MBEDTLS_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define MBEDTLS_X509_USE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ + +#define MBEDTLS_X509_CRT_PARSE_C /** * \def MBEDTLS_X509_CREATE_C * diff --git a/src/platform/Infineon/CYW30739/cyw30739_platform.gni b/src/platform/Infineon/CYW30739/cyw30739_platform.gni index 367727207e506b..9854a590b99841 100644 --- a/src/platform/Infineon/CYW30739/cyw30739_platform.gni +++ b/src/platform/Infineon/CYW30739/cyw30739_platform.gni @@ -20,7 +20,7 @@ import("${chip_root}/src/platform/Infineon/CYW30739/args.gni") cyw30739_platform_dir = "${chip_root}/src/platform/Infineon/CYW30739" template("cyw30739_platform") { - forward_variables_from(invoker, [ "chip_family" ]) + forward_variables_from(invoker, [ "board" ]) static_library(target_name) { sources = [ @@ -29,6 +29,7 @@ template("cyw30739_platform") { "${cyw30739_platform_dir}/ConfigurationManagerImpl.cpp", "${cyw30739_platform_dir}/DiagnosticDataProviderImpl.cpp", "${cyw30739_platform_dir}/EventFlags.cpp", + "${cyw30739_platform_dir}/FactoryDataProvider.cpp", "${cyw30739_platform_dir}/Logging.cpp", "${cyw30739_platform_dir}/OTAImageProcessorImpl.cpp", "${cyw30739_platform_dir}/PlatformManagerImpl.cpp", @@ -40,8 +41,14 @@ template("cyw30739_platform") { sources += [ "${cyw30739_platform_dir}/ThreadStackManagerImpl.cpp" ] } - configs += - [ "${matter_wpan_sdk_build_root}:wpan_sdk-${chip_family}-config" ] + if (invoker.board_use_optiga) { + sources += [ + "${cyw30739_platform_dir}/OptigaFactoryDataProvider.cpp", + "${cyw30739_platform_dir}/UnprovisionedOptigaFactoryDataProvider.cpp", + ] + } + + configs += [ "${matter_wpan_sdk_build_root}:${board}-config" ] deps = [ "${chip_root}/src/platform:platform", diff --git a/third_party/infineon/repos/matter-wpan-sdk b/third_party/infineon/repos/matter-wpan-sdk index f6e196cbd982cf..6086f0a77620a3 160000 --- a/third_party/infineon/repos/matter-wpan-sdk +++ b/third_party/infineon/repos/matter-wpan-sdk @@ -1 +1 @@ -Subproject commit f6e196cbd982cfd4c74ffca6ba4128dba298b8ac +Subproject commit 6086f0a77620a33af7ef1ae95c1d6bd959f8a5e0