Skip to content

Commit

Permalink
temp: update pairing process, part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
M1nd3r committed Jan 29, 2025
1 parent be5a181 commit d8506f8
Show file tree
Hide file tree
Showing 24 changed files with 1,373 additions and 938 deletions.
2 changes: 1 addition & 1 deletion common/protob/messages-debug.proto
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ message DebugLinkState {
repeated string tokens = 13; // current layout represented as a list of string tokens
optional uint32 thp_pairing_code_entry_code = 14;
optional bytes thp_pairing_code_qr_code = 15;
optional bytes thp_pairing_code_nfc_unidirectional = 16;
optional bytes thp_pairing_code_nfc = 16;
}

/**
Expand Down
106 changes: 56 additions & 50 deletions common/protob/messages-thp.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,28 @@ option (include_in_bitcoin_only) = true;
* Mapping between Trezor wire identifier (uint) and a Thp protobuf message
*/
enum ThpMessageType {
reserved 0 to 999; // Values reserved by other messages, see messages.proto
reserved 0 to 999; // Values reserved by other messages, see messages.proto

ThpMessageType_ThpCreateNewSession = 1000[(bitcoin_only)=true];
ThpMessageType_ThpNewSession = 1001[(bitcoin_only)=true];
ThpMessageType_ThpStartPairingRequest = 1008 [(bitcoin_only) = true];
ThpMessageType_ThpCreateNewSession = 1000 [(bitcoin_only)=true];
ThpMessageType_ThpPairingRequest = 1006 [(bitcoin_only) = true];
ThpMessageType_ThpPairingRequestApproved = 1007 [(bitcoin_only) = true];
ThpMessageType_ThpSelectMethod = 1008 [(bitcoin_only) = true];
ThpMessageType_ThpPairingPreparationsFinished = 1009 [(bitcoin_only) = true];
ThpMessageType_ThpCredentialRequest = 1010 [(bitcoin_only) = true];
ThpMessageType_ThpCredentialResponse = 1011 [(bitcoin_only) = true];
ThpMessageType_ThpEndRequest = 1012 [(bitcoin_only) = true];
ThpMessageType_ThpEndResponse = 1013[(bitcoin_only) = true];
ThpMessageType_ThpCodeEntryCommitment = 1016[(bitcoin_only)=true];
ThpMessageType_ThpCodeEntryChallenge = 1017[(bitcoin_only)=true];
ThpMessageType_ThpCodeEntryCpaceHost = 1018[(bitcoin_only)=true];
ThpMessageType_ThpCodeEntryCpaceTrezor = 1019[(bitcoin_only)=true];
ThpMessageType_ThpCodeEntryTag = 1020[(bitcoin_only)=true];
ThpMessageType_ThpCodeEntrySecret = 1021[(bitcoin_only)=true];
ThpMessageType_ThpQrCodeTag = 1024[(bitcoin_only)=true];
ThpMessageType_ThpQrCodeSecret = 1025[(bitcoin_only)=true];
ThpMessageType_ThpNfcUnidirectionalTag = 1032[(bitcoin_only)=true];
ThpMessageType_ThpNfcUnidirectionalSecret = 1033[(bitcoin_only)=true];
ThpMessageType_ThpEndResponse = 1013 [(bitcoin_only) = true];
ThpMessageType_ThpCodeEntryCommitment = 1016 [(bitcoin_only)=true];
ThpMessageType_ThpCodeEntryChallenge = 1017 [(bitcoin_only)=true];
ThpMessageType_ThpCodeEntryCpaceTrezor = 1018 [(bitcoin_only)=true];
ThpMessageType_ThpCodeEntryCpaceHostTag = 1019 [(bitcoin_only)=true];
ThpMessageType_ThpCodeEntrySecret = 1020 [(bitcoin_only)=true];
ThpMessageType_ThpQrCodeTag = 1024 [(bitcoin_only)=true];
ThpMessageType_ThpQrCodeSecret = 1025 [(bitcoin_only)=true];
ThpMessageType_ThpNfcTagHost = 1032 [(bitcoin_only)=true];
ThpMessageType_ThpNfcTagTrezor = 1033 [(bitcoin_only)=true];

reserved 1100 to 2147483647; // Values reserved by other messages, see messages.proto
reserved 1100 to 2147483647; // Values reserved by other messages, see messages.proto
}


Expand All @@ -43,10 +43,10 @@ enum ThpMessageType {
* @embed
*/
enum ThpPairingMethod {
NoMethod = 1; // Trust without MITM protection.
SkipPairing = 1; // Trust without MITM protection.
CodeEntry = 2; // User types code diplayed on Trezor into the host application.
QrCode = 3; // User scans code displayed on Trezor into host application.
NFC_Unidirectional = 4; // Trezor transmits an authentication key to the host device via NFC.
NFC = 4; // Trezor and host application exchange authentication secrets via NFC.
}

/**
Expand All @@ -55,8 +55,8 @@ enum ThpPairingMethod {
message ThpDeviceProperties {
optional string internal_model = 1; // Internal model name e.g. "T2B1".
optional uint32 model_variant = 2; // Encodes the device properties such as color.
optional bool bootloader_mode = 3; // Indicates whether the device is in bootloader or firmware mode.
optional uint32 protocol_version = 4; // The communication protocol version supported by the firmware.
optional uint32 protocol_version_major = 3; // The major version of the communication protocol used by the firmware.
optional uint32 protocol_version_minor = 4; // The minor version of the communication protocol used by the firmware.
repeated ThpPairingMethod pairing_methods = 5; // The pairing methods supported by the Trezor.
}

Expand All @@ -65,13 +65,11 @@ message ThpDeviceProperties {
*/
message ThpHandshakeCompletionReqNoisePayload {
optional bytes host_pairing_credential = 1; // Host's pairing credential
repeated ThpPairingMethod pairing_methods = 2; // The pairing methods chosen by the host
}

/**
* Request: Ask device for a new session with given passphrase.
* @start
* @next ThpNewSession
* @next Success
*/
message ThpCreateNewSession{
Expand All @@ -80,31 +78,41 @@ message ThpCreateNewSession{
optional bool derive_cardano = 3; // If True, Cardano keys will be derived. Ignored with BTC-only
}


/**
* Response: Contains session_id of the newly created session.
* @end
* Request: Start pairing process.
* @start
* @next ThpPairingRequestApproved
*/
message ThpNewSession{
optional uint32 new_session_id = 1;
message ThpPairingRequest{
optional string host_name = 1; // Human-readable host name
}

/**
* Request: Start pairing process.
* Response: Host is allowed to start pairing process.
* @start
* @next ThpSelectMethod
*/
message ThpPairingRequestApproved{
}

/**
* Request: Start pairing using the method selected.
* @start
* @next ThpCodeEntryCommitment
* @next ThpPairingPreparationsFinished
* @next ThpCodeEntryCommitment
*/
message ThpStartPairingRequest{
optional string host_name = 1; // Human-readable host name
message ThpSelectMethod {
optional ThpPairingMethod selected_pairing_method = 1 [default=NFC];;
}

/**
* Response: Pairing is ready for user input / OOB communication.
* @next ThpCodeEntryCpace
* @next ThpQrCodeTag
* @next ThpNfcUnidirectionalTag
* @next ThpNfcTagHost
*/
message ThpPairingPreparationsFinished{
message ThpPairingPreparationsFinished{
}

/**
Expand All @@ -117,34 +125,30 @@ message ThpCodeEntryCommitment {

/**
* Response: Host responds to Trezor's Code Entry commitment with a challenge.
* @next ThpPairingPreparationsFinished
* @next ThpCodeEntryCpaceTrezor
*/
message ThpCodeEntryChallenge {
optional bytes challenge = 1; // host's random 32-byte challenge
optional bytes challenge = 1; // Host's random 32-byte challenge
}

/**
* Request: User selected Code Entry option in Host. Host starts CPACE protocol with Trezor.
* @next ThpCodeEntryCpaceTrezor
*/
message ThpCodeEntryCpaceHost {
optional bytes cpace_host_public_key = 1; // Host's ephemeral CPace public key
}


/**
* Response: Trezor continues with the CPACE protocol.
* @next ThpCodeEntryTag
* @next ThpCodeEntryCpaceHostTag
*/
message ThpCodeEntryCpaceTrezor {
optional bytes cpace_trezor_public_key = 1; // Trezor's ephemeral CPace public key
}

/**
* Response: Host continues with the CPACE protocol.
* Request: User selected Code Entry option in Host. Host starts CPACE protocol with Trezor.
* @next ThpCodeEntrySecret
*/
message ThpCodeEntryTag {
optional bytes tag = 2; // SHA-256 of shared secret
message ThpCodeEntryCpaceHostTag {
optional bytes cpace_host_public_key = 1; // Host's ephemeral CPace public key
optional bytes tag = 2; // SHA-256 of shared secret

}

/**
Expand Down Expand Up @@ -175,19 +179,19 @@ message ThpQrCodeSecret {

/**
* Request: User selected Unidirectional NFC pairing option. Host sends an Unidirectional NFC Tag.
* @next ThpNfcUnidirectionalSecret
* @next ThpNfcTagTrezor
*/
message ThpNfcUnidirectionalTag {
optional bytes tag = 1; // SHA-256 of shared secret
message ThpNfcTagHost {
optional bytes tag = 1; // Host's tag
}

/**
* Response: Trezor sends the Unidirectioal NFC secret.
* @next ThpCredentialRequest
* @next ThpEndRequest
*/
message ThpNfcUnidirectionalSecret {
optional bytes secret = 1; // Trezor's secret
message ThpNfcTagTrezor {
optional bytes tag = 1; // Trezor's tag
}

/**
Expand All @@ -197,6 +201,7 @@ message ThpNfcUnidirectionalSecret {
*/
message ThpCredentialRequest {
optional bytes host_static_pubkey = 1; // Host's static public key used in the handshake.
optional bool autoconnect = 2; // Whether host wants to autoconnect without user confirmation
}

/**
Expand Down Expand Up @@ -229,6 +234,7 @@ message ThpEndResponse {}
message ThpCredentialMetadata {
option (internal_only) = true;
optional string host_name = 1; // Human-readable host name
optional bool autoconnect = 2; // Whether host is allowed to autoconnect without user confirmation
}

/**
Expand Down
16 changes: 8 additions & 8 deletions core/src/apps/debug/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ async def dispatch_DebugLinkDecision(
def _state(
thp_pairing_code_entry_code: int | None = None,
thp_pairing_code_qr_code: bytes | None = None,
thp_pairing_code_nfc_unidirectional: bytes | None = None,
thp_pairing_code_nfc: bytes | None = None,
) -> DebugLinkState:
from trezor.messages import DebugLinkState

Expand All @@ -274,7 +274,7 @@ def callback(*args: str) -> None:
tokens=tokens,
thp_pairing_code_entry_code=thp_pairing_code_entry_code,
thp_pairing_code_qr_code=thp_pairing_code_qr_code,
thp_pairing_code_nfc_unidirectional=thp_pairing_code_nfc_unidirectional,
thp_pairing_code_nfc=thp_pairing_code_nfc,
)

async def dispatch_DebugLinkGetState(
Expand All @@ -283,7 +283,7 @@ async def dispatch_DebugLinkGetState(

thp_pairing_code_entry_code: int | None = None
thp_pairing_code_qr_code: bytes | None = None
thp_pairing_code_nfc_unidirectional: bytes | None = None
thp_pairing_code_nfc: bytes | None = None
if utils.USE_THP and msg.thp_channel_id is not None:
channel_id = int.from_bytes(msg.thp_channel_id, "big")

Expand All @@ -301,15 +301,15 @@ async def dispatch_DebugLinkGetState(
if ctx is not None and isinstance(ctx, PairingContext):
thp_pairing_code_entry_code = ctx.display_data.code_code_entry
thp_pairing_code_qr_code = ctx.display_data.code_qr_code
thp_pairing_code_nfc_unidirectional = (
ctx.display_data.code_nfc_unidirectional
)
thp_pairing_code_nfc = ctx.display_data.code_nfc
# if msg.host_nfc_secret is not None:
# ctx.host_nfc_secret = msg.host_nfc_secret

if msg.wait_layout == DebugWaitType.IMMEDIATE:
return _state(
thp_pairing_code_entry_code,
thp_pairing_code_qr_code,
thp_pairing_code_nfc_unidirectional,
thp_pairing_code_nfc,
)

assert DEBUG_CONTEXT is not None
Expand All @@ -324,7 +324,7 @@ async def dispatch_DebugLinkGetState(
return _state(
thp_pairing_code_entry_code,
thp_pairing_code_qr_code,
thp_pairing_code_nfc_unidirectional,
thp_pairing_code_nfc,
)

async def dispatch_DebugLinkRecordScreen(msg: DebugLinkRecordScreen) -> Success:
Expand Down
Loading

0 comments on commit d8506f8

Please sign in to comment.