Skip to content

Commit 004f3da

Browse files
committed
feat: add constant-time equality checking
1 parent b45c384 commit 004f3da

6 files changed

Lines changed: 119 additions & 154 deletions

File tree

Cargo.lock

Lines changed: 34 additions & 143 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ documentation = "https://docs.rs/secure-string/"
1111
edition = "2021"
1212

1313
[dependencies]
14-
libc = "0.2.148"
15-
zeroize = { version = "1.6.0", features = ["std"] }
16-
serde = { version = "1.0.188", optional = true }
14+
libc = "0.2"
15+
zeroize = { version = "1", features = ["std"] }
16+
serde = { version = "1", optional = true }
17+
subtle = "2"
1718

1819
[dev-dependencies]
19-
pre = "0.2.1"
2020
serde_cbor = "0.11"
21-
serde_json = "1.0.105"
21+
serde_json = "1"

src/secure_types/array.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{
44
str::FromStr,
55
};
66

7+
use subtle::ConstantTimeEq;
78
use zeroize::Zeroize;
89

910
use crate::secure_utils::memlock;
@@ -17,7 +18,7 @@ use crate::secure_utils::memlock;
1718
/// - Automatic `madvise(MADV_NOCORE/MADV_DONTDUMP)` to protect against leaking into core dumps (FreeBSD, DragonflyBSD, Linux)
1819
///
1920
/// Comparisons using the `PartialEq` implementation are undefined behavior (and most likely wrong) if `T` has any padding bytes.
20-
#[derive(Eq, PartialEq, PartialOrd, Ord, Hash)]
21+
#[derive(Eq, PartialOrd, Ord, Hash)]
2122
pub struct SecureArray<T, const LENGTH: usize>
2223
where
2324
T: Copy + Zeroize,
@@ -56,6 +57,29 @@ impl<T: Copy + Zeroize, const LENGTH: usize> Clone for SecureArray<T, LENGTH> {
5657
}
5758
}
5859

60+
impl<T, const LENGTH: usize> PartialEq for SecureArray<T, LENGTH>
61+
where
62+
T: Copy + Zeroize,
63+
{
64+
fn eq(&self, other: &Self) -> bool {
65+
let self_bytes = unsafe {
66+
std::slice::from_raw_parts(
67+
self.content.as_ptr() as *const T as *const u8,
68+
LENGTH * std::mem::size_of::<T>(),
69+
)
70+
};
71+
72+
let other_bytes = unsafe {
73+
std::slice::from_raw_parts(
74+
other.content.as_ptr() as *const T as *const u8,
75+
LENGTH * std::mem::size_of::<T>(),
76+
)
77+
};
78+
79+
self_bytes.ct_eq(other_bytes).into()
80+
}
81+
}
82+
5983
// Creation
6084
impl<T, const LENGTH: usize> From<[T; LENGTH]> for SecureArray<T, LENGTH>
6185
where

src/secure_types/boxed.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{
44
mem::MaybeUninit,
55
};
66

7+
use subtle::ConstantTimeEq;
78
use zeroize::Zeroize;
89

910
use crate::secure_utils::memlock;
@@ -17,7 +18,7 @@ use crate::secure_utils::memlock;
1718
/// - Automatic `madvise(MADV_NOCORE/MADV_DONTDUMP)` to protect against leaking into core dumps (FreeBSD, DragonflyBSD, Linux)
1819
///
1920
/// Comparisons using the `PartialEq` implementation are undefined behavior (and most likely wrong) if `T` has any padding bytes.
20-
#[derive(Eq, PartialEq, PartialOrd, Ord, Hash)]
21+
#[derive(Eq, PartialOrd, Ord, Hash)]
2122
pub struct SecureBox<T>
2223
where
2324
T: Copy,
@@ -53,6 +54,29 @@ impl<T: Copy> Clone for SecureBox<T> {
5354
}
5455
}
5556

57+
impl<T> PartialEq for SecureBox<T>
58+
where
59+
T: Copy,
60+
{
61+
fn eq(&self, other: &Self) -> bool {
62+
let self_bytes = unsafe {
63+
std::slice::from_raw_parts(
64+
self.content.as_ref().expect("SecureBox content should always be Some").as_ref() as *const T as *const u8,
65+
std::mem::size_of::<T>(),
66+
)
67+
};
68+
69+
let other_bytes = unsafe {
70+
std::slice::from_raw_parts(
71+
other.content.as_ref().expect("SecureBox content should always be Some").as_ref() as *const T as *const u8,
72+
std::mem::size_of::<T>(),
73+
)
74+
};
75+
76+
self_bytes.ct_eq(other_bytes).into()
77+
}
78+
}
79+
5680
// Delegate indexing
5781
impl<T, U> std::ops::Index<U> for SecureBox<T>
5882
where

0 commit comments

Comments
 (0)