Live data from Hacker News

Constant-time support coming to LLVM: Protecting cryptographic code

blog.trailofbits.com

31–40 of 62 posts

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#31
post #14
post #2

This has been a sore point in a lot of discussions regarding compiler optimizations and cryptographic code, how compilers and compiler engineers are sabotaging the efforts of cryptographers in making sure there are no side-channels in their code. The issue has never been the compiler, and has always been the language: there was never a way to express the right intention from within C (or most other languages, really)…

What happened to the blog post? It was moved and now it has disappeared :-(

Sorry, it was published early and we have to wait for some approval checks to clear

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#32

Earlier quoted context omitted.

Sorry, I may be missing the point here, but reading that page doesn’t immediately make it obvious to me what that feature is. Is it some constant time execution mechanism that you can enable / disable on a per-thread basis to do… what exactly?

As a concrete example, say I have a (very naive and bad) password-checker that works like this pseudocode: > for i = 1 to len(real_password) { > if entered_password[i] != real_password[i] { > return FAILURE > } > } > > return SUCCESS OK now an alert attacker with the ability to very accurately record the time it takes to check the password can determine the length at least of the real password, because the time compl…

Why not just always spin until a fixed number of ticks (or microseconds for slewing clocks) have passed (starting from function entry), prior to returning?

Obviously this doesn't mitigate power usage side channel attacks, but that's not the point here.

It's time-bound, so let's check time.

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#33

Earlier quoted context omitted.

As a concrete example, say I have a (very naive and bad) password-checker that works like this pseudocode: > for i = 1 to len(real_password) { > if entered_password[i] != real_password[i] { > return FAILURE > } > } > > return SUCCESS OK now an alert attacker with the ability to very accurately record the time it takes to check the password can determine the length at least of the real password, because the time compl…

Why not just always spin until a fixed number of ticks (or microseconds for slewing clocks) have passed (starting from function entry), prior to returning? Obviously this doesn't mitigate power usage side channel attacks, but that's not the point here. It's time-bound, so let's check time .

Wouldn't that be much less efficient?

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#34
post #27

Earlier quoted context omitted.

There really ought to be a subset of C that lets you write portable assembly. One where only a defined set of optimisations are allowed and required to be performed, "inline" means always inline, the "register" and "auto" keywords have their original meanings, every stack variable is allocated unless otherwise indicated, every expression has defined evaluation order, every read/write from/to an address is carried out…

Why would you like register and auto to have meaning?

Because for timing-sensitive code, those are important. If a variable is really a register, cache-based timing attacks just don't happen, because there is no cache in between.

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#35

Earlier quoted context omitted.

As a concrete example, say I have a (very naive and bad) password-checker that works like this pseudocode: > for i = 1 to len(real_password) { > if entered_password[i] != real_password[i] { > return FAILURE > } > } > > return SUCCESS OK now an alert attacker with the ability to very accurately record the time it takes to check the password can determine the length at least of the real password, because the time compl…

Why not just always spin until a fixed number of ticks (or microseconds for slewing clocks) have passed (starting from function entry), prior to returning? Obviously this doesn't mitigate power usage side channel attacks, but that's not the point here. It's time-bound, so let's check time .

You could totally do that, but in the exact same way as the above, you'd want the compiler not to optimize your spinlock away thinking it wasn't needed. My understanding is in lots of real applications, the asm code that I mentioned is in part making sure it waits specific numbers of clocks in each branch to ensure they all exactly balance.

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#36

These are meaningless without guarantees that the processor will run the instructions in constant time and not run the code as fast as possible. Claims like cmov on x86 always being constant time are dangerous because a microcode update could change that to not be the case anymore. Programmers want an actual guarantee that the code will take the same amount of time. We should be asking our CPU vendors to support enab…

I agree. For use cases where side channel attacks are likely to be attempted, the security of the system ultimately depends on both the software and hardware used.

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#37
post #9

So this makes me curious: is there a reason we don't do something like a __builtin_ct_begin()/__builtin_ct_end() set of intrinsics? Where the begin intrinsic begins a constant-time code region, and all code within that region must be constant-time, and that region must be ended with an end() call? I'm not too familiar with compiler intrinsics or how these things work so thought I'd ask. The intrinsic could be scoped…

It'd be very hard for the compiler to enforce constant-time execution for generic code. As an example, if you wrote the naive password checking where the first byte that doesn't match returns false, is that a compiler error if it can't transform it into a constant time version?

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#38

Earlier quoted context omitted.

Sorry, I may be missing the point here, but reading that page doesn’t immediately make it obvious to me what that feature is. Is it some constant time execution mechanism that you can enable / disable on a per-thread basis to do… what exactly?

As a concrete example, say I have a (very naive and bad) password-checker that works like this pseudocode: > for i = 1 to len(real_password) { > if entered_password[i] != real_password[i] { > return FAILURE > } > } > > return SUCCESS OK now an alert attacker with the ability to very accurately record the time it takes to check the password can determine the length at least of the real password, because the time compl…

By the way, for small arrays removing branches also improves performance (according to my tests). So if you do a constant-time comparison like this:

    match = True
    for a, b in pad(entered_pass, real_pass):
        match = match and a == b
    return match
Then it will be faster as well. I was surprised to find this.

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#39

I think __builtin_ct_select and __builtin_ct_expr would be good ideas. (They could also be implemented in GCC in future, as well as LLVM.) In some cases it might be necessary to consider the possibility of invalid memory accesses (and avoid the side-channels when doing so). (The example given in the article works around this issue, but I don't know if there are any situations where this will not help.)

The names are pretty unattractive (which is not uncommon for C) though to the point one would want to avoid them in the code.

Re: Constant-time support coming to LLVM: Protecting cryptographic code

#40
post #23

Earlier quoted context omitted.

Last I saw, it seemed like the plan was to unconditionally enable it, and on the off chance there's ever a piece of hardware where it's a substantial performance win, offer a way to opt out of it.

I advocated for that, and then I completely lost track of the status. The whole design is ridiculous.

What would be more sane alternatives, when it becomes obvious that any side-effect of timing is a potential attack vector? See https://www.hertzbleed.com/ for frequency side channels. I do only see dedicated security cores as options with fast data lanes to the CPU similar to what Apple is doing with Secure Enclave or do you have better suggestions that still allow performance and power savings?
Post reply on HN