<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Jul 1, 2018 at 3:38 PM, Trevor Perrin <span dir="ltr"><<a href="mailto:trevp@trevp.net" target="_blank">trevp@trevp.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">My hope is that code-generators could combine the flexibility of<br>
names/patterns/modifiers with simple/auditable outputs.  Someday!<br></blockquote><div><br></div><div>Yes, someday. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span><br>
<br>
> I have now begun work on NoiseSocket and NoiseLink and have a few<br>
> observations / questions.  Apologies if these issues have already been<br>
> raised previously.<br>
<br>
</span>Nope, this is great - these are untested and unstable specs in<br>
desperate need of feedback...<br>
<br>
(Also, Gerardo and I are discussing this renaming, if you have opinions:<br>
<br>
<a href="https://moderncrypto.org/mail-archive/noise/2018/001594.html" rel="noreferrer" target="_blank">https://moderncrypto.org/mail-<wbr>archive/noise/2018/001594.html</a><br>
)<br></blockquote><div><br></div><div>It would be nice if there was a uniform set of tags so that 4 doesn't mean different things in different contexts.  But I can live with it the way it is.</div><div><br></div><div>The only "wart" I've found is "string rejected_protocol = 5" in NoiseLingoNegotiationDataReque<wbr>st and "bool rejected = 5" in NoiseLingoNegotiationDataRespo<wbr>nse.  The tag numbers and field types are otherwise identical between request and response.  The change in type for tag 5 struck me as odd.<br></div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span><br>
> Section "2.3 Encrypted Payloads" of NoiseSocket is a little unclear as to<br>
> the handling of cleartext payloads in handshake messages.  Should they also<br>
> have a body_len and padding, or should they be omitted?<br>
<br>
</span>Only encrypted payloads should have those things (for padding).<br>
<span>[...]<br>

</span>You want padding, even for cleartext payloads?  Seems like a slight<br>
waste of bytes.  I assume implementations can combine decryption with<br>
de-padding, and that's clean enough?<br></blockquote><div><br></div><div>The issue is one of payload formatting: knowing ahead of time to add the body_len prefix to the payload when the payload is encrypted, but leave it off if the payload is cleartext.  I think I've come up with an API solution with an extra parameter to WriteMessage()/ReadMessage() to indicate "apply length prefix and padding if the payload is encrypted, or encode as literal if cleartext".</div><div><br></div><div>Maybe this needs to be thought about in the core Noise specification: applying a conditional padding transformation to the payload before calling EncryptAndHash().<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span></span><span>> Only NoiseTinyLink appears to allow transport options to be negotiated, but<br>
> not full NoiseLink.  How do I select continuous rekey in the full protocol<br>
> for example?  Or negotiate smaller packet lengths?<br>
<br>
</span>As of now, you don't.  NoiseLink was intended as a simple starting<br>
point for Internet protocols.  You could modify the NoiseLink profile<br>
to include those things if you need them, but your typical Internet<br>
protocol doesn't.<br></blockquote><div><br></div><div>OK.  If the feature can be asked for, then it isn't a drama.  See below. <br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span> 
</span>* BLAKE2s: was specified for NoiseTinyLink, but not NoiseLink.<br>
Rationale was that SHA256 is everywhere, so it makes sense for<br>
Internet devices.  For tiny devices maybe the efficiency advantage of<br>
BLAKE2 would make a difference.  But on considering this, I'm not sure<br>
it's worth it.  There are better symmetric-crypto optimizations we<br>
could do for small devices (non-HMAC/HKDF; unifying the ck and h<br>
chains; coalescing repeated MixHash inputs into a single hash block;<br>
Keccak/STROBE/Disco etc).  So maybe we should just stick with SHA256<br>
for the default profiles, until we've spec'd these other things.<br></blockquote><div><br></div><div>BLAKE2s has a speed advantage over SHA256 when there's no hardware acceleration available.  Memory space is identical in small-footprint configurations.</div><div><br></div>Since both MD5 and SHA-1 fell to attacks, I've been looking to get away from that family wherever possible.  Same with AES frankly - timing attacks are hard to avoid without trusting your privacy to a black box in-CPU crypto accelerator, so I usually say "No sboxes!  It's the law!".<br><div><br></div><div><div>As for Keccak and friends - slow.  I'd look at the finalists in the CAESAR AEAD competition instead for a Disco-style replacement.  ACORN128 is freaking incredible in terms of speed and memory footprint.<br></div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span>
> Negotiation of max_send_length and max_recv_length is a little fuzzy.  The<br>
> simplest interpretation is "if my send length is greater than the other<br>
> party's receive length, then reduce my send length so as not to overflow<br>
> their receive buffer".  In fact, I think only one buffer size on each end<br>
> needs to be negotiated.  I would reduce it to max_recv_length only with a<br>
> policy of "don't send me transport messages larger than this or I'll cut you<br>
> off".<br>
<br>
</span>That's true; if you advertise a max_send_length the receiver can<br>
allocate a smaller buffer, but maybe that's not worth the effort.  We<br>
could take it out of NLS entirely, or just not use it in the default<br>
profiles?<br></blockquote><div><br></div><div>Leave it in for now - at the moment I'm allocating buffers before the session starts so as to reduce the likelihood of a failed memory allocation mid-session.  But another implementation might find it useful to reclaim the memory if it isn't needed.<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

This bring up another problem w/TransportOptions:  There's no way to<br>
advertise/negotiate which options you support.  You have to know in<br>
advance whether the other side is able to accept your options.<br>
<br>
If we expect to have a small number of options, we could possibly just<br>
add a uint32 bitfield to TransportOptions saying which options you<br>
support (it will be encoded as a varint, so typically smaller than 4<br>
bytes).  Each party can send whatever options it wants, but it will<br>
only assume the other party accepted the option if it receives a<br>
bitfield with the appropriate bit set.<br></blockquote><div><br></div><div>Or a packed array of tag numbers which will be extensible to tag numbers beyond 31.  It is also useful to distinguish between optional/desirable options that would be nice to use if the other side supports them (e.g. continuous_rekey), and mandatory options that the other side must support or communications isn't possible (e.g. packet length negotiation for NoiseTinyLink):<br></div><div><br></div><div>  repeated int32 desirable_options = ??;<br>  repeated int32 mandatory_options = ??;<br></div><div><br></div><div>The trick is where to announce this so that both sides have the opportunity to configure a desirable option value.  In NoiseTinyLink, the server/responder is the first to announce transport options.  The client cannot ask for or demand a feature before then.  Even if the client does ask for a feature in the third message, the server can no longer say "yes, and here is my value" because the handshake is over.<br></div><div><br></div><div>Possibly the client could list its desirable/mandatory options in the early payload section of the negotiation request, with the server responding in kind in the second handshake message.  The client then sends its actual values in the third handshake message.<br></div><div><br></div><div>Example 1: Tiny client connecting to full server that cannot negotiate packet lengths:</div><div>    Client: mandatory_options = {2} /* max_recv_length */<br></div><div>    Server: rejected = true, bye!<br></div><div><br></div><div>Example 2: Tiny client connecting to full server that *can* negotiate packet lengths:<br></div><div><div>    Client: mandatory_options = {2}<br></div><div>    Server: desirable_options = {3}, continuous_rekey = true, max_recv_length = 65535</div><div>    Client: max_recv_length = 256, continuous_rekey = true<br></div><div><br></div></div></div><div>Example 3: Tiny client that does not support continuous_rekey:<br></div><div><div>    Client: mandatory_options = {2}<br></div><div>    Server: desirable_options = {3}, continuous_rekey = true, max_recv_length = 65535</div><div>    Client: max_recv_length = 256<br></div><div><br></div></div>The lack of the continuous_rekey value in the client's Example 3 response indicates that the server cannot use it either and must drop the option value it sent previously.  The presence of an option value indicates that the request to use the feature has been ACK'ed.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Note that the client in Example 2 may respond with continuous_rekey = false to indicate that while it accepts re-keying in messages from the server, it will not be re-keying its own transmitted messages (for whatever reason).<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Cheers,</div><div class="gmail_extra"><br></div><div class="gmail_extra">Rhys.<br></div></div>