2005-04-08 14:21:26 +00:00
|
|
|
<code>$Id: udp.html,v 1.9 2005/04/05 10:28:54 jrandom Exp $</code>
|
2005-03-26 05:47:40 +00:00
|
|
|
|
|
|
|
<h1>Secure Semireliable UDP (SSU)</h1>
|
|
|
|
<b>DRAFT</b>
|
|
|
|
|
|
|
|
<p>
|
2005-03-26 09:22:17 +00:00
|
|
|
The goal of this protocol is to provide secure, authenticated,
|
2005-03-26 09:19:42 +00:00
|
|
|
semireliable, and unordered message delivery, exposing only a minimal
|
2005-03-26 06:23:57 +00:00
|
|
|
amount of data easily discernible to third parties. It should
|
2005-03-26 05:47:40 +00:00
|
|
|
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.</p>
|
|
|
|
|
|
|
|
<h2><a name="addressing">Addressing and introduction</a></h2>
|
|
|
|
|
2005-03-26 09:19:42 +00:00
|
|
|
<p>To contact an SSU peer, one of two sets of information is necessary:
|
2005-03-26 05:47:40 +00:00
|
|
|
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.</p>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
Direct: udp://host:port/introKey
|
|
|
|
Indirect: udp://tag@relayhost:port/relayIntroKey/targetIntroKey
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<p>These introduction keys are delivered through an external channel
|
|
|
|
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).</p>
|
|
|
|
|
|
|
|
<h2><a name="header">Header</a></h2>
|
|
|
|
|
|
|
|
<p>All UDP datagrams begin with a MAC and an IV, followed by a variable
|
|
|
|
size payload encrypted with the appropriate key. The MAC used is
|
|
|
|
HMAC-SHA256, truncated to 16 bytes, while the key is a full AES256
|
|
|
|
key. The specific construct of the MAC is the first 16 bytes from:</p>
|
|
|
|
<pre>
|
2005-03-27 22:08:16 +00:00
|
|
|
HMAC-SHA256(payload || IV || payloadLength, macKey)
|
2005-03-26 05:47:40 +00:00
|
|
|
</pre>
|
|
|
|
|
2005-03-27 22:08:16 +00:00
|
|
|
<p>The payload itself is AES256/CBC encrypted with the IV and the
|
|
|
|
sessionKey, with replay prevention addressed within its body,
|
2005-04-05 15:28:54 +00:00
|
|
|
explained below. The payloadLength in the MAC is a 2 byte unsigned
|
|
|
|
integer in 2s complement.</p>
|
2005-03-26 05:47:40 +00:00
|
|
|
|
|
|
|
<h2><a name="payload">Payload</a></h2>
|
|
|
|
|
|
|
|
<p>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:</p>
|
|
|
|
<pre>
|
|
|
|
bits 0-3: payload type
|
|
|
|
bit 4: rekey?
|
|
|
|
bit 5: extended options included
|
|
|
|
bits 6-7: reserved
|
|
|
|
</pre>
|
|
|
|
|
2005-03-27 22:08:16 +00:00
|
|
|
<p>If the rekey flag is set, 64 bytes of keying material follow the
|
2005-03-26 05:47:40 +00:00
|
|
|
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.</p>
|
|
|
|
|
2005-03-27 22:08:16 +00:00
|
|
|
<p>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.</p>
|
2005-03-26 05:47:40 +00:00
|
|
|
|
|
|
|
<pre>
|
|
|
|
Header: 37+ bytes
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| MAC |
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| IV |
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|flag| time | (optionally |
|
|
|
|
+----+----+----+----+----+ |
|
2005-03-27 22:08:16 +00:00
|
|
|
| this may have 64 byte keying material |
|
2005-03-26 05:47:40 +00:00
|
|
|
| and/or a one+N byte extended options) |
|
|
|
|
+---------------------------------------|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h2><a name="messages">Messages</a></h2>
|
|
|
|
|
|
|
|
<h3><a name="sessionRequest">SessionRequest (type 0)</a></h3>
|
|
|
|
<table border="1">
|
|
|
|
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
|
|
|
<td>Alice to Bob</td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Data:</b></td>
|
|
|
|
<td><ul>
|
|
|
|
<li>256 byte X, to begin the DH agreement</li>
|
|
|
|
<li>1 byte IP address size</li>
|
|
|
|
<li>that many byte representation of Bob's IP address</li>
|
|
|
|
<li>N bytes, currently uninterpreted (later, for challenges)</li>
|
|
|
|
</ul></td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
|
|
|
<td>introKey</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| X, as calculated from DH |
|
|
|
|
| |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|size| that many byte IP address (4-16) |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| arbitrary amount |
|
|
|
|
| of uninterpreted data |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h3><a name="sessionCreated">SessionCreated (type 1)</a></h3>
|
|
|
|
<table border="1">
|
|
|
|
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
|
|
|
<td>Bob to Alice</td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Data:</b></td>
|
|
|
|
<td><ul>
|
|
|
|
<li>256 byte Y, to complete the DH agreement</li>
|
|
|
|
<li>1 byte IP address size</li>
|
|
|
|
<li>that many byte representation of Alice's IP address</li>
|
|
|
|
<li>2 byte port number (unsigned, big endian 2s complement)</li>
|
|
|
|
<li>4 byte relay tag which Alice can publish (else 0x0)</li>
|
2005-04-08 14:21:26 +00:00
|
|
|
<li>4 byte timestamp (seconds from the epoch) for use in the DSA
|
|
|
|
signature</li>
|
|
|
|
<li>40 byte DSA signature of the critical exchanged data
|
|
|
|
(Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's
|
|
|
|
new relay tag + Bob's signed on time), encrypted with another
|
|
|
|
layer of encryption using the negotiated sessionKey. The IV
|
|
|
|
is reused here.</li>
|
2005-04-05 15:28:54 +00:00
|
|
|
<li>8 bytes padding, encrypted with an additional layer of encryption
|
|
|
|
using the negotiated session key as part of the DSA block</li>
|
2005-03-26 05:47:40 +00:00
|
|
|
<li>N bytes, currently uninterpreted (later, for challenges)</li>
|
|
|
|
</ul></td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
2005-04-05 15:28:54 +00:00
|
|
|
<td>introKey, with an additional layer of encryption over the 40 byte
|
|
|
|
signature and the following 8 bytes padding.</td></tr>
|
2005-03-26 05:47:40 +00:00
|
|
|
</table>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| Y, as calculated from DH |
|
|
|
|
| |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|size| that many byte IP address (4-16) |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2005-04-08 14:21:26 +00:00
|
|
|
| Port (A)| public relay tag | signed
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
on time | |
|
|
|
|
+----+----+ |
|
|
|
|
| DSA signature |
|
2005-03-26 05:47:40 +00:00
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
2005-04-08 14:21:26 +00:00
|
|
|
| +----+----+----+----+----+----+
|
|
|
|
| | (8 bytes of padding)
|
2005-04-05 15:28:54 +00:00
|
|
|
+----+----+----+----+----+----+----+----+
|
2005-04-08 14:21:26 +00:00
|
|
|
| |
|
|
|
|
+----+----+ |
|
2005-04-05 15:28:54 +00:00
|
|
|
| arbitrary amount |
|
|
|
|
| of uninterpreted data |
|
|
|
|
. . .
|
2005-03-26 05:47:40 +00:00
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h3><a name="sessionConfirmed">SessionConfirmed (type 2)</a></h3>
|
|
|
|
<table border="1">
|
|
|
|
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
2005-04-08 14:21:26 +00:00
|
|
|
<td>Alice to Bob</td></tr>
|
2005-03-26 05:47:40 +00:00
|
|
|
<tr><td align="right" valign="top"><b>Data:</b></td>
|
|
|
|
<td><ul>
|
|
|
|
<li>1 byte identity fragment info:<pre>
|
|
|
|
bits 0-3: current identity fragment #
|
|
|
|
bits 4-7: total identity fragments</pre></li>
|
|
|
|
<li>N byte fragment of Alice's identity, sent over a number
|
|
|
|
of messages.</li>
|
2005-04-08 14:21:26 +00:00
|
|
|
<li>on the last identity fragment, the signed on time is
|
|
|
|
included after the identity fragment, and the last 40
|
|
|
|
bytes contain the DSA signature of the critical exchanged
|
|
|
|
data (Alice's IP + Alice's port + Bob's IP + Bob's port
|
|
|
|
+ Alice's new relay key + Alice's signed on time)</li>
|
2005-03-26 05:47:40 +00:00
|
|
|
</ul></td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
|
|
|
<td>sessionKey</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
<b>Fragment 1 through N-1</b>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|info| fragment of Alice's full |
|
|
|
|
+----+ |
|
|
|
|
| identity keys |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|
|
|
|
<b>Fragment N:</b>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|info| fragment of Alice's full |
|
|
|
|
+----+ |
|
|
|
|
| identity keys |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2005-04-08 14:21:26 +00:00
|
|
|
| signed on time | |
|
|
|
|
+----+----+----+----+ |
|
2005-03-26 05:47:40 +00:00
|
|
|
| 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 |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h3><a name="relayRequest">RelayRequest (type 3)</a></h3>
|
|
|
|
<table border="1">
|
|
|
|
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
|
|
|
<td>Alice to Bob</td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Data:</b></td>
|
|
|
|
<td><ul>
|
|
|
|
<li>4 byte relay tag</li>
|
|
|
|
<li>1 byte IP address size</li>
|
|
|
|
<li>that many byte representation of Bob's IP address</li>
|
|
|
|
<li>1 byte IP address size</li>
|
|
|
|
<li>that many byte representation of Alice's IP address</li>
|
|
|
|
<li>2 byte port number (of Alice)</li>
|
|
|
|
<li>1 byte challenge size</li>
|
|
|
|
<li>that many bytes to be relayed to Charlie in the intro</li>
|
|
|
|
<li>N bytes, currently uninterpreted</li>
|
|
|
|
</ul></td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
|
|
|
<td>introKey (or sessionKey, if Alice/Bob is established)</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| relay tag |size| that many |
|
|
|
|
+----+----+----+----+----+ +----|
|
|
|
|
| bytes making up Bob's IP address |size|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| that many bytes making up Alice's IP |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| Port (A)|size| that many challenge |
|
|
|
|
+----+----+----+ |
|
|
|
|
| bytes to be delivered to Charlie |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| arbitrary amount of uninterpreted data|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h3><a name="relayResponse">RelayResponse (type 4)</a></h3>
|
|
|
|
<table border="1">
|
|
|
|
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
|
|
|
<td>Bob to Alice</td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Data:</b></td>
|
|
|
|
<td><ul>
|
|
|
|
<li>1 byte IP address size</li>
|
|
|
|
<li>that many byte representation of Charlie's IP address</li>
|
|
|
|
<li>2 byte port number</li>
|
|
|
|
<li>1 byte IP address size</li>
|
|
|
|
<li>that many byte representation of Alice's IP address</li>
|
|
|
|
<li>2 byte port number</li>
|
|
|
|
<li>N bytes, currently uninterpreted</li>
|
|
|
|
</ul></td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
|
|
|
<td>introKey (or sessionKey, if Alice/Bob is established)</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|size| that many bytes making up |
|
|
|
|
+----+ +----+----+
|
|
|
|
| Charlie's IP address | Port (C)|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|size| that many bytes making up |
|
|
|
|
+----+ +----+----+
|
|
|
|
| Alice's IP address | Port (A)|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| arbitrary amount of uninterpreted data|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h3><a name="relayIntro">RelayIntro (type 5)</a></h3>
|
|
|
|
<table border="1">
|
|
|
|
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
|
|
|
<td>Bob to Charlie</td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Data:</b></td>
|
|
|
|
<td><ul>
|
|
|
|
<li>1 byte IP address size</li>
|
|
|
|
<li>that many byte representation of Alice's IP address</li>
|
|
|
|
<li>2 byte port number (of Alice)</li>
|
|
|
|
<li>1 byte challenge size</li>
|
|
|
|
<li>that many bytes relayed from Alice</li>
|
|
|
|
<li>N bytes, currently uninterpreted</li>
|
|
|
|
</ul></td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
|
|
|
<td>sessionKey</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|size| that many bytes making up |
|
|
|
|
+----+ +----+----+
|
|
|
|
| Charlie's IP address | Port (C)|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|size| that many bytes of challenge |
|
|
|
|
+----+ |
|
|
|
|
| data relayed from Alice |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| arbitrary amount of uninterpreted data|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h3><a name="data">Data (type 6)</a></h3>
|
|
|
|
<table border="1">
|
|
|
|
<tr><td align="right" valign="top"><b>Peer:</b></td>
|
|
|
|
<td>Any</td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Data:</b></td>
|
|
|
|
<td><ul>
|
|
|
|
<li>1 byte flags:<pre>
|
|
|
|
bit 0: explicit ACKs included
|
|
|
|
bit 1: explicit NACKs included
|
|
|
|
bit 2: numACKs included
|
2005-04-04 17:21:30 +00:00
|
|
|
bit 3: explicit congestion notification
|
|
|
|
bit 4: request previous ACKs
|
2005-03-26 05:47:40 +00:00
|
|
|
bit 5: want reply
|
2005-04-04 17:21:30 +00:00
|
|
|
bit 6: extended data included
|
|
|
|
bit 7: reserved</pre></li>
|
2005-03-26 05:47:40 +00:00
|
|
|
<li>if explicit ACKs are included:<ul>
|
|
|
|
<li>a 1 byte number of ACKs</li>
|
|
|
|
<li>that many 4 byte MessageIds being fully ACKed</li>
|
|
|
|
</ul></li>
|
|
|
|
<li>if explicit NACKs are included:<ul>
|
|
|
|
<li>a 1 byte number of NACKs</li>
|
|
|
|
<li>that many 4 byte MessageIds + 1 byte fragmentNum NACKs</li>
|
|
|
|
</ul></li>
|
|
|
|
<li>if numACKs included:<ul>
|
2005-03-30 00:20:07 +00:00
|
|
|
<li>a 2 byte number for how many messages were fully
|
2005-03-26 05:47:40 +00:00
|
|
|
received in the last minute.</li></ul></li>
|
2005-04-04 17:21:30 +00:00
|
|
|
<li>If extended data included:<ul>
|
|
|
|
<li>1 byte data size</li>
|
|
|
|
<li>that many bytes of extended data (currently uninterpreted)</li</ul></li>
|
2005-03-26 05:47:40 +00:00
|
|
|
<li>1 byte number of fragments</li>
|
|
|
|
<li>that many message fragments:<ul>
|
|
|
|
<li>4 byte messageId</li>
|
|
|
|
<li>1 byte fragment info:<pre>
|
|
|
|
bits 0-4: fragment #
|
|
|
|
bit 5: isLast (1 = true)
|
|
|
|
bits 6-7: unused</pre></li>
|
|
|
|
<li>2 byte fragment size</li>
|
|
|
|
<li>that many bytes</li>
|
|
|
|
<li>1 byte fragment size</li></ul>
|
|
|
|
<li>N bytes padding, uninterpreted</li>
|
|
|
|
</ul></td></tr>
|
|
|
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
|
|
|
<td>sessionKey</td></tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|flag| (additional headers, determined |
|
|
|
|
+----+ |
|
|
|
|
| by the flags, such as ACKs, NACKs, or |
|
|
|
|
| simple rate of full ACKs) |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|#frg| messageId |info|fragSize |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| that many bytes of fragment data |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| messageId |info|fragSize | |
|
|
|
|
+----+----+----+----+----+----+----+ |
|
|
|
|
| that many bytes of fragment data |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| messageId |info|fragSize | |
|
|
|
|
+----+----+----+----+----+----+----+ |
|
|
|
|
| that many bytes of fragment data |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| arbitrary amount of uninterpreted data|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
2005-04-04 17:21:30 +00:00
|
|
|
<h2><a name="congestioncontrol">Congestion control</a></h2>
|
|
|
|
|
|
|
|
<p>SSU's need for only semireliable delivery, TCP-friendly operation,
|
|
|
|
and the capacity for high throughput allows a great deal of latitude in
|
|
|
|
congestion control. The congestion control algorithm outlined below is
|
|
|
|
meant to be both efficient in bandwidth as well as simple to implement.</p>
|
|
|
|
|
|
|
|
<p>Data is transmitted in volleys of up to 1 second, sending N bytes within
|
|
|
|
P packets. The volley a packet is a part of is defined by the second field
|
|
|
|
in the encrypted <a href="#payload">payload</a>. The receiver of a volley
|
|
|
|
should send back a full set of ACKs and NACKs for message IDs received in
|
|
|
|
the previous volley - these ACKs and NACKs should be included in all messages
|
|
|
|
sent until either the volley changes again or the the receiver gets a message
|
|
|
|
in the current volley stating that the previous ACKs are no longer required.
|
|
|
|
Subsequent responses from the receiver in the current volley should not
|
|
|
|
contain the ACKs.</p>
|
|
|
|
|
|
|
|
<p>After receiving a volley with at least one data message fragment, the
|
|
|
|
receiver should send back at least one message with the ACKs. Each time
|
|
|
|
subsequent messages arrive on the current volley with the "request previous
|
|
|
|
ACKs" flag set, if no messages in the current volley have arrived without
|
|
|
|
that being set the receiver should send back a data message with the ACKs,
|
|
|
|
if the receiver has the bandwidth to do so.</p>
|
|
|
|
|
|
|
|
<p>The number of bytes sent in each volley (N) should be initialized as
|
|
|
|
8192 bytes (an arbitrarily high value). At the beginning of a volley, if
|
|
|
|
the ACKs/NACKs received for the volley two periods back contain any NACKs,
|
|
|
|
N should be set to the minimum of N and the number of bytes fully ACKed,
|
|
|
|
though no less than 1/2 of N. If there were no NACKs and all of the
|
|
|
|
messages sent were ACKed, N is increased by the average packet size. If
|
|
|
|
a message is received in a volley with the explicit congestion
|
|
|
|
notification bit set, at the beginning of the next volley N is set to
|
|
|
|
1/2 N.</p>
|
|
|
|
|
|
|
|
<p>Messages which are partially sent or NACKed have the unsent fragments
|
|
|
|
transmitted in the next volley, unless the message expiration occurs, in
|
|
|
|
which case it is dropped entirely.</p>
|
|
|
|
|
|
|
|
<p>The simplest possible implementation does not need to pad the packets to
|
|
|
|
any particular size, but instead just places a single message fragment into
|
|
|
|
a packet and sends it off (careful not to exceed the MTU). A more efficient
|
|
|
|
strategy would be to bundle multiple message fragments into the same packet,
|
|
|
|
so long as it doesn't exceed the MTU, but this is not necessary. Eventually,
|
|
|
|
a set of fixed packet sizes may be appropriate to further hide the data
|
|
|
|
fragmentation to external adversaries, but the tunnel, garlic, and end to
|
|
|
|
end padding should be sufficient for most needs until then.</p>
|
|
|
|
|
|
|
|
<h3><a name="congestionscenarios">Congestion scenarios</a></h3>
|
|
|
|
|
|
|
|
<b>Unidirectional transfer</b><br />
|
|
|
|
<pre>
|
|
|
|
Alice Bob
|
|
|
|
Data 1, volley 1, no ACKs--------->
|
|
|
|
Data 2, volley 1, no ACKs--------->
|
|
|
|
Data 3, volley 1, no ACKs--------->
|
|
|
|
Data 4, volley 1, no ACKs--------->
|
|
|
|
Data 5, volley 2, want ACKs------->
|
|
|
|
Data 6, volley 2, want ACKs-------> // want ACK since ACKs not received
|
|
|
|
<------------------ACK 1, 2, 3, 4 // automatically sent
|
|
|
|
<------------------ACK 1, 2, 3, 4 // sent due to Data 6
|
|
|
|
Data 7, volley 2, no ACKs---------> // no further ACKs required
|
|
|
|
Data 8, volley 2, no ACKs--------->
|
|
|
|
Data 9, volley 3, want ACKs-------> // new volley, we want ACKs!
|
|
|
|
<------------------ACK 5, 6, 7, 8 // automatically sent
|
|
|
|
Data 10, volley 3, no ACKs--------->
|
|
|
|
Data 11, volley 3, no ACKs--------->
|
|
|
|
Data 12, volley 3, no ACKs--------->
|
|
|
|
<------------------ACK 9, 10, 11, 12 // automatically sent
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<b>Bidirectional transfer</b><br />
|
|
|
|
<pre>
|
|
|
|
Alice Bob
|
|
|
|
Data 1, volley 1, no ACKs------------------------->
|
|
|
|
<-----------------------------Data 1, volley 1, no ACKs
|
|
|
|
Data 2, volley 1, no ACKs------------------------->
|
|
|
|
<-----------------------------Data 2, volley 1, no ACKs
|
|
|
|
Data 3, volley 1, no ACKs------------------------->
|
|
|
|
<-----------------------------Data 3, volley 1, no ACKs
|
|
|
|
Data 4, volley 1, no ACKs------------------------->
|
|
|
|
<-----------------------------Data 4, volley 1, no ACKs
|
|
|
|
Data 5, volley 2, want ACKs, ACK 1, 2, 3, 4-------> // new volley, send ACKs
|
|
|
|
<---------------Data 5, volley 2, no ACKs, ACK 1, 2, 3, 4 // received ACKs, no need to ask for them
|
|
|
|
Data 6, volley 2, no ACKs------------------------->
|
|
|
|
<-----------------------------Data 6, volley 2, no ACKs
|
|
|
|
Data 7, volley 2, no ACKs------------------------->
|
|
|
|
<-----------------------------Data 8, volley 2, no ACKs
|
|
|
|
Data 8, volley 2, no ACKs------------------------->
|
|
|
|
<-----------------------------Data 9, volley 2, no ACKs
|
|
|
|
ACK 5, 6, 7, 8, 9--------------------------------->
|
|
|
|
<-----------------------------------ACK 5, 6, 7, 8
|
|
|
|
</pre>
|
|
|
|
|
2005-03-26 05:47:40 +00:00
|
|
|
<h2><a name="keys">Keys</a></h2>
|
|
|
|
|
2005-03-26 05:56:06 +00:00
|
|
|
<p>All encryption used is AES256/CBC with 32 byte keys and 16 byte IVs.
|
2005-03-27 22:08:16 +00:00
|
|
|
The MAC and session keys are negotiated as part of the DH exchange, used
|
|
|
|
for the HMAC and encryption, respectively. Prior to the DH exchange,
|
|
|
|
the publicly knowable introKey is used for the MAC and encryption.</p>
|
|
|
|
|
|
|
|
<p>When using the introKey, both the initial message and any subsequent
|
2005-03-26 05:47:40 +00:00
|
|
|
reply use the introKey of the responder (Bob) - the responder does
|
|
|
|
not need to know the introKey of the requestor (Alice). The DSA
|
|
|
|
signing key used by Bob should already be known to Alice when she
|
|
|
|
contacts him, though Alice's DSA key may not already be known by
|
|
|
|
Bob.</p>
|
|
|
|
|
|
|
|
<p>Upon receiving a message, the receiver checks the from IP address
|
|
|
|
with any established sessions - if there is one or more matches,
|
2005-03-27 22:08:16 +00:00
|
|
|
those session's MAC keys are tested sequentially in the HMAC. If none
|
2005-03-26 05:47:40 +00:00
|
|
|
of those verify or if there are no matching IP addresses, the
|
|
|
|
receiver tries their introKey in the MAC. If that does not verify,
|
|
|
|
the packet is dropped. If it does verify, it is interpreted
|
|
|
|
according to the message type, though if the receiver is overloaded,
|
|
|
|
it may be dropped anyway.</p>
|
|
|
|
|
|
|
|
<p>If Alice and Bob have an established session, but Alice loses the
|
2005-03-27 22:08:16 +00:00
|
|
|
keys for some reason and she wants to contact Bob, she may at any
|
2005-03-26 05:47:40 +00:00
|
|
|
time simply establish a new session through the SessionRequest and
|
|
|
|
related messages. If Bob has lost the key but Alice does not know
|
|
|
|
that, she will first attempt to prod him to reply, by sending a
|
|
|
|
DataMessage with the wantReply flag set, and if Bob continually
|
|
|
|
fails to reply, she will assume the key is lost and reestablish a
|
|
|
|
new one.</p>
|
|
|
|
|
|
|
|
<p>For the DH key agreement,
|
|
|
|
<a href="http://www.faqs.org/rfcs/rfc3526.html">RFC3526</a> 2048bit
|
|
|
|
MODP group (#14) is used:</p>
|
|
|
|
<pre>
|
|
|
|
p = 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
|
|
|
|
g = 2
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<p>The DSA p, q, and g are shared according to the scope of the
|
|
|
|
identity which created them.</p>
|
|
|
|
|
2005-03-26 09:19:42 +00:00
|
|
|
<h2><a name="replay">Replay prevention</a></h2>
|
|
|
|
|
|
|
|
<p>Replay prevention at the SSU layer occurs by rejecting packets
|
|
|
|
with exceedingly old timestamps or those which reuse an IV. To
|
|
|
|
detect duplicate IVs, a sequence of Bloom filters are employed to
|
|
|
|
"decay" periodically so that only recently added IVs are detected.</p>
|
|
|
|
|
|
|
|
<p>The messageIds used in DataMessages are defined at layers above
|
|
|
|
the SSU transport and are passed through transparently. These IDs
|
|
|
|
are not in any particular order - in fact, they are likely to be
|
|
|
|
entirely random. The SSU layer makes no attempt at messageId
|
|
|
|
replay prevention - higher layers should take that into account.</p>
|
|
|
|
|
2005-03-26 05:47:40 +00:00
|
|
|
<h2><a name="messageSequences">Message sequences</a></h2>
|
|
|
|
|
|
|
|
<h3><a name="establishDirect">Connection establishment (direct)</a></h3>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
Alice Bob
|
|
|
|
SessionRequest--------------------->
|
|
|
|
<---------------------SessionCreated
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
SessionConfirmed------------------->
|
|
|
|
<--------------------------Data
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h3><a name="establishIndirect">Connection establishment (indirect)</a></h3>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
Alice Bob Charlie
|
|
|
|
RelayRequest ---------------------->
|
|
|
|
<--------------RelayResponse RelayIntro----------->
|
|
|
|
<--------------------------------------------Data (ignored)
|
|
|
|
SessionRequest-------------------------------------------->
|
|
|
|
<--------------------------------------------SessionCreated
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
SessionConfirmed------------------------------------------>
|
|
|
|
<---------------------------------------------------Data
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<h2><a name="sampleDatagrams">Sample datagrams</a></h2>
|
|
|
|
|
|
|
|
<b>Minimal data message (no fragments, no ACKs, no NACKs, etc)</b><br />
|
|
|
|
<i>(Size: 39 bytes)</i>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| MAC |
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| IV |
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|flag| time |flag|#frg| |
|
|
|
|
+----+----+----+----+----+----+----+ |
|
|
|
|
| padding to fit a full AES256 block |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<b>Minimal data message with payload</b><br />
|
|
|
|
<i>(Size: 46+fragmentSize bytes)</i>
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| MAC |
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| IV |
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|flag| time |flag|#frg|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
messageId |info| fragSize| |
|
|
|
|
+----+----+----+----+----+----+ |
|
|
|
|
| that many bytes of fragment data |
|
|
|
|
. . .
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
</pre>
|