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:
zzz
2021-10-26 13:06:04 -04:00
parent 9fae96a317
commit ddddc9dc9d

View File

@@ -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) and sending ceases when a packet containing that information is remain the same)
acknowledged. 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) Any retransmission of packet contents (whether or not the contents remain the same)
must use the next unused packet number. 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 Packet numbering starts with Session Request. Assuming no retransmissions
in the handshake, and no Retry reply from Bob, the packet numbers in the handshake, and no Retry reply from Bob, the packet numbers
in an example standard handshake will be: in an example standard handshake will be:
@@ -2775,7 +2779,7 @@ Alice Bob
Any retransmission of handshake messages Any retransmission of handshake messages
(SessionRequest, SessionCreated, or SessionConfirmed) (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 Do not use different ephemeral keys or change the payload
when retransmitting these messages. when retransmitting these messages.
@@ -2836,7 +2840,7 @@ Header Protection KDF:
{% highlight lang='dataspec' %} {% highlight lang='dataspec' %}
// incoming encrypted packet // incoming encrypted packet
len = packet.length 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] sample = packet[len-32:len-17]
n = sample[4:15] n = sample[4:15]
key = header protection key key = header protection key
@@ -2844,9 +2848,6 @@ Header Protection KDF:
mask = ChaCha20.encrypt(key, n, data) mask = ChaCha20.encrypt(key, n, data)
// encrypt the header by XORing with the mask // encrypt the header by XORing with the mask
// short header
header[8:12] ^= mask[0:4]
// long header
header[8:15] ^= mask[0:7] 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 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 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 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 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, Destination Connection ID :: As sent in Session Request,
or one received in Session Confirmed? 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 type :: 2
@@ -4247,7 +4249,7 @@ Session setup is not complete until all fragments are received.
+----+----+----+----+----+ + +----+----+----+----+----+ +
| | | |
+ Router Info fragment + + Router Info fragment +
| (Alice RI in Sessopm Confirmed) | | (Alice RI in Session Confirmed) |
~ (Alice, Bob, or third-party ~ ~ (Alice, Bob, or third-party ~
| RI in data phase) | | RI in data phase) |
~ . . . ~ ~ . . . ~
@@ -4259,7 +4261,8 @@ Session setup is not complete until all fragments are received.
flag :: 1 byte flags flag :: 1 byte flags
bit order: 76543210 (bit 7 is MSB) bit order: 76543210 (bit 7 is MSB)
bit 0: 0 for local store, 1 for flood request 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: frag :: 1 byte fragment info:
bit order: 76543210 (bit 7 is MSB) bit order: 76543210 (bit 7 is MSB)
bits 7-4: fragment number 0-14, big endian 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, treat it as a DatabaseStore Message with a nonzero reply token,
and flood it to the nearest floodfills. and flood it to the nearest floodfills.
- The Router Info is NOT compressed with gzip - The Router Info is optionally compressed with gzip,
(unlike in a DatabaseStore Message, where it is) 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 - Flooding must not be requested unless there are published
RouterAddresses in the RouterInfo. The receiving router RouterAddresses in the RouterInfo. The receiving router
@@ -4942,9 +4957,10 @@ Session Request
---------------- ----------------
If no Session Created is received by Alice: If no Session Created is received by Alice:
Maintain same source and connection IDs and ephemeral key. Increment packet number. Maintain same source and connection IDs, ephemeral key, and packet number 0.
Re-encrypt Noise payload as AEAD (packet number) changed. Or, just retain the encrypted packet.
Re-protect header, re-obfuscate header, as packet number changed. 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 retransmission intervals: 3 and 6 seconds (3 and 9 seconds after first sent).
Recommended timeout: 15 seconds total Recommended timeout: 15 seconds total
@@ -4954,9 +4970,10 @@ Session Created
---------------- ----------------
If no Session Confirmed is received by Bob: If no Session Confirmed is received by Bob:
Maintain same source and connection IDs and ephemeral key. Increment packet number. Maintain same source and connection IDs, ephemeral key, and packet number 0.
Re-encrypt Noise payload as AEAD (packet number) changed. Or, just retain the encrypted packet.
Re-protect header, re-obfuscate header, as packet number changed. 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 retransmission intervals: 3 and 6 seconds (3 and 9 seconds after first sent).
Recommended timeout: 15 seconds total 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 must retain the information required to retransmit the Session Confirmed message.
Alice should also retransmit all Data messages after the Sesession Confirmed Alice should also retransmit all Data messages after the Sesession Confirmed
message is retransmitted. 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. Bob may retain (queue) the data messages received before the Session Confirmed message.
Neither the header protection keys nor the decryption keys are available Neither the header protection keys nor the decryption keys are available
before the Session Confirmed message is received, so Bob does not know before the Session Confirmed message is received, so Bob does not know
@@ -4999,13 +5023,13 @@ as Alice will retransmit them.
Retry 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. 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 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) different IPv4 or IPv6 IPs are supported (currently supported by i2pd but not Java i2p)
the sizes could increase significantly. 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 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. 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). 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. and a second header decryption.
Only Session Created and Retry (and possibly others TBD) will require Only Session Created and Retry (and possibly others TBD) will require
the fallback processing. 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: 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. b) If the message type is Session Confirmed, it is a long header.
Verify the net ID and protocol version are valid. Verify the net ID and protocol version are valid.
Decrypt the next 16 bytes of the header with ChaCha20 Decrypt the next 16 bytes of the header with ChaCha20
using the local router hash as the key. Then decrypt the message with using the local intro key with n=1. Then MixHash() the
Noise, using the decrypted 32-byte header as the AD. decrypted 32 byte header and decrypt the message with Noise.
c) If the message type is valid but not Session Confirmed, c) If the message type is valid but not Session Confirmed,
it is a short header. it is a short header.
Verify the net ID and protocol version are valid. 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). allowed out-of-session (TBD).
a) If all is valid and the message type is Session Request, 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 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. with ChaCha20 using the local intro key with n=1.
- If the token at header bytes 24-31 is accepted, decrypt the - If the token at header bytes 24-31 is accepted,
message with Noise, using the decrypted 32-byte header as the AD. then MixHash() the decrypted 32 byte header and
Send a Session Created in response. decrypt the message with Noise.
- If the token is not accepted, send a Retry message to the Send a Session Created in response.
source IP/port with a token. Do not attempt to - If the token is not accepted, send a Retry message to the
decrypt the message with Noise to avoid DDoS attacks. 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 b) If the message type is some other message that is valid
out-of-session, presumably with a short header, out-of-session, presumably with a short header,
decrypt the rest of the message with ChaCha20/Poly1305 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 Verify the net ID and protocol version are valid, and
the message type is Session Response or Retry, or other message type the message type is Session Response or Retry, or other message type
allowed out-of-session (TBD). allowed out-of-session (TBD).
- If all is valid and the message type is Session Response, - 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 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. 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. Then MixHash() the decrypted 32 byte header and
Send a Session Confirmed in response. decrypt the message with Noise.
- If all is valid and the message type is Retry, Send a Session Confirmed in response.
decrypt the next 16 bytes of the header - If all is valid and the message type is Retry,
with ChaCha20 using Bob's router hash as the key with n=1. decrypt the next 16 bytes of the header
Validate the remaining data (padding) and MAC using ChaCha20/Poly1305 using with ChaCha20 using Bob's router hash as the key with n=1.
TBD as the key and TBD as the nonce and the decrypted 32-byte header as the AD. Validate the remaining data (padding) and MAC using ChaCha20/Poly1305 using
Resend a Session Request with the received token in response. TBD as the key and TBD as the nonce and the decrypted 32-byte header as the AD.
- If the message type is some other message that is valid Resend a Session Request with the received token in response.
out-of-session, presumably with a short header, - If the message type is some other message that is valid
decrypt the rest of the message with ChaCha20/Poly1305 out-of-session, presumably with a short header,
using the intro key (TBD), using the decrypted 16-byte header decrypt the rest of the message with ChaCha20/Poly1305
as the AD. Process the message. 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, c) If a pending outbound session is not found,
or the session ID does not match the pending session, drop the message, or the session ID does not match the pending session, drop the message,
unless the port is shared with SSU 1. unless the port is shared with SSU 1.