Internet-Draft | CORE Authenticated Key Exchange (CAKE) | November 2024 |
Schanzenbach | Expires 17 May 2025 | [Page] |
This document contains the GNUnet CORE AKE (CAKE).¶
This document defines the normative wire format of the protocol, cryptographic routines and security considerations for use by implementers.¶
This specification was developed outside the IETF and does not have IETF consensus. It is published here to inform readers about the function of GNUnet communicators, guide future implementations, and ensure interoperability including with the pre-existing GNUnet implementation.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 17 May 2025.¶
Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.¶
This specification was developed outside the IETF and does not have IETF consensus. It is published here to guide implementers of GNS and to ensure interoperability among implementations.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
While some of the terminology is explicitly re-defined here, the reader is expected to be familiar with TLS 1.3 ([RFC8446]), DTLS 1.3 ([RFC9147]) and HPKE ([RFC9180]).¶
The design rationale for CAKE is similar to DTLS 1.3 (cf. Section 3 of [RFC9147]). Except that CAKE does not consider Fragmentation as this is expected to be provided by the transport underlay layer of GNUnet.¶
This protocol is heavily inspired by [KEMTLS].¶
We assume that the peers have semi-static (as opposed to ephemeral) key pairs. Let (pkA,skA) be the key pair of peer PIDA and (pkB,skB) the key pair of peer PIDB.¶
For any secure handshake protocol, we have to dermine an initiator and a receiver in the protocol. We use GNUNET_CRYPTO_hash_cmp
to determine which peer is the receiver R and which peer the initiator I:¶
if (GNUNET_CRYPTO_hash_cmp (pk_A, pk_B)) { pk_I = pk_A pk_R = pk_B } else { pk_I = pk_B pk_R = pk_A }¶
It is possible that the designated initiator does not initiate the handshake. After a pre-determined timeout, the respective other peer may initiate.
We assume that the initiator knows pkR (pre-distributed through HELLO
, for example).¶
Below is a swimlane of the protocol messages. On the left and right side of the swimlanes the secrets known to the Initiator and Receiver are shown respectively. If a private key of a key pair is known it is implied that the public key is also known. Messages in brackets are optional. Messages in braces are encrypted with the key after "*".¶
Notice how we do not need any acknowledgement messages until after InitiatorFinished (after 1.5 RTT). The InitiatorHello message is a single flight that is implicitly ack'ed with ReceiverHello. ReceiverHello is a single flight that is implicitly ack'ed with InitiatorFinished. InitiatorFinished 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 Section 5.7 of [RFC9147] into a single message (ReceiverHello). Hence the only message that is sent without any expected response (and consequently requiring an explicit ACK) is InitiatorFinished (and KeyUpdate).¶
The Initiator creates the InitiatorHello message which includes the encrypted tuple (pkI,ServicesInfo). The fields are encrypted using a key derived from the ETS according to Figure 1 and Figure 2. The ReceiverKemChallenge is computed as:¶
R processes the InitiatorHello as follows:¶
The ETS, the Handshake and Master Secrets are generated according to Figure 2. Note that IATS cannot be derived (yet) at this point. R may now generate its ReceiverHello message:¶
I processes the message received by R:¶
At this point we have a secure channel.¶
Note that for the handshake we do not use epochs or sequence numbers. The reason for this is simple: DTLS uses epoch 0 for plaintext messages. Epoch 1 is reserved for payload encrypted with a key derived from ETS. However, we only have a single message that contains such a payload: InitiatorHello. Epoch 2 is reserved for payload encrypted with a key derived from *HTS. But we only have a single message that contains a payload encrypted with a key derived from RHTS: ReceiverHello. We also only have a single message that contains a payload encrypted with a key derived from AHTS: InitiatorFinished. Consequently, we do not need any signalling of Epochs until we encrypt data using *ATS secrets. The optional application data that may already be sent by the receiver after its first handshake message or by the initiator after its second handshake message, are already wrapped inside an EncryptedMessage and have both Epoch and sequence numbers set.¶
The key schedule is very similar to [RFC8446] Section 7.1:¶
When a traffic secret (*TS) is used to encrypt data, the respective encryption key and starting nonce is generated as follows:¶
After a successful initial handshake, both initiator and receiver may update the application traffic secrets ([A,I]ATS) and generate new keys. Let [I,R]ATS0 be the initial secrets with index 0. The next secret is derived as:¶
When a peer wants to update keys, it sends a key update message Section 6.10. Implementations SHOULD delete old traffic secrets and their derived keys.¶
This section is named and structured to mimic Section 5 of [RFC9147].¶
CAKE reuses the logic for timeout and retransmission from Section 5.8 of [RFC9147]. It differs in that large flight sizes are not of concern for CAKE. Similarly, the only Post-Handshake message relevant for CAKE is the KeyUpdate message.¶
Section 7.1 of [RFC8446] specifies that HKDF-Expand-Label uses a label prefix of "tls13 ". For CAKE, that label SHALL be "cake ". This ensures key separation between CAKE, DTLS 1.3 and TLS 1.3.¶
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.¶
The HandshakeFinished field contains either InitiatorFinished or ReceiverFinished value:¶
Any sent message starts with a MessageHeader
:¶
The possible types of messages are:¶
An encrypted message also always starts with a MessageHeader and the allowed types are:¶
The InitiatorHello:¶
The InitiatorKemChallenge is generated according to Figure 2 using:¶
The pkI and ServiceInfo
are encrypted using ChaCha20-Poly1305 [RFC8439]
with key and IV derived from the ETS.¶
The ReceiverHello:¶
The protected fields after the nonce are encrypted using a key derived from AHTS. They are not encrypted individually but as a single payload.¶
The InitiatorDone message contains the InitiatorFinished field encrypted with a key derived from the IHTS. The message type MUST be CORE_INITIATOR_DONE.¶
The EncryptedMessage follows a message header with type CORE_ENCRYPTED_MESSAGE
:¶
The epoch starts at 0 after the handshake with the first *ATS secret. The sequence number is encrypted with the output as defined in Section 4.2.3 of [RFC9147] 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 followed by encrypted application data. The length of the data is included in the size field of the MessageHeader preceeding the EncryptedMessage header.¶
The per-message nonce is not transmitted and instead generated as defined in Section 5.3 of [RFC8446].¶
The KeyUpdate message is a simple MessageHeader inside an EncryptedMessage with type CORE_KEY_UPDATE
followed by an UpdateRequested indicator.
This means that for every received EncryptedMessage
the peer MUST check if this is a KeyUpdate.
A KeyUpdate message indicates that the sender has switched its traffic secrets
according to the key schedule in Section 5.
If any bit in the UpdateRequested field is set, this means that the receiver
of the KeyUpdate MUST send its own KeyUpdate message.
Any bytes following the UpdateRequested field are updated ServicesInfo (Section 6.3).
ServicesInfo updates are optional.¶
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).¶
We must discuss EdDSA vs X25519 KEM usage. Maybe see Communicator draft for this.¶
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. We can get away with ChaCha20 (TLS, IETF) and its 32-bit internal counter because our messages are <= 216-1 bytes and the counter cannot overflow.¶
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. In such cases we may simply do both key exchanges. If both succeed, we drop the key exchange that was not initiated by the designated initiator on both peers. Otherwise we use the successful key exchange and the roles are swapped.¶
-¶