I guess that's bad unless it fits in a cache line though...
Conversation
I always did things like ((a-b)|(b-a))>>31, which a good compiler with constant-time properties in mind would not convert to a branch, but I have no idea if LLVM would...
2
LLVM (and gcc, but less so) is pretty good at recovering "simpler" branches. __builtin_unpredictable helps a bit.
2
1
Seems like some volatile intermediates might be a cleaner way to block it.
1
Outside of compilers targeting embedded systems, I'm very hesitant to rely on volatile to do anything. It seems like the C standard gives license to the compiler to optimize out volatile accesses if it can prove the side effects aren't needed.
1
They can't generally justify removing writes though, since they could be used outside the process. Perhaps they can justify removing reads, but I think that's a bit sketchy. What if the read was going to fault, and the fault was going to be handled? There's a lot requiring this.
3
In general, there's no way to write robust constant-time code in a language without a clear contract from the toolchain though. GCC and LLVM don't offer it. For example, what happens to supposedly constant-time code when using sanitizers? Even with asm, what does a CPU guarantee?
2
1
Right but time can be mitigated by spinning up to expected max time. Branches otoh leak to cache state and are much worse. Compiler should not be randomly introducing them.
1
What if you build the code with options to assure memory safety or to mitigate exploitation, and this ends up introducing various branches that break the constant-time guarantee?
Also, separately, maybe CMOV isn't actually always constant-time. I doubt it's documented as such.
1
Time can be solved (just spin until total elapsed is constant). Branches are far worse because they have observable cache effects.
2
What about non-cryptographic code though, like the code working with the sensitive data that was decrypted?



