Skip to content
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

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
75 changes: 37 additions & 38 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ 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
`CryptoBlockRng`. Generators (RNGs) implementing one of these traits which are
used according to these additional constraints:

- If the RNG implements `Default`, it may be default-constructed
- If the RNG implements `SeedableRng`, it may be constructed and seeded using
`SeedableRng::from_seed` with a cryptographically secure seed value
- If the RNG implements `SeedableRng`, it may be constructed and seeded from
another RNG which is itself cryptographically secure
Comment on lines +16 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I reading this correctly ...
Default means it will be seeded securely and automatically without any work by the caller.
SeedableRng relies on the caller providing a seed that is cryptographically secure from some other source, possibly from another RNG.

If so maybe this is more clear to have one SeedableRng bullet...

Suggested change
- If the RNG implements `Default`, it may be default-constructed
- If the RNG implements `SeedableRng`, it may be constructed and seeded using
`SeedableRng::from_seed` with a cryptographically secure seed value
- If the RNG implements `SeedableRng`, it may be constructed and seeded from
another RNG which is itself cryptographically secure
- If the RNG implements `Default`, it may be default-constructed
- If the RNG implements `SeedableRng`, it may be constructed and seeded using
`SeedableRng::from_seed` with a cryptographically secure seed value, possibly
from another RNG which is itself cryptographically secure

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OsRng and ThreadRng can be default constructed and be secure.

Another way to read this is that a CryptoRng should not support Default if the result would be insecure.

I admit that there is potential for confusion here. Perhaps I should add to the first point:

Note that generators should only implement Default where a default-constructed instance is no more predictable than a securely seeded instance; for example OsRng (which is a stateless) supports Default construction.

- The state (memory) of the RNG and its seed value are not exposed

are expected to provide the following:
Expand All @@ -34,48 +37,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.