From c1adc7ef1fd532d5127f6c40ed4b06b40fbb3a39 Mon Sep 17 00:00:00 2001
From: zzz <zzz@i2pmail.org>
Date: Mon, 2 May 2022 12:04:44 -0400
Subject: [PATCH] Prop. 159 hole punch updates

SSU spec: add more info on changes in 0.9.50
---
 i2p2www/pages/site/docs/transport/ssu.html |  12 +-
 i2p2www/spec/proposals/159-ssu2.rst        | 144 +++++++++++++++++++--
 2 files changed, 142 insertions(+), 14 deletions(-)

diff --git a/i2p2www/pages/site/docs/transport/ssu.html b/i2p2www/pages/site/docs/transport/ssu.html
index 8983ab5c6..f865a403b 100644
--- a/i2p2www/pages/site/docs/transport/ssu.html
+++ b/i2p2www/pages/site/docs/transport/ssu.html
@@ -1,7 +1,7 @@
 {% extends "global/layout.html" %}
 {% block title %}{% trans %}Secure Semireliable UDP{% endtrans %} (SSU){% endblock %}
-{% block lastupdated %}2021-10{% endblock %}
-{% block accuratefor %}0.9.52{% endblock %}
+{% block lastupdated %}2022-05{% endblock %}
+{% block accuratefor %}0.9.54{% endblock %}
 {% block content %}
 
 <p>{% trans transports=site_url('docs/transport'), ntcp=site_url('docs/transport/ntcp'), ntcp2=site_url('docs/spec/ntcp2') -%}
@@ -527,10 +527,18 @@ and Alice-Bob and Alice-Charlie communication may be via IPv6,
 if Bob and Charlie indicate support with a 'B' capability in their published IPv6 address.
 See <a href="/spec/proposals/126-ipv6-peer-testing">Proposal 126</a> for details.
 </p><p>
