Skip to content

Commit ae91548

Browse files
committed
crypto_provider: avoid rand dep for GREASE HPKE
Previously we used the `rand` crate as a convenient way to select a supported HPKE suite at random for ECH when using GREASE. In general it's crummy to take a dep for such a minor need. Instead, adapt the crypto provider CSRNG to this task by performing a truncated uniform sampling. This should be more than sufficient for the use-case and avoids an extra dep.
1 parent c74587b commit ae91548

File tree

5 files changed

+32
-9
lines changed

5 files changed

+32
-9
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ webpki = { package = "rustls-webpki", version = "0.102.0", default-features = fa
1717
libc = "0.2"
1818
log = "0.4.22"
1919
rustls-platform-verifier = "0.5"
20-
rand = "0.8"
2120
regex = "1.9.6"
2221
toml = { version = "0.6.0", default-features = false, features = ["parse"] }
2322
hickory-resolver = { version = "=0.25.0-alpha.4", features = ["dns-over-https-rustls", "webpki-roots"] }

librustls/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ webpki = { workspace = true }
3333
libc = { workspace = true }
3434
log = { workspace = true }
3535
rustls-platform-verifier = { workspace = true }
36-
rand = { workspace = true }
3736

3837
[lib]
3938
name = "rustls_ffi"

librustls/src/client.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,12 @@ impl rustls_client_config_builder {
454454
let builder = try_mut_from_ptr!(builder);
455455
let hpke = try_ref_from_ptr!(hpke);
456456

457-
let Some((suite, placeholder_pk)) = hpke.grease_public_key() else {
457+
let provider = match &builder.provider {
458+
Some(provider) => provider,
459+
None => return rustls_result::NoDefaultCryptoProvider,
460+
};
461+
462+
let Some((suite, placeholder_pk)) = hpke.grease_public_key(provider) else {
458463
return rustls_result::HpkeError;
459464
};
460465

librustls/src/crypto_provider.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::slice;
22
use std::sync::Arc;
33

44
use libc::size_t;
5-
use rand::seq::SliceRandom;
65

76
#[cfg(feature = "aws-lc-rs")]
87
use rustls::crypto::aws_lc_rs;
@@ -509,10 +508,28 @@ impl Hpke {
509508
///
510509
/// Returns both the selected Rustls `hpke::Hpke` suite and the `hpke::HpkePublicKey`
511510
/// or `None` if an error occurs.
512-
pub(crate) fn grease_public_key(&self) -> Option<(&dyn hpke::Hpke, hpke::HpkePublicKey)> {
513-
let suite = self.suites.choose(&mut rand::thread_rng())?;
511+
pub(crate) fn grease_public_key(
512+
&self,
513+
provider: &CryptoProvider,
514+
) -> Option<(&dyn hpke::Hpke, hpke::HpkePublicKey)> {
515+
let num_suites = self.suites.len();
516+
if num_suites == 0 {
517+
return None;
518+
}
519+
debug_assert!(num_suites < u32::MAX as usize);
520+
521+
let mut buf = [0u8; 4];
522+
let threshold = u32::MAX - (u32::MAX % num_suites as u32);
523+
let suite = loop {
524+
provider.secure_random.fill(&mut buf).ok()?;
525+
let value = u32::from_ne_bytes(buf);
526+
if value < threshold {
527+
break self.suites[value as usize / (threshold as usize / num_suites)];
528+
}
529+
};
530+
514531
let pk = suite.generate_key_pair().map(|pair| pair.0).ok()?;
515-
Some((*suite, pk))
532+
Some((suite, pk))
516533
}
517534
}
518535

@@ -625,13 +642,17 @@ mod tests {
625642
#[test]
626643
#[cfg(feature = "aws-lc-rs")]
627644
fn test_hpke_aws_lc_rs() {
645+
let provider = rustls_crypto_provider_default();
646+
assert!(!provider.is_null());
647+
let provider = try_clone_arc!(provider);
648+
628649
let hpke = rustls_supported_hpke();
629650
assert!(!hpke.is_null());
630651

631652
let hpke = try_ref_from_ptr!(hpke);
632653

633654
// We should be able to pick an HPKE suite and a pubkey for ECH GREASE.
634-
let (suite, pk) = hpke.grease_public_key().unwrap();
655+
let (suite, pk) = hpke.grease_public_key(&provider).unwrap();
635656
// The PK and the suite should be compatible. Setup a sealer to check.
636657
let (_, _) = suite.setup_sealer(&[0xC0, 0xFF, 0xEE], &pk).unwrap();
637658
}

0 commit comments

Comments
 (0)