[noise] Hashing additional context into handshake

Trevor Perrin trevp at trevp.net
Sat Jun 30 12:17:23 PDT 2018


Noise currently documents how to do 0-RTT encryption based on the
responder's long-lived static key.

We've been slowly working out 2 additional ways to do it:

 (1) PSK-based resumption:  Use an "Additional Symmetric Key"
mechanism to derive a resumption PSK from an initial session, and then
use that PSK in a later handshake.

 (2) Short-lived statics:  The server changes its static key
frequently, and signs the static key with an Offline Signing Key.  A
client can lookup the current short-lived static key + OSK public key
+ OSK signature from some directory, or can fetch these values from
the server itself by doing a handshake like NX or XX.  Then the client
can use the short-lived static with a 0-RTT encrypted handshake like
NK, XK, or IK.


In both (1) and (2) the need might arise to bind some additional
"context" into the handshake:

 (1) We might want the resumed PSK handshake bound to a
collision-resistant hash of the original handshake transcript, to
ensure that the client and server have the same view of the original
handshake.  The Additional Symmetric Key mechanism hashes h into each
output key (ASK), but h might be 512 bits, and ASKs and PSKs are only
256 bits.

To preserve the full 512 bits for collision-resistance when using
512-bit hashes, we could use the ASK mechanism to derive both a PSK
and a PSK "addendum" value [1].  The addendum would be a second
256-bit value that should be hashed into the transcript of the resumed
handshake.  It can be also be used an an identifier for the PSK, e.g.
the client could send the first 128 bits of the addendum to tell the
server which stored PSK to use.

It's not clear how the addendum would be hashed into the the resumed
handshake, but [1] proposes including it in the prologue.

 (2) When encrypting to a short-lived static public key signed by an
Offline Signing Key, it's important to somehow bind the handshake to
the OSK public key.  Otherwise you might contact some directory and
fetch an OSK public key + signature that were provided by a malicious
party who is trying to "take credit" for the server's communication -
this is a classic "Unknown Key Share" attack.

It's not clear how the OSK public key would be hashed into the
handshake, however.  In the past we've talked about using the prologue
[2].


So in both (1) and (2) there's a need for a mechanism to bind some
additional data (a PSK addendum or OSK public key) into the handshake.
We could try to stuff all these into the prologue, but we'd have to
define more structure (protobufs?) and APIs to fit all these different
things into the prologue, and it's messy to be adding all this outside
our existing naming / patterns mechanisms.

An alternative might be:

 * Define a new "h" token which is processed simply as
MixHash(some_data).  (This idea was already discussed in the thread
about "Authentication of handshake data between messages").

 * Define modifiers to insert this token for cases (1) and (2):

   - For (1), a "pska?" modifier could be the same as "psk?", but also
inserts the "h" token prior to the "psk", and "h" is used to
MixHash(psk_addendum).  So for example, NNpska0 would become:


NNpska0:
  -> h, psk, e
  <- e, ee


   - For (2), an "osk" modifier would insert the "h" token prior to
the first use of the server's static in a DH.  "h" would be used to
MixHash(OSK_public_key).  So for example, NK would become:

NKosk:
  <- s
  ...
  -> e, h, es
  <- e, ee


Thoughts?

Trevor

[1] https://moderncrypto.org/mail-archive/noise/2018/001636.html
[2] https://moderncrypto.org/mail-archive/noise/2017/001215.html


More information about the Noise mailing list