feat: enable secure boot feature for esp32c61

This commit is contained in:
nilesh.kale 2024-06-10 15:01:07 +05:30
parent 7e2bc478d7
commit 849726a3b7
13 changed files with 151 additions and 5 deletions

View File

@ -33,6 +33,8 @@
#include "esp32p4/rom/secure_boot.h" #include "esp32p4/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C5 #elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/secure_boot.h" #include "esp32c5/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C61
#include "esp32c61/rom/secure_boot.h"
#endif #endif
#ifdef CONFIG_SECURE_BOOT_V1_ENABLED #ifdef CONFIG_SECURE_BOOT_V1_ENABLED

View File

@ -27,6 +27,8 @@
#include "esp32p4/rom/secure_boot.h" #include "esp32p4/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C5 #elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/secure_boot.h" #include "esp32c5/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C61
#include "esp32c61/rom/secure_boot.h"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <strings.h>
#include "esp_flash_encrypt.h"
#include "esp_secure_boot.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_log.h"
#include "sdkconfig.h"
static __attribute__((unused)) const char *TAG = "secure_boot";
esp_err_t esp_secure_boot_enable_secure_features(void)
{
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
ESP_LOGI(TAG, "Enabling Security download mode...");
esp_err_t err = esp_efuse_enable_rom_secure_download_mode();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Could not enable Security download mode...");
return err;
}
#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
ESP_LOGI(TAG, "Disable ROM Download mode...");
esp_err_t err = esp_efuse_disable_rom_download_mode();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Could not disable ROM Download mode...");
return err;
}
#else
ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
#endif
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
ESP_LOGI(TAG, "Disable hardware & software JTAG...");
esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
// TODO in IDF-10694
// esp_efuse_write_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, ESP_EFUSE_SOFT_DIS_JTAG[0]->bit_count);
#else
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
#endif
#ifdef CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE);
#endif
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
bool rd_dis_now = true;
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
/* If flash encryption is not enabled yet then don't read-disable efuses yet, do it later in the boot
when Flash Encryption is being enabled */
rd_dis_now = esp_flash_encryption_enabled();
#endif
if (rd_dis_now) {
ESP_LOGI(TAG, "Prevent read disabling of additional efuses...");
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
}
#else
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
#endif
return ESP_OK;
}

View File

@ -23,6 +23,8 @@
#include "esp32p4/rom/secure_boot.h" #include "esp32p4/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C5 #elif CONFIG_IDF_TARGET_ESP32C5
#include "esp32c5/rom/secure_boot.h" #include "esp32c5/rom/secure_boot.h"
#elif CONFIG_IDF_TARGET_ESP32C61
#include "esp32c61/rom/secure_boot.h"
#endif #endif
esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, const ets_secure_boot_sig_block_t *trusted_block); esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, const ets_secure_boot_sig_block_t *trusted_block);

View File

