Skip to content

Commit

Permalink
separate AtomicOnceCell into its own feature
Browse files Browse the repository at this point in the history
  • Loading branch information
stevefan1999-personal committed Sep 25, 2024
1 parent c433975 commit 9655431
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ rust-version = "1.75"
[dependencies]
aead = { version = "0.5.2", default-features = false }
aes-gcm = { version = "0.10.3", default-features = false, features = ["aes", "alloc"] }
atomic_once_cell = "0.1.6"
atomic_once_cell = { version = "0.1.6", optional = true }
chacha20poly1305 = { version = "0.10.1", default-features = false }
crypto-common = { version = "0.1.6", default-features = false }
der = { version = "0.7.9", default-features = false }
Expand All @@ -42,7 +42,7 @@ webpki = { package = "rustls-webpki", version = "0.102.0", default-features = fa
x25519-dalek = { version = "2", default-features = false }

[features]
default = ["std", "tls12", "zeroize", "getrandom"]
default = ["std", "tls12", "zeroize", "getrandom", "atomic"]
logging = ["rustls/logging"]
tls12 = ["rustls/tls12"]

Expand All @@ -56,3 +56,4 @@ alloc = ["webpki/alloc", "pki-types/alloc", "aead/alloc", "ed25519-dalek/alloc"]
zeroize = ["ed25519-dalek/zeroize", "x25519-dalek/zeroize"]

getrandom = ["rand_core/getrandom"]
atomic = ["dep:atomic_once_cell"]
17 changes: 11 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ extern crate alloc;

use core::fmt::Debug;

#[cfg(feature = "alloc")]
use atomic_once_cell::AtomicOnceCell;
#[cfg(not(feature = "atomic"))]
use core::cell::OnceCell;

#[cfg(feature = "atomic")]
use atomic_once_cell::AtomicOnceCell as OnceCell;

#[cfg(feature = "alloc")]
use alloc::sync::Arc;
Expand Down Expand Up @@ -75,8 +78,9 @@ pub fn provider_and_init_rng(rng: &'static mut (dyn RngCore + Send + Sync)) -> C
provider()
}

static mut RNG: AtomicOnceCell<&'static mut (dyn RngCore + Send + Sync)> = AtomicOnceCell::new();

// The global RNG cell that points to a user-defined, custom global RNG state.
// Technically speaking, we want something similar to a lazy cell, except the user can customize the closure
static mut RNG: OnceCell<&'static mut (dyn RngCore + Send + Sync)> = OnceCell::new();

fn get_rng_danger() -> &'static mut (dyn RngCore + Send + Sync) {
#[cfg(feature = "getrandom")]
Expand All @@ -94,11 +98,12 @@ fn get_rng_danger() -> &'static mut (dyn RngCore + Send + Sync) {
}
}

// Initialize an RNG source, and panic if was already set when it think it is unset, which would only happen if two threads set the data at the same time.
// Initialize an RNG source, and panic if was already set when it think it is unset, which would only happen if two threads set the data at the same time, otherwise a no-op if it was already set.
// This ensures the user would have to decide on the RNG source at the very beginning, likely the first function call in main and find way to provide entropy themselves
// TIP: you can put your RNG state as a global variable, which is usually useful for MCUs
pub unsafe fn init_randomness_source(rng: &'static mut (dyn RngCore + Send + Sync)) {
// SAFETY: If randomness source is already set, the whole program panics
// SAFETY (under "atomic" assumption): If the randomness source is already set in progress when it is trying to set the value, either one can safely commit the write or the whole program panic
// DANGER (without "atomic" assumption): this operation can be racy if any two asymmetric cores access the same memory region at the same time without prior cache invalidation knowledge
#[allow(static_mut_refs)]
unsafe {
let _ = RNG.set(rng);
Expand Down

0 comments on commit 9655431

Please sign in to comment.