mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-15 19:18:11 +00:00
TR-core: solve missing SD card
This commit is contained in:
parent
a1135489eb
commit
84acfac493
@ -566,11 +566,13 @@ if FROZEN:
|
|||||||
SOURCE_PY_DIR = 'src/'
|
SOURCE_PY_DIR = 'src/'
|
||||||
|
|
||||||
SOURCE_PY = Glob(SOURCE_PY_DIR + '*.py')
|
SOURCE_PY = Glob(SOURCE_PY_DIR + '*.py')
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/*.py',
|
||||||
|
exclude=[
|
||||||
|
SOURCE_PY_DIR + 'trezor/sdcard.py',
|
||||||
|
] if TREZOR_MODEL not in ('T',) else []
|
||||||
|
))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/crypto/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/crypto/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/*.py'))
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/common/*.py'))
|
|
||||||
|
|
||||||
# UI layouts - common files and then model-specific. Exclude FIDO when BTC-only.
|
# UI layouts - common files and then model-specific. Exclude FIDO when BTC-only.
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/*.py',
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/*.py',
|
||||||
@ -595,7 +597,11 @@ if FROZEN:
|
|||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/wire/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/wire/*.py'))
|
||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'storage/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'storage/*.py',
|
||||||
|
exclude=[
|
||||||
|
SOURCE_PY_DIR + 'storage/sd_salt.py',
|
||||||
|
] if TREZOR_MODEL not in ('T',) else []
|
||||||
|
))
|
||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/messages/__init__.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/messages/__init__.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/*.py',
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/*.py',
|
||||||
@ -615,8 +621,11 @@ if FROZEN:
|
|||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/common/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/common/*.py',
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/common/*/*.py'))
|
exclude=[
|
||||||
|
SOURCE_PY_DIR + 'apps/common/sdcard.py',
|
||||||
|
] if TREZOR_MODEL not in ('T',) else []
|
||||||
|
))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/debug/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/debug/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py',
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py',
|
||||||
|
@ -530,11 +530,13 @@ if FROZEN:
|
|||||||
SOURCE_PY_DIR = 'src/'
|
SOURCE_PY_DIR = 'src/'
|
||||||
|
|
||||||
SOURCE_PY = Glob(SOURCE_PY_DIR + '*.py')
|
SOURCE_PY = Glob(SOURCE_PY_DIR + '*.py')
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/*.py',
|
||||||
|
exclude=[
|
||||||
|
SOURCE_PY_DIR + 'trezor/sdcard.py',
|
||||||
|
] if TREZOR_MODEL not in ('T',) else []
|
||||||
|
))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/crypto/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/crypto/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/*.py'))
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/components/common/*.py'))
|
|
||||||
|
|
||||||
# UI layouts - common files and then model-specific. Exclude FIDO when BTC-only.
|
# UI layouts - common files and then model-specific. Exclude FIDO when BTC-only.
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/*.py',
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/*.py',
|
||||||
@ -559,7 +561,11 @@ if FROZEN:
|
|||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/wire/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/wire/*.py'))
|
||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'storage/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'storage/*.py',
|
||||||
|
exclude=[
|
||||||
|
SOURCE_PY_DIR + 'storage/sd_salt.py',
|
||||||
|
] if TREZOR_MODEL not in ('T',) else []
|
||||||
|
))
|
||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/messages/__init__.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/messages/__init__.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/*.py',
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/*.py',
|
||||||
@ -579,8 +585,11 @@ if FROZEN:
|
|||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/common/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/common/*.py',
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/common/*/*.py'))
|
exclude=[
|
||||||
|
SOURCE_PY_DIR + 'apps/common/sdcard.py',
|
||||||
|
] if TREZOR_MODEL not in ('T',) else []
|
||||||
|
))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/debug/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/debug/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py'))
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py'))
|
||||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py',
|
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py',
|
||||||
|
@ -41,9 +41,7 @@ def busy_expiry_ms() -> int:
|
|||||||
|
|
||||||
def get_features() -> Features:
|
def get_features() -> Features:
|
||||||
import storage.recovery as storage_recovery
|
import storage.recovery as storage_recovery
|
||||||
import storage.sd_salt as storage_sd_salt
|
|
||||||
|
|
||||||
from trezor import sdcard
|
|
||||||
from trezor.enums import Capability
|
from trezor.enums import Capability
|
||||||
from trezor.messages import Features
|
from trezor.messages import Features
|
||||||
|
|
||||||
@ -92,11 +90,18 @@ def get_features() -> Features:
|
|||||||
Capability.ShamirGroups,
|
Capability.ShamirGroups,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Other models are not capable of PassphraseEntry
|
# Some models are not capable of PassphraseEntry
|
||||||
if utils.MODEL in ("T",):
|
if utils.MODEL in ("T", "R"):
|
||||||
f.capabilities.append(Capability.PassphraseEntry)
|
f.capabilities.append(Capability.PassphraseEntry)
|
||||||
|
|
||||||
f.sd_card_present = sdcard.is_present()
|
# Only some models are capable of SD card
|
||||||
|
if utils.MODEL in ("T",):
|
||||||
|
from trezor import sdcard
|
||||||
|
|
||||||
|
f.sd_card_present = sdcard.is_present()
|
||||||
|
else:
|
||||||
|
f.sd_card_present = False
|
||||||
|
|
||||||
f.initialized = storage_device.is_initialized()
|
f.initialized = storage_device.is_initialized()
|
||||||
|
|
||||||
# private fields:
|
# private fields:
|
||||||
@ -109,7 +114,15 @@ def get_features() -> Features:
|
|||||||
f.flags = storage_device.get_flags()
|
f.flags = storage_device.get_flags()
|
||||||
f.recovery_mode = storage_recovery.is_in_progress()
|
f.recovery_mode = storage_recovery.is_in_progress()
|
||||||
f.backup_type = mnemonic.get_type()
|
f.backup_type = mnemonic.get_type()
|
||||||
f.sd_protection = storage_sd_salt.is_enabled()
|
|
||||||
|
# Only some models are capable of SD card
|
||||||
|
if utils.MODEL in ("T",):
|
||||||
|
import storage.sd_salt as storage_sd_salt
|
||||||
|
|
||||||
|
f.sd_protection = storage_sd_salt.is_enabled()
|
||||||
|
else:
|
||||||
|
f.sd_protection = False
|
||||||
|
|
||||||
f.wipe_code_protection = config.has_wipe_code()
|
f.wipe_code_protection = config.has_wipe_code()
|
||||||
f.passphrase_always_on_device = storage_device.get_passphrase_always_on_device()
|
f.passphrase_always_on_device = storage_device.get_passphrase_always_on_device()
|
||||||
f.safety_checks = safety_checks.read_setting()
|
f.safety_checks = safety_checks.read_setting()
|
||||||
|
@ -2,20 +2,46 @@ import utime
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import storage.cache as storage_cache
|
import storage.cache as storage_cache
|
||||||
from trezor import config, wire
|
from trezor import config, utils, wire
|
||||||
|
|
||||||
from .sdcard import request_sd_salt
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Any, NoReturn
|
from typing import Any, NoReturn
|
||||||
from trezor.wire import Context, GenericContext
|
from trezor.wire import Context, GenericContext
|
||||||
|
|
||||||
|
|
||||||
def can_lock_device() -> bool:
|
async def _request_sd_salt(
|
||||||
"""Return True if the device has a PIN set or SD-protect enabled."""
|
ctx: wire.GenericContext, raise_cancelled_on_unavailable: bool = False
|
||||||
import storage.sd_salt
|
) -> bytearray | None:
|
||||||
|
"""Helper to get SD salt in a general manner, working for all models.
|
||||||
|
|
||||||
return config.has_pin() or storage.sd_salt.is_enabled()
|
Is model-specific, because some models (like TR/T2B1) do not even
|
||||||
|
have SD card support (and we do not want to include SD-card connected code).
|
||||||
|
"""
|
||||||
|
from trezor import utils
|
||||||
|
|
||||||
|
if utils.MODEL in ("R",):
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
from .sdcard import request_sd_salt, SdCardUnavailable
|
||||||
|
|
||||||
|
try:
|
||||||
|
return await request_sd_salt(ctx)
|
||||||
|
except SdCardUnavailable:
|
||||||
|
if raise_cancelled_on_unavailable:
|
||||||
|
raise wire.PinCancelled("SD salt is unavailable")
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def can_lock_device() -> bool:
|
||||||
|
"""Return True if the device has a PIN set or SD-protect enabled (when supported)."""
|
||||||
|
# TR/T2B1 does not support SD card
|
||||||
|
if utils.MODEL in ("R",):
|
||||||
|
return config.has_pin()
|
||||||
|
else:
|
||||||
|
import storage.sd_salt
|
||||||
|
|
||||||
|
return config.has_pin() or storage.sd_salt.is_enabled()
|
||||||
|
|
||||||
|
|
||||||
async def request_pin(
|
async def request_pin(
|
||||||
@ -50,7 +76,7 @@ async def request_pin_and_sd_salt(
|
|||||||
else:
|
else:
|
||||||
pin = ""
|
pin = ""
|
||||||
|
|
||||||
salt = await request_sd_salt(ctx)
|
salt = await _request_sd_salt(ctx)
|
||||||
|
|
||||||
return pin, salt
|
return pin, salt
|
||||||
|
|
||||||
@ -67,8 +93,6 @@ async def verify_user_pin(
|
|||||||
retry: bool = True,
|
retry: bool = True,
|
||||||
cache_time_ms: int = 0,
|
cache_time_ms: int = 0,
|
||||||
) -> None:
|
) -> None:
|
||||||
from .sdcard import SdCardUnavailable
|
|
||||||
|
|
||||||
# _get_last_unlock_time
|
# _get_last_unlock_time
|
||||||
last_unlock = int.from_bytes(
|
last_unlock = int.from_bytes(
|
||||||
storage_cache.get(storage_cache.APP_COMMON_REQUEST_PIN_LAST_UNLOCK, b""), "big"
|
storage_cache.get(storage_cache.APP_COMMON_REQUEST_PIN_LAST_UNLOCK, b""), "big"
|
||||||
@ -92,10 +116,7 @@ async def verify_user_pin(
|
|||||||
else:
|
else:
|
||||||
pin = ""
|
pin = ""
|
||||||
|
|
||||||
try:
|
salt = await _request_sd_salt(ctx, raise_cancelled_on_unavailable=True)
|
||||||
salt = await request_sd_salt(ctx)
|
|
||||||
except SdCardUnavailable:
|
|
||||||
raise wire.PinCancelled("SD salt is unavailable")
|
|
||||||
if config.unlock(pin, salt):
|
if config.unlock(pin, salt):
|
||||||
_set_last_unlock_time()
|
_set_last_unlock_time()
|
||||||
return
|
return
|
||||||
|
@ -10,8 +10,9 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
T = TypeVar("T", bound=Callable)
|
T = TypeVar("T", bound=Callable)
|
||||||
|
|
||||||
|
# TODO: solve this for model R, which does not have a filesystem
|
||||||
fatfs = io.fatfs # global_import_cache
|
if hasattr(io, "fatfs"):
|
||||||
|
fatfs = io.fatfs # global_import_cache
|
||||||
|
|
||||||
SD_CARD_HOT_SWAPPABLE = False
|
SD_CARD_HOT_SWAPPABLE = False
|
||||||
SD_SALT_LEN_BYTES = const(32)
|
SD_SALT_LEN_BYTES = const(32)
|
||||||
|
Loading…
Reference in New Issue
Block a user