forked from I2P_Developers/i2p.www
Add HMAC spec and links to SSU
HMAC and IV clarifications NTCP formatting cleanups
This commit is contained in:
@@ -27,13 +27,16 @@ 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
|
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:</p>
|
key. The specific construct of the MAC is the first 16 bytes from:</p>
|
||||||
<pre>
|
<pre>
|
||||||
HMAC-MD5(payload || IV || (payloadLength ^ protocolVersion), macKey)
|
HMAC-MD5(encryptedPayload + IV + (payloadLength ^ protocolVersion), macKey)
|
||||||
</pre>
|
</pre>
|
||||||
where '||' means append.
|
where '+' means append and '^' means exclusive-or.
|
||||||
The payload is the message starting with the flag byte.
|
</p><p>
|
||||||
|
The IV is generated randomly for each packet.
|
||||||
|
The encryptedPayload is the encrypted version of the message starting with the flag byte (encrypt-then-MAC).
|
||||||
|
The payloadLength used in the MAC is a 2 byte unsigned integer.
|
||||||
|
Note that protocolVersion is 0, so the exclusive-or is a no-op.
|
||||||
The macKey is either the introduction key or is constructed from the
|
The macKey is either the introduction key or is constructed from the
|
||||||
exchanged DH key (see details below), as specified for each message below.
|
exchanged DH key (see details below), as specified for each message below.
|
||||||
Note that protocolVersion is 0, so the exclusive or is a no-op.
|
|
||||||
<b>WARNING</b> - the HMAC-MD5-128 used here is non-standard,
|
<b>WARNING</b> - the HMAC-MD5-128 used here is non-standard,
|
||||||
see <a href="{{ site_url('docs/how/cryptography') }}#udp">the cryptography page</a> for details.
|
see <a href="{{ site_url('docs/how/cryptography') }}#udp">the cryptography page</a> for details.
|
||||||
|
|
||||||
@@ -41,14 +44,38 @@ see <a href="{{ site_url('docs/how/cryptography') }}#udp">the cryptography page<
|
|||||||
<p>The payload itself (that is, the message starting with the flag byte)
|
<p>The payload itself (that is, the message starting with the flag byte)
|
||||||
is AES256/CBC encrypted with the IV and the
|
is AES256/CBC encrypted with the IV and the
|
||||||
sessionKey, with replay prevention addressed within its body,
|
sessionKey, with replay prevention addressed within its body,
|
||||||
explained below. The payloadLength in the MAC is a 2 byte unsigned
|
explained below.
|
||||||
integer.</p>
|
</p>
|
||||||
|
|
||||||
<p>The protocolVersion is a 2 byte unsigned integer
|
<p>The protocolVersion is a 2 byte unsigned integer
|
||||||
and is currently set to 0. Peers using a different protocol version will
|
and is currently set to 0. Peers using a different protocol version will
|
||||||
not be able to communicate with this peer, though earlier versions not
|
not be able to communicate with this peer, though earlier versions not
|
||||||
using this flag are.</p>
|
using this flag are.</p>
|
||||||
|
|
||||||
|
<h3>HMAC Specification</h3>
|
||||||
|
<ul><li>
|
||||||
|
Inner padding: 0x36...
|
||||||
|
</li><li>
|
||||||
|
Outer padding: 0x5C...
|
||||||
|
</li><li>
|
||||||
|
Key: 32 bytes
|
||||||
|
</li><li>
|
||||||
|
Hash digest function: MD5, 16 bytes
|
||||||
|
</li><li>
|
||||||
|
Block size: 64 bytes
|
||||||
|
</li><li>
|
||||||
|
MAC size: 16 bytes
|
||||||
|
</li><li>
|
||||||
|
Example C implementations:
|
||||||
|
hmac.h in <a href="https://github.com/orignal/i2pd">i2pd</a>
|
||||||
|
and
|
||||||
|
I2PHMAC.cpp in <a href="https://github.com/i2pcpp/i2pcpp">i2pcpp</a>.
|
||||||
|
</li><li>
|
||||||
|
Example Java implementation:
|
||||||
|
I2PHMac.java in <a href="https://github.com/i2p/i2p.i2p">i2p</a>
|
||||||
|
</li></ul>
|
||||||
|
|
||||||
|
|
||||||
<h3>Session Key Details</h3>
|
<h3>Session Key Details</h3>
|
||||||
The 32-byte session key is created as follows:
|
The 32-byte session key is created as follows:
|
||||||
<ol><li>
|
<ol><li>
|
||||||
|
@@ -95,6 +95,7 @@ Alice contacts Bob
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
{% trans %}Legend:{% endtrans %}
|
{% trans %}Legend:{% endtrans %}
|
||||||
X, Y: {% trans %}256 byte DH public keys{% endtrans %}
|
X, Y: {% trans %}256 byte DH public keys{% endtrans %}
|
||||||
H(): 32 byte SHA256 Hash
|
H(): 32 byte SHA256 Hash
|
||||||
@@ -163,7 +164,7 @@ Alice sends Bob:
|
|||||||
{% trans %}Size:{% endtrans %} 288 bytes
|
{% trans %}Size:{% endtrans %} 288 bytes
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
<p>{% trans %}Contents:{% endtrans %}</p>
|
<p>{% trans %}Contents:{% endtrans %}</p>
|
||||||
{% highlight %}
|
{% highlight lang='dataspec' %}
|
||||||
+----+----+----+----+----+----+----+----+
|
+----+----+----+----+----+----+----+----+
|
||||||
| X, as calculated from DH |
|
| X, as calculated from DH |
|
||||||
+ +
|
+ +
|
||||||
@@ -182,6 +183,7 @@ Alice sends Bob:
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
X: {% trans %}256 byte X from Diffie Hellman{% endtrans %}
|
X: {% trans %}256 byte X from Diffie Hellman{% endtrans %}
|
||||||
|
|
||||||
HXxorHI: {% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
HXxorHI: {% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||||
@@ -231,6 +233,7 @@ This is the DH reply. Bob sends Alice:
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
Y: {% trans %}256 byte Y from Diffie Hellman{% endtrans %}
|
Y: {% trans %}256 byte Y from Diffie Hellman{% endtrans %}
|
||||||
|
|
||||||
HXY: {% trans %}SHA256 Hash(X concatenated with Y){% endtrans %}
|
HXY: {% trans %}SHA256 Hash(X concatenated with Y){% endtrans %}
|
||||||
@@ -243,7 +246,7 @@ This is the DH reply. Bob sends Alice:
|
|||||||
|
|
||||||
|
|
||||||
<p>{% trans %}Encrypted Contents:{% endtrans %}</p>
|
<p>{% trans %}Encrypted Contents:{% endtrans %}</p>
|
||||||
{% highlight %}
|
{% highlight lang='dataspec' %}
|
||||||
+----+----+----+----+----+----+----+----+
|
+----+----+----+----+----+----+----+----+
|
||||||
| Y as calculated from DH |
|
| Y as calculated from DH |
|
||||||
+ +
|
+ +
|
||||||
@@ -266,6 +269,7 @@ This is the DH reply. Bob sends Alice:
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
Y: {% trans %}256 byte Y from Diffie Hellman{% endtrans %}
|
Y: {% trans %}256 byte Y from Diffie Hellman{% endtrans %}
|
||||||
|
|
||||||
encrypted data: {% trans cryptography=site_url('docs/how/cryptography') -%}
|
encrypted data: {% trans cryptography=site_url('docs/how/cryptography') -%}
|
||||||
@@ -291,7 +295,7 @@ This contains Alice's router identity, and a DSA signature of the critical data.
|
|||||||
{% trans %}Size:{% endtrans %} 448 bytes (typ. for 387 byte identity)
|
{% trans %}Size:{% endtrans %} 448 bytes (typ. for 387 byte identity)
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
<p>{% trans %}Unencrypted Contents:{% endtrans %}</p>
|
<p>{% trans %}Unencrypted Contents:{% endtrans %}</p>
|
||||||
{% highlight %}
|
{% highlight lang='dataspec' %}
|
||||||
+----+----+----+----+----+----+----+----+
|
+----+----+----+----+----+----+----+----+
|
||||||
| sz | Alice's Router Identity |
|
| sz | Alice's Router Identity |
|
||||||
+----+----+ +
|
+----+----+ +
|
||||||
@@ -318,6 +322,7 @@ This contains Alice's router identity, and a DSA signature of the critical data.
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
sz: {% trans %}2 byte size of Alice's router identity to follow (should always be 387){% endtrans %}
|
sz: {% trans %}2 byte size of Alice's router identity to follow (should always be 387){% endtrans %}
|
||||||
|
|
||||||
ident: {% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
ident: {% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||||
@@ -337,7 +342,7 @@ the 40 byte <a href="{{ commonstructures }}#type_Signature">DSA signature</a> of
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>{% trans %}Encrypted Contents:{% endtrans %}</p>
|
<p>{% trans %}Encrypted Contents:{% endtrans %}</p>
|
||||||
{% highlight %}
|
{% highlight lang='dataspec' %}
|
||||||
+----+----+----+----+----+----+----+----+
|
+----+----+----+----+----+----+----+----+
|
||||||
| |
|
| |
|
||||||
+ +
|
+ +
|
||||||
@@ -348,6 +353,7 @@ the 40 byte <a href="{{ commonstructures }}#type_Signature">DSA signature</a> of
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
encrypted data: {% trans cryptography=site_url('docs/how/cryptography') -%}
|
encrypted data: {% trans cryptography=site_url('docs/how/cryptography') -%}
|
||||||
448 bytes <a href="{{ cryptography }}#AES">AES encrypted</a> using the DH session key and
|
448 bytes <a href="{{ cryptography }}#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
|
the last 16 bytes of HXxorHI (i.e., the last 16 bytes of message #1) as the IV
|
||||||
@@ -381,7 +387,7 @@ This is a DSA signature of the critical data. Bob sends Alice:
|
|||||||
{% trans %}Size:{% endtrans %} 48 bytes
|
{% trans %}Size:{% endtrans %} 48 bytes
|
||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
<p>{% trans %}Unencrypted Contents:{% endtrans %}</p>
|
<p>{% trans %}Unencrypted Contents:{% endtrans %}</p>
|
||||||
{% highlight %}
|
{% highlight lang='dataspec' %}
|
||||||
+----+----+----+----+----+----+----+----+
|
+----+----+----+----+----+----+----+----+
|
||||||
| |
|
| |
|
||||||
+ +
|
+ +
|
||||||
@@ -398,6 +404,7 @@ This is a DSA signature of the critical data. Bob sends Alice:
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
signature: {% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
signature: {% trans commonstructures=site_url('docs/spec/common-structures') -%}
|
||||||
the 40 byte <a href="{{ commonstructures }}#type_Signature">DSA signature</a> of the following concatenated data:
|
the 40 byte <a href="{{ commonstructures }}#type_Signature">DSA signature</a> of the following concatenated data:
|
||||||
X, Y, Alice's <a href="{{ commonstructures }}#struct_RouterIdentity">Router Identity</a>, tsA, tsB.
|
X, Y, Alice's <a href="{{ commonstructures }}#struct_RouterIdentity">Router Identity</a>, tsA, tsB.
|
||||||
@@ -410,7 +417,7 @@ the 40 byte <a href="{{ commonstructures }}#type_Signature">DSA signature</a> of
|
|||||||
|
|
||||||
|
|
||||||
<p>{% trans %}Encrypted Contents:{% endtrans %}</p>
|
<p>{% trans %}Encrypted Contents:{% endtrans %}</p>
|
||||||
{% highlight %}
|
{% highlight lang='dataspec' %}
|
||||||
+----+----+----+----+----+----+----+----+
|
+----+----+----+----+----+----+----+----+
|
||||||
| |
|
| |
|
||||||
+ +
|
+ +
|
||||||
@@ -421,6 +428,7 @@ the 40 byte <a href="{{ commonstructures }}#type_Signature">DSA signature</a> of
|
|||||||
{% endhighlight %}
|
{% endhighlight %}
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
||||||
encrypted data: {% trans cryptography=site_url('docs/how/cryptography') -%}
|
encrypted data: {% trans cryptography=site_url('docs/how/cryptography') -%}
|
||||||
48 bytes <a href="{{ cryptography }}#AES">AES encrypted</a> using the DH session key and
|
48 bytes <a href="{{ cryptography }}#AES">AES encrypted</a> using the DH session key and
|
||||||
the last 16 bytes of the encrypted contents of message #2 as the IV
|
the last 16 bytes of the encrypted contents of message #2 as the IV
|
||||||
|
Reference in New Issue
Block a user