[noise] Kernel-land C implementation of latest noise specification

Jason A. Donenfeld Jason at zx2c4.com
Tue Jul 7 17:18:02 PDT 2015


On Wed, Jul 8, 2015 at 1:16 AM, Trevor Perrin <trevp at trevp.net> wrote:
> OK.  I've edited the spec so the GETKEY call is done external to the
> KDF, so you just have to define KDF to be keyed BLAKE2b.
>
> I don't think that loses any important generality, and it makes the
> ciphersuite definitions simpler and less error-prone.

I just looked at the commit you made. I'm pretty sure there's a
misunderstanding.

Blake2b offers a replacement for SHA2-256 in the form of:

Blake2b(m) = hash

Blake2b ALSO offers a replacement for HMAC-SHA2-256 in the form of:

Blake2b(key, m) = hash

So, I'm NOT modifying your GETKEY function -- I still use chacha20(k,
n) for this, as you specify.

What I'm doing, instead is replacing your usage of HMAC-SHA2-256(key,
m) with Blake2b(key, m), and replacing your usage of SHA2-256(m) with
Blake2b(m).

Does this make sense?

Perhaps revert <https://github.com/trevp/noise/commit/2dec3fd894f37a0c014b4f8656b9f90299840e8e>
and parts of <https://github.com/trevp/noise/commit/15ac0473cf6f6e9a9ff500ecfa5ba5c00701d06b>?
I rather liked the GETKEY part being mandated. I think these two edits
made the specification much less clear.

> The fact that you're not finding the prologue useful is a concern.
> Maybe it needs more work.

What use could I have for the payload? For sending data in my VPN, I
generally need to send two things unencrypted:

- message type
- key index parameter

Then I send one big chunk encrypted:

- VPN data

The VPN data authenticates the two unencrypted parameters before it.
If everything checks out, I'm set. I'm not sure what use I'd have for
something different beyond that. I generally don't like variable
length messages when I don't need them.

>
>> At handshake initiation, I set peer.handshake.key.h to its initial
>> value, peer.handshake.key.nonce to zero, and
>> peer.handshake.static_public/private and peer.handshake.remote_static
>> to the right pre-known values.
>
> Do you create and consume pre-messages for the pre-known static value?
>  You want it to be hashed into h, so you shouldn't set it directly.

Woooooah nelly. Good catch. So in other words, the initial value of h
is actually HASH(HASH("Noise255-blablah") || s).

But actually, this isn't possible -- we've got a catch 22 here.
HandshakeIK's first step is "e, dhes, s, dhss", which means that when
the responder processes it, it hashes "dhes" into "h" before it can
even get to decrypting "s" to learn who's talking to it. The whole
purpose of the "I" in IK is that the static key needs to be
transmitted to the responder immediately, because the responder
doesn't know who is talking to it. As such, it's not possible for the
responder to "create" a pre-message, even though it is possible for
the initiator to "consume" one. In order to keep the states of "h"
synchronized, "s" cannot be hashed into "h" before both parties know
about "s", and that means after the "e, dhes, s, dhss".

>
> Honestly I'm not going to pore over the code too much, I'm mainly
> interested in lessons learned about the spec - what are rough spots,
> confusing points, what else is needed, etc.

Shucks okay. Welp, if anyone else on the list wants to get their hands
dirty with kernel land C, be my guest!


More information about the Noise mailing list