diff --git a/examples/system/efuse/conftest.py b/examples/system/efuse/conftest.py new file mode 100644 index 0000000000..d334688310 --- /dev/null +++ b/examples/system/efuse/conftest.py @@ -0,0 +1,99 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os + +import pytest +from _pytest.fixtures import FixtureRequest +from _pytest.monkeypatch import MonkeyPatch +from pytest_embedded_idf.app import FlashFile +from pytest_embedded_idf.serial import IdfSerial + + +# This is a custom IdfSerial class to support custom functionality +# which is required only for this test +class EfuseFlashEncSerial(IdfSerial): + + @IdfSerial.use_esptool + def write_flash_no_enc(self) -> None: + self.app.flash_settings['encrypt'] = False + flash_files = [] + for file in self.app.flash_files: + # Set encrypted flag to false for each file. + flash_files.append(file._replace(encrypted=False)) + # Replace the original tuple with modified tuple with all the files marked as unencrypted. + self.app.flash_files = tuple(flash_files) + # Now flash the files + self.flash() + + def bootloader_flash(self) -> None: + """ + Flash bootloader. + + :return: None + """ + logging.info('Flashing bootloader') + bootloader_path = os.path.join(self.app.binary_path, 'bootloader', 'bootloader.bin') + offs = int(self.app.sdkconfig.get('BOOTLOADER_OFFSET_IN_FLASH', 0)) + logging.info('bootloader offset is {0}'.format(hex(offs))) + prev_flash_files = self.app.flash_files + flash_files = [] + flash_files.append( + FlashFile( + offs, + bootloader_path, + False, + ) + ) + self.app.flash_files = flash_files + self.app.flash_settings['encrypt'] = False + self.flash() + # Restore self.app.flash files to original value + self.app.flash_files = prev_flash_files + + def erase_field_on_emul_efuse(self, pos_of_bits: list) -> None: + emul_efuse_bin_path = os.path.join(self.app.binary_path, 'emul_efuse.bin') + self.dump_flash(output=emul_efuse_bin_path, partition='emul_efuse') + logging.info('Erasing field on emulated efuse') + + def erase_bit(pos_of_bit: int) -> None: + nbytes, nbits = divmod(pos_of_bit, 8) + with open(emul_efuse_bin_path, 'r+b') as f: + f.seek(nbytes) + data = ord(f.read(1)) + data &= ~(1 << nbits) + f.seek(-1, os.SEEK_CUR) + f.write(bytes([data])) + + for pos_of_bit in sorted(pos_of_bits): + erase_bit(pos_of_bit) + + offs = self.app.partition_table['emul_efuse']['offset'] + logging.info('emul efuse offset is {0}'.format(hex(offs))) + prev_flash_files = self.app.flash_files + + flash_files = [] + flash_files.append( + FlashFile( + offs, + emul_efuse_bin_path, + False, + ) + ) + self.app.flash_files = flash_files + self.app.flash_settings['encrypt'] = False + self.flash() + self.app.flash_files = prev_flash_files + + +@pytest.fixture(scope='module') +def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: + mp = MonkeyPatch() + request.addfinalizer(mp.undo) + return mp + + +@pytest.fixture(scope='module', autouse=True) +def replace_dut_class(monkeypatch_module: MonkeyPatch) -> None: + monkeypatch_module.setattr('pytest_embedded_idf.serial.IdfSerial', EfuseFlashEncSerial) diff --git a/examples/system/efuse/example_test.py b/examples/system/efuse/pytest_efuse.py similarity index 62% rename from examples/system/efuse/example_test.py rename to examples/system/efuse/pytest_efuse.py index af5afa9e62..f8545e49bb 100644 --- a/examples/system/efuse/example_test.py +++ b/examples/system/efuse/pytest_efuse.py @@ -1,76 +1,63 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 from __future__ import unicode_literals +import logging import os -import re -import ttfw_idf +import pytest +from pytest_embedded import Dut -def erase_field_on_emul_efuse(dut, pos_of_bits): # type: (ttfw_idf.TinyFW.Env, list) -> None - emul_efuse_bin_path = os.path.join(dut.app.binary_path, 'emul_efuse.bin') - dut.dump_flash(emul_efuse_bin_path, partition='emul_efuse') - - def erase_bit(pos_of_bit): # type: (int) -> None - nbytes, nbits = divmod(pos_of_bit, 8) - with open(emul_efuse_bin_path, 'r+b') as f: - f.seek(nbytes) - data = ord(f.read(1)) - data &= ~(1 << nbits) - f.seek(-1, os.SEEK_CUR) - f.write(bytes([data])) - - for pos_of_bit in sorted(pos_of_bits): - erase_bit(pos_of_bit) - - offs = dut.app.partition_table['emul_efuse']['offset'] - flash_files = [(offs, emul_efuse_bin_path)] - dut.write_flash(flash_files) +@pytest.mark.generic +@pytest.mark.esp32 +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +def test_examples_efuse(dut: Dut) -> None: + dut.expect(r'example: Coding Scheme (3/4)|(NONE)|(REPEAT)|(RS \(Reed-Solomon coding\))', timeout=20) + dut.expect(['example: read efuse fields', + r'example: 1. read MAC address: {}'.format(r':'.join((r'[0-9a-f]{2}',) * 6)), + 'example: 2. read secure_version: 0', + 'example: 3. read custom fields', + 'example: module_version = 0', + 'example: device_role = None', + 'example: setting_1 = 0', + 'example: setting_2 = 0', + 'example: custom_secure_version = 0', + 'example: This example does not burn any efuse in reality only virtually', + 'example: Write operations in efuse fields are performed virtually', + 'example: write custom efuse fields', + 'efuse: Virtual efuses enabled: Not really burning eFuses', + 'example: module_version = 1', + 'example: device_role = Slave', + 'example: setting_1 = 3', + 'example: setting_2 = 4', + 'example: custom_secure_version = 5', + 'example: Done'], expect_all=True) -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3', 'esp32c2']) -def test_examples_efuse(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse') - dut.start_app() - dut.expect_all(re.compile(r'example: Coding Scheme (3/4)|(NONE)|(REPEAT)|(RS \(Reed-Solomon coding\))'), - 'example: read efuse fields', - re.compile(r'example: 1. read MAC address: {}'.format(r':'.join((r'[0-9a-f]{2}',) * 6))), - 'example: 2. read secure_version: 0', - 'example: 3. read custom fields', - 'example: module_version = 0', - 'example: device_role = None', - 'example: setting_1 = 0', - 'example: setting_2 = 0', - 'example: custom_secure_version = 0', - 'example: This example does not burn any efuse in reality only virtually', - 'example: Write operations in efuse fields are performed virtually', - 'example: write custom efuse fields', - 'efuse: Virtual efuses enabled: Not really burning eFuses', - 'example: module_version = 1', - 'example: device_role = Slave', - 'example: setting_1 = 3', - 'example: setting_2 = 4', - 'example: custom_secure_version = 5', - 'example: Done', - timeout=30) - - -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2']) -def test_examples_efuse_with_virt_flash_enc(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc') +@pytest.mark.generic +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.parametrize('config', ['virt_flash_enc',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_flash_enc(dut: Dut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_flash_enc_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Checking flash encryption...') dut.expect('Generating new flash encryption key...') - if dut.TARGET == 'esp32': + if dut.app.target == 'esp32': dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2') dut.expect('Setting CRYPT_CONFIG efuse to 0xF') dut.expect('Not disabling UART bootloader encryption') @@ -79,7 +66,7 @@ def test_examples_efuse_with_virt_flash_enc(env, _): # type: (ttfw_idf.TinyFW.E dut.expect('Disable JTAG...') dut.expect('Disable ROM BASIC interpreter fallback...') else: - if dut.TARGET == 'esp32c2': + if dut.app.target == 'esp32c2': dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1') else: dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4') @@ -93,30 +80,32 @@ def test_examples_efuse_with_virt_flash_enc(env, _): # type: (ttfw_idf.TinyFW.E dut.expect('Loading virtual efuse blocks from flash') dut.expect('Checking flash encryption...') - if dut.TARGET == 'esp32': - dut.expect('flash encryption is enabled (3 plaintext flashes left)') + if dut.app.target == 'esp32': + dut.expect_exact('flash encryption is enabled (3 plaintext flashes left)', timeout=3) else: - dut.expect('flash encryption is enabled (1 plaintext flashes left)') + dut.expect_exact('flash encryption is enabled (1 plaintext flashes left)') - dut.expect('Flash encryption mode is DEVELOPMENT (not secure)') + dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2']) -def test_examples_efuse_with_virt_flash_enc_aes_256(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None +@pytest.mark.generic +@pytest.mark.esp32s2 +@pytest.mark.parametrize('config', ['virt_flash_enc_aes_256',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_flash_enc_aes_256(dut: Dut) -> None: # Only ESP32-S2 has support AES-256 FLASH_ENCRYPTION key - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc_aes_256') # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_flash_enc_aes_256_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Checking flash encryption...') dut.expect('Generating new flash encryption key...') @@ -134,52 +123,57 @@ def test_examples_efuse_with_virt_flash_enc_aes_256(env, _): # type: (ttfw_idf. dut.expect('Loading virtual efuse blocks from flash') dut.expect('Checking flash encryption...') - dut.expect('flash encryption is enabled (1 plaintext flashes left)') + dut.expect_exact('flash encryption is enabled (1 plaintext flashes left)') - dut.expect('Flash encryption mode is DEVELOPMENT (not secure)') + dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2']) -def test_examples_efuse_with_virt_flash_enc_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc') +@pytest.mark.generic +@pytest.mark.esp32 +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32s2 +@pytest.mark.parametrize('config', ['virt_flash_enc',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_flash_enc_pre_loaded(dut: Dut) -> None: print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Flash encryption completed', timeout=90) dut.expect('Resetting with flash encryption enabled...') - dut.expect('Flash encryption mode is DEVELOPMENT (not secure)') + dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') dut.expect('example: Done') - if dut.TARGET == 'esp32': + if dut.app.target == 'esp32': print(' - Flash emul_efuse with pre-loaded efuses (FLASH_CRYPT_CNT 1 -> 0)') # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv FLASH_CRYPT_CNT = 20 # Resets eFuse, which enables Flash encryption feature - erase_field_on_emul_efuse(dut, [FLASH_CRYPT_CNT]) - elif dut.TARGET == 'esp32c2': + dut.serial.erase_field_on_emul_efuse([FLASH_CRYPT_CNT]) + elif dut.app.target == 'esp32c2': FLASH_CRYPT_CNT = 39 - erase_field_on_emul_efuse(dut, [FLASH_CRYPT_CNT]) + dut.serial.erase_field_on_emul_efuse([FLASH_CRYPT_CNT]) else: # offset of this eFuse is taken from components/efuse/{target}/esp_efuse_table.csv print(' - Flash emul_efuse with pre-loaded efuses (SPI_BOOT_CRYPT_CNT 1 -> 0)') SPI_BOOT_CRYPT_CNT = 82 # Resets eFuse, which enables Flash encryption feature - erase_field_on_emul_efuse(dut, [SPI_BOOT_CRYPT_CNT]) + dut.serial.erase_field_on_emul_efuse([SPI_BOOT_CRYPT_CNT]) print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Checking flash encryption...') dut.expect('Using pre-loaded flash encryption key in efuse') - if dut.TARGET == 'esp32': + if dut.app.target == 'esp32': dut.expect('Setting CRYPT_CONFIG efuse to 0xF') dut.expect('Not disabling UART bootloader encryption') dut.expect('Disable UART bootloader decryption...') @@ -197,33 +191,37 @@ def test_examples_efuse_with_virt_flash_enc_pre_loaded(env, _): # type: (ttfw_i dut.expect('Loading virtual efuse blocks from flash') dut.expect('Checking flash encryption...') - if dut.TARGET == 'esp32': - dut.expect('flash encryption is enabled (3 plaintext flashes left)') + if dut.app.target == 'esp32': + dut.expect_exact('flash encryption is enabled (3 plaintext flashes left)') else: - dut.expect('flash encryption is enabled (1 plaintext flashes left)') + dut.expect_exact('flash encryption is enabled (1 plaintext flashes left)') - dut.expect('Flash encryption mode is DEVELOPMENT (not secure)') + dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2']) -def test_examples_efuse_with_virt_flash_enc_release(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc_release') +@pytest.mark.generic +@pytest.mark.esp32 +@pytest.mark.esp32c2 +@pytest.mark.esp32c3 +@pytest.mark.esp32s2 +@pytest.mark.parametrize('config', ['virt_flash_enc_release',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_flash_enc_release(dut: Dut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_flash_enc_release_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) - print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Checking flash encryption...') dut.expect('Generating new flash encryption key...') - if dut.TARGET == 'esp32': + if dut.app.target == 'esp32': dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2') dut.expect('Setting CRYPT_CONFIG efuse to 0xF') dut.expect('Disable UART bootloader encryption...') @@ -232,7 +230,7 @@ def test_examples_efuse_with_virt_flash_enc_release(env, _): # type: (ttfw_idf. dut.expect('Disable JTAG...') dut.expect('Disable ROM BASIC interpreter fallback...') else: - if dut.TARGET == 'esp32c2': + if dut.app.target == 'esp32c2': dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1') else: dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4') @@ -247,30 +245,31 @@ def test_examples_efuse_with_virt_flash_enc_release(env, _): # type: (ttfw_idf. dut.expect('Loading virtual efuse blocks from flash') dut.expect('Checking flash encryption...') - dut.expect('flash encryption is enabled (0 plaintext flashes left)') - + dut.expect_exact('flash encryption is enabled (0 plaintext flashes left)', timeout=5) dut.expect('Flash encryption mode is RELEASE') dut.expect('Start eFuse example') dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) -def test_examples_efuse_with_virt_secure_boot_v1(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None +@pytest.mark.generic +@pytest.mark.esp32 +@pytest.mark.parametrize('config', ['virt_secure_boot_v1',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v1(dut: Dut) -> None: # only for ESP32 - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1') # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_secure_boot_v1_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Flash bootloader') - dut.bootloader_flash() + dut.serial.bootloader_flash() print(' - Start app (flash partition_table and app)') - dut.start_app() + dut.serial.flash() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Verifying image signature...') @@ -290,7 +289,7 @@ def test_examples_efuse_with_virt_secure_boot_v1(env, _): # type: (ttfw_idf.Tin dut.expect('Start eFuse example') dut.expect('example: Done') - dut.reset() + dut.serial.hard_reset() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..') @@ -300,16 +299,18 @@ def test_examples_efuse_with_virt_secure_boot_v1(env, _): # type: (ttfw_idf.Tin dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) -def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - # only for ESP32 - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1') - +@pytest.mark.generic +@pytest.mark.esp32 +@pytest.mark.parametrize('config', ['virt_secure_boot_v1',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(dut: Dut) -> None: print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() + print(' - Flash bootloader') + dut.serial.bootloader_flash() + print(' - Start app (flash partition_table and app)') + dut.serial.flash() - dut.bootloader_flash() - dut.start_app() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') @@ -320,10 +321,10 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (t # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv ABS_DONE_0 = 196 # Resets eFuse, which enables Secure boot (V1) feature - erase_field_on_emul_efuse(dut, [ABS_DONE_0]) + dut.serial.erase_field_on_emul_efuse([ABS_DONE_0]) print(' - Start app (flash partition_table and app)') - dut.start_app() + dut.serial.flash() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') @@ -343,7 +344,7 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (t dut.expect('Start eFuse example') dut.expect('example: Done') - dut.reset() + dut.serial.hard_reset() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..') @@ -353,28 +354,26 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (t dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32']) -def test_examples_efuse_with_virt_secure_boot_v2(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None +@pytest.mark.esp32 +@pytest.mark.parametrize('config', [('virt_secure_boot_v2.esp32'),], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2(dut: Dut) -> None: # only for ESP32 ECO3 - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET) - # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_secure_boot_v2_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) print(' - Erase flash') - dut.erase_flash() - + dut.serial.erase_flash() print(' - Flash bootloader') - dut.bootloader_flash() - + dut.serial.bootloader_flash() print(' - Start app (flash partition_table and app)') - dut.start_app() + dut.serial.flash() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Verifying image signature...') dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set') - dut.expect('secure_boot_v2: Verifying with RSA-PSS...') + dut.expect('secure_boot_v2: Verifying with RSA-PSS...', timeout=20) dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: enabling secure boot v2...') @@ -384,12 +383,12 @@ def test_examples_efuse_with_virt_secure_boot_v2(env, _): # type: (ttfw_idf.Tin dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: Secure boot digests absent, generating..') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader') dut.expect('Writing EFUSE_BLK_KEY1 with purpose 3') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') - dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app') + dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)') dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('Disable JTAG...') @@ -403,7 +402,63 @@ def test_examples_efuse_with_virt_secure_boot_v2(env, _): # type: (ttfw_idf.Tin dut.expect('Start eFuse example') dut.expect('example: Done') - dut.reset() + dut.serial.hard_reset() + dut.expect('Loading virtual efuse blocks from flash') + dut.expect('Verifying image signature...') + dut.expect('secure_boot_v2: Verifying with RSA-PSS...') + dut.expect('secure_boot_v2: Signature verified successfully!') + dut.expect('secure_boot_v2: enabling secure boot v2...') + dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..') + dut.expect('Start eFuse example') + dut.expect('example: Done') + print(' - Erase flash') + dut.serial.erase_flash() + + print(' - Flash bootloader and app') + dut.serial.bootloader_flash() + dut.serial.flash() + dut.expect('Loading virtual efuse blocks from real efuses') + dut.expect('Loading virtual efuse blocks from flash') + dut.expect('Start eFuse example') + dut.expect('example: Done') + + print(' - Flash emul_efuse with pre-loaded efuses (ABS_DONE_1 1 -> 0)') + # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv + ABS_DONE_1 = 197 + # Resets eFuse, which enables Secure boot (V2) feature + dut.serial.erase_field_on_emul_efuse([ABS_DONE_1]) + + print(' - Start app (flash partition_table and app)') + dut.serial.flash() + dut.expect('Loading virtual efuse blocks from flash') + + dut.expect('Verifying image signature...') + dut.expect('secure_boot_v2: Verifying with RSA-PSS...') + dut.expect('secure_boot_v2: Signature verified successfully!') + + dut.expect('secure_boot_v2: enabling secure boot v2...') + dut.expect('Verifying image signature...') + dut.expect('secure_boot_v2: Verifying with RSA-PSS...') + dut.expect('secure_boot_v2: Signature verified successfully!') + dut.expect('secure_boot_v2: Secure boot digests already present') + dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse') + dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app') + dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)') + + dut.expect('secure_boot_v2: blowing secure boot efuse...') + dut.expect('Disable JTAG...') + dut.expect('Disable ROM BASIC interpreter fallback...') + dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED') + dut.expect('Prevent read disabling of additional efuses...') + dut.expect('secure_boot_v2: Secure boot permanently enabled') + + dut.expect('cpu_start: Pro cpu up') + dut.expect('Loading virtual efuse blocks from flash') + dut.expect('Start eFuse example') + dut.expect('example: Done') + + dut.serial.hard_reset() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') dut.expect('secure_boot_v2: Verifying with RSA-PSS...') @@ -414,17 +469,17 @@ def test_examples_efuse_with_virt_secure_boot_v2(env, _): # type: (ttfw_idf.Tin dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32']) -def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - # only for ESP32 ECO3 - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET) +@pytest.mark.esp32 +@pytest.mark.parametrize('config', [('virt_secure_boot_v2.esp32'),], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(dut: Dut) -> None: print(' - Erase flash') dut.erase_flash() - print(' - Flash bootloader and app') dut.bootloader_flash() - dut.start_app() + print(' - Start app (flash partition_table and app)') + dut.serial.flash() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') @@ -435,10 +490,10 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _): # type: (t # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv ABS_DONE_1 = 197 # Resets eFuse, which enables Secure boot (V2) feature - erase_field_on_emul_efuse(dut, [ABS_DONE_1]) + dut.serial.erase_field_on_emul_efuse([ABS_DONE_1]) print(' - Start app (flash partition_table and app)') - dut.start_app() + dut.serial.flash() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') @@ -452,8 +507,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _): # type: (t dut.expect('secure_boot_v2: Secure boot digests already present') dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') - dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app') + dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)') dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('Disable JTAG...') @@ -467,7 +522,7 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _): # type: (t dut.expect('Start eFuse example') dut.expect('example: Done') - dut.reset() + dut.serial.hard_reset() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') dut.expect('secure_boot_v2: Verifying with RSA-PSS...') @@ -478,27 +533,26 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _): # type: (t dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2', 'esp32c3', 'esp32c2']) -def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET) +def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut: Dut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_secure_boot_v2_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) print(' - Erase flash') - dut.erase_flash() - + dut.serial.erase_flash() print(' - Flash bootloader') - dut.bootloader_flash() - + dut.serial.bootloader_flash() print(' - Start app (flash partition_table and app)') - dut.start_app() + dut.serial.flash() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Verifying image signature...') dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set') - signed_scheme = 'ECDSA' if dut.TARGET == 'esp32c2' else 'RSA-PSS' + if dut.app.target == 'esp32c2': + signed_scheme = 'ECDSA' + else: + signed_scheme = 'RSA-PSS' dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme) dut.expect('secure_boot_v2: Signature verified successfully!') @@ -509,18 +563,18 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _): # type: (ttfw dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: Secure boot digests absent, generating..') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader') - if dut.TARGET == 'esp32c2': + if dut.app.target == 'esp32c2': dut.expect('Writing EFUSE_BLK_KEY0 with purpose 3') else: dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') - dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)') - if dut.TARGET != 'esp32c2': - dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...') - dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app') + dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)') + if dut.app.target != 'esp32c2': + dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (1)...') + dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (2)...') dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED') dut.expect('Disable hardware & software JTAG...') @@ -531,7 +585,7 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _): # type: (ttfw dut.expect('Start eFuse example') dut.expect('example: Done') - dut.reset() + dut.serial.hard_reset() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme) @@ -542,16 +596,37 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _): # type: (ttfw dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2', 'esp32c3', 'esp32c2']) -def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET) +@pytest.mark.generic +@pytest.mark.esp32c3 +@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c3'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2_esp32c3(dut: Dut) -> None: + test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut) + +@pytest.mark.generic +@pytest.mark.esp32c2 +@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c2'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2_esp32c2(dut: Dut) -> None: + test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut) + + +@pytest.mark.generic +@pytest.mark.esp32s2 +@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32s2'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2_esp32s2(dut: Dut) -> None: + test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut) + + +def test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut: Dut) -> None: print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Flash bootloader and app') - dut.bootloader_flash() - dut.start_app() + dut.serial.bootloader_flash() + dut.serial.flash() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') @@ -560,9 +635,9 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # print(' - Flash emul_efuse with pre-loaded efuses (SECURE_BOOT_EN 1 -> 0, SECURE_BOOT_KEY_REVOKE[0..2] -> 0)') # offsets of eFuses are taken from components/efuse/{target}/esp_efuse_table.csv - if dut.TARGET == 'esp32c2': + if dut.app.target == 'esp32c2': SECURE_BOOT_EN = 53 - erase_field_on_emul_efuse(dut, [SECURE_BOOT_EN]) + dut.serial.erase_field_on_emul_efuse([SECURE_BOOT_EN]) else: SECURE_BOOT_EN = 116 SECURE_BOOT_KEY_REVOKE0 = 85 @@ -570,36 +645,39 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # SECURE_BOOT_KEY_REVOKE2 = 87 # Resets eFuse, which enables Secure boot feature # Resets eFuses, which control digest slots - erase_field_on_emul_efuse(dut, [SECURE_BOOT_EN, SECURE_BOOT_KEY_REVOKE0, SECURE_BOOT_KEY_REVOKE1, SECURE_BOOT_KEY_REVOKE2]) + dut.serial.erase_field_on_emul_efuse([SECURE_BOOT_EN, SECURE_BOOT_KEY_REVOKE0, SECURE_BOOT_KEY_REVOKE1, SECURE_BOOT_KEY_REVOKE2]) print(' - Start app (flash partition_table and app)') - dut.start_app() + dut.serial.flash() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') - signed_scheme = 'ECDSA' if dut.TARGET == 'esp32c2' else 'RSA-PSS' + if dut.app.target == 'esp32c2': + signed_scheme = 'ECDSA' + else: + signed_scheme = 'RSA-PSS' + dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme) dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: Secure boot digests already present') dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') - dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)') - if dut.TARGET != 'esp32c2': - dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...') - dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app') + if dut.app.target != 'esp32c2': + dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (1)...') + dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (2)...') dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED') dut.expect('Disable hardware & software JTAG...') - dut.expect('secure_boot_v2: Secure boot permanently enabled') + dut.expect('secure_boot_v2: Secure boot permanently enabled', timeout=20) dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') dut.expect('Start eFuse example') dut.expect('example: Done') - dut.reset() + dut.serial.hard_reset() dut.expect('Loading virtual efuse blocks from flash') dut.expect('Verifying image signature...') dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme) @@ -610,22 +688,48 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) -def test_examples_efuse_with_virt_sb_v1_and_fe(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v1_and_fe') +@pytest.mark.generic +@pytest.mark.esp32c3 +@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c3'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2_esp32c3_pre_loaded(dut: Dut) -> None: + test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut) + + +@pytest.mark.generic +@pytest.mark.esp32c2 +@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c2'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2_esp32c2_pre_loaded(dut: Dut) -> None: + test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut) + + +@pytest.mark.generic +@pytest.mark.esp32s2 +@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32s2'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_secure_boot_v2_esp32s2_pre_loaded(dut: Dut) -> None: + test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut) + + +@pytest.mark.generic +@pytest.mark.esp32 +@pytest.mark.parametrize('config', ['virt_sb_v1_and_fe',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_sb_v1_and_fe(dut: Dut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_sb_v1_and_fe_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Flash bootloader') - dut.bootloader_flash() + dut.serial.bootloader_flash() print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Verifying image signature...') @@ -660,34 +764,34 @@ def test_examples_efuse_with_virt_sb_v1_and_fe(env, _): # type: (ttfw_idf.TinyF dut.expect('Verifying image signature...') dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..') dut.expect('Checking flash encryption...') - dut.expect('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)') + dut.expect_exact('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)') dut.expect('Checking secure boot...') dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..') dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') - dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)') + dut.expect_exact('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32']) -def test_examples_efuse_with_virt_sb_v2_and_fe(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - # only for ESP32 ECO3 - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v2_and_fe.' + env.default_dut_cls.TARGET) +@pytest.mark.esp32 +@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32',], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_sb_v2_and_fe(dut: Dut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_sb_v2_and_fe_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Flash bootloader') - dut.bootloader_flash() + dut.serial.bootloader_flash() print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set') @@ -701,12 +805,12 @@ def test_examples_efuse_with_virt_sb_v2_and_fe(env, _): # type: (ttfw_idf.TinyF dut.expect('secure_boot_v2: Signature verified successfully') dut.expect('secure_boot_v2: Secure boot digests absent, generating..') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader') dut.expect('Writing EFUSE_BLK_KEY1 with purpose 3') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') - dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app') + dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)') dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('Disable JTAG...') @@ -742,35 +846,32 @@ def test_examples_efuse_with_virt_sb_v2_and_fe(env, _): # type: (ttfw_idf.TinyF dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: enabling secure boot v2...') dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..') - dut.expect('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)') + dut.expect_exact('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)') dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') - dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)') + dut.expect_exact('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') dut.expect('example: Done') -@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2', 'esp32c3', 'esp32c2']) -def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None - dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v2_and_fe.' + env.default_dut_cls.TARGET) +def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut: Dut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024)) + logging.info('{}_bootloader_virt_sb_v2_and_fe_bin_size: {}KB'.format(dut.app.target, bin_size // 1024)) - print(' - Erase flash') - dut.erase_flash() + dut.serial.erase_flash() print(' - Flash bootloader') - dut.bootloader_flash() + dut.serial.bootloader_flash() print(' - Start app (flash partition_table and app)') - dut.start_app_no_enc() + dut.serial.write_flash_no_enc() dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Verifying image signature...') dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set') - signed_scheme = 'ECDSA' if dut.TARGET == 'esp32c2' else 'RSA-PSS' + signed_scheme = 'ECDSA' if dut.app.target == 'esp32c2' else 'RSA-PSS' dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme) dut.expect('secure_boot_v2: Signature verified successfully!') @@ -781,28 +882,28 @@ def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _): # type: (ttfw_i dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: Secure boot digests absent, generating..') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader') - if dut.TARGET == 'esp32c2': + if dut.app.target == 'esp32c2': dut.expect('Writing EFUSE_BLK_KEY0 with purpose 3') else: dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9') dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') - dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') - dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)') - if dut.TARGET != 'esp32c2': - dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...') - dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...') + dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app') + dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)') + if dut.app.target != 'esp32c2': + dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (1)...') + dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (2)...') dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED') dut.expect('Disable hardware & software JTAG...') - if dut.TARGET != 'esp32c2': + if dut.app.target != 'esp32c2': dut.expect('secure_boot_v2: Secure boot permanently enabled') dut.expect('Checking flash encryption...') dut.expect('flash_encrypt: Generating new flash encryption key...') - if dut.TARGET == 'esp32c2': + if dut.app.target == 'esp32c2': dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2') else: dut.expect('Writing EFUSE_BLK_KEY1 with purpose 4') @@ -811,7 +912,7 @@ def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _): # type: (ttfw_i dut.expect('Disable UART bootloader cache...') dut.expect('Disable JTAG...') - if dut.TARGET == 'esp32c2': + if dut.app.target == 'esp32c2': dut.expect('boot: Secure boot permanently enabled') dut.expect('Verifying image signature...') @@ -832,26 +933,30 @@ def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _): # type: (ttfw_i dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: enabling secure boot v2...') dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..') - dut.expect('flash_encrypt: flash encryption is enabled (1 plaintext flashes left)') + dut.expect_exact('flash_encrypt: flash encryption is enabled (1 plaintext flashes left)') dut.expect('cpu_start: Pro cpu up') dut.expect('Loading virtual efuse blocks from flash') - dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)') + dut.expect_exact('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)') dut.expect('Start eFuse example') dut.expect('example: Done') -if __name__ == '__main__': - test_examples_efuse() - test_examples_efuse_with_virt_flash_enc() - test_examples_efuse_with_virt_flash_enc_pre_loaded() - test_examples_efuse_with_virt_flash_enc_aes_256() - test_examples_efuse_with_virt_flash_enc_release() - test_examples_efuse_with_virt_secure_boot_v1() - test_examples_efuse_with_virt_secure_boot_v1_pre_loaded() - test_examples_efuse_with_virt_secure_boot_v2() - test_examples_efuse_with_virt_secure_boot_v2_pre_loaded() - test_examples_efuse_with_virt_secure_boot_v2_esp32xx() - test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded() - test_examples_efuse_with_virt_sb_v1_and_fe() - test_examples_efuse_with_virt_sb_v2_and_fe() - test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx() +@pytest.mark.esp32c3 +@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32c3'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_sb_v2_and_fe_esp32c3(dut: Dut) -> None: + test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut) + + +@pytest.mark.esp32c2 +@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32c2'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_sb_v2_and_fe_esp32c2(dut: Dut) -> None: + test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut) + + +@pytest.mark.esp32s2 +@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32s2'], indirect=True) +@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +def test_examples_efuse_with_virt_sb_v2_and_fe_esp32s2(dut: Dut) -> None: + test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut)