stealth / opmsg

opmsg message encryption
Other
750 stars 39 forks source link

Crypto Questions #4

Closed bnagy closed 9 years ago

bnagy commented 9 years ago

Congrats on the project! There's a lot of ideas to like, here, and a drop-in replacement for GPG would be most welcome. I particularly like the rapid persona creation and ditching the web of trust.

I have questions in two areas, though.

  1. DH and fallback

Could you produce something that explains the DH / PFS approach in more detail? The way I understand DH, you can't send a "DH Key" with a message, only the initiator half of a DH exchange. Are you saving half-open exchanges and then completing as you reply to messages (like an OTR/axolotl ratchet) or doing something else?

When you fall back, I wonder why you chose to fall all the way back to RSA instead of staying with the latest DH-negotiated key for that peer? It seems like this would improve FS, because a break of your Persona RSA key affects less messages. Again, maybe I just misunderstood the explanation.

  1. Symmetric Choices

Firstly, why support CFB/OFB at all? I can't see the utility of turning a block cipher into a stream cipher for this tool, which is operating on complete messages. OFB in particular is pretty fiddly, and I would have thought that CTR would be a better choice than either. CBC is no picnic, either, because it means that you need to be very careful with padding, and it's still vulnerable to message tampering (which your mandatory signatures takes care of)

Is there some reason that you chose not to use, say, GCM? It seems like a greenfield project could just skip all of the scary old modes with well known failure areas and an authenticated mode from the outset.

Secondly, and I know this is more a personal preference issue, supporting CAST5 raised my eyebrow, but supporting Blowfish blew them both right off my head. I would have thought that, for a tool which explicitly supports operation on local files, the smaller blocksizes would be enough of a concern to discount those ciphers (small blocksizes plus very large files is a potential area of concern).

Is there really such a groundswell of users that don't trust AES? One of the oft-cited complaints against GPG is complexity, and offering hundreds of options that users are not equipped to understand. I very much like that you simplified the available options, but feel that more could be done...

Finally, I considered asking why you skipped EC to stay with giant dinosaur RSA keys, but on reflection it's probably a pretty reasonable choice for a low latency application, and there are fewer footguns available to the developer. :)

Anyway, thanks again for the project. It's easy to point and laugh at GPG, but a lot harder to actually produce a working alternative, so this is a great milestone.

stealth commented 9 years ago

Ok.

For 1) Thats correct. In that sense I do half-open DH exchange with each mail that is completed with the reply. The DH parameters (p, g) are created when the persona is created. Nevertheless, you can create new DH params at any time (which is unncecessary though). Then for each mail 3 DH keys are generated from these (public) parameters. So the DH blob contains: the parameters (p,g) and the pub_key. Thats all the peer needs on his side for an Kex. When peer wants to do (complete) the DH Kex, it takes these DH parameters that are included in the DH b64-blob, creates his own DH Key, and uses the pub_key part to complete Kex. Then sends his own pub_key from his DH generation step to the peer, attached to the mail , who then has all the bits to complete the Kex on his side (he is only missing the peer's pub_key; anything else was already exchanged and is kept in local store for later Kex completion). For the RSA fallback: it weakens the crypto if you do a second (and a third...) DH Kex with the same p,g and pub_key material. I am sure you can derive the secret from it if you use the pub_key often enough to exp(exp(g,x),pub_key) with different x but same pub_key.

2) Right. The plan is to add GCM indeed, just I was not 100% sure with the API, because of the AAD thing and the (missing) padding. So I just added the ciphers where I was sure that I am doing it correctly rather than "guessing" other ciphers into opmsg. For OCB padding etc, OpenSSL should handle that; and as signatures are mandatory, GCM's AAD doesnt bring real benefit. In fact you are right, keeping it as simple as possible is one goal, but I learned in crypto class to make crypto projects it flexible enough so its easy to switch cipher algos in case something is found weak. opmsg will "negotiate" to the peer what you are using, so if you prefer AES, just do it (and GCM will come later:). From the coding point, its no overhead, the code is cipher-algo agnostic, (due to OpenSSL EVP cipher abstraction), so adding more ciphers is not really adding complexity.

