1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 12:28:09 +00:00

feat(tests): Add SLIP-39 reset-upgrade-backup test.

This commit is contained in:
Andrew Kozlik 2024-05-24 17:03:08 +02:00 committed by Andrew Kozlik
parent d4953e4af3
commit 162649aec7
2 changed files with 83 additions and 12 deletions

View File

@ -46,6 +46,17 @@ core_only = pytest.mark.skipif(
) )
def version_from_tag(tag: str | None) -> tuple | None:
if tag is None or not tag.startswith("v"):
return None
# Strip initial "v" and optional revision from the tag string.
tag_version = tag[1:].partition("-")[0]
# Translate string to an integer tuple.
return tuple(int(n) for n in tag_version.split("."))
def for_all( def for_all(
*args: str, *args: str,
legacy_minimum_version: Tuple[int, int, int] = (1, 0, 0), legacy_minimum_version: Tuple[int, int, int] = (1, 0, 0),
@ -84,13 +95,9 @@ def for_all(
continue continue
try: try:
for tag in ALL_TAGS[gen]: for tag in ALL_TAGS[gen]:
if tag.startswith("v"): tag_version = version_from_tag(tag)
tag_version = tag[1:] if tag_version is not None and tag_version < minimum_version:
if "-" in tag: # contains revision continue
tag_version = tag[1:-9]
tag_version = tuple(int(n) for n in tag_version.split("."))
if tag_version < minimum_version:
continue
all_params.append((gen, tag)) all_params.append((gen, tag))
# at end, add None tag, which is the current master # at end, add None tag, which is the current master

View File

@ -18,22 +18,26 @@ import dataclasses
from typing import TYPE_CHECKING, List, Optional from typing import TYPE_CHECKING, List, Optional
import pytest import pytest
from shamir_mnemonic import shamir
from trezorlib import btc, debuglink, device, exceptions, fido, models from trezorlib import btc, debuglink, device, exceptions, fido, models
from trezorlib.messages import BackupType from trezorlib.messages import ApplySettings, BackupType, Success
from trezorlib.tools import H_ from trezorlib.tools import H_
from ..common import MNEMONIC_SLIP39_BASIC_20_3of6, MNEMONIC_SLIP39_BASIC_20_3of6_SECRET from ..common import MNEMONIC_SLIP39_BASIC_20_3of6, MNEMONIC_SLIP39_BASIC_20_3of6_SECRET
from ..device_handler import BackgroundDeviceHandler from ..device_handler import BackgroundDeviceHandler
from ..emulators import ALL_TAGS, EmulatorWrapper from ..emulators import ALL_TAGS, EmulatorWrapper
from . import for_all, for_tags, recovery_old from ..input_flows import InputFlowSlip39BasicBackup
from . import for_all, for_tags, recovery_old, version_from_tag
if TYPE_CHECKING: if TYPE_CHECKING:
from trezorlib.debuglink import TrezorClientDebugLink as Client from trezorlib.debuglink import TrezorClientDebugLink as Client
models.TREZOR_ONE = dataclasses.replace(models.TREZOR_ONE, minimum_version=(1, 0, 0)) models.T1B1 = dataclasses.replace(models.T1B1, minimum_version=(1, 0, 0))
models.TREZOR_T = dataclasses.replace(models.TREZOR_T, minimum_version=(2, 0, 0)) models.T2T1 = dataclasses.replace(models.T2T1, minimum_version=(2, 0, 0))
models.TREZORS = {models.TREZOR_ONE, models.TREZOR_T} models.TREZOR_ONE = models.T1B1
models.TREZOR_T = models.T2T1
models.TREZORS = {models.T1B1, models.T2T1}
# **** COMMON DEFINITIONS **** # **** COMMON DEFINITIONS ****
@ -333,6 +337,66 @@ def test_upgrade_shamir_recovery(gen: str, tag: Optional[str]):
assert state.mnemonic_type == BackupType.Slip39_Basic assert state.mnemonic_type == BackupType.Slip39_Basic
@for_all("core", core_minimum_version=(2, 1, 9))
def test_upgrade_shamir_backup(gen: str, tag: Optional[str]):
with EmulatorWrapper(gen, tag) as emu:
# Generate a new encrypted master secret and record it.
device.reset(
emu.client,
pin_protection=False,
skip_backup=True,
backup_type=BackupType.Slip39_Basic,
)
device_id = emu.client.features.device_id
backup_type = emu.client.features.backup_type
mnemonic_secret = emu.client.debug.state().mnemonic_secret
# Set passphrase_source = HOST.
resp = emu.client.call(ApplySettings(_passphrase_source=2, use_passphrase=True))
assert isinstance(resp, Success)
# Get a passphrase-less and a passphrased address.
address = btc.get_address(emu.client, "Bitcoin", PATH)
emu.client.init_device(new_session=True)
emu.client.use_passphrase("TREZOR")
address_passphrase = btc.get_address(emu.client, "Bitcoin", PATH)
assert emu.client.features.needs_backup
storage = emu.get_storage()
with EmulatorWrapper(gen, storage=storage) as emu:
assert emu.client.features.device_id == device_id
# Create a backup of the encrypted master secret.
assert emu.client.features.needs_backup
with emu.client:
IF = InputFlowSlip39BasicBackup(emu.client, False)
emu.client.set_input_flow(IF.get())
device.backup(emu.client)
assert not emu.client.features.needs_backup
# Check the backup type.
assert emu.client.features.backup_type == backup_type
tag_version = version_from_tag(tag)
if tag_version is not None:
assert (
backup_type == BackupType.Slip39_Basic
if tag_version < (2, 7, 1)
else BackupType.Slip39_Basic_Extendable
)
# Check that the backup contains the originally generated encrypted master secret.
groups = shamir.decode_mnemonics(IF.mnemonics[:3])
ems = shamir.recover_ems(groups)
assert ems.ciphertext == mnemonic_secret
# Check that addresses are the same after firmware upgrade and backup.
assert btc.get_address(emu.client, "Bitcoin", PATH) == address
emu.client.init_device(new_session=True)
emu.client.use_passphrase("TREZOR")
assert btc.get_address(emu.client, "Bitcoin", PATH) == address_passphrase
@for_all(legacy_minimum_version=(1, 8, 4), core_minimum_version=(2, 1, 9)) @for_all(legacy_minimum_version=(1, 8, 4), core_minimum_version=(2, 1, 9))
def test_upgrade_u2f(gen: str, tag: str): def test_upgrade_u2f(gen: str, tag: str):
"""Check U2F counter stayed the same after an upgrade.""" """Check U2F counter stayed the same after an upgrade."""