mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-30 17:21:21 +00:00
feat(core, python): implement nfc pairing for tests, add device test
[no changelog]
This commit is contained in:
parent
7bdaa2dfad
commit
76e3ce611e
@ -221,10 +221,6 @@ async def _handle_code_entry_is_selected_first_time(ctx: PairingContext) -> None
|
||||
@check_state_and_log(ChannelState.TP1)
|
||||
async def _handle_nfc_is_selected(ctx: PairingContext) -> None:
|
||||
ctx.nfc_secret = random.bytes(16)
|
||||
sha_ctx = sha256(ctx.channel_ctx.get_handshake_hash())
|
||||
sha_ctx.update(ctx.nfc_secret)
|
||||
sha_ctx.update(bytes("PairingMethod_NfcUnidirectional", "utf-8"))
|
||||
ctx.display_data.code_nfc = sha_ctx.digest()[:16]
|
||||
await ctx.write_force(ThpPairingPreparationsFinished())
|
||||
|
||||
|
||||
@ -327,9 +323,13 @@ async def _handle_nfc_tag(
|
||||
) -> protobuf.MessageType:
|
||||
if TYPE_CHECKING:
|
||||
assert isinstance(message, ThpNfcTagHost)
|
||||
|
||||
assert ctx.nfc_secret is not None
|
||||
assert ctx.handshake_hash_host is not None
|
||||
assert ctx.nfc_secret_host is not None
|
||||
|
||||
sha_ctx = sha256(ThpPairingMethod.NFC.to_bytes(1, "big"))
|
||||
sha_ctx.update(ctx.channel_ctx.get_handshake_hash())
|
||||
assert ctx.nfc_secret is not None
|
||||
sha_ctx.update(ctx.nfc_secret)
|
||||
expected_tag = sha_ctx.digest()
|
||||
if expected_tag != message.tag:
|
||||
@ -338,10 +338,12 @@ async def _handle_nfc_tag(
|
||||
) # TODO remove after testing
|
||||
raise ThpError("Unexpected NFC Unidirectional Tag")
|
||||
|
||||
if ctx.handshake_hash_host[:16] != ctx.channel_ctx.get_handshake_hash()[:16]:
|
||||
raise ThpError("Handshake hash mismatch")
|
||||
|
||||
sha_ctx = sha256(ThpPairingMethod.NFC.to_bytes(1, "big"))
|
||||
sha_ctx.update(ctx.channel_ctx.get_handshake_hash())
|
||||
# TODO add Host's secret from NFC message transferred over NFC
|
||||
# sha_ctx.update(host's secret)
|
||||
sha_ctx.update(ctx.nfc_secret_host)
|
||||
trezor_tag = sha_ctx.digest()
|
||||
return await _handle_secret_reveal(
|
||||
ctx,
|
||||
|
@ -18,6 +18,8 @@ from trezorlib.messages import (
|
||||
ThpCodeEntrySecret,
|
||||
ThpEndRequest,
|
||||
ThpEndResponse,
|
||||
ThpNfcTagHost,
|
||||
ThpNfcTagTrezor,
|
||||
ThpPairingMethod,
|
||||
ThpPairingPreparationsFinished,
|
||||
ThpPairingRequest,
|
||||
@ -252,3 +254,69 @@ def test_pairing_code_entry(client: Client) -> None:
|
||||
_read_message(ThpEndResponse)
|
||||
|
||||
protocol._has_valid_channel = True
|
||||
|
||||
|
||||
def test_pairing_nfc(client: Client) -> None:
|
||||
global protocol
|
||||
_prepare_protocol(client)
|
||||
|
||||
# Generate ephemeral keys
|
||||
host_ephemeral_privkey = curve25519.get_private_key(os.urandom(32))
|
||||
host_ephemeral_pubkey = curve25519.get_public_key(host_ephemeral_privkey)
|
||||
|
||||
protocol._do_channel_allocation()
|
||||
|
||||
protocol._do_handshake(host_ephemeral_privkey, host_ephemeral_pubkey)
|
||||
|
||||
_send_message(ThpPairingRequest())
|
||||
|
||||
_read_message(ButtonRequest)
|
||||
|
||||
_send_message(ButtonAck())
|
||||
|
||||
client.debug.press_yes()
|
||||
|
||||
_read_message(ThpPairingRequestApproved)
|
||||
|
||||
_send_message(ThpSelectMethod(selected_pairing_method=ThpPairingMethod.NFC))
|
||||
|
||||
_read_message(ThpPairingPreparationsFinished)
|
||||
|
||||
# NFC screen shown
|
||||
_read_message(ButtonRequest)
|
||||
_send_message(ButtonAck())
|
||||
|
||||
nfc_secret_host = b"\x02\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" # TODO generate randomly
|
||||
|
||||
# Read `nfc_secret` and `handshake_hash` from Trezor using debuglink
|
||||
pairing_info = client.debug.pairing_info(
|
||||
thp_channel_id=protocol.channel_id.to_bytes(2, "big"),
|
||||
handshake_hash=protocol.handshake_hash,
|
||||
nfc_secret_host=nfc_secret_host,
|
||||
)
|
||||
handshake_hash_trezor = pairing_info.handshake_hash
|
||||
nfc_secret_trezor = pairing_info.nfc_secret_trezor
|
||||
|
||||
assert handshake_hash_trezor[:16] == protocol.handshake_hash[:16]
|
||||
|
||||
# Compute tag for response
|
||||
sha_ctx = hashlib.sha256(ThpPairingMethod.NFC.to_bytes(1, "big"))
|
||||
sha_ctx.update(protocol.handshake_hash)
|
||||
sha_ctx.update(nfc_secret_trezor)
|
||||
tag_host = sha_ctx.digest()
|
||||
|
||||
_send_message(ThpNfcTagHost(tag=tag_host))
|
||||
|
||||
tag_trezor_msg = _read_message(ThpNfcTagTrezor)
|
||||
|
||||
# Check that the `code` was derived from the revealed secret
|
||||
sha_ctx = hashlib.sha256(ThpPairingMethod.NFC.to_bytes(1, "big"))
|
||||
sha_ctx.update(protocol.handshake_hash)
|
||||
sha_ctx.update(nfc_secret_host)
|
||||
computed_tag = sha_ctx.digest()
|
||||
assert tag_trezor_msg.tag == computed_tag
|
||||
|
||||
_send_message(ThpEndRequest())
|
||||
_read_message(ThpEndResponse)
|
||||
|
||||
protocol._has_valid_channel = True
|
||||
|
Loading…
Reference in New Issue
Block a user