Remove Servo's wrapper around rand (#39979)

This wrapper was added in order to eliminate the number of file
descriptors used accessing `/dev/urandom`, but these days `osrandom` and
by proxy `rand` will try to use `getrandom` on Linux and similar system
APIs on other platforms [^1].

This is a trial balloon for removing the wrapper, since almost all
modern Linux systems have `getrandom`  (available since Linux
3.17).

[^1]: https://docs.rs/getrandom/0.3.4/getrandom/#supported-targets

Testing: Should not change observable behavior (only in random ways), so
should
be covered by WPT tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson
2025-10-18 15:54:20 +02:00
committed by GitHub
parent bf42488da8
commit c776475b3b
25 changed files with 75 additions and 362 deletions

34
Cargo.lock generated
View File

@@ -936,8 +936,8 @@ dependencies = [
"embedder_traits",
"ipc-channel",
"log",
"rand 0.9.2",
"servo_config",
"servo_rand",
"uuid",
]
@@ -1590,12 +1590,12 @@ dependencies = [
"parking_lot",
"profile",
"profile_traits",
"rand 0.9.2",
"rustc-hash 2.1.1",
"script_traits",
"serde",
"servo-tracing",
"servo_config",
"servo_rand",
"servo_url",
"storage_traits",
"stylo",
@@ -2047,11 +2047,11 @@ dependencies = [
"log",
"net",
"net_traits",
"rand 0.9.2",
"rustc-hash 2.1.1",
"serde",
"serde_json",
"servo_config",
"servo_rand",
"servo_url",
"uuid",
]
@@ -5569,12 +5569,12 @@ dependencies = [
"percent-encoding",
"pixels",
"profile_traits",
"rand 0.9.2",
"rustc-hash 2.1.1",
"rustls-pki-types",
"serde",
"servo_arc",
"servo_malloc_size_of",
"servo_rand",
"servo_url",
"url",
"uuid",
@@ -6860,15 +6860,6 @@ dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "rand_isaac"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fac4373cd91b4f55722c553fb0f286edbb81ef3ff6eec7b99d1898a4110a0b28"
dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "range"
version = "0.0.1"
@@ -7330,6 +7321,7 @@ dependencies = [
"phf",
"pixels",
"profile_traits",
"rand 0.9.2",
"range",
"regex",
"rustc-hash 2.1.1",
@@ -7343,7 +7335,6 @@ dependencies = [
"servo_config",
"servo_geometry",
"servo_malloc_size_of",
"servo_rand",
"servo_url",
"smallvec",
"storage_traits",
@@ -7922,29 +7913,16 @@ dependencies = [
"wr_malloc_size_of",
]
[[package]]
name = "servo_rand"
version = "0.0.1"
dependencies = [
"log",
"malloc_size_of_derive",
"rand 0.8.5",
"rand_core 0.6.4",
"rand_isaac",
"servo_malloc_size_of",
"uuid",
]
[[package]]
name = "servo_url"
version = "0.0.1"
dependencies = [
"encoding_rs",
"malloc_size_of_derive",
"rand 0.9.2",
"serde",
"servo_arc",
"servo_malloc_size_of",
"servo_rand",
"url",
"uuid",
]

View File

@@ -115,9 +115,7 @@ percent-encoding = "2.3"
proc-macro2 = "1"
profile_traits = { path = "components/shared/profile" }
quote = "1"
rand = "0.8"
rand_core = "0.6"
rand_isaac = "0.3"
rand = "0.9"
raw-window-handle = "0.6"
rayon = "1"
read-fonts = "0.33.1"

View File

@@ -19,8 +19,8 @@ blurmock = { version = "0.1.2", optional = true }
embedder_traits = { workspace = true }
ipc-channel = { workspace = true }
log = { workspace = true }
rand = { workspace = true }
servo_config = { path = "../config" }
servo_rand = { path = "../rand" }
uuid = { workspace = true }
[target.'cfg(target_os = "linux")'.dependencies]

View File

@@ -34,8 +34,8 @@ use bluetooth_traits::{
use embedder_traits::{EmbedderMsg, EmbedderProxy};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use log::warn;
use rand::{self, Rng};
use servo_config::pref;
use servo_rand::{self, Rng};
use crate::bluetooth::{
BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic, BluetoothGATTDescriptor,
@@ -430,9 +430,9 @@ impl BluetoothManager {
fn generate_device_id(&mut self) -> String {
let mut device_id;
let mut rng = servo_rand::thread_rng();
let mut rng = rand::rng();
loop {
device_id = rng.r#gen::<u32>().to_string();
device_id = rng.random::<u32>().to_string();
if !self.cached_devices.contains_key(&device_id) {
break;
}

View File

@@ -49,12 +49,12 @@ net_traits = { workspace = true }
parking_lot = { workspace = true }
profile = { path = "../profile" }
profile_traits = { workspace = true }
rand = { workspace = true }
rustc-hash = { workspace = true }
script_traits = { workspace = true }
serde = { workspace = true }
servo-tracing = { workspace = true }
servo_config = { path = "../config" }
servo_rand = { path = "../rand" }
servo_url = { path = "../url" }
storage_traits = { workspace = true }
stylo = { workspace = true }

View File

@@ -158,6 +158,9 @@ use net_traits::{
};
use profile_traits::mem::ProfilerMsg;
use profile_traits::{mem, time};
use rand::rngs::SmallRng;
use rand::seq::IndexedRandom;
use rand::{Rng, SeedableRng};
use rustc_hash::{FxHashMap, FxHashSet};
use script_traits::{
ConstellationInputEvent, DiscardBrowsingContext, DocumentActivity, ProgressiveWebMetricType,
@@ -166,7 +169,6 @@ use script_traits::{
use serde::{Deserialize, Serialize};
use servo_config::prefs::{self, PrefValue};
use servo_config::{opts, pref};
use servo_rand::{Rng, ServoRng, SliceRandom, random};
use servo_url::{Host, ImmutableOrigin, ServoUrl};
use storage_traits::StorageThreads;
use storage_traits::webstorage_thread::{StorageType, WebStorageThreadMsg};
@@ -449,7 +451,7 @@ pub struct Constellation<STF, SWF> {
/// The random number generator and probability for closing pipelines.
/// This is for testing the hardening of the constellation.
random_pipeline_closure: Option<(ServoRng, f32)>,
random_pipeline_closure: Option<(SmallRng, f32)>,
/// Phantom data that keeps the Rust type system happy.
phantom: PhantomData<(STF, SWF)>,
@@ -733,12 +735,12 @@ where
webrender_wgpu,
shutting_down: false,
handled_warnings: VecDeque::new(),
random_pipeline_closure: random_pipeline_closure_probability.map(|prob| {
let seed = random_pipeline_closure_seed.unwrap_or_else(random);
let rng = ServoRng::new_manually_reseeded(seed as u64);
warn!("Randomly closing pipelines.");
info!("Using seed {} for random pipeline closure.", seed);
(rng, prob)
random_pipeline_closure: random_pipeline_closure_probability.map(|probability| {
let rng = random_pipeline_closure_seed
.map(|seed| SmallRng::seed_from_u64(seed as u64))
.unwrap_or_else(SmallRng::from_os_rng);
warn!("Randomly closing pipelines using seed {random_pipeline_closure_seed:?}.");
(rng, probability)
}),
webgl_threads: state.webgl_threads,
webxr_registry: state.webxr_registry,
@@ -5600,7 +5602,7 @@ where
fn maybe_close_random_pipeline(&mut self) {
match self.random_pipeline_closure {
Some((ref mut rng, probability)) => {
if probability <= rng.r#gen::<f32>() {
if probability <= rng.random::<f32>() {
return;
}
},
@@ -5616,7 +5618,7 @@ where
.pending_changes
.iter()
.any(|change| change.new_pipeline_id == pipeline.id) &&
probability <= rng.r#gen::<f32>()
probability <= rng.random::<f32>()
{
// We tend not to close pending pipelines, as that almost always
// results in pipelines being closed early in their lifecycle,

View File

@@ -24,11 +24,11 @@ ipc-channel = { workspace = true }
log = { workspace = true }
net = { path = "../net" }
net_traits = { workspace = true }
rand = { workspace = true }
rustc-hash = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
servo_config = { path = "../config" }
servo_rand = { path = "../rand" }
servo_url = { path = "../url" }
uuid = { workspace = true }

View File

@@ -29,10 +29,10 @@ use devtools_traits::{
use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy};
use ipc_channel::ipc::IpcSender;
use log::{trace, warn};
use rand::{RngCore, rng};
use resource::{ResourceArrayType, ResourceAvailable};
use rustc_hash::FxHashMap;
use serde::Serialize;
use servo_rand::RngCore;
use crate::actor::{Actor, ActorRegistry};
use crate::actors::browsing_context::BrowsingContextActor;
@@ -142,7 +142,7 @@ impl DevtoolsInstance {
// A token shared with the embedder to bypass permission prompt.
let port = if bound.is_some() { Ok(port) } else { Err(()) };
let token = format!("{:X}", servo_rand::ServoRng::default().next_u32());
let token = format!("{:X}", rng().next_u32());
embedder.send(EmbedderMsg::OnDevtoolsStarted(port, token.clone()));
let listener = match bound {

View File

@@ -1,21 +0,0 @@
[package]
name = "servo_rand"
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true
publish.workspace = true
rust-version.workspace = true
[lib]
name = "servo_rand"
path = "lib.rs"
[dependencies]
log = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
rand = { workspace = true }
rand_core = { workspace = true }
rand_isaac = { workspace = true }
uuid = { workspace = true }

View File

@@ -1,197 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Mutex;
use log::trace;
use malloc_size_of_derive::MallocSizeOf;
/// A random number generator which shares one instance of an `OsRng`.
///
/// A problem with `OsRng`, which is inherited by `StdRng` and so
/// `ThreadRng`, is that it reads from `/dev/random`, and so consumes
/// a file descriptor. For multi-threaded applications like Servo,
/// it is easy to exhaust the supply of file descriptors this way.
///
/// This crate fixes that, by only using one `OsRng`, which is just
/// used to seed and re-seed an `ServoRng`.
use rand::distributions::{Distribution, Standard};
use rand::rngs::OsRng;
use rand::rngs::adapter::ReseedingRng;
pub use rand::seq::SliceRandom;
pub use rand::{Rng, RngCore, SeedableRng};
use rand_isaac::isaac::IsaacCore;
use uuid::{Builder, Uuid};
// The shared RNG which may hold on to a file descriptor
static OS_RNG: Mutex<OsRng> = Mutex::new(OsRng);
// Generate 32K of data between reseedings
const RESEED_THRESHOLD: u64 = 32_768;
// An in-memory RNG that only uses the shared file descriptor for seeding and reseeding.
#[derive(MallocSizeOf)]
pub struct ServoRng {
#[ignore_malloc_size_of = "Defined in rand"]
rng: ReseedingRng<IsaacCore, ServoReseeder>,
}
impl RngCore for ServoRng {
#[inline]
fn next_u32(&mut self) -> u32 {
self.rng.next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
self.rng.next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
self.rng.fill_bytes(bytes)
}
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
self.rng.try_fill_bytes(bytes)
}
}
#[derive(Default)]
pub struct Seed([u8; 32]);
impl AsMut<[u8]> for Seed {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
impl SeedableRng for ServoRng {
type Seed = Seed;
// This function is used in the reseeding process of rand hence why the RESEED_THRESHOLD is
// used.
fn from_seed(seed: Seed) -> ServoRng {
trace!("Creating a new ServoRng.");
let isaac_rng = IsaacCore::from_seed(seed.0);
let reseeding_rng = ReseedingRng::new(isaac_rng, RESEED_THRESHOLD, ServoReseeder);
ServoRng { rng: reseeding_rng }
}
}
impl ServoRng {
/// Create a manually-reseeding instance of `ServoRng`.
///
/// Note that this RNG does not reseed itself, so care is needed to reseed the RNG
/// is required to be cryptographically sound.
pub fn new_manually_reseeded(seed: u64) -> ServoRng {
trace!("Creating a new manually-reseeded ServoRng.");
let isaac_rng = IsaacCore::seed_from_u64(seed);
let reseeding_rng = ReseedingRng::new(isaac_rng, 0, ServoReseeder);
ServoRng { rng: reseeding_rng }
}
}
impl Default for ServoRng {
/// Create an auto-reseeding instance of `ServoRng`.
///
/// This uses the shared `OsRng`, so avoids consuming
/// a file descriptor.
fn default() -> Self {
trace!("Creating new ServoRng.");
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
let isaac_rng = IsaacCore::from_rng(&mut *os_rng).unwrap();
let reseeding_rng = ReseedingRng::new(isaac_rng, RESEED_THRESHOLD, ServoReseeder);
ServoRng { rng: reseeding_rng }
}
}
// The reseeder for the in-memory RNG.
struct ServoReseeder;
impl RngCore for ServoReseeder {
#[inline]
fn next_u32(&mut self) -> u32 {
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
os_rng.next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
os_rng.next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
os_rng.fill_bytes(bytes)
}
#[inline]
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
os_rng.try_fill_bytes(bytes)
}
}
impl Default for ServoReseeder {
fn default() -> ServoReseeder {
ServoReseeder
}
}
// A thread-local RNG, designed as a drop-in replacement for rand::ThreadRng.
#[derive(Clone)]
pub struct ServoThreadRng {
rng: Rc<RefCell<ServoRng>>,
}
// A thread-local RNG, designed as a drop-in replacement for rand::thread_rng.
pub fn thread_rng() -> ServoThreadRng {
SERVO_THREAD_RNG.with(|t| t.clone())
}
thread_local! {
static SERVO_THREAD_RNG: ServoThreadRng = ServoThreadRng { rng: Rc::new(RefCell::new(ServoRng::default())) };
}
impl RngCore for ServoThreadRng {
fn next_u32(&mut self) -> u32 {
self.rng.borrow_mut().next_u32()
}
fn next_u64(&mut self) -> u64 {
self.rng.borrow_mut().next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
self.rng.borrow_mut().fill_bytes(bytes)
}
#[inline]
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
(self.rng.borrow_mut()).try_fill_bytes(bytes)
}
}
// Generates a random value using the thread-local random number generator.
// A drop-in replacement for rand::random.
#[inline]
pub fn random<T>() -> T
where
Standard: Distribution<T>,
{
thread_rng().r#gen()
}
// TODO(eijebong): Replace calls to this by random once `uuid::Uuid` implements `rand::Rand` again.
#[inline]
pub fn random_uuid() -> Uuid {
let mut bytes = [0; 16];
thread_rng().fill_bytes(&mut bytes);
Builder::from_random_bytes(bytes).into_uuid()
}

View File

@@ -100,6 +100,7 @@ percent-encoding = { workspace = true }
phf = "0.11"
pixels = { path = "../pixels" }
profile_traits = { workspace = true }
rand = { workspace = true }
range = { path = "../range" }
regex = { workspace = true }
rustc-hash = { workspace = true }
@@ -112,7 +113,6 @@ servo-media = { workspace = true }
servo_arc = { workspace = true }
servo_config = { path = "../config" }
servo_geometry = { path = "../geometry" }
servo_rand = { path = "../rand" }
servo_url = { path = "../url" }
smallvec = { workspace = true }
storage_traits = { workspace = true }

View File

@@ -6,10 +6,10 @@ use dom_struct::dom_struct;
use js::jsapi::{JSObject, Type};
use js::rust::CustomAutoRooterGuard;
use js::typedarray::{ArrayBufferView, ArrayBufferViewU8, TypedArray};
use servo_rand::{RngCore, ServoRng};
use rand::TryRngCore;
use rand::rngs::OsRng;
use uuid::Uuid;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::CryptoBinding::CryptoMethods;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
@@ -23,8 +23,6 @@ use crate::script_runtime::{CanGc, JSContext};
#[dom_struct]
pub(crate) struct Crypto {
reflector_: Reflector,
#[no_trace]
rng: DomRefCell<ServoRng>,
subtle: MutNullableDom<SubtleCrypto>,
}
@@ -32,7 +30,6 @@ impl Crypto {
fn new_inherited() -> Crypto {
Crypto {
reflector_: Reflector::new(),
rng: DomRefCell::new(ServoRng::default()),
subtle: MutNullableDom::default(),
}
}
@@ -68,7 +65,11 @@ impl CryptoMethods<crate::DomTypeHolder> for Crypto {
requested: None,
});
}
self.rng.borrow_mut().fill_bytes(data);
if OsRng.try_fill_bytes(data).is_err() {
return Err(Error::JSFailed);
}
let underlying_object = unsafe { input.underlying_object() };
TypedArray::<ArrayBufferViewU8, *mut JSObject>::from(*underlying_object)
.map_err(|_| Error::JSFailed)

View File

@@ -16,8 +16,8 @@ use js::rust::HandleObject;
use mime::{self, Mime};
use net_traits::http_percent_encode;
use net_traits::request::Referrer;
use rand::random;
use rustc_hash::FxBuildHasher;
use servo_rand::random;
use style::attr::AttrValue;
use style::str::split_html_space_chars;
use stylo_atoms::Atom;

View File

@@ -19,10 +19,8 @@ use js::jsval::{ObjectValue, UndefinedValue};
use js::rust::wrappers::JS_ParseJSON;
use js::rust::{HandleValue, MutableHandleValue};
use js::typedarray::ArrayBufferU8;
use servo_rand::ServoRng;
use crate::dom::bindings::buffer_source::create_buffer_source;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{
CryptoKeyMethods, KeyType, KeyUsage,
};
@@ -112,15 +110,12 @@ enum Operation {
#[dom_struct]
pub(crate) struct SubtleCrypto {
reflector_: Reflector,
#[no_trace]
rng: DomRefCell<ServoRng>,
}
impl SubtleCrypto {
fn new_inherited() -> SubtleCrypto {
SubtleCrypto {
reflector_: Reflector::new(),
rng: DomRefCell::new(ServoRng::default()),
}
}
@@ -709,7 +704,6 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
&subtle.global(),
extractable,
key_usages,
&subtle.rng,
CanGc::note(),
) {
Ok(result) => result,
@@ -2540,51 +2534,30 @@ impl NormalizedAlgorithm {
global: &GlobalScope,
extractable: bool,
usages: Vec<KeyUsage>,
rng: &DomRefCell<ServoRng>,
can_gc: CanGc,
) -> Result<CryptoKeyOrCryptoKeyPair, Error> {
match self {
NormalizedAlgorithm::AesKeyGenParams(algo) => match algo.name.as_str() {
ALG_AES_CTR => aes_operation::generate_key_aes_ctr(
global,
algo,
extractable,
usages,
rng,
can_gc,
)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
ALG_AES_CBC => aes_operation::generate_key_aes_cbc(
global,
algo,
extractable,
usages,
rng,
can_gc,
)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
ALG_AES_GCM => aes_operation::generate_key_aes_gcm(
global,
algo,
extractable,
usages,
rng,
can_gc,
)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
ALG_AES_KW => aes_operation::generate_key_aes_kw(
global,
algo,
extractable,
usages,
rng,
can_gc,
)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
ALG_AES_CTR => {
aes_operation::generate_key_aes_ctr(global, algo, extractable, usages, can_gc)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
},
ALG_AES_CBC => {
aes_operation::generate_key_aes_cbc(global, algo, extractable, usages, can_gc)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
},
ALG_AES_GCM => {
aes_operation::generate_key_aes_gcm(global, algo, extractable, usages, can_gc)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
},
ALG_AES_KW => {
aes_operation::generate_key_aes_kw(global, algo, extractable, usages, can_gc)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
},
_ => Err(Error::NotSupported),
},
NormalizedAlgorithm::HmacKeyGenParams(algo) => {
hmac_operation::generate_key(global, algo, extractable, usages, rng, can_gc)
hmac_operation::generate_key(global, algo, extractable, usages, can_gc)
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
},
_ => Err(Error::NotSupported),

View File

@@ -10,9 +10,9 @@ use aes_gcm::{AeadInPlace, AesGcm, KeyInit};
use aes_kw::{KekAes128, KekAes192, KekAes256};
use base64::prelude::*;
use cipher::consts::{U12, U16, U32};
use servo_rand::{RngCore, ServoRng};
use rand::TryRngCore;
use rand::rngs::OsRng;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{
CryptoKeyMethods, KeyType, KeyUsage,
};
@@ -108,7 +108,6 @@ pub(crate) fn generate_key_aes_ctr(
normalized_algorithm: &SubtleAesKeyGenParams,
extractable: bool,
usages: Vec<KeyUsage>,
rng: &DomRefCell<ServoRng>,
can_gc: CanGc,
) -> Result<DomRoot<CryptoKey>, Error> {
generate_key_aes(
@@ -116,7 +115,6 @@ pub(crate) fn generate_key_aes_ctr(
normalized_algorithm,
extractable,
usages,
rng,
ALG_AES_CTR,
&[
KeyUsage::Encrypt,
@@ -258,7 +256,6 @@ pub(crate) fn generate_key_aes_cbc(
normalized_algorithm: &SubtleAesKeyGenParams,
extractable: bool,
usages: Vec<KeyUsage>,
rng: &DomRefCell<ServoRng>,
can_gc: CanGc,
) -> Result<DomRoot<CryptoKey>, Error> {
generate_key_aes(
@@ -266,7 +263,6 @@ pub(crate) fn generate_key_aes_cbc(
normalized_algorithm,
extractable,
usages,
rng,
ALG_AES_CBC,
&[
KeyUsage::Encrypt,
@@ -547,7 +543,6 @@ pub(crate) fn generate_key_aes_gcm(
normalized_algorithm: &SubtleAesKeyGenParams,
extractable: bool,
usages: Vec<KeyUsage>,
rng: &DomRefCell<ServoRng>,
can_gc: CanGc,
) -> Result<DomRoot<CryptoKey>, Error> {
generate_key_aes(
@@ -555,7 +550,6 @@ pub(crate) fn generate_key_aes_gcm(
normalized_algorithm,
extractable,
usages,
rng,
ALG_AES_GCM,
&[
KeyUsage::Encrypt,
@@ -687,7 +681,6 @@ pub(crate) fn generate_key_aes_kw(
normalized_algorithm: &SubtleAesKeyGenParams,
extractable: bool,
usages: Vec<KeyUsage>,
rng: &DomRefCell<ServoRng>,
can_gc: CanGc,
) -> Result<DomRoot<CryptoKey>, Error> {
generate_key_aes(
@@ -695,7 +688,6 @@ pub(crate) fn generate_key_aes_kw(
normalized_algorithm,
extractable,
usages,
rng,
ALG_AES_KW,
&[KeyUsage::WrapKey, KeyUsage::UnwrapKey],
can_gc,
@@ -745,7 +737,6 @@ fn generate_key_aes(
normalized_algorithm: &SubtleAesKeyGenParams,
extractable: bool,
usages: Vec<KeyUsage>,
rng: &DomRefCell<ServoRng>,
alg_name: &str,
allowed_usages: &[KeyUsage],
can_gc: CanGc,
@@ -764,7 +755,10 @@ fn generate_key_aes(
// Step 3. Generate an AES key of length equal to the length member of normalizedAlgorithm.
// Step 4. If the key generation step fails, then throw an OperationError.
let mut rand = vec![0; normalized_algorithm.length as usize / 8];
rng.borrow_mut().fill_bytes(&mut rand);
if OsRng.try_fill_bytes(&mut rand).is_err() {
return Err(Error::JSFailed);
}
let handle = match normalized_algorithm.length {
128 => Handle::Aes128(rand),
192 => Handle::Aes192(rand),

View File

@@ -4,11 +4,11 @@
use aws_lc_rs::hmac;
use base64::prelude::*;
use rand::TryRngCore;
use rand::rngs::OsRng;
use script_bindings::codegen::GenericBindings::CryptoKeyBinding::CryptoKeyMethods;
use script_bindings::domstring::DOMString;
use servo_rand::{RngCore, ServoRng};
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, KeyUsage};
use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::{JsonWebKey, KeyFormat};
use crate::dom::bindings::error::Error;
@@ -75,7 +75,6 @@ pub(crate) fn generate_key(
normalized_algorithm: &SubtleHmacKeyGenParams,
extractable: bool,
usages: Vec<KeyUsage>,
rng: &DomRefCell<ServoRng>,
can_gc: CanGc,
) -> Result<DomRoot<CryptoKey>, Error> {
// Step 1. If usages contains any entry which is not "sign" or "verify", then throw a SyntaxError.
@@ -107,11 +106,11 @@ pub(crate) fn generate_key(
};
// Step 3. Generate a key of length length bits.
let mut key_data = vec![0; length as usize];
rng.borrow_mut().fill_bytes(&mut key_data);
// Step 4. If the key generation step fails, then throw an OperationError.
// NOTE: Our key generation is infallible.
let mut key_data = vec![0; length as usize];
if OsRng.try_fill_bytes(&mut key_data).is_err() {
return Err(Error::JSFailed);
}
// Step 6. Let algorithm be a new HmacKeyAlgorithm.
// Step 7. Set the name attribute of algorithm to "HMAC".

View File

@@ -23,7 +23,7 @@ use net_traits::request::{
CredentialsMode, Destination, InsecureRequestsPolicy, ParserMetadata, Referrer, RequestBuilder,
RequestMode,
};
use servo_rand::random;
use rand::random;
use servo_url::{ImmutableOrigin, ServoUrl};
use style::thread_state::{self, ThreadState};

View File

@@ -25,8 +25,8 @@ use net_traits::CustomResponseMediator;
use net_traits::request::{
CredentialsMode, Destination, InsecureRequestsPolicy, ParserMetadata, Referrer, RequestBuilder,
};
use rand::random;
use servo_config::pref;
use servo_rand::random;
use servo_url::ServoUrl;
use style::thread_state::{self, ThreadState};

View File

@@ -185,7 +185,7 @@ malloc_size_of_is_0!(WorkletId);
impl WorkletId {
fn new() -> WorkletId {
WorkletId(servo_rand::random_uuid())
WorkletId(Uuid::new_v4())
}
}

View File

@@ -34,11 +34,11 @@ num-traits = { workspace = true }
percent-encoding = { workspace = true }
pixels = { path = "../../pixels" }
profile_traits = { path = "../profile" }
rand = { workspace = true }
rustc-hash = { workspace = true }
rustls-pki-types = { workspace = true }
serde = { workspace = true }
servo_arc = { workspace = true }
servo_rand = { path = "../../rand" }
servo_url = { path = "../../url" }
url = { workspace = true }
uuid = { workspace = true }

View File

@@ -23,11 +23,11 @@ use ipc_channel::router::ROUTER;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
use mime::Mime;
use rand::{RngCore, rng};
use request::RequestId;
use rustc_hash::FxHashMap;
use rustls_pki_types::CertificateDer;
use serde::{Deserialize, Serialize};
use servo_rand::RngCore;
use servo_url::{ImmutableOrigin, ServoUrl};
use crate::filemanager_thread::FileManagerThreadMsg;
@@ -1107,5 +1107,4 @@ pub fn set_default_accept_language(headers: &mut HeaderMap) {
);
}
pub static PRIVILEGED_SECRET: LazyLock<u32> =
LazyLock::new(|| servo_rand::ServoRng::default().next_u32());
pub static PRIVILEGED_SECRET: LazyLock<u32> = LazyLock::new(|| rng().next_u32());

View File

@@ -26,7 +26,7 @@ pub struct RequestId(pub Uuid);
impl Default for RequestId {
fn default() -> Self {
Self(servo_rand::random_uuid())
Self(Uuid::new_v4())
}
}

View File

@@ -17,8 +17,8 @@ doctest = false
encoding_rs = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] }
servo_arc = { workspace = true }
servo_rand = { path = "../rand" }
url = { workspace = true, features = ["serde"] }
uuid = { workspace = true, features = ["serde"] }

View File

@@ -40,14 +40,12 @@ impl ImmutableOrigin {
/// Creates a new opaque origin that is only equal to itself.
pub fn new_opaque() -> ImmutableOrigin {
ImmutableOrigin::Opaque(OpaqueOrigin::Opaque(servo_rand::random_uuid()))
ImmutableOrigin::Opaque(OpaqueOrigin::Opaque(Uuid::new_v4()))
}
// For use in mixed security context tests because data: URL workers inherit contexts
pub fn new_opaque_data_url_worker() -> ImmutableOrigin {
ImmutableOrigin::Opaque(OpaqueOrigin::SecureWorkerFromDataUrl(
servo_rand::random_uuid(),
))
ImmutableOrigin::Opaque(OpaqueOrigin::SecureWorkerFromDataUrl(Uuid::new_v4()))
}
pub fn scheme(&self) -> Option<&str> {

View File

@@ -70,17 +70,6 @@ allow = []
# List of crates to deny:
deny = [
"num",
# cargo-deny does not allow denying the rand crate while also skipping
# it for duplicate checks. While the ecosystem is split between 0.8 and 0.9,
# we need to prioritize allowing duplicate versions.
#{ crate = "rand", wrappers = [
# "ipc-channel",
# "phf_generator",
# "quickcheck",
# "servo_rand",
# "tracing-perfetto",
# "tungstenite",
#] },
]
# List of crates to skip for the duplicate check: