lsd0012

LSD0012: CORE Authenticated Key Exchange (CAKE)
Log | Files | Refs

commit 1253010f83b1935e4681d9f9310b19311395ac62
parent 4139a9af86f95735d9ccc7acff7d7b4b5a88fdde
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Fri,  1 Aug 2025 13:04:36 +0200

some implementation updates

Diffstat:
Mdraft-schanzen-cake.xml | 101++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 64 insertions(+), 37 deletions(-)

diff --git a/draft-schanzen-cake.xml b/draft-schanzen-cake.xml @@ -144,7 +144,7 @@ <dt>H(D):</dt> <dd>A 512-bit hash over D. The hash function is TBD (Blake2b or SHA-512).</dd> <dt>T(M):</dt> <dd>means the transcript as a concatenation of received/sent messages starting from and including the InitiatorHello pk_e until and including M. Note that the transcript refers to everything that is seen on the wire, including potentially encrypted messages or fields and metadata.</dd> <dt>'{}K'</dt> <dd>indicates encryption with a handshake traffic key K and a modified <xref target="RFC8439"/>, the XChaCha20-Poly1305 Authenticated Encryption with Associated Data (AEAD) construction.</dd> - <dt>'[]K'</dt> <dd>indicates encryption with an application traffic key K and a modified <xref target="RFC8439"/>, the XChaCha20-Poly1305 Authenticated Encryption with Associated Data (AEAD) construction.</dd> + <dt>'[]K'</dt> <dd>indicates encryption with an application traffic key K using the XChaCha20-Poly1305 Authenticated Encryption with Associated Data (AEAD) construction.</dd> </dl> </section> <section anchor="rationale" numbered="true" toc="default"> @@ -219,12 +219,12 @@ ss_R | | | | ss_R | | ss_I | | ss_e - | ResponderHello: | + | ResponderHello: | | c_e | | r_R | | {svcinfo_R,c_I}RHTS | - | {finished_R}RHTS | - | *[Application Payload]RATS | + | {finished_R}RHTS | + | [ACK]RATS | |<----------------------------------------------+ r_R | | c_I | | @@ -232,8 +232,8 @@ c_e | | ss_I | | ss_e | | | InitiatorDone: | - | {finished_I}IHTS | - | *[Application Payload]IATS | + | {finished_I}IHTS | + | [ACK]IATS | +---------------------------------------------->| | | | | @@ -246,14 +246,12 @@ ss_e | | ]]></artwork> </figure> <t> - Notice how we do not need any acknowledgement messages until after finished<sub>I</sub> (after 1.5 RTT). + Notice how we do not need any acknowledgement messages until after finished<sub>R</sub> (after 1 RTT). + We use the ACKs in the handshake as explicit key confirmations. The InitiatorHello message is a single flight that is implicitly ack'ed with ResponderHello. ResponderHello is a single flight that is implicitly ack'ed with finished<sub>I</sub>. - finished<sub>I</sub> requires an explicit ack; at this time R and I have already established a secure channel - and R can use an EncryptedMessage to send the ack. The reason why this works is because CAKE groups the messages in row 3 of Table 1 in <xref target="RFC9147" section="5.7"/> into a single message (ResponderHello). - Hence the only message that is sent without any expected response (and consequently requiring an explicit - ACK) is finished<sub>I</sub> (and KeyUpdate). + Hence the only message that is sent without any expected response (and consequently requiring an explicit ACK) is finished<sub>I</sub> (and Heartbeats). N<sub>I</sub> is a nonce generated by the initiator. N<sub>R</sub> is a nonce generated by the responder. </t> @@ -417,7 +415,7 @@ nonce = HKDF-Expand-Label ([I,R][A,H]TS, "iv", 24) ]]></artwork> </figure> <t> - When a peer wants to update keys, it sends a key update message <xref target="key_update_msg"/>. + When a peer wants to update keys, it sends a key update message <xref target="heartbeat_msg"/>. Implementations <bcp14>SHOULD</bcp14> delete old traffic secrets and their derived keys. </t> </section> @@ -584,9 +582,9 @@ nonce = HKDF-Expand-Label ([I,R][A,H]TS, "iv", 24) <artwork name="" type="" align="left" alt=""><![CDATA[ 0 8 16 24 32 40 48 56 +-----+-----+-----+-----+-----+-----+-----+-----+ -| Epoch | Sequence Number | +| Epoch | +-----+-----+-----+-----+-----+-----+-----+-----+ -| Timestamp | +| Sequence Number | +-----+-----+-----+-----+-----+-----+-----+-----+ | Tag | | | @@ -595,19 +593,49 @@ nonce = HKDF-Expand-Label ([I,R][A,H]TS, "iv", 24) </figure> <t> The epoch starts at 0 after the handshake with the first *ATS secret. - The sequence number is encrypted with the output as defined in <xref target="RFC9147" section="4.2.3"/> + Any peer may at any time update to a new epoch. + Peers may keep a history of secrets for respective epochs at their own discretion in + order to handle out-of-order message deliveries. + Unlike DTLS1.3 in CAKE does not truncate the epoch and no reconstruction is + necessary, hence the epoch may be bumped by peers at their own discretion without + explicit key update mechanisms. + A peer may consider the epoch too old or too far in the future and reject description. + For this purpose, a peer may manage a sliding window of epochs that can be used + by the other peer. + </t> + <t> + The sequence number is encrypted as defined in <xref target="RFC9147" section="4.2.3"/> for ChaCha20-based AEAD schemes. For clarity, the XOR-based encryption using the 64 byte output of ChaCha20 is as follows: - The sequence number is padded to the left such that it is exactly 8 bytes (as if the Epoch field - was still present). - Then, the first 8 bytes of the output of ChaCha20 are XORed with the resulting byte string. - The first 16 bits can be ignored (zeroed). - Note that an implementation may simply XOR the first 8 byte of the EncryptedMessage. - However, this will include the Epoch field and whatever value it was set to so after - the XOR this value will have to be reconstructed or otherwise masked beforehand. + The Tag is divided into a 32-bit counter and 96-bit nonce for use with ChaCha20. + The key is derived from the *ats as follows: </t> + <figure anchor="figure_sn_key_derivation" title="Traffic Key Generation."> + <artwork name="" type="" align="left" alt=""><![CDATA[ +sn_secret = HKDF-Expand-Label [I,R]ATS_N, "sn", 32) + ]]></artwork> + </figure> <t> - The tag is followed by encrypted application data. + Where [I,R]ATS_N is the respective ATS secret of epoch N. + The leading 8 bytes of the 64 byte output of ChaCha20 are then + XORed with the sequence number in network byte order: + </t> + <figure anchor="figure_sn_xor" title="Traffic Key Generation."> + <artwork name="" type="" align="left" alt=""><![CDATA[ +sn_key = HKDF-Expand-Label(Secret, "sn", "", 8) +mask = ChaCha20(sn_key, Ciphertext[0..3], Ciphertext[4..15]) +sn_enc = mask[0..8] XOR sn_nbo + ]]></artwork> + </figure> + <t> + Notice how this requires a ciphertext of at least 16 bytes. + But our ciphertexts are always at least 16 bytes due to the Poly1305 + atuthentication tag. In fact, since the authentication tag is considered + part of the ciphertext, and is prepended in front of the encrypted plaintext, + the mask is always computed on the authentication tag only. + </t> + <t> + The Tag is followed by encrypted application data. The length of the data is included in the size field of the MessageHeader preceeding the EncryptedMessage header. </t> @@ -616,17 +644,16 @@ nonce = HKDF-Expand-Label ([I,R][A,H]TS, "iv", 24) <!-- FIXME the records/encryptions apply to all messages(?)--> </t> </section> - <section anchor="key_update_msg" numbered="true" toc="default"> - <name>KeyUpdate</name> + <section anchor="heartbeat_msg" numbered="true" toc="default"> + <name>Heartbeat</name> <t> - The KeyUpdate message is a simple MessageHeader inside an EncryptedMessage with type <tt>CORE_KEY_UPDATE</tt> - followed by an UpdateRequested indicator. + The HEARTBEAT message is a simple MessageHeader inside an EncryptedMessage with type <tt>CORE_HEARTBEAT</tt> followed by an UpdateRequested indicator. This means that for every received EncryptedMessage - the peer <bcp14>MUST</bcp14> check if this is a KeyUpdate. - A KeyUpdate message indicates that the sender has switched its traffic secrets - according to the key schedule in <xref target="key_schedule"/>. + the peer <bcp14>MUST</bcp14> check if this is a Heartbeat. + A Heartbeat message may implicitlyindicate that the sender has switched its + traffic secrets according to the key schedule in <xref target="key_schedule"/>. If any bit in the UpdateRequested field is set, this means that the responder - of the KeyUpdate <bcp14>MUST</bcp14> send its own KeyUpdate message. + of the Heartbeat <bcp14>SHOULD</bcp14> increment its epoch. Any bytes following the UpdateRequested field are updated services info svcinfo (<xref target="svcinfo"/>). Services info updates are optional. @@ -646,18 +673,18 @@ nonce = HKDF-Expand-Label ([I,R][A,H]TS, "iv", 24) <section anchor="ack_msg" numbered="true" toc="default"> <name>ACK</name> <t> - The ACK message: See <xref target="RFC9147" section="7"/>. + The ACK message is a simple MessageHeader inside an EncryptedMessage with + type <tt>CORE_ACK</tt>. + This means that for every received EncryptedMessage + the peer <bcp14>MUST</bcp14> check if this is an ACK message after decryption. + The peer may use the ACK in order to ensure liveliness of connected peers in + combination with Heartbeats. </t> </section> </section> <section anchor="open" numbered="true" toc="default"> <name>Open Issues</name> <t> - We must include ACK handling. In general we need to take a look at DTLS and port - whatever it does to ensure failure tolerance with out-of-order and unreliable transmissions. - This includes ACKs as well as retransmission (timers). - </t> - <t> We must discuss EdDSA vs X25519 KEM usage. Maybe see Communicator draft for this. </t> <t>