Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mem.timingSafeEql() for constant-time array comparison #6140

Closed
wants to merge 1 commit into from

Conversation

jedisct1
Copy link
Contributor

Add mem.timingSafeEql() for constant-time array comparison.

  • Assembly code is generated on x86_64. SSE2-only, so compatible with a baseline CPU target).
  • On other targets, best efforts are made to avoid compiler optimizations by avoiding inlining and using empty assembly blocks.

More assembly implementations are planned to be added shortly after (starting with arm & aarch64).

@daurnimator daurnimator added the standard library This issue involves writing Zig code for the standard library. label Aug 23, 2020
@komuw
Copy link

komuw commented Aug 23, 2020

also relevant: #1776

@kubkon
Copy link
Member

kubkon commented Aug 25, 2020

The Windows fail seems mysterious.

@jedisct1 jedisct1 force-pushed the timingSafeEql branch 2 times, most recently from 2eefd15 to b4d0c7f Compare August 26, 2020 09:39
@jedisct1 jedisct1 force-pushed the timingSafeEql branch 3 times, most recently from 59c22dd to 78e5ada Compare September 9, 2020 10:17
@jedisct1
Copy link
Contributor Author

@andrewrk Do you have any idea about what could explain the failure with MSVC?

This happens even if the tests are removed, and the functions are not called anywhere.

@kubkon
Copy link
Member

kubkon commented Sep 23, 2020

@jedisct1 when I find some time, I'll spin up your changes on Windows locally and see if I can help out with debugging the issue with the CI.

@jedisct1
Copy link
Contributor Author

Thank you @kubkon !

@jedisct1
Copy link
Contributor Author

@kubkon
Copy link
Member

kubkon commented Sep 26, 2020

Darn, can't seem to be able to replicate the fault locally...

@jedisct1
Copy link
Contributor Author

Fun :(

@LemonBoy
Copy link
Contributor

Given that the functions are meant to compare small (< 100 bytes) I'd go for something simpler. I definitely agree on implementing the core logic with an inline asm block, but I see no need to take out the big guns, let's write a single function that uses a siiiimple byte-by-byte loop that's portable, simpler to write, read and audit and serves its main purpose. I'd also change the != 0 to use some bit-level trickery (eg. or all the 8 result bits together) and avoid a conditional branch there (using cmov is cheating?) to make the whole comparison as robust as possible wrt LLVM influence.

This paper proposes and interesting statistical method to check for info leakages, it may be interesting to run the resulting function trough the same evaluation process and see how well it fares.

- Assembly code is generated on x86_64. SSE2-only, so compatible
with a baseline CPU target).
- On other targets, best efforts are made to avoid compiler
optimizations by avoiding inlining and using empty assembly blocks.
@andrewrk
Copy link
Member

andrewrk commented Oct 22, 2020

I'd like to explore #1776 before resorting to this. The approach in this patch - which I recognize is the industry-accepted standard in all other programming languages - throws away all the language semantics, and basically amounts to giving up and coding in assembly. It moves into userland the main thing that a compiler is supposed to do: converting language semantics into code generation to many different architectures, keeping up with new CPUs and features, and catching bugs via semantic analysis. It thwarts zig's comptime feature- the ability to call the same functions both at comptime and runtime. And yet it's still tricky to use correctly, landmines are present at the seams of the APIs here.

Let's spend energy towards #1776 before spending it on this kind of thing. I want to climb the big mountain, not the small hill next to it. We can come back to this if it turns out #1776 won't work out. But I don't want to green light this as part of the standard library until that possibility is exhausted.

Here's a start: at which callsites did you want to use this function? Let's pick one example, and see if we can start working on #1776 and do a proof of concept with it.

I hope you can give this a chance. I think this could potentially not work out, but on the other hand, this could end up being a big deal and make a huge paradigm shift in the field of software security. I think it's worth a shot.

@andrewrk andrewrk closed this Oct 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants