From 56e40bae861fb7db8de4bafa820d0b076a2dbdef Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 12 Feb 2022 10:59:08 -0500 Subject: [PATCH] Prop. 159 updates - New Token message - First Packet Number block - Misc. cleanups --- i2p2www/spec/proposals/159-ssu2.rst | 224 ++++++++++++++++++++++++---- 1 file changed, 197 insertions(+), 27 deletions(-) diff --git a/i2p2www/spec/proposals/159-ssu2.rst b/i2p2www/spec/proposals/159-ssu2.rst index 26d5f3e1..0d1b0404 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-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