1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-01 20:08:26 +00:00
trezor-firmware/core/src/storage/recovery.py

158 lines
4.1 KiB
Python
Raw Normal View History

2019-07-11 14:52:25 +00:00
from micropython import const
2024-04-23 10:26:46 +00:00
from typing import TYPE_CHECKING
2019-07-11 14:52:25 +00:00
from storage import common
2024-04-23 10:26:46 +00:00
if TYPE_CHECKING:
from trezor.enums import RecoveryType
2024-04-23 10:26:46 +00:00
2019-07-11 14:52:25 +00:00
# Namespace:
_NAMESPACE = common.APP_RECOVERY
2019-07-11 14:52:25 +00:00
# fmt: off
# Keys:
_IN_PROGRESS = const(0x00) # bool
_TYPE = const(0x01) # int
2019-07-11 14:52:25 +00:00
_SLIP39_IDENTIFIER = const(0x03) # bytes
2019-09-19 07:37:23 +00:00
_REMAINING = const(0x05) # int
2019-07-11 14:52:25 +00:00
_SLIP39_ITERATION_EXPONENT = const(0x06) # int
_SLIP39_GROUP_COUNT = const(0x07) # int
_SLIP39_EXTENDABLE = const(0x08) # bool
# Deprecated Keys:
# _WORD_COUNT = const(0x02) # int
# _SLIP39_THRESHOLD = const(0x04) # int
2019-07-11 14:52:25 +00:00
# fmt: on
# Default values:
_DEFAULT_SLIP39_GROUP_COUNT = const(1)
2019-10-02 12:40:25 +00:00
def _require_progress() -> None:
if not is_in_progress():
raise RuntimeError
def set_in_progress(val: bool) -> None:
common.set_bool(_NAMESPACE, _IN_PROGRESS, val)
2019-07-11 14:52:25 +00:00
def is_in_progress() -> bool:
return common.get_bool(_NAMESPACE, _IN_PROGRESS)
2019-07-11 14:52:25 +00:00
def set_type(val: int) -> None:
_require_progress()
common.set_uint8(_NAMESPACE, _TYPE, val)
2024-04-23 10:26:46 +00:00
2019-07-11 14:52:25 +00:00
def get_type() -> RecoveryType:
from trezor.enums import RecoveryType
2019-07-11 14:52:25 +00:00
_require_progress()
recovery_type = common.get_uint8(_NAMESPACE, _TYPE)
if recovery_type is None:
recovery_type = RecoveryType.NormalRecovery
if recovery_type not in (
RecoveryType.NormalRecovery,
RecoveryType.DryRun,
RecoveryType.UnlockRepeatedBackup,
2024-04-23 10:26:46 +00:00
):
# Invalid recovery type
2024-04-23 10:26:46 +00:00
raise RuntimeError
return recovery_type
2019-07-11 14:52:25 +00:00
def set_slip39_identifier(identifier: int) -> None:
_require_progress()
common.set_uint16(_NAMESPACE, _SLIP39_IDENTIFIER, identifier)
2019-07-11 14:52:25 +00:00
def get_slip39_identifier() -> int | None:
_require_progress()
return common.get_uint16(_NAMESPACE, _SLIP39_IDENTIFIER)
2019-07-11 14:52:25 +00:00
def set_slip39_iteration_exponent(exponent: int) -> None:
_require_progress()
common.set_uint8(_NAMESPACE, _SLIP39_ITERATION_EXPONENT, exponent)
2019-07-11 14:52:25 +00:00
def get_slip39_iteration_exponent() -> int | None:
_require_progress()
return common.get_uint8(_NAMESPACE, _SLIP39_ITERATION_EXPONENT)
2019-07-11 14:52:25 +00:00
def set_slip39_group_count(group_count: int) -> None:
_require_progress()
common.set_uint8(_NAMESPACE, _SLIP39_GROUP_COUNT, group_count)
2019-10-02 12:40:25 +00:00
def get_slip39_group_count() -> int:
_require_progress()
return (
common.get_uint8(_NAMESPACE, _SLIP39_GROUP_COUNT) or _DEFAULT_SLIP39_GROUP_COUNT
)
2019-09-19 07:37:23 +00:00
def set_slip39_remaining_shares(shares_remaining: int, group_index: int) -> None:
"""
We store the remaining shares as a bytearray of length group_count.
Each byte represents share remaining for group of that group_index.
0x10 (16) was chosen as the default value because it's the max
share count for a group.
"""
from trezor.crypto.slip39 import MAX_SHARE_COUNT
_require_progress()
remaining = common.get(_NAMESPACE, _REMAINING)
2019-09-19 07:37:23 +00:00
group_count = get_slip39_group_count()
if not group_count:
raise RuntimeError
if remaining is None:
remaining = bytearray([MAX_SHARE_COUNT] * group_count)
remaining = bytearray(remaining)
remaining[group_index] = shares_remaining
common.set(_NAMESPACE, _REMAINING, remaining)
def get_slip39_remaining_shares(group_index: int) -> int | None:
from trezor.crypto.slip39 import MAX_SHARE_COUNT
_require_progress()
remaining = common.get(_NAMESPACE, _REMAINING)
if remaining is None or remaining[group_index] == MAX_SHARE_COUNT:
return None
else:
return remaining[group_index]
def fetch_slip39_remaining_shares() -> list[int] | None:
_require_progress()
remaining = common.get(_NAMESPACE, _REMAINING)
if not remaining:
return None
2019-09-19 13:42:12 +00:00
group_count = get_slip39_group_count()
if not group_count:
raise RuntimeError
return list(remaining[:group_count])
def end_progress() -> None:
from . import recovery_shares
_require_progress()
for key in (
_IN_PROGRESS,
_TYPE,
_SLIP39_IDENTIFIER,
_REMAINING,
_SLIP39_ITERATION_EXPONENT,
_SLIP39_GROUP_COUNT,
):
common.delete(_NAMESPACE, key)
2019-07-11 14:52:25 +00:00
recovery_shares.delete()