From f46a93e565476d3b123de66780461225e5d20e13 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Fri, 6 Oct 2023 14:03:40 +0530 Subject: [PATCH 1/2] feat(secure_boot): add secure boot support for esp32p4 --- components/app_update/esp_ota_ops.c | 2 + .../secure_boot_signature_priv.h | 2 + .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32p4/include/soc/soc_caps.h | 2 +- docs/docs_not_updated/esp32p4.txt | 2 - docs/en/security/secure-boot-v2.rst | 38 ++++++++++--------- .../test_apps/security/secure_boot/README.md | 9 +++-- .../security/secure_boot/conftest.py | 16 ++++++++ .../secure_boot/pytest_secure_boot.py | 7 +++- 9 files changed, 56 insertions(+), 26 deletions(-) diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 94bcc430fe85..bbb4b83ba5bb 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -45,6 +45,8 @@ #include "esp32c6/rom/secure_boot.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32P4 +#include "esp32p4/rom/secure_boot.h" #endif #define SUB_TYPE_ID(i) (i & 0x0F) 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 8e8bd43a09ed..bd7b752f5595 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 @@ -19,6 +19,8 @@ #include "esp32c6/rom/secure_boot.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/secure_boot.h" +#elif CONFIG_IDF_TARGET_ESP32P4 +#include "esp32p4/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/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 5e7f874cfc33..92d738ab2c7f 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -111,6 +111,10 @@ config SOC_FLASH_ENC_SUPPORTED bool default y +config SOC_SECURE_BOOT_SUPPORTED + bool + default y + config SOC_LP_GPIO_MATRIX_SUPPORTED bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 7e26ff2db4bf..15248d84b79a 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -66,7 +66,7 @@ #define SOC_ECDSA_SUPPORTED 1 // #define SOC_KEY_MANAGER_SUPPORTED 1 //TODO: IDF-7925 #define SOC_FLASH_ENC_SUPPORTED 1 -// #define SOC_SECURE_BOOT_SUPPORTED 1 //TODO: IDF-7544 +#define SOC_SECURE_BOOT_SUPPORTED 1 // #define SOC_BOD_SUPPORTED 1 //TODO: IDF-7519 // #define SOC_APM_SUPPORTED 1 //TODO: IDF-7542 // #define SOC_PMU_SUPPORTED 1 //TODO: IDF-7531 diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index 6ed3f4c6facb..4c942554ab6d 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -202,8 +202,6 @@ api-reference/protocols/asio.rst security/host-based-security-workflows.rst security/flash-encryption.rst security/security.rst -security/secure-boot-v2.rst -security/secure-boot-v1.rst security/esp32p4_log.inc security/index.rst about.rst diff --git a/docs/en/security/secure-boot-v2.rst b/docs/en/security/secure-boot-v2.rst index 9b047a9dd890..a4a3f7f12f23 100644 --- a/docs/en/security/secure-boot-v2.rst +++ b/docs/en/security/secure-boot-v2.rst @@ -3,11 +3,11 @@ Secure Boot V2 ============== -{IDF_TARGET_SBV2_SCHEME:default="RSA-PSS", esp32c2="ECDSA", esp32c6 or esp32h2="RSA-PSS or ECDSA"} +{IDF_TARGET_SBV2_SCHEME:default="RSA-PSS", esp32c2="ECDSA", esp32c6 or esp32h2 or esp32p4="RSA-PSS or ECDSA"} -{IDF_TARGET_SBV2_KEY:default="RSA-3072", esp32c2="ECDSA-256 or ECDSA-192", esp32c6 or esp32h2="RSA-3072, ECDSA-256, or ECDSA-192"} +{IDF_TARGET_SBV2_KEY:default="RSA-3072", esp32c2="ECDSA-256 or ECDSA-192", esp32c6 or esp32h2 or esp32p4="RSA-3072, ECDSA-256, or ECDSA-192"} -{IDF_TARGET_SECURE_BOOT_OPTION_TEXT:default="", esp32c6 or esp32h2="RSA is recommended because of faster verification time. You can choose between RSA and ECDSA scheme from the menu."} +{IDF_TARGET_SECURE_BOOT_OPTION_TEXT:default="", esp32c6 or esp32h2 or esp32p4="RSA is recommended because of faster verification time. You can choose between RSA and ECDSA scheme from the menu."} {IDF_TARGET_ECO_VERSION:default="", esp32="(ECO 3 onwards)", esp32c3="(ECO 3 onwards)"} @@ -138,21 +138,23 @@ The signature block starts on a 4 KB aligned boundary and has a flash sector of RSA is recommended for use cases where fast bootup time is required whereas ECDSA is recommended for use cases where shorter key length is required. - .. list-table:: Comparison between signature verification time - :widths: 10 10 20 - :header-rows: 1 - - * - **Verification scheme** - - **Time** - - **CPU Frequency** - * - RSA-3072 - - {IDF_TARGET_RSA_TIME} - - {IDF_TARGET_CPU_FREQ} - * - ECDSA-P256 - - {IDF_TARGET_ECDSA_TIME} - - {IDF_TARGET_CPU_FREQ} - - The above table compares the time taken to verify a signature in a particular scheme. It does not indicate the bootup time. + .. only:: not esp32p4 + + .. list-table:: Comparison between signature verification time + :widths: 10 10 20 + :header-rows: 1 + + * - **Verification scheme** + - **Time** + - **CPU Frequency** + * - RSA-3072 + - {IDF_TARGET_RSA_TIME} + - {IDF_TARGET_CPU_FREQ} + * - ECDSA-P256 + - {IDF_TARGET_ECDSA_TIME} + - {IDF_TARGET_CPU_FREQ} + + The above table compares the time taken to verify a signature in a particular scheme. It does not indicate the bootup time. The content of each signature block is shown in the following table: diff --git a/tools/test_apps/security/secure_boot/README.md b/tools/test_apps/security/secure_boot/README.md index 95a83e2834ae..992dd8f16d2e 100644 --- a/tools/test_apps/security/secure_boot/README.md +++ b/tools/test_apps/security/secure_boot/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # Secure Boot @@ -15,6 +15,7 @@ Any of the following ESP module: * ESP32S2 (supports Secure Boot V2) * ESP32C3-ECO3 (supports Secure Boot V2) * ESP32S3 (supports Secure Boot V2) +* ESP32P4 (supports Secure Boot V2) It is recommended to use Secure Boot V2 from ESP32-ECO3 onwards. @@ -69,7 +70,7 @@ Purpose of the test case (`pytest_secure_boot.py`) is to test the secure boot im ### Hardware required -* FPGA setup with ESP32C3/ESP32S3 image +* FPGA setup with ESP32C3/ESP32S3/ESP32P4 image * COM port for programming and export it as ESPPORT e.g `export ESPPORT=/dev/ttyUSB0` @@ -82,7 +83,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) +idf.py set-target esp32c3 #(or esp32s3 / esp32p4) idf.py menuconfig ``` diff --git a/tools/test_apps/security/secure_boot/conftest.py b/tools/test_apps/security/secure_boot/conftest.py index f0007f639c00..40e4334e5bbd 100644 --- a/tools/test_apps/security/secure_boot/conftest.py +++ b/tools/test_apps/security/secure_boot/conftest.py @@ -159,6 +159,20 @@ def secure_boot_burn_digest(self, digest: str, key_index: int = 0, block: int = self.serial.burn_efuse_key_digest(digest, 'SECURE_BOOT_DIGEST%d' % key_index, 'BLOCK_KEY%d' % block) +class Esp32p4FpgaDut(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() @@ -173,5 +187,7 @@ def replace_dut_class(monkeypatch_module: MonkeyPatch, pytestconfig: pytest.Conf monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32c3FpgaDut) elif target == 'esp32s3': monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32s3FpgaDut) + elif target == 'esp32p4': + monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', Esp32p4FpgaDut) 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 6dedf31ca344..5ed4c808c798 100644 --- a/tools/test_apps/security/secure_boot/pytest_secure_boot.py +++ b/tools/test_apps/security/secure_boot/pytest_secure_boot.py @@ -81,6 +81,7 @@ def dut_start_secure_app(dut: Dut) -> None: # Correctly signed bootloader + correctly signed app should work @pytest.mark.esp32c3 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 def test_examples_security_secure_boot(dut: Dut) -> None: dut_start_secure_app(dut) dut.expect('Secure Boot is enabled', timeout=10) @@ -92,6 +93,7 @@ def test_examples_security_secure_boot(dut: Dut) -> None: # Any key index can be written to any key block and should work @pytest.mark.esp32c3 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 # Increasing the test timeout to 1200s as the test runs for 18 iterations # and thus the default 600s timeout is not sufficient @pytest.mark.timeout(1200) @@ -113,6 +115,7 @@ def test_examples_security_secure_boot_key_combo(dut: Dut) -> None: # If a key is revoked, bootloader signed with that key should fail verification @pytest.mark.esp32c3 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 def test_examples_security_secure_boot_key_revoke(dut: Dut) -> None: dut_start_secure_app(dut) dut.expect('Secure Boot is enabled', timeout=10) @@ -131,6 +134,7 @@ def test_examples_security_secure_boot_key_revoke(dut: Dut) -> None: # Corrupt one byte at a time of bootloader signature and test that the verification fails @pytest.mark.esp32c3 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.timeout(18000) # Increasing the test timeout to 18000s as the test runs for 384 iterations # and thus the default 600s timeout is not sufficient @@ -167,6 +171,7 @@ def test_examples_security_secure_boot_corrupt_bl_sig(dut: Dut) -> None: # Corrupt app signature, one byte at a time, and test that the verification fails @pytest.mark.esp32c3 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.timeout(18000) # Increasing the test timeout to 18000s as the test runs for 385 iterations # and thus the default 600s timeout is not sufficient @@ -208,6 +213,6 @@ def test_examples_security_secure_boot_corrupt_app_sig(dut: Dut) -> None: dut.secure_boot_burn_en_bit() dut.secure_boot_burn_digest('test_rsa_3072_key.pem', 0, 0) - dut.expect('Sig block 0 invalid: Stored CRC ends', timeout=2) + dut.expect('Sig block 0 invalid: {}'.format('CRC mismatch' if dut.target == 'esp32p4' else 'Stored CRC ends'), timeout=2) dut.expect('Secure boot signature verification failed', timeout=2) dut.expect('No bootable app partitions in the partition table', timeout=2) From ef92f03658e49bf2e957725f0719e7be67b14099 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Fri, 6 Oct 2023 16:17:31 +0530 Subject: [PATCH 2/2] feat(efuses): enable eFuse example test (secure boot) for ESP32-P4 --- .../system/efuse/pytest_system_efuse_example.py | 2 ++ .../sdkconfig.ci.virt_secure_boot_v2.esp32p4 | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32p4 diff --git a/examples/system/efuse/pytest_system_efuse_example.py b/examples/system/efuse/pytest_system_efuse_example.py index 85d854c48ea7..f5c70f7a16e3 100644 --- a/examples/system/efuse/pytest_system_efuse_example.py +++ b/examples/system/efuse/pytest_system_efuse_example.py @@ -554,6 +554,7 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(dut: Dut) -> None: @pytest.mark.esp32c2 @pytest.mark.esp32c6 @pytest.mark.esp32h2 +@pytest.mark.esp32p4 @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.generic @@ -626,6 +627,7 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut: Dut) -> None: @pytest.mark.esp32c2 @pytest.mark.esp32c6 @pytest.mark.esp32h2 +@pytest.mark.esp32p4 @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.generic diff --git a/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32p4 b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32p4 new file mode 100644 index 000000000000..2847c533c144 --- /dev/null +++ b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32p4 @@ -0,0 +1,16 @@ +# SECURE_BOOT_V2 with EFUSE_VIRTUAL_KEEP_IN_FLASH + +CONFIG_IDF_TARGET="esp32p4" + +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