A compliance audit asks whether your OpenSSL build is actually running in FIPS mode, and fips_config(5ssl) is the file that proves it or does not. This page covers a safe workflow for creating and checking that small configuration file, which records the provider module MAC and self-test state. It is not a general OpenSSL configuration and it is not a file to edit by hand.
Allow about fifteen minutes. You need OpenSSL 3.x, the openssl-fipsinstall subcommand, a FIPS provider module supplied for your platform, and permission to read the module and write the destination directory. The examples use OpenSSL 3.0 terminology from fips_config(5ssl). The machine used for these checks has the Ubuntu package openssl 3.0.13-0ubuntu3.15, but its first openssl on PATH is OpenSSL 3.6.1 from Linuxbrew. Check your executable rather than assuming the package database describes it.
Start with ordinary, read-only checks. They need no elevated privileges:
$ command -v openssl
$ openssl version -a
$ openssl fipsinstall -help | sed -n '1,80p'
$ dpkg-query -W -f='${Package} ${Version}\n' openssl 2>/dev/null || true
The help output should include -module, -in, -out and -verify. The last command is only package metadata, and is useful on Debian or Ubuntu. It does not prove that the executable selected by your shell came from that package.
Checkpoint: Record the path and version from the first two commands. Run every later command with that same executable, especially if the host has more than one OpenSSL installation.
The configuration file authenticates a particular provider shared library. Find the module supplied by your OpenSSL installation, rather than guessing a path from an example copied from another distribution:
$ openssl version -m
$ find /path/to/your/openssl -type f -name '*fips*.so' -print
Replace /path/to/your/openssl with an explicit installation directory. On a packaged system, ask the package manager which files belong to the OpenSSL provider package. If no FIPS module exists, stop here: generating a file for a different library would give you a configuration that cannot authenticate the provider you intend to load.
Do not download an arbitrary shared library or copy one between hosts. The MAC in the output is tied to the exact module bytes, and FIPS validation is also tied to the provider build and its security policy.
Generation is the normal creation path. Use a temporary output first, then inspect it before installing it. Writing below /etc is a privileged, security-sensitive change, so this example keeps the first attempt in /tmp:
$ FIPS_MODULE='/path/to/your/fips.so'
$ FIPS_CONFIG='/tmp/fipsmodule.cnf'
$ openssl fipsinstall \
-module "$FIPS_MODULE" \
-out "$FIPS_CONFIG"
INSTALL PASSED
The exact self-test messages can vary. A successful generation ends with a success result and creates the output file. If the command cannot read the module, reports a failed self-test or rejects an option, do not install a partial file. Check the module path and the OpenSSL executable first.
The generated section normally contains names such as activate, install-version, conditional-errors, security-checks, module-mac, install-status and install-mac:
$ sed -n '1,80p' "$FIPS_CONFIG"
[fips_sect]
activate = 1
install-version = 1
conditional-errors = 1
security-checks = 1
module-mac = ...
install-status = INSTALL_SELF_TEST_KATS_RUN
install-mac = ...
The MAC values above are illustrative shape only. Your values must come from your command. Never paste them from documentation or replace them with a newly calculated value after manually changing another field.
Verification reruns the checks against the module and configuration. It is read-only and should happen before copying anything into a system configuration directory:
$ openssl fipsinstall \
-verify \
-module "$FIPS_MODULE" \
-in "$FIPS_CONFIG"
VERIFY PASSED
Treat a non-zero exit status as a deployment failure. Common causes are a configuration edited after generation, an install-status value whose MAC no longer matches, or a different provider module at the path now being verified. A successful verification proves that the file matches that module. It does not prove that an application is actually loading the FIPS provider.
fips_config(5ssl) describes the provider's private section, not the complete parent configuration. The providers section in the parent OpenSSL configuration identifies the section through its fips option. The parent file must also enable configuration diagnostics if you need mistakes to fail loudly:
config_diagnostics = 1
[providers]
fips = fips_sect
.include /etc/ssl/fipsmodule.cnf
[fips_sect]
activate = 1
Do not copy this fragment into production unchanged. The include path, provider section layout and module path are installation-specific, and the generated file already owns the authenticated FIPS options. Follow the parent config(5) layout used by your OpenSSL build and place the generated file where that configuration expects it.
Warning: Changing the active OpenSSL configuration can alter which algorithms applications use and can disrupt services on their next start. Make a recoverable backup, deploy during a maintenance window, and keep the previous configuration available for rollback. If a deployment fails, restore the previous file and restart only the affected service according to its normal recovery procedure.
The generated defaults matter. conditional-errors = 1 makes the FIPS module enter its error mode after a failed continuous test, blocking its services. Setting it to 0 relaxes that response; the operation still fails, but later operations may be attempted. security-checks = 1 enables runtime checks for requirements such as minimum key strength and approved curve names. Disabling it is not a harmless troubleshooting switch: compliance then depends on procedures in the relevant security policy.
If install-status is absent, the module runs its startup self-tests when it loads. That can be intentional, but it changes startup cost and failure timing. The openssl-fipsinstall options that alter self-test timing, conditional errors or security checks should be chosen from the provider's approved deployment guidance, not added to make an error disappear.
Do not confuse this file with a proof that the process is in FIPS mode. Confirm the application's provider configuration separately, and test the algorithms and policy constraints that matter to that application. A normal OpenSSL build may support the subcommand while having no FIPS provider module installed.
PATH.openssl fipsinstall generated the file and completed its self-tests.openssl fipsinstall -verify passed against the same module and file.