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 constant-time AES-GCM that doesn't require assembly language #104

Closed
briansmith opened this issue Feb 4, 2016 · 16 comments
Closed

Add constant-time AES-GCM that doesn't require assembly language #104

briansmith opened this issue Feb 4, 2016 · 16 comments
Assignees

Comments

@briansmith
Copy link
Owner

Currently, we have AES-GCM implementations that are constant time for many advanced processors, with SIMD and/or dedicated instructions (e.g. AES-NI). However, we should have constant-time AES-GCM for every platform we support.

See https://bugzilla.mozilla.org/show_bug.cgi?id=868948 for ideas, though we can't copy code from that bug without assurances that we can use it under an ISC license or similar.

@DemiMarie
Copy link

The obvious implementation is dog slow.

There is a trick that uses precomputed tables and uses bitwise operations for lookups, but it is also slow, even with SIMD.

Some thoughts:

  • I believe that x86 chip built since 2003 has SSE2, so I think we can simply drop support for >= 13-year-old hardware.
  • My understanding of AArch64 is that SIMD is built in to that instruction set.
  • That leaves 32-bit ARM. IMO forcing such a chip to do AES-GCM is a bug in a higher-level protocol and/or its implementation (should be using ChaCha20-Poly1305), but in the real world some have no choice.

My first thought would be to check if cache lookups within a cache line are constant time on ARM32. Otherwise, such users will need to live with miserable performance.

@briansmith
Copy link
Owner Author

That leaves 32-bit ARM.

Also, eventually, MIPS. (I would live to eventually port ring to OpenWRT and other low-end MIPS devices.)

My first thought would be to check if cache lookups within a cache line are constant time on ARM32. Otherwise, such users will need to live with miserable performance.

That's mostly what I'm thinking too. See also the comments in aes-586.pl regarding cache timing countermeasures.

@jkilpatr
Copy link

@briansmith what would be the criteria for a solution to this issue? Long story short we need mips support and are in a position where we pretty much just have to add it.

Can we make a arch generic pure rust implementation instead of a mips specific one? I understand that might have constant time issues, any thoughts on solutions?

If we must write assembly what are the exact criteria?

@randombit
Copy link

Don't know if it helps but there is an approach implemented here:

https://raw.githubusercontent.com/randombit/botan/master/src/lib/modes/aead/gcm/ghash.cpp
https://raw.githubusercontent.com/randombit/botan/master/src/lib/modes/aead/gcm/clmul_ssse3/clmul_ssse3.cpp

that is constant time (without relying on lookups within a cache line being side channel silent, which at this point is known to be an invalid assumption), easily implemented with either ALU or SIMD, and relatively fast (on a Sandybridge, the SSSE3 version is ~18 cycles/byte, ALU ~22 cycles/byte which seems to compare favorably with the 29 cpb reported for the (not const time) NSS patch on same arch). The SSSE3 version would map well to NEON I think, though I haven't tried yet.

@jkilpatr
Copy link

jkilpatr commented Jul 18, 2018

barebones mips processors have no vector extensions. The generic cpp could be useful.

@DemiMarie
Copy link

DemiMarie commented Jul 19, 2018 via email

@jkilpatr
Copy link

we are using ChaCha20-Poly1305 unrelated to Ring we have some libraries (infrequently used for signing things) that pull in Ring, so we need mips support for Ring and speed is not really a concern.

@briansmith
Copy link
Owner Author

Regarding MIPS support, let's discuss that in the MIPS issue: #562. Maybe fixing this issue (#104) is part of solving that, maybe not.

@briansmith briansmith changed the title Add constant-time(-ish) AES-GCM for simple processors Add constant-time(-ish) AES-GCM that doesn't require assembly language Apr 29, 2020
@briansmith briansmith self-assigned this Apr 29, 2020
@briansmith
Copy link
Owner Author

PR #970 is the first step at this. After that, my plan is to merge the BoringSSL C fallback implementation of GCM and then its C fallback implementation of AES.

@briansmith briansmith changed the title Add constant-time(-ish) AES-GCM that doesn't require assembly language Add constant-time AES-GCM that doesn't require assembly language Apr 29, 2020
@briansmith
Copy link
Owner Author

PR #972 is the next step.

@briansmith briansmith removed the bug label Apr 30, 2020
@briansmith
Copy link
Owner Author

PR #973 adds the GCM code needed for this. AES to follow.

@briansmith
Copy link
Owner Author

PR #976 and PR #977 are two more steps towards getting this done.

@briansmith
Copy link
Owner Author

PR #981 adds the Rust GCM code.

@briansmith
Copy link
Owner Author

PR #993 adds the AES code.

@briansmith
Copy link
Owner Author

Note that the portable AES and GCM implementations come from BoringSSL. BoringSSL writes their code assuming the target is little endian. Thus, additional work is necessary to adapt this code to work for big-endian targets. I don't intend to do that adaptation myself, but I will review PRs that do that adaptation.

@briansmith
Copy link
Owner Author

This is done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants