From 6a1928a83ba4cf9a052b4200142dc3410ee73f37 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:24:13 -0500 Subject: [PATCH] Add constant-time hash equality via `subtle` --- Cargo.toml | 6 +++++- src/lib.rs | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c5f8c99d..7f063095 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ neon = [] # --no-default-features, the only way to use the SIMD implementations in this # crate is to enable the corresponding instruction sets statically for the # entire build, with e.g. RUSTFLAGS="-C target-cpu=native". -std = [] +std = ["subtle?/std"] # The `rayon` feature (disabled by default, but enabled for docs.rs) adds the # `update_rayon` and (in combination with `mmap` below) `update_mmap_rayon` @@ -42,6 +42,9 @@ mmap = ["std", "dep:memmap2"] # Implement the zeroize::Zeroize trait for types in this crate. zeroize = ["dep:zeroize", "arrayvec/zeroize"] +# Enable the `ConstantTimeEq` trait for `Hash` using `subtle` functionality. +subtle = ["dep:subtle"] + # This crate implements traits from the RustCrypto project, exposed here as the # "traits-preview" feature. However, these traits aren't stable, and they're # expected to change in incompatible ways before they reach 1.0. For that @@ -103,6 +106,7 @@ digest = { version = "0.10.1", features = [ "mac" ], optional = true } memmap2 = { version = "0.9", optional = true } rayon-core = { version = "1.12.1", optional = true } serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } +subtle = { version = "2.6", default-features = false, optional = true } zeroize = { version = "1", default-features = false, optional = true } [dev-dependencies] diff --git a/src/lib.rs b/src/lib.rs index 37c2c0b3..61dab5db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -138,6 +138,8 @@ use arrayvec::{ArrayString, ArrayVec}; use core::cmp; use core::fmt; use platform::{Platform, MAX_SIMD_DEGREE, MAX_SIMD_DEGREE_OR_2}; +#[cfg(feature = "subtle")] +use subtle::ConstantTimeEq; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -315,6 +317,13 @@ impl Zeroize for Hash { } } +#[cfg(feature = "subtle")] +impl ConstantTimeEq for Hash { + fn ct_eq(&self, other: &Self) -> subtle::Choice { + self.0.ct_eq(&other.0) + } +} + /// This implementation is constant-time. impl PartialEq for Hash { #[inline]