4 ms·
Sorry, 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 pa
by richm44 12y ago
Sorry, 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?
- richm44 12y ago> 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. Take a look. You'll see that for example openssl uses perl to generate assembly, and nettle also uses native code. This is needed if you want to use things like the AES instructions on modern CPUs.
- nitrogen 12y agoIf the code paths are identical (failure and success) what is it optimising out exactly? JITs can create separate versions of a function for different inputs. A good JIT can turn one general case function into multiple optimized special cases using techniques that include eliminating pseudoconstants (variables that always have the same or a small number of values) and skipping computation of never-referenced results. Even normal compilers can do a lot of that.
- yohanatan 12y agoI think a succinct way to put it is: on-the-fly "profile-guided optimization". A good JITter will do this automatically (as you said).