[noise] Negotiation and 0-RTT

Alexey Ermishkin scratch.net at gmail.com
Fri Jul 7 12:24:58 PDT 2017

Seems reasonable, lgtm. However we might expect some servers just to drop connections instead of explaining anything

-----Original Message-----
From: Trevor Perrin [mailto:trevp at trevp.net] 
Sent: Friday, July 7, 2017 10:36 PM
To: Alexey Ermishkin <scratch.net at gmail.com>
Cc: noise <noise at moderncrypto.org>
Subject: Re: [noise] Negotiation and 0-RTT

I'm wondering if we could better support a couple cases:

 * Client attempts a 0-RTT handshake, but the server doesn't recognize the client_version, so can't read the ephemeral and attempt a fallback.  For example, maybe you're rolling out 0-RTT support across your fleet of servers, and the client hits a server that isn't updated yet.

 * Client supports several different DH choices, but doesn't want to generate and send several DH ephemerals in the initial message.

In both cases it might be helpful if the server could request the client to retry the initial request, and optionally send some negotiation data to help the client choose a better initial protocol.
It would also be good if this happened as part of a single handshake, so we could hash everything into the transcript and prevent attackers from forging retry requests.

One idea would be to allow server_version = 0xFFFFFFFF to signal negotiation failure / retry request: the server keeps the connection open, and the client can send a second initial message.  All of this data is added to the transcript, for prologue purposes.

To make this more useful we could add negotiation_data into the server's first response message, making it symmetrical with the client's initial message:

Message1 and Message2 header:
 - 4 bytes: version
 - 2 bytes: negotiation_len
 - " bytes: negotiation_data
 - 2 bytes: noise_message_len
 - " bytes: noise_message

If server_version == client_version, then the server's negotiation_data must be empty (since there's no fallback protocol here, it might not be convenient to hash the server_version into the prologue, e.g. if the client used 0-RTT encryption).  If server_version != client_version, then the server could send negotiation_data.  I'm not sure how useful negotiation_data would be for server_version != 0xFFFFFFFF, since I think the server should generally be able to either fit its choices into server_version, or request a retry.  But perhaps this gives us some flexibility for the future.

For future-proofing, servers would be recommended to handle unknown client_version by returning server_version=0xFFFFFFFF so that future clients can attempt more advanced protocols but retry with an older protocol if needed.



More information about the Noise mailing list