commit 29f4ab60c50f15e058728f37f2b6709c36100a2d
parent 4c33a7046b740466c62055188588264d8188c7ed
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Tue, 12 Nov 2024 07:06:25 +0100
cleanup
Diffstat:
1 file changed, 121 insertions(+), 101 deletions(-)
diff --git a/draft-schanzen-cake.xml b/draft-schanzen-cake.xml
@@ -131,8 +131,8 @@
this document.
</t>
</section>
- <section anchor="handshake" numbered="true" toc="default">
- <name>Handshake protocol</name>
+ <section anchor="protocol_flow" numbered="true" toc="default">
+ <name>Protocol Flow</name>
<t>
This protocol is heavily inspired by <xref target="KEMTLS"/>.
</t>
@@ -177,7 +177,7 @@ sk_e | |
ES,ETS | |
| |
| InitiatorHello |
- | (InitiatorCert)*ETS |
+ | (pk_I,ServicesInfo)*ETS |
+---------------------------------------------->|
| | pk_I
| | ES,ETS
@@ -187,7 +187,7 @@ ES,ETS | |
| | [I,R]HTS
| | RATS
| ReceiverHello |
- | (ReceiverCert)*RHTS |
+ | (ServicesInfo)*RHTS |
| (ReceiverKemCiphertext)*RTHS |
| (ReceiverFinished)*RHTS |
| [(Application Payload)*RATS] |
@@ -214,7 +214,63 @@ MS | |
]]></artwork>
</figure>
<t>
- Expectedly, the key schedule is very similar to <xref target="RFC8446"/> Section 7.1:
+ The Initiator creates the messages according to <xref target="figure_swimlane"/> and <xref target="figure_key_schedule"/> using:
+ </t>
+ <ol>
+ <li>(ss<sub>R</sub>,c<sub>R</sub>) <- Encaps(pk<sub>R</sub>)</li>
+ </ol>
+ <t>
+ pk<sub>I</sub> and <tt>ServicesInfo</tt> are encrypted using the early secret ETS
+ using XChaCha20-Poly1305 (citation to IETF RFC).
+ <!-- FIXME: Discuss IV. We may be able to use data from HKDF-Expand for that -->
+ </t>
+ <t>
+ R receives the first message, and processes it as defined in the following
+ to create and send the second message.
+ </t>
+ <t>
+ The encryption key ETS to decrypt the encrypted (pk<sub>I</sub>,<tt>ServicesInfo</tt>), the Handshake and Master Secrets are generated according to <xref target="figure_key_schedule"/> using:
+ </t>
+ <ol>
+ <li>(ss<sub>R</sub>,c<sub>R</sub>) <- Decaps(sk<sub>R</sub>, c<sub>R</sub>)</li>
+ <li>(ss<sub>e</sub>,c<sub>e</sub>) <- Encaps(pk<sub>e</sub>)</li>
+ <li>(ss<sub>I</sub>,c<sub>I</sub>) <- Encaps(pk<sub>I</sub>)</li>
+ </ol>
+ <t>
+ The secrets can also be generated as-needed and not necessarily all at once.
+ Note that IATS cannot be derived (yet) at this point.
+ </t>
+ <t>
+ Build ReceiverFinished message:
+ </t>
+ <ol>
+ <li>fk<sub>R</sub> <- HKDF-Expand(MS, "r finished", NULL)</li>
+ <li>RF <- HMAC(fk<sub>R</sub>, InitiatorHello...ReceiverKemCiphertext)</li>
+ <li>ReceiverFinished <- Enc(RHTS, RF) (TLS1.3-style explicit authentication of receiver after 1RTT!)</li>
+ </ol>
+ <t>
+ R sends to I the third message consisting of a <tt>MessageHeader</tt>,
+ the <tt>InitiatorFinished</tt> message as defined
+ in the following.
+ </t>
+ <ol>
+ <li>Verify that the message type is TBD</li>
+ <li>Setup remaining keys using ss<sub>e</sub> <- Decaps(sk<sub>e</sub>,c<sub>e</sub>).</li>
+ <li>fk<sub>I</sub> <- HKDF-Expand(MS, "i finished", NULL)</li>
+ <li>IF <- HMAC(fk<sub>I</sub>, InitiatorHello...ReceiverFinished)</li>
+ <li>fk<sub>R</sub> <- HKDF-Expand(MS, "r finished", NULL)</li>
+ <li>RF <- Dec(RHTS, ReceiverFinished)</li>
+ <li>assert HMAC(fk<sub>R</sub>, InitiatorHello...ReceiverKemCiphertext) == RF</li>
+ <li>InitiatorFinished <- Enc(IHTS, IF)</li>
+ </ol>
+ <t>
+ At this point we have a secure channel.
+ </t>
+ </section>
+ <section anchor="key_schedule" numbered="true" toc="default">
+ <name>Key Schedule</name>
+ <t>
+ The key schedule is very similar to <xref target="RFC8446"/> Section 7.1:
</t>
<figure anchor="figure_key_schedule" title="The Key Schedule.">
<artwork name="" type="" align="left" alt=""><![CDATA[
@@ -253,26 +309,15 @@ ss_I -> HKDF-Extract = Master Secret (MS)
InitiatorHello...ReceiverFinished)
= RATS
]]></artwork>
- </figure>
- <section anchor="first_message" numbered="true" toc="default">
- <name>First Message</name>
+ </figure>
+ </section>
+ <section anchor="wire_formats" numbered="true" toc="default">
+ <name>Wire Formats</name>
+ <section anchor="message_hdr" numbered="true" toc="default">
+ <name>Message Header</name>
<t>
- I sends to R the <tt>FirstMessage</tt> consisting of a <tt>MessageHeader</tt>,
- the <tt>InitiatorHello</tt> and the encrypted <tt>InitiatorCertificate</tt> as defined
- in the following.
+ Any sent message is prepended with a <tt>MessageHeader</tt>:
</t>
- <figure anchor="figure_first_msg" title="The Wire Format of the FirstMessage.">
- <artwork name="" type="" align="left" alt=""><![CDATA[
- 0 8 16 24 32 40 48 56
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | MessageHeader |
- +-----+-----+-----+-----+-----+-----+-----+-----+
- / InitiatorHello /
- +-----+-----+-----+-----+-----+-----+-----+-----+
- / Encrypted InitiatorCertificate /
- +-----+-----+-----+-----+-----+-----+-----+-----+
- ]]></artwork>
- </figure>
<figure anchor="figure_msghdr" title="The Wire Format of the Message Header.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
@@ -281,6 +326,12 @@ ss_I -> HKDF-Extract = Master Secret (MS)
+-----+-----+-----+-----+-----+-----+-----+-----+
]]></artwork>
</figure>
+ </section>
+ <section anchor="initiator_hello" numbered="true" toc="default">
+ <name>InitiatorHello</name>
+ <t>
+ The InitiatorHello:
+ </t>
<figure anchor="figure_inithello" title="The Wire Format of the InitiatorHello.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
@@ -289,110 +340,72 @@ ss_I -> HKDF-Extract = Master Secret (MS)
| |
| |
+-----+-----+-----+-----+-----+-----+-----+-----+
- | PeerID Hash (512 bit) |
- / /
- | |
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | Nonce |
- +-----+-----+-----+-----+-----+-----+-----+-----+
- ]]></artwork>
- </figure>
- <figure anchor="figure_initcert" title="The Wire Format of the plaintext of the InitiatorCertificate.">
- <artwork name="" type="" align="left" alt=""><![CDATA[
- 0 8 16 24 32 40 48 56
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | PeerID |
+ | KemCiphertext |
| |
| |
+-----+-----+-----+-----+-----+-----+-----+-----+
- | ServicesString |
- / /
+ | ReceiverPeerID Hash (512 bit) |
/ /
+ | |
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ | Nonce |
+-----+-----+-----+-----+-----+-----+-----+-----+
]]></artwork>
</figure>
<t>
- The encryption key ETS is generated according to <xref target="figure_key_schedule"/> using:
+ The KemCiphertext is generated according to <xref target="figure_key_schedule"/> using:
</t>
<ol>
<li>(ss<sub>R</sub>,c<sub>R</sub>) <- Encaps(pk<sub>R</sub>)</li>
</ol>
<t>
- The <tt>InitiatorCert</tt> is encrypted using XChaCha20-Poly1305 (citation to IETF RFC).
+ The pk<sub>I</sub> and <tt>ServiceInfo</tt> are encrypted using XChaCha20-Poly1305 (citation to IETF RFC).
<!-- FIXME: Discuss IV. We may be able to use data from HKDF-Expand for that -->
</t>
- </section>
- <section anchor="second_message" numbered="true" toc="default">
- <name>Second Message</name>
+ </section>
+ <section anchor="svcinfo" numbered="true" toc="default">
+ <name>ServicesInfo</name>
<t>
- R receives the <tt>FirstMessage</tt>, and processes it as defined in the following
- to create and send the <tt>SecondMessage</tt>.
+ The ServicesInfo is a string consisting of key-value pairs separated by
+ a separator indicating supported services and their versions.
+ E.g. "dht:1.1;cadet:0.4".
+ The ServicesInfo is zero terminated.
</t>
- <figure anchor="figure_second_msg" title="The Wire Format of the SecondMessage.">
+ </section>
+ <section anchor="receiver_hello" numbered="true" toc="default">
+ <name>ReceiverHello</name>
+ <t>
+ The ReceiverHello:
+ </t>
+ <figure anchor="figure_recvhello" title="The Wire Format of the ReceiverHello.">
<artwork name="" type="" align="left" alt=""><![CDATA[
0 8 16 24 32 40 48 56
+-----+-----+-----+-----+-----+-----+-----+-----+
- | MessageHeader |
- +-----+-----+-----+-----+-----+-----+-----+-----+
- / ReceiverHello /
- +-----+-----+-----+-----+-----+-----+-----+-----+
- / Encrypted ServicesString /
- +-----+-----+-----+-----+-----+-----+-----+-----+
- / ReceiverKemCiphertext /
+ | KemCiphertext |
+ | |
+ | |
+-----+-----+-----+-----+-----+-----+-----+-----+
- / ReceiverFinished /
+ | Nonce |
+-----+-----+-----+-----+-----+-----+-----+-----+
]]></artwork>
</figure>
+ </section>
+ <section anchor="receiver_finished" numbered="true" toc="default">
+ <name>ReceiverFinished</name>
<t>
- The encryption key ETS to decrypt the encrypted <tt>IntiatorCertificate</tt>, the Handshake and Master Secrets are generated according to <xref target="figure_key_schedule"/> using:
- </t>
- <ol>
- <li>(ss<sub>R</sub>,c<sub>R</sub>) <- Decaps(sk<sub>R</sub>, c<sub>R</sub>)</li>
- <li>(ss<sub>e</sub>,c<sub>e</sub>) <- Encaps(pk<sub>e</sub>)</li>
- <li>(ss<sub>I</sub>,c<sub>I</sub>) <- Encaps(pk<sub>I</sub>)</li>
- </ol>
- <t>
- The secrets can also be generated as-needed and not necessarily all at once.
- Note that IATS cannot be derived (yet) at this point.
+ The ReceiverFinished:
</t>
- <t>
- ReceiverHello and ReceiverKemCiphertext:
- </t>
- <ol>
- <li>ReceiverHello <- (c<sub>e</sub>, r<sub>R</sub>, [SelectedAlgs])</li>
- <li>ReceiverKemCiphertext <- Enc(RHTS, c<sub>I</sub>)</li>
- </ol>
- <t>
- Build ReceiverFinished message:
- </t>
- <ol>
- <li>fk<sub>R</sub> <- HKDF-Expand(MS, "r finished", NULL)</li>
- <li>RF <- HMAC(fk<sub>R</sub>, InitiatorHello...ReceiverKemCiphertext)</li>
- <li>ReceiverFinished <- Enc(RHTS, RF) (TLS1.3-style explicit authentication of receiver after 1RTT!)</li>
- </ol>
- </section>
- <section anchor="third_message" numbered="true" toc="default">
- <name>Third Message</name>
- <t>
- R sends to I the third message consisting of a <tt>MessageHeader</tt>,
- the <tt>InitiatorFinished</tt> message as defined
- in the following.
- </t>
- <ol>
- <li>Verify that the message type is TBD</li>
- <li>Setup remaining keys using ss<sub>e</sub> <- Decaps(sk<sub>e</sub>,c<sub>e</sub>).</li>
- <li>fk<sub>I</sub> <- HKDF-Expand(MS, "i finished", NULL)</li>
- <li>IF <- HMAC(fk<sub>I</sub>, InitiatorHello...ReceiverFinished)</li>
- <li>fk<sub>R</sub> <- HKDF-Expand(MS, "r finished", NULL)</li>
- <li>RF <- Dec(RHTS, ReceiverFinished)</li>
- <li>assert HMAC(fk<sub>R</sub>, InitiatorHello...ReceiverKemCiphertext) == RF</li>
- <li>InitiatorFinished <- Enc(IHTS, IF)</li>
- </ol>
- <t>
- At this point we have a secure channel.
- </t>
- </section>
+ <figure anchor="figure_recvfinished" title="The Wire Format of the ReceiverFinished.">
+ <artwork name="" type="" align="left" alt=""><![CDATA[
+ 0 8 16 24 32 40 48 56
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ | ReceiverFinished |
+ | |
+ | |
+ +-----+-----+-----+-----+-----+-----+-----+-----+
+ ]]></artwork>
+ </figure>
+ </section>
</section>
<section anchor="open" numbered="true" toc="default">
<name>Open Issues</name>
@@ -400,6 +413,13 @@ ss_I -> HKDF-Extract = Master Secret (MS)
Rekey
</t>
<t>
+ We must discuss ChaCha20 vs XChaCha20.
+ For XChaCha20 (currently implemented) we can use fresh nonces when the key is re-used.
+ With ChaCha20, we should increment the nonce.
+ We could probably increment both. Incrementing may allow us to derive a starting nonce from
+ the key schedule.
+ </t>
+ <t>
The Initiator/Receiver selection logic may require a timed fallback: The designates Initiator may never initiate (NAT, already has sufficient connections, learns about receiver later than receiver about initiator etc.).
This may result in edge cases where the Initiator initiates a handshake and the Receiver also initiates a handshake at the same time switching roles.