|
41 | 41 | //! inner `u8` by passing it through a volatile read. For more information, see |
42 | 42 | //! the _About_ section below. |
43 | 43 | //! |
44 | | -//! Rust versions from 1.66 or higher support a new best-effort optimization |
45 | | -//! barrier ([`core::hint::black_box`]). To use the new optimization barrier, |
46 | | -//! enable the `core_hint_black_box` feature. |
47 | | -//! |
48 | 44 | //! Rust versions from 1.51 or higher have const generics support. You may enable |
49 | 45 | //! `const-generics` feautre to have `subtle` traits implemented for arrays `[T; N]`. |
50 | 46 | //! |
|
74 | 70 | //! based on Tim Maclean's [work on `rust-timing-shield`][rust-timing-shield], |
75 | 71 | //! which attempts to provide a more comprehensive approach for preventing |
76 | 72 | //! software side-channels in Rust code. |
77 | | -//! |
78 | 73 | //! From version `2.2`, it was based on Diane Hosfelt and Amber Sprenkels' work on |
79 | | -//! "Secret Types in Rust". Version `2.5` adds the `core_hint_black_box` feature, |
80 | | -//! which uses the original method through the [`core::hint::black_box`] function |
81 | | -//! from the Rust standard library. |
| 74 | +//! "Secret Types in Rust". |
82 | 75 | //! |
83 | 76 | //! `subtle` is authored by isis agora lovecruft and Henry de Valence. |
84 | 77 | //! |
|
93 | 86 | //! **USE AT YOUR OWN RISK** |
94 | 87 | //! |
95 | 88 | //! [docs]: https://docs.rs/subtle |
96 | | -//! [`core::hint::black_box`]: https://doc.rust-lang.org/core/hint/fn.black_box.html |
97 | 89 | //! [rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security |
98 | 90 |
|
99 | 91 | #[cfg(feature = "std")] |
@@ -214,47 +206,13 @@ impl Not for Choice { |
214 | 206 | } |
215 | 207 | } |
216 | 208 |
|
217 | | -/// This function is a best-effort attempt to prevent the compiler from knowing |
218 | | -/// anything about the value of the returned `u8`, other than its type. |
219 | | -/// |
220 | | -/// Because we want to support stable Rust, we don't have access to inline |
221 | | -/// assembly or test::black_box, so we use the fact that volatile values will |
222 | | -/// never be elided to register values. |
223 | | -/// |
224 | | -/// Note: Rust's notion of "volatile" is subject to change over time. While this |
225 | | -/// code may break in a non-destructive way in the future, “constant-time” code |
226 | | -/// is a continually moving target, and this is better than doing nothing. |
227 | | -#[cfg(not(feature = "core_hint_black_box"))] |
228 | | -#[inline(never)] |
229 | | -fn black_box(input: u8) -> u8 { |
230 | | - debug_assert!((input == 0u8) | (input == 1u8)); |
231 | | - |
232 | | - unsafe { |
233 | | - // Optimization barrier |
234 | | - // |
235 | | - // Unsafe is ok, because: |
236 | | - // - &input is not NULL; |
237 | | - // - size of input is not zero; |
238 | | - // - u8 is neither Sync, nor Send; |
239 | | - // - u8 is Copy, so input is always live; |
240 | | - // - u8 type is always properly aligned. |
241 | | - core::ptr::read_volatile(&input as *const u8) |
242 | | - } |
243 | | -} |
244 | | - |
245 | | -#[cfg(feature = "core_hint_black_box")] |
246 | | -#[inline] |
247 | | -fn black_box(input: u8) -> u8 { |
248 | | - debug_assert!((input == 0u8) | (input == 1u8)); |
249 | | - core::hint::black_box(input) |
250 | | -} |
251 | | - |
252 | 209 | impl From<u8> for Choice { |
253 | 210 | #[inline] |
254 | 211 | fn from(input: u8) -> Choice { |
| 212 | + debug_assert!((input == 0u8) | (input == 1u8)); |
255 | 213 | // Our goal is to prevent the compiler from inferring that the value held inside the |
256 | 214 | // resulting `Choice` struct is really an `i1` instead of an `i8`. |
257 | | - Choice(black_box(input)) |
| 215 | + Choice(core::hint::black_box(input)) |
258 | 216 | } |
259 | 217 | } |
260 | 218 |
|
|
0 commit comments