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

Revert new black_box optimization barrier #107

Merged
merged 4 commits into from
Apr 4, 2023

Conversation

dsprenkels
Copy link
Contributor

In #96 (comment), @tarcieri noticed that recently the rustdoc documentation has added a big notice that core::hint::black_box should not be relied upon for correctness, especially for security or cryptographic purposes. It seems wise to revert that change. :(

Review suggestions:

  • I kept the feature flag intact, but it is a no-op, to be removed at the next major version bump, to prevent builds from breaking.

tarcieri
tarcieri previously approved these changes Mar 12, 2023
@dsprenkels
Copy link
Contributor Author

dsprenkels commented Mar 13, 2023

There is also an alternative solution: Back when I proposed #54, assembly directives were still unstable, requiring a nightly rust compiler. However, assembly directives are stable now on multiple platforms [https://doc.rust-lang.org/reference/inline-assembly.html]. As far as I know, this is still a robust method to break any optimizations on the values passing through the assembly directive, and this is also what core::hint::black_box currently uses.

I suppose we can now also replace the core::hint::black_box call by an empty assembly directive. What do you think?

Alternatively, we can leave the code like this, but we start periodically running a test on every new nightly compiler version to see if core::hint::black_box still behaves correctly. (I might do this in any case tbh.)

@tarcieri
Copy link
Contributor

There's a PR to zeroize to do something similar (which is actually where these concerns about core::hint::black_box came up): RustCrypto/utils#841

I'd suggest gating something like that under an asm feature.

The other concern there is ASM is only stable for x86/x86_64, ARM, and RISC-V and therefore needs to be gated appropriately with fallback to the previous implementation for other target CPU architectures.

.travis.yml Outdated Show resolved Hide resolved
Copy link
Member

@isislovecruft isislovecruft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dsprenkels!

Originally the black_box function(s, there was an experiment at creating a handwritten wat/wasm version) was written in inline assembly, just a volatile NOP to convince LLVM to do nothing to the input. I wonder if maybe now that asm! is more stabilised, if we might want to opportunistically return to doing that on architectures which support it?

@isislovecruft isislovecruft changed the base branch from main to develop April 3, 2023 23:24
cargo test --no-default-features --features "std const-generics" &&
cargo test --no-default-features --features "std i128 core_hint_black_box" &&
cargo test --no-default-features --features "std i128 core_hint_black_box const-generics"
cargo test --no-default-features --features "std i128 const-generics"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh also I guess one thing since we added the const-generics feature it wasn't being tested in the github actions workflow, so I'll add that back in.

@isislovecruft isislovecruft merged commit a7ce809 into dalek-cryptography:develop Apr 4, 2023
@tarcieri
Copy link
Contributor

tarcieri commented Apr 4, 2023

just a volatile NOP to convince LLVM to do nothing to the input. I wonder if maybe now that asm! is more stabilised, if we might want to opportunistically return to doing that on architectures which support it?

That's one option.

Another is to use predication instructions like CMOV. We've been working on that in the @RustCrypto cmov crate: https://github.com/RustCrypto/utils/tree/master/cmov

The pattern can be used to implement e.g. ConditionallySelectable::conditional_assign which you can build pretty much everything else on top of, including ConstantTimeEq.

We've discussed opening a PR to allow subtle to use it or vendoring in the x86/x86_64 (CMOV) and aarch64 (CSEL) assembly we have into subtle to allow these sort of ASM-based backends.

Using CMOV/CSEL inline assembly helps guarantee that not only will LLVM not rewrite the code, but that the resulting code will be executed by the CPU in constant-time.

Edit: I guess I already opened an issue for this: #101

AaronFeickert added a commit to tari-project/triptych that referenced this pull request Mar 5, 2024
We currently use the `core_hint_black_box` feature from `subtle`, which uses a particular [optimization barrier](https://github.com/dalek-cryptography/subtle/blob/6b6a81ad9a6a00c0b42c327eaf4b2f785774377e/src/lib.rs#L245-L250).

However, the standard library [documentation](https://doc.rust-lang.org/std/hint/fn.black_box.html) cautions against the use of `std::hint::black_box` for cryptographic use. This has led `subtle` to [remove it](dalek-cryptography/subtle#107) in an upcoming release, at which point the feature will do nothing.

This PR takes the proactive step of removing the feature. There is still an [optimization barrier](https://github.com/dalek-cryptography/subtle/blob/6b6a81ad9a6a00c0b42c327eaf4b2f785774377e/src/lib.rs#L227-L243) in place, which will become the default after the feature is deprecated.
SWvheerden pushed a commit to tari-project/tari that referenced this pull request Mar 6, 2024
Description
---
Removes the `core_hint_black_box` feature from `subtle`.

Motivation and Context
---
We currently use the `core_hint_black_box` feature from `subtle`, which
uses a particular [optimization
barrier](https://github.com/dalek-cryptography/subtle/blob/6b6a81ad9a6a00c0b42c327eaf4b2f785774377e/src/lib.rs#L245-L250).

However, the standard library
[documentation](https://doc.rust-lang.org/std/hint/fn.black_box.html)
cautions against the use of `std::hint::black_box` for cryptographic
use. This has led `subtle` to [remove
it](dalek-cryptography/subtle#107) in an
upcoming release, at which point the feature will do nothing.

This PR takes the proactive step of removing the feature. There is still
an [optimization
barrier](https://github.com/dalek-cryptography/subtle/blob/6b6a81ad9a6a00c0b42c327eaf4b2f785774377e/src/lib.rs#L227-L243)
in place, which will become the default after the feature is deprecated.

How Has This Been Tested?
---
Existing tests pass.

What process can a PR reviewer use to test or verify this change?
---
Check the claims made in the PR about the feature behavior.
elichai added a commit to elichai/subtle that referenced this pull request Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants