

Secure channels over TCP/IP - purak
https://kyleisom.net/projects/schannel/

======
agwa
You wouldn't want to use this. The key exchange is vulnerable to replay and
identity misbinding attacks. To fix the replay attack, you also need to sign a
nonce from the peer (or its ephemeral public key) to prove that the message is
fresh. To fix the identity misbinding attack, you also need to sign the
identity of the peer. Then it's probably secure, but the protocol would lack
identity hiding. You really want a key exchange protocol like SIGMA, which is
secure and provides identity hiding.

See the following presentation, which presents insecure key exchange protocols
(the key exchange from the article is on page 4) while building up to SIGMA:
[https://www.ietf.org/proceedings/52/slides/ipsec-9.pdf](https://www.ietf.org/proceedings/52/slides/ipsec-9.pdf)

As you can see, this stuff is hard and you really shouldn't be designing your
own. CurveZMQ (basically, DJB's CurveCP over TCP) is probably a better choice
if you want a NaCl-based secure channel. CurveZMQ also happens to be pretty
well documented if you want to learn about what it takes to design a secure
protocol: [http://curvezmq.org/page:read-the-
docs](http://curvezmq.org/page:read-the-docs)

~~~
tptacek
Didn't CodesInChaos document a misbinding attack against CurveCP, too?

~~~
agwa
He found problems with the identity binding where if even a short-term key was
compromised, it would allow impersonation attacks in the future[1]. That's a
poor way to handle failure (and it's fixed in CurveZMQ with the minor changes
he proposed) but it requires a key compromise to exploit so it's not as bad as
a straight-up misbinding attack which any MitM can exploit.

[1]
[https://codesinchaos.wordpress.com/2012/09/09/curvecp-1/](https://codesinchaos.wordpress.com/2012/09/09/curvecp-1/)

------
diafygi
What advantage does this have over spiped[1]? Since there's not really a good
way to distribute public keys, you really need to just put them on a thumb
drive and walk them over to the person that wants them. And if you're doing
that, you might as well give the person a shared secret.

[1]:
[https://www.tarsnap.com/spiped.html](https://www.tarsnap.com/spiped.html)

~~~
rakoo
And the corresponding Go library:
[https://github.com/dchest/spipe](https://github.com/dchest/spipe)

------
jallmann
The public key operations during setup are clearly useful for authentication
against a possibly untrusted peer. What mechanism is used for key
distribution? Revocation? Is the main advantage over TLS in its use of a
limited set of cryptographic primitives (as provided by NaCl), at the expense
of flexibility? Any other advantages, such as decreased setup time? What about
upgradeability -- does the protocol have the ability to roll in additional
keys/exchange algos or ciphers as better ones become available?

Of course, the more of these features you add, the closer you get to TLS. That
being said, without these features (eg, if you need to basically upgrade your
whole fleet just to update to a newer NaCl or to add keys as opposed to using
a signed certificate mechanism), the advantage starts shifting towards even
simpler approaches, such as spiped, which omits all the public-key ceremony in
favor of a shared secret key.

~~~
0xEA
I agree, you would have to tie IPs->peer keys to make this work.

------
cespare
Interesting. A couple of questions that come to mind:

\- Any rough benchmarks vs. TLS? Or even just back-of-the-envelope
math/reasoning behind the claim in the opening paragraph: "without the
overhead of TLS".

\- Instead of generating 24 PRNG bytes for each message to use as the NaCl
nonce, why not use the sequence number each message is assigned anyway?

~~~
0xEA
nacl says that for security each nonce/key pair must be unique for each
message. If you send a "HELO" message, for example first, you've made it
possible to build a pretty simple rainbow table if nonce just starts at 0 or
1. That said, it would seem that the first nonce being random and then
incremented would likely work well.

~~~
agwa
A rainbow table? The key space is 2^256. If you're talking about building a
table containing the ciphertext of "HELO" with all possible keys, that's
totally infeasible. As you correctly state, NaCl requires each nonce/key pair
to be unique. If you start the nonce at 0 for a given key and increment it for
each message, as is commonly done, that satisfies the requirement and is
secure.

------
mborch
"On our production frontend machines, SSL/TLS accounts for less than 1% of the
CPU load, less than 10 KB of memory per connection and less than 2% of network
overhead. Many people believe that SSL/TLS takes a lot of CPU time and we hope
the preceding numbers will help to dispel that." \- Adam Langley, Google.

~~~
slasaus
I assume your point is about the first sentence of the article "This library
was born out of a need to set up a secure channel over a TCP/IP network
without the overhead of TLS.", but I interpreted this not in terms of
performance, but in terms of lines of source code. OpenSSL in particular is
pretty bloated [1].

[1] [http://www.zdnet.com/article/openbsd-forks-prunes-fixes-
open...](http://www.zdnet.com/article/openbsd-forks-prunes-fixes-openssl/)

------
doomrobo
The key exchange high-level overview looks like it has some typos.

Firstly, the <sub></sub> is being escaped instead of being interpreted as a
tag. Also you say that the client and server make a keypair and create a tuple
k_(pub,1) || k_(pub,2) || sig. Why would one participant have 2 pubkeys? If
you meant it to be one public and one private, why would it include a private
key? Is it actually that the client makes k_(pub,1) || client_sig and the
server makes k_(pub,2) || server_sig? Also later you reference k_(peer,1) and
k_(priv,1) which weren't mentioned previously at any point.

Sorry if I'm misunderstanding anything. I'm gonna read through the Go code to
see if I can understand better, this looks really interesting!

~~~
doomrobo
Update

Looking at the source, it seems like the initial key exchange keys are sent as
a k_(pub,x) || sig tuple where x is 1 for the sender and 2 for the receiver.
Similarly, it looks like the shared keys are derived from subslices of
k_(pub,x) and k_(priv,3-x).

Is there a particular reason there isn't a single read/write symmetric key
that's derived from the entirety of the public and private keys?

------
0xEA
Your message length is sent in plain text and unauthenticated. Does this
present a problem?

~~~
tptacek
Probably not, because messages are authenticated cryptographically, and the
lengths are validated before being passed to libsodium. You can't truncate an
authenticated message.