@ -360,7 +360,7 @@ static const esp_efuse_desc_t UART_PRINT_CONTROL[] = {
}; };
static const esp_efuse_desc_t FORCE_SEND_RESUME[] = { static const esp_efuse_desc_t FORCE_SEND_RESUME[] = {
{EFUSE_BLK0, 103, 1}, // [] Represents whether ROM code is forced to send a resume commmand during SPI boot, {EFUSE_BLK0, 103, 1}, // [] Represents whether ROM code is forced to send a resume command during SPI boot,
}; };
static const esp_efuse_desc_t SECURE_VERSION[] = { static const esp_efuse_desc_t SECURE_VERSION[] = {
@ -879,7 +879,7 @@ const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[] = {
}; };
const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[] = { const esp_efuse_desc_t* ESP_EFUSE_FORCE_SEND_RESUME[] = {
&FORCE_SEND_RESUME[0], // [] Represents whether ROM code is forced to send a resume commmand during SPI boot &FORCE_SEND_RESUME[0], // [] Represents whether ROM code is forced to send a resume command during SPI boot
NULL NULL
}; };

View File

@ -47,6 +47,10 @@ config SOC_FLASH_ENC_SUPPORTED
bool bool
default y default y
config SOC_SECURE_BOOT_SUPPORTED
bool
default y
config SOC_PMU_SUPPORTED config SOC_PMU_SUPPORTED
bool bool
default y default y

View File

@ -48,7 +48,7 @@
#define SOC_ECC_SUPPORTED 1 #define SOC_ECC_SUPPORTED 1
#define SOC_ECC_EXTENDED_MODES_SUPPORTED 1 #define SOC_ECC_EXTENDED_MODES_SUPPORTED 1
#define SOC_FLASH_ENC_SUPPORTED 1 #define SOC_FLASH_ENC_SUPPORTED 1
// \#define SOC_SECURE_BOOT_SUPPORTED 1 //TODO: [ESP32C61] IDF-9233 #define SOC_SECURE_BOOT_SUPPORTED 1
// \#define SOC_BOD_SUPPORTED 1 //TODO: [ESP32C61] IDF-9254 // \#define SOC_BOD_SUPPORTED 1 //TODO: [ESP32C61] IDF-9254
// \#define SOC_APM_SUPPORTED 1 //TODO: [ESP32C61] IDF-9230 // \#define SOC_APM_SUPPORTED 1 //TODO: [ESP32C61] IDF-9230
#define SOC_PMU_SUPPORTED 1 //TODO: [ESP32C61] IDF-9250 #define SOC_PMU_SUPPORTED 1 //TODO: [ESP32C61] IDF-9250

View File

@ -565,6 +565,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(dut: Dut) -> None:
@pytest.mark.esp32c2 @pytest.mark.esp32c2
# TODO: [ESP32C5] IDF-10043 # TODO: [ESP32C5] IDF-10043
# @pytest.mark.esp32c5 # @pytest.mark.esp32c5
# TODO: [ESP32C5] IDF-10102
# @pytest.mark.esp32c61
@pytest.mark.esp32c6 @pytest.mark.esp32c6
@pytest.mark.esp32h2 @pytest.mark.esp32h2
@pytest.mark.esp32p4 @pytest.mark.esp32p4
@ -640,6 +642,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut: Dut) -> None:
@pytest.mark.esp32c2 @pytest.mark.esp32c2
# TODO: [ESP32C5] IDF-10043 # TODO: [ESP32C5] IDF-10043
# @pytest.mark.esp32c5 # @pytest.mark.esp32c5
# TODO: [ESP32C5] IDF-10102
# @pytest.mark.esp32c61
@pytest.mark.esp32c6 @pytest.mark.esp32c6
@pytest.mark.esp32h2 @pytest.mark.esp32h2
@pytest.mark.esp32p4 @pytest.mark.esp32p4

View File

@ -0,0 +1,18 @@
# FLASH_ENCRYPTION & SECURE_BOOT_V2 with EFUSE_VIRTUAL_KEEP_IN_FLASH
CONFIG_IDF_TARGET="esp32c61"
CONFIG_PARTITION_TABLE_OFFSET=0xD000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_V2_ENABLED=y
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key.pem"
CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=y
CONFIG_SECURE_FLASH_ENC_ENABLED=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@ -0,0 +1,16 @@
# SECURE_BOOT_V2 with EFUSE_VIRTUAL_KEEP_IN_FLASH
CONFIG_IDF_TARGET="esp32c61"
CONFIG_PARTITION_TABLE_OFFSET=0xC000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv"
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_BOOT_V2_ENABLED=y
CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key.pem"
CONFIG_SECURE_INSECURE_ALLOW_DL_MODE=y
# IMPORTANT: ONLY VIRTUAL eFuse MODE!
CONFIG_EFUSE_VIRTUAL=y
CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y

View File

@ -17,6 +17,7 @@ Any of the following ESP module:
* ESP32S3 (supports Secure Boot V2) * ESP32S3 (supports Secure Boot V2)
* ESP32P4 (supports Secure Boot V2) * ESP32P4 (supports Secure Boot V2)
* ESP32C5 (supports Secure Boot V2) * ESP32C5 (supports Secure Boot V2)
* ESP32C61 (supports Secure Boot V2)
It is recommended to use Secure Boot V2 from ESP32-ECO3 onwards. It is recommended to use Secure Boot V2 from ESP32-ECO3 onwards.
@ -71,7 +72,7 @@ Purpose of the test case (`pytest_secure_boot.py`) is to test the secure boot im
### Hardware required ### Hardware required
* FPGA setup with ESP32C3/ESP32S3/ESP32P4/ESP32C5 image * FPGA setup with ESP32C3/ESP32S3/ESP32P4/ESP32C5/ESP32C61 image
* COM port for programming and export it as ESPPORT * COM port for programming and export it as ESPPORT
e.g `export ESPPORT=/dev/ttyUSB0` e.g `export ESPPORT=/dev/ttyUSB0`
@ -84,7 +85,7 @@ Purpose of the test case (`pytest_secure_boot.py`) is to test the secure boot im
``` ```
export IDF_ENV_FPGA=1 export IDF_ENV_FPGA=1
idf.py set-target esp32c3 #(or esp32s3 / esp32p4 / esp32c5) idf.py set-target esp32c3 #(or esp32s3 / esp32p4 / esp32c5 / esp32c61)
idf.py menuconfig idf.py menuconfig
``` ```

View File

