openssl/openssl
Random
Active contributors: Pauli, Tomas Mraz, slontis, Bob Beck
Purpose
OpenSSL builds a hierarchy of NIST SP 800-90A DRBGs (CTR, HMAC, HASH) seeded from an OS-provided entropy source (or a CPU jitter source on FIPS builds). The hierarchy gives every libctx and every thread its own DRBG instance while sharing a small number of seed sources.
The user-facing API is the legacy RAND_* family (RAND_bytes, RAND_priv_bytes, RAND_status, …) plus the modern EVP_RAND / EVP_RAND_CTX from EVP. Both ultimately call into the same provider implementations.
Directory layout
crypto/rand/
├── rand_lib.c -- the public RAND_* API and the per-libctx DRBG hierarchy
├── rand_local.h
├── rand_pool.c -- entropy pool helper
├── rand_unix.c -- Linux/macOS/BSD entropy collector (getrandom, /dev/urandom, ...)
├── rand_win.c -- Windows entropy collector
├── rand_vms.c -- VMS entropy collector
├── rand_vxworks.c -- VxWorks entropy collector
├── rand_uefi.c -- UEFI entropy collector
├── rand_egd.c -- EGD-style entropy daemon support
├── rand_meth.c, randfile.c, rand_deprecated.c, rand_err.c
├── rand_seed.c -- the OS-independent "seed source" interface
└── prov_seed.c -- the seed source exposed back to providers via the OSSL_OP_RAND interface
providers/implementations/rands/
├── drbg.c -- the DRBG state machine common to all three variants
├── drbg_local.h
├── drbg_ctr.c -- AES-CTR-DRBG (NIST SP 800-90A)
├── drbg_hash.c -- HASH-DRBG (NIST SP 800-90A)
├── drbg_hmac.c -- HMAC-DRBG (NIST SP 800-90A)
├── seeding/ -- platform-specific entropy gathering helpers (used by both rand and FIPS)
├── seed_src.c -- the SEED-SRC pseudo-RAND used by the DRBGs to draw from the OS entropy
├── seed_src_jitter.c -- the jitter entropy variant (FIPS jitter mode)
├── crngt.c -- the continuous RNG self-test
└── test_rng.c -- the deterministic test-only RAND used in unit testsDRBG hierarchy
graph TD
OS[OS entropy<br/>getrandom / RDRAND fallback / /dev/urandom / ...] -->|seeds| Primary
Primary[Primary DRBG<br/>per OSSL_LIB_CTX] -->|reseeds| Public
Primary -->|reseeds| Private
Public[Public DRBG<br/>per thread] -->|RAND_bytes| App
Private[Private DRBG<br/>per thread] -->|RAND_priv_bytes| AppFor each OSSL_LIB_CTX:
- One primary DRBG draws entropy from the OS seed source.
- Each thread has its own public and private DRBG that periodically reseed from the primary.
RAND_bytesconsumes the public DRBG;RAND_priv_bytesconsumes the private DRBG (used when generating long-lived secrets like RSA private keys, so a forensics-style compromise of one stream doesn't leak the other).
The reseed schedule is controlled by OSSL_DRBG_PARAM_RESEED_* parameters (interval, time, requests) — see include/openssl/core_names.h.in.
Selecting the DRBG type
By default the primary uses CTR-DRBG over AES-256 (also denoted CTR-DRBG-AES256). It is the fastest of the three on x86 with AES-NI. To pick a different one:
EVP_set_default_properties(libctx, "");
RAND_set_DRBG_type(libctx, "HASH-DRBG", NULL, NULL, NULL);Or per-libctx via openssl.cnf (RANDFILE / [rand] section).
Compile-time flag OPENSSL_DEFAULT_RAND_TYPE controls the build's preferred primary.
Entropy sources
crypto/rand/rand_unix.c (and the per-OS counterparts) try a sequence of entropy mechanisms:
getrandom(GRND_NONBLOCK)(Linux, FreeBSD ≥ 12, OpenBSD ≥ 5.6, …).getentropy()(macOS, OpenBSD)./dev/urandom.- CPU instructions (
RDRAND/RDSEEDviacrypto/cpuid.cand the asm helpers). - EGD-style daemons (
rand_egd.c).
The collector pushes raw bytes into a pool managed by rand_pool.c, then condenses them into a seed for the primary DRBG.
Continuous self-test
The Continuous RNG Test (CRNGT, crngt.c) verifies that consecutive raw entropy draws are not equal — defense against a stuck source. It runs on every block of entropy drawn from the seed source and is mandatory for FIPS.
FIPS mode
When the FIPS provider is loaded, it has its own DRBG hierarchy inside its private libctx (a "child" libctx — see subsystems/core-and-libctx). The same DRBG state machine in providers/implementations/rands/drbg.c is reused. Two FIPS-relevant entropy options:
- External entropy (default): the FIPS module uses a host-provided entropy source via
OSSL_FUNC_RAND_GET_SEED. - Jitter entropy (with
enable-fips-jitter, 3.5+): the module ships its own jitter source. This makes the module non-compliant unless an ESV is independently completed; seeREADME-FIPS.md.
Test RAND
test_rng.c is a deterministic RAND that the test suite installs to make crypto tests reproducible. OPENSSL_TEST_RAND_SEED=42 make test seeds it from the env var.
Integration points
- Every
RAND_bytes/RAND_priv_bytescall routes through the per-libctx DRBG hierarchy. - Asymmetric key generation uses
RAND_priv_bytes. Symmetric IVs useRAND_bytes. - TLS 1.3 / QUIC generate random data via the same hierarchy;
EVP_RAND_CTXdirectly when very large or non-default amounts are needed. - Providers call back into core via
OSSL_FUNC_get_seed/OSSL_FUNC_clear_seedwhen they need entropy (this is how the FIPS provider gets its seed).
Entry points for modification
- New entropy source: add a backend in
crypto/rand/rand_<plat>.cand route it viacrypto/rand/rand_lib.c. Be careful with reentrancy — the seed path runs at first-use of any DRBG. - New DRBG variant: extend
providers/implementations/rands/drbg_*.c, register it in the provider table. - Reseed policy: per-instance
OSSL_DRBG_PARAM_*parameters. Defaults are indrbg_local.h.
Documentation
doc/man7/RAND.pod,doc/man3/RAND_bytes.pod,RAND_set_DRBG_type.pod,EVP_RAND.pod.doc/man3/RAND_load_file.pod— file-based seeding.doc/man7/EVP_RAND-CTR-DRBG.pod,EVP_RAND-HASH-DRBG.pod,EVP_RAND-HMAC-DRBG.pod,EVP_RAND-JITTER.pod,EVP_RAND-SEED-SRC.pod.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.