Prop. 159 updates

- New Token message
- First Packet Number block
- Misc. cleanups
This commit is contained in:
zzz
2022-02-12 10:59:08 -05:00
parent 8dfe9fcfe9
commit 56e40bae86

View File

@ -5,7 +5,7 @@ SSU2
:author: eyedeekay, orignal, zlatinb, zzz
:created: 2021-09-12
:thread: http://zzz.i2p/topics/2612
:lastupdated: 2022-02-10
:lastupdated: 2022-02-12
:status: Open
:target: 0.9.55
@ -2605,6 +2605,7 @@ Type Message Notes
7 PeerTest TBD may be a block
8 SessionDestroyed NO, block only??
9 Retry
10 Token Request
n/a HolePunch
==== ================ =====
@ -2626,7 +2627,24 @@ Alice Bob
{% endhighlight %}
When address verification is used, the establishment sequence is as follows:
When address verification is used, and Alice does not have a valid token, the establishment sequence is as follows:
.. raw:: html
{% highlight %}
Alice Bob
TokenRequest --------------------->
<--------------------------- Retry
SessionRequest ------------------->
<------------------- SessionCreated
SessionConfirmed ----------------->
{% endhighlight %}
When address verification is used, Alice thinks she has a valid token,
but Bob rejects it (perhaps because Bob restarted),
the establishment sequence is as follows:
.. raw:: html
@ -2756,12 +2774,23 @@ TBD change during handshake like QUIC?
Packet Numbering
`````````````````
Packets are numbered within a single session, for each direction, starting from 0, to a max of (2**32 -1).
If no First Packet Number block is sent in the handshake,
packets are numbered within a single session, for each direction, starting from 0, to a max of (2**32 -1).
A session must be terminated, and a new session created, well before the max
number of packets is sent.
If a First Packet Number block is sent in the handshake,
packets are numbered within a single session, for that direction, starting from that packet number.
The packet number may wrap around during the session.
When a max of 2**32 packets have been sent, wrapping the packet number back
to the first packet number, that session is no longer valid.
A session must be terminated, and a new session created, well before the max
number of packets is sent.
TODO key rotation, reduce max packet number?
Handshake packets that are determined to be lost are retransmitted
whole, with the identical header including packet number.
The handshake messages Session Request, Session Created, and Session Confirmed
@ -2875,7 +2904,7 @@ The unencrypted data is random, so the encrypted data will appear to be random.
There are five header protection key phases:
- Session Request
- Session Request and Token Request
- Session Created
- Retry
- Session Confirmed
@ -2885,6 +2914,7 @@ There are five header protection key phases:
================= =================== ====================
Message Key k_header_1 Key k_header_2
================= =================== ====================
Token Request Bob Intro Key Bob Intro Key
Session Request Bob Intro Key Bob Intro Key
Session Created Bob Intro Key See Session Request KDF
Session Confirmed Bob Intro Key See Session Created KDF
@ -3183,9 +3213,15 @@ KDF for Session Request
SessionRequest (Type 0)
------------------------
Alice sends to Bob.
Alice sends to Bob, either as the first message in the handshake,
or in response to a Retry message.
Bob responds with a Session Created message.
Size: 80 + payload size.
If Alice does not have a valid token, Alice should send a Token Request message
instead of a Session Request, to avoid the asymmetric encryption
overhead in generating a Session Request.
Long header.
Noise content: Alice's ephemeral key X
Noise payload: datetime, optional relay tag request, and padding blocks
@ -3459,7 +3495,8 @@ KDF for Session Created and Session Confirmed part 1
SessionCreated (Type 1)
------------------------
Bob sends to Alice.
Bob sends to Alice, in response to a Session Request message.
Alice responds with a Session Confirmed message.
Size: 80 + payload size.
Noise content: Bob's ephemeral key Y
@ -3608,6 +3645,7 @@ Payload
- Address block
- Relay Tag block (optional)
- New Token block (optional)
- First Packet Number block (optional)
- Options block (optional)
- Termination block (optional, if session is rejected)
- Padding block (optional)
@ -3740,7 +3778,7 @@ This is the "se" message pattern:
SessionConfirmed (Type 2)
-----------------------------
Alice sends to Bob.
Alice sends to Bob, in response to a Session Created message.
Size: 80 + payload size.
Noise content: Alice's static key
@ -3884,6 +3922,7 @@ Payload
- RouterInfo block
- Options block (optional)
- New Token block (optional)
- First Packet Number block (optional)
- I2NP, First Fragment, or Follow-on Fragment blocks (optional, but probably no room)
- Padding block (optional)
@ -4131,7 +4170,8 @@ Also, this message must be fast to generate, using symmetric encryption only.
Retry (Type 9)
-------------------------------
Bob sends to Alice.
Bob sends to Alice, in response to a Session Request or Token Request message.
Alice responds with a new Session Request.
Size: 48 + payload size.
Noise payload: See below.
@ -4143,11 +4183,11 @@ Raw contents:
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| Long Header bytes 0-15, ChaCha20 |
+ encrypted with Bob intro key n=0 +
| bytes 8-15 header protected |
+ encrypted with Bob intro key +
| |
+----+----+----+----+----+----+----+----+
| Long Header bytes 16-31, ChaCha20 |
+ encrypted with Bob intro key n=1 +
+ encrypted with Bob intro key +
| |
+----+----+----+----+----+----+----+----+
| |
@ -4207,7 +4247,6 @@ Unencrypted data (Poly1305 authentication tag not shown):
{% endhighlight %}
Payload
```````
- DateTime block
@ -4220,18 +4259,125 @@ 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.
KDF for Token Request
--------------------------
This message must be fast to generate, using symmetric encryption only.
.. raw:: html
{% highlight lang='text' %}
// AEAD parameters
// bik = Bob's intro key
k = bik
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 = bik
k_header_2 = bik
{% endhighlight %}
Token Request (Type 10)
-------------------------------
Alice sends to Bob. Bob response with a Retry message.
Size: 48 + payload size.
If Alice does not have a valid token, Alice may send this message
instead of a Session Request, to avoid the asymmetric encryption
overhead in generating a Session Request.
Noise payload: See below.
Raw contents:
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+----+
| Long Header bytes 0-15, ChaCha20 |
+ encrypted with Bob intro key +
| |
+----+----+----+----+----+----+----+----+
| Long Header bytes 16-31, ChaCha20 |
+ encrypted with Bob 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 :: The Source Connection ID
received from Alice in Session Request
type :: 10
ver :: 2
id :: 1 byte, the network ID (currently 2, except for test networks)
flag :: 1 byte, unused, set to 0 for future compatibility
Packet Number :: Random number generated by Bob
Source Connection ID :: The Destination Connection ID
received from Alice in Session Request
Token :: zero
{% endhighlight %}
Payload
```````
- DateTime block
- Padding block
The minimum payload size is 8 bytes.
Notes
`````
- This is NOT a standard Noise message and is not part of the handshake.
It is not bound to the Session Request message other than by connection IDs.
It is not required to decrypt the Session Request Noise message to create this
message in response.
- Alice must drop the message if the source IP and port do not match
the destination IP and port of the Session Request.
- Alice must drop the message if the Destination and Source Connection IDs
do not match the Source and Destination Connection IDs of the Session Request.
- Alice must drop the message if the payload is not successfully decrypted.
@ -4353,6 +4499,7 @@ Relay Tag 16 7
New Token 17 15
Path Challenge 18 varies
Path Response 19 varies
First Packet Number 20 7
reserved for experimental features 224-253
Padding 254 varies
reserved for future extension 255
@ -5196,6 +5343,29 @@ used as a keep-alive or to validate an IP/Port change.
First Packet Number
``````````````````````
Optionally included in the handshake in each direction,
to specify the first packet number that will be sent.
This provides more security for header encryption,
similar to TCP.
.. raw:: html
{% highlight lang='dataspec' %}
+----+----+----+----+----+----+----+
| 20 | size | First pkt number |
+----+----+----+----+----+----+----+
blk :: 20
size :: 4
pkt num :: The first packet number to be sent in the data phase
{% endhighlight %}
Padding
```````
This is for padding inside AEAD payloads.
@ -6096,17 +6266,17 @@ Outbound Packet Creation
Handshake messages (Session Request/Created/Confirmed, Retry) basic steps, in order:
- Create 16 or 32 byte header
- Create body
- Create payload
- mixHash() the header (except for Retry)
- Encrypt the body using Noise (except for Retry, use ChaChaPoly)
- Encrypt the payload using Noise (except for Retry, use ChaChaPoly with the header as AD)
- Encrypt the header, and for Session Request/Created, the ephemeral key
Data phase messages basic steps, in order:
- Create 16-byte header
- Create body
- Encrypt the body using ChaChaPoly using the header as AD
- Create payload
- Encrypt the payload using ChaChaPoly using the header as AD
- Encrypt the header
@ -6142,8 +6312,8 @@ Handshake messages (Session Request/Created/Confirmed, Retry) processing:
- For Session Request/Created and Retry, decrypt bytes 16-31 of the header
- For Session Request/Created, decrypt the ephemeral key
- mixHash() the header
- For Session Request/Created/Confirmed, decrypt the body using Noise
- For Retry and data phase, decrypt the body using ChaChaPoly
- For Session Request/Created/Confirmed, decrypt the payload using Noise
- For Retry and data phase, decrypt the payload using ChaChaPoly
- Process the header and payload
@ -6151,7 +6321,7 @@ Data phase messages processing:
- Decrypt bytes 8-15 of the header
(the packet type, version, and net ID) with the correct key
- Decrypt the body using ChaChaPoly using the header as AD
- Decrypt the payload using ChaChaPoly using the header as AD
- Process the header and payload