10 ms·
Guidelines for low-level cryptography software
- nsajko 7y ago> Some compilers will optimize out operations they deem useless. A compiler translates a certain language to machine code. If it is optimizing it will use that language's semantics for optimization. That is necessary, otherwise we would be writing almost everything in assembly. > Know what optimizations your compiler can do, and carefully consider the effect of each one on security programming patterns. In particular, be careful of optimizations that can remove code or branches, and code that prevents errors which "should be impossible" if the rest of the program is correct. A priority is to understand the language one is writing in. > When possible, consider disabling compiler optimizations that can eliminate or weaken security checks. A better solution is to use assembly language and thus exactly specify your program's semantics within the program; that compiler flag could be removed by whoever builds the program, or something like link-time optimization.
- karl_schlagenfu 7y ago> A priority is to understand the language one is writing in. That's all well and good but you can't expect a developer to know all the optimisations different compilers will do, especially when it relates to undefined behaviuor.
- charleslmunger 7y agoI think the point of the OP is that you shouldn't think about the optimizations a compiler might do, but what the language spec guarantees. If the language spec guarantees that your code behaves the way you want, no correct compiler will break it.
- zokier 7y agoThe problem arises when the language simply does not provide any guarantees on the sorts side-effects you are interested in, so you can not simply rely on specified behavior.
- zaarn 7y agoAnd next thing you know, 1000 people with compilers that subtle do not behave to spec knock on your door.
- irundebian 7y agoIt's worrying that for some cases you have to put a lot of effort into "obscuring" code and destroy readability to comply with the rules just because the C's semantics is not obvious and its type system weak and dated. A good language for cryptography engineering should at least somehow allow the programmer to annotate/type variables containing secret data and functions as constant-time so that the programmer can concentrate on implementing the cryptography logic while the compiler warns on correctness issues or security violations.
- nickpsecurity 7y agoYup: https://www.cryptol.net/ https://www.cryptol.net/ https://cseweb.ucsd.edu/~dstefan/pubs/cauligi:2017:fact.pdf https://cseweb.ucsd.edu/~dstefan/pubs/cauligi:2017:fact.pdf There's also program analysis work in this area: https://michael-emmi.github.io/papers/conf-uss-AlmeidaBBDE16.pdf https://michael-emmi.github.io/papers/conf-uss-AlmeidaBBDE16...
- ReidZB 7y agoI admit I've only ever taken cursory glances at Cryptol, but it's never seemed like a replacement for the sort of low-level programming described in the article. If anything, it goes the opposite way - its Haskell base inherits one of Haskell's flaws, namely that it can be difficult to understand the runtime/performance implications of Haskell code without careful analysis. Cryptol's README describes it as a sort of standardization/prototyping language. That said, I don't know these things for sure, and I'd love to be corrected if I'm wrong.
- nickpsecurity 7y agoIt's a higher-level language that generates or compiles to the lower-level forms, including C and hardware languages, so you don't have to worry about that stuff. The expert can specify the algorithm, mathematically verify it, synthesize it to code, another tool like Galois' SAW can verify that, and they usually do a certifying compiler (esp CompCert) at the end. Rockwell-Collins and Galois both use the tools in high-security projects. I can't remember if it addresses constant-time programming. So, I went looking arount, found the other language, and maybe someone will merge them.
- arkadiyt 7y agoThis is great for educational purposes, but if you're thinking of implementing your own primitives or cryptosystems please use a vetted out-of-the-box solution like libsodium instead.
- zokier 7y ago> On most operating systems memory owned by one process can be reused by another without being cleared Isn't this plainly false? I think on all mainstream platforms memory is cleared when it is mapped to process
- tempguy9999 7y agoSlightly tangential to the article but still important, it says "Some compilers infer that they can eliminate checks based on erroneous code elsewhere in the program. For example, [obviously dodgy code snipped]some compilers will decide that ptr == NULL must always be false, since otherwise it would be incorrect to dereference it in call_fn()" So why does the compiler not report this error, or better still reject the code outright? It seems to turn a compile-time-detected fatal error into a critically dangerous runtime error.