Live data from Hacker News

Constant-time support coming to LLVM: Protecting cryptographic code

blog.trailofbits.com

21–30 of 62 posts

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

#21
post #16

Too bad that Intel chips more or less reserve the right to take LLVM’s nice output and make it non-constant-time anyway. See: https://www.intel.com/content/www/us/en/developer/articles/t... Sure, you could run on some hypothetical OS that supports DOITM and insert syscalls around every manipulation of secret data. Yeah, right.

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?

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

#22
post #16

Too bad that Intel chips more or less reserve the right to take LLVM’s nice output and make it non-constant-time anyway. See: https://www.intel.com/content/www/us/en/developer/articles/t... Sure, you could run on some hypothetical OS that supports DOITM and insert syscalls around every manipulation of secret data. Yeah, right.

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?

It turns off CPU features that could cause execution time to vary in a way that depends on the data being operated on.

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

#23
post #16

Too bad that Intel chips more or less reserve the right to take LLVM’s nice output and make it non-constant-time anyway. See: https://www.intel.com/content/www/us/en/developer/articles/t... Sure, you could run on some hypothetical OS that supports DOITM and insert syscalls around every manipulation of secret data. Yeah, right.

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.

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

#24
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 enabling a constant time mode of some sort for sensitive operations.

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

#25
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 :-(

https://web.archive.org/web/20251125224147/https://blog.trai...

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

#26
post #16

Too bad that Intel chips more or less reserve the right to take LLVM’s nice output and make it non-constant-time anyway. See: https://www.intel.com/content/www/us/en/developer/articles/t... Sure, you could run on some hypothetical OS that supports DOITM and insert syscalls around every manipulation of secret data. Yeah, right.

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 complexity of this check is O(length of the real password), and they could also gradually determine the password itself because the check would take longer as the attacker got each successive character correct.

Taking this general idea and expanding it, there are lots of places where the timing of branches of code can leak information about some secret, so in cryptographic code in particular, it’s often beneficial to be able to ensure that two branches (the success and failure branches in the above) take exactly the same amount of time so the timing doesn’t leak information. So to fix the above you would probably want to do two things. Firstly set a boolean to failure and still continue the checking to ensure the “return failure quickly” problem doesn’t leak information and also change your password check to check against a fixed-width hash or something so the length of the password itself wasn’t a factor.

The problem is lots of performance optimizations (pipelining, branch prediction etc) work specifically against this goal- they aim to take branches quickly in the happy path of the code because normally that’s what you want to ensure optimal performance.

So say instead of the above I do

  > bool status = SUCCESS
  > for i = 1 to hash_length {
  >   if hash_of_entered_password[i] != hash_of_real_password[i] {
  >      status = FAILURE
  >   }
  > }
  >
  > return status 
…I don’t want the optimizer to realize that when status becomes FAILURE it can never become SUCCESS again and the loop doesn’t do anything else so just return early. I want it to actually run the pointless comparison of the rest of the hash so the timing is exactly the same each time.

But now my check is constant time but I’ve shifted the burden onto the person who writes the hash function. That has to run in constant time or my check will once again leak. So in general people want the ability to tell the compiler that they want a particular piece of code to run in constant time. At the moment, in the general case I think you have to break into inline assembly to achieve this.

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

#27
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)…

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, nothing is ever reordered, and undefined behaviour is switched to machine-specific behaviour. Currently if you need that level of control, your only option is writing it in assembly, which gets painful when you need to support multiple architectures, or want fancy features like autocomplete or structs and functions.

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

#28
post #27
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)…

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?

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

#29
post #27
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)…

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…

> want fancy features like autocomplete or structs and functions

I would argue that given a certain ISA, it's probably easier to write an autocomplete extension for assembly targeting that ISA, rather than autocomplete for C, or goodness forbid, C++.

Likewise for structs, functions, jump targets, etc. One could probably set up snippets corresponding to different sorts of conditional execution—loops, if/else/while, switch, etc.

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

#30

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…

That's been one of my counters to the bitch that C isn't safe. The underlying architecture isn't safe.

That said WG21 and WG14 don't seem to be able to get the memo that safety is more important than single core speed. Or as I suspect a bunch members are actually malicious.

Post reply on HN