From 70bffa82e4ef3cc1afde3d9c50fc5d27d7f89baf Mon Sep 17 00:00:00 2001 From: Ricardo Casallas Date: Mon, 27 Jun 2022 09:58:30 -0400 Subject: [PATCH] EFR32: DeviceAttestationCredentialsProvider implemented. --- examples/chef/efr32/src/AppTask.cpp | 8 ++ .../light-switch-app/efr32/src/AppTask.cpp | 8 ++ examples/lighting-app/efr32/src/AppTask.cpp | 8 ++ examples/lock-app/efr32/src/AppTask.cpp | 8 ++ examples/platform/efr32/efr32_certs.h | 17 ++++ examples/window-app/common/src/WindowApp.cpp | 8 ++ .../operational-credentials-server.cpp | 1 - src/credentials/BUILD.gn | 17 ++-- src/platform/EFR32/BUILD.gn | 6 ++ .../EFR32/DeviceAttestationCredsImpl.cpp | 92 +++++++++++++++++++ .../EFR32/DeviceAttestationCredsImpl.h | 36 ++++++++ src/platform/device.gni | 3 + third_party/silabs/efr32_sdk.gni | 13 +++ 13 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 examples/platform/efr32/efr32_certs.h create mode 100644 src/platform/EFR32/DeviceAttestationCredsImpl.cpp create mode 100644 src/platform/EFR32/DeviceAttestationCredsImpl.h diff --git a/examples/chef/efr32/src/AppTask.cpp b/examples/chef/efr32/src/AppTask.cpp index 15ff91d64a5fa6..cce862a5120bef 100644 --- a/examples/chef/efr32/src/AppTask.cpp +++ b/examples/chef/efr32/src/AppTask.cpp @@ -44,7 +44,11 @@ #include #include +#ifdef DEVICE_ATTESTATION_CREDENTIALS +#include +#else #include +#endif #include #include @@ -207,7 +211,11 @@ CHIP_ERROR AppTask::Init() chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config +#ifdef DEVICE_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(EFR32::GetDACProvider()); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif chip::DeviceLayer::PlatformMgr().UnlockChipStack(); // Create FreeRTOS sw timer for Function Selection. diff --git a/examples/light-switch-app/efr32/src/AppTask.cpp b/examples/light-switch-app/efr32/src/AppTask.cpp index fe982497bd6245..004992d132bfa5 100644 --- a/examples/light-switch-app/efr32/src/AppTask.cpp +++ b/examples/light-switch-app/efr32/src/AppTask.cpp @@ -42,7 +42,11 @@ #include #include +#ifdef DEVICE_ATTESTATION_CREDENTIALS +#include +#else #include +#endif #include #include @@ -198,7 +202,11 @@ CHIP_ERROR AppTask::Init() chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config +#ifdef DEVICE_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(EFR32::GetDACProvider()); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif chip::DeviceLayer::PlatformMgr().UnlockChipStack(); // Create FreeRTOS sw timer for Function Selection. diff --git a/examples/lighting-app/efr32/src/AppTask.cpp b/examples/lighting-app/efr32/src/AppTask.cpp index 7e1e8d9a811e82..6280e051f48cb2 100644 --- a/examples/lighting-app/efr32/src/AppTask.cpp +++ b/examples/lighting-app/efr32/src/AppTask.cpp @@ -40,7 +40,11 @@ #include #include +#ifdef DEVICE_ATTESTATION_CREDENTIALS +#include +#else #include +#endif #include #include @@ -203,7 +207,11 @@ CHIP_ERROR AppTask::Init() chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config +#ifdef DEVICE_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(EFR32::GetDACProvider()); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif chip::DeviceLayer::PlatformMgr().UnlockChipStack(); // Create FreeRTOS sw timer for Function Selection. diff --git a/examples/lock-app/efr32/src/AppTask.cpp b/examples/lock-app/efr32/src/AppTask.cpp index d3cc7e9a6f17d6..0d66f3b7330986 100644 --- a/examples/lock-app/efr32/src/AppTask.cpp +++ b/examples/lock-app/efr32/src/AppTask.cpp @@ -44,7 +44,11 @@ #include #include +#ifdef DEVICE_ATTESTATION_CREDENTIALS +#include +#else #include +#endif #include #include @@ -212,7 +216,11 @@ CHIP_ERROR AppTask::Init() chip::DeviceLayer::PlatformMgr().LockChipStack(); // Initialize device attestation config +#ifdef DEVICE_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(EFR32::GetDACProvider()); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif chip::DeviceLayer::PlatformMgr().UnlockChipStack(); // Create FreeRTOS sw timer for Function Selection. diff --git a/examples/platform/efr32/efr32_certs.h b/examples/platform/efr32/efr32_certs.h new file mode 100644 index 00000000000000..ebfdec0c985404 --- /dev/null +++ b/examples/platform/efr32/efr32_certs.h @@ -0,0 +1,17 @@ +#ifndef MATTER_MFG_TOKENS_EFR32 +#define MATTER_MFG_TOKENS_EFR32 + +#include "psa/crypto.h" + +#define EFR32_CERTS_DAC_ID PSA_KEY_ID_USER_MIN + 1 + +#define CREATOR_MFG_MATTER_CD (USERDATA_TOKENS | 0x200) // 4 bytes +#define CREATOR_MFG_MATTER_PAI (USERDATA_TOKENS | 0x420) // 4 bytes +#define CREATOR_MFG_MATTER_DAC (USERDATA_TOKENS | 0x5F0) // 4 bytes + +#define MFG_MATTER_CD_SIZE 541 +#define MFG_MATTER_PAI_SIZE 463 +#define MFG_MATTER_DAC_SIZE 492 +#define MFG_MATTER_DAC_KEY_ID PSA_KEY_ID_USER_MIN + 1 + +#endif // MATTER_MFG_TOKENS_EFR32 diff --git a/examples/window-app/common/src/WindowApp.cpp b/examples/window-app/common/src/WindowApp.cpp index 4c846ecf6a8c05..c4cf624d9f4e10 100644 --- a/examples/window-app/common/src/WindowApp.cpp +++ b/examples/window-app/common/src/WindowApp.cpp @@ -22,7 +22,11 @@ #include #include #include +#ifdef DEVICE_ATTESTATION_CREDENTIALS +#include +#else #include +#endif #include #include @@ -113,7 +117,11 @@ WindowApp::Cover * WindowApp::GetCover(chip::EndpointId endpoint) CHIP_ERROR WindowApp::Init() { // Initialize device attestation config +#ifdef DEVICE_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(EFR32::GetDACProvider()); +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif ConfigurationMgr().LogDeviceConfig(); diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index e7f71c0e3a67cf..37ac71aee1854c 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index ad809326b892d2..875cc378350584 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -47,16 +47,21 @@ static_library("credentials") { "attestation_verifier/DeviceAttestationDelegate.h", "attestation_verifier/DeviceAttestationVerifier.cpp", "attestation_verifier/DeviceAttestationVerifier.h", - "examples/DeviceAttestationCredsExample.cpp", - "examples/DeviceAttestationCredsExample.h", - "examples/ExampleDACs.cpp", - "examples/ExampleDACs.h", - "examples/ExamplePAI.cpp", - "examples/ExamplePAI.h", "examples/LastKnownGoodTimeCertificateValidityPolicyExample.h", "examples/StrictCertificateValidityPolicyExample.h", ] + if (!chip_device_attestation_credentials) { + sources += [ + "examples/DeviceAttestationCredsExample.cpp", + "examples/DeviceAttestationCredsExample.h", + "examples/ExampleDACs.cpp", + "examples/ExampleDACs.h", + "examples/ExamplePAI.cpp", + "examples/ExamplePAI.h", + ] + } + # TODO: These tests files should be removed after the DeviceAttestationCredsExample implementation # is changed to generate it's own credentials instead of using Test credentials. # For mbed and nrfconnect test builds, which are bilding monolithic test library these files are not needed. diff --git a/src/platform/EFR32/BUILD.gn b/src/platform/EFR32/BUILD.gn index a50db957df5e48..4b16c79f4472bb 100644 --- a/src/platform/EFR32/BUILD.gn +++ b/src/platform/EFR32/BUILD.gn @@ -25,6 +25,7 @@ if (chip_enable_openthread) { static_library("EFR32") { sources = [ + "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", "../FreeRTOS/SystemTimeSupport.cpp", "../SingletonConfigurationManager.cpp", "BLEManagerImpl.cpp", @@ -56,6 +57,11 @@ static_library("EFR32") { "gatt_db.h", ] + if (chip_device_attestation_credentials) { + defines = [ "DEVICE_ATTESTATION_CREDENTIALS=1" ] + sources += [ "DeviceAttestationCredsImpl.cpp" ] + } + if (chip_enable_ota_requestor) { sources += [ "OTAImageProcessorImpl.cpp", diff --git a/src/platform/EFR32/DeviceAttestationCredsImpl.cpp b/src/platform/EFR32/DeviceAttestationCredsImpl.cpp new file mode 100644 index 00000000000000..56b01f4a944dbb --- /dev/null +++ b/src/platform/EFR32/DeviceAttestationCredsImpl.cpp @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2021 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 "DeviceAttestationCredsImpl.h" +#include +#include +#include + +#include "efr32_certs.h" +#include "psa/crypto.h" +#include "sl_token_api.h" +#include "sl_token_manager.h" +#include + +namespace chip { +namespace Credentials { +namespace EFR32 { + +namespace { + +class DeviceAttestationCredsImpl : public DeviceAttestationCredentialsProvider +{ +public: + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & out_buffer) override + { + uint8_t cd_buf[MFG_MATTER_CD_SIZE]; + int err = sl_token_get_data(CREATOR_MFG_MATTER_CD, 0, cd_buf, sizeof(cd_buf)); + VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL); + return CopySpanToMutableSpan(ByteSpan(cd_buf), out_buffer); + } + + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override + { + // TODO: We need a real example FirmwareInformation to be populated. + out_firmware_info_buffer.reduce_size(0); + return CHIP_NO_ERROR; + } + + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_buffer) override + { + uint8_t cert_buf[MFG_MATTER_PAI_SIZE]; + int err = sl_token_get_data(CREATOR_MFG_MATTER_DAC, 0, cert_buf, sizeof(cert_buf)); + VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL); + return CopySpanToMutableSpan(ByteSpan(cert_buf), out_buffer); + } + + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_pai_buffer) override + { + uint8_t cert_buf[MFG_MATTER_DAC_SIZE]; + int err = sl_token_get_data(CREATOR_MFG_MATTER_PAI, 0, cert_buf, sizeof(cert_buf)); + VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL); + return CopySpanToMutableSpan(ByteSpan(cert_buf), out_pai_buffer); + } + + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & digest_to_sign, MutableByteSpan & out_buffer) override + { + psa_key_id_t key_id = MFG_MATTER_DAC_KEY_ID; + uint8_t signature[512]; + size_t signature_length = 0; + psa_status_t err = psa_sign_message(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest_to_sign.data(), digest_to_sign.size(), + signature, sizeof(signature), &signature_length); + ChipLogDetail(MessageLayer, "~ SignWithDeviceAttestationKey, err:%ld, size:%zu\n", err, signature_length); + VerifyOrReturnError(!err, CHIP_ERROR_INTERNAL); + + return CopySpanToMutableSpan(ByteSpan{ signature, signature_length }, out_buffer); + } +}; + +} // namespace + +DeviceAttestationCredentialsProvider * GetDACProvider() +{ + static DeviceAttestationCredsImpl dac_provider; + return &dac_provider; +} + +} // namespace EFR32 +} // namespace Credentials +} // namespace chip diff --git a/src/platform/EFR32/DeviceAttestationCredsImpl.h b/src/platform/EFR32/DeviceAttestationCredsImpl.h new file mode 100644 index 00000000000000..3ef42471938704 --- /dev/null +++ b/src/platform/EFR32/DeviceAttestationCredsImpl.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +namespace chip { +namespace Credentials { +namespace EFR32 { + +/** + * @brief Get implementation of a sample DAC provider to validate device + * attestation procedure. + * + * @returns a singleton DeviceAttestationCredentialsProvider that relies on no + * storage abstractions. + */ +DeviceAttestationCredentialsProvider * GetDACProvider(); + +} // namespace EFR32 +} // namespace Credentials +} // namespace chip diff --git a/src/platform/device.gni b/src/platform/device.gni index 8bf94a7e788ae0..0c6697ebbda8cf 100755 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -23,6 +23,9 @@ declare_args() { # Substitute fake platform when building with chip_device_platform=auto. chip_fake_platform = false + + # Use actual device attestation credentials + chip_device_attestation_credentials = false } if (chip_device_platform == "auto") { diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 6e2ec20615d7ed..a40cda2108c7b3 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -103,6 +103,13 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/service/sleeptimer/config", "${efr32_sdk_root}/platform/service/system/inc", "${efr32_sdk_root}/platform/service/udelay/inc", + "${efr32_sdk_root}/platform/service/legacy_hal/inc", + "${efr32_sdk_root}/platform/service/token_manager/config", + "${efr32_sdk_root}/platform/service/token_manager/inc", + "${efr32_sdk_root}/platform/service/token_manager/test", + "${efr32_sdk_root}/platform/service/token_manager/test/include", + "${efr32_sdk_root}/platform/service/token_manager/test/stack/config", + "${efr32_sdk_root}/platform/service/token_manager/test/stack/include", "${efr32_sdk_root}/platform/middleware/glib", "${efr32_sdk_root}/platform/middleware/glib/glib", "${efr32_sdk_root}/platform/middleware/glib/dmd", @@ -153,6 +160,8 @@ template("efr32_sdk") { "MBEDTLS_THREADING_ALT=1", "SL_THREADING_ALT=1", "SL_COMPONENT_CATALOG_PRESENT", + "PLATFORM_HEADER=\"platform-header.h\"", + "USE_NVM3=1", #"__STACK_SIZE=0", ] @@ -346,6 +355,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_pti/sl_rail_util_pti.c", "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_nvic.c", "${efr32_sdk_root}/platform/service/hfxo_manager/src/sl_hfxo_manager.c", + "${efr32_sdk_root}/platform/service/legacy_hal/src/token_legacy.c", "${efr32_sdk_root}/platform/service/mpu/src/sl_mpu.c", "${efr32_sdk_root}/platform/service/power_manager/src/sl_power_manager.c", "${efr32_sdk_root}/platform/service/power_manager/src/sl_power_manager_debug.c", @@ -357,6 +367,9 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/service/system/src/sl_system_init.c", "${efr32_sdk_root}/platform/service/system/src/sl_system_kernel.c", "${efr32_sdk_root}/platform/service/system/src/sl_system_process_action.c", + "${efr32_sdk_root}/platform/service/token_manager/src/sl_token_def.c", + "${efr32_sdk_root}/platform/service/token_manager/src/sl_token_manager.c", + "${efr32_sdk_root}/platform/service/token_manager/src/sl_token_manufacturing.c", "${efr32_sdk_root}/platform/service/udelay/src/sl_udelay.c", "${efr32_sdk_root}/platform/service/udelay/src/sl_udelay_armv6m_gcc.S", "${efr32_sdk_root}/protocol/bluetooth/src/sl_bt_mbedtls_context.c",