@ -502,11 +502,10 @@ The above rendezvous session is insecure, providing no confidentiality nor authe
even arbitrary network participants which possess the rendezvous session ID and server base URL.
To provide a secure channel on top of this insecure rendezvous session transport, we propose the following scheme.
This scheme is essentially [HPKE](https://www.rfc-editor.org/rfc/rfc9180) in [base
We use [HPKE](https://www.rfc-editor.org/rfc/rfc9180) in [base
mode](https://www.rfc-editor.org/rfc/rfc9180.html#name-hpke-modes) instantiated with X25519, HKDF-SHA256 for the KDF and
ChaCha20-Poly1305 (as specified by [RFC8439](https://datatracker.ietf.org/doc/html/rfc8439#section-2.8)) for the
authenticated encryption. Therefore, existing security analyses of HPKE are applicable in this setting too. Nevertheless
we include below a short description of our instantiation of HPKE and discuss some potential pitfalls and attacks.
authenticated encryption.
The primary limitation of HPKE in base mode is that there is no authentication for the initiating party (the one to send
the first payload; Device S in the text below). Thus the recipient party (the one to receive the first payload; Device G
@ -514,30 +513,23 @@ in the text below) has no assurance as to who actually sent the payload. In QR c
by exploiting the fact that both of these devices are physically present during the exchange and offloading the check
that they are both in the correct state to the user performing the QR code login process.
Additionally the HPKE RFC exclusively defines unidirectional encryption. The scheme found in the [Oblivious
Additionally the HPKE RFC exclusively defines unidirectional encryption. So, we use the scheme found in the [Oblivious
HTTP](https://www.rfc-editor.org/rfc/rfc9458) RFC under the [Encapsulation of
Responses](https://www.rfc-editor.org/rfc/rfc9458#name-encapsulation-of-responses) section is used to enable
bidirectional encryption in our chosen HPKE scheme.
Responses](https://www.rfc-editor.org/rfc/rfc9458#name-encapsulation-of-responses) section to enable
bidirectional encryption.
The existing security analyses of HPKE are applicable to our usage. We also discuss some potential pitfalls and attacks.
### Establishment
Participants:
- Device G (the device generating the QR code)
- Device S (the device scanning the QR code)
- Device G: the device generating the QR code
- Device S: the device scanning the QR code
Regardless of which device generates the QR code, either device can be the existing (already signed in) device. The
other device is then the new device (one seeking to be signed in).
Symmetric encryption uses a separate encryption key for each sender, both derived from a shared secret using HKDF.
Separate nonces are used for each direction of the communication channel. Device S will create a base nonce from the
shared secret, while Device G will create a new random base nonce.
As described by [HPKE](https://www.rfc-editor.org/rfc/rfc9180.html#section-5.2-7), each base nonce is mixed with a
monotonically-incrementing sequence number before being used as a per-message nonce. Devices initially set both sequence numbers to `0` and increment the corresponding
number by `1` for each message sent and received. The per-message nonce is is the result of XORing the base nonce with
the current sequence number, encoded as a big-endian integer of the same length as base nonce.
1. **Ephemeral key pair generation**
Both devices generate an _ephemeral_ Curve25519 key pair:
@ -572,49 +564,31 @@ At this point Device S should check that the received intent matches what the us
4. **Device S sends the initial payload**
Device S performs an ECDH operation using **Ss** and **Gp** to compute the ECDH shared secret **SharedSecret**. This
value is input to the HPKE key schedule, where it is first expanded into a common secret **Secret** using HKDF-SHA256.
After this step, **Ss** is discarded.
Device S performs an ECDH operation using **Ss** and **Gp** to compute the shared secret **SharedSecret**.
From this common **Secret**, the HPKE key schedule derives the following values:
The **SharedSecret** is then used to initialize an