prop. 159 fixes
- Don't increment packet numbers for retransmitted handshake msgs - Header is input to MixHash(), not AD, in handshake - Optional compression for router info block - Attempt to fix sublists markdown
This commit is contained in:
@ -2747,10 +2747,14 @@ when a packet containing that information is determined to be lost,
|
||||
and sending ceases when a packet containing that information is remain the same)
|
||||
acknowledged.
|
||||
|
||||
Packets are never retransmitted with the same packet number.
|
||||
Data Packets are never retransmitted with the same packet number.
|
||||
Any retransmission of packet contents (whether or not the contents remain the same)
|
||||
must use the next unused packet number.
|
||||
|
||||
The handshake messages Session Request, Session Created, and Session Confirmed
|
||||
MUST be retransmitted with the same packet number and identical encrypted contents,
|
||||
so that the same chained hash will be used to encrypt the response.
|
||||
|
||||
Packet numbering starts with Session Request. Assuming no retransmissions
|
||||
in the handshake, and no Retry reply from Bob, the packet numbers
|
||||
in an example standard handshake will be:
|
||||
@ -2775,7 +2779,7 @@ Alice Bob
|
||||
|
||||
Any retransmission of handshake messages
|
||||
(SessionRequest, SessionCreated, or SessionConfirmed)
|
||||
must be resent unchanged, except for incrementing the packet number.
|
||||
must be resent unchanged, with the same packet number.
|
||||
Do not use different ephemeral keys or change the payload
|
||||
when retransmitting these messages.
|
||||
|
||||
@ -2836,7 +2840,7 @@ Header Protection KDF:
|
||||
{% highlight lang='dataspec' %}
|
||||
// incoming encrypted packet
|
||||
len = packet.length
|
||||
// take the last 16 bytes before the MAC
|
||||
// take the last 12 bytes before the MAC
|
||||
sample = packet[len-32:len-17]
|
||||
n = sample[4:15]
|
||||
key = header protection key
|
||||
@ -2844,9 +2848,6 @@ Header Protection KDF:
|
||||
mask = ChaCha20.encrypt(key, n, data)
|
||||
|
||||
// encrypt the header by XORing with the mask
|
||||
// short header
|
||||
header[8:12] ^= mask[0:4]
|
||||
// long header
|
||||
header[8:15] ^= mask[0:7]
|
||||
|
||||
|
||||
@ -3204,7 +3205,7 @@ Unencrypted data (Poly1305 authentication tag not shown):
|
||||
|
||||
flag :: 1 byte, unused, set to 0 for future compatibility
|
||||
|
||||
Packet Number :: 0 unless retransmitted or resent after Retry
|
||||
Packet Number :: 0 unless resent after Retry
|
||||
|
||||
Source Connection ID :: Randomly generated by Alice
|
||||
|
||||
@ -3464,7 +3465,7 @@ Unencrypted data (Poly1305 auth tag not shown):
|
||||
|
||||
flag :: 1 byte, unused, set to 0 for future compatibility
|
||||
|
||||
Packet Number :: 0 unless retransmitted or resent after Retry
|
||||
Packet Number :: 0 unless resent after Retry
|
||||
|
||||
Source Connection ID :: Randomly generated by Alice
|
||||
|
||||
@ -3722,7 +3723,8 @@ Unencrypted data (Poly1305 auth tags not shown):
|
||||
Destination Connection ID :: As sent in Session Request,
|
||||
or one received in Session Confirmed?
|
||||
|
||||
Packet Number :: 1 unless retransmitted or resent after Retry
|
||||
Packet Number :: 1 unless the Session Request message was
|
||||
retransmitted or resent after Retry
|
||||
|
||||
type :: 2
|
||||
|
||||
@ -4247,7 +4249,7 @@ Session setup is not complete until all fragments are received.
|
||||
+----+----+----+----+----+ +
|
||||
| |
|
||||
+ Router Info fragment +
|
||||
| (Alice RI in Sessopm Confirmed) |
|
||||
| (Alice RI in Session Confirmed) |
|
||||
~ (Alice, Bob, or third-party ~
|
||||
| RI in data phase) |
|
||||
~ . . . ~
|
||||
@ -4259,7 +4261,8 @@ Session setup is not complete until all fragments are received.
|
||||
flag :: 1 byte flags
|
||||
bit order: 76543210 (bit 7 is MSB)
|
||||
bit 0: 0 for local store, 1 for flood request
|
||||
bits 7-1: Unused, set to 0 for future compatibility
|
||||
bit 1: 0 for uncompressed, 1 for gzip compressed
|
||||
bits 7-2: Unused, set to 0 for future compatibility
|
||||
frag :: 1 byte fragment info:
|
||||
bit order: 76543210 (bit 7 is MSB)
|
||||
bits 7-4: fragment number 0-14, big endian
|
||||
@ -4280,8 +4283,20 @@ Notes:
|
||||
treat it as a DatabaseStore Message with a nonzero reply token,
|
||||
and flood it to the nearest floodfills.
|
||||
|
||||
- The Router Info is NOT compressed with gzip
|
||||
(unlike in a DatabaseStore Message, where it is)
|
||||
- The Router Info is optionally compressed with gzip,
|
||||
as indicated by flag bit 1.
|
||||
This is different from NTCP2, where it is never compressed,
|
||||
and from a DatabaseStore Message, where it always is compressed.
|
||||
Compression is optional because it usually is of little benefit
|
||||
for small Router Infos, where there is little compressible content,
|
||||
but is very beneficial for large Router Infos with several
|
||||
compressible Router Addresses.
|
||||
Compression is recommended if it allows a Router Info to fit
|
||||
in a single message without fragmentation.
|
||||
|
||||
- If the Router Info is compressed AND fragmented,
|
||||
the data is compressed first and then fragmented.
|
||||
The fragments are not individually compressed.
|
||||
|
||||
- Flooding must not be requested unless there are published
|
||||
RouterAddresses in the RouterInfo. The receiving router
|
||||
@ -4942,9 +4957,10 @@ Session Request
|
||||
----------------
|
||||
If no Session Created is received by Alice:
|
||||
|
||||
Maintain same source and connection IDs and ephemeral key. Increment packet number.
|
||||
Re-encrypt Noise payload as AEAD (packet number) changed.
|
||||
Re-protect header, re-obfuscate header, as packet number changed.
|
||||
Maintain same source and connection IDs, ephemeral key, and packet number 0.
|
||||
Or, just retain the encrypted packet.
|
||||
Packet number must not be incremented, because that would change
|
||||
the chained hash value used to encrypt the Session Created message.
|
||||
|
||||
Recommended retransmission intervals: 3 and 6 seconds (3 and 9 seconds after first sent).
|
||||
Recommended timeout: 15 seconds total
|
||||
@ -4954,9 +4970,10 @@ Session Created
|
||||
----------------
|
||||
If no Session Confirmed is received by Bob:
|
||||
|
||||
Maintain same source and connection IDs and ephemeral key. Increment packet number.
|
||||
Re-encrypt Noise payload as AEAD (packet number) changed.
|
||||
Re-protect header, re-obfuscate header, as packet number changed.
|
||||
Maintain same source and connection IDs, ephemeral key, and packet number 0.
|
||||
Or, just retain the encrypted packet.
|
||||
Packet number must not be incremented, because that would change
|
||||
the chained hash value used to encrypt the Session Confirmed message.
|
||||
|
||||
Recommended retransmission intervals: 3 and 6 seconds (3 and 9 seconds after first sent).
|
||||
Recommended timeout: 15 seconds total
|
||||
@ -4986,6 +5003,13 @@ The preferred alternative is option 2).
|
||||
Alice must retain the information required to retransmit the Session Confirmed message.
|
||||
Alice should also retransmit all Data messages after the Sesession Confirmed
|
||||
message is retransmitted.
|
||||
|
||||
When retransmitting Session Confirmed,
|
||||
maintain same source and connection IDs, ephemeral key, and packet number 1.
|
||||
Or, just retain the encrypted packet.
|
||||
Packet number must not be incremented, because that would change
|
||||
the chained hash value which is an input for the split() function.
|
||||
|
||||
Bob may retain (queue) the data messages received before the Session Confirmed message.
|
||||
Neither the header protection keys nor the decryption keys are available
|
||||
before the Session Confirmed message is received, so Bob does not know
|
||||
@ -4999,13 +5023,13 @@ as Alice will retransmit them.
|
||||
|
||||
Retry
|
||||
---------
|
||||
If no Session Request is received:
|
||||
A Retry message is never retransmitted, except in response to a repeated
|
||||
Session Request message being received.
|
||||
|
||||
If resending the Retry message:
|
||||
Maintain same source and connection IDs. Increment packet number.
|
||||
Re-protect header, re-obfuscate header, as packet number changed.
|
||||
Re-protect header, re-obfuscate header, as the packet number changed.
|
||||
|
||||
Recommended retransmission intervals: 3 and 6 seconds (3 and 9 seconds after first sent).
|
||||
Recommended timeout: 15 seconds total
|
||||
|
||||
|
||||
Total Timeout
|
||||
@ -5080,6 +5104,14 @@ If both SSU and SSU2 addresses are supported, or if multiple addresses for
|
||||
different IPv4 or IPv6 IPs are supported (currently supported by i2pd but not Java i2p)
|
||||
the sizes could increase significantly.
|
||||
|
||||
The Router Info block supports optional gzip compression.
|
||||
Compression is optional because it usually is of little benefit
|
||||
for small Router Infos, where there is little compressible content,
|
||||
but is very beneficial for large Router Infos with several
|
||||
compressible Router Addresses.
|
||||
Compression is recommended if it allows a Router Info to fit
|
||||
in a single message without fragmentation.
|
||||
|
||||
While a typical MTU and Router Info size would allow the Router Info to be sent
|
||||
unfragmented, fragmentation will be necessary and this protocol must support it.
|
||||
The Router Info block contains a fragmentation field (unlike in NTCP2 where it is not required).
|
||||
@ -5756,6 +5788,11 @@ a (possibly expensive) fallback lookup by source IP/port
|
||||
and a second header decryption.
|
||||
Only Session Created and Retry (and possibly others TBD) will require
|
||||
the fallback processing.
|
||||
If an endpoint changes IP or port after session creation,
|
||||
the session ID is still used to lookup the session.
|
||||
It is never necessary to use heuristics to find the session,
|
||||
for example by looking for a different session with the same
|
||||
IP but a different port.
|
||||
|
||||
|
||||
Therefore, the recommended processing steps in the receiver loop logic are:
|
||||
@ -5768,8 +5805,8 @@ Therefore, the recommended processing steps in the receiver loop logic are:
|
||||
b) If the message type is Session Confirmed, it is a long header.
|
||||
Verify the net ID and protocol version are valid.
|
||||
Decrypt the next 16 bytes of the header with ChaCha20
|
||||
using the local router hash as the key. Then decrypt the message with
|
||||
Noise, using the decrypted 32-byte header as the AD.
|
||||
using the local intro key with n=1. Then MixHash() the
|
||||
decrypted 32 byte header and decrypt the message with Noise.
|
||||
c) If the message type is valid but not Session Confirmed,
|
||||
it is a short header.
|
||||
Verify the net ID and protocol version are valid.
|
||||
@ -5794,13 +5831,14 @@ Therefore, the recommended processing steps in the receiver loop logic are:
|
||||
allowed out-of-session (TBD).
|
||||
a) If all is valid and the message type is Session Request,
|
||||
decrypt the next 16 bytes of the header and the 32-byte X value
|
||||
with ChaCha20 using the local router hash as the key with n=1.
|
||||
- If the token at header bytes 24-31 is accepted, decrypt the
|
||||
message with Noise, using the decrypted 32-byte header as the AD.
|
||||
Send a Session Created in response.
|
||||
- If the token is not accepted, send a Retry message to the
|
||||
source IP/port with a token. Do not attempt to
|
||||
decrypt the message with Noise to avoid DDoS attacks.
|
||||
with ChaCha20 using the local intro key with n=1.
|
||||
- If the token at header bytes 24-31 is accepted,
|
||||
then MixHash() the decrypted 32 byte header and
|
||||
decrypt the message with Noise.
|
||||
Send a Session Created in response.
|
||||
- If the token is not accepted, send a Retry message to the
|
||||
source IP/port with a token. Do not attempt to
|
||||
decrypt the message with Noise to avoid DDoS attacks.
|
||||
b) If the message type is some other message that is valid
|
||||
out-of-session, presumably with a short header,
|
||||
decrypt the rest of the message with ChaCha20/Poly1305
|
||||
@ -5818,22 +5856,23 @@ Therefore, the recommended processing steps in the receiver loop logic are:
|
||||
Verify the net ID and protocol version are valid, and
|
||||
the message type is Session Response or Retry, or other message type
|
||||
allowed out-of-session (TBD).
|
||||
- If all is valid and the message type is Session Response,
|
||||
decrypt the next 16 bytes of the header and the 32-byte Y value
|
||||
with ChaCha20 using Bob's router hash as the key with n=1.
|
||||
Decrypt the message with Noise, using the decrypted 32-byte header as the AD.
|
||||
Send a Session Confirmed in response.
|
||||
- If all is valid and the message type is Retry,
|
||||
decrypt the next 16 bytes of the header
|
||||
with ChaCha20 using Bob's router hash as the key with n=1.
|
||||
Validate the remaining data (padding) and MAC using ChaCha20/Poly1305 using
|
||||
TBD as the key and TBD as the nonce and the decrypted 32-byte header as the AD.
|
||||
Resend a Session Request with the received token in response.
|
||||
- If the message type is some other message that is valid
|
||||
out-of-session, presumably with a short header,
|
||||
decrypt the rest of the message with ChaCha20/Poly1305
|
||||
using the intro key (TBD), using the decrypted 16-byte header
|
||||
as the AD. Process the message.
|
||||
- If all is valid and the message type is Session Response,
|
||||
decrypt the next 16 bytes of the header and the 32-byte Y value
|
||||
with ChaCha20 using Bob's router hash as the key with n=1.
|
||||
Then MixHash() the decrypted 32 byte header and
|
||||
decrypt the message with Noise.
|
||||
Send a Session Confirmed in response.
|
||||
- If all is valid and the message type is Retry,
|
||||
decrypt the next 16 bytes of the header
|
||||
with ChaCha20 using Bob's router hash as the key with n=1.
|
||||
Validate the remaining data (padding) and MAC using ChaCha20/Poly1305 using
|
||||
TBD as the key and TBD as the nonce and the decrypted 32-byte header as the AD.
|
||||
Resend a Session Request with the received token in response.
|
||||
- If the message type is some other message that is valid
|
||||
out-of-session, presumably with a short header,
|
||||
decrypt the rest of the message with ChaCha20/Poly1305
|
||||
using the intro key (TBD), using the decrypted 16-byte header
|
||||
as the AD. Process the message.
|
||||
c) If a pending outbound session is not found,
|
||||
or the session ID does not match the pending session, drop the message,
|
||||
unless the port is shared with SSU 1.
|
||||
|
Reference in New Issue
Block a user