mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-22 04:22:07 +00:00
feat(core): incorporate handshake hash into pairing
This commit is contained in:
parent
45e2819789
commit
1bf927c943
@ -132,7 +132,7 @@ async def show_display_data(ctx: PairingContext, expected_types: Container[int]
|
||||
if cancel_task in race.finished:
|
||||
raise ActionCancelled
|
||||
else:
|
||||
return Exception("Should not happen") # TODO
|
||||
return Exception("Should not happen") # TODO what to do here?
|
||||
|
||||
|
||||
@check_state_and_log(ChannelState.TP1)
|
||||
@ -149,12 +149,11 @@ async def _handle_code_entry_is_included(ctx: PairingContext) -> None:
|
||||
|
||||
if challenge_message.challenge is None:
|
||||
raise Exception("Invalid message")
|
||||
|
||||
code_code_entry_hash = sha256(
|
||||
challenge_message.challenge
|
||||
+ ctx.secret
|
||||
+ bytes("PairingMethod_CodeEntry", "utf-8")
|
||||
).digest() # TODO add handshake hash
|
||||
sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
|
||||
sha_ctx.update(ctx.secret)
|
||||
sha_ctx.update(challenge_message.challenge)
|
||||
sha_ctx.update(bytes("PairingMethod_CodeEntry", "utf-8"))
|
||||
code_code_entry_hash = sha_ctx.digest()
|
||||
ctx.display_data.code_code_entry = (
|
||||
int.from_bytes(code_code_entry_hash, "big") % 1000000
|
||||
)
|
||||
@ -163,21 +162,19 @@ async def _handle_code_entry_is_included(ctx: PairingContext) -> None:
|
||||
|
||||
@check_state_and_log(ChannelState.TP1, ChannelState.TP2)
|
||||
def _handle_qr_code_is_included(ctx: PairingContext) -> None:
|
||||
ctx.display_data.code_qr_code = sha256(
|
||||
ctx.secret + bytes("PairingMethod_QrCode", "utf-8")
|
||||
).digest()[
|
||||
:16
|
||||
] # TODO add handshake hash
|
||||
sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
|
||||
sha_ctx.update(ctx.secret)
|
||||
sha_ctx.update(bytes("PairingMethod_QrCode", "utf-8"))
|
||||
ctx.display_data.code_qr_code = sha_ctx.digest()[:16]
|
||||
ctx.display_data.display_qr_code = True
|
||||
|
||||
|
||||
@check_state_and_log(ChannelState.TP1, ChannelState.TP2)
|
||||
def _handle_nfc_unidirectional_is_included(ctx: PairingContext) -> None:
|
||||
ctx.display_data.code_nfc_unidirectional = sha256(
|
||||
ctx.secret + bytes("PairingMethod_NfcUnidirectional", "utf-8")
|
||||
).digest()[
|
||||
:16
|
||||
] # TODO add handshake hash
|
||||
sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
|
||||
sha_ctx.update(ctx.secret)
|
||||
sha_ctx.update(bytes("PairingMethod_NfcUnidirectional", "utf-8"))
|
||||
ctx.display_data.code_nfc_unidirectional = sha_ctx.digest()[:16]
|
||||
ctx.display_data.display_nfc_unidirectional = True
|
||||
|
||||
|
||||
@ -208,7 +205,10 @@ async def _handle_code_entry_cpace(
|
||||
if message.cpace_host_public_key is None:
|
||||
raise ThpError("Message ThpCodeEntryCpaceHost has no public key")
|
||||
|
||||
ctx.cpace = Cpace(message.cpace_host_public_key)
|
||||
ctx.cpace = Cpace(
|
||||
message.cpace_host_public_key,
|
||||
ctx.channel_ctx.get_handshake_hash(),
|
||||
)
|
||||
assert ctx.display_data.code_code_entry is not None
|
||||
ctx.cpace.generate_keys_and_secret(
|
||||
ctx.display_data.code_code_entry.to_bytes(6, "big")
|
||||
|
@ -76,6 +76,9 @@ class Channel:
|
||||
log.debug(__name__, "get_channel_state: %s", state_to_str(state))
|
||||
return state
|
||||
|
||||
def get_handshake_hash(self) -> bytes:
|
||||
return self.channel_cache.get(CHANNEL_HANDSHAKE_HASH) or b""
|
||||
|
||||
def set_channel_state(self, state: ChannelState) -> None:
|
||||
self.channel_cache.state = bytearray(state.to_bytes(1, "big"))
|
||||
if __debug__:
|
||||
@ -178,7 +181,7 @@ class Channel:
|
||||
else:
|
||||
key_receive = self.channel_cache.get(CHANNEL_KEY_RECEIVE)
|
||||
nonce_receive = self.channel_cache.get_int(CHANNEL_NONCE_RECEIVE)
|
||||
auth_data = self.channel_cache.get(CHANNEL_HANDSHAKE_HASH)
|
||||
auth_data = self.get_handshake_hash()
|
||||
|
||||
assert key_receive is not None
|
||||
assert nonce_receive is not None
|
||||
@ -212,7 +215,7 @@ class Channel:
|
||||
else:
|
||||
key_send = self.channel_cache.get(CHANNEL_KEY_SEND)
|
||||
nonce_send = self.channel_cache.get_int(CHANNEL_NONCE_SEND)
|
||||
auth_data = self.channel_cache.get(CHANNEL_HANDSHAKE_HASH)
|
||||
auth_data = self.get_handshake_hash()
|
||||
|
||||
assert key_send is not None
|
||||
assert nonce_send is not None
|
||||
|
@ -11,19 +11,22 @@ class Cpace:
|
||||
CPace, a balanced composable PAKE: https://datatracker.ietf.org/doc/draft-irtf-cfrg-cpace/
|
||||
"""
|
||||
|
||||
def __init__(self, cpace_host_public_key: bytes) -> None:
|
||||
def __init__(self, cpace_host_public_key: bytes, handshake_hash: bytes) -> None:
|
||||
self.handshake_hash: bytes = handshake_hash
|
||||
self.host_public_key: bytes = cpace_host_public_key
|
||||
self.shared_secret: bytes
|
||||
self.trezor_private_key: bytes
|
||||
self.trezor_public_key: bytes
|
||||
self.shared_secret: bytes
|
||||
|
||||
def generate_keys_and_secret(self, code_code_entry: bytes) -> None:
|
||||
"""
|
||||
Generate ephemeral key pair and a shared secret using Elligator2 with X25519.
|
||||
"""
|
||||
pregenerator = sha512(_PREFIX + code_code_entry + _PADDING).digest()[
|
||||
:32
|
||||
] # TODO add handshake hash
|
||||
sha_ctx = sha512(_PREFIX)
|
||||
sha_ctx.update(code_code_entry)
|
||||
sha_ctx.update(_PADDING)
|
||||
sha_ctx.update(self.handshake_hash)
|
||||
pregenerator = sha_ctx.digest()[:32]
|
||||
generator = elligator2.map_to_curve25519(pregenerator)
|
||||
self.trezor_private_key = random.bytes(32)
|
||||
if __debug__:
|
||||
|
Loading…
Reference in New Issue
Block a user