{% extends "_layout.html" %} {% block title %}SSU Specification{% endblock %} {% block content %} Updated July 2010 for release 0.8
See the SSU page for an overview of the SSU transport.
The goal of this protocol is to provide secure, authenticated, semireliable, and unordered message delivery, exposing only a minimal amount of data easily discernible to third parties. It should support high degree communication as well as TCP-friendly congestion control, and may include PMTU detection. It should be capable of efficiently moving bulk data at rates sufficient for home users. In addition, it should support techniques for addressing network obstacles, like most NATs or firewalls.
To contact an SSU peer, one of two sets of information is necessary: a direct address, for when the peer is publicly reachable, or an indirect address, for using a third party to introduce the peer. There is no restriction on the number of addresses a peer may have.
Direct: ssu://host:port/introKey[?opts=[A-Z]*] Indirect: ssu://tag@relayhost:port/relayIntroKey/targetIntroKey[?opts=[A-Z]*]
These introduction keys are delivered through an external channel (the network database, where they are identical to the router Hash for now) and must be used when establishing a session key. For the indirect address, the peer must first contact the relayhost and ask them for an introduction to the peer known at that relayhost under the given tag. If possible, the relayhost sends a message to the addressed peer telling them to contact the requesting peer, and also gives the requesting peer the IP and port on which the addressed peer is located. In addition, the peer establishing the connection must already know the public keys of the peer they are connecting to (but not necessary to any intermediary relay peer).
Each of the addresses may also expose a series of options - special capabilities of that particular peer. For a list of available capabilities, see below.
All UDP datagrams begin with a 16 byte MAC (Message Authentication Code) and a 16 byte IV (Initialization Vector followed by a variable size payload encrypted with the appropriate key. The MAC used is HMAC-MD5, truncated to 16 bytes, while the key is a full 32 byte AES256 key. The specific construct of the MAC is the first 16 bytes from:
HMAC-MD5(payload || IV || (payloadLength ^ protocolVersion), macKey)
The protocol version is currently 0.
The payload itself is AES256/CBC encrypted with the IV and the sessionKey, with replay prevention addressed within its body, explained below. The payloadLength in the MAC is a 2 byte unsigned integer in 2s complement.
The protocolVersion is a 2 byte unsigned integer in 2s complement, and currently set to 0. Peers using a different protocol version will not be able to communicate with this peer, though earlier versions not using this flag are.
Within the AES encrypted payload, there is a minimal common structure to the various messages - a one byte flag and a four byte sending timestamp (*seconds* since the unix epoch). The flag byte contains the following bitfields:
Bit order: 76543210 (bit 7 is MSB) bits 7-4: payload type bit 3: rekey? bit 2: extended options included bits 1-0: reserved
If the rekey flag is set, 64 bytes of keying material follow the timestamp. If the extended options flag is set, a one byte option size value is appended to, followed by that many extended option bytes, which are currently uninterpreted.
When rekeying, the first 32 bytes of the keying material is fed into a SHA256 to produce the new MAC key, and the next 32 bytes are fed into a SHA256 to produce the new session key, though the keys are not immediately used. The other side should also reply with the rekey flag set and that same keying material. Once both sides have sent and received those values, the new keys should be used and the previous keys discarded. It may be useful to keep the old keys around briefly, to address packet loss and reordering.
NOTE: Rekeying is currently unimplemented.
Header: 37+ bytes +----+----+----+----+----+----+----+----+ | MAC | | | +----+----+----+----+----+----+----+----+ | IV | | | +----+----+----+----+----+----+----+----+ |flag| time | (optionally | +----+----+----+----+----+ | | this may have 64 byte keying material | | and/or a one+N byte extended options) | +---------------------------------------|
There are 9 messages defined:
Type | Message | Notes |
---|---|---|
0 | SessionRequest | |
1 | SessionCreated | |
2 | SessionConfirmed | |
3 | RelayRequest | |
4 | RelayResponse | |
5 | RelayIntro | |
6 | Data | |
7 | PeerTest | |
8 | SessionDestroyed | Unimplemented |
Peer: | Alice to Bob |
Data: |
|
Key used: | introKey |
+----+----+----+----+----+----+----+----+ | X, as calculated from DH | | | . . . | | +----+----+----+----+----+----+----+----+ |size| that many byte IP address (4-16) | +----+----+----+----+----+----+----+----+ | arbitrary amount | | of uninterpreted data | . . . | | +----+----+----+----+----+----+----+----+
Peer: | Bob to Alice |
Data: |
|
Key used: | introKey, with an additional layer of encryption over the 40 byte signature and the following 8 bytes padding. |
+----+----+----+----+----+----+----+----+ | Y, as calculated from DH | | | . . . | | +----+----+----+----+----+----+----+----+ |size| that many byte IP address (4-16) | +----+----+----+----+----+----+----+----+ | Port (A)| public relay tag | signed +----+----+----+----+----+----+----+----+ on time | | +----+----+ | | DSA signature | | | | | | | | +----+----+----+----+----+----+ | | (8 bytes of padding) +----+----+----+----+----+----+----+----+ | | +----+----+ | | arbitrary amount | | of uninterpreted data | . . . | | +----+----+----+----+----+----+----+----+
Peer: | Alice to Bob |
Data: |
|
Key used: | sessionKey |
Fragment 1 through N-1 +----+----+----+----+----+----+----+----+ |info| cursize | | +----+----+----+ | | fragment of Alice's full | | identity keys | . . . | | +----+----+----+----+----+----+----+----+ Fragment N: +----+----+----+----+----+----+----+----+ |info| cursize | | +----+----+----+ | | fragment of Alice's full | | identity keys | . . . | | +----+----+----+----+----+----+----+----+ | signed on time | | +----+----+----+----+ | | arbitrary amount of uninterpreted | | data, up from the end of the | | identity key to 40 bytes prior to | | end of the current packet | +----+----+----+----+----+----+----+----+ | DSA signature | | | | | | | | | +----+----+----+----+----+----+----+----+
Peer: | Alice to Bob or Bob to Alice |
Data: | none |
Key used: | sessionKey or introKey |
+----+----+----+----+----+----+----+----+ | no data | +----+----+----+----+----+----+----+----+
Peer: | Alice to Bob |
Data: |
|
Key used: | introKey (or sessionKey, if Alice/Bob is established) |
+----+----+----+----+----+----+----+----+ | relay tag |size| that many | +----+----+----+----+----+ +----| | bytes for Alice's IP address |port +----+----+----+----+----+----+----+----+ (A) |size| that many challenge bytes | +----+----+ | | to be delivered to Charlie | +----+----+----+----+----+----+----+----+ | Alice's intro key | | | | | | | +----+----+----+----+----+----+----+----+ | nonce | | +----+----+----+----+ | | arbitrary amount of uninterpreted data| +----+----+----+----+----+----+----+----+
Peer: | Bob to Alice |
Data: |
|
Key used: | introKey (or sessionKey, if Alice/Bob is established) |
+----+----+----+----+----+----+----+----+ |size| that many bytes making up | +----+ +----+----+ | Charlie's IP address | Port (C)| +----+----+----+----+----+----+----+----+ |size| that many bytes making up | +----+ +----+----+ | Alice's IP address | Port (A)| +----+----+----+----+----+----+----+----+ | nonce | | +----+----+----+----+ | | arbitrary amount of uninterpreted data| +----+----+----+----+----+----+----+----+
Peer: | Bob to Charlie |
Data: |
|
Key used: | sessionKey |
+----+----+----+----+----+----+----+----+ |size| that many bytes making up | +----+ +----+----+ | Alice's IP address | Port (A)| +----+----+----+----+----+----+----+----+ |size| that many bytes of challenge | +----+ | | data relayed from Alice | +----+----+----+----+----+----+----+----+ | arbitrary amount of uninterpreted data| +----+----+----+----+----+----+----+----+
Peer: | Any |
Data: |
|
Key used: | sessionKey |
+----+----+----+----+----+----+----+----+ |flag| (additional headers, determined | +----+ | | by the flags, such as ACKs or | | bitfields | +----+----+----+----+----+----+----+----+ |#frg| messageId | frag info | +----+----+----+----+----+----+----+----+ | that many bytes of fragment data | . . . | | +----+----+----+----+----+----+----+----+ | messageId | frag info | | +----+----+----+----+----+----+----+ | | that many bytes of fragment data | . . . | | +----+----+----+----+----+----+----+----+ | messageId | frag info | | +----+----+----+----+----+----+----+ | | that many bytes of fragment data | . . . | | +----+----+----+----+----+----+----+----+ | arbitrary amount of uninterpreted data| +----+----+----+----+----+----+----+----+
Peer: | Any |
Data: |
|
Key used: | introKey (or sessionKey if the connection has already been established) |
+----+----+----+----+----+----+----+----+ | test nonce |size| that many | +----+----+----+----+----+ | |bytes making up Alice's IP address | |----+----+----+----+----+----+----+----+ | Port (A)| Alice or Charlie's | +----+----+ | | introduction key (Alice's is sent to | | Bob and Charlie, while Charlie's is | | | sent to Alice) | | +----+----+----+----+----+----+ | | arbitrary amount of | |----+----+ | | uninterpreted data | +----+----+----+----+----+----+----+----+{% endblock %}