1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00

storage: implement no_backup option (aka seedless setup)

This commit is contained in:
Pavol Rusnak 2018-10-04 17:36:44 +02:00
parent 1991d44e6b
commit d2521de385
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
8 changed files with 34 additions and 10 deletions

View File

@ -1,7 +1,7 @@
with import <nixpkgs> {}; with import <nixpkgs> {};
let let
myPython = python36.withPackages(ps: [ps.trezor ps.pytest]); myPython = python36.withPackages(ps: [ps.trezor ps.pytest ps.flake8 ps.isort ps.black]);
in in
stdenv.mkDerivation { stdenv.mkDerivation {
name = "trezor-core-dev"; name = "trezor-core-dev";

View File

@ -25,6 +25,7 @@ _U2F_COUNTER = const(0x09) # int
_PASSPHRASE_SOURCE = const(0x0A) # int _PASSPHRASE_SOURCE = const(0x0A) # int
_UNFINISHED_BACKUP = const(0x0B) # bool (0x01 or empty) _UNFINISHED_BACKUP = const(0x0B) # bool (0x01 or empty)
_AUTOLOCK_DELAY_MS = const(0x0C) # int _AUTOLOCK_DELAY_MS = const(0x0C) # int
_NO_BACKUP = const(0x0D) # bool (0x01 or empty)
# fmt: on # fmt: on
@ -60,13 +61,17 @@ def get_homescreen() -> bytes:
return config.get(_APP, _HOMESCREEN, True) # public 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, _MNEMONIC, mnemonic.encode())
config.set(_APP, _VERSION, _STORAGE_VERSION) config.set(_APP, _VERSION, _STORAGE_VERSION)
if needs_backup: if no_backup:
config.set(_APP, _NEEDS_BACKUP, b"\x01") config.set(_APP, _NO_BACKUP, b"\x01")
else: 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: def needs_backup() -> bool:
@ -88,6 +93,10 @@ def set_unfinished_backup(state: bool) -> None:
config.set(_APP, _UNFINISHED_BACKUP, b"") config.set(_APP, _UNFINISHED_BACKUP, b"")
def no_backup() -> bool:
return bool(config.get(_APP, _NO_BACKUP))
def get_passphrase_source() -> int: def get_passphrase_source() -> int:
b = config.get(_APP, _PASSPHRASE_SOURCE) b = config.get(_APP, _PASSPHRASE_SOURCE)
if b == b"\x01": if b == b"\x01":

View File

@ -25,6 +25,7 @@ def get_features():
f.passphrase_cached = cache.has_passphrase() f.passphrase_cached = cache.has_passphrase()
f.needs_backup = storage.needs_backup() f.needs_backup = storage.needs_backup()
f.unfinished_backup = storage.unfinished_backup() f.unfinished_backup = storage.unfinished_backup()
f.no_backup = storage.no_backup()
f.flags = storage.get_flags() f.flags = storage.get_flags()
return f return f

View File

@ -23,7 +23,13 @@ def display_homescreen():
if not image: if not image:
image = res.load("apps/homescreen/res/bg.toif") 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.bar(0, 0, ui.WIDTH, 30, ui.RED)
ui.display.text_center( ui.display.text_center(
ui.WIDTH // 2, 22, "BACKUP FAILED!", ui.BOLD, ui.WHITE, ui.RED ui.WIDTH // 2, 22, "BACKUP FAILED!", ui.BOLD, ui.WHITE, ui.RED

View File

@ -46,7 +46,7 @@ async def reset_device(ctx, msg):
ent_ack = await ctx.call(EntropyRequest(), MessageType.EntropyAck) ent_ack = await ctx.call(EntropyRequest(), MessageType.EntropyAck)
mnemonic = generate_mnemonic(msg.strength, internal_ent, ent_ack.entropy) 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 # require confirmation of the mnemonic safety
await show_warning(ctx) await show_warning(ctx)
@ -63,11 +63,13 @@ async def reset_device(ctx, msg):
# write settings and mnemonic into storage # write settings and mnemonic into storage
storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) 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 # show success message. if we skipped backup, it's possible that homescreen
# is still running, uninterrupted. restart it to pick up new label. # 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) await show_success(ctx)
else: else:
workflow.restartdefault() workflow.restartdefault()

View File

@ -34,6 +34,7 @@ class Features(p.MessageType):
fw_vendor: str = None, fw_vendor: str = None,
fw_vendor_keys: bytes = None, fw_vendor_keys: bytes = None,
unfinished_backup: bool = None, unfinished_backup: bool = None,
no_backup: bool = None,
) -> None: ) -> None:
self.vendor = vendor self.vendor = vendor
self.major_version = major_version self.major_version = major_version
@ -61,6 +62,7 @@ class Features(p.MessageType):
self.fw_vendor = fw_vendor self.fw_vendor = fw_vendor
self.fw_vendor_keys = fw_vendor_keys self.fw_vendor_keys = fw_vendor_keys
self.unfinished_backup = unfinished_backup self.unfinished_backup = unfinished_backup
self.no_backup = no_backup
@classmethod @classmethod
def get_fields(cls): def get_fields(cls):
@ -91,4 +93,5 @@ class Features(p.MessageType):
25: ('fw_vendor', p.UnicodeType, 0), 25: ('fw_vendor', p.UnicodeType, 0),
26: ('fw_vendor_keys', p.BytesType, 0), 26: ('fw_vendor_keys', p.BytesType, 0),
27: ('unfinished_backup', p.BoolType, 0), 27: ('unfinished_backup', p.BoolType, 0),
28: ('no_backup', p.BoolType, 0),
} }

View File

@ -16,6 +16,7 @@ class ResetDevice(p.MessageType):
label: str = None, label: str = None,
u2f_counter: int = None, u2f_counter: int = None,
skip_backup: bool = None, skip_backup: bool = None,
no_backup: bool = None,
) -> None: ) -> None:
self.display_random = display_random self.display_random = display_random
self.strength = strength self.strength = strength
@ -25,6 +26,7 @@ class ResetDevice(p.MessageType):
self.label = label self.label = label
self.u2f_counter = u2f_counter self.u2f_counter = u2f_counter
self.skip_backup = skip_backup self.skip_backup = skip_backup
self.no_backup = no_backup
@classmethod @classmethod
def get_fields(cls): def get_fields(cls):
@ -37,4 +39,5 @@ class ResetDevice(p.MessageType):
6: ('label', p.UnicodeType, 0), 6: ('label', p.UnicodeType, 0),
7: ('u2f_counter', p.UVarintType, 0), 7: ('u2f_counter', p.UVarintType, 0),
8: ('skip_backup', p.BoolType, 0), 8: ('skip_backup', p.BoolType, 0),
9: ('no_backup', p.BoolType, 0),
} }

@ -1 +1 @@
Subproject commit 6c47e483d4e7dc6c5149cf53d11e543a6f2a07bd Subproject commit 41e4a84b5b01d03e980f84fab29c8f0b0ec948f5