1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-15 20:19:23 +00:00

TR-core: solve missing SD card

This commit is contained in:
grdddj 2023-03-31 12:52:34 +02:00
parent a1135489eb
commit 84acfac493
5 changed files with 87 additions and 34 deletions

View File

@ -566,11 +566,13 @@ if FROZEN:
SOURCE_PY_DIR = 'src/'
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/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.
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 + '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/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/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/homescreen/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py',

View File

@ -530,11 +530,13 @@ if FROZEN:
SOURCE_PY_DIR = 'src/'
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/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.
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 + '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/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/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/homescreen/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py',

View File

@ -41,9 +41,7 @@ def busy_expiry_ms() -> int:
def get_features() -> Features:
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.messages import Features
@ -92,11 +90,18 @@ def get_features() -> Features:
Capability.ShamirGroups,
]
# Other models are not capable of PassphraseEntry
if utils.MODEL in ("T",):
# Some models are not capable of PassphraseEntry
if utils.MODEL in ("T", "R"):
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()
# private fields:
@ -109,7 +114,15 @@ def get_features() -> Features:
f.flags = storage_device.get_flags()
f.recovery_mode = storage_recovery.is_in_progress()
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.passphrase_always_on_device = storage_device.get_passphrase_always_on_device()
f.safety_checks = safety_checks.read_setting()

View File

@ -2,20 +2,46 @@ import utime
from typing import TYPE_CHECKING
import storage.cache as storage_cache
from trezor import config, wire
from .sdcard import request_sd_salt
from trezor import config, utils, wire
if TYPE_CHECKING:
from typing import Any, NoReturn
from trezor.wire import Context, GenericContext
def can_lock_device() -> bool:
"""Return True if the device has a PIN set or SD-protect enabled."""
import storage.sd_salt
async def _request_sd_salt(
ctx: wire.GenericContext, raise_cancelled_on_unavailable: bool = False
) -> 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(
@ -50,7 +76,7 @@ async def request_pin_and_sd_salt(
else:
pin = ""
salt = await request_sd_salt(ctx)
salt = await _request_sd_salt(ctx)
return pin, salt
@ -67,8 +93,6 @@ async def verify_user_pin(
retry: bool = True,
cache_time_ms: int = 0,
) -> None:
from .sdcard import SdCardUnavailable
# _get_last_unlock_time
last_unlock = int.from_bytes(
storage_cache.get(storage_cache.APP_COMMON_REQUEST_PIN_LAST_UNLOCK, b""), "big"
@ -92,10 +116,7 @@ async def verify_user_pin(
else:
pin = ""
try:
salt = await request_sd_salt(ctx)
except SdCardUnavailable:
raise wire.PinCancelled("SD salt is unavailable")
salt = await _request_sd_salt(ctx, raise_cancelled_on_unavailable=True)
if config.unlock(pin, salt):
_set_last_unlock_time()
return

View File

@ -10,8 +10,9 @@ if TYPE_CHECKING:
T = TypeVar("T", bound=Callable)
fatfs = io.fatfs # global_import_cache
# TODO: solve this for model R, which does not have a filesystem
if hasattr(io, "fatfs"):
fatfs = io.fatfs # global_import_cache
SD_CARD_HOT_SWAPPABLE = False
SD_SALT_LEN_BYTES = const(32)