openssl/openssl
FIPS provider
Active contributors: Pauli, slontis, Tomas Mraz
Purpose
The FIPS provider is a separately-built shared module (fips.so on Unix, fips.dll on Windows) that ships a subset of the default provider's algorithms in a form that can be FIPS 140 validated. It is the only piece of OpenSSL whose object code is meant to be bit-for-bit identical to a previously-validated copy.
The user-facing setup is documented in README-FIPS.md. This page walks through the implementation.
Directory layout
providers/
├── fips/
│ ├── fips_entry.c -- the OSSL_provider_init entry symbol
│ ├── fipsprov.c -- ~56 KB: dispatch tables, capabilities, init
│ ├── self_test.c -- on-load tests (integrity check + KATs)
│ ├── self_test_data.c -- 184 KB of test vectors (SHA, RSA, ECDSA, …)
│ ├── self_test_kats.c -- the actual KAT functions
│ ├── self_test.h
│ ├── fipsindicator.c -- non-approved-algo indicator API
│ ├── fipsparams.inc.in -- the FIPS module's per-machine config schema
│ └── include/ -- private headers
├── fips.module.sources -- list of every source file that goes into fips.so + SHA-256 hashes
├── fips-sources.checksums -- SHA-256 of the module sources, computed at build time
├── fips.checksum -- the integrity check value baked into the module
└── implementations/ -- shared with the default provider; FIPS uses a subsetBuild
To build the FIPS provider you must ./Configure enable-fips. The build produces:
providers/fips.so(the module).providers/fipsmodule.cnf(a generated config file).- The
apps/openssl fipsinstallsubcommand (inapps/fipsinstall.c).
The list of source files compiled into fips.so is exactly providers/fips.module.sources. Touching any file listed there invalidates the recorded checksum, which is how .github/workflows/fips-checksums.yml and util/fips-checksums.sh keep contributors honest.
How the integrity check works
sequenceDiagram
participant App
participant LibCrypto as libcrypto
participant Loader as dlopen(fips.so)
participant ST as self_test.c
participant CFG as fipsmodule.cnf
App->>LibCrypto: OSSL_PROVIDER_load(libctx, "fips")
LibCrypto->>Loader: open the module
Loader->>ST: OSSL_provider_init(...)
ST->>CFG: read recorded HMAC + module's claimed version
ST->>ST: HMAC-SHA-256 over module bytes, compare to fipsmodule.cnf
alt mismatch
ST-->>LibCrypto: failure
else match
ST->>ST: run KATs (self_test_kats.c)
alt KAT fails
ST-->>LibCrypto: failure
else
ST-->>LibCrypto: ok
LibCrypto-->>App: OSSL_PROVIDER *
end
endImplementation:
providers/fips/self_test.c:SELF_TEST_post()is run from the provider init path.- It HMACs the module bytes (using the embedded HMAC key in
include/openssl/fipskey.h.in) and compares against themodule-macvalue infipsmodule.cnf. - It runs Known-Answer Tests for every approved algorithm class. Test vectors are in
providers/fips/self_test_data.c(184 KB of static arrays). - For OpenSSL 3.5 onwards, deferred and on-demand self-tests are available; see
doc/designs/fips_deferred_tests.md.
The openssl fipsinstall subcommand (apps/fipsinstall.c) produces fipsmodule.cnf. It computes the module HMAC, runs the KATs, and writes the resulting status. The output must not be copied between machines on OpenSSL 3.1.2 because the install-status field is host-specific; later versions made this safer.
Algorithm subset
The FIPS provider exposes only FIPS-approved algorithms:
- Digests: SHA-1, SHA-2, SHA-3, SHAKE, KECCAK-KMAC.
- Symmetric: AES-128/192/256 in approved modes (CBC, CCM, CFB, CTR, ECB, GCM, OFB, KW, KWP, XTS, GCM-SIV).
- 3DES (CBC) — limited to legacy use windows.
- Public-key: RSA (PKCS#1 v1.5, PSS, OAEP, KEM), DSA, DH (FFDHE only), ECDSA, ECDH on NIST curves, EdDSA (Ed25519/Ed448), X25519/X448 (CNSA 2.0 / FIPS 186-5).
- KEMs: ML-KEM, RSA-KEM.
- Signatures: ML-DSA, SLH-DSA, LMS.
- KDFs: HKDF, PBKDF2, SS-KDF, SSH-KDF, X9.42, X9.63, KB-KDF, IKEv2-KDF, KRB5-KDF, TLS1-PRF, TLS-1.3-KDF, SRTP-KDF, HMAC-DRBG-KDF.
- MACs: HMAC, CMAC, GMAC, KMAC.
- RNGs: HASH-DRBG, HMAC-DRBG, CTR-DRBG.
ChaCha20, Poly1305, ChaCha20-Poly1305, Argon2, scrypt, AES-OCB, AES-SIV, BLAKE2, MD2/4/5, MDC2, RIPEMD-160, IDEA, RC2/4/5, CAST, SEED, ARIA, Camellia, SM2/3/4 are not in the FIPS provider.
Entropy
The FIPS provider relies on an external entropy source by default. With enable-fips-jitter (3.5+) it ships with an internal jitter entropy source, but using it puts the module in a non-compliant mode unless an entropy assessment (ESV) and CMVP validation are independently completed. See README-FIPS.md for the full discussion.
Indicators (3.5+)
Even in FIPS mode, some algorithms run in a non-approved configuration (e.g. an RSA key smaller than the approved minimum). To allow callers to detect this without breaking working code, the FIPS module exposes per-call indicators:
EVP_CIPHER_CTX_get_params(ctx, OSSL_CIPHER_PARAM_FIPS_APPROVED_INDICATOR …)EVP_MD_CTX_get_params(...)EVP_PKEY_CTX_get_params(...)
The implementation is in providers/fips/fipsindicator.c and providers/common/securitycheck_fips.c. See doc/designs/fips_indicator.md for the design.
Vendor builds
Vendors who patch the FIPS module and submit it under their own CMVP certificate can override the module's reported name and version via VERSION.dat's PRE_RELEASE_TAG, BUILD_METADATA, and FIPS_VENDOR fields. See "3rd-Party Vendor Builds" at the bottom of README-FIPS.md.
Using a validated FIPS provider with a newer libcrypto
The pattern documented in README-FIPS.md:
- Build the validated source tree (e.g. 3.1.2) → produces
providers/fips.soandproviders/fipsmodule.cnf. - Build the latest source tree (e.g. 3.6.x) with
enable-fips. - Replace the latter's
fips.soandfipsmodule.cnfwith those from the validated build. - Verify with
openssl list -provider-path providers -provider fips -providers.
Entry points for modification
- Adding a new approved algorithm: list its source in
providers/fips.module.sources, add a row in the relevantfipsprov.ctable, write KATs inself_test_kats.cwith vectors inself_test_data.c, and updatesecuritycheck_fips.cif there are strength constraints. - Adjusting strength policy:
providers/common/securitycheck_fips.c. - Adjusting the indicator surface:
providers/fips/fipsindicator.c, plus the relevant per-algorithmset_ctx_params. - Modifying the integrity check:
providers/fips/self_test.c. (Rarely changed — needs CMVP-level scrutiny.)
Documentation
README-FIPS.md— user-facing.doc/man7/fips_module.pod— concepts.doc/man5/fips_config.pod—fipsmodule.cnfschema.doc/designs/fips_deferred_tests.md,fips_indicator.md— design notes.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.