Skip to content

Revise "not a crypto library" policy and SECURITY.md #1565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ Rand **is not**:
not simplicity. If you prefer a small-and-simple library, there are
alternatives including [fastrand](https://crates.io/crates/fastrand)
and [oorandom](https://crates.io/crates/oorandom).
- A cryptography library. Rand provides functionality for generating
unpredictable random data (potentially applicable depending on requirements)
but does not provide high-level cryptography functionality.

Rand is a community project and cannot provide legally-binding guarantees of
security.
- Primarily a cryptographic library. `rand` does provide some generators which
aim to support unpredictable value generation under certain constraints;
see [SECURITY.md](SECURITY.md) for details.
Users are expected to determine for themselves
whether `rand`'s functionality meets their own security requirements.

Documentation:

Expand Down Expand Up @@ -97,16 +96,13 @@ Many (but not all) algorithms are intended to have reproducible output. Read mor

The Rand library supports a variety of CPU architectures. Platform integration is outsourced to [getrandom].

### WASM support
### WebAssembly support

Seeding entropy from OS on WASM target `wasm32-unknown-unknown` is not
*automatically* supported by `rand` or `getrandom`. If you are fine with
seeding the generator manually, you can disable the `os_rng` feature
and use the methods on the `SeedableRng` trait. To enable seeding from OS,
either use a different target such as `wasm32-wasi` or add a direct
dependency on [getrandom] with the `js` feature (if the target supports
JavaScript). See
[getrandom#WebAssembly support](https://docs.rs/getrandom/latest/getrandom/#webassembly-support).
The [WASI](https://github.com/WebAssembly/WASI/tree/main) and Emscripten
targets are directly supported. The `wasm32-unknown-unknown` target is not
*automatically* supported. To enable support for this target, refer to the
[`getrandom` documentation for WebAssembly](https://docs.rs/getrandom/latest/getrandom/#webassembly-support).
Alternatively, the `os_rng` feature may be disabled.

# License

Expand Down
86 changes: 47 additions & 39 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,24 @@ security.
### Marker traits

Rand provides the marker traits `CryptoRng`, `TryCryptoRng` and
`CryptoBlockRng`. Generators implementing one of these traits and used in a way
which meets the following additional constraints:

- Instances of seedable RNGs (those implementing `SeedableRng`) are
constructed with cryptographically secure seed values
- The state (memory) of the RNG and its seed value are not exposed
`CryptoBlockRng`. Generators (RNGs) implementing one of these traits which are
used according to these additional constraints:

- The generator may be constructed using `std::default::Default` where the
generator supports this trait. Note that generators should *only* support
`Default` where the `default()` instance is appropriately seeded: for
example `OsRng` has no state and thus has a trivial `default()` instance
while `ThreadRng::default()` returns a handle to a thread-local instance
seeded using `OsRng`.
- The generator may be constructed using `rand_core::SeedableRng` in any of
the following ways where the generator supports this trait:

- Via `SeedableRng::from_seed` using a cryptographically secure seed value
- Via `SeedableRng::from_rng` or `try_from_rng` using a cryptographically
secure source `rng`
- Via `SeedableRng::from_os_rng` or `try_from_os_rng`
- The state (memory) of the generator and its seed value (or source `rng`) are
not exposed

are expected to provide the following:

Expand All @@ -34,48 +46,44 @@ are expected to provide the following:
`OsRng` is a stateless "generator" implemented via [getrandom]. As such, it has
no possible state to leak and cannot be improperly seeded.

`ThreadRng` will periodically reseed itself, thus placing an upper bound on the
number of bits of output from an instance before any advantage an attacker may
have gained through state-compromising side-channel attacks is lost.
`StdRng` is a `CryptoRng` and `SeedableRng` using a pseudo-random algorithm
selected for good security and performance qualities. Since it does not offer
reproducibility of output, its algorithm may be changed in any release version.

`ChaCha12Rng` and `ChaCha20Rng` are selected pseudo-random generators
distributed by the `rand` project which meet the requirements of the `CryptoRng`
trait and implement `SeedableRng` with a commitment to reproducibility of
results.

`ThreadRng` is a conveniently-packaged generator over `StdRng` offering
automatic seeding from `OsRng`, periodic reseeding and thread locality.
This random source is intended to offer a good compromise between cryptographic
security, fast generation with reasonably low memory and initialization cost
overheads, and robustness against misuse.

[getrandom]: https://crates.io/crates/getrandom

### Distributions

Additionally, derivations from such an RNG (including the `Rng` trait,
implementations of the `Distribution` trait, and `seq` algorithms) should not
introduce significant bias other than that expected from the operation in
question (e.g. bias from a weighted distribution).
Methods of the `Rng` trait, functionality of the `rand::seq` module and
implementators of the `Distribution` trait are expected, while using a
cryptographically secure `CryptoRng` instance meeting the above constraints,
to not introduce significant bias to their operation beyond what would be
expected of the operation. Note that the usage of 'significant' here permits
some bias, as noted for example in the documentation of the `Uniform`
distribution.

## Supported Versions

We will attempt to uphold these premises in the following crate versions,
provided that only the latest patch version is used, and with potential
exceptions for theoretical issues without a known exploit:

| Crate | Versions | Exceptions |
| ----- | -------- | ---------- |
| `rand` | 0.8 | |
| `rand` | 0.7 | |
| `rand` | 0.5, 0.6 | Jitter |
| `rand` | 0.4 | Jitter, ISAAC |
| `rand_core` | 0.2 - 0.6 | |
| `rand_chacha` | 0.1 - 0.3 | |
We aim to provide security fixes in the form of a new patch version for the
latest release version of `rand` and its dependencies `rand_core` and
`rand_chacha`, as well as for prior major and minor releases which were, at some
time during the previous 12 months, the latest release version.

Explanation of exceptions:

- Jitter: `JitterRng` is used as an entropy source when the primary source
fails; this source may not be secure against side-channel attacks, see #699.
- ISAAC: the [ISAAC](https://burtleburtle.net/bob/rand/isaacafa.html) RNG used
to implement `ThreadRng` is difficult to analyse and thus cannot provide
strong assertions of security.

## Known issues
## Reporting a Vulnerability

In `rand` version 0.3 (0.3.18 and later), if `OsRng` fails, `ThreadRng` is
seeded from the system time in an insecure manner.
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.

## Reporting a Vulnerability
Please disclose it at [security advisory](https://github.com/rust-random/rand/security/advisories/new).

To report a vulnerability, [open a new issue](https://github.com/rust-random/rand/issues/new).
Once the issue is resolved, the vulnerability should be [reported to RustSec](https://github.com/RustSec/advisory-db/blob/master/CONTRIBUTING.md).
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.
58 changes: 34 additions & 24 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,32 +175,32 @@ where
}
}

/// A marker trait used to indicate that an [`RngCore`] implementation is
/// supposed to be cryptographically secure.
/// A marker trait over [`RngCore`] for securely unpredictable RNGs
///
/// *Cryptographically secure generators*, also known as *CSPRNGs*, should
/// satisfy an additional properties over other generators: given the first
/// *k* bits of an algorithm's output
/// sequence, it should not be possible using polynomial-time algorithms to
/// predict the next bit with probability significantly greater than 50%.
/// This marker trait indicates that the implementing generator is intended,
/// when correctly seeded and protected from side-channel attacks such as a
/// leaking of state, to be a cryptographically secure generator. This trait is
/// provided as a tool to aid review of cryptographic code, but does not by
/// itself guarantee suitability for cryptographic applications.
///
/// Some generators may satisfy an additional property, however this is not
/// required by this trait: if the CSPRNG's state is revealed, it should not be
/// computationally-feasible to reconstruct output prior to this. Some other
/// generators allow backwards-computation and are considered *reversible*.
/// Implementors of `CryptoRng` automatically implement the [`TryCryptoRng`]
/// trait.
///
/// Note that this trait is provided for guidance only and cannot guarantee
/// suitability for cryptographic applications. In general it should only be
/// implemented for well-reviewed code implementing well-regarded algorithms.
/// Implementors of `CryptoRng` should only implement [`Default`] if the
/// `default()` instances are themselves secure generators: for example if the
/// implementing type is a stateless interface over a secure external generator
/// (like [`OsRng`]) or if the `default()` instance uses a strong, fresh seed.
///
/// Note also that use of a `CryptoRng` does not protect against other
/// weaknesses such as seeding from a weak entropy source or leaking state.
///
/// Note that implementors of [`CryptoRng`] also automatically implement
/// the [`TryCryptoRng`] trait.
/// Formally, a CSPRNG (Cryptographically Secure Pseudo-Random Number Generator)
/// should satisfy an additional property over other generators: assuming that
/// the generator has been appropriately seeded and has unknown state, then
/// given the first *k* bits of an algorithm's output
/// sequence, it should not be possible using polynomial-time algorithms to
/// predict the next bit with probability significantly greater than 50%.
///
/// [`BlockRngCore`]: block::BlockRngCore
/// [`Infallible`]: core::convert::Infallible
/// An optional property of CSPRNGs is backtracking resistance: if the CSPRNG's
/// state is revealed, it will not be computationally-feasible to reconstruct
/// prior output values. This property is not required by `CryptoRng`.
pub trait CryptoRng: RngCore {}

impl<T: DerefMut> CryptoRng for T where T::Target: CryptoRng {}
Expand Down Expand Up @@ -269,10 +269,20 @@ impl<R: RngCore> TryRngCore for R {
}
}

/// A marker trait used to indicate that a [`TryRngCore`] implementation is
/// supposed to be cryptographically secure.
/// A marker trait over [`TryRngCore`] for securely unpredictable RNGs
///
/// This trait is like [`CryptoRng`] but for the trait [`TryRngCore`].
///
/// This marker trait indicates that the implementing generator is intended,
/// when correctly seeded and protected from side-channel attacks such as a
/// leaking of state, to be a cryptographically secure generator. This trait is
/// provided as a tool to aid review of cryptographic code, but does not by
/// itself guarantee suitability for cryptographic applications.
///
/// See [`CryptoRng`] docs for more information about cryptographically secure generators.
/// Implementors of `TryCryptoRng` should only implement [`Default`] if the
/// `default()` instances are themselves secure generators: for example if the
/// implementing type is a stateless interface over a secure external generator
/// (like [`OsRng`]) or if the `default()` instance uses a strong, fresh seed.
pub trait TryCryptoRng: TryRngCore {}

impl<R: CryptoRng> TryCryptoRng for R {}
Expand Down