storage: implement no_backup option (aka seedless setup)

pull/25/head
Pavol Rusnak 6 years ago
parent 1991d44e6b
commit d2521de385
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -1,7 +1,7 @@
with import <nixpkgs> {};
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";

@ -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":

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

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

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

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

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

@ -1 +1 @@
Subproject commit 6c47e483d4e7dc6c5149cf53d11e543a6f2a07bd
Subproject commit 41e4a84b5b01d03e980f84fab29c8f0b0ec948f5
Loading…
Cancel
Save