Short exponent updates for 0.9.8 - I2CP: Updates re: SSL, C library Don't claim we never send private keys over I2CP Future work updates
438 lines
16 KiB
HTML
438 lines
16 KiB
HTML
{% extends "_layout.html" %}
|
|
{% block title %}NTCP{% endblock %}
|
|
{% block content %}
|
|
|
|
Updated December 2013 for release 0.9.9
|
|
|
|
<h2>NTCP (NIO-based TCP)</h2>
|
|
|
|
<p>
|
|
NTCP
|
|
is one of two <a href="transport.html">transports</a> currently implemented in I2P.
|
|
The other is <a href="udp.html">SSU</a>.
|
|
NTCP
|
|
is a Java NIO-based transport
|
|
introduced in I2P release 0.6.1.22.
|
|
Java NIO (new I/O) does not suffer from the 1 thread per connection issues of the old TCP transport.
|
|
NTCP-over-IPv6 is supported as of version 0.9.8.
|
|
</p><p>
|
|
|
|
By default,
|
|
NTCP uses the IP/Port
|
|
auto-detected by SSU. When enabled on config.jsp,
|
|
SSU will notify/restart NTCP when the external address changes
|
|
or when the firewall status changes.
|
|
Now you can enable inbound TCP without a static IP or dyndns service.
|
|
</p><p>
|
|
|
|
The NTCP code within I2P is relatively lightweight (1/4 the size of the SSU code)
|
|
because it uses the underlying Java TCP transport for reliable delivery.
|
|
</p>
|
|
|
|
|
|
<h2>NTCP Protocol Specification</h2>
|
|
|
|
<h3>Standard Message Format</h3>
|
|
<p>
|
|
After establishment,
|
|
the NTCP transport sends individual I2NP messages, with a simple checksum.
|
|
The unencrypted message is encoded as follows:
|
|
<pre>
|
|
* +-------+-------+--//--+---//----+-------+-------+-------+-------+
|
|
* | sizeof(data) | data | padding | Adler checksum of sz+data+pad |
|
|
* +-------+-------+--//--+---//----+-------+-------+-------+-------+
|
|
</pre>
|
|
The data is then AES/256/CBC encrypted. The session key for the encryption
|
|
is negotiated during establishment (using Diffie-Hellman 2048 bit).
|
|
The establishment between two routers is implemented in the EstablishState class
|
|
and detailed below.
|
|
The IV for AES/256/CBC encryption is the last 16 bytes of the previous encrypted message.
|
|
</p>
|
|
|
|
<p>
|
|
0-15 bytes of padding are required to bring the total message length
|
|
(including the six size and checksum bytes) to a multiple of 16.
|
|
The maximum message size is currently 16 KB.
|
|
Therefore the maximum data size is currently 16 KB - 6, or 16378 bytes.
|
|
The minimum data size is 1.
|
|
</p>
|
|
|
|
<h3>Time Sync Message Format</h3>
|
|
<p>
|
|
One special case is a metadata message where the sizeof(data) is 0. In
|
|
that case, the unencrypted message is encoded as:
|
|
<pre>
|
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
* | 0 | timestamp in seconds | uninterpreted
|
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
* uninterpreted | Adler checksum of bytes 0-11 |
|
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
</pre>
|
|
Total length: 16 bytes. The time sync message is sent at approximately 15 minute intervals.
|
|
The message is encrypted just as standard messages are.
|
|
|
|
|
|
<h3>Checksums</h3>
|
|
The standard and time sync messages use the Adler-32 checksum
|
|
as defined in the <a href="http://tools.ietf.org/html/rfc1950">ZLIB Specification</a>.
|
|
|
|
|
|
<h3>Establishment Sequence</h3>
|
|
In the establish state, there is a 4-phase message sequence to exchange DH keys and signatures.
|
|
In the first two messages there is a 2048-bit Diffie Hellman exchange.
|
|
Then, DSA signatures of the critical data are exchanged to confirm the connection.
|
|
<pre>
|
|
* Alice contacts Bob
|
|
* =========================================================
|
|
* X+(H(X) xor Bob.identHash)----------------------------->
|
|
* <----------------------------------------Y+E(H(X+Y)+tsB+padding, sk, Y[239:255])
|
|
* E(sz+Alice.identity+tsA+padding+S(X+Y+Bob.identHash+tsA+tsB), sk, hX_xor_Bob.identHash[16:31])--->
|
|
* <----------------------E(S(X+Y+Alice.identHash+tsA+tsB)+padding, sk, prev)
|
|
|
|
</pre>
|
|
|
|
<pre>
|
|
Legend:
|
|
X, Y: 256 byte DH public keys
|
|
H(): 32 byte SHA256 Hash
|
|
E(data, session key, IV): AES256 Encrypt
|
|
S(): 40 byte DSA Signature
|
|
tsA, tsB: timestamps (4 bytes, seconds since epoch)
|
|
sk: 32 byte Session key
|
|
sz: 2 byte size of Alice identity to follow
|
|
</pre>
|
|
|
|
<h4 id="DH">DH Key Exchange</h4>
|
|
<p>
|
|
The initial 2048-bit DH key exchange
|
|
uses the same shared prime (p) and generator (g) as that used for I2P's
|
|
<a href="how_cryptography.html#elgamal">ElGamal encryption</a>.
|
|
</p>
|
|
|
|
<p>
|
|
The DH key exchange consists of a number of steps, displayed below.
|
|
The mapping between these steps and the messages sent between I2P routers,
|
|
is marked in bold.
|
|
<ol>
|
|
<li>Alice generates a secret integer x.
|
|
She then calculates X = g^x mod p.
|
|
</li>
|
|
<li>Alice sends X to Bob <b>(Message 1)</b>.</li>
|
|
<li>Bob generates a secret integer y.
|
|
He then calculates Y = g^y mod p.</li>
|
|
<li>Bob sends Y to Alice.<b>(Message 2)</b></li>
|
|
<li>Alice can now compute sessionKey = Y^x mod p.</li>
|
|
<li>Bob can now compute sessionKey = X^y mod p.</li>
|
|
<li>Both Alice and Bob now have a shared key sessionKey = g^(x*y) mod p.</li>
|
|
</ol>
|
|
The sessionKey is then used to exchange identities in <b>Message 3</b> and <b>Message 4</b>.
|
|
The exponent (x and y) length for the DH exchange is documented on the
|
|
<a href="how_cryptography.html#exponent">cryptography page</a>.
|
|
</p>
|
|
|
|
<h4>Message 1 (Session Request)</h4>
|
|
This is the DH request.
|
|
Alice already has Bob's
|
|
<a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>,
|
|
IP address, and port, as contained in his
|
|
<a href="common_structures_spec.html#struct_RouterInfo">Router Info</a>,
|
|
which was published to the
|
|
<a href="how_networkdatabase.html">network database</a>.
|
|
Alice sends Bob:
|
|
<pre>
|
|
* X+(H(X) xor Bob.identHash)----------------------------->
|
|
|
|
Size: 288 bytes
|
|
</pre>
|
|
Contents:
|
|
<pre>
|
|
+----+----+----+----+----+----+----+----+
|
|
| X, as calculated from DH |
|
|
+ +
|
|
| |
|
|
~ . . . ~
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
| |
|
|
+ +
|
|
| HXxorHI |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
X: 256 byte X from Diffie Hellman
|
|
|
|
HXxorHI: SHA256 Hash(X) xored with SHA256 Hash(Bob's <a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>)
|
|
(32 bytes)
|
|
|
|
</pre>
|
|
|
|
<p><b>Notes:</b>
|
|
<ul><li>
|
|
Bob verifies HXxorHI using his own router hash. If it does not verify,
|
|
Alice has contacted the wrong router, and Bob drops the connection.
|
|
</li></ul>
|
|
|
|
|
|
<h4>Message 2 (Session Created)</h4>
|
|
This is the DH reply. Bob sends Alice:
|
|
<pre>
|
|
* <----------------------------------------Y+E(H(X+Y)+tsB+padding, sk, Y[239:255])
|
|
|
|
Size: 304 bytes
|
|
</pre>
|
|
Unencrypted Contents:
|
|
<pre>
|
|
+----+----+----+----+----+----+----+----+
|
|
| Y as calculated from DH |
|
|
+ +
|
|
| |
|
|
~ . . . ~
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
| |
|
|
+ +
|
|
| HXY |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
| tsB | padding |
|
|
+----+----+----+----+ +
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
Y: 256 byte Y from Diffie Hellman
|
|
|
|
HXY: SHA256 Hash(X concatenated with Y)
|
|
(32 bytes)
|
|
|
|
tsB: 4 byte timestamp (seconds since the epoch)
|
|
|
|
padding: 12 bytes random data
|
|
|
|
</pre>
|
|
|
|
|
|
Encrypted Contents:
|
|
<pre>
|
|
+----+----+----+----+----+----+----+----+
|
|
| Y as calculated from DH |
|
|
+ +
|
|
| |
|
|
~ . . . ~
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
| |
|
|
+ +
|
|
| encrypted data |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
Y: 256 byte Y from Diffie Hellman
|
|
|
|
encrypted data: 48 bytes <a href="how_cryptography.html#AES">AES encrypted</a> using the DH session key and
|
|
the last 16 bytes of Y as the IV
|
|
|
|
</pre>
|
|
|
|
|
|
<p><b>Notes:</b>
|
|
<ul><li>
|
|
Alice may drop the connection if the clock skew with Bob is too high as calculated using tsB.
|
|
</li></ul>
|
|
</p>
|
|
|
|
|
|
<h4>Message 3 (Session Confirm A)</h4>
|
|
This contains Alice's router identity, and a DSA signature of the critical data. Alice sends Bob:
|
|
<pre>
|
|
* E(sz+Alice.identity+tsA+padding+S(X+Y+Bob.identHash+tsA+tsB), sk, hX_xor_Bob.identHash[16:31])--->
|
|
|
|
Size: 448 bytes (typ. for 387 byte identity)
|
|
</pre>
|
|
Unencrypted Contents:
|
|
<pre>
|
|
+----+----+----+----+----+----+----+----+
|
|
| sz | Alice's Router Identity |
|
|
+----+----+ +
|
|
| |
|
|
~ . . . ~
|
|
| |
|
|
+ +----+----+----+
|
|
| | tsA
|
|
+----+----+----+----+----+----+----+----+
|
|
| padding |
|
|
+----+ +
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
| |
|
|
+ +
|
|
| signature |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
sz: 2 byte size of Alice's router identity to follow (should always be 387)
|
|
|
|
ident: Alice's 387 byte <a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>
|
|
|
|
tsA: 4 byte timestamp (seconds since the epoch)
|
|
|
|
padding: 15 bytes random data
|
|
|
|
signature: the 40 byte <a href="common_structures_spec.html#type_Signature">DSA signature</a> of the following concatenated data:
|
|
X, Y, Bob's <a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>, tsA, tsB.
|
|
Alice signs it with the <a href="common_structures_spec.html#type_SigningPrivateKey">private signing key</a> associated with the <a href="common_structures_spec.html#type_SigningPublicKey">public signing key</a> in her <a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>
|
|
|
|
</pre>
|
|
|
|
Encrypted Contents:
|
|
<pre>
|
|
+----+----+----+----+----+----+----+----+
|
|
| |
|
|
+ +
|
|
| encrypted data |
|
|
~ . . . ~
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
encrypted data: 448 bytes <a href="how_cryptography.html#AES">AES encrypted</a> using the DH session key and
|
|
the last 16 bytes of HXxorHI (i.e., the last 16 bytes of message #1) as the IV
|
|
|
|
</pre>
|
|
|
|
|
|
<p><b>Notes:</b>
|
|
<ul><li>
|
|
Bob verifies the signature, and on failure, drops the connection.
|
|
</li><li>
|
|
Bob may drop the connection if the clock skew with Alice is too high as calculated using tsA.
|
|
</li></ul>
|
|
</p>
|
|
|
|
|
|
|
|
<h4>Message 4 (Session Confirm B)</h4>
|
|
This is a DSA signature of the critical data. Bob sends Alice:
|
|
<pre>
|
|
* <----------------------E(S(X+Y+Alice.identHash+tsA+tsB)+padding, sk, prev)
|
|
|
|
Size: 48 bytes
|
|
</pre>
|
|
Unencrypted Contents:
|
|
<pre>
|
|
+----+----+----+----+----+----+----+----+
|
|
| |
|
|
+ +
|
|
| signature |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+ +
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
| padding |
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|
|
signature: the 40 byte <a href="common_structures_spec.html#type_Signature">DSA signature</a> of the following concatenated data:
|
|
X, Y, Alice's <a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>, tsA, tsB.
|
|
Bob signs it with the <a href="common_structures_spec.html#type_SigningPrivateKey">private signing key</a> associated with the <a href="common_structures_spec.html#type_SigningPublicKey">public signing key</a> in his <a href="common_structures_spec.html#struct_RouterIdentity">Router Identity</a>
|
|
|
|
padding: 8 bytes random data
|
|
|
|
</pre>
|
|
|
|
|
|
Encrypted Contents:
|
|
<pre>
|
|
+----+----+----+----+----+----+----+----+
|
|
| |
|
|
+ +
|
|
| encrypted data |
|
|
~ . . . ~
|
|
| |
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
encrypted data: 48 bytes <a href="how_cryptography.html#AES">AES encrypted</a> using the DH session key and
|
|
the last 16 bytes of the encrypted contents of message #2 as the IV
|
|
|
|
</pre>
|
|
|
|
<p><b>Notes:</b>
|
|
<ul><li>
|
|
Alice verifies the signature, and on failure, drops the connection.
|
|
</li></ul>
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h4>After Establishment</h4>
|
|
<p>
|
|
The connection is established, and standard or time sync messages may be exchanged.
|
|
All subsequent messages are AES encrypted using the negotiated DH session key.
|
|
Alice will use the last 16 bytes of the encrypted contents of message #3 as the next IV.
|
|
Bob will use the last 16 bytes of the encrypted contents of message #4 as the next IV.
|
|
</p>
|
|
|
|
|
|
|
|
<h3>Check Connection Message</h3>
|
|
Alternately, when Bob receives a connection, it could be a
|
|
check connection (perhaps prompted by Bob asking for someone
|
|
to verify his listener).
|
|
Check Connection is not currently used.
|
|
However, for the record, check connections are formatted as follows.
|
|
A check info connection will receive 256 bytes containing:
|
|
<ul>
|
|
<li> 32 bytes of uninterpreted, ignored data
|
|
<li> 1 byte size
|
|
<li> that many bytes making up the local router's IP address (as reached by the remote side)
|
|
<li> 2 byte port number that the local router was reached on
|
|
<li> 4 byte i2p network time as known by the remote side (seconds since the epoch)
|
|
<li> uninterpreted padding data, up to byte 223
|
|
<li> xor of the local router's identity hash and the SHA256 of bytes 32 through bytes 223
|
|
</ul>
|
|
</pre>
|
|
|
|
<h2>Discussion</h2>
|
|
Now on the <a href="ntcp_discussion.html">NTCP Discussion Page</a>.
|
|
|
|
<h2><a name="future">Future Work</a></h2>
|
|
<ul><li>
|
|
The maximum message size should be increased to approximately 32 KB.
|
|
</li><li>
|
|
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.
|
|
However, there is currently no provision for padding beyond the next 16-byte boundary,
|
|
to create a limited number of message sizes.
|
|
</li><li>
|
|
Memory utilization (including that of the kernel) for NTCP should be compared to that for SSU.
|
|
</li><li>
|
|
Can the establishment messages be randomly padded somehow, to frustrate
|
|
identification of I2P traffic based on initial packet sizes?
|
|
</li><li>
|
|
Review and possibly disable 'check connection'
|
|
</li></ul>
|
|
</p>
|
|
|
|
{% endblock %}
|