+Prior to release 0.9.50,
 Alice sends the request to Bob using an existing session over the transport (IPv4 or IPv6) that she wishes to test.
 When Bob receives a request from Alice via IPv4, Bob must select a Charlie that advertises an IPv4 address.
 When Bob receives a request from Alice via IPv6, Bob must select a Charlie that advertises an IPv6 address.
 The actual Bob-Charlie communication may be via IPv4 or IPv6 (i.e., independent of Alice's address type).
+</p><p>
+As of release 0.9.50,
+If the message is over IPv6 for an IPv4 introduction,
+  or (as of release 0.9.50) over IPv4 for an IPv6 introduction,
+  Alice must include her introduction address and port.
+
+See <a href="/spec/proposals/158">Proposal 158</a> for details.
 </p>
 
 
diff --git a/i2p2www/spec/proposals/159-ssu2.rst b/i2p2www/spec/proposals/159-ssu2.rst
index 6eb3f7c09..af4d7ff76 100644
--- a/i2p2www/spec/proposals/159-ssu2.rst
+++ b/i2p2www/spec/proposals/159-ssu2.rst
@@ -5,7 +5,7 @@ SSU2
     :author: eyedeekay, orignal, zlatinb, zzz
     :created: 2021-09-12
     :thread: http://zzz.i2p/topics/2612
-    :lastupdated: 2022-04-30
+    :lastupdated: 2022-05-02
     :status: Open
     :target: 0.9.56
 
@@ -2237,6 +2237,10 @@ correlate the HolePunch with Charlie.
 Four byte nonce may need to be replaced or supplemented by
 8-byte connection ID.
 
+The empty Hole Punch message is unique and may be used
+by on-path observers to identify the protocol, this should be
+changed.
+
 
 Peer Test Security
 ---------------------
@@ -2664,7 +2668,7 @@ The "packet header" is the part after the IP/UDP header.
 
 TODO except fragmented Session Confirmed
 
-All SSU2 messages are at least 40 bytes in length, except for Hole Punch which is empty.
+All SSU2 messages are at least 40 bytes in length.
 Any message of length 1-39 bytes is invalid.
 All SSU2 messages are less than or equal to 1472 (IPv4) or 1452 (IPv6) bytes in length. The message
 format is based on Noise messages, with modifications for framing and indistinguishability.
@@ -2684,7 +2688,7 @@ Type      Message       Header Length  Header Encr. Length
   7   PeerTest          32             32
   9   Retry             32             32
  10   Token Request     32             32
-n/a   HolePunch          0              0
+ 11   HolePunch         32             32
 ====  ================  =============  =============
 
 
@@ -3065,7 +3069,7 @@ For Retry, bytes 16-31 of the long header
 are encrypted using ChaCha20.
 The unencrypted data is random, so the encrypted data will appear to be random.
 
-There are six header protection key phases:
+There are seven header protection key phases:
 
 - Session Request and Token Request
 - Session Created
@@ -3073,6 +3077,7 @@ There are six header protection key phases:
 - Session Confirmed
 - Data Phase
 - Peer Test
+- Hole Punch
 
 
 =================  ===================  ====================
@@ -3086,6 +3091,7 @@ Retry              Bob Intro Key        Bob Intro Key
 Data               Alice/Bob Intro Key  See data phase KDF
 Peer Test 5,7      Alice Intro Key      Alice Intro Key
 Peer Test 6        Charlie Intro Key    Charlie Intro Key
+Hole Punch         Alice Intro Key      Alice Intro Key
 =================  ===================  ====================
 
 
@@ -4867,16 +4873,124 @@ Notes
 
 
 
-Hole Punch Message
+KDF for Hole Punch
+--------------------------
+
+This message must be fast to generate, using symmetric encryption only.
+
+.. raw:: html
+
+  {% highlight lang='text' %}
+
+// AEAD parameters
+  // aik = Alice's intro key
+  k = aik
+  n = 4 byte packet number from header
+  ad = 32 byte header, before header encryption
+  ciphertext = ENCRYPT(k, n, payload, ad)
+
+  // Header encryption keys for this message
+  k_header_1 = aik
+  k_header_2 = aik
+
+{% endhighlight %}
+
+
+
+
+Hole Punch (Type 11)
 -------------------------------
 
-An empty datagram. No content. Same as SSU 1.
-A HolePunch is simply a UDP packet with no data.  It is unauthenticated and
-unencrypted.  It does not contain a SSU header, so it does not have a message
-type number.  It is sent from Charlie to Alice as a part of the Introduction
-sequence.
+Charlie sends to Alice, in response to a Relay Intro received from Bob.
+Alice responds with a new Session Request.
+Size: 48 + payload size.
+
+Noise payload: See below.
+
+Raw contents:
+
+.. raw:: html
+
+  {% highlight lang='dataspec' %}
++----+----+----+----+----+----+----+----+
+  |  Long Header bytes 0-15, ChaCha20     |
+  +  encrypted with Alice intro key       +
+  |                                       |
+  +----+----+----+----+----+----+----+----+
+  |  Long Header bytes 16-31, ChaCha20    |
+  +  encrypted with Alice intro key       +
+  |                                       |
+  +----+----+----+----+----+----+----+----+
+  |                                       |
+  +                                       +
+  |   ChaCha20 encrypted data             |
+  +          (length varies)              +
+  |                                       |
+  +  see KDF for key and n                +
+  |  see KDF for associated data          |
+  +----+----+----+----+----+----+----+----+
+  |                                       |
+  +        Poly1305 MAC (16 bytes)        +
+  |                                       |
+  +----+----+----+----+----+----+----+----+
+
+
+{% endhighlight %}
+
+Unencrypted data (Poly1305 authentication tag not shown):
+
+.. raw:: html
+
+  {% highlight lang='dataspec' %}
++----+----+----+----+----+----+----+----+
+  |      Destination Connection ID        |
+  +----+----+----+----+----+----+----+----+
+  |   Packet Number   |type| ver| id |flag|
+  +----+----+----+----+----+----+----+----+
+  |        Source Connection ID           |
+  +----+----+----+----+----+----+----+----+
+  |                 Token                 |
+  +----+----+----+----+----+----+----+----+
+  |    ChaCha20 payload (block data)      |
+  +          (length varies)              +
+  |    see below for allowed blocks       |
+  +----+----+----+----+----+----+----+----+
+
+
+  Destination Connection ID :: See below
+
+  Packet Number :: Random number generated by Charlie
+
+  type :: 11
+
+  ver :: 2
+
+  id :: 1 byte, the network ID (currently 2, except for test networks)
+
+  flag :: 1 byte, unused, set to 0 for future compatibility
+
+  Source Connection ID :: See below
+
+  Token :: 8 byte unsigned integer, randomly generated by Charlie, nonzero.
+           Identical to the token sent in the Relay Response.
+
+{% endhighlight %}
+
+Payload
+```````
+- DateTime block
+- Address block
+- Padding block (optional)
+
+The minimum payload size is 8 bytes. Since the DateTime and Address blocks
+total more than that, the requirement is met with only those two blocks.
+
+Connection IDs: The two connection IDs are derived from the test nonce.
+The Destination Connection ID
+is two copies of the 4-byte relay nonce, i.e. ((nonce << 32) | nonce).
+The Source Connection ID is the inverse of the Destination Connection ID,
+i.e. ~((nonce << 32) | nonce).
 
-TODO should it be a real peer test message instead?
 
 
 
@@ -5472,6 +5586,8 @@ See Relay Process section below.
   ~                                       ~
   |                 . . .                 |
   +----+----+----+----+----+----+----+----+
+  |                 Token                 |
+  +----+----+----+----+----+----+----+----+
 
   blk :: 8
   size :: 2 bytes, 6
@@ -5516,7 +5632,11 @@ See Relay Process section below.
   signature :: length varies, 64 bytes for Ed25519.
                Signature of prologue, Bob's hash,
                and signed data above, as signed by
-               Alice.
+               Charlie.
+               Not present if rejected by Bob.
+  token :: Token generated by Charlie for Alice to use
+           in the Session Request.
+           Only present if code is 0 (accept)
 
 {% endhighlight %}
 
-- 
GitLab