Merge branch 'esp_secure_cert_partition' into 'main'

DAC Provider Implementation to read attestation information from esp_secure_cert partition

See merge request app-frameworks/esp-matter!232
This commit is contained in:
Shu Chen
2022-12-07 10:43:14 +08:00
12 changed files with 254 additions and 14 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ set(INCLUDE_DIRS_LIST "."
"${MATTER_SDK_PATH}/src"
"${ZAP_GENERATED_PATH}/../")
set(REQUIRES_LIST chip bt esp_matter_console nvs_flash app_update esp32_mbedtls esp_system route_hook)
set(REQUIRES_LIST chip bt esp_matter_console nvs_flash app_update esp_secure_cert_mgr esp32_mbedtls esp_system route_hook)
if ("${IDF_TARGET}" STREQUAL "esp32h2")
list(APPEND REQUIRES_LIST openthread esp_matter_openthread)
+24
View File
@@ -12,4 +12,28 @@ menu "ESP Matter"
help
The NVS Partition name for ESP Matter to store the NONVOLATILE attribues
choice ESP_MATTER_DAC_PROVIDER
prompt "DAC Provider options"
default EXAMPLE_DAC_PROVIDER
help
This option determines which attestation credentials provider will be used.
config EXAMPLE_DAC_PROVIDER
bool "Attestation - Test"
help
An example DAC Provider which provides test attestation information
config FACTORY_PARTITION_DAC_PROVIDER
depends on ENABLE_ESP32_FACTORY_DATA_PROVIDER
bool "Attestation - Factory"
help
An implementation which reads attestation information from the factory partition
config SEC_CERT_DAC_PROVIDER
bool "Attestation - Secure Cert"
help
An implementation which reads attestation information from the esp_secure_cert partition
endchoice
endmenu
+3 -9
View File
@@ -31,7 +31,6 @@
#include <app/server/Server.h>
#include <app/util/attribute-storage.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/DiagnosticDataProvider.h>
#include <platform/ESP32/ESP32FactoryDataProvider.h>
@@ -41,6 +40,7 @@
#endif
#include <esp_matter_ota.h>
#include <esp_route_hook.h>
#include <esp_matter_dac_provider.h>
using chip::CommandId;
using chip::DataVersion;
@@ -49,7 +49,6 @@ using chip::kInvalidCommandId;
using chip::kInvalidClusterId;
using chip::kInvalidEndpointId;
using chip::Credentials::SetDeviceAttestationCredentialsProvider;
using chip::Credentials::Examples::GetExampleDACProvider;
using chip::DeviceLayer::ChipDeviceEvent;
using chip::DeviceLayer::ConfigurationMgr;
using chip::DeviceLayer::ConnectivityManager;
@@ -876,20 +875,15 @@ static esp_err_t chip_init(event_callback_t callback)
return ESP_FAIL;
}
/* TODO: Remove the examples DAC provider once we have a concrete
* way to generate attestation credentials.
*/
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
SetDeviceAttestationCredentialsProvider(&factory_data_provider);
SetCommissionableDataProvider(&factory_data_provider);
#if CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER
SetDeviceInstanceInfoProvider(&factory_data_provider);
#endif // CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER
#else // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
SetDeviceAttestationCredentialsProvider(GetExampleDACProvider());
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
SetDeviceAttestationCredentialsProvider(get_dac_provider());
ConnectivityMgr().SetBLEAdvertisingEnabled(true);
// ConnectivityMgr().SetWiFiAPMode(ConnectivityManager::kWiFiAPMode_Enabled);
if (PlatformMgr().StartEventLoopTask() != CHIP_NO_ERROR) {
@@ -0,0 +1,169 @@
// Copyright 2022 Espressif Systems (Shanghai) PTE LTD
//
// 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 <credentials/examples/DeviceAttestationCredsExample.h>
#include <crypto/CHIPCryptoPAL.h>
#include <platform/ESP32/ESP32Config.h>
#include <platform/ESP32/ESP32FactoryDataProvider.h>
#include <esp_fault.h>
#include <esp_log.h>
#include <esp_secure_cert_read.h>
#define TAG "dac_provider"
#if CONFIG_SEC_CERT_DAC_PROVIDER
namespace chip {
namespace DeviceLayer {
using namespace chip::Credentials;
using namespace chip::DeviceLayer::Internal;
namespace {
static constexpr uint32_t kDACPrivateKeySize = 32;
static constexpr uint32_t kDACPublicKeySize = 65;
static constexpr uint8_t kPrivKeyOffset = 7;
static constexpr uint8_t kPubKeyOffset = 56;
CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair)
{
Crypto::P256SerializedKeypair serializedKeypair;
ReturnErrorOnFailure(serializedKeypair.SetLength(privateKey.size() + publicKey.size()));
memcpy(serializedKeypair.Bytes(), publicKey.data(), publicKey.size());
memcpy(serializedKeypair.Bytes() + publicKey.size(), privateKey.data(), privateKey.size());
return keypair.Deserialize(serializedKeypair);
}
} // namespace
class SecureCertDACProvider: public Credentials::DeviceAttestationCredentialsProvider
{
public:
SecureCertDACProvider() : Credentials::DeviceAttestationCredentialsProvider() {}
CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override
{
size_t certSize;
ReturnErrorOnFailure(
ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CertDeclaration, outBuffer.data(), outBuffer.size(), certSize));
outBuffer.reduce_size(certSize);
return CHIP_NO_ERROR;
}
CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override
{
// We do not provide any FirmwareInformation.
out_firmware_info_buffer.reduce_size(0);
return CHIP_NO_ERROR;
}
CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override
{
char *dac_cert = NULL;
uint32_t dac_len = 0;
esp_err_t err = esp_secure_cert_get_device_cert(&dac_cert, &dac_len);
if (err == ESP_OK && dac_cert != NULL && dac_len != 0)
{
ESP_FAULT_ASSERT(err == ESP_OK && dac_cert != NULL && dac_len != 0);
memcpy(outBuffer.data(), dac_cert, dac_len);
outBuffer.reduce_size(dac_len);
esp_secure_cert_free_device_cert(dac_cert);
return CHIP_NO_ERROR;
}
ESP_LOGE(TAG, "esp_secure_cert_get_device_cert failed err:%d", err);
return CHIP_ERROR_INCORRECT_STATE;
}
CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override
{
char *pai_cert = NULL;
uint32_t pai_len = 0;
esp_err_t err = esp_secure_cert_get_ca_cert(&pai_cert, &pai_len);
if (err == ESP_OK && pai_cert != NULL && pai_len != 0)
{
ESP_FAULT_ASSERT(err == ESP_OK && pai_cert != NULL && pai_len != 0);
memcpy(outBuffer.data(), pai_cert, pai_len);
outBuffer.reduce_size(pai_len);
esp_secure_cert_free_ca_cert(pai_cert);
return CHIP_NO_ERROR;
}
ESP_LOGE(TAG, "esp_secure_cert_get_ca_cert failed err:%d", err);
return CHIP_ERROR_INCORRECT_STATE;
}
CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override
{
Crypto::P256ECDSASignature signature;
Crypto::P256Keypair keypair;
char *sc_keypair = NULL;
uint32_t sc_keypair_len = 0;
VerifyOrReturnError(IsSpanUsable(outSignBuffer), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(IsSpanUsable(messageToSign), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL);
esp_err_t err = esp_secure_cert_get_priv_key(&sc_keypair, &sc_keypair_len);
if (err == ESP_OK && sc_keypair != NULL && sc_keypair_len != 0)
{
ESP_FAULT_ASSERT(err == ESP_OK && sc_keypair != NULL && sc_keypair_len != 0);
CHIP_ERROR chipError = LoadKeypairFromRaw(ByteSpan(reinterpret_cast<const uint8_t *>(sc_keypair + kPrivKeyOffset), kDACPrivateKeySize),
ByteSpan(reinterpret_cast<const uint8_t *>(sc_keypair + kPubKeyOffset), kDACPublicKeySize), keypair);
if (chipError != CHIP_NO_ERROR)
{
esp_secure_cert_free_priv_key(sc_keypair);
return chipError;
}
chipError = keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature);
if (chipError != CHIP_NO_ERROR)
{
esp_secure_cert_free_priv_key(sc_keypair);
return chipError;
}
esp_secure_cert_free_priv_key(sc_keypair);
chipError = CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer);
return chipError;
}
ESP_LOGE(TAG, "esp_secure_cert_get_priv_key failed err:%d", err);
return CHIP_ERROR_INCORRECT_STATE;
}
};
} // namespace DeviceLayer
} // namespace chip
#endif // CONFIG_SEC_CERT_DAC_PROVIDER
namespace esp_matter {
// TODO: Need some method or mechanism to use the custom implementation along with the above three
chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void)
{
#if CONFIG_SEC_CERT_DAC_PROVIDER
static chip::DeviceLayer::SecureCertDACProvider instance;
return &instance;
#elif CONFIG_FACTORY_PARTITION_DAC_PROVIDER
static chip::DeviceLayer::ESP32FactoryDataProvider instance;
return &instance;
#else // CONFIG_EXAMPLE_DAC_PROVIDER
return chip::Credentials::Examples::GetExampleDACProvider();
#endif
}
} // namespace esp_matter
@@ -0,0 +1,35 @@
// Copyright 2022 Espressif Systems (Shanghai) PTE LTD
//
// 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 <credentials/DeviceAttestationCredsProvider.h>
namespace esp_matter {
/**
* @brief Get the DAC Provider implementation based on the configuration option
*
* If CONFIG_EXAMPLE_DAC_PROVIDER option is enabled then implementation which uses test data is used.
*
* If CONFIG_FACTORY_PARTITION_DAC_PROVIDER option is enabled then implementation which reads attestation
* information from factory partition is used.
*
* If CONFIG_SEC_CERT_DAC_PROVIDER option is enabled then implementation which reads attestation information
* from the esp_secure_cert partition is used.
*
* @return Pointer to the object of type DeviceAttestationCredentialsProvider
*/
chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void);
} // namespace esp_matter
+6
View File
@@ -0,0 +1,6 @@
## IDF Component Manager Manifest File
dependencies:
espressif/esp_secure_cert_mgr: "^2.0.4"
## Required IDF version
idf:
version: ">=4.4.2"
+2 -1
View File
@@ -1,7 +1,8 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition
esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
nvs, data, nvs, 0x10000, 0x6000,
nvs_keys, data, nvs_keys,, 0x1000,
otadata, data, ota, , 0x2000
phy_init, data, phy, , 0x1000,
ota_0, app, ota_0, 0x20000, 0x1E0000,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
3 sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
4 nvs, data, nvs, 0x10000, 0x6000,
5 nvs_keys, data, nvs_keys,, 0x1000,
6 otadata, data, ota, , 0x2000
7 phy_init, data, phy, , 0x1000,
8 ota_0, app, ota_0, 0x20000, 0x1E0000,
+2 -1
View File
@@ -1,7 +1,8 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition
esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
nvs, data, nvs, 0x10000, 0x6000,
nvs_keys, data, nvs_keys, , 0x1000,
phy_init, data, phy, , 0x1000,
# Temporarily disable ota for ESP32-H2 because the use of flash need to be optimized.
factory, app, factory, , 0x1C0000,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
3 sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
4 nvs, data, nvs, 0x10000, 0x6000,
5 nvs_keys, data, nvs_keys, , 0x1000,
6 phy_init, data, phy, , 0x1000,
7 # Temporarily disable ota for ESP32-H2 because the use of flash need to be optimized.
8 factory, app, factory, , 0x1C0000,
+4
View File
@@ -16,6 +16,7 @@ CONFIG_LWIP_IPV6_AUTOCONFIG=y
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0xC000
# Enable chip shell
CONFIG_ENABLE_CHIP_SHELL=y
@@ -30,3 +31,6 @@ CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
# disable softap by default
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
# Disable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
+2 -1
View File
@@ -1,7 +1,8 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition
esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
nvs, data, nvs, 0x10000, 0x6000,
nvs_keys, data, nvs_keys,, 0x1000,
otadata, data, ota, , 0x2000
phy_init, data, phy, , 0x1000,
ota_0, app, ota_0, 0x20000, 0x1E0000,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
3 sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
4 nvs, data, nvs, 0x10000, 0x6000,
5 nvs_keys, data, nvs_keys,, 0x1000,
6 otadata, data, ota, , 0x2000
7 phy_init, data, phy, , 0x1000,
8 ota_0, app, ota_0, 0x20000, 0x1E0000,
+2 -1
View File
@@ -1,7 +1,8 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition
esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
nvs, data, nvs, 0x10000, 0x6000,
nvs_keys, data, nvs_keys, , 0x1000,
phy_init, data, phy, , 0x1000,
# Temporarily disable ota for ESP32-H2 because the use of flash need to be optimized.
factory, app, factory, , 0x1C0000,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
3 sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition esp_secure_cert, 0x3F, ,0xd000, 0x2000, , # Never mark this as an encrypted partition
4 nvs, data, nvs, 0x10000, 0x6000,
5 nvs_keys, data, nvs_keys, , 0x1000,
6 phy_init, data, phy, , 0x1000,
7 # Temporarily disable ota for ESP32-H2 because the use of flash need to be optimized.
8 factory, app, factory, , 0x1C0000,
+4
View File
@@ -16,6 +16,7 @@ CONFIG_LWIP_IPV6_AUTOCONFIG=y
# Use a custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0xC000
# Testing Options
CONFIG_USE_TEST_SETUP_PIN_CODE=20212020
@@ -34,3 +35,6 @@ CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
# disable softap by default
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
# Disable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n