1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-08 22:40:59 +00:00
trezor-firmware/src/apps/common/storage.py

183 lines
4.6 KiB
Python
Raw Normal View History

2016-09-29 10:29:43 +00:00
from micropython import const
2018-02-27 15:35:21 +00:00
from ubinascii import hexlify
2018-07-03 14:20:26 +00:00
2016-09-26 11:06:28 +00:00
from trezor import config
2018-02-27 15:35:21 +00:00
from trezor.crypto import random
2018-07-03 14:20:26 +00:00
2018-02-27 15:35:21 +00:00
from apps.common import cache
2016-11-23 13:46:55 +00:00
HOMESCREEN_MAXSIZE = 16384
2018-07-03 14:20:58 +00:00
_STORAGE_VERSION = b"\x01"
2016-11-23 13:46:55 +00:00
# fmt: off
_APP = const(0x01) # app namespace
_DEVICE_ID = const(0x00) # bytes
_VERSION = const(0x01) # int
_MNEMONIC = const(0x02) # str
_LANGUAGE = const(0x03) # str
_LABEL = const(0x04) # str
_USE_PASSPHRASE = const(0x05) # bool (0x01 or empty)
_HOMESCREEN = const(0x06) # bytes
_NEEDS_BACKUP = const(0x07) # bool (0x01 or empty)
_FLAGS = const(0x08) # int
_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
2016-09-26 11:06:28 +00:00
def _new_device_id() -> str:
return hexlify(random.bytes(12)).decode().upper()
def get_device_id() -> str:
dev_id = config.get(_APP, _DEVICE_ID, True).decode() # public
if not dev_id:
dev_id = _new_device_id()
config.set(_APP, _DEVICE_ID, dev_id.encode(), True) # public
2016-11-23 13:46:55 +00:00
return dev_id
2016-09-26 11:06:28 +00:00
def is_initialized() -> bool:
2017-10-24 11:58:40 +00:00
return bool(config.get(_APP, _VERSION))
2016-11-15 10:50:45 +00:00
def get_label() -> str:
return config.get(_APP, _LABEL, True).decode() # public
2016-12-15 11:48:33 +00:00
def get_mnemonic() -> str:
2017-10-24 11:58:40 +00:00
return config.get(_APP, _MNEMONIC).decode()
2016-11-23 13:46:55 +00:00
2017-10-24 11:58:40 +00:00
def has_passphrase() -> bool:
return bool(config.get(_APP, _USE_PASSPHRASE))
2017-12-13 01:41:59 +00:00
def get_homescreen() -> bytes:
return config.get(_APP, _HOMESCREEN, True) # public
2017-12-13 01:41:59 +00:00
def load_mnemonic(mnemonic: str, needs_backup: bool, no_backup: bool) -> None:
2017-10-24 11:58:40 +00:00
config.set(_APP, _MNEMONIC, mnemonic.encode())
config.set(_APP, _VERSION, _STORAGE_VERSION)
if no_backup:
config.set(_APP, _NO_BACKUP, b"\x01")
else:
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:
return bool(config.get(_APP, _NEEDS_BACKUP))
def set_backed_up() -> None:
2018-07-03 14:20:58 +00:00
config.set(_APP, _NEEDS_BACKUP, b"")
def unfinished_backup() -> bool:
return bool(config.get(_APP, _UNFINISHED_BACKUP))
def set_unfinished_backup(state: bool) -> None:
if state:
2018-07-03 14:20:58 +00:00
config.set(_APP, _UNFINISHED_BACKUP, b"\x01")
else:
2018-07-03 14:20:58 +00:00
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)
2018-07-03 14:20:58 +00:00
if b == b"\x01":
return 1
2018-07-03 14:20:58 +00:00
elif b == b"\x02":
return 2
else:
return 0
2018-07-03 14:20:58 +00:00
def load_settings(
label: str = None,
use_passphrase: bool = None,
homescreen: bytes = None,
passphrase_source: int = None,
) -> None:
2017-10-24 11:58:40 +00:00
if label is not None:
config.set(_APP, _LABEL, label.encode(), True) # public
2017-10-24 11:58:40 +00:00
if use_passphrase is True:
2018-07-03 14:20:58 +00:00
config.set(_APP, _USE_PASSPHRASE, b"\x01")
2017-10-24 11:58:40 +00:00
if use_passphrase is False:
2018-07-03 14:20:58 +00:00
config.set(_APP, _USE_PASSPHRASE, b"")
2017-12-13 01:41:59 +00:00
if homescreen is not None:
2018-07-03 14:20:58 +00:00
if homescreen[:8] == b"TOIf\x90\x00\x90\x00":
if len(homescreen) <= HOMESCREEN_MAXSIZE:
config.set(_APP, _HOMESCREEN, homescreen, True) # public
2017-12-13 01:41:59 +00:00
else:
2018-07-03 14:20:58 +00:00
config.set(_APP, _HOMESCREEN, b"", True) # public
if passphrase_source is not None:
if passphrase_source in [0, 1, 2]:
config.set(_APP, _PASSPHRASE_SOURCE, bytes([passphrase_source]))
2016-12-15 11:48:33 +00:00
def get_flags() -> int:
b = config.get(_APP, _FLAGS)
if b is None:
return 0
else:
2018-07-03 14:20:58 +00:00
return int.from_bytes(b, "big")
def set_flags(flags: int) -> None:
b = config.get(_APP, _FLAGS)
if b is None:
b = 0
else:
2018-07-03 14:20:58 +00:00
b = int.from_bytes(b, "big")
flags = (flags | b) & 0xFFFFFFFF
if flags != b:
2018-07-03 14:20:58 +00:00
config.set(_APP, _FLAGS, flags.to_bytes(4, "big"))
def get_autolock_delay_ms() -> int:
b = config.get(_APP, _AUTOLOCK_DELAY_MS)
if b is None:
return 10 * 60 * 1000
else:
2018-07-03 14:20:58 +00:00
return int.from_bytes(b, "big")
def set_autolock_delay_ms(delay_ms: int) -> None:
if delay_ms < 60 * 1000:
delay_ms = 60 * 1000
2018-07-03 14:20:58 +00:00
config.set(_APP, _AUTOLOCK_DELAY_MS, delay_ms.to_bytes(4, "big"))
def next_u2f_counter() -> int:
b = config.get(_APP, _U2F_COUNTER)
if b is None:
b = 0
else:
2018-07-03 14:20:58 +00:00
b = int.from_bytes(b, "big") + 1
set_u2f_counter(b)
return b
def set_u2f_counter(cntr: int):
2018-07-03 14:20:58 +00:00
config.set(_APP, _U2F_COUNTER, cntr.to_bytes(4, "big"))
2016-11-23 13:46:55 +00:00
def wipe():
config.wipe()
cache.clear()