3) For ECC. Thats I just dont trust NIST to not have backdoored the curve parameters (like with the RNG's they did). Maybe Suite-B curves could be a choice. But given that the RSA part is only for signing, that should be OK.

stealth commented 9 years ago

solved by adding ctr and gcm mode and kicking ofb

bnagy commented 9 years ago

Sorry to go dead, I was travelling :)

That was fast! :)

  1. Re the DH stuff... I'm not suggesting doing more DH exchanges with the same pub values ( although it's not obvious to me that this is unsafe, cf ElGamal ) I'm just suggesting that once we've completed a DH with a peer we have a key we share with that (and only that) peer. Why not keep using that key until a new DH KEX is complete, at which time we use the latest available key. That limits damage to the message(s) encrypted with that secret.
  2. I don't think I was all that clear about CFB/OFB/CTR. I don't see the benefit from using any of these modes, because I don't see why you would want a stream cipher mode when you have the full plaintext available already.

It's great that adding GCM was so fast. IMHO I would give serious thought to making AES-128-GCM the default, even if I can't convince you to kick CAST and Blowfish :)

Cheers!

malexmave commented 9 years ago

I'm going to attach my questions to this issue, since it is on the same topic.

  1. As I understand it, after sending a PFS-Message with one of the DH keys, the sending client deletes the DH key, and the recipient flags it as "used". Does the sender have any way to decrypt the message he sent? Because if he deletes the DH key, it should be impossible to decrypt it, unless the message is also encrypted with the public key of the sender, which would defeat the whole point of PFS. Maybe you could clarify this in the README.
  2. The list of supported ciphers contains the cipher "null", which is, presumably, to not encrypt at all. Is this equivalent to simply signing the message without encryption, or why is it in the list?
  3. Speaking of signing without encryption, one of the things I like about PGP is that you can sign all your messages, even if you don't know the public key of a recipient, and that the recipient can then use the signature to retrieve your key from the keyservers. Does opmsg support a similar mode of operation for distributing your key (-identifier) with unencrypted messages, or do you have to perform an explicit key exchange before you can sign your messages? Again, I was not quite able to find this in the README...

Thanks a lot for writing this application. I really love the idea of opmsg, and I'll see if I can get a few of my friends to give it a try with me. Sadly, I'm not using mutt, only Thunderbird, so that will involve some manual labor, but still.

stealth commented 9 years ago

So...

Ben1) Indeed. Could be done but adds additional signalling overhead which I want to keep to a minimum for safety reasons. Being encouraged to regularily change the persona id's should make that affordable. As a rule of thumb, if theres something wrong with that personas keystore or it gets bloated; just create a new one for that peer. The 1:1 linking makes that easy, as you just have to handshake with that one peer again. Ben2) So this sounds you have an AES CBC exploit and even more reason for me to have a list of cipher/mode choices. :D

Max1) Correct. Once encryption is done, you are missing the other half of the key which is needed for decryption. Your half of DH is thrown away once opmsg exits (it only existed in memory). So no way to read the message unless you are the recipient or you can break DH or AES (ask Ben) Max2) correct. Max3) Yes,but the way opmsg is designed requires that both parties exchange their personas before,because opmsg needs proof that the message is from that origin; otherwise MiM could send you fake DH keys.

In general, PGP behavior is only mimiced to allow easy MUA integration, not for the usage or msg exchange style.

Theres nothing that prevents opmsg to work with Thunderbird or other MUAs, if they support S/MIME. The mutt integration is just an example. If your mailer works with PGP+S/MIME, it should also work with opmsg. In fact, I'd be happy to receive as many MUA config snippets for integration as possible, so I can add it to the README. Just look how your mailer/config calls PGP externally and use the mutt example to adapt it.

bnagy commented 9 years ago

I don't understand your answer on 1), sorry. I'm talking purely about the situation where we have no more unused secrets from the pool of DH secrets with peerA. DH secret exhaustion should only happen when there is a lot of messages from A to B and not enough from B to A to complete DH exchanges. I'm suggesting that it might be better to re-use the most recent DH secret for that peer and not use the RSA key. I don't see any extra signalling here at all. Anyway, this isn't a big deal :)

