commit 9654deac5a462a63a5423d652ff1d670499b332f
parent 86878e4b8806d8b3786081f27149f517e6d66c62
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Mon, 11 Nov 2024 15:10:49 +0100
More details on the CAKE
Diffstat:
1 file changed, 123 insertions(+), 21 deletions(-)
diff --git a/developers/apis/cong.rst b/developers/apis/cong.rst
@@ -145,32 +145,102 @@ Handshake Protocol (Draft)
The initiator selection remains unchanged from the above protocol.
-``I`` calculates:
+
+
+First Message (RTT=0):
+======================
+
+``I`` sends to ``R`` the following message:
+
+``MessageHeader||InitiatorHello||EncryptedInitiatorCert``
+
+where:
+
+``MessageHeader`` is a ``GNUNET_MessageHeader`` of type *TBD* (GANA registration).
+
+The ``InitiatorHello`` consists of:
+
+* (pk\ :sub:`e`, c\ :sub:`R`, SHA512(pk\ :sub:`R`), r\ :sub:`I`, [SupportedAlgs,Version])
+
+r\ :sub:`I` is nonce value (256 or 512 bit TBD).
+pk\ :sub:`e` is the public key from a freshly generated ephemeral key pair:
* (pk\ :sub:`e`,sk\ :sub:`e`) <- *KeyGen*\ ()
+
+In GNUnet this ``KeyGen`` corresponds to ``GNUNET_CRYPTO_ecdhe_key_create()``. This is a X25519 key pair.
+The ``InitiatorHello`` may contain our version and other metadata which
+is indicated by the brackets. But, we may want to put this information into the ``cert`` below, as this is encrypted
+(identity hiding).
+
+The ``EncryptedInitiatorCert`` is created as
+
+* *Enc*\ (**ETS**, cert [pk\ :sub:`I`])
+
+We may encode the capabilities/supported class in ``cert``.
+We do not want to use X.509 here, probably. ``cert`` is just a placeholder for the
+signed metadata (e.g. supported services string) and pk\ :sub:`I`.
+
+.. admonition:: Certificate definition
+
+ The definition of certificate is incomplete.
+ For now, we only use self-signed certificates: The cert is signed using sk\ :sub:`I`. Use ``GNUNET_CRYPTO_eddsa_sign`` API for this.
+
+
+.. admonition:: Supported services string
+
+ Supported services are just a series of *service*:*version* strings
+ separated by a separator. We may want to use libtool versioning?
+
+*Enc* is XChaCha20-Poly1305 (IETF version).
+To derive **ETS** we create our first shared secret as:
+
* (ss\ :sub:`R`,c\ :sub:`R`) <- *Encaps*\ (pk\ :sub:`R`)
+
+pk\ :sub:`R` is the EdDSA public key of the peer we want to connect to.
+We should have received this as part of the trigger for this message.
+In GNUnet, ``Encaps`` corresponds to ``GNUNET_CRYPTO_eddsa_kem_encaps``.
+
+.. admonition:: X25519 vs EdDSA
+ Notice how X25519 and EdDSA keys are different. Accordingly, different/additional KEM implementations may be required in this handshake, but here the EdDSA version is correct.
+
+We then derive our encryption keys:
+
* **ES** <- *HKDF-Extract*\ (ss\ :sub:`R`, 0)
-* ``InitiatorHello`` <- (pk\ :sub:`e`, c\ :sub:`R`, H(pk\ :sub:`R`), r\ :sub:`I`, [SupportedAlgs,Services,Version])
* **ETS** <- *HKDF-Expand*\ (**ES**, ``"early data"``, ``InitiatorHello``)
-* ``InitiatorCert`` <- *Enc*\ (**ETS**, cert [pk\ :sub:`I`])
-.. admonition:: ``I`` sends to ``R``
+and encrypt the certificate giving us the ``EncryptedInitiatorCert``.
- ``InitiatorHello``, ``InitiatorCert``
-.. note:: We may encode the typemap and capabilities/supported class in ``InitiatorCert``'s cert. We do not want to use X.509 here, probably.
+Second Message (RTT=0.5)
+========================
-``R`` calculates:
+``R`` the receives:
+
+``MessageHeader||InitiatorHello||EncryptedInitiatorCert``
+
+and sends to ``I`` the following message:
+
+``MessageHeader||ReceiverHello||EncryptedExtensions||ReceiverKemCiphertext||ReceiverFinished``
+
+The message may have already application payload appended, but in our case this is unlikely.
+
+First ``R`` processes the message received from ``I``:
-* Decrypt ``InitiatorCert``:
+* Verify that the message type is *TBD*
+
+* Decrypt ``EncryptedInitiatorCert`` (cf. encryption above):
* (ss\ :sub:`R`) <- Decaps(sk\ :sub:`R`, c\ :sub:`R`)
* **ES** <- *HKDF-Extract*\ (ss\ :sub:`R`, 0)
* **ETS** <- *HKDF-Expand*\ (**ES**, "early data", ``InitiatorHello``)
- * cert [pk\ :sub:`I`] <- *Dec*\ (**ETS**, ``InitiatorCert``)
+ * cert [pk\ :sub:`I`] <- *Dec*\ (**ETS**, ``EncryptedInitiatorCert``)
+
+.. admonition:: Encaps X25519
+
+ Here, ``Decaps`` corresponds to ``GNUNET_CRYPTO_eddsa_kem_decaps``.
-* Setup Master Secret:
+* Setup Handshake and Master Secrets (these can also be done as-needed and not necessarily all at once here):
* **dES** <- *HKDF-Expand*\ (**ES**, "derived", ``NULL``)
* (ss\ :sub:`e`,c\ :sub:`e`) <- *Encaps*\ (pk\ :sub:`e`)
@@ -179,6 +249,10 @@ The initiator selection remains unchanged from the above protocol.
* (ss\ :sub:`I`,c\ :sub:`I`) <- ``Encaps``\ (pk\ :sub:`I`)
* **MS** <- *HKDF-Extract*\ (ss\ :sub:`I`, **dHS**)
+.. admonition:: Encaps X25519
+
+ Here, ``Encaps`` corresponds to ``GNUNET_CRYPTO_hpke_kem_encaps``.
+
* Derive Handshake Traffic Encryption Keys:
* ``ReceiverHello`` <- (c\ :sub:`e`, r\ :sub:`R`, [SelectedAlgs])
@@ -198,24 +272,35 @@ The initiator selection remains unchanged from the above protocol.
* **RATS** <- *HKDF-Expand*\ (**MS**, "r ap traffic", ``InitiatorHello...ReceiverFinished``)
+Third Message (RTT=1.5)
+=======================
+
+``I`` receives:
+
+``MessageHeader||ReceiverHello||EncryptedExtensions||ReceiverKemCiphertext||ReceiverFinished``
-.. admonition:: ``R`` sends to ``I`` (0.5 RTT):
+and sends to ``I`` the following message:
- ``ReceiverHello``, ``EncryptedExtensions``, ``ReceiverKemCiphertext``, ``ReceiverFinished`` and optionally application payload encrypted using **RATS**.
+``MessageHeader||IteratorFinished``
-``I`` computes:
+The message may have already application payload appended, but in our case this again is unlikely.
-* Setup Master Secret:
+First ``I`` processes the message received from ``R``:
+
+* Verify that the message type is *TBD*
+
+* Setup Master Secret (cf. derivation in Second Message):
+
+ * (ss\ :sub:`e`) <- *Decaps*\ (sk\ :sub:`e`, c\ :sub:`e`) (X25519 KEM)
- * (ss\ :sub:`e`) <- *Decaps*\ (sk\ :sub:`e`, c\ :sub:`e`)
* **dES** <- *HKDF-Expand*\ (**ES**, ``"derived"``, ``NULL``)
* **HS** <- *HKDF-Extract*\ (ss\ :sub:`e`, **dES**)
* **dHS** <- *HKDF-Expand*\ (**HS**, "derived", ``NULL``)
- * (ss\ :sub:`I`) <- *Decaps*\ (sk\ :sub:`I`, c\ :sub:`I`)
+ * (ss\ :sub:`I`) <- *Decaps*\ (sk\ :sub:`I`, c\ :sub:`I`) (EdDSA KEM)
* **MS** <- *HKDF-Extract*\ (ss\ :sub:`I`, **dHS**)
-* Derive Traffic Encryption Keys:
+* Derive Traffic Encryption Keys (these can also be done as-needed and not necessarily all at once here):
* **IHTS** <- *HKDF-Expand*\ (**HS**, "i hs traffic", ``InitiatorHello...ReceiverHello``)
* **RHTS** <- *HKDF-Expand*\ (**HS**, "r hs traffic", ``InitiatorHello...ReceiverHello``)
@@ -232,11 +317,11 @@ The initiator selection remains unchanged from the above protocol.
* ``InitiatorFinished`` <- *Enc*\ (**IHTS**, ``IF``)
-.. admonition:: ``I`` sends to ``R`` (1.5 RTT):
- ``InitiatorFinished`` and optionally application payload encrypted using **IATS**. ``I`` can now decrypt received payload using **RATS**.
+Confirmation (RTT=1.5)
+======================
-``R`` computes:
+``R`` receives ``IteratorFinished`` and computes:
* ``IF`` <- *Dec*\ (IHTS, ``InitiatorFinished``)
* fk\ :sub:`I` <- *HKDF-Expand*\ (**MS**, "i finished", ``NULL``)
@@ -244,7 +329,24 @@ The initiator selection remains unchanged from the above protocol.
* **IATS** <- *HKDF-Expand*\ (**MS**, "i ap traffic", ``InitiatorHello...InitiatorFinished``)
-Glossary:
+At this point we have a secure channel and application payload can be en/decrypted using **IATS** and **RATS**, respectively.
+
+Rekey / Service Status change
+=============================
+
+TODO
+
+
+Edge Cases
+==========
+
+* 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.
+
+
+Glossary
+========
* **IATS**: Initiator Application Traffic Secret Key
* **RATS**: Receiver Application Traffic Secret Key