From 151dc967eb0454f86b650ecb825ae594a3afba63 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Tue, 19 Dec 2023 12:15:32 +0530 Subject: [PATCH 1/6] [ESP32] Added an API to set the CD in DAC providers --- config/esp32/components/chip/Kconfig | 9 ++++++++ .../ESP32/ESP32FactoryDataProvider.cpp | 4 ++++ src/platform/ESP32/ESP32FactoryDataProvider.h | 21 +++++++++++++++++++ .../ESP32/ESP32SecureCertDACProvider.cpp | 4 ++++ .../ESP32/ESP32SecureCertDACProvider.h | 21 +++++++++++++++++++ 5 files changed, 59 insertions(+) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index ec2ab1a6b26d64..d616603c6bb03d 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -867,6 +867,15 @@ menu "CHIP Device Layer" then this option gets enabled. Also, please disable ESP_SECURE_CERT_DS_PERIPHERAL from the menuconfig when this option is disabled + config ENABLE_SET_CERT_DECLARATION_API + depends on ENABLE_ESP32_FACTORY_DATA_PROVIDER || SEC_CERT_DAC_PROVIDER + bool "Enable Set CD API" + default n + help + By default, the implementation reads the Certification Declaration (CD) from the 'chip-factory' + NVS namespace. If this option is enabled, the application can use an API to set a CD, + the configured CD will be used for subsequent CD reads. + config ENABLE_ESP_INSIGHTS_TRACE bool "Enable Matter ESP Insights" depends on ESP_INSIGHTS_ENABLED diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index 1066955292d6fd..4ff4f9d2d29678 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -123,11 +123,15 @@ CHIP_ERROR ESP32FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & CHIP_ERROR ESP32FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_PAICert, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.h b/src/platform/ESP32/ESP32FactoryDataProvider.h index d69e64ffd1fcc1..b5566cc89afbe0 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.h +++ b/src/platform/ESP32/ESP32FactoryDataProvider.h @@ -60,6 +60,22 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + /** + * API to set the CD. + * + * GetCertificationDeclaration() API impl reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different place, eg: embedded in the firmware. + * Subsequent reads after calling this API will return the set CD. + */ + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) + { + VerifyOrReturnError(!cd.empty(), CHIP_ERROR_INVALID_ARGUMENT); + mCD = cd; + return CHIP_NO_ERROR; + } +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + #if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER // ===== Members functions that implement the GenericDeviceInstanceInfoProvider CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; @@ -75,6 +91,11 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; #endif // CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER + +private: +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + ByteSpan mCD; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API }; } // namespace DeviceLayer diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.cpp b/src/platform/ESP32/ESP32SecureCertDACProvider.cpp index 1b06224318231c..a1bdedf03e1711 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.cpp +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.cpp @@ -55,11 +55,15 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P CHIP_ERROR ESP32SecureCertDACProvider ::GetCertificationDeclaration(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CertDeclaration, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32SecureCertDACProvider ::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.h b/src/platform/ESP32/ESP32SecureCertDACProvider.h index 997695aec0ec74..94866d5e0e125e 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.h +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.h @@ -31,6 +31,27 @@ class ESP32SecureCertDACProvider : public Credentials::DeviceAttestationCredenti CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + /** + * API to set the CD. + * + * GetCertificationDeclaration() API impl reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different place, eg: embedded in the firmware. + * Subsequent reads after calling this API will return the set CD. + */ + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) + { + VerifyOrReturnError(!cd.empty(), CHIP_ERROR_INVALID_ARGUMENT); + mCD = cd; + return CHIP_NO_ERROR; + } +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + +private: +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + ByteSpan mCD; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API }; } // namespace DeviceLayer } // namespace chip From f0546a51e8a3c23017df7aeeebd345f0c3d2ef26 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Tue, 19 Dec 2023 12:21:17 +0530 Subject: [PATCH 2/6] Usage of SetCertificationDeclaration() API in lighting-app/esp32 --- examples/lighting-app/esp32/README.md | 17 ++++++++--------- examples/lighting-app/esp32/main/CMakeLists.txt | 4 ++++ examples/lighting-app/esp32/main/main.cpp | 14 +++++++++++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/examples/lighting-app/esp32/README.md b/examples/lighting-app/esp32/README.md index 5a6f9be37d286a..63b65f760f009b 100644 --- a/examples/lighting-app/esp32/README.md +++ b/examples/lighting-app/esp32/README.md @@ -16,8 +16,8 @@ guides to get started. - Create a file named insights_auth_key.txt in the main directory of the example. -- Follow the steps - present[here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) +- Follow the steps present + [here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) to set up an insights_account and the auth key created while setting it up will be used in the example. @@ -27,13 +27,6 @@ guides to get started. cp /path/to/auth/key.txt path/to/connectedhomeip/examples/lighting-app/esp32/main/insights_auth_key.txt ``` ---- - -- [Cluster Control](#cluster-control) -- [Matter OTA guide](../../../docs/guides/esp32/ota.md) - ---- - ### Cluster Control - After successful commissioning, use the OnOff cluster command to control the @@ -50,3 +43,9 @@ cp /path/to/auth/key.txt path/to/connectedhomeip/examples/lighting-app/esp32/mai control the color attributes: $ ./out/debug/chip-tool colorcontrol move-to-hue-and-saturation 240 100 0 0 0 1 + +--- + +- [Matter OTA guide](../../../docs/guides/esp32/ota.md) + +--- diff --git a/examples/lighting-app/esp32/main/CMakeLists.txt b/examples/lighting-app/esp32/main/CMakeLists.txt index 96279bd4d83dde..a7cc4136145981 100644 --- a/examples/lighting-app/esp32/main/CMakeLists.txt +++ b/examples/lighting-app/esp32/main/CMakeLists.txt @@ -111,6 +111,10 @@ if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE) target_add_binary_data(${COMPONENT_TARGET} "insights_auth_key.txt" TEXT) endif() +if (CONFIG_ENABLE_SET_CERT_DECLARATION_API) + target_add_binary_data(${COMPONENT_TARGET} "certification_declaration.der" BINARY) +endif() + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC diff --git a/examples/lighting-app/esp32/main/main.cpp b/examples/lighting-app/esp32/main/main.cpp index adb2bafd84f577..120c004782c895 100644 --- a/examples/lighting-app/esp32/main/main.cpp +++ b/examples/lighting-app/esp32/main/main.cpp @@ -100,13 +100,25 @@ DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; DeviceLayer::ESP32SecureCertDACProvider gSecureCertDACProvider; #endif // CONFIG_SEC_CERT_DAC_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API +extern const uint8_t cd_start[] asm("_binary_certification_declaration_der_start"); +extern const uint8_t cd_end[] asm("_binary_certification_declaration_der_end"); +ByteSpan cdSpan(cd_start, static_cast(cd_end - cd_start)); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void) { #if CONFIG_SEC_CERT_DAC_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + gSecureCertDACProvider.SetCertificationDeclaration(cdSpan); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API return &gSecureCertDACProvider; #elif CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + sFactoryDataProvider.SetCertificationDeclaration(cdSpan); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API return &sFactoryDataProvider; -#else // EXAMPLE_DAC_PROVIDER +#else // EXAMPLE_DAC_PROVIDER return chip::Credentials::Examples::GetExampleDACProvider(); #endif } From 1e486cf432485ab6875af659b05baca422c776c3 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Tue, 19 Dec 2023 12:22:35 +0530 Subject: [PATCH 3/6] [docs] Added some references for production workflows --- docs/guides/esp32/factory_data.md | 29 +++++++++++++++++++++- docs/guides/esp32/secure_cert_partition.md | 25 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/docs/guides/esp32/factory_data.md b/docs/guides/esp32/factory_data.md index 179fb2e315a9c0..1686e6f08f5b19 100644 --- a/docs/guides/esp32/factory_data.md +++ b/docs/guides/esp32/factory_data.md @@ -1,5 +1,21 @@ ## Using ESP32 Factory Data Provider +--- + +**WARNING:** The following steps outline the development workflow for building a +matter device. + +Please take a look at +[security considerations](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/security.html) +and review the security guidelines outlined in +[security workflow](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/host-based-security-workflows.html) +for production workflows. + +Ensure to select the appropriate SoC from the menu on the left-hand side, as the +provided references are specific to ESP32. + +--- + By default applications uses test-mode or default commissionable data provider, device attestation credentials provider, device instance info provider, and device info provider. @@ -47,6 +63,15 @@ specific implementation of `CommissionableDataProvider` and [Component config → CHIP Device Layer → Commissioning options → Use ESP32 Factory Data Provider] +By default, the factory data provider implementation reads the Certification +Declaration (CD) from the 'chip-factory' NVS namespace. Enable +`CONFIG_ENABLE_SET_CERT_DECLARATION_API` option to enable an API which lets you +set the CD from the application and the configured CD will be used for +subsequent CD reads. + +[Component config -> CHIP Device Layer -> Commissioning options -> Enable Set CD +API] + Enable config option `CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER` to use ESP32 specific implementation of `DeviceInstanceInfoProvider`. @@ -107,4 +132,6 @@ appropriate address. ### Securing NVS binary image with NVS Encryption -Please check [Flash and NVS encryption guide](flash_nvs_encryption.md) +WARNING: NVS binary image may contain the sensitive information and it must be +secured using NVS encryption. For more details please check +[Flash and NVS encryption guide](flash_nvs_encryption.md) diff --git a/docs/guides/esp32/secure_cert_partition.md b/docs/guides/esp32/secure_cert_partition.md index 40d40d92d4432a..5982b750a74b86 100644 --- a/docs/guides/esp32/secure_cert_partition.md +++ b/docs/guides/esp32/secure_cert_partition.md @@ -1,5 +1,21 @@ # Using esp_secure_cert partition +--- + +**WARNING:** The following steps outline the development workflow for building a +matter device. + +Please take a look at +[security considerations](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/security.html) +and review the security guidelines outlined in +[security workflow](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/host-based-security-workflows.html) +for production workflows. + +Ensure to select the appropriate SoC from the menu on the left-hand side, as the +provided references are specific to ESP32. + +--- + ## 1.1 ESP Secure Cert Partition - When a device is pre-provisioned, PKI credentials are generated for the @@ -177,6 +193,15 @@ CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER=y CONFIG_CHIP_FACTORY_NAMESPACE_PARTITION_LABEL="fctry" ``` +By default, the secure cert DAC provider implementation reads the Certification +Declaration (CD) from the 'chip-factory' NVS namespace. Enable +`CONFIG_ENABLE_SET_CERT_DECLARATION_API` option to enable an API which lets you +set the CD from the application and the configured CD will be used for +subsequent CD reads. + +[Component config -> CHIP Device Layer -> Commissioning options -> Enable Set CD +API] + In order to use the esp_secure_cert_partition, in addition to enabling the above config options, you should also have the esp_secure_cert_partition and factory partition in your app. For reference, refer to partitions.csv file of From d757fb057f74afdced02dd15910ce6dec424dfad Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Tue, 19 Dec 2023 15:07:06 +0530 Subject: [PATCH 4/6] fix the readme files --- docs/guides/esp32/factory_data.md | 2 -- docs/guides/esp32/secure_cert_partition.md | 2 -- examples/lighting-app/esp32/README.md | 7 +++---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/docs/guides/esp32/factory_data.md b/docs/guides/esp32/factory_data.md index 1686e6f08f5b19..9ea2e12d1a87d3 100644 --- a/docs/guides/esp32/factory_data.md +++ b/docs/guides/esp32/factory_data.md @@ -1,7 +1,5 @@ ## Using ESP32 Factory Data Provider ---- - **WARNING:** The following steps outline the development workflow for building a matter device. diff --git a/docs/guides/esp32/secure_cert_partition.md b/docs/guides/esp32/secure_cert_partition.md index 5982b750a74b86..cef971f30f0910 100644 --- a/docs/guides/esp32/secure_cert_partition.md +++ b/docs/guides/esp32/secure_cert_partition.md @@ -1,7 +1,5 @@ # Using esp_secure_cert partition ---- - **WARNING:** The following steps outline the development workflow for building a matter device. diff --git a/examples/lighting-app/esp32/README.md b/examples/lighting-app/esp32/README.md index 63b65f760f009b..3e3dc5ee0a27cf 100644 --- a/examples/lighting-app/esp32/README.md +++ b/examples/lighting-app/esp32/README.md @@ -44,8 +44,7 @@ cp /path/to/auth/key.txt path/to/connectedhomeip/examples/lighting-app/esp32/mai $ ./out/debug/chip-tool colorcontrol move-to-hue-and-saturation 240 100 0 0 0 1 ---- +### Matter OTA -- [Matter OTA guide](../../../docs/guides/esp32/ota.md) - ---- +For Matter OTA please take a look at +[Matter OTA guide](../../../docs/guides/esp32/ota.md). From e9ac9e77bd95e3f47944d4ffd1e9676a0505dfbb Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Wed, 20 Dec 2023 21:21:47 +0530 Subject: [PATCH 5/6] Add some docs for the lifetime of data --- src/platform/ESP32/ESP32FactoryDataProvider.h | 2 ++ src/platform/ESP32/ESP32SecureCertDACProvider.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.h b/src/platform/ESP32/ESP32FactoryDataProvider.h index b5566cc89afbe0..61ccd8d33d5dc6 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.h +++ b/src/platform/ESP32/ESP32FactoryDataProvider.h @@ -67,6 +67,8 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, * GetCertificationDeclaration() API impl reads the CD from the NVS namespace `chip-factory`. * Use this API to set the CD if it is stored at a different place, eg: embedded in the firmware. * Subsequent reads after calling this API will return the set CD. + * + * API do not make a copy of underlying data, and any calls made by the Matter stack shall reach it. */ CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) { diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.h b/src/platform/ESP32/ESP32SecureCertDACProvider.h index 94866d5e0e125e..78fb55bb71a993 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.h +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.h @@ -39,6 +39,8 @@ class ESP32SecureCertDACProvider : public Credentials::DeviceAttestationCredenti * GetCertificationDeclaration() API impl reads the CD from the NVS namespace `chip-factory`. * Use this API to set the CD if it is stored at a different place, eg: embedded in the firmware. * Subsequent reads after calling this API will return the set CD. + * + * API do not make a copy of underlying data, and any calls made by the Matter stack shall reach it. */ CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) { From b1713300e8912d102809976bd31ab1f8b5ce4469 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Thu, 21 Dec 2023 09:54:16 +0530 Subject: [PATCH 6/6] adjustment to the API documentation --- src/platform/ESP32/ESP32FactoryDataProvider.h | 12 ++++++++---- src/platform/ESP32/ESP32SecureCertDACProvider.h | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.h b/src/platform/ESP32/ESP32FactoryDataProvider.h index 61ccd8d33d5dc6..1d78f2c2e8fa0b 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.h +++ b/src/platform/ESP32/ESP32FactoryDataProvider.h @@ -62,13 +62,17 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, #ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API /** - * API to set the CD. + * @brief API to set the Certification Declaration (CD). * - * GetCertificationDeclaration() API impl reads the CD from the NVS namespace `chip-factory`. - * Use this API to set the CD if it is stored at a different place, eg: embedded in the firmware. + * The GetCertificationDeclaration() API implementation reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different location, e.g., embedded in the firmware. * Subsequent reads after calling this API will return the set CD. * - * API do not make a copy of underlying data, and any calls made by the Matter stack shall reach it. + * @param[in] cd ByteSpan containing the Certification Declaration. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. + * + * @return CHIP_ERROR indicating the success or failure of the operation. */ CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) { diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.h b/src/platform/ESP32/ESP32SecureCertDACProvider.h index 78fb55bb71a993..4e09c1efa1c5c0 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.h +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.h @@ -34,13 +34,17 @@ class ESP32SecureCertDACProvider : public Credentials::DeviceAttestationCredenti #ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API /** - * API to set the CD. + * @brief API to set the Certification Declaration (CD). * - * GetCertificationDeclaration() API impl reads the CD from the NVS namespace `chip-factory`. - * Use this API to set the CD if it is stored at a different place, eg: embedded in the firmware. + * The GetCertificationDeclaration() API implementation reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different location, e.g., embedded in the firmware. * Subsequent reads after calling this API will return the set CD. * - * API do not make a copy of underlying data, and any calls made by the Matter stack shall reach it. + * @param[in] cd ByteSpan containing the Certification Declaration. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. + * + * @return CHIP_ERROR indicating the success or failure of the operation. */ CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) {