diff options
Diffstat (limited to 'vendor/subtle')
-rw-r--r-- | vendor/subtle/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | vendor/subtle/CHANGELOG.md | 15 | ||||
-rw-r--r-- | vendor/subtle/Cargo.toml | 16 | ||||
-rw-r--r-- | vendor/subtle/README.md | 23 | ||||
-rw-r--r-- | vendor/subtle/src/lib.rs | 136 | ||||
-rw-r--r-- | vendor/subtle/tests/mod.rs | 40 |
6 files changed, 205 insertions, 27 deletions
diff --git a/vendor/subtle/.cargo-checksum.json b/vendor/subtle/.cargo-checksum.json index 57f71292d..62db1587b 100644 --- a/vendor/subtle/.cargo-checksum.json +++ b/vendor/subtle/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"1d604ca36159c79a4341f0c15fc249da7bf2912cd5b1bbf4964ce03dd887fc02","CONTRIBUTING.md":"2fbb44138ececdef7c0950fae6ed1dcad481fb2f368df0e3734c9902be791f3e","Cargo.toml":"2206ebe5be7cca3ad0a5dcbb0b12f85ac091b4b6a58861cddc8ecd5d137d4c7c","LICENSE":"36c48715a280d334a995f26fc38103f21cb92425a20c8eeaa368b229b49b6d4d","README.md":"ee1a1768f9b119a36db27a170f7f6bb8bdb79f868db28b37a11d1a57a208e9f5","src/lib.rs":"d873dd52215caf21a385391ed88f75e09f8f32203e93e3530c2a22d19e5a6452","tests/mod.rs":"127c8ab8ddbfa554f11876d76926f710382e293629875673e3bc99d738a13733"},"package":"6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"}
\ No newline at end of file +{"files":{"CHANGELOG.md":"02f92a31269311c965b1dfa705f22f341dc9cce73af08a8c9840c91b8ceb79df","CONTRIBUTING.md":"2fbb44138ececdef7c0950fae6ed1dcad481fb2f368df0e3734c9902be791f3e","Cargo.toml":"72ff6f9d47061233fc938824f2adc126ba9e8f686df75dec4ab7a0f44327d5c6","LICENSE":"36c48715a280d334a995f26fc38103f21cb92425a20c8eeaa368b229b49b6d4d","README.md":"9a04bb0dee4e6c350d1728ec225f162081d31273dbae6580757aadb363c76cdf","src/lib.rs":"7e14a5d5f2351343e41ff0e085a348190178ebe19cf12ffce083ce75ae6fba9d","tests/mod.rs":"61e6540375c1ccf5a5f134336d5297ecbda6ef76dd3cd81c600b303d2572e7ee"},"package":"81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"}
\ No newline at end of file diff --git a/vendor/subtle/CHANGELOG.md b/vendor/subtle/CHANGELOG.md index 152e7bcac..e6a386365 100644 --- a/vendor/subtle/CHANGELOG.md +++ b/vendor/subtle/CHANGELOG.md @@ -2,6 +2,21 @@ Entries are listed in reverse chronological order. +## 2.5.0 + +* Add constant-timedness note to the documentation for `CtOption::unwrap_or_else`. +* Add `CtOption::expect`. +* Add `ConstantTimeEq::ct_ne` with default implementation. +* Add new `core_hint_black_box` feature from Diane Hosfelt and Amber + Sprenkels which utilises the original `black_box` functionality from + when subtle was first written, which has now found it's way into the + Rust standard library. +* Add new `const-generics` feature from @survived which adds support + for subtle traits for generic arrays `[T; N]`. +* Add new feature for supporting `core::cmp::Ordering` for types which + implement subtle traits, patch from @tarcieri. +* Update `rand` dependency to 0.8. + ## 2.4.1 * Fix a bug in how the README was included in the documentation builds diff --git a/vendor/subtle/Cargo.toml b/vendor/subtle/Cargo.toml index 8689ad2f7..351989ace 100644 --- a/vendor/subtle/Cargo.toml +++ b/vendor/subtle/Cargo.toml @@ -3,16 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] +edition = "2018" name = "subtle" -version = "2.4.1" +version = "2.5.0" authors = ["Isis Lovecruft <isis@patternsinthevoid.net>", "Henry de Valence <hdevalence@hdevalence.ca>"] exclude = ["**/.gitignore", ".travis.yml"] description = "Pure-Rust traits and utilities for constant-time cryptographic implementations." @@ -24,9 +24,11 @@ categories = ["cryptography", "no-std"] license = "BSD-3-Clause" repository = "https://github.com/dalek-cryptography/subtle" [dev-dependencies.rand] -version = "0.7" +version = "0.8" [features] +const-generics = [] +core_hint_black_box = [] default = ["std", "i128"] i128 = [] nightly = [] diff --git a/vendor/subtle/README.md b/vendor/subtle/README.md index 81ac448fe..de7757554 100644 --- a/vendor/subtle/README.md +++ b/vendor/subtle/README.md @@ -7,7 +7,7 @@ instead of `bool` which are intended to execute in constant-time. The `Choice` type is a wrapper around a `u8` that holds a `0` or `1`. ```toml -subtle = "2.4" +subtle = "2.5" ``` This crate represents a “best-effort” attempt, since side-channels @@ -26,6 +26,13 @@ prevent this refinement, the crate tries to hide the value of a `Choice`'s inner `u8` by passing it through a volatile read. For more information, see the _About_ section below. +Rust versions from 1.66 or higher support a new best-effort optimization +barrier ([`core::hint::black_box`]). To use the new optimization barrier, +enable the `core_hint_black_box` feature. + +Rust versions from 1.51 or higher have const generics support. You may enable +`const-generics` feautre to have `subtle` traits implemented for arrays `[T; N]`. + Versions prior to `2.2` recommended use of the `nightly` feature to enable an optimization barrier; this is not required in versions `2.2` and above. @@ -48,10 +55,15 @@ Minimum supported Rust version can be changed in the future, but it will be done This library aims to be the Rust equivalent of Go’s `crypto/subtle` module. -The optimization barrier in `impl From<u8> for Choice` was based on Tim -Maclean's [work on `rust-timing-shield`][rust-timing-shield], which attempts to -provide a more comprehensive approach for preventing software side-channels in -Rust code. +Old versions of the optimization barrier in `impl From<u8> for Choice` were +based on Tim Maclean's [work on `rust-timing-shield`][rust-timing-shield], +which attempts to provide a more comprehensive approach for preventing +software side-channels in Rust code. + +From version `2.2`, it was based on Diane Hosfelt and Amber Sprenkels' work on +"Secret Types in Rust". Version `2.5` adds the `core_hint_black_box` feature, +which uses the original method through the [`core::hint::black_box`] function +from the Rust standard library. `subtle` is authored by isis agora lovecruft and Henry de Valence. @@ -66,4 +78,5 @@ effort is fundamentally limited. **USE AT YOUR OWN RISK** [docs]: https://docs.rs/subtle +[`core::hint::black_box`]: https://doc.rust-lang.org/core/hint/fn.black_box.html [rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security diff --git a/vendor/subtle/src/lib.rs b/vendor/subtle/src/lib.rs index 27d05eeae..795eade44 100644 --- a/vendor/subtle/src/lib.rs +++ b/vendor/subtle/src/lib.rs @@ -11,7 +11,7 @@ #![no_std] #![deny(missing_docs)] #![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")] -#![doc(html_root_url = "https://docs.rs/subtle/2.4.1")] +#![doc(html_root_url = "https://docs.rs/subtle/2.5.0")] //! # subtle [![](https://img.shields.io/crates/v/subtle.svg)](https://crates.io/crates/subtle) [![](https://img.shields.io/badge/dynamic/json.svg?label=docs&uri=https%3A%2F%2Fcrates.io%2Fapi%2Fv1%2Fcrates%2Fsubtle%2Fversions&query=%24.versions%5B0%5D.num&colorB=4F74A6)](https://doc.dalek.rs/subtle) [![](https://travis-ci.org/dalek-cryptography/subtle.svg?branch=master)](https://travis-ci.org/dalek-cryptography/subtle) //! @@ -22,7 +22,7 @@ //! type is a wrapper around a `u8` that holds a `0` or `1`. //! //! ```toml -//! subtle = "2.4" +//! subtle = "2.5" //! ``` //! //! This crate represents a “best-effort” attempt, since side-channels @@ -41,6 +41,13 @@ //! inner `u8` by passing it through a volatile read. For more information, see //! the _About_ section below. //! +//! Rust versions from 1.66 or higher support a new best-effort optimization +//! barrier ([`core::hint::black_box`]). To use the new optimization barrier, +//! enable the `core_hint_black_box` feature. +//! +//! Rust versions from 1.51 or higher have const generics support. You may enable +//! `const-generics` feautre to have `subtle` traits implemented for arrays `[T; N]`. +//! //! Versions prior to `2.2` recommended use of the `nightly` feature to enable an //! optimization barrier; this is not required in versions `2.2` and above. //! @@ -63,10 +70,15 @@ //! //! This library aims to be the Rust equivalent of Go’s `crypto/subtle` module. //! -//! The optimization barrier in `impl From<u8> for Choice` was based on Tim -//! Maclean's [work on `rust-timing-shield`][rust-timing-shield], which attempts to -//! provide a more comprehensive approach for preventing software side-channels in -//! Rust code. +//! Old versions of the optimization barrier in `impl From<u8> for Choice` were +//! based on Tim Maclean's [work on `rust-timing-shield`][rust-timing-shield], +//! which attempts to provide a more comprehensive approach for preventing +//! software side-channels in Rust code. +//! +//! From version `2.2`, it was based on Diane Hosfelt and Amber Sprenkels' work on +//! "Secret Types in Rust". Version `2.5` adds the `core_hint_black_box` feature, +//! which uses the original method through the [`core::hint::black_box`] function +//! from the Rust standard library. //! //! `subtle` is authored by isis agora lovecruft and Henry de Valence. //! @@ -81,12 +93,14 @@ //! **USE AT YOUR OWN RISK** //! //! [docs]: https://docs.rs/subtle +//! [`core::hint::black_box`]: https://doc.rust-lang.org/core/hint/fn.black_box.html //! [rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security #[cfg(feature = "std")] #[macro_use] extern crate std; +use core::cmp; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Neg, Not}; use core::option::Option; @@ -210,6 +224,7 @@ impl Not for Choice { /// Note: Rust's notion of "volatile" is subject to change over time. While this /// code may break in a non-destructive way in the future, “constant-time” code /// is a continually moving target, and this is better than doing nothing. +#[cfg(not(feature = "core_hint_black_box"))] #[inline(never)] fn black_box(input: u8) -> u8 { debug_assert!((input == 0u8) | (input == 1u8)); @@ -227,6 +242,13 @@ fn black_box(input: u8) -> u8 { } } +#[cfg(feature = "core_hint_black_box")] +#[inline(never)] +fn black_box(input: u8) -> u8 { + debug_assert!((input == 0u8) | (input == 1u8)); + core::hint::black_box(input) +} + impl From<u8> for Choice { #[inline] fn from(input: u8) -> Choice { @@ -259,6 +281,19 @@ pub trait ConstantTimeEq { /// * `Choice(0u8)` if `self != other`. #[inline] fn ct_eq(&self, other: &Self) -> Choice; + + /// Determine if two items are NOT equal. + /// + /// The `ct_ne` function should execute in constant time. + /// + /// # Returns + /// + /// * `Choice(0u8)` if `self == other`; + /// * `Choice(1u8)` if `self != other`. + #[inline] + fn ct_ne(&self, other: &Self) -> Choice { + !self.ct_eq(other) + } } impl<T: ConstantTimeEq> ConstantTimeEq for [T] { @@ -350,6 +385,14 @@ generate_integer_equal!(u64, i64, 64); generate_integer_equal!(u128, i128, 128); generate_integer_equal!(usize, isize, ::core::mem::size_of::<usize>() * 8); +/// `Ordering` is `#[repr(i8)]` making it possible to leverage `i8::ct_eq`. +impl ConstantTimeEq for cmp::Ordering { + #[inline] + fn ct_eq(&self, other: &Self) -> Choice { + (*self as i8).ct_eq(&(*other as i8)) + } +} + /// A type which can be conditionally selected in constant time. /// /// This trait also provides generic implementations of conditional @@ -367,7 +410,6 @@ pub trait ConditionallySelectable: Copy { /// # Example /// /// ``` - /// # extern crate subtle; /// use subtle::ConditionallySelectable; /// # /// # fn main() { @@ -390,7 +432,6 @@ pub trait ConditionallySelectable: Copy { /// # Example /// /// ``` - /// # extern crate subtle; /// use subtle::ConditionallySelectable; /// # /// # fn main() { @@ -416,7 +457,6 @@ pub trait ConditionallySelectable: Copy { /// # Example /// /// ``` - /// # extern crate subtle; /// use subtle::ConditionallySelectable; /// # /// # fn main() { @@ -511,6 +551,26 @@ generate_integer_conditional_select!( u64 i64); #[cfg(feature = "i128")] generate_integer_conditional_select!(u128 i128); +/// `Ordering` is `#[repr(i8)]` where: +/// +/// - `Less` => -1 +/// - `Equal` => 0 +/// - `Greater` => 1 +/// +/// Given this, it's possible to operate on orderings as if they're integers, +/// which allows leveraging conditional masking for predication. +impl ConditionallySelectable for cmp::Ordering { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let a = *a as i8; + let b = *b as i8; + let ret = i8::conditional_select(&a, &b, choice); + + // SAFETY: `Ordering` is `#[repr(i8)]` and `ret` has been assigned to + // a value which was originally a valid `Ordering` then cast to `i8` + unsafe { *((&ret as *const _) as *const cmp::Ordering) } + } +} + impl ConditionallySelectable for Choice { #[inline] fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { @@ -518,6 +578,25 @@ impl ConditionallySelectable for Choice { } } +#[cfg(feature = "const-generics")] +impl<T, const N: usize> ConditionallySelectable for [T; N] +where + T: ConditionallySelectable, +{ + #[inline] + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let mut output = *a; + output.conditional_assign(b, choice); + output + } + + fn conditional_assign(&mut self, other: &Self, choice: Choice) { + for (a_i, b_i) in self.iter_mut().zip(other) { + a_i.conditional_assign(b_i, choice) + } + } +} + /// A type which can be conditionally negated in constant time. /// /// # Note @@ -605,6 +684,18 @@ impl<T> CtOption<T> { } } + /// Returns the contained value, consuming the `self` value. + /// + /// # Panics + /// + /// Panics if the value is none with a custom panic message provided by + /// `msg`. + pub fn expect(self, msg: &str) -> T { + assert_eq!(self.is_some.unwrap_u8(), 1, "{}", msg); + + self.value + } + /// This returns the underlying value but panics if it /// is not `Some`. #[inline] @@ -626,6 +717,9 @@ impl<T> CtOption<T> { /// This returns the underlying value if it is `Some` /// or the value produced by the provided closure otherwise. + /// + /// This operates in constant time, because the provided closure + /// is always called. #[inline] pub fn unwrap_or_else<F>(self, f: F) -> T where @@ -748,7 +842,6 @@ pub trait ConstantTimeGreater { /// # Example /// /// ``` - /// # extern crate subtle; /// use subtle::ConstantTimeGreater; /// /// let x: u8 = 13; @@ -801,7 +894,7 @@ macro_rules! generate_unsigned_integer_greater { Choice::from((bit & 1) as u8) } } - } + }; } generate_unsigned_integer_greater!(u8, 8); @@ -811,6 +904,16 @@ generate_unsigned_integer_greater!(u64, 64); #[cfg(feature = "i128")] generate_unsigned_integer_greater!(u128, 128); +impl ConstantTimeGreater for cmp::Ordering { + #[inline] + fn ct_gt(&self, other: &Self) -> Choice { + // No impl of `ConstantTimeGreater` for `i8`, so use `u8` + let a = (*self as i8) + 1; + let b = (*other as i8) + 1; + (a as u8).ct_gt(&(b as u8)) + } +} + /// A type which can be compared in some manner and be determined to be less /// than another of the same type. pub trait ConstantTimeLess: ConstantTimeEq + ConstantTimeGreater { @@ -832,7 +935,6 @@ pub trait ConstantTimeLess: ConstantTimeEq + ConstantTimeGreater { /// # Example /// /// ``` - /// # extern crate subtle; /// use subtle::ConstantTimeLess; /// /// let x: u8 = 13; @@ -862,3 +964,13 @@ impl ConstantTimeLess for u32 {} impl ConstantTimeLess for u64 {} #[cfg(feature = "i128")] impl ConstantTimeLess for u128 {} + +impl ConstantTimeLess for cmp::Ordering { + #[inline] + fn ct_lt(&self, other: &Self) -> Choice { + // No impl of `ConstantTimeLess` for `i8`, so use `u8` + let a = (*self as i8) + 1; + let b = (*other as i8) + 1; + (a as u8).ct_lt(&(b as u8)) + } +} diff --git a/vendor/subtle/tests/mod.rs b/vendor/subtle/tests/mod.rs index eaa98a460..f6b3982e0 100644 --- a/vendor/subtle/tests/mod.rs +++ b/vendor/subtle/tests/mod.rs @@ -1,5 +1,4 @@ -extern crate rand; -extern crate subtle; +use std::cmp; use rand::rngs::OsRng; use rand::RngCore; @@ -96,6 +95,19 @@ fn custom_conditional_select_i16() { assert_eq!(i16::conditional_select(&x, &y, 1.into()), 514); } +#[test] +fn ordering_conditional_select() { + assert_eq!( + cmp::Ordering::conditional_select(&cmp::Ordering::Less, &cmp::Ordering::Greater, 0.into()), + cmp::Ordering::Less + ); + + assert_eq!( + cmp::Ordering::conditional_select(&cmp::Ordering::Less, &cmp::Ordering::Greater, 1.into()), + cmp::Ordering::Greater + ); +} + macro_rules! generate_integer_equal_tests { ($($t:ty),*) => ($( let y: $t = 0; // all 0 bits @@ -105,6 +117,8 @@ macro_rules! generate_integer_equal_tests { assert_eq!(x.ct_eq(&y).unwrap_u8(), 0); assert_eq!(x.ct_eq(&z).unwrap_u8(), 1); + assert_eq!(x.ct_ne(&y).unwrap_u8(), 1); + assert_eq!(x.ct_ne(&z).unwrap_u8(), 0); )*) } @@ -148,6 +162,16 @@ fn choice_equal() { } #[test] +fn ordering_equal() { + let a = cmp::Ordering::Equal; + let b = cmp::Ordering::Greater; + let c = a; + + assert_eq!(a.ct_eq(&b).unwrap_u8(), 0); + assert_eq!(a.ct_eq(&c).unwrap_u8(), 1); +} + +#[test] fn test_ctoption() { let a = CtOption::new(10, Choice::from(1)); let b = CtOption::new(9, Choice::from(1)); @@ -333,6 +357,12 @@ fn greater_than_u128() { } #[test] +fn greater_than_ordering() { + assert_eq!(cmp::Ordering::Less.ct_gt(&cmp::Ordering::Greater).unwrap_u8(), 0); + assert_eq!(cmp::Ordering::Greater.ct_gt(&cmp::Ordering::Less).unwrap_u8(), 1); +} + +#[test] /// Test that the two's compliment min and max, i.e. 0000...0001 < 1111...1110, /// gives the correct result. (This fails using the bit-twiddling algorithm that /// go/crypto/subtle uses.) @@ -387,3 +417,9 @@ fn less_than_u64() { fn less_than_u128() { generate_less_than_test!(u128); } + +#[test] +fn less_than_ordering() { + assert_eq!(cmp::Ordering::Greater.ct_lt(&cmp::Ordering::Less).unwrap_u8(), 0); + assert_eq!(cmp::Ordering::Less.ct_lt(&cmp::Ordering::Greater).unwrap_u8(), 1); +} |