[noise] New draft: "noh2" branch
Trevor Perrin
trevp at trevp.net
Thu Aug 27 09:58:26 PDT 2015
On Thu, Aug 27, 2015 at 8:50 AM, Tiffany Bennett <tiffany at stormbit.net> wrote:
>
> Having a length field that is processed by the session doesn't make
> sense, since Session doesn't handle framing for TCP, and is redundant
> for UDP. I feel like this should be removed and given to a "framing
> layer", which may or may not be explicitly encoded into the
> specification.
I'd argue the length fields are harmless. If your specific case
doesn't need them just omit them and say they're implied.
But specifying them is simple and encourages interop, e.g. if you use
Noise over TCP it's obvious what to do.
>
> More concretely, the framing layer as I envision it is laid out as
> such (and may need to be expanded to accommodate branching):
>
> - session: The session as used by the framing layer.
> - descriptors: A list of lists of descriptors, for each step of the handshake.
> - stepping: As existed before in the session.
> - nonce: Mutually exclusive with stepping.
We could put "stepping" and "nonces" in an extension spec, but I'd
really like the core spec to be simple and friendly, without too much
clutter.
> - framing: Whether or not the connection is stream-based or
> datagram-based, determines if a length field is needed.
> - split: I see that EndHandshake now unconditionally creates a
> bidirectional stream, so this flag should perhaps not be included,
> unless there is a reason to support one-directional streams.
If you want a one-directional stream you can ignore (or even not
calculate) the second session, so I didn't think an optional "split"
was worth the complexity.
> I see that the termination handling is now gone. I like this change. I
> prefer for application-level protocols to decide when a connection has
> been terminated, and for the controlling application, when it receives
> its application-layer termination message, to simply destroy all
> resources associated with the connection, instead of needing to chain
> through two or more layers of the IP stack telling lower layers that
> they need to begin closing the connection.
It's actually moved into the first byte of transport message payloads.
You could ignore it if you want, but by default it's safest for the
crypto layer to resist truncation attacks (of sessions, or one-way
messages). It at least forces you to think about that.
> I like where this branch is going at the moment. The session is less
> complex than it used to be, now that the kernel has been split off
> from it. It has better interoperability than previous versions. I
> would like better error detection, though. At the moment, a mismatched
> protocol will likely produce an invalid MAC error or something
> similarly unhelpful. The only solution I see is including the name of
> the protocol (or the hash of it) in the first handshake message,
> however.
Maybe, but error messages often get used against you (to enable oracle
attacks, or timing attacks), and complicate things, so I would leave
those for the application to add if it insists.
Trevor
>
>
> On Thu, Aug 27, 2015 at 3:37 AM, Trevor Perrin <trevp at trevp.net> wrote:
>> On Wed, Aug 26, 2015 at 5:28 PM, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>>>
>>> FWIW, I prefer master to noh, and I prefer noh to noh2. Noh2 and noh seem to
>>> add quite a bit of complexity and implementation prescription that I don't
>>> openly welcome.
>>
>> I'm still trying to simplify noh2, see if you like revision 1 any better.
>>
>>
>>> What I dislike: the considerable complexity and abstraction added.
>>
>>
>> A lot of the complexity from noh got removed in noh2. Hard to know
>> what else to cut:
>>
>> * If the patterns are confusing we could go back to the original
>> Noise design that used a single "e, dheX, s, dhsX" pattern for every
>> message. But you'd end up with redundant fields and DH ops (e.g. in
>> brackets) that we currently tailor away:
>>
>> XX:
>> -> e
>> <- e, dhee, s, dhse
>> -> [e, dhee,] s, dhse
>>
>> IS:
>> -> e, dhes, s, dhss
>> <- e, dhee, [s,] dhss
>>
>> XS:
>> -> e, dhes, [e, dhes]
>> <- e, dhee, [e, dhee]
>> -> s, dhse, [s, dhse]
>>
>>
>> * We could write a concrete spec that presents a concrete Noise Pipe
>> protocol, and then have the general framework in a separate document.
>> But I'm not sure presenting a long list of concrete steps is that much
>> better. For example, I find the pattern easier to deal with then a
>> list of steps:
>>
>> -> e
>> <- e, dhee, s, dhse
>> -> s, dhse
>>
>> vs
>>
>> def WritePipeHandshakeMessage0():
>> kernel.MixKey(name + ZERO + preshared_key)
>> e = GENERATE_KEYPAIR()
>> Write(e.pub)
>> Write(payload)
>>
>> def WritePipeHandshakeMessage1():
>> e = GENERATE_KEYPAIR()
>> Write(e.pub)
>> kernel.MixKey(DH(e, re))
>> Write(kernel.Encrypt(s.pub))
>> kernel.MixHash(s)
>> kernel.MixKey(DH(s, re))
>> Write(kernel.Encrypt(payload))
>>
>> def WritePipeHandshakeMessage2():
>> Write(kernel.Encrypt(s.pub))
>> kernel.MixHash(s)
>> kernel.MixKey(DH(s, re))
>> Write(kernel.Encrypt(payload))
>>
>>
>>
>>> While
>>> elegant, in fact I don't want the ability for "parties to alter handshake
>>> patterns, ciphersets, and transport flags on the fly".
>>
>> I do think being able to choose whether or not to authenticate, or
>> execute a 0-RTT handshake, are pretty useful, and the "noh2" design
>> achieves them at low cost.
>>
>>
>>> This might make noise
>>> suitable as a general purpose TLS-rank protocol, but I'm after something
>>> small, minimal, secure, and easy to produce an audit-able implementation. I
>>> don't want it to have so many bells and whistles that I need to write it in
>>> Rust or Haskell to have faith in my code; instead I want to write C that I
>>> can confidently verify without my eyes bleeding.
>>
>> I would hope we achieve that to. I'll try to implement noh2 soon and
>> see how it goes.
>>
>>
>>> I also liked the quality of the master branch where all previous bytes were
>>> in aad for each encryption, which imposed ordering constraints (in addition
>>> to binding relevant data to the exchange).
>>
>> I'm not sure what "ordering constraint" means here. I don't think
>> there's any way to maliciously reorder handshake messages.
>>
>>
>>> It also had the nice effect of
>>> authenticating the prologue, which seems like a nice quality, as I wouldn't
>>> want an attacker to be able to "break apart" any components of one message
>>> and put them in a message of another type.
>>
>> None of the type, length fields need to be in aad, nor does an
>> explicit nonce. So I'm not sure what we'd use this for: what data
>> needs to be authenticated and go in prologue that couldn't just go in
>> the payload?
>>
>>
>> Trevor
>> _______________________________________________
>> Noise mailing list
>> Noise at moderncrypto.org
>> https://moderncrypto.org/mailman/listinfo/noise
> _______________________________________________
> Noise mailing list
> Noise at moderncrypto.org
> https://moderncrypto.org/mailman/listinfo/noise
More information about the Noise
mailing list