From 849726a3b717bde589cd1d1a101c9b6a2d352885 Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Mon, 10 Jun 2024 15:01:07 +0530 Subject: [PATCH] feat: enable secure boot feature for esp32c61 --- .../include/esp_secure_boot.h | 2 + .../private_include/bootloader_signature.h | 2 + .../esp32c61/secure_boot_secure_features.c | 71 +++++++++++++++++++ .../secure_boot_signature_priv.h | 2 + components/efuse/esp32c61/esp_efuse_table.c | 4 +- .../esp32c61/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32c61/include/soc/soc_caps.h | 2 +- .../efuse/pytest_system_efuse_example.py | 4 ++ .../sdkconfig.ci.virt_sb_v2_and_fe.esp32c61 | 18 +++++ .../sdkconfig.ci.virt_secure_boot_v2.esp32c61 | 16 +++++ .../test_apps/security/secure_boot/README.md | 5 +- .../security/secure_boot/conftest.py | 16 +++++ .../secure_boot/pytest_secure_boot.py | 10 +++ 13 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 components/bootloader_support/src/esp32c61/secure_boot_secure_features.c create mode 100644 examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c61 create mode 100644 examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c61 diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 93396b1fe3..cc8c5b852b 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -33,6 +33,8 @@ #include "esp32p4/rom/secure_boot.h" #elif CONFIG_IDF_TARGET_ESP32C5 #include "esp32c5/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32C61 +#include "esp32c61/rom/secure_boot.h" #endif #ifdef CONFIG_SECURE_BOOT_V1_ENABLED diff --git a/components/bootloader_support/private_include/bootloader_signature.h b/components/bootloader_support/private_include/bootloader_signature.h index 5386e1ddae..f101b42402 100644 --- a/components/bootloader_support/private_include/bootloader_signature.h +++ b/components/bootloader_support/private_include/bootloader_signature.h @@ -27,6 +27,8 @@ #include "esp32p4/rom/secure_boot.h" #elif CONFIG_IDF_TARGET_ESP32C5 #include "esp32c5/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32C61 +#include "esp32c61/rom/secure_boot.h" #endif #ifdef __cplusplus diff --git a/components/bootloader_support/src/esp32c61/secure_boot_secure_features.c b/components/bootloader_support/src/esp32c61/secure_boot_secure_features.c new file mode 100644 index 0000000000..7cb01c89b1 --- /dev/null +++ b/components/bootloader_support/src/esp32c61/secure_boot_secure_features.c @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#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; +} diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h b/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h index b52b38086e..22a7701f18 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_signature_priv.h @@ -23,6 +23,8 @@ #include "esp32p4/rom/secure_boot.h" #elif CONFIG_IDF_TARGET_ESP32C5 #include "esp32c5/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32C61 +#include "esp32c61/rom/secure_boot.h" #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); diff --git a/components/efuse/esp32c61/esp_efuse_table.c b/components/efuse/esp32c61/esp_efuse_table.c index f5245687fb..87757107fa 100644 --- a/components/efuse/esp32c61/esp_efuse_table.c +++ b/components/efuse/esp32c61/esp_efuse_table.c @@ -360,7 +360,7 @@ static const esp_efuse_desc_t UART_PRINT_CONTROL[] = { }; 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[] = { @@ -879,7 +879,7 @@ const esp_efuse_desc_t* ESP_EFUSE_UART_PRINT_CONTROL[] = { }; 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 }; diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 5f96bc2684..52a7216261 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -47,6 +47,10 @@ config SOC_FLASH_ENC_SUPPORTED bool default y +config SOC_SECURE_BOOT_SUPPORTED + bool + default y + config SOC_PMU_SUPPORTED bool default y diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index 69b3dfe8a4..ab4b912195 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -48,7 +48,7 @@ #define SOC_ECC_SUPPORTED 1 #define SOC_ECC_EXTENDED_MODES_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_APM_SUPPORTED 1 //TODO: [ESP32C61] IDF-9230 #define SOC_PMU_SUPPORTED 1 //TODO: [ESP32C61] IDF-9250 diff --git a/examples/system/efuse/pytest_system_efuse_example.py b/examples/system/efuse/pytest_system_efuse_example.py index 0e650f24d4..235417526a 100644 --- a/examples/system/efuse/pytest_system_efuse_example.py +++ b/examples/system/efuse/pytest_system_efuse_example.py @@ -565,6 +565,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(dut: Dut) -> None: @pytest.mark.esp32c2 # TODO: [ESP32C5] IDF-10043 # @pytest.mark.esp32c5 +# TODO: [ESP32C5] IDF-10102 +# @pytest.mark.esp32c61 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 @@ -640,6 +642,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut: Dut) -> None: @pytest.mark.esp32c2 # TODO: [ESP32C5] IDF-10043 # @pytest.mark.esp32c5 +# TODO: [ESP32C5] IDF-10102 +# @pytest.mark.esp32c61 @pytest.mark.esp32c6 @pytest.mark.esp32h2 @pytest.mark.esp32p4 diff --git a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c61 b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c61 new file mode 100644 index 0000000000..7b20f08885 --- /dev/null +++ b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c61 @@ -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 diff --git a/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c61 b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c61 new file mode 100644 index 0000000000..afc034365b --- /dev/null +++ b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c61 @@ -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 diff --git a/tools/test_apps/security/secure_boot/README.md b/tools/test_apps/security/secure_boot/README.md index d29d95a396..f042b06414 100644 --- a/tools/test_apps/security/secure_boot/README.md +++ b/tools/test_apps/security/secure_boot/README.md @@ -17,6 +17,7 @@ Any of the following ESP module: * ESP32S3 (supports Secure Boot V2) * ESP32P4 (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. @@ -71,7 +72,7 @@ Purpose of the test case (`pytest_secure_boot.py`) is to test the secure boot im ### 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 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 -idf.py set-target esp32c3 #(or esp32s3 / esp32p4 / esp32c5) +idf.py set-target esp32c3 #(or esp32s3 / esp32p4 / esp32c5 / esp32c61) idf.py menuconfig ``` diff --git a/tools/test_apps/security/secure_boot/conftest.py b/tools/test_apps/security/secure_boot/conftest.py index 1b5db63931..ec30181580 100644 --- a/tools/test_apps/security/secure_boot/conftest.py +++ b/tools/test_apps/security/secure_boot/conftest.py @@ -186,6 +186,20 @@ class Esp32c5FpgaDut(FpgaDut): 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') def monkeypatch_module(request: FixtureRequest) -> 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) elif target == 'esp32c5': 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) diff --git a/tools/test_apps/security/secure_boot/pytest_secure_boot.py b/tools/test_apps/security/secure_boot/pytest_secure_boot.py index 2252233b30..c570e8de43 100644 --- a/tools/test_apps/security/secure_boot/pytest_secure_boot.py +++ b/tools/test_apps/security/secure_boot/pytest_secure_boot.py @@ -82,6 +82,8 @@ def dut_start_secure_app(dut: Dut) -> None: @pytest.mark.esp32c3 # TODO: [ESP32C5] IDF-10043 # @pytest.mark.esp32c5 +# TODO: [ESP32C5] IDF-10102 +# @pytest.mark.esp32c61 @pytest.mark.esp32s3 @pytest.mark.esp32p4 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 # TODO: [ESP32C5] IDF-10043 # @pytest.mark.esp32c5 +# TODO: [ESP32C5] IDF-10102 +# @pytest.mark.esp32c61 @pytest.mark.esp32s3 @pytest.mark.esp32p4 # 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 # TODO: [ESP32C5] IDF-10043 # @pytest.mark.esp32c5 +# TODO: [ESP32C5] IDF-10102 +# @pytest.mark.esp32c61 @pytest.mark.esp32s3 @pytest.mark.esp32p4 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 # TODO: [ESP32C5] IDF-10043 # @pytest.mark.esp32c5 +# TODO: [ESP32C5] IDF-10102 +# @pytest.mark.esp32c61 @pytest.mark.esp32s3 @pytest.mark.esp32p4 @pytest.mark.timeout(18000) @@ -180,6 +188,8 @@ def test_examples_security_secure_boot_corrupt_bl_sig(dut: Dut) -> None: @pytest.mark.esp32c3 # TODO: [ESP32C5] IDF-10043 # @pytest.mark.esp32c5 +# TODO: [ESP32C5] IDF-10102 +# @pytest.mark.esp32c61 @pytest.mark.esp32s3 @pytest.mark.esp32p4 @pytest.mark.timeout(18000)