mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(secure_boot): add secure boot support for esp32p4
This commit is contained in:
parent
a21e46dc64
commit
f46a93e565
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
.. only:: not esp32p4
|
||||
|
||||
* - **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}
|
||||
.. list-table:: Comparison between signature verification time
|
||||
:widths: 10 10 20
|
||||
:header-rows: 1
|
||||
|
||||
The above table compares the time taken to verify a signature in a particular scheme. It does not indicate the bootup time.
|
||||
* - **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:
|
||||
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user