yesodweb / clientsession

Stores web session data in a client cookie, protected with authentication and encryption.
MIT License
24 stars 14 forks source link

Use AEAD's GCM / OCB instead of encryption+MAC. #23

Open vincenthz opened 10 years ago

vincenthz commented 10 years ago

The AES-CTR+Skein-MAC method used by clientsession could be replaced by AES-GCM or AES-OCB, and in theory it would be much faster (practically current version have lot of room for optimisations). Provided I send a PR for this, does clientsession need to remain backward compatible, and is that a good idea to provide different choosable alternatives to the user ?

snoyberg commented 10 years ago

@meteficha Do you have an opinion on this? I haven't really looked at the crypto aspects of clientsession in a long while.

meteficha commented 10 years ago

Regarding backwards compatibility, when upgrading the library all users will have their sessions invalidated. Either we do nothing and just bump the major version, or we'd have to maintain both implementations for some time in order to keep both kinds of sessions up.

Regarding AES-GCM, I would not be very comfortable with implementing this algorithm myself since I hear it's easy to screw up doing so. Assuming that someone more knowledgeable than me implemented these algorithms (e.g., @vincenthz :)), I don't have any objections to using it on clientsession. skein was faster at the time that I've benchmarked the library, but that was a long time ago.

Regarding AES-OCB, I'm against it since it's encumbered by patents.

Regarding providing choosable alternatives, I don't think we should do that. We should just make the best choice we can (wrt. security and performance). Given that we're aiming for 256 bits of security, I can't see how giving more choices would benefit anyone.

snoyberg commented 10 years ago

Sorry, I forgot to discuss backwards compatibility. I think it's OK to simply drop it, having users log in again is acceptable.

vincenthz commented 10 years ago

Both GCM and OCB are already implemented in cipher-aes. So it would just be a matter of using them. Conveniently they are behind the same API and they work the same way, so it's easy to switch between the two.

OCB patents are not worldwide (only USA is covered), and since 2013 Rogaway provide nice licenses for opensource (which cipher-aes fall in, as BSD3 software). see http://www.cs.ucdavis.edu/~rogaway/ocb/license.htm. It's also going through IETF standardization at the moment.

OCB is my favorite choice, and it's easier to make fast than GCM. GCM pretty much requires pclmulqdq instructions to go fast and at the moment cipher-aes doesn't even have support for accelerated GCM.

I don't think it's necessarily a bad thing to offer a way to have alternatives, specially if it is easy to switch between alternative and that's there is a good default. I think that's different use case (based on the actual security of the data in this session) and scenarios (server with no accelerated instructions) might warrant having multiple backends.

meteficha commented 10 years ago

I didn't read the text of the patent license, but I would assume that one may not integrate OCB on a proprietary, commercial software even though Yesod is open source. If my understanding is correct, using OCB on Yesod would be like putting a landmine on the library. My opinion is that it should not be included, not even as an option, especially if it comes with the tempting label of having better performance.

vincenthz commented 10 years ago

Considering pretty much every aspect of software is now a mine fields of patents, this is hard to believe that somehow stuff in Yesod or in many other place is not infringing some patents somewhere already. That being said, I still think the patent risks are fairly small here.

The patents are USA only, so anyone in the world except in the US can use it without having to consider patents. And I don't think it impact the clients of sessions, has they have nothing to do with the session blob they receive (no decryption/encryption).

License 1 is covering every opensource use for US user. if it remain opensource BSD/GPL/etc.., anyone can use it through this patent license.

Proprietary software using ocb mode through cipher-aes would be covered by license 2, which allow software implementation for commercial and non-commercial use for US users, provided it's not used by the following US agencies : Department of Defense, Armed Forces, Department of Energy; Department of Homeland Security and intelligence agencies.

Those agencies wouldn't use something non NIST standardized like CTR+Skein or OCB anyway (or Haskell probably), so the chances that the licenses overlapping doesn't cover every use related to users of clientsession, are pretty slim.

vincenthz commented 10 years ago

Also one thing about clientsession's current state.

For example AES256 seems overblown for most use (US TOP SECRET level !). Quoting Bruce Schneider: "And for new applications I suggest that people don't use AES-256. AES-128 provides more than enough security margin for the forseeable future."

And Skein MAC 512 taking a massive 64 bytes key (hence a key space that is square of aes256's key space, 2^512 !). I can understand the need for being conservative and again, some people might need those level, but I think it would be good to offer choices to the users related to their usage. It could remain simple like:

data SecurityLevel = OnlyAuth | High | Extreme

Where each options would (try to) explain the tradeoff.

meteficha commented 9 years ago

I just took a stab at using AES-GCM. Unfortunately, the results weren't promising benchmark-wise. You can see them here: https://gist.github.com/meteficha/a2bea768ef3255f8ab70. At best AES-GCM was 28% slower, but on a unrealistic session size (80kb). At worst it was 7.6x slower (0-byte session).

My CPU doesn't have AES-NI instructions, but the old version was using AES-CTR. IIUC, AES-GCM should need just one more AES block encryption wrt AES-CTR.

My CPU also doesn't have the PCLMULQDQ instruction, perhaps this would make a huge difference? Do most server CPUs have these instructions?

@vincenthz Do you think there's room for improvement on my stab? Besides lowering to AES128, as it would make for a unfair benchmark :P.

meteficha commented 9 years ago

I forgot to mention, this is the commit: https://github.com/meteficha/clientsession/commit/e5960ee7e383dc7168f14df06335700a459950a9. The benchmark is built with --enable-tests. You can build the Skein one by taking the parent of that commit.

vincenthz commented 9 years ago

@meteficha: this is very likely the problem is on my side, as currently GCM is still quite slow compared to state-of-the-art implementations out there. My implementation of GCM doesn't use PCLMULQDQ as of yet; So it shouldn't make a difference overall in your benchmark that you don't have a cpu that support it.

GCM need one GFmul per blocks in addition to CTR mode, which is the place that is severely not optimised.

meteficha commented 9 years ago

@vincenthz I took a cursory look at your code and the only room for improvement I saw besides GFmul was removing SecureMem copies. But at best this would bring improvements for the short plaintext case, the large plaintext case probably wouldn't be affected since there are a constant number of SecureMem copies. IOW, AES-GCM would probably still be slower. However, I'm not confident enough to try to optimize GFmul.

My current opinion is that using something more standard such as AES-GCM would be nice, but performance is the priority. (After security, of course, but I AFAIK: Skein-MAC is secure, its reference implementation is bug-free, my bindings don't introduce any problems.)

jckeme commented 8 years ago

@vincenthz Hi, Sorry for bringing up this thread again. So did you end up implementing AES-OCB in any form? If yes, I am wondering how possible it might be to do this since there seems to be some liberty to use the AES-OCB for academic purposes.

vincenthz commented 8 years ago

@jckeme: yes AES-OCB has been implemented in cryptonite; also related ChaChaPoly1305 is available, which is my favorite default choice lately for this purpose.