Live data from Hacker News

Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

github.com

1–10 of 27 posts

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#3
Interesting, though AFAIK a secure tunnel is only useful for a net.Conn, not an io.ReadWriter. What's the usecase for a "secure tunnel" over a bytes.Buffer?

btw, I noticed that the decrypt function reads a 32-bit message length and immediately allocates a slice of that size. That means an attacker can send 0xFFFFFFFF and cause you to allocate 4GiB.

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#4
post #3

Interesting, though AFAIK a secure tunnel is only useful for a net.Conn, not an io.ReadWriter. What's the usecase for a "secure tunnel" over a bytes.Buffer? btw, I noticed that the decrypt function reads a 32-bit message length and immediately allocates a slice of that size. That means an attacker can send 0xFFFFFFFF and cause you to allocate 4GiB.

Yeah this code review isn’t gonna go great.

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#5
There is no description of the protocol or of its security goals, so I am making some guesses based on a cursory look at the source and what I imagine this might be for.

A single symmetric key is derived for both directions, and there is no checking of nonces, so as far as I can tell any message can be dropped, reordered, or replayed in both directions. (Including replaying message from A to B as if they were from B to A.) This is a bit like using ECB and likely to lead to fun application-specific attacks like [0].

This is very much rolling your own crypto, in a dangerous way. I am on the record as being "against" the "don't roll your own crypto" refrain [1], but mostly because it doesn't work: it should discourage people from publishing hand-rolled protocols such as this, but instead people think it means "don't roll your own primitives" and accept any use of "Ed25519/X25519" as probably secure.

Please read about the Noise framework [2] to get an idea of how much nuance there is to this, and consider using a Go implementation of it [3] instead.

P.S. This kind of issue is also why I maintain that NaCl is not a high-level scheme [4]: this could have used NaCl and have the exact same issues. libsodium has a couple slightly higher-level APIs that could have helped, secretstream [5] and kx [6], but again please use Noise.

[0] https://cryptopals.com/sets/2/challenges/13

[1] https://securitycryptographywhatever.buzzsprout.com/1822302/...

[2] https://noiseprotocol.org/noise.html

[3] https://github.com/flynn/noise

[4] https://words.filippo.io/dispatches/nacl-api/

[5] https://libsodium.gitbook.io/doc/secret-key_cryptography/sec...

[6] https://libsodium.gitbook.io/doc/key_exchange

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#6

There is no description of the protocol or of its security goals, so I am making some guesses based on a cursory look at the source and what I imagine this might be for. A single symmetric key is derived for both directions, and there is no checking of nonces, so as far as I can tell any message can be dropped, reordered, or replayed in both directions. (Including replaying message from A to B as if they were from B…

I once heard something along the lines of "if you're writing the words RSA, you're doing it wrong." I guess that goes for ED25519 also.

If you want to secure a stream with asymmetric cryptography and don't need all the bells and whistles of TLS, what's the correct way to do it? Noise? Is there nothing simpler?

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#7

There is no description of the protocol or of its security goals, so I am making some guesses based on a cursory look at the source and what I imagine this might be for. A single symmetric key is derived for both directions, and there is no checking of nonces, so as far as I can tell any message can be dropped, reordered, or replayed in both directions. (Including replaying message from A to B as if they were from B…

I mean this looks like standard ECIES to me. I think it could even count as a Noise protocol, as in my understanding that protocol family subsumes most of the classic Diffie Hellman based key exchanges. Reading the source the author seems to use a long-lived ECDSA key pair to sign and exchange an ephemeral ECDH key pair, then derives a symmetric AES key from that and uses that for AES-GCM. Not sure how you would do message reordering here as GCM takes care of authenticating your data and keys are not reused. If you want replay protection it's probably sufficient to either remember used keys or add a timestamp. It's a well-done example of writing such a simple protocol, I don't think the author plans to replace TLS with it and he even mentions that in the README.

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#8

There is no description of the protocol or of its security goals, so I am making some guesses based on a cursory look at the source and what I imagine this might be for. A single symmetric key is derived for both directions, and there is no checking of nonces, so as far as I can tell any message can be dropped, reordered, or replayed in both directions. (Including replaying message from A to B as if they were from B…

I mean this looks like standard ECIES to me. I think it could even count as a Noise protocol, as in my understanding that protocol family subsumes most of the classic Diffie Hellman based key exchanges. Reading the source the author seems to use a long-lived ECDSA key pair to sign and exchange an ephemeral ECDH key pair, then derives a symmetric AES key from that and uses that for AES-GCM. Not sure how you would do m…

Can you express this with Noise framework tokens? I don't think you can. Noise is fiddlier than it looks! It's not just an ordering of DH exchanges; it's transcript hashes, cipher state tracking (and reinitializing), key derivation, the whole 9. The temptation (at least for me) is to just skip to the table of handshakes and skim, but the actual protocol framework is in Section 5, where they define precisely what each of those tokens really entails.

(To say nothing of: this uses signatures, and Noise does not).

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#9

There is no description of the protocol or of its security goals, so I am making some guesses based on a cursory look at the source and what I imagine this might be for. A single symmetric key is derived for both directions, and there is no checking of nonces, so as far as I can tell any message can be dropped, reordered, or replayed in both directions. (Including replaying message from A to B as if they were from B…

I mean this looks like standard ECIES to me. I think it could even count as a Noise protocol, as in my understanding that protocol family subsumes most of the classic Diffie Hellman based key exchanges. Reading the source the author seems to use a long-lived ECDSA key pair to sign and exchange an ephemeral ECDH key pair, then derives a symmetric AES key from that and uses that for AES-GCM. Not sure how you would do m…

Each Write encrypts a separate "record" (in the parlance of TLS and Noise). Each of those records can be arbitrarily dropped, replayed, or reflected.

Here's an example, if you do

    Write("Hello")
    Write(" the password is ")
    Write("password")
then without a key I can make you or your peer read "Hello the password is Hello" (or "HelloHelloHello" or any composition of those messages).

No Noise protocol would allow that.

Re: Whisper: Wraps any Go io.ReadWriter in a secure tunnel using Ed25519/X25519

#10
post #8

Earlier quoted context omitted.

I mean this looks like standard ECIES to me. I think it could even count as a Noise protocol, as in my understanding that protocol family subsumes most of the classic Diffie Hellman based key exchanges. Reading the source the author seems to use a long-lived ECDSA key pair to sign and exchange an ephemeral ECDH key pair, then derives a symmetric AES key from that and uses that for AES-GCM. Not sure how you would do m…

Can you express this with Noise framework tokens? I don't think you can. Noise is fiddlier than it looks! It's not just an ordering of DH exchanges; it's transcript hashes, cipher state tracking (and reinitializing), key derivation, the whole 9. The temptation (at least for me) is to just skip to the table of handshakes and skim, but the actual protocol framework is in Section 5, where they define precisely what each…

[deleted]
Post reply on HN