From a0b8f38ab54ac451646aa00cd5e91b6c76f22a84 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:57:19 +0200 Subject: Merging upstream version 1.72.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/subtle/src/lib.rs | 136 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 124 insertions(+), 12 deletions(-) (limited to 'vendor/subtle/src/lib.rs') 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 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 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 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 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::() * 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 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 CtOption { } } + /// 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 CtOption { /// 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(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)) + } +} -- cgit v1.2.3