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
|
|
|
|
2021-03-22 15:14:24 +00:00
|
|
|
from storage import common
|
2019-08-14 13:46:08 +00:00
|
|
|
|
2024-04-23 10:26:46 +00:00
|
|
|
if TYPE_CHECKING:
|
2024-05-23 14:09:16 +00:00
|
|
|
from trezor.enums import RecoveryType
|
2024-04-23 10:26:46 +00:00
|
|
|
|
2019-07-11 14:52:25 +00:00
|
|
|
# Namespace:
|
2019-09-12 12:18:00 +00:00
|
|
|
_NAMESPACE = common.APP_RECOVERY
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
# fmt: off
|
|
|
|
# Keys:
|
|
|
|
_IN_PROGRESS = const(0x00) # bool
|
2024-05-23 14:09:16 +00:00
|
|
|
_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
|
2019-08-14 13:46:08 +00:00
|
|
|
_SLIP39_GROUP_COUNT = const(0x07) # int
|
2024-04-30 18:26:46 +00:00
|
|
|
_SLIP39_EXTENDABLE = const(0x08) # bool
|
2019-09-20 07:46:49 +00:00
|
|
|
|
|
|
|
# Deprecated Keys:
|
|
|
|
# _WORD_COUNT = const(0x02) # int
|
2023-06-29 15:26:51 +00:00
|
|
|
# _SLIP39_THRESHOLD = const(0x04) # int
|
2019-07-11 14:52:25 +00:00
|
|
|
# fmt: on
|
|
|
|
|
2019-09-20 07:46:49 +00:00
|
|
|
# Default values:
|
|
|
|
_DEFAULT_SLIP39_GROUP_COUNT = const(1)
|
|
|
|
|
|
|
|
|
2019-10-02 12:40:25 +00:00
|
|
|
def _require_progress() -> None:
|
2019-09-20 07:46:49 +00:00
|
|
|
if not is_in_progress():
|
|
|
|
raise RuntimeError
|
|
|
|
|
|
|
|
|
2019-07-29 14:34:30 +00:00
|
|
|
def set_in_progress(val: bool) -> None:
|
2019-09-12 12:18:00 +00:00
|
|
|
common.set_bool(_NAMESPACE, _IN_PROGRESS, val)
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
|
2019-07-29 14:34:30 +00:00
|
|
|
def is_in_progress() -> bool:
|
2019-09-12 12:18:00 +00:00
|
|
|
return common.get_bool(_NAMESPACE, _IN_PROGRESS)
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
|
2024-05-23 14:09:16 +00:00
|
|
|
def set_type(val: int) -> None:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2024-05-23 14:09:16 +00:00
|
|
|
common.set_uint8(_NAMESPACE, _TYPE, val)
|
2024-04-23 10:26:46 +00:00
|
|
|
|
2019-07-11 14:52:25 +00:00
|
|
|
|
2024-05-23 14:09:16 +00:00
|
|
|
def get_type() -> RecoveryType:
|
|
|
|
from trezor.enums import RecoveryType
|
2019-07-11 14:52:25 +00:00
|
|
|
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2024-05-23 14:09:16 +00:00
|
|
|
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
|
|
|
):
|
2024-05-23 14:09:16 +00:00
|
|
|
# Invalid recovery type
|
2024-04-23 10:26:46 +00:00
|
|
|
raise RuntimeError
|
2024-05-23 14:09:16 +00:00
|
|
|
return recovery_type
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
def set_slip39_identifier(identifier: int) -> None:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
common.set_uint16(_NAMESPACE, _SLIP39_IDENTIFIER, identifier)
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
|
2021-03-18 09:48:50 +00:00
|
|
|
def get_slip39_identifier() -> int | None:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
return common.get_uint16(_NAMESPACE, _SLIP39_IDENTIFIER)
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
def set_slip39_iteration_exponent(exponent: int) -> None:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
common.set_uint8(_NAMESPACE, _SLIP39_ITERATION_EXPONENT, exponent)
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
|
2021-03-18 09:48:50 +00:00
|
|
|
def get_slip39_iteration_exponent() -> int | None:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
return common.get_uint8(_NAMESPACE, _SLIP39_ITERATION_EXPONENT)
|
2019-07-11 14:52:25 +00:00
|
|
|
|
|
|
|
|
2019-08-14 13:46:08 +00:00
|
|
|
def set_slip39_group_count(group_count: int) -> None:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
common.set_uint8(_NAMESPACE, _SLIP39_GROUP_COUNT, group_count)
|
2019-08-14 13:46:08 +00:00
|
|
|
|
|
|
|
|
2019-10-02 12:40:25 +00:00
|
|
|
def get_slip39_group_count() -> int:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
|
|
|
return (
|
|
|
|
common.get_uint8(_NAMESPACE, _SLIP39_GROUP_COUNT) or _DEFAULT_SLIP39_GROUP_COUNT
|
|
|
|
)
|
2019-08-14 13:46:08 +00:00
|
|
|
|
|
|
|
|
2019-09-19 07:37:23 +00:00
|
|
|
def set_slip39_remaining_shares(shares_remaining: int, group_index: int) -> None:
|
2019-08-14 13:46:08 +00:00
|
|
|
"""
|
|
|
|
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.
|
|
|
|
"""
|
2021-03-22 15:14:24 +00:00
|
|
|
from trezor.crypto.slip39 import MAX_SHARE_COUNT
|
|
|
|
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
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
|
2019-08-14 13:46:08 +00:00
|
|
|
if remaining is None:
|
2021-03-22 15:14:24 +00:00
|
|
|
remaining = bytearray([MAX_SHARE_COUNT] * group_count)
|
2019-08-14 13:46:08 +00:00
|
|
|
remaining = bytearray(remaining)
|
|
|
|
remaining[group_index] = shares_remaining
|
2019-09-12 12:18:00 +00:00
|
|
|
common.set(_NAMESPACE, _REMAINING, remaining)
|
2019-08-14 13:46:08 +00:00
|
|
|
|
|
|
|
|
2021-03-18 09:48:50 +00:00
|
|
|
def get_slip39_remaining_shares(group_index: int) -> int | None:
|
2021-03-22 15:14:24 +00:00
|
|
|
from trezor.crypto.slip39 import MAX_SHARE_COUNT
|
|
|
|
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
remaining = common.get(_NAMESPACE, _REMAINING)
|
2021-03-22 15:14:24 +00:00
|
|
|
if remaining is None or remaining[group_index] == MAX_SHARE_COUNT:
|
2019-08-14 13:46:08 +00:00
|
|
|
return None
|
|
|
|
else:
|
|
|
|
return remaining[group_index]
|
|
|
|
|
|
|
|
|
2021-03-18 09:48:50 +00:00
|
|
|
def fetch_slip39_remaining_shares() -> list[int] | None:
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2019-09-12 12:18:00 +00:00
|
|
|
remaining = common.get(_NAMESPACE, _REMAINING)
|
2019-08-14 13:46:08 +00:00
|
|
|
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
|
2019-09-19 15:27:23 +00:00
|
|
|
return list(remaining[:group_count])
|
2019-08-14 13:46:08 +00:00
|
|
|
|
|
|
|
|
2019-07-29 14:34:30 +00:00
|
|
|
def end_progress() -> None:
|
2021-03-22 15:14:24 +00:00
|
|
|
from . import recovery_shares
|
|
|
|
|
2019-09-20 07:46:49 +00:00
|
|
|
_require_progress()
|
2022-09-21 10:50:01 +00:00
|
|
|
for key in (
|
|
|
|
_IN_PROGRESS,
|
2024-05-23 14:09:16 +00:00
|
|
|
_TYPE,
|
2022-09-21 10:50:01 +00:00
|
|
|
_SLIP39_IDENTIFIER,
|
|
|
|
_REMAINING,
|
|
|
|
_SLIP39_ITERATION_EXPONENT,
|
|
|
|
_SLIP39_GROUP_COUNT,
|
|
|
|
):
|
|
|
|
common.delete(_NAMESPACE, key)
|
|
|
|
|
2019-07-11 14:52:25 +00:00
|
|
|
recovery_shares.delete()
|