diff --git a/shell.nix b/shell.nix index a4155b4795..54b9e061a7 100644 --- a/shell.nix +++ b/shell.nix @@ -1,7 +1,7 @@ with import {}; let - myPython = python36.withPackages(ps: [ps.trezor ps.pytest]); + myPython = python36.withPackages(ps: [ps.trezor ps.pytest ps.flake8 ps.isort ps.black]); in stdenv.mkDerivation { name = "trezor-core-dev"; diff --git a/src/apps/common/storage.py b/src/apps/common/storage.py index 6295e06e33..af43a6321e 100644 --- a/src/apps/common/storage.py +++ b/src/apps/common/storage.py @@ -25,6 +25,7 @@ _U2F_COUNTER = const(0x09) # int _PASSPHRASE_SOURCE = const(0x0A) # int _UNFINISHED_BACKUP = const(0x0B) # bool (0x01 or empty) _AUTOLOCK_DELAY_MS = const(0x0C) # int +_NO_BACKUP = const(0x0D) # bool (0x01 or empty) # fmt: on @@ -60,13 +61,17 @@ def get_homescreen() -> bytes: return config.get(_APP, _HOMESCREEN, True) # public -def load_mnemonic(mnemonic: str, needs_backup: bool) -> None: +def load_mnemonic(mnemonic: str, needs_backup: bool, no_backup: bool) -> None: config.set(_APP, _MNEMONIC, mnemonic.encode()) config.set(_APP, _VERSION, _STORAGE_VERSION) - if needs_backup: - config.set(_APP, _NEEDS_BACKUP, b"\x01") + if no_backup: + config.set(_APP, _NO_BACKUP, b"\x01") else: - config.set(_APP, _NEEDS_BACKUP, b"") + config.set(_APP, _NO_BACKUP, b"") + if needs_backup: + config.set(_APP, _NEEDS_BACKUP, b"\x01") + else: + config.set(_APP, _NEEDS_BACKUP, b"") def needs_backup() -> bool: @@ -88,6 +93,10 @@ def set_unfinished_backup(state: bool) -> None: config.set(_APP, _UNFINISHED_BACKUP, b"") +def no_backup() -> bool: + return bool(config.get(_APP, _NO_BACKUP)) + + def get_passphrase_source() -> int: b = config.get(_APP, _PASSPHRASE_SOURCE) if b == b"\x01": diff --git a/src/apps/homescreen/__init__.py b/src/apps/homescreen/__init__.py index 7461ea383c..9e7c089eeb 100644 --- a/src/apps/homescreen/__init__.py +++ b/src/apps/homescreen/__init__.py @@ -25,6 +25,7 @@ def get_features(): f.passphrase_cached = cache.has_passphrase() f.needs_backup = storage.needs_backup() f.unfinished_backup = storage.unfinished_backup() + f.no_backup = storage.no_backup() f.flags = storage.get_flags() return f diff --git a/src/apps/homescreen/homescreen.py b/src/apps/homescreen/homescreen.py index 5eaa97f2c2..3a9777e92d 100644 --- a/src/apps/homescreen/homescreen.py +++ b/src/apps/homescreen/homescreen.py @@ -23,7 +23,13 @@ def display_homescreen(): if not image: image = res.load("apps/homescreen/res/bg.toif") - if storage.is_initialized() and storage.unfinished_backup(): + if storage.is_initialized() and storage.no_backup(): + ui.display.bar(0, 0, ui.WIDTH, 30, ui.RED) + ui.display.text_center( + ui.WIDTH // 2, 22, "NO BACKUP!", ui.BOLD, ui.WHITE, ui.RED + ) + ui.display.bar(0, 30, ui.WIDTH, ui.HEIGHT - 30, ui.BG) + elif storage.is_initialized() and storage.unfinished_backup(): ui.display.bar(0, 0, ui.WIDTH, 30, ui.RED) ui.display.text_center( ui.WIDTH // 2, 22, "BACKUP FAILED!", ui.BOLD, ui.WHITE, ui.RED diff --git a/src/apps/management/reset_device.py b/src/apps/management/reset_device.py index 20d7f47e60..a3bc4f3656 100644 --- a/src/apps/management/reset_device.py +++ b/src/apps/management/reset_device.py @@ -46,7 +46,7 @@ async def reset_device(ctx, msg): ent_ack = await ctx.call(EntropyRequest(), MessageType.EntropyAck) mnemonic = generate_mnemonic(msg.strength, internal_ent, ent_ack.entropy) - if not msg.skip_backup: + if not msg.skip_backup and not msg.no_backup: # require confirmation of the mnemonic safety await show_warning(ctx) @@ -63,11 +63,13 @@ async def reset_device(ctx, msg): # write settings and mnemonic into storage storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) - storage.load_mnemonic(mnemonic=mnemonic, needs_backup=msg.skip_backup) + storage.load_mnemonic( + mnemonic=mnemonic, needs_backup=msg.skip_backup, no_backup=msg.no_backup + ) # show success message. if we skipped backup, it's possible that homescreen # is still running, uninterrupted. restart it to pick up new label. - if not msg.skip_backup: + if not msg.skip_backup and not msg.no_backup: await show_success(ctx) else: workflow.restartdefault() diff --git a/src/trezor/messages/Features.py b/src/trezor/messages/Features.py index e82ed51e7b..47507c5e40 100644 --- a/src/trezor/messages/Features.py +++ b/src/trezor/messages/Features.py @@ -34,6 +34,7 @@ class Features(p.MessageType): fw_vendor: str = None, fw_vendor_keys: bytes = None, unfinished_backup: bool = None, + no_backup: bool = None, ) -> None: self.vendor = vendor self.major_version = major_version @@ -61,6 +62,7 @@ class Features(p.MessageType): self.fw_vendor = fw_vendor self.fw_vendor_keys = fw_vendor_keys self.unfinished_backup = unfinished_backup + self.no_backup = no_backup @classmethod def get_fields(cls): @@ -91,4 +93,5 @@ class Features(p.MessageType): 25: ('fw_vendor', p.UnicodeType, 0), 26: ('fw_vendor_keys', p.BytesType, 0), 27: ('unfinished_backup', p.BoolType, 0), + 28: ('no_backup', p.BoolType, 0), } diff --git a/src/trezor/messages/ResetDevice.py b/src/trezor/messages/ResetDevice.py index 7689776b2b..8c41eafc32 100644 --- a/src/trezor/messages/ResetDevice.py +++ b/src/trezor/messages/ResetDevice.py @@ -16,6 +16,7 @@ class ResetDevice(p.MessageType): label: str = None, u2f_counter: int = None, skip_backup: bool = None, + no_backup: bool = None, ) -> None: self.display_random = display_random self.strength = strength @@ -25,6 +26,7 @@ class ResetDevice(p.MessageType): self.label = label self.u2f_counter = u2f_counter self.skip_backup = skip_backup + self.no_backup = no_backup @classmethod def get_fields(cls): @@ -37,4 +39,5 @@ class ResetDevice(p.MessageType): 6: ('label', p.UnicodeType, 0), 7: ('u2f_counter', p.UVarintType, 0), 8: ('skip_backup', p.BoolType, 0), + 9: ('no_backup', p.BoolType, 0), } diff --git a/vendor/trezor-common b/vendor/trezor-common index 6c47e483d4..41e4a84b5b 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit 6c47e483d4e7dc6c5149cf53d11e543a6f2a07bd +Subproject commit 41e4a84b5b01d03e980f84fab29c8f0b0ec948f5