5 ms·
I'm saying they're unfixable because there's no way to tell the JIT to create constant-time code. Certainly Christopher Meyer has said that he's reported some t
by richm44 12y ago
I'm saying they're unfixable because there's no way to tell the JIT to create constant-time code. Certainly Christopher Meyer has said that he's reported some that remain private since they've not been fixed.
Heartbleed was certainly easier to exploit, than a timing attack - no disagreement there. But the Java SSL stack is pretty flakey and largely seems to be unused. It has lots of interoperability problems with other implementations and generally seems immature. It's not something I'd trust in production myself.
- Someone1234 12y ago> I'm saying they're unfixable because there's no way to tell the JIT to create constant-time code. What does that even mean? If you write your fail and success states to follow the same exact code paths (i.e. no branches, breaks, returns, or similar for failed) then you've created a "constant time" function. The inputted parameters are dynamic so the JIT-compiler cannot optimise code away, and even if it could it would do so equally for both the failed or success states. > Certainly Christopher Meyer has said that he's reported some that remain private since they've not been fixed. I tried Googling that but nothing. Can you link whatever it is you're talking about?
- richm44 12y agoCertainly. I was referring to this blog post, http://armoredbarista.blogspot.co.uk/2014/04/easter-hack-even-more-critical-bugs-in.html http://armoredbarista.blogspot.co.uk/2014/04/easter-hack-eve... however rereading it I see he was saying it was the ones in the hardware accelerators that haven't yet been fixed.
- richm44 12y agoSorry, I realised I'd failed to address your other point: "What does that even mean? If you write your fail and success states to follow the same exact code paths (i.e. no branches, breaks, returns, or similar for failed) then you've created a "constant time" function." Well, if you've got a JIT that is analysing which code actually executes, and no control over the optimisations then how do you achieve this? If the hotpath is normally the success condition for example then the JIT will optimise that more. The rare and more dangerous condition will be optimised less. If this happens of course will depend on the engine, but you can't control that without working at a much lower level than managed code offers.
- Someone1234 12y ago> Well, if you've got a JIT that is analysing which code actually executes, and no control over the optimisations then how do you achieve this? The same is true with native code optimising. > If the hotpath is normally the success condition for example then the JIT will optimise that more. The paths should be identical for both failure and success states. That's fundamentally how you "fix" timing attacks. > If this happens of course will depend on the engine, but you can't control that without working at a much lower level than managed code offers. You write code that has no hot paths regardless of if correct/wrong. That's how timing attacks are mitigated in all languages.
- richm44 12y ago> The same is true with native code optimising. This is rubbish. If I use custom assembler then that's what gets run. Even if I use C code then I know what the result will be since I can actually check. > The paths should be identical for both failure and success states. That's fundamentally how you "fix" timing attacks. That's certainly the ideal. But it's impossible - one result will succeed the other won't. The aim is to make sure both take the same time which is an achievable goal, however to do this you need to know what will execute. You might have that guarantee in practice on a particular JVM for example, but the whole point of using something like a JIT is that it will be smart about optimising stuff based on what actually happens. That's normally great, but this is a situation where all that needed is predictability not performance.
- Someone1234 12y ago> This is rubbish. If I use custom assembler then that's what gets run. Even if I use C code then I know what the result will be since I can actually check. It is "rubbish?" Nobody does that. Most crypto libraries are written in C or C++. You can pre-JIT (AOT) managed code and check there too. > That's certainly the ideal. But it's impossible - one result will succeed the other won't. It is absolutely possible with high coding standards. Keep in mind you only have to write "correct" code in sections which have access to things like crypto keys (or things that are derived from similar), since that's what at risk with timing attacks. > You might have that guarantee in practice on a particular JVM for example, but the whole point of using something like a JIT is that it will be smart about optimising stuff based on what actually happens. If the code paths are identical (failure and success) what is it optimising out exactly?
- mike_hearn 12y agoHe's talking about a couple of recent very clever timing attacks on JSSE. However they are not comparable to Heartbleed or this SChannel overflow in severity at all: (1) They require you to have a pre-recorded SSL session you're trying to crack. Random script kiddies won't find it useful. (2) They require sending a lot of traffic to the server to try and break that single recording (you can get caught quite easily!) (3) They don't reveal the private key, only per connection premaster secrets (if I understood correctly). Basically, the first attack was possible because JSSE returned "internal server error" when faced with a particular kind of malformed packet instead of "bad padding" - this binary yes/no thing was enough to allow the attacker to divine some internal state and with enough queries retrieve the PMS. The second was a similar trick but instead of observing a different error code, it exploited the fact that internally the code was throwing an exception and this made a difference of some microseconds in the response. Over a LAN, with enough queries, that was enough to eventually reveal the PMS. However when running over a much noisier environment like the internet, number of queries required goes up quite a bit. I believe, they did not test that. As I said before, they were both fixed, and I think Rich now agrees with me that they were fixed. There may be others that would require compiler support or hand coding of assembly to fix. Certainly there's nothing in the design of Java or the JVM that makes that impossible however. Stuff handling key material is only a small part of the overall SSL picture.
- richm44 12y agoYeah, like I said in my other comment, I'd misread which issues have been fixed. I still stand by point that for constant time you need to be close to the metal but I think we're in agreement there anyway. I think using native code for the low-level implementation of the ciphers, padding etc. would be a good move from a security point of view and is the only way to get constant time implementation. As you say, there's nothing that prevents that in the design of Java.
- mike_hearn 12y agoRight - it is looking more and more like truly constant time code can only be obtained by using hand written assembly or hardware. In that eventuality, I guess the core crypto code in the JVM will have to be changed to use hand written assembly as well, however, SSL is huge and most of it doesn't need to be constant time (certificate parsing, managing network buffers, message parsing etc). That is often where the bugs creep in. Going with JSSE does have the downside that it's less widely used. Browser makers don't patch it with the latest gizmos like they do with OpenSSL. However, it's at least got a full time development team (unlike OpenSSL until very recently), and ultimately if there are odd conformance bugs lurking the only way they'll be shaken out is by people using it for real. Passing the Qualys test is a good start, but for now my little website is ideal because it is unlikely to ever be popular enough to have serious scaling issues and I can tolerate some incompatibility with odd clients.
- richm44 12y ago"Right - it is looking more and more like truly constant time code can only be obtained by using hand written assembly or hardware. In that eventuality, I guess the core crypto code in the JVM will have to be changed to use hand written assembly as well, however, SSL is huge and most of it doesn't need to be constant time (certificate parsing, managing network buffers, message parsing etc). That is often where the bugs creep in." I completely agree with you there. X.509 is a nightmare and it's not an area where constant time matters at all. Being resistant to buffer overruns and general logic errors is much more important there.
- dvanduzer 12y agoX.509 is a nightmare because it is complex, and the political infrastructure is vulnerable. There is no reason ciphers like djb's that use data-independent code paths couldn't be integrated into X.509 if the will was there. Totally separate issues.
- ars 12y ago> can only be obtained by using hand written assembly or hardware Even that is harder than it looks. For example, a common way of doing a constant time string compare is: $result |= (ord($safe[$i % $safeLen]) ^ ord($user[$i])); i.e. get the character to compare mod the length, so you wrap around if the length of the two strings is not the same. Unfortunately the mod operator does not take a constant time on a CPU! If the result is evenly divisible it's faster. So even in assembly you might not be able to protect from a timing attack. Even if you check your current CPU a new one might be different. (In this case a better way to do the compare is if the strings are not the same length, compare the attackers string against itself, and then return false.)
- pjmlp 12y ago> I'm saying they're unfixable because there's no way to tell the JIT to create constant-time code. Your fallacy is that there are several JVMs to choose from, each with its own set of JIT and AOT compilers. Don't judge Java by OpenJDK, it is only the reference implementation.