Open-Source Wikis

/

OpenSSL

/

Providers

/

FIPS provider

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 subset

Build

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 fipsinstall subcommand (in apps/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
    end

Implementation:

  • 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 the module-mac value in fipsmodule.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:

  1. Build the validated source tree (e.g. 3.1.2) → produces providers/fips.so and providers/fipsmodule.cnf.
  2. Build the latest source tree (e.g. 3.6.x) with enable-fips.
  3. Replace the latter's fips.so and fipsmodule.cnf with those from the validated build.
  4. 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 relevant fipsprov.c table, write KATs in self_test_kats.c with vectors in self_test_data.c, and update securitycheck_fips.c if there are strength constraints.
  • Adjusting strength policy: providers/common/securitycheck_fips.c.
  • Adjusting the indicator surface: providers/fips/fipsindicator.c, plus the relevant per-algorithm set_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.podfipsmodule.cnf schema.
  • 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.

FIPS provider – OpenSSL wiki | Factory