@ -186,6 +186,20 @@ class Esp32c5FpgaDut(FpgaDut):
self.serial.burn_efuse_key_digest(digest, 'SECURE_BOOT_DIGEST%d' % key_index, 'BLOCK_KEY%d' % block) self.serial.burn_efuse_key_digest(digest, 'SECURE_BOOT_DIGEST%d' % key_index, 'BLOCK_KEY%d' % block)
class Esp32c61FpgaDut(FpgaDut):
SECURE_BOOT_EN_KEY = 'SECURE_BOOT_EN'
SECURE_BOOT_EN_VAL = 1
def burn_wafer_version(self) -> None:
pass
def secure_boot_burn_en_bit(self) -> None:
self.serial.burn_efuse(self.SECURE_BOOT_EN_KEY, self.SECURE_BOOT_EN_VAL)
def secure_boot_burn_digest(self, digest: str, key_index: int = 0, block: int = 0) -> None:
self.serial.burn_efuse_key_digest(digest, 'SECURE_BOOT_DIGEST%d' % key_index, 'BLOCK_KEY%d' % block)
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch:
mp = MonkeyPatch() mp = MonkeyPatch()
@ -204,5 +218,7 @@ def replace_dut_class(monkeypatch_module: MonkeyPatch, pytestconfig: pytest.Conf
monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32p4FpgaDut) monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32p4FpgaDut)
elif target == 'esp32c5': elif target == 'esp32c5':
monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32c5FpgaDut) monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32c5FpgaDut)
elif target == 'esp32c61':
monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32c61FpgaDut)
monkeypatch_module.setattr('pytest_embedded_idf.IdfSerial', FpgaSerial) monkeypatch_module.setattr('pytest_embedded_idf.IdfSerial', FpgaSerial)

View File

@ -82,6 +82,8 @@ def dut_start_secure_app(dut: Dut) -> None:
@pytest.mark.esp32c3 @pytest.mark.esp32c3
# TODO: [ESP32C5] IDF-10043 # TODO: [ESP32C5] IDF-10043
# @pytest.mark.esp32c5 # @pytest.mark.esp32c5
# TODO: [ESP32C5] IDF-10102
# @pytest.mark.esp32c61
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
def test_examples_security_secure_boot(dut: Dut) -> None: def test_examples_security_secure_boot(dut: Dut) -> None:
@ -96,6 +98,8 @@ def test_examples_security_secure_boot(dut: Dut) -> None:
@pytest.mark.esp32c3 @pytest.mark.esp32c3
# TODO: [ESP32C5] IDF-10043 # TODO: [ESP32C5] IDF-10043
# @pytest.mark.esp32c5 # @pytest.mark.esp32c5
# TODO: [ESP32C5] IDF-10102
# @pytest.mark.esp32c61
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
# Increasing the test timeout to 1200s as the test runs for 18 iterations # Increasing the test timeout to 1200s as the test runs for 18 iterations
@ -120,6 +124,8 @@ def test_examples_security_secure_boot_key_combo(dut: Dut) -> None:
@pytest.mark.esp32c3 @pytest.mark.esp32c3
# TODO: [ESP32C5] IDF-10043 # TODO: [ESP32C5] IDF-10043
# @pytest.mark.esp32c5 # @pytest.mark.esp32c5
# TODO: [ESP32C5] IDF-10102
# @pytest.mark.esp32c61
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
def test_examples_security_secure_boot_key_revoke(dut: Dut) -> None: def test_examples_security_secure_boot_key_revoke(dut: Dut) -> None:
@ -141,6 +147,8 @@ def test_examples_security_secure_boot_key_revoke(dut: Dut) -> None:
@pytest.mark.esp32c3 @pytest.mark.esp32c3
# TODO: [ESP32C5] IDF-10043 # TODO: [ESP32C5] IDF-10043
# @pytest.mark.esp32c5 # @pytest.mark.esp32c5
# TODO: [ESP32C5] IDF-10102
# @pytest.mark.esp32c61
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
@pytest.mark.timeout(18000) @pytest.mark.timeout(18000)
@ -180,6 +188,8 @@ def test_examples_security_secure_boot_corrupt_bl_sig(dut: Dut) -> None:
@pytest.mark.esp32c3 @pytest.mark.esp32c3
# TODO: [ESP32C5] IDF-10043 # TODO: [ESP32C5] IDF-10043
# @pytest.mark.esp32c5 # @pytest.mark.esp32c5
# TODO: [ESP32C5] IDF-10102
# @pytest.mark.esp32c61
@pytest.mark.esp32s3 @pytest.mark.esp32s3
@pytest.mark.esp32p4 @pytest.mark.esp32p4
@pytest.mark.timeout(18000) @pytest.mark.timeout(18000)