Merge branch 'feature/update_efuse_example_test_to_pytest' into 'master'

efuse_exmple_test: Update to pytest framework

See merge request espressif/esp-idf!18702
This commit is contained in:
Aditya Patwardhan
2022-10-28 11:52:53 +08:00
2 changed files with 439 additions and 235 deletions

View File

@@ -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)

View File

@@ -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 from __future__ import unicode_literals
import logging
import os 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 @pytest.mark.generic
emul_efuse_bin_path = os.path.join(dut.app.binary_path, 'emul_efuse.bin') @pytest.mark.esp32
dut.dump_flash(emul_efuse_bin_path, partition='emul_efuse') @pytest.mark.esp32c2
@pytest.mark.esp32c3
def erase_bit(pos_of_bit): # type: (int) -> None def test_examples_efuse(dut: Dut) -> None:
nbytes, nbits = divmod(pos_of_bit, 8) dut.expect(r'example: Coding Scheme (3/4)|(NONE)|(REPEAT)|(RS \(Reed-Solomon coding\))', timeout=20)
with open(emul_efuse_bin_path, 'r+b') as f: dut.expect(['example: read efuse fields',
f.seek(nbytes) r'example: 1. read MAC address: {}'.format(r':'.join((r'[0-9a-f]{2}',) * 6)),
data = ord(f.read(1)) 'example: 2. read secure_version: 0',
data &= ~(1 << nbits) 'example: 3. read custom fields',
f.seek(-1, os.SEEK_CUR) 'example: module_version = 0',
f.write(bytes([data])) 'example: device_role = None',
'example: setting_1 = 0',
for pos_of_bit in sorted(pos_of_bits): 'example: setting_2 = 0',
erase_bit(pos_of_bit) 'example: custom_secure_version = 0',
'example: This example does not burn any efuse in reality only virtually',
offs = dut.app.partition_table['emul_efuse']['offset'] 'example: Write operations in efuse fields are performed virtually',
flash_files = [(offs, emul_efuse_bin_path)] 'example: write custom efuse fields',
dut.write_flash(flash_files) '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']) @pytest.mark.generic
def test_examples_efuse(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.esp32
dut = env.get_dut('efuse', 'examples/system/efuse') @pytest.mark.esp32s2
dut.start_app() @pytest.mark.esp32c2
dut.expect_all(re.compile(r'example: Coding Scheme (3/4)|(NONE)|(REPEAT)|(RS \(Reed-Solomon coding\))'), @pytest.mark.esp32c3
'example: read efuse fields', @pytest.mark.parametrize('config', ['virt_flash_enc',], indirect=True)
re.compile(r'example: 1. read MAC address: {}'.format(r':'.join((r'[0-9a-f]{2}',) * 6))), @pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
'example: 2. read secure_version: 0', def test_examples_efuse_with_virt_flash_enc(dut: Dut) -> None:
'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')
# check and log bin size # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Checking flash encryption...') dut.expect('Checking flash encryption...')
dut.expect('Generating new flash encryption key...') 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('Writing EFUSE_BLK_KEY0 with purpose 2')
dut.expect('Setting CRYPT_CONFIG efuse to 0xF') dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('Not disabling UART bootloader encryption') 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 JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...') dut.expect('Disable ROM BASIC interpreter fallback...')
else: else:
if dut.TARGET == 'esp32c2': if dut.app.target == 'esp32c2':
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1') dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1')
else: else:
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4') 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('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...') dut.expect('Checking flash encryption...')
if dut.TARGET == 'esp32': if dut.app.target == 'esp32':
dut.expect('flash encryption is enabled (3 plaintext flashes left)') dut.expect_exact('flash encryption is enabled (3 plaintext flashes left)', timeout=3)
else: 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2']) @pytest.mark.generic
def test_examples_efuse_with_virt_flash_enc_aes_256(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @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 # 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 # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Checking flash encryption...') dut.expect('Checking flash encryption...')
dut.expect('Generating new flash encryption key...') 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('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...') 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2']) @pytest.mark.generic
def test_examples_efuse_with_virt_flash_enc_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.esp32
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc') @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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Flash encryption completed', timeout=90) dut.expect('Flash encryption completed', timeout=90)
dut.expect('Resetting with flash encryption enabled...') 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('Start eFuse example')
dut.expect('example: Done') 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)') 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 # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv
FLASH_CRYPT_CNT = 20 FLASH_CRYPT_CNT = 20
# Resets eFuse, which enables Flash encryption feature # Resets eFuse, which enables Flash encryption feature
erase_field_on_emul_efuse(dut, [FLASH_CRYPT_CNT]) dut.serial.erase_field_on_emul_efuse([FLASH_CRYPT_CNT])
elif dut.TARGET == 'esp32c2': elif dut.app.target == 'esp32c2':
FLASH_CRYPT_CNT = 39 FLASH_CRYPT_CNT = 39
erase_field_on_emul_efuse(dut, [FLASH_CRYPT_CNT]) dut.serial.erase_field_on_emul_efuse([FLASH_CRYPT_CNT])
else: else:
# offset of this eFuse is taken from components/efuse/{target}/esp_efuse_table.csv # 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)') print(' - Flash emul_efuse with pre-loaded efuses (SPI_BOOT_CRYPT_CNT 1 -> 0)')
SPI_BOOT_CRYPT_CNT = 82 SPI_BOOT_CRYPT_CNT = 82
# Resets eFuse, which enables Flash encryption feature # 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)') 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('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...') dut.expect('Checking flash encryption...')
dut.expect('Using pre-loaded flash encryption key in efuse') 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('Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('Not disabling UART bootloader encryption') dut.expect('Not disabling UART bootloader encryption')
dut.expect('Disable UART bootloader decryption...') 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('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...') dut.expect('Checking flash encryption...')
if dut.TARGET == 'esp32': if dut.app.target == 'esp32':
dut.expect('flash encryption is enabled (3 plaintext flashes left)') dut.expect_exact('flash encryption is enabled (3 plaintext flashes left)')
else: 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2']) @pytest.mark.generic
def test_examples_efuse_with_virt_flash_enc_release(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.esp32
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc_release') @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 # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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.serial.erase_flash()
dut.erase_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Checking flash encryption...') dut.expect('Checking flash encryption...')
dut.expect('Generating new flash encryption key...') 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('Writing EFUSE_BLK_KEY0 with purpose 2')
dut.expect('Setting CRYPT_CONFIG efuse to 0xF') dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
dut.expect('Disable UART bootloader encryption...') 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 JTAG...')
dut.expect('Disable ROM BASIC interpreter fallback...') dut.expect('Disable ROM BASIC interpreter fallback...')
else: else:
if dut.TARGET == 'esp32c2': if dut.app.target == 'esp32c2':
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1') dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1')
else: else:
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4') 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('Loading virtual efuse blocks from flash')
dut.expect('Checking flash encryption...') 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('Flash encryption mode is RELEASE')
dut.expect('Start eFuse example') dut.expect('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) @pytest.mark.generic
def test_examples_efuse_with_virt_secure_boot_v1(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @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 # only for ESP32
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1')
# check and log bin size # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Flash bootloader') print(' - Flash bootloader')
dut.bootloader_flash() dut.serial.bootloader_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...') 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
dut.reset() dut.serial.hard_reset()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..') 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') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) @pytest.mark.generic
def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.esp32
# only for ESP32 @pytest.mark.parametrize('config', ['virt_secure_boot_v1',], indirect=True)
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1') @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') 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('Loading virtual efuse blocks from real efuses')
dut.expect('cpu_start: Pro cpu up') dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash') 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 # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv
ABS_DONE_0 = 196 ABS_DONE_0 = 196
# Resets eFuse, which enables Secure boot (V1) feature # 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)') print(' - Start app (flash partition_table and app)')
dut.start_app() dut.serial.flash()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
dut.reset() dut.serial.hard_reset()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') dut.expect('Verifying image signature...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..') 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') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32']) @pytest.mark.esp32
def test_examples_efuse_with_virt_secure_boot_v2(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @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 # 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') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Flash bootloader') print(' - Flash bootloader')
dut.bootloader_flash() dut.serial.bootloader_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...') 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: 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: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...') 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: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..') 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: 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('Writing EFUSE_BLK_KEY1 with purpose 3')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') 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_exact('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: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Disable JTAG...') 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('Start eFuse example')
dut.expect('example: Done') 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('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...') 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') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32']) @pytest.mark.esp32
def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.parametrize('config', [('virt_secure_boot_v2.esp32'),], indirect=True)
# only for ESP32 ECO3 @pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
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_pre_loaded(dut: Dut) -> None:
print(' - Erase flash') print(' - Erase flash')
dut.erase_flash() dut.erase_flash()
print(' - Flash bootloader and app') print(' - Flash bootloader and app')
dut.bootloader_flash() 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('Loading virtual efuse blocks from real efuses')
dut.expect('cpu_start: Pro cpu up') dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash') 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 # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv
ABS_DONE_1 = 197 ABS_DONE_1 = 197
# Resets eFuse, which enables Secure boot (V2) feature # 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)') print(' - Start app (flash partition_table and app)')
dut.start_app() dut.serial.flash()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') 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: Secure boot digests already present')
dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse') 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: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') dut.expect_exact('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: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Disable JTAG...') 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
dut.reset() dut.serial.hard_reset()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with RSA-PSS...') 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') 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(dut: Dut) -> None:
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)
# check and log bin size # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Flash bootloader') print(' - Flash bootloader')
dut.bootloader_flash() dut.serial.bootloader_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...') 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: 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: Verifying with %s...' % signed_scheme)
dut.expect('secure_boot_v2: Signature verified successfully!') 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: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..') 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: 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') dut.expect('Writing EFUSE_BLK_KEY0 with purpose 3')
else: else:
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9') 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: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') dut.expect_exact('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: Application key(0) matches with bootloader key(0)')
if dut.TARGET != 'esp32c2': if dut.app.target != 'esp32c2':
dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...') dut.expect_exact('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: Revoking empty key digest slot (2)...')
dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED') dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED')
dut.expect('Disable hardware & software JTAG...') 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
dut.reset() dut.serial.hard_reset()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme) 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') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2', 'esp32c3', 'esp32c2']) @pytest.mark.generic
def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.esp32c3
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET) @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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Flash bootloader and app') print(' - Flash bootloader and app')
dut.bootloader_flash() dut.serial.bootloader_flash()
dut.start_app() dut.serial.flash()
dut.expect('Loading virtual efuse blocks from real efuses') dut.expect('Loading virtual efuse blocks from real efuses')
dut.expect('cpu_start: Pro cpu up') dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash') 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)') 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 # 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 SECURE_BOOT_EN = 53
erase_field_on_emul_efuse(dut, [SECURE_BOOT_EN]) dut.serial.erase_field_on_emul_efuse([SECURE_BOOT_EN])
else: else:
SECURE_BOOT_EN = 116 SECURE_BOOT_EN = 116
SECURE_BOOT_KEY_REVOKE0 = 85 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 SECURE_BOOT_KEY_REVOKE2 = 87
# Resets eFuse, which enables Secure boot feature # Resets eFuse, which enables Secure boot feature
# Resets eFuses, which control digest slots # 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)') print(' - Start app (flash partition_table and app)')
dut.start_app() dut.serial.flash()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') 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: Verifying with %s...' % signed_scheme)
dut.expect('secure_boot_v2: Signature verified successfully!') dut.expect('secure_boot_v2: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests already present') 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: Using pre-loaded public key digest in eFuse')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') 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_exact('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.app.target != 'esp32c2':
if dut.TARGET != 'esp32c2': dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (1)...')
dut.expect('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: Revoking empty key digest slot (2)...')
dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED') dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED')
dut.expect('Disable hardware & software JTAG...') 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('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Start eFuse example') dut.expect('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
dut.reset() dut.serial.hard_reset()
dut.expect('Loading virtual efuse blocks from flash') dut.expect('Loading virtual efuse blocks from flash')
dut.expect('Verifying image signature...') dut.expect('Verifying image signature...')
dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme) 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') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) @pytest.mark.generic
def test_examples_efuse_with_virt_sb_v1_and_fe(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.esp32c3
dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v1_and_fe') @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 # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Flash bootloader') print(' - Flash bootloader')
dut.bootloader_flash() dut.serial.bootloader_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...') 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('Verifying image signature...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..') dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..')
dut.expect('Checking flash encryption...') 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('Checking secure boot...')
dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..') dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..')
dut.expect('cpu_start: Pro cpu up') dut.expect('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash') 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32']) @pytest.mark.esp32
def test_examples_efuse_with_virt_sb_v2_and_fe(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None @pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32',], indirect=True)
# only for ESP32 ECO3 @pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
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(dut: Dut) -> None:
# check and log bin size # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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') print(' - Erase flash')
dut.erase_flash() dut.serial.erase_flash()
print(' - Flash bootloader') print(' - Flash bootloader')
dut.bootloader_flash() dut.serial.bootloader_flash()
print(' - Start app (flash partition_table and app)') 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('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') 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: Signature verified successfully')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..') 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: 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('Writing EFUSE_BLK_KEY1 with purpose 3')
dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures') 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_exact('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: Application key(0) matches with bootloader key(0)')
dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('Disable JTAG...') 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: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...') dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..') 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('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash') 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('Start eFuse example')
dut.expect('example: Done') 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(dut: Dut) -> None:
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)
# check and log bin size # check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin') binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
bin_size = os.path.getsize(binary_file) 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.serial.erase_flash()
dut.erase_flash()
print(' - Flash bootloader') print(' - Flash bootloader')
dut.bootloader_flash() dut.serial.bootloader_flash()
print(' - Start app (flash partition_table and app)') 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('Loading virtual efuse blocks from real efuses')
dut.expect('Verifying image signature...') 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: 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: Verifying with %s...' % signed_scheme)
dut.expect('secure_boot_v2: Signature verified successfully!') 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: Signature verified successfully!')
dut.expect('secure_boot_v2: Secure boot digests absent, generating..') 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: 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') dut.expect('Writing EFUSE_BLK_KEY0 with purpose 3')
else: else:
dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9') 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: Digests successfully calculated, 1 valid signatures')
dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app') dut.expect_exact('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: Application key(0) matches with bootloader key(0)')
if dut.TARGET != 'esp32c2': if dut.app.target != 'esp32c2':
dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...') dut.expect_exact('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: Revoking empty key digest slot (2)...')
dut.expect('secure_boot_v2: blowing secure boot efuse...') dut.expect('secure_boot_v2: blowing secure boot efuse...')
dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED') dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED')
dut.expect('Disable hardware & software JTAG...') 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('secure_boot_v2: Secure boot permanently enabled')
dut.expect('Checking flash encryption...') dut.expect('Checking flash encryption...')
dut.expect('flash_encrypt: Generating new flash encryption key...') 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') dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
else: else:
dut.expect('Writing EFUSE_BLK_KEY1 with purpose 4') 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 UART bootloader cache...')
dut.expect('Disable JTAG...') dut.expect('Disable JTAG...')
if dut.TARGET == 'esp32c2': if dut.app.target == 'esp32c2':
dut.expect('boot: Secure boot permanently enabled') dut.expect('boot: Secure boot permanently enabled')
dut.expect('Verifying image signature...') 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: Signature verified successfully!')
dut.expect('secure_boot_v2: enabling secure boot v2...') dut.expect('secure_boot_v2: enabling secure boot v2...')
dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..') 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('cpu_start: Pro cpu up')
dut.expect('Loading virtual efuse blocks from flash') 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('Start eFuse example')
dut.expect('example: Done') dut.expect('example: Done')
if __name__ == '__main__': @pytest.mark.esp32c3
test_examples_efuse() @pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32c3'], indirect=True)
test_examples_efuse_with_virt_flash_enc() @pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
test_examples_efuse_with_virt_flash_enc_pre_loaded() def test_examples_efuse_with_virt_sb_v2_and_fe_esp32c3(dut: Dut) -> None:
test_examples_efuse_with_virt_flash_enc_aes_256() test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut)
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() @pytest.mark.esp32c2
test_examples_efuse_with_virt_secure_boot_v2() @pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32c2'], indirect=True)
test_examples_efuse_with_virt_secure_boot_v2_pre_loaded() @pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
test_examples_efuse_with_virt_secure_boot_v2_esp32xx() def test_examples_efuse_with_virt_sb_v2_and_fe_esp32c2(dut: Dut) -> None:
test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded() test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut)
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.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)