commit 1d229c465213d531ef4cb06482c77b960dccdd56
parent 578dc2e138f55633f874df854a79802d8f869e73
Author: Pedram Fardzadeh <p.fardzadeh@protonmail.com>
Date: Mon, 17 Jun 2024 06:06:06 +0200
Updated UDP message exchange and rekeying
Diffstat:
1 file changed, 119 insertions(+), 73 deletions(-)
diff --git a/draft-gnunet-communicators.xml b/draft-gnunet-communicators.xml
@@ -204,48 +204,42 @@
<name>UDP communicator</name>
<t>
The UDP communicator implements an encryption layer that protects both the payload and the communicator's
- specific metadata (not to be confused with the UDP header). In particular, any packet sent by the communicator
- is indistinguishable from random noise to an outside observer.
+ specific metadata (not to be confused with the UDP header). In particular, any message sent by the communicator
+ is indistinguishable from random noise to an outside observer (FIXME: Not the case for BROADCAST messages).
</t>
<t>
For any new connection to a target peer, the communicator attempts to establish a shared secret using an
Elliptic-Curve Diffie-Hellman key exchange. The communicator initiating the connection creates an ephemeral
- key pair to encrypt the message for the target peer identity. The encrypted message is prepended by a
- KX Header, which contains the ephemeral public key and is then sent to the target peer. This procedure
- is repeated with a new ephemeral key for each subsequent packet. The wire format for such a KX packet can
- be found in <xref target="figure_udp_initialkx"/>.
+ key pair to encrypt the message for the target peer identity. Both the ephemeral public key and the encrypted
+ message are sent to the receiving peer together with an authentication tag that authenticates the encrypted
+ message. Independent of the payload, each message includes the sender's peer ID, a monotonic timestamp, and a
+ signature over the session's meta data. Receivers should keep track of the monotonic timestamps for each peer
+ ID to reject possible replay attacks. For each subsequent message the same procedure is conducted with a new
+ ephemeral key pair.
While the communicator always offers this type of message queue to a reachable peer, it is inefficient for
- high-volume data transfer because a new key exchange is conducted for every packet.
+ high-volume data transfer because a new key exchange is conducted for every message.
</t>
<t>
- If the target peer acknowledges the reception of a KX packet, the resulting key can be reused. Such an ACK
- packet can be sent either via a bi-directional UDP connection or a backchannel connection provided by
- TRANSPORT. The wire format for an ACK packet is depicted in <xref target="figure_udp_ack"/>.
+ If the target peer acknowledges the reception of a message, the employed key can be reused. Such acknowledgemnts
+ can be sent either via a bi-directional UDP connection or a backchannel connection provided by TRANSPORT.
This acknowledgment prompts the communicator to offer a new queue to TRANSPORT, which has a higher priority
than the default queue but starts with limited capacity. The capacity increases whenever the communicator
receives an ACK for a transmission. This queue is suitable for high-volume data transfer, and TRANSPORT
will prioritize it if available.
</t>
<t>
- The communicator initiating the connection attempts to authenticate its peer ID (public key) in the initial packets
- by signing a monotonic time stamp, its peer ID, and the target peer ID. This signed data, along with the signature,
- is sent in one of the first packets. Receivers should keep track (persist) of the monotonic time stamps for each
- peer ID to reject possible replay attacks.
- </t>
- <t>
- All metadata for headers is chosen such that they are indistinguishable from random.
- There are three distinct message types that are sent and received by UDP communciators: KX, BOX, BROADCAST.
- In any case, the common header is 32 + 16 bytes in length.
+ There are three distinct message types that are sent and received by UDP communicators: KX, BOX and BROADCAST.
+ For KX and BOX messages, their metadata is chosen such that they are indistinguishable from random.
</t>
<section anchor="Key_exchange" numbered="true" toc="default">
<name>Key exchange</name>
<t>
Independent of the type of message queue, an X25519-based key exchange is at least initiated once by the sending peer. In cases
- where the receiving peer cannot acknowledge the reception of packets, a key exchange is performed for every packet. The UDP
+ where the receiving peer cannot acknowledge the reception of messages, a key exchange is performed for every message. The UDP
communicator uses a modified version of the standard X25519 key exchange described in section 6.1 of <xref target="RFC7748"/>.
The two key pair needed for such a key exchange is an ephemeral key pair generated by the initiating communiciator and the peer
- identity of the receiving communciator. The ephemeral public key is transfered via a key exchange packet as defined in
+ identity of the receiving communciator. The ephemeral public key is transfered via a key exchange message as defined in
<xref target="figure_udp_initialkx"/>.
</t>
<t>
@@ -253,11 +247,11 @@
due to the transmission of an ephemeral public key from the sending peer to the receiving peer. In a censored environment,
this could lead to packet interception, preventing communication between peers. The UDP communicator addresses this by encoding
the ephemeral public key into a random-looking byte stream (referred to as the "representative") before sending it. Since the
- GCM tag and the encrypted data in the key exchange (KX) packet also appear random, the entire packet is indistinguishable from a
+ GCM tag and the encrypted data in the key exchange message also appear random, the entire message is indistinguishable from a
random byte stream. This leaves a censor with the option to either do nothing or intercept all random-looking UDP packets, thereby
disrupting a disproportionate part of today's internet communication.
</t>
- <figure anchor="figure_udp_initialkx" title="The binary representation of the initial key exchange packet.">
+ <figure anchor="figure_udp_initialkx" title="The binary representation of the key exchange message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -297,10 +291,10 @@
</dd>
</dl>
<t>
- In order to prevent replay attacks for KX messages, the plaintext resulting from decryption of the ENCRYPTED DATA
- in the KX message starts with a session-specific confirmation header:
+ In order to prevent replay attacks for KX messages, the plaintext resulting from decryption of the encrypted data
+ starts with a session-specific confirmation header:
</t>
-<figure anchor="figure_udp_confirmation" title="The binary representation of the KX confirmation packet">
+<figure anchor="figure_udp_confirmation" title="The binary representation of the KX confirmation header">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -350,7 +344,7 @@
The message payload data.
</dd>
</dl>
- <figure anchor="figure_udp_handshake_sig" title="The wire format used for creating the signature of the identification packet.">
+ <figure anchor="figure_udp_handshake_sig" title="The wire format used for creating the signature of the UDP Confirmation header.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -412,7 +406,8 @@
</dd>
<dt>EPHEMERAL PUBLIC KEY</dt>
<dd>
- A 256-bit Curve25519 public key. This public key is send in an encodeded format in the KX packet.
+ A 256-bit Curve25519 public key. This public key is send in an Elligator encodeded format, called
+ the representative, in the KX header.
</dd>
<dt>MONOTONIC TIMESTAMP</dt>
<dd>
@@ -424,7 +419,7 @@
</dd>
</dl>
<t>
- Upon receiving a KX packet, the receiving peer decodes the representative into the original ephemeral public key and subsequently
+ Upon receiving a KX message, the receiving peer decodes the representative into the original ephemeral public key and subsequently
computes the shared secret. The UDP communicator utilizes Elligator for the encoding and decoding of the ephemeral public key
described in Section 5. <xref target="BHKL13"/>. More details about the construction of the representative and Elligator's
usage can be found in <xref target="Elligator"/>.
@@ -449,8 +444,9 @@ Decap(REPR) := (K,IV) = SetupCipher(X25519(REC_SK, Dec(REPR)), 0)
to be safe. For further details, refer to the paper <xref target="T21"/>.
</t>
<t>
- Once a KX message is received and validated, the peer <bcp14>SHOULD</bcp14> try to acknowledge the established shared secret to switch to the more
- efficient queue. The details about the acknowledgement process and subsequent message exchange can be found in <xref target="udp_message_exchange"/>.
+ Additional data might be inserted after the Confirmation header as part of the encrypted data of the KX message. Padding may be necessary due to the
+ use of AES-GCM. Once a KX message is received and validated, the peer <bcp14>SHOULD</bcp14> try to acknowledge the established shared secret to switch
+ to the more efficient queue. The details about the acknowledgment process and subsequent message exchange can be found in <xref target="udp_message_exchange"/>.
</t>
</section>
<section anchor="udp_key_schedule" numbered="true" toc="default">
@@ -489,8 +485,8 @@ DeriveKID(MSK,SEQ):
return KID
]]></artwork>
<t>
- The sequence number SEQ for any shared secret is initially 0 and incremented
- with each successive encryption (sent/received message).
+ The sequence number SEQ for any shared secret is initially 0 and incremented on the senders side with each
+ successive encryption and on the receivers side on each decryption.
</t>
</section>
<section anchor="udp_message_exchange" numbered="true" toc="default">
@@ -498,12 +494,13 @@ DeriveKID(MSK,SEQ):
<t>
KX messages as presented in <xref target="Key_exchange"/> are sufficient for transferring arbitrary amounts of data. This way of
communicating is slow, due to the establishment of a shared secret for each message using asymmetric cryptography. The UDP communicator
- offers a faster way of communication with the reuse of a shared secret. For this purpose, the receiver of a KX message needs to acknowledge
- the reception of the representative. The acknowledgement is sent via a UDP Box Message as defined in <xref target="figure_udp_box"/> which
- contains an ACK Header as its payload. The wire format of the ACK Header can be seen in <xref target="figure_udp_ack"/>.
- (FIXME: documentation for message exchange is missing, specifically usage of UDP BOX and ACK Header)
+ offers a faster way of communication with the reuse of a shared secret. For this purpose, the receiver of a message <bcp14>SHOULD</bcp14>
+ acknowledge the reception to signal the sender that the same shared secret can be reused. The sender can then use the acknowledged shared
+ secret and increment the utilized sequence number for each subsequent message to derive new symmetric key material. These messages are
+ send as BOX messages, which incorporate a KID as defined in <xref target="derive_kid"/> to identify both the shared secret and sequence
+ number. The wire format of a BOX message is depicted in <xref target="figure_udp_box"/>.
</t>
-<figure anchor="figure_udp_box" title="The binary representation of the UDP Box.">
+ <figure anchor="figure_udp_box" title="The binary representation of the UDP Box.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -533,7 +530,7 @@ DeriveKID(MSK,SEQ):
</dd>
<dt>GCM TAG</dt>
<dd>
- A 128-bit GCM tag used to authenticate the ciphertext immediately following this KX.
+ A 128-bit GCM tag used to authenticate the ciphertext immediately following this TCP Box header.
</dd>
<dt>ENCRYPTED DATA</dt>
<dd>
@@ -542,12 +539,10 @@ DeriveKID(MSK,SEQ):
</dd>
</dl>
<t>
- Notice how a receiver should have precalculated all derived keys and corresponding
- KIDs for which it has already sent ACKs.
- Consequently, for valid sequence numbers below the current ACK limit,
- KID should match one of the precalculated keys in the key cache and
- the encrypted data can be decrypted.
- Otherwise, the message <bcp14>MUST</bcp14> be rejected.
+ An acknowldgement can be sent in various ways is ultimately decided by TRANSPORT. If the target peer can also reach the sending peer via
+ UDP messages, both KX messages or BOX messages could be utilized to send the acknowledgment as their payload. TRANSPORT could also choose
+ to utilize another communicator type to send the acknowledgment (backchannel). Either way, acknowledgments are always sent in form of a
+ ACK header. The wire format of the ACK header can be seen in <xref target="figure_udp_ack"/>.
</t>
<figure anchor="figure_udp_ack" title="The wire format of an ACK header.">
<artwork name="" type="" align="left" alt=""><![CDATA[
@@ -576,13 +571,46 @@ DeriveKID(MSK,SEQ):
+-----+-----+-----+-----+-----+-----+-----+-----+
]]></artwork>
</figure>
+ <dl>
+ <dt>SIZE</dt>
+ <dd>
+ A 32-bit value containing the length of the signed data in bytes in network byte order.
+ </dd>
+ <dt>TYPE</dt>
+ <dd>
+ A 16-bit signature type flag in network byte order. The value of this field MUST be 1460.
+ </dd>
+ <dt>SEQ ACK</dt>
+ <dd>
+ Sequence acknowledgment limit. Specifies current maximum sequence number supported by receiver.
+ </dd>
+ <dt>MSK HASH</dt>
+ <dd>
+ CMAC of the base key being acknowledged.
+ </dd>
+ </dl>
+ <t>
+ To avoid having to acknowledge every single message individually, the sender of an acknowledgment can specify the allowed sequence number for
+ the sender in the ACK header. Notice how a receiver should have precalculated all derived keys and corresponding KIDs for which it has already
+ sent ACKs. Consequently, for valid sequence numbers below the current ACK limit, KID should match one of the precalculated keys in the key cache,
+ and the encrypted data can be decrypted. Otherwise, the message <bcp14>MUST</bcp14> be rejected.
+ </t>
+ <t>
+ Multiple shared secrets can be used simultaneously between the sending peer and target peer (FIXME: currently limited to 256). Should the
+ sending peer use up all acknowledgments for all its shared secrets, messages are sent through KX messages again.
+ </t>
</section>
<section anchor="udp_rekeying" numbered="true" toc="default">
<name>Rekeying</name>
<t>
- (FIXME: rekeying procedure documentation is missing)
+ The amount of data which can be encrypted with a shared secret <bcp14>MUST</bcp14> be limited (FIXME: Currently at 4GB). Before
+ the capacity of a shared secret is used up (FIXME: currently at 70%), the sender initiates rekeying by sending a new ephemeral public key
+ for a key exchange. As multiple shared secrets can be used simultaneously, rekeying doesn't necessarily delete the old shared secret if its
+ capacity is not yet reached. The ephemeral public key is sent encrypted in a Rekey header as part of the payload of BOX message. Because the
+ ephemeral public key is encrypted, there is no need to use Elligator's encoding function. The wire format of the Rekey header can
+ be seen in <xref target="figure_udp_rekey"/>.
</t>
- <figure anchor="figure_udp_rekey" title="The wire format of a REKEY header.">
+ <figure anchor="figure_udp_rekey" title="The wire format of a Rekey header.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 16
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -599,6 +627,24 @@ DeriveKID(MSK,SEQ):
+-----+-----+-----+-----+-----+-----+-----+-----+
]]></artwork>
</figure>
+ <dl>
+ <dt>SIZE</dt>
+ <dd>
+ A 16-bit value containing the length of the message in bytes in network byte order
+ </dd>
+ <dt>TYPE</dt>
+ <dd>
+ A 16-bit signature type flag in network byte order. The value of this field MUST be 1462.
+ </dd>
+ <dt>EPHEMERAL PUBLIC KEY</dt>
+ <dd>
+ A 256-bit X25519 ephemeral public key to rekey with.
+ </dd>
+ </dl>
+ <t>
+ Additional data might be inserted after the Rekey header as part of the encrypted data of the BOX message. Padding
+ may be necessary due to the use of AES-GCM.
+ </t>
</section>
<section anchor="udp_bc" numbered="true" toc="default">
<name>Broadcast</name>
@@ -637,12 +683,12 @@ DeriveKID(MSK,SEQ):
material.
</t>
<t>
- The sent public key <bcp14>MUST</bcp14> be directly followed by an encrypted TCP handshake packet as shown
+ The sent public key <bcp14>MUST</bcp14> be directly followed by an encrypted TCP handshake message as shown
in <xref target="figure_tcp_handshake"/>. In addition to the peer identity of the sender and a timestamp, it
contains a nonce as a challenge for the receiving TCP communicator. All this data is authenticated via a
- signature, which is also included in the TCP handshake packet.
+ signature, which is also included in the TCP handshake message.
</t>
- <figure anchor="figure_tcp_handshake" title="The binary representation of the TCP handshake packet.">
+ <figure anchor="figure_tcp_handshake" title="The binary representation of the TCP handshake message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -685,13 +731,13 @@ DeriveKID(MSK,SEQ):
</dd>
<dt>NONCE</dt>
<dd>
- A 256-bit random value used as a challenge to be signed in a TCP handshake acknowledgment packet.
+ A 256-bit random value used as a challenge to be signed in a TCP handshake acknowledgment message.
</dd>
</dl>
<t>
The data scheme used for computing the signature is depicted in <xref target="figure_tcp_handshake_sig"/>.
</t>
- <figure anchor="figure_tcp_handshake_sig" title="The wire format used for creating the signature of the tcp handshake packet.">
+ <figure anchor="figure_tcp_handshake_sig" title="The wire format used for creating the signature of the tcp handshake message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -768,13 +814,13 @@ DeriveKID(MSK,SEQ):
</dl>
<t>
Upon reception of the ephemeral public key, the receiving TCP communicator carries out the decapsulation step of the
- key exchange and retrieves the shared key material. The subsequently received TCP handshake packet is then decrypted and verified.
+ key exchange and retrieves the shared key material. The subsequently received TCP handshake message is then decrypted and verified.
If the signature is invalid, the connection is dropped. (FIXME: Other checks such as sender peer identity etc needed).
- In the case of a valid signature, the receiving TCP communicator sends its own TCP handshake packet to establish
- shared key material for outgoing messages and also replies with an encrypted TCP handshake acknowledgment packet as defined
+ In the case of a valid signature, the receiving TCP communicator sends its own TCP handshake message to establish
+ shared key material for outgoing messages and also replies with an encrypted TCP handshake acknowledgment message as defined
in <xref target="figure_tcp_handshake_ack"/>.
</t>
- <figure anchor="figure_tcp_handshake_ack" title="The binary representation of the tcp handshake acknowledgement packet.">
+ <figure anchor="figure_tcp_handshake_ack" title="The binary representation of the tcp handshake acknowledgment message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -855,10 +901,10 @@ DeriveKID(MSK,SEQ):
</dd>
</dl>
<t>
- The data scheme used for computing the signature for the acknowledgement packet is depicted
+ The data scheme used for computing the signature for the acknowledgment message is depicted
in <xref target="figure_tcp_handshake_ack_sig"/>.
</t>
- <figure anchor="figure_tcp_handshake_ack_sig" title="The wire format used for creating the signature of the tcp handshake acknowledgement packet.">
+ <figure anchor="figure_tcp_handshake_ack_sig" title="The wire format used for creating the signature of the tcp handshake acknowledgment message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -922,9 +968,9 @@ DeriveKID(MSK,SEQ):
</dd>
</dl>
<t>
- The initiating TCP communicator also replies with a TCP handshake acknowledgement packet after receiving
- a valid TCP handshake packet. Lastly, each party verifies both the signature and the challenge within the received
- TCP handshake acknowledgement packet, thus completing the handshake.
+ The initiating TCP communicator also replies with a TCP handshake acknowledgment message after receiving
+ a valid TCP handshake message. Lastly, each party verifies both the signature and the challenge within the received
+ TCP handshake acknowledgment message, thus completing the handshake.
</t>
</section>
<section anchor="tcp_KEM" numbered="true" toc="default">
@@ -972,9 +1018,9 @@ SetupCipher(MSK):
]]></artwork>
<t>
Note that the initiating TCP communicator can already perform the encapsulation step after generating the ephemeral
- key pair and immediately encrypt the TCP handshake packet before sending it. As soon as the receiving TCP communicator
+ key pair and immediately encrypt the TCP handshake message before sending it. As soon as the receiving TCP communicator
receives and decodes the ephemeral public key, it can perform the decapsulation step of the KEM and decrypt the
- following TCP handshake packet. The same applies for the TCP handshake packet send by the receiving TCP communicator.
+ following TCP handshake message. The same applies for the TCP handshake message send by the receiving TCP communicator.
</t>
<t>
Similarly to the usage of Elligator in the UDP communicator, it's important to note that in the TCP communicator, the
@@ -989,8 +1035,8 @@ SetupCipher(MSK):
<section anchor="tcp_message_exchange" numbered="true" toc="default">
<name>Message exchange</name>
<t>
- Once the handshake is completed actual payloads can be exchanged bi-directionally using TCP Box messages. A TCP Box message
- consists of a TCP Box packet as defined in <xref target="figure_tcp_box"/>, followed by the payload. Both parts are encrypted
+ Once the handshake is completed actual payloads can be exchanged bi-directionally using TCP BOX messages. A TCP Box message
+ consists of a TCP BOX message as defined in <xref target="figure_tcp_box"/>, followed by the payload. Both parts are encrypted
before being sent to the receiving peer.
</t>
<t>
@@ -1005,7 +1051,7 @@ SetupCipher(MSK):
<t>
(FIXME: hmac, MtE discussion, padding-oracle).
</t>
- <figure anchor="figure_tcp_box" title="The binary representation of the tcp box packet.">
+ <figure anchor="figure_tcp_box" title="The binary representation of the TCP BOX message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -1049,14 +1095,14 @@ SetupCipher(MSK):
one day, rekeying is set off anyway.
</t>
<t>
- The receiving communicator is signaled about a rekeying through the dispatch of a TCP Rekey packet as defined in
- <xref target="figure_tcp_rekey"/>. The packet <bcp14>MUST</bcp14> be encrypted with the current key. Due to the encryption of the packet,
+ The receiving communicator is signaled about a rekeying through the dispatch of a TCP Rekey message as defined in
+ <xref target="figure_tcp_rekey"/>. The message <bcp14>MUST</bcp14> be encrypted with the current key. Due to the encryption of the message,
the encoding of the new ephemeral public key with Elligator is not needed. Similarly to the initial handshake, the ephemeral public key
is used to perform a key exchange from which new key material for the encryption and authentication code scheme are derived. For further
- details please refer to <xref target="tcp_KEM"/>. Note that th reception of the TCP Rekey packet is not acknowledged by the receiver, so
- the sender might send new payload encrypted by the new key right after sending the packet.
+ details please refer to <xref target="tcp_KEM"/>. Note that they rekeying process doesn't involve an acknowledgment by the receiver of
+ a TCP Rekey message. So the sender might send new payload encrypted by the new key right after sending the TCP Rekey message.
</t>
- <figure anchor="figure_tcp_rekey" title="The binary representation of the TCP Rekey packet.">
+ <figure anchor="figure_tcp_rekey" title="The binary representation of the TCP Rekey message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24
+-----+-----+-----+-----+-----+-----+-----+-----+
@@ -1107,7 +1153,7 @@ SetupCipher(MSK):
</dd>
<dt>HASHCODE</dt>
<dd>
- A 256-bit HMAC-SHA512 hashcode of this TCP Rekey packet. The hashcode is
+ A 256-bit HMAC-SHA512 hashcode of this TCP Rekey message. The hashcode is
computed with the hashcode field initially set to zero and is inserted afterward.
</dd>
<dt>EPHEMERAL PUBLIC KEY</dt>
@@ -1125,7 +1171,7 @@ SetupCipher(MSK):
FIXME.
</dd>
</dl>
- <figure anchor="figure_tcp_rekey_sig" title="The wire format used for creating the signature of the TCP Rekey packet.">
+ <figure anchor="figure_tcp_rekey_sig" title="The wire format used for creating the signature of the TCP Rekey message.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
+-----+-----+-----+-----+-----+-----+-----+-----+