Переглянути джерело

Merge branch 'feature/enable_secure_boot_esp32p4' into 'master'

feat(secure_boot): add secure boot support for esp32p4

Closes IDF-7544 and IDF-7745

See merge request espressif/esp-idf!26335
Mahavir Jain 2 роки тому
батько
коміт
1501aef1b3

+ 2 - 0
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)

+ 2 - 0
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);

+ 4 - 0
components/soc/esp32p4/include/soc/Kconfig.soc_caps.in

@@ -115,6 +115,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

+ 1 - 1
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

+ 0 - 2
docs/docs_not_updated/esp32p4.txt

@@ -199,8 +199,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

+ 20 - 18
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:
 

+ 2 - 0
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

+ 16 - 0
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

+ 5 - 4
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
 ```

+ 16 - 0
tools/test_apps/security/secure_boot/conftest.py

@@ -159,6 +159,20 @@ class Esp32s3FpgaDut(FpgaDut):
         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)

+ 6 - 1
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)