Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Soft-locking for Trezor T #958

Merged
merged 64 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
94ad9bd
core: move base functions from "homescreen" app to "base"
matejcik Apr 14, 2020
8040dc2
core: add BITCOIN_ONLY to mock file
matejcik Apr 20, 2020
bb27bdb
core: expose storage_is_unlocked() as config.is_unlocked()
matejcik Apr 21, 2020
d5b841b
core/wire: make handler lookup pluggable
matejcik Apr 21, 2020
e9198f9
core: add default messages to some error codes
matejcik Apr 21, 2020
30a5c23
core: use wire.PinCancelled/PinInvalid instead of custom versions
matejcik Apr 21, 2020
8427673
core: make verify_user_pin accept a Context argument
matejcik Apr 21, 2020
e89c618
common: rename ClearSession to LockDevice, introduce EndSession
matejcik Apr 21, 2020
5149d41
core: factor out the decision whether to lock the device
matejcik Apr 22, 2020
afcdecd
core: refactor homescreen app, include lockscreen in it
matejcik Apr 14, 2020
bcf6194
core: introduce PIN soft-locking
matejcik Apr 21, 2020
c5bf806
core: consider lockscreen to be a separate homescreen
matejcik Apr 22, 2020
614af52
core/boot: modify initial lockscreen label
matejcik Apr 24, 2020
4507254
core: only softlock when PIN is set
matejcik Apr 24, 2020
9387f2b
core: hide some fields when softlocked
matejcik Apr 27, 2020
3dd4518
python/debuglink: clean out debuglink methods
matejcik Apr 24, 2020
78c475a
python/debuglink: add debuglink message logging
matejcik Apr 24, 2020
8bf45bb
python/debuglink: proto -> messages
matejcik Apr 24, 2020
dc8f029
python/debuglink: implement use_pin_sequence support for trezor-core
matejcik Apr 27, 2020
bdd0dae
tests: fix test suite for softlock
matejcik Apr 27, 2020
1211528
tests: disable PIN detection, all PIN uses must be explicit
matejcik Apr 27, 2020
8a4e590
tests: refactor T1 changepin test
matejcik Apr 27, 2020
174c888
test: refactor RecoveryDevice test for TT
matejcik Apr 27, 2020
56c32cb
core: refactor usage of input_signals
matejcik Apr 27, 2020
9508ab2
tests: fix terminalreporter deprecation warning
matejcik Apr 28, 2020
7d5b26d
core: disable trezor-crypto BIP32 cache
matejcik Apr 29, 2020
6840cf0
core: do not prompt for PIN just to lock the device again
matejcik Apr 29, 2020
b38a5e6
core/webauthn: Implement U2F unlocking from softlock.
andrewkozlik Apr 29, 2020
6ca645e
core/webauthn: Allow confirm_dialog() to return a new state as an alt…
andrewkozlik May 1, 2020
0751369
core/webauthn: Implement FIDO2 unlocking from softlock.
andrewkozlik May 1, 2020
26c2a94
core/webauthn: Cache user verification for 3 minutes.
andrewkozlik May 1, 2020
8995ccb
tests: update UI test fixtures
matejcik May 15, 2020
61be017
core: add a global idle timer
matejcik May 18, 2020
4242a69
core: implement auto-lock after a configurable timeout (fixes #75)
matejcik May 18, 2020
65c9281
tests: cleaner way to get the ui parameter
matejcik May 19, 2020
f1980f3
core: dim lockscreen (fixes #974)
matejcik May 19, 2020
6ad7139
core/lockscreen: ignore exception when user taps "unlock" and then ca…
matejcik May 21, 2020
d99bdbc
core/loop: introduce spawn syscall
matejcik May 22, 2020
7709a9d
core: replace workflow.on_start/on_close with workflow.spawn
matejcik May 22, 2020
88fa079
core: make sure that auto-lock shuts down running workflows
matejcik May 19, 2020
7ca167e
tests: enable auto-lock tests for TT
matejcik May 19, 2020
5835d0b
tests: update UI test fixtures
matejcik May 19, 2020
9b0e7c4
core/loop: prevent finalizers from doing things when task is closed e…
matejcik May 22, 2020
92a5ea9
tests: rename test_address to get_test_address
matejcik May 22, 2020
36d4927
common: introduce ButtonRequestType.PinEntry
matejcik May 25, 2020
f4cb1d4
core: use ButtonRequestType.PinEntry for PIN entry
matejcik May 25, 2020
4be66fc
core: rework wait_layout()
matejcik May 22, 2020
3a2f742
core: bump version (necessary for wait_layout detection)
matejcik May 27, 2020
44ddba8
tests: move autolock tests to a separate file
matejcik May 25, 2020
ac4fa36
core: call close_others() in place of ButtonRequest
matejcik May 25, 2020
c4f5719
tests: fix wait_layout() behavior
matejcik May 25, 2020
f53a103
core: replace workflow.kill_default with workflow.close_others
matejcik May 25, 2020
a433b89
core: add Cancel to a list of allowed messages while locked
matejcik May 25, 2020
c736eeb
core: debuglink interface avoids workflow management
matejcik May 25, 2020
d6a98b7
core: fix artifacts in click-based UI tests
matejcik May 26, 2020
61e8b9c
core: start USB after booting apps
matejcik May 27, 2020
6bee7a7
tests: update UI test fixtures
matejcik May 25, 2020
f43220b
core: only unlock storage if it is locked (solves determinism issue i…
matejcik May 28, 2020
3ccf0b5
tests/ui_tests: use separate temporary directories for test cases
matejcik May 29, 2020
cfb4acc
core: simplify homescreen and lockscreen implementations
matejcik Jun 1, 2020
2dde7f3
core: lower scheduler resolution to milliseconds
matejcik Jun 2, 2020
c63b5e5
core: set a scheduler-safe maximum for autolock
matejcik Jun 2, 2020
caf7a87
core/ui: lower lockscreen brightness
matejcik Jun 2, 2020
38bb3ff
core: fix rendering issues in homescreens
matejcik Jun 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions common/protob/messages-common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ message ButtonRequest {
ButtonRequest_Success = 17;
ButtonRequest_Warning = 18;
ButtonRequest_PassphraseEntry = 19;
ButtonRequest_PinEntry = 20;
}
}

Expand Down
11 changes: 11 additions & 0 deletions common/protob/messages-debug.proto
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,14 @@ message DebugLinkEraseSdCard {
optional bool format = 1; // if true, the card will be formatted to FAT32.
// if false, it will be all 0xFF bytes.
}


/**
* Request: Start or stop tracking layout changes
* @start
* @next Success
*/
message DebugLinkWatchLayout {
optional bool watch = 1; // if true, start watching layout.
// if false, stop.
}
14 changes: 12 additions & 2 deletions common/protob/messages-management.proto
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,21 @@ message Features {
}

/**
* Request: clear session (removes cached PIN, passphrase, etc).
* Request: soft-lock the device. Following actions will require PIN. Passphrases remain cached.
* @start
* @next Success
*/
message ClearSession {
message LockDevice {
}

/**
* Request: end the current sesson. Following actions must call Initialize again.
* Cache for the current session is discarded, other sessions remain intact.
* Device is not PIN-locked.
* @start
* @next Success
*/
message EndSession {
}

/**
Expand Down
4 changes: 3 additions & 1 deletion common/protob/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ enum MessageType {
MessageType_PinMatrixRequest = 18 [(wire_out) = true];
MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
MessageType_Cancel = 20 [(wire_in) = true, (wire_tiny) = true];
MessageType_ClearSession = 24 [(wire_in) = true];
MessageType_LockDevice = 24 [(wire_in) = true];
MessageType_ApplySettings = 25 [(wire_in) = true];
MessageType_ButtonRequest = 26 [(wire_out) = true];
MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
Expand All @@ -63,6 +63,7 @@ enum MessageType {
MessageType_GetNextU2FCounter = 80 [(wire_in) = true];
MessageType_NextU2FCounter = 81 [(wire_out) = true];
MessageType_ChangeWipeCode = 82 [(wire_in) = true];
MessageType_EndSession = 83 [(wire_in) = true];

// Deprecated messages, kept for protobuf compatibility.
// Both are marked wire_out so that we don't need to implement incoming handler for legacy
Expand Down Expand Up @@ -114,6 +115,7 @@ enum MessageType {
MessageType_DebugLinkRecordScreen = 9003 [(wire_debug_in) = true];
MessageType_DebugLinkShowText = 9004 [(wire_debug_in) = true];
MessageType_DebugLinkEraseSdCard = 9005 [(wire_debug_in) = true];
MessageType_DebugLinkWatchLayout = 9006 [(wire_debug_in) = true];

// Ethereum
MessageType_EthereumGetPublicKey = 450 [(wire_in) = true];
Expand Down
2 changes: 2 additions & 0 deletions core/SConscript.firmware
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ CPPDEFINES_MOD += [
'AES_128',
'AES_192',
'RAND_PLATFORM_INDEPENDENT',
('USE_BIP32_CACHE', '0'),
tsusanka marked this conversation as resolved.
Show resolved Hide resolved
('USE_KECCAK', '1'),
('USE_ETHEREUM', '1' if EVERYTHING else '0'),
('USE_MONERO', '1' if EVERYTHING else '0'),
Expand Down Expand Up @@ -486,6 +487,7 @@ if FROZEN:
])
)

SOURCE_PY.append(SOURCE_PY_DIR + 'apps/base.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/debug/*.py'))
Expand Down
2 changes: 2 additions & 0 deletions core/SConscript.unix
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ CPPPATH_MOD += [
CPPDEFINES_MOD += [
'AES_128',
'AES_192',
('USE_BIP32_CACHE', '0'),
('USE_KECCAK', '1'),
('USE_ETHEREUM', '1' if EVERYTHING else '0'),
('USE_MONERO', '1' if EVERYTHING else '0'),
Expand Down Expand Up @@ -454,6 +455,7 @@ if FROZEN:
])
)

SOURCE_PY.append(SOURCE_PY_DIR + 'apps/base.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/debug/*.py'))
Expand Down
15 changes: 15 additions & 0 deletions core/embed/extmod/modtrezorconfig/modtrezorconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ STATIC mp_obj_t mod_trezorconfig_lock(void) {
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_lock_obj,
mod_trezorconfig_lock);

/// def is_unlocked() -> bool:
/// """
/// Returns True if storage is unlocked, False otherwise.
/// """
STATIC mp_obj_t mod_trezorconfig_is_unlocked(void) {
if (sectrue != storage_is_unlocked()) {
return mp_const_false;
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_is_unlocked_obj,
mod_trezorconfig_is_unlocked);

/// def has_pin() -> bool:
/// """
/// Returns True if storage has a configured PIN, False otherwise.
Expand Down Expand Up @@ -374,6 +387,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = {
MP_ROM_PTR(&mod_trezorconfig_check_pin_obj)},
{MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&mod_trezorconfig_unlock_obj)},
{MP_ROM_QSTR(MP_QSTR_lock), MP_ROM_PTR(&mod_trezorconfig_lock_obj)},
{MP_ROM_QSTR(MP_QSTR_is_unlocked),
MP_ROM_PTR(&mod_trezorconfig_is_unlocked_obj)},
{MP_ROM_QSTR(MP_QSTR_has_pin), MP_ROM_PTR(&mod_trezorconfig_has_pin_obj)},
{MP_ROM_QSTR(MP_QSTR_get_pin_rem),
MP_ROM_PTR(&mod_trezorconfig_get_pin_rem_obj)},
Expand Down
23 changes: 11 additions & 12 deletions core/embed/extmod/modtrezorcrypto/modtrezorcrypto-bip32.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,18 +240,17 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_path(mp_obj_t self,
mp_raise_ValueError("Path cannot be longer than 32 indexes");
}

// convert path to int array
uint32_t pi;
uint32_t pints[plen];
for (pi = 0; pi < plen; pi++) {
pints[pi] = trezor_obj_get_uint(pitems[pi]);
}

if (!hdnode_private_ckd_cached(&o->hdnode, pints, plen, &o->fingerprint)) {
// derivation failed, reset the state and raise
o->fingerprint = 0;
memzero(&o->hdnode, sizeof(o->hdnode));
mp_raise_ValueError("Failed to derive path");
for (uint32_t pi = 0; pi < plen; pi++) {
if (pi == plen - 1) {
// fingerprint is calculated from the parent of the final derivation
o->fingerprint = hdnode_fingerprint(&o->hdnode);
}
uint32_t pitem = trezor_obj_get_uint(pitems[pi]);
if (!hdnode_private_ckd(&o->hdnode, pitem)) {
o->fingerprint = 0;
memzero(&o->hdnode, sizeof(o->hdnode));
mp_raise_ValueError("Failed to derive path");
}
}

return mp_const_none;
Expand Down
10 changes: 5 additions & 5 deletions core/embed/extmod/modtrezorio/modtrezorio-poll.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

/// package: trezorio.__init__

/// def poll(ifaces: Iterable[int], list_ref: List, timeout_us: int) -> bool:
/// def poll(ifaces: Iterable[int], list_ref: List, timeout_ms: int) -> bool:
/// """
/// Wait until one of `ifaces` is ready to read or write (using masks
// `io.POLL_READ` and `io.POLL_WRITE`) and assign the result into
Expand All @@ -42,14 +42,14 @@
/// If timeout occurs, False is returned, True otherwise.
/// """
STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
mp_obj_t timeout_us) {
mp_obj_t timeout_ms) {
mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref);
if (!MP_OBJ_IS_TYPE(list_ref, &mp_type_list) || ret->len < 2) {
mp_raise_TypeError("invalid list_ref");
}

const mp_uint_t timeout = trezor_obj_get_uint(timeout_us);
const mp_uint_t deadline = mp_hal_ticks_us() + timeout;
const mp_uint_t timeout = trezor_obj_get_uint(timeout_ms);
const mp_uint_t deadline = mp_hal_ticks_ms() + timeout;
mp_obj_iter_buf_t iterbuf;

for (;;) {
Expand Down Expand Up @@ -125,7 +125,7 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
}
}

if (mp_hal_ticks_us() >= deadline) {
if (mp_hal_ticks_ms() >= deadline) {
break;
} else {
MICROPY_EVENT_POLL_HOOK
Expand Down
1 change: 1 addition & 0 deletions core/embed/extmod/modtrezorutils/modtrezorutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_halt_obj, 0, 1,
/// VERSION_PATCH: int
/// MODEL: str
/// EMULATOR: bool
/// BITCOIN_ONLY: bool

STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorutils)},
Expand Down
2 changes: 1 addition & 1 deletion core/embed/firmware/version.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define VERSION_MAJOR 2
#define VERSION_MINOR 3
#define VERSION_PATCH 1
#define VERSION_PATCH 2
#define VERSION_BUILD 0

#define FIX_VERSION_MAJOR 2
Expand Down
7 changes: 7 additions & 0 deletions core/mocks/generated/trezorconfig.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ def lock() -> None:
"""


# extmod/modtrezorconfig/modtrezorconfig.c
def is_unlocked() -> bool:
"""
Returns True if storage is unlocked, False otherwise.
"""


# extmod/modtrezorconfig/modtrezorconfig.c
def has_pin() -> bool:
"""
Expand Down
2 changes: 1 addition & 1 deletion core/mocks/generated/trezorio/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class HID:


# extmod/modtrezorio/modtrezorio-poll.h
def poll(ifaces: Iterable[int], list_ref: List, timeout_us: int) -> bool:
def poll(ifaces: Iterable[int], list_ref: List, timeout_ms: int) -> bool:
"""
Wait until one of `ifaces` is ready to read or write (using masks
`list_ref`:
Expand Down
1 change: 1 addition & 0 deletions core/mocks/generated/trezorutils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ VERSION_MINOR: int
VERSION_PATCH: int
MODEL: str
EMULATOR: bool
BITCOIN_ONLY: bool