5 ms·
"Let's just rewrite all the crypto ourselves! In assembly!" Sorry to be a buzzkill, but that sounds like a recipe for disaster.
by thomasahle 12y ago
"Let's just rewrite all the crypto ourselves! In assembly!"
Sorry to be a buzzkill, but that sounds like a recipe for disaster.
- imaginenore 12y agoIf it's tested extensively, it should be fine. Somebody has to write the crypto.
- vitriol83 12y agowithout formal methods it's impossible to fully test crypto implementations, such as ECDH, because the number of possible inputs are enormous. bugs in small proportion of inputs can lead to fault attacks. and furthermore side channel attacks are very common.
- imaginenore 12y agoThat's true of every crypto implementation.
- vitriol83 12y agoSure, that's why I think there's an argument to use ones which are more 'battle tested'.
- amaranth 12y agoThat's not an option here though because of the poor performance of Go's C FFI infrastructure. It's like Java in this regard, unless you're handing off large batches of work to the C level all at once it's more efficient to just do the work in Go. Except in this case pure Go isn't fast enough either thus assembly.
- Twirrim 12y agoGo's existing crypto library is far from battle tested either (as well as being comparatively slow)
- tptacek 12y agoGo's crypto library is probably the best of all the "standard library" crypto implementations. The modal standard crypto library among other languages is a set of bindings to OpenSSL.
- lmm 12y agoThe most popular language around is still Java, I think? Which comes with a reputable, non-OpenSSL crypto implementation in its standard library.
- TheLoneWolfling 12y agoExcept that it's quite literally impossible to ensure data-independent timing in Java - or, for that matter, in any language that does optimizations without a way to disable them. Yes, this includes standard-compliant C / C++, ironically enough. JITters are especially bad for this - what is data-independent today may not be data-independent tomorrow. Or even in a couple minutes when it decides to re-optimize. You ultimately have to dip down to assembly, or something that can be relied on to not do data-dependent optimizations, to ensure resilience against timing attacks. JNI can work, as can inline assembly in things like C / C++, or specifying compilers. But that's just punting things to another language. And you lose portability, among other things. Or worse, you end up with something that looks like language X, and is valid code in language X, but breaks evilly if it's ever run as though it was in language X.
- tptacek 12y agoNo, I do not think Java's crypto library is as well regarded as Golang's. For example, didn't Java SSL recently manage to reincarnate the Bleichenbacher padding oracle?
- pjc50 12y agoYeah, the point of moving from C to Go would be to get away from all the disasters. But if the core is small enough using short bursts of inline assembly to actually calculate the cipher, while all the complex protocol handling and buffer manipulation is done in the safe layer, it would be a good solution. Edit: that does indeed appear to be what they've done. In particular using the AESENC instruction. https://github.com/cloudflare/go/blob/master/src/crypto/aes/aes_gcm_amd64.s https://github.com/cloudflare/go/blob/master/src/crypto/aes/...
- 4ad 12y agoAll the low-level crypto is written in assembly. And not only for speed, but for ensuring properties like constant-time execution, etc. It's the same for OpenSSL, and the same for commercial crypto libraries. Go is not at all different here. The difference is that the higher-level crypto is written in Go, not in C; Go is memory safe, much more strongly-typed in general, and with run-time bounds checking which eliminate buffer overflows. The bugs are almost never in the low-level algorithms, they are in the higher-level components.
- alfiedotwtf 12y agoThere was a post on HN a few weeks ago talking about "ensuring properties like constant-time execution" isn't possible as instruction timings doesn't take in account things like caching, pipelining, task switching, microcode optimisations etc.
- sdevlin 12y agoWhen people describe crypto code as "constant-time", they typically just mean its execution time is data-independent.
- zurn 12y agoOpenSSL does optional assembly implementations for many primitive+platform combinations, but also many of the algorithms under crypto/ have zero or one architectures covered. And many asm implementations predate widespread concerns about timing attacks.
- jussij 12y agoAnd only a year or two ago OpenSSL was found to have a major hole (i.e. remember Heartbleed), caused by a buffer overrun bug that had been around for years. If I remember correctly I also remember reading on the Go forums Go didn't have that issue, only because it had been fully re-written.
- grittygrease 12y agoThe OpenSSL AES-GCM and P256 assembly code was also written by Vlad. There's no better person to write the Golang version.
- thomasahle 12y agoThat's a good argument. However (unless the changes get merged upstream) it is still one more crypto library for 'bad people' to find weaknesses in.
- sdevlin 12y agoNeat, I didn't even notice this. Vlad Krasnov is also a co-author of this paper on state-of-the-art P256 implementation: https://eprint.iacr.org/2013/816.pdf https://eprint.iacr.org/2013/816.pdf.
- sdevlin 12y agoA couple points on this. First, as some have noted, serious crypto primitive implementations are written in assembly. This is both to achieve state-of-the-art performance as well as data-independent execution times. The latter is important to prevent timing attacks. Second: I'm not sure if this was your point, but some have invoked Heartbleed and other native code disasters. But the kind of problems that lead to Heartbleed aren't likely to be a problem in low-level crypto implementations. This is because they tend to operate on fixed-size buffers using algorithms with little or no conditional logic. While there could certainly be mathematical flaws (i.e. producing the wrong output), something like a buffer overrun is not likely here. If you look in basically any crypto library, you will find important primitives implemented in assembly. This is even true in the main Go repository, where AES is implemented in assembly.
- deleted 12y ago[deleted]