diff --git a/src/apps/common/cache.py b/src/apps/common/cache.py index d60d3b6f..4f28b831 100644 --- a/src/apps/common/cache.py +++ b/src/apps/common/cache.py @@ -4,28 +4,26 @@ from apps.common import storage memory = {} _seed = None _passphrase = None -_state_salt = None -def get_state(salt: bytes=None, passphrase: str=None): - global _passphrase, _state_salt - if salt is None: - # generate a random salt if not provided and not already cached - if _state_salt is None: - _state_salt = random.bytes(32) +def get_state(state: bytes=None, passphrase: str=None): + + if state is None: + salt = random.bytes(32) # generate a random salt if no state provided else: - # otherwise copy provided salt to cached salt - _state_salt = salt + salt = state[:32] # use salt from provided state + + if passphrase is None: + global _passphrase + if _passphrase is None: + return None + passphrase = _passphrase # use cached passphrase # state = HMAC(passphrase, salt || device_id) - if passphrase is None: - key = _passphrase if _passphrase is not None else '' - else: - key = passphrase - msg = _state_salt + storage.get_device_id().encode() - state = hmac.new(key.encode(), msg, hashlib.sha256).digest() + msg = salt + storage.get_device_id().encode() + state = hmac.new(passphrase.encode(), msg, hashlib.sha256).digest() - return _state_salt + state + return salt + state def get_seed(): @@ -45,6 +43,4 @@ def has_passphrase(): def clear(): global _seed, _passphrase - global _state_salt _seed, _passphrase = None, None - _state_salt = None diff --git a/src/apps/common/request_passphrase.py b/src/apps/common/request_passphrase.py index 405be02a..ec116228 100644 --- a/src/apps/common/request_passphrase.py +++ b/src/apps/common/request_passphrase.py @@ -3,6 +3,7 @@ from trezor.messages import ButtonRequestType, wire_types from trezor.messages.ButtonRequest import ButtonRequest from trezor.messages.FailureType import ActionCancelled, ProcessError from trezor.messages.PassphraseRequest import PassphraseRequest +from trezor.messages.PassphraseStateRequest import PassphraseStateRequest from trezor.ui.entry_select import DEVICE, EntrySelector from trezor.ui.passphrase import CANCELLED, PassphraseKeyboard from trezor.ui.text import Text @@ -53,15 +54,15 @@ async def request_passphrase_ack(ctx, on_device): raise wire.FailureError(ProcessError, 'Passphrase not provided') passphrase = ack.passphrase - return ack.state, passphrase + req = PassphraseStateRequest(state=get_state(state=ack.state, passphrase=passphrase)) + ack = await ctx.call(req, wire_types.PassphraseStateAck, wire_types.Cancel) + + return passphrase async def request_passphrase(ctx): on_device = await request_passphrase_entry(ctx) == DEVICE - state, passphrase = await request_passphrase_ack(ctx, on_device) - if state is not None: - if state != get_state(salt=state[:32], passphrase=passphrase): - raise wire.FailureError(ProcessError, 'Passphrase mismatch') + passphrase = await request_passphrase_ack(ctx, on_device) return passphrase diff --git a/src/apps/homescreen/__init__.py b/src/apps/homescreen/__init__.py index b29225ed..5234908a 100644 --- a/src/apps/homescreen/__init__.py +++ b/src/apps/homescreen/__init__.py @@ -11,7 +11,7 @@ from apps.common import storage, coins, cache async def respond_Features(ctx, msg): if msg.__qualname__ == 'Initialize': - if msg.state is None or msg.state != cache.get_state(salt=msg.state[:32]): + if msg.state is None or msg.state != cache.get_state(state=msg.state): cache.clear() f = Features() @@ -32,7 +32,6 @@ async def respond_Features(ctx, msg): f.needs_backup = storage.needs_backup() f.flags = storage.get_flags() f.model = 'T' - f.state = cache.get_state() return f diff --git a/src/trezor/messages/Features.py b/src/trezor/messages/Features.py index af5d4ade..0c908ae2 100644 --- a/src/trezor/messages/Features.py +++ b/src/trezor/messages/Features.py @@ -31,7 +31,6 @@ class Features(p.MessageType): 24: ('fw_patch', p.UVarintType, 0), 25: ('fw_vendor', p.UnicodeType, 0), 26: ('fw_vendor_keys', p.BytesType, 0), - 27: ('state', p.BytesType, 0), } MESSAGE_WIRE_TYPE = 17 @@ -63,7 +62,6 @@ class Features(p.MessageType): fw_patch: int = None, fw_vendor: str = None, fw_vendor_keys: bytes = None, - state: bytes = None, **kwargs, ): self.vendor = vendor @@ -92,5 +90,4 @@ class Features(p.MessageType): self.fw_patch = fw_patch self.fw_vendor = fw_vendor self.fw_vendor_keys = fw_vendor_keys - self.state = state p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/MessageType.py b/src/trezor/messages/MessageType.py index ca870dd5..1dff26cf 100644 --- a/src/trezor/messages/MessageType.py +++ b/src/trezor/messages/MessageType.py @@ -41,6 +41,8 @@ VerifyMessage = const(39) MessageSignature = const(40) PassphraseRequest = const(41) PassphraseAck = const(42) +PassphraseStateRequest = const(77) +PassphraseStateAck = const(78) EstimateTxSize = const(43) TxSize = const(44) RecoveryDevice = const(45) diff --git a/src/trezor/messages/PassphraseStateAck.py b/src/trezor/messages/PassphraseStateAck.py new file mode 100644 index 00000000..5f48710a --- /dev/null +++ b/src/trezor/messages/PassphraseStateAck.py @@ -0,0 +1,12 @@ +# Automatically generated by pb2py +import protobuf as p + + +class PassphraseStateAck(p.MessageType): + MESSAGE_WIRE_TYPE = 78 + + def __init__( + self, + **kwargs, + ): + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/PassphraseStateRequest.py b/src/trezor/messages/PassphraseStateRequest.py new file mode 100644 index 00000000..0bc84ae4 --- /dev/null +++ b/src/trezor/messages/PassphraseStateRequest.py @@ -0,0 +1,17 @@ +# Automatically generated by pb2py +import protobuf as p + + +class PassphraseStateRequest(p.MessageType): + FIELDS = { + 1: ('state', p.BytesType, 0), + } + MESSAGE_WIRE_TYPE = 77 + + def __init__( + self, + state: bytes = None, + **kwargs, + ): + self.state = state + p.MessageType.__init__(self, **kwargs) diff --git a/src/trezor/messages/wire_types.py b/src/trezor/messages/wire_types.py index 11ae6e11..eadc919a 100644 --- a/src/trezor/messages/wire_types.py +++ b/src/trezor/messages/wire_types.py @@ -63,6 +63,8 @@ NEMSignTx = const(69) NEMSignedTx = const(70) PassphraseAck = const(42) PassphraseRequest = const(41) +PassphraseStateAck = const(78) +PassphraseStateRequest = const(77) PinMatrixAck = const(19) PinMatrixRequest = const(18) Ping = const(1) diff --git a/vendor/trezor-common b/vendor/trezor-common index d85f7ac6..0924bd68 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit d85f7ac6bbcccbc83012d85fdf25635e57c5f15b +Subproject commit 0924bd6826bb63f66010e2e511356d54ea733df3