6 ms·
> it's the C standard that is under specified to the author's liking Isn't this unreasonable? Here we are, 52, years down the road with C et al. and suddenly
by topspin 2y ago
> it's the C standard that is under specified to the author's liking
Isn't this unreasonable? Here we are, 52, years down the road with C et al. and suddenly it's expected that compiler developers must consider any change in the light of timing attacks? At what point do such new expectations grind compiler development to a halt? What standard would a compiler developer refer to to stay between the lines? My instincts tell me that this would be a forever narrowing and forever moving target.
Does timing sensitivity ever end? Asked differently: is there any code that deals in sensitive information that can't, somehow, be compromised by timing analysis? Never mind cryptographic algorithms. Just measuring the time needed to compute the length of strings will leak something of use, given enough stimuli and data collection.
Is there some reason a cryptographic algorithm developer must track the latest release of a compiler? Separate compilation and linking is still a thing, as far as I know. Such work could be isolated to "validated" compilers, leaving the insensitive code (if that concept is even real...) to whatever compiler prevails.
Also, it's not just compilers that can "optimize" code. Processing elements do this as well. Logically, therefore, must we not also expect CPU designers to also forego changes that could alter timing behavior? Forever?
I've written a lot of question marks above. That's because this isn't my field. However, invoking my instincts again: what, short of regressing to in-order, non-speculative cores and freezing all compiler development, could possibly satisfy the expectation that no changes are permitted to reveal timing differences where it previously hadn't?
This all looks like an engineering purity spiral.
- dataflow 2y ago> Isn't this unreasonable? Here we are, 52, years down the road with C et al. and suddenly it's expected that compiler developers must consider any change in the light of timing attacks? We already went through a similar case to this: when the C++11 multithreaded memory model was introduced, compiler authors were henceforth forced to consider all future optimizations in light of multithreading. Which actually forced them to go back and suppress some optimizations that otherwise appeared reasonable. This isn't to say the idea is good (or bad), but just that "compiler development will grind to a halt" is not a convincing against it.
- uecker 2y agoIt is completely unreasonable though to assume that a compiler should now preserve some assumed (!) timing of source operations. It would be reasonable to implement (and later standardize) a pragma or something that specifies timings constraint for a subset of the language. But somebody would need to do the work.
- mst 2y agoAn attribute for functions that says "no optimisations may be applied to the body that would change timings" seems like a reasonable level of granularity here, and if you were conservative about which optimisations it allowed in version zero it'd probably not be a vast amount of work. I'm sort of reminded of the software people vs. hardware people stuff in embedded work, where ideally you'd have people around who'd crossed over from one to another but (comparing to crypto authors and compiler authors) there's enough of a cultural disconnect between the two groups that it doesn't happen as often as one might prefer.
- saalweachter 2y agoWhy not just specify "all branches of this code must execute in the same amount of time", and let the compiler figure it out for the architecture being compiled for?
- davrosthedalek 2y agoInstruction duration isn't constant even within the same arch. You cannot have branches in constant-time code. I do wonder though how often cpu instructions have data-dependent execution times....
- davrosthedalek 2y ago(Correction: You cannot have data-dependent branches. You can of course have branches to make a fixed-iterations for loop, for example)
- komon 2y ago> Is there some reason a cryptographic algorithm developer must track the latest release of a compiler? Tracking the latest release is important because: 1. Distributions build (most? all?) libraries from source, using compilers and flags the algorithm authors can't control 2. Today's latest release is the base of tomorrow's LTS. If the people who know most about these algorithms aren't tracking the latest compiler releases, then who else would be qualified to detect these issues before a compiler version bearing a problematic optimization is used for the next release of Debian or RHEL? > Logically, therefore, must we not also expect CPU designers to also forego changes that could alter timing behavior? Maybe? [1] > freezing all compiler development There are many, many interesting areas of compiler development beyond incremental application of increasingly niche optimizations. For instance, greater ability to demarcate code that is intended to be constant time. Or test suites that can detect when optimizations pose a threat to certain algorithms or implementations. Or optimizing the performance of the compiler itself. Overall I agree with you somewhat. All engineers must constantly rail against entropy, and we are doomed to fail. But DJB is probably correct that a well-reasoned rant aimed at the community that both most desires and most produces the problematic optimizations has a better chance at changing the tide of opinion and shifting the rate at which all must diminish than yelling at chipmakers or the laws of thermodynamics. [1]https://en.m.wikipedia.org/wiki/Spectre_(security_vulnerability) https://en.m.wikipedia.org/wiki/Spectre_(security_vulnerabil...
- thesz 2y ago> short of regressing to in-order, non-speculative cores I guess you are referring to a GPU cores here. It is a joke but can hint that in-order non-speculative cores are powerful computers nonetheless.
- SkiFire13 2y agoThey are a totally different kind of powerful computer though, you can't compare them for sequential workloads.
- topspin 2y agoYou make a fine point. If you follow this regression to its limit you're going to end up doing your cryptography on a MCU core with a separate, controlled tool chain. TPM hardware has been a thing for a while as well. Also, HSMs. This seems a lot more sane than trying to retrofit these concerns onto the entire stack of general purpose hardware and software.
- NohatCoder 2y agoWe had ~30 years of "undefined behaviour" practically meaning "do whatever the CPU does". It is not new that people want predictable behaviour, it simply wasn't a talking point as we already had it.
- GTP 2y agoIt's not even that. Yes, in case of signed intger overflow, usually yoj get whatever the CPU gives as answer for the sum. But you also have the famous case of an if branch checking for a null pointer being optimized away. And even in the case of integer overflow, the way to correctly check for it isn't intuitive at first, because you need to check for integer overflow without the check itsef falling under UB. EDIT: just to make my point clear: the problem with UB isn't just that it exists, it is also that compiler optimizations make it hard to check for it.
- atiedebee 2y agoWhen do NULL checks get optimised away, apart from the case where the pointer has already been accessed/is known at compile time to be invalid?
- GTP 2y agoI couldn't find again the example I saw many years ago, I could only find a GCC bug that has been fixed now. So you're likely right and I just didn't remember correctly. But we still can have the zeroing out of memory before deallocation that can get silently optimized away. Maybe also naive attempts at checking for signed integer overflow could be silently optimized away. My general point is that, if the compiler determines that the code has dead instructions/unneded checks, it is very likely that the programmer's mental model of the code is wrong. So, just like the case of using an integer as a pointer or vice versa, we should have a warning telling the programmers that some code is going to not be compiled. Also in the case of the null pointer check: this would make the programmer realize that the check is happening too late and should instead be performed earlier
- adrianN 2y ago
- klyrs 2y agoThe author is somewhat known for his over-the-top rants. When you read his writing in the context of a 90's flamewar, you'll find them to be quite moderate and reasonable. But it comes from a good place; he's a perfectionist, and he merely expects perfection from the rest of us as well.
- jeanlucas 2y ago> he's a perfectionist, and he merely expects perfection from the rest of us as well. Nicely put, but at the end perfectionism is a flaw.
- himinlomax 2y agoNot when computer security is concerned.
- klyrs 2y agoIn all things, moderation. Security must be evaluated as a collection of tradeoffs -- privacy, usability, efficiency, etc. must be considered. For example, you might suspect that the NSA has a better sieve than the public, and conclude that your RSA key needs to be a full terabyte*. We know that this isn't perfect, of course, but going much beyond that key length will prevent your recipient from decrypting the message in their lifetime. * runtime estimates were not performed to arrive at this large and largely irrelevant number
- saagarjha 2y agoSecurity is a tradeoff. Perfect security is not using a computer.
- jeanlucas 2y agoSecurity is a constant tradeoff, and trading off time for perfectionism is not a good one to take.
- duped 2y ago> This all looks like an engineering purity spiral. To get philosophical for a second, all of engineering is analyzing problems and synthesizing solutions. When faced with impossible problems or infinite solution space, we must constrain the problem domain and search space to find solutions that are physically and economically realizable. That's why the answer to every one of your questions is, "it depends." But at the top, yes, it's unreasonable. The C standard specifies the observable behavior of software in C. It does not (and cannot) specify the observable behavior of the hardware that evaluates that software. Since these behavior are architecture and application specific, it falls to other tools for the engineer to find solutions. Simply put, it isn't the job of the C standard to solve these problems. C is not a specification of how a digital circuit evaluates object code. It is a specification of how a higher level language translates into that object code.