2) I don't have any "exploit" for CBC that's not common knowledge, but there are definitely a lot of known ways that CBC can cause trouble, whereas an AEAD mode like GCM is a safer default for software being written today ( TLS etc is slowly deprecating AES-CBC for example ). Personally, I wouldn't offer the user choices that are widely considered to be suboptimal. In this case, that's every cipher and mode except AES-GCM, for assorted reasons. However, I completely respect that you want to offer a choice so that "expert" users can roll their own threat model. My only point is that I think the default ( which almost all users will end up with ) should be the safest choice. I think a quick straw poll of crypto experts should be enough to convince you that (from your available options) that is AES-GCM here :)

malexmave commented 9 years ago

Thank you for your quick reply.

Max1) Correct. Once encryption is done, you are missing the other half of the key which is needed for decryption. Your half of DH is thrown away once opmsg exits (it only existed in memory). So no way to read the message unless you are the recipient or you can break DH or AES (ask Ben) Okay, good to know. That should probably be made a bit clearer in the documentation, since this is unexpected for people coming from basically any other encryption system. I personally look at encrypted sent messages quite often to find out what I told someone, and that is impossible with this system.

This is not necessarily a bad thing, but it should be documented explicitly at some point, because it could lead to tears otherwise.

Also, since the recipient retains the DH-Keys to be able to later recover the contents of the message, can this still be considered to be forward secure? Because a key compromise would in almost all cases also result in a compromise of the cached DH keys. You are correct when you say that users should "keep their box unpwned", but this system could lead to problems in the following situation:

Alice sends a DH-encrypted message to Bob. Eve intercepts and stores the message (we assume that Eve has broken or circumvented all other layers of crypto and the message is only protected with opmsg). Bob receives the message, reads it, then deletes it in his client and on the server. A few days later, Eve compromises Bob's Box.

In the current design, Eve could grab the DH key store of Bob and use the stored key to decrypt the message she has intercepted, even though it is no longer present on Bob's box. Thus, it may be forward-secret in the strict sense of the word (capturing the master key does not lead to a compromise of the messages), but capturing the whole key store compromises all received messages.

An alternative would be to decrypt the incoming message and re-encrypt it using RSA with the public key of the persona. That way, the DH keys could be instantly deleted, and thus deleting the message on the client would reliably destroy the message, since it can no longer be captured by pwning the box later (assuming you are not using IMAP and thus have not sent the RSA-encrypted message over the wire). This would at least improve the FS-properties of the application.

Disclaimer: I am not a crypto expert, just an IT Security student, but this is how I see it. Would be interested in your thoughts on this issue.

Also, for the record, I agree with @bnagy concerning the choice of the default algorithm. It's fine to offer potentially weaker algorithms like aes128-cbc, but the default value should always be the strongest possible compatible algorithm, unless you have very good reasons not to do so, since this will be the one that the vast majority of users will be using.

stealth commented 9 years ago

The README explains the PFS situation, why used keys are tagged and that you should erase them if you want PFS. opmsg could burn them after reading itself, but this would give even more tears. So if you know what you are doing and want your PFS, just shred -u 'used' keys.

I agree to use the safest ciphers as default, but I wont consider GCM safer than CBC mode. Indeed block cipher modes are considered stronger than stream ciphers such as CTR or GCM. What makes GCM "stronger" is the use of AAD, but as message signing is mandatory in opmsg, GCM with its AAD has no real benefit compared to CBC.

bnagy commented 9 years ago

but I wont consider GCM safer than CBC mode. Indeed block cipher modes are considered stronger than stream ciphers such as CTR or GCM.

Well that's an astonishing claim. I'll leave you to it, then.

(I'll just leave this here http://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf)

stealth commented 9 years ago

FWIW, a --burn option has been added to nuke ephemeral key after decryption as well as support for EC personas and ECDH Kex. EC persona creation just takes a few ms, so its really easy creation and throw-away. Recommended to use recent libressl/openssl clone since only newer versions have brainpool EC curves.

bnagy commented 9 years ago

How did I know you would pick Brainpool? ;) Please tell me you also support 22519?

I'm interested in the persona creation now you have EC support. So it should be reasonable now to have a persona per recipient, right? Can this be automated?

stealth commented 9 years ago

25519 will be integrated as soon as either libressl or openssl make it selectable via their API. So far I havent found any traces of their group parameters in their gits. Right, the main point with EC personas is that you can have per-rcpt persona as its effectively takes no time to generate them. You need to --link them after you --imported your peer. Cant be automated more as it is, since I wouldnt know your ID's or that of your peers and I cant think of any heuristics that would determine which import belongs to which local persona.