Changes

Jump to navigation Jump to search
3,844 bytes added ,  16:23, 26 February 2021
Document RCD handshake
Line 34: Line 34:  
In theory, multiple "services" could be multiplexed over a single TCP connection, but in practice only a single service is allowed per TCP port.
 
In theory, multiple "services" could be multiplexed over a single TCP connection, but in practice only a single service is allowed per TCP port.
   −
== Handshake protocol ==
+
= Handshake protocol =
   −
Service ID: 0x0001
+
Service ID: 0x0001<br />
 
Commands: 4
 
Commands: 4
   −
When a device first establishes a wireless connection, it connects to the Switch on a well-known port to access the "handshake" service and make its presence known. A successful handshake causes application-specific RCD connections to be established. Commands must be sent in order (and no more than once).
+
When a device first establishes a wireless connection, it connects to the Switch on a well-known port to access the "handshake" service and make its presence known. A successful handshake causes application-specific RCD connections to be established. Commands must be sent in order (and no more than once), or error code 0x810e8 is generated by the host.
 +
 
 +
== Command 0x1: Begin handshake ==
 +
 
 +
{| class="wikitable" border="1"
 +
|+ Command 0x1 input+output payload
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x10 || Handshake protocol version; one byte followed by zero-padding. Must be 1.
 +
|-
 +
| 0x10 || 0x10 || Device "name" (e.g. 'Fuji'), followed by zero-padding. The Switch uses the empty string.
 +
|-
 +
| 0x20 || 0x10 || Device identifier. Devices embed their MAC as the last 6 bytes; host seems to use a randomly-generated UUID.
 +
|-
 +
| 0x30 || 0x20 || Nonce; cryptographic random bytes with no special purpose.
 +
|}
 +
 
 +
This command is sent first (by the device). The host responds in kind. Error code 0x800e8 is generated if the handshake version is not 1.
 +
 
 +
== Command 0x2: Version negotiation ==
 +
 
 +
{| class="wikitable" border="1"
 +
|+ Command 0x2 input payload
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x20 || Pairing identifier
 +
|-
 +
| 0x20 || 0x1 || Number of versions offered
 +
|-
 +
| 0x21 || Varies || One 8-bit integer per version offered. There is no padding.
 +
|}
 +
 
 +
{| class="wikitable" border="1"
 +
|+ Command 0x2 output payload
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x20 || Pairing identifier
 +
|-
 +
| 0x20 || 0x1 || Selected version
 +
|-
 +
| 0x21 || 0xF || Zero-padding
 +
|}
 +
 
 +
There are a few moving parts here.
 +
 
 +
Firstly, this command is responsible for negotiating a version for the underlying protocols. The host looks at all versions offered by the device and selects the newest version that it recognizes. Error code 0x820e8 is sent if no (recognized) versions are offered.
 +
 
 +
Secondly, the device sends its "pairing identifier," if it recognizes the name/identifier of the host (from command 0x1). If the device does not recognize the host, it sends all-zeroes instead. If the host recognizes the pairing identifier for the device, it sends that same identifier back and expects command 0x4 next (and command 0x3, if sent, will result in error code 0x810e8). If the host doesn't recognize the identifier, it will either send error code 0x850e8 (if it isn't expecting to pair) or send a randomly-generated identifier and expect command 0x3 next.
 +
 
 +
== Command 0x3: Get secret key ==
 +
 
 +
{| class="wikitable" border="1"
 +
|+ Command 0x3 input payload
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x20 || Unknown; always all zeroes?
 +
|}
 +
 
 +
{| class="wikitable" border="1"
 +
|+ Command 0x3 output payload
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x40 || Secret key
 +
|}
 +
 
 +
When a new pairing is being established (see command 0x2), this is used to request the secret key generated for the pairing. It's currently unknown what purpose this "secret key" has.
 +
 
 +
When not expected (including when the RCD host isn't set up for pairing), it generates error code 0x810e8.
 +
 
 +
== Command 0x4: Finalize ==
 +
 
 +
{| class="wikitable" border="1"
 +
|+ Command 0x4 input payload
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x20 || SHA256 of all payloads (not headers) up to this point after truncation to a multiple of 0x40 bytes.
 +
|}
 +
 
 +
{| class="wikitable" border="1"
 +
|+ Command 0x4 output payload
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0 || 0x20 || SHA256 of all payloads (not headers) up to this point, including the input to this command.
 +
|}
 +
 
 +
This is used to finalize the handshake. SHA256 hashes of the handshake up to this point are exchanged, as an integrity check. If the client sends the wrong hash, error code 0x830e8 is sent. If the device sends the correct hash, the host responds with its own hash, and carries on with using the device.
 +
 
 +
If the device accepts the response, it leaves the channel open, and activates other network services for the host to use. If the device rejects the response, it closes the channel, resets its networking stack, and attempts the connection again from scratch. Closing the handshake channel at any point afterward will trigger this same behavior.
30

edits

Navigation menu