[nanomsg] Re: end-to-end security

  • From: Garrett D'Amore <garrett@xxxxxxxxxx>
  • To: nanomsg@xxxxxxxxxxxxx, Alex Elsayed <eternaleye@xxxxxxxxx>
  • Date: Wed, 12 Mar 2014 13:37:22 -0700

Key lookup will be necessary in any end-to-end system for nanomsg - you 
either need a.) a round trip to exchange keys b.) static keys or c.) a key 

a.) is impossible with SP semantics, b.) is imposible with dynamic 
join/leave, which means c.) is the only option. 
Not really.  In particular, “a” is only impossible *at the SP layer*.  
Conversely, its nearly *trivial* at the application layer.  The more I think 
about e2e, the more I believe this is truly an application problem.  Only the 
app knows what its threat model is like, and almost any “policy” decision we 
might make in a common framework (key exchange, registry, PKI, web-of-trust, 
whatever) is going to be right for only a minority of users.  Its not for 
nothing that IPsec and WPA *both* declined to specify these details, but left 
instead the door open for multiple possible solutions (IKE, EAP, etc.)  e2e is 
*hard* to get right in the general case.

Conversely, given a stateful application layer exchange, its trivial at the app 
layer.  (You *do* need state though.)

Session-key-with-message is also impossible to avoid in e2e. 
Only if you are completely stateless.

Replay is an issue that would need addressed, yes - timestamps require clock 
synchronization; nonces require synchronizing the state of seen-nonces 
between load-balanced endpoints. This is nontrivial However, it _is_ no 
worse than unencrypted even with replay. 
*Except* that when you start making promises about crypto, and people start 
putting the stuff on the hostile Internet.  Its very important to understand 
that in some important ways *weak* security can be more damaging than *no* 
security.  (With the “no” security option, people will secure either in their 
application or build on top of secure networks — e.g. use IPsec.)

I honestly feel that a meaningful security architecture will have make use 
of both transport-layer _and_ e2e security. 

I think providing e2e is probably part of any comprehensive application design. 
 However, I’m becoming less convinced that we can address it comprehensively in 
nanomsg itself.  (Although building a library of functions that run on top of 
SP, might be reasonable.  Conversely building a new “secure” REP/REQ protocol 
is doable — but you’d need to introduce some new state in the sockets, etc.  I 
don’t see this being even remotely reasonably possible comprehensively though.) 
 Conversely, I *am* convinced that transport security is a fairly easy problem 
to tackle.

> For pseudo-multicast (PUB/SUB), the broadcaster will have to resend 
> / reencrypt the message for each subscriber. This would be wasteful if we 
> could have used a multicast transport (we don’t support that now in 
> nanomsg), and it wastes CPU cycles on the transmitter. But it avoids 
> sending n encrypted sessions to each subscriber, too, which is a good 
> thing. :-) 

There are costs involved, yes. Then again, who is to say that the entire 
application needs to use the same level of e2e? If you have an _internal_ 
system that is e2e from producer to consumer, which then publishes without 
e2e to the _public_, you have still gained - that gateway can be assured 
that the data it is republishing has not been tampered with. 
You can get that with transport layer on the backend (secure network).  Well 
understood multi-tier architecture.  However, its not really e2e.  But I 
totally agree that the e2e decisions and tradeoffs are going to vary from 
application to application.

> I don’t believe we’re serious about trying to make nanomsg utilize IP 
> level multicast, are we? Even for pub/sub it seems like IP multicast 
> creates more problems than it really solves (mostly because IP multicast 
> is unevenly supported across increasingly fragmented IP/NAT’d networks, 
> and limited or broken router/gateway firmwares.) 

Agreed, although there are more reasons to use datagram transports than 
multicast. In particular, multiplexing of channels over unreliable datagrams 
sidesteps the head-of-line-blocking horrorshow that happens when you try to 
multiplex over TCP. See also the 'minion' suite of protocols, which turn TCP 
(or TLS!) into something with unreliable-datagram semantics (which are 
useful) without changing the wire format (allowing it to be deployed even 
over networks that try to "helpfully" munge your data). 
We could probably add a udp transport fairly trivially, especially if we are 
willing to accept that the maximum SP message over such a transport was limited 
by the maximum UDP packet size (minus headers).  I.e. about 65000 bytes.  (64K 
- 20 bytes of IP header, and 8 bytes of UDP header.  Assuming we don’t add our 
own… and I think we would want to add something here — probably something like 
the SP header and packet size combined. ;-)

I think it would only take an hour or two to add such to my current 
implementation.  (It takes about 10 minutes to add another stream oriented 
protocol.  Packet oriented will take extra because I can’t use the common 
stream based code. :-)

Its probably about the same effort to add UDP to nanomsg C as well, although I 
guess the state machine would need some work.

Btw, I’ve not looked yet, but does anyone know if the ipc transport uses the 
same wire format as tcp does?  I’m sort of assuming (hoping!) that it does.  
(I’ll look later.)

> 4. I think there is also TLS/SSL session resumption designed to avoid some 
> of the costs. Not sure what platforms actually have it implemented 
> though. 

Pretty much all of them. It's such a huge latency/power-use win that it's 
very very common. 
Makes sense, and that is really good news!

Yup. the various ECDHE_ECDSA_* ciphersuites are quite good on that count. 
However, blowfish is actually a pretty terrible choice when it comes to low- 
latency key negotiation - it's so famously expensive it's been used as a 
password hash! In addition, Blowfish suffers from classes of weak keys, and 
is frequently disabled for that reason. AES is simply better there. 
Yeah, I’d use AES in favor of every other choice these days.  (I think the 
password hash version of blowfish uses extra rounds, though… and you can 
“avoid” weak keys by simply not *choosing* them.)

In addition, CipherSuites are monolithic - you can't mix-and-match key- 
exchange and symmetric-alg freely, which is surprising to most. I don't 
think the combination of EC and Blowfish was ever given a code point, just 
like none of the Kerberos KEX modes has an AES-GCM variant. 

Good point!  I had forgotten about that… its been a *long* time since I hacked 
into the internals of SSL/TLS, and I’d forgotten that.

Currently, some ChaCha-based stuff is passing through the IETF to become a 
TLS ciphersuite, and would be essentially ideal for his needs - it's near 
AES speeds even when AES has hardware help. 

Do not use RC4, it's known to have serious flaws regarding biases in its 
output, which make a number of attacks possible. 

Yep.  Although it gets a far worse rap than it deserves due to poor 
implementation choices in the protocols built on top of it (WEP again!).  
Still, I don’t think anybody sane uses RC4 for anything anymore (TKIP 

        - Garrett

Other related posts: