1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
use log::error;
use rand::rngs::adapter::ReseedingRng;
use rand::rngs::OsRng;
use rand::FromEntropy;
use rand_chacha::ChaChaCore;

// A `ChaChaRng` which is periodically reseeded from an `OsRng`. This was originally using an
// `OsRng`, but sourcing entropy from the kernel was measured to be a performance bottleneck.
// Conventional wisdom seems to be that a securely seeded ChaCha20 PRNG is secure enough for
// cryptographic purposes, so it's certainly secure enough for generating unpredictable session
// identifiers.
pub(super) type SessionIdentifierRng = ReseedingRng<ChaChaCore, OsRng>;

pub(super) fn session_identifier_rng() -> SessionIdentifierRng {
    let os_rng = match OsRng::new() {
        Ok(rng) => rng,
        Err(e) => {
            error!(
                "Backend::random_identifier failed at rand::OsRng::new(), \
                 is the system RNG missing? {:?}",
                e
            );
            unreachable!("no rng available, this should never happen");
        }
    };

    let rng = ChaChaCore::from_entropy();

    // Reseed every 32KiB.
    ReseedingRng::new(rng, 32_768, os_rng)
}