On 9/4/25 8:52 AM, Vegard Nossum wrote:
> Add documentation for the FIPS140 standalone module.
>
> Cc: Jonathan Corbet <[email protected]>
> Cc: [email protected]
> Signed-off-by: Vegard Nossum <[email protected]>
> ---
> Documentation/crypto/fips140.rst | 231 +++++++++++++++++++++++++++++++
> Documentation/crypto/index.rst | 1 +
> 2 files changed, 232 insertions(+)
> create mode 100644 Documentation/crypto/fips140.rst
>
> diff --git a/Documentation/crypto/fips140.rst
> b/Documentation/crypto/fips140.rst
> new file mode 100644
> index 000000000000..14a7fb7a69ed
> --- /dev/null
> +++ b/Documentation/crypto/fips140.rst
> @@ -0,0 +1,231 @@
> +=========================
> +FIPS140 standalone module
> +=========================
> +
> +:Author: Vegard Nossum <[email protected]>
> +
> +
> +Target audience
> +===============
> +
> +This document is primarily meant for Linux distribution developers and
> +maintainers. It may also be interesting for kernel developers
> +contributing to the kernel's crypto code as it explains some of the
> +concepts and rationale behind the architecture of the crypto code and
> +how FIPS support is implemented.
> +
> +
> +Introduction
> +============
> +
> +FIPS 140-3 is a Federal Information Protection Standard, "Security
> +Requirements for Cryptographic Modules", maintained by the US National
> +Institute of Standards and Technology (NIST). [#fips140]_
> +
> +Binary implementation of specific approved cryptographic algorithms
> +can be certified as part of the Cryptographic Module Validation
> +Program (CMVP). In practice, the certification process includes both
> +source and binary code, though the end result is a certification
> +attached to the binary code.
> +
> +Having FIPS 140-3 certification is a requirement for running in many
> +secure contexts -- many Linux distros certify their kernels in order
> +to satisfy these requirements.
> +
> +Many distros have certified the entire kernel as a "FIPS module" (not
> +to be confused with kernel modules). Unfortunately, this means that
> +one cannot change any part of the kernel without invalidating the
> +certification. Moreover, certification is a costly process that can
> +last up to or even more than 12 months.
> +
> +The FIPS 140 standalone module (AKA ``fips140.ko``) fixes this situation
> +by allowing one to build the kernel's crypto code once and reuse it in
> +subsequent builds, thus enabling the rest of the kernel to receive bug
> +fixes and updates without invalidating the certification of the FIPS
> +module.
> +
> +
> +Design
> +======
> +
> +Requirements:
> +
> +- the FIPS module must not impose a stable internal kernel API on
> + mainline or stable kernels
> +- the FIPS module must be a single, contiguous binary file and its HMAC
> + (for easy verification)
> +- all crypto algorithms and code must reside within the FIPS module
> +- no crypto code in the FIPS module can be used before the FIPS module
> + has executed its self-tests
> +- the FIPS module only comes into play when the kernel is booted with
> + ``fips=1``
> +- source code should be shared between the kernel and the FIPS module
> + where possible
> +
> +In order to satisfy these requirements, we have settled on a design
> +where the FIPS module duplicates the crypto API and all the algorithm
> +implementations that are part of the FIPS module. To avoid source code
> +duplication, we use symlinks from ``fips140/`` to the rest of the kernel
> +tree and build this directory as an external module -- in other words,
> +all the code and algorithms is built twice; once as part of vmlinux
> +and/or regular (non-FIPS) kernel modules, and once as part of
> +``fips140.ko``.
> +
> +To allow hot-swapping the crypto code (API + algorithms) at runtime
> +(i.e. when ``fips=1`` is detected during boot), we wrap any exported
> +symbols in C macros. These macros use static calls (see [#static_call]_)
> +to patch any and all users of the crypto code to call the FIPS module's
> +version of these functions instead of the functions in vmlinux.
> +
> +``fips140.ko`` is not really an ordinary kernel module -- it is not
> +meant to be loaded with ``modprobe`` or ``insmod``; instead, it is
> +embedded into the ``vmlinux`` image at build time. This avoid any
> +chicken-and-egg issues around how to verify cryptographic signatures
> +without using unverified crypto code. ``fips140.ko`` is loaded during
> +early boot -- before any crypto code is used by the kernel.
Hm, I was going to look at how that is done, but I cannot find any
downloadable fips140 source code. Is it available for free download
somewhere?
Is it GPL-v2 licensed?
> +
> +The code for the FIPS 140 standalone module is therefore split into
> +two parts: the module itself (``fips140.ko``) and the loader
> +(``crypto/fips140-loader.c``). The loader is **NOT** part of the module
> +itself and is not covered by the certification; however, it is
> +essentially just a wrapper around the kernel module loader that runs
> +during early boot.
> +
> +We provide no explicit mechanisms to ensure compatibility between a
> +precompiled FIPS module and the rest of the kernel; this is the
> +responsibility of distros that choose to use the standalone FIPS module.
> +
> +
> +Building
> +========
> +
> +First off, ensure that ``CONFIG_CRYPTO_FIPS140_EXTMOD`` is enabled.
> +
> +Prepare for building out-of-tree module::
> +
> + make modules_prepare
> +
> +Build fips140.ko as an out-of-tree module::
> +
> + make M=fips140/ KBUILD_MODPOST_WARN=1
> + cp fips140/fips140.ko crypto/
> +
> +Generate fips140.hmac::
> +
> + hmac_key=$(awk -F'"' '/^CONFIG_CRYPTO_FIPS140_HMAC_KEY=/{print $2}'
> .config)
> + openssl dgst -sha256 -hmac $hmac_key -binary -out crypto/fips140.hmac
> crypto/fips140.ko
> +
> +Build the rest of the kernel::
> +
> + make
> +
> +
> +Adopting a standaline FIPS module for your distro
> +=================================================
> +
> +1. Carefully select which algorithms you want your FIPS module to
> + provide (``CONFIG_FIPS140_*`` and ``CONFIG_CRYPTO_FIPS140_*``
> + options)
> +
> +2. Integrate building ``fips140/`` as an out-of-tree module with the
> + build system used by your distro's package manager.
> +
> + - You may want to strip and separate out debuginfo before copying
> + ``fips140.ko`` into ``crypto/``.
> + - You need a mechanism to save and reintroduce the precompiled
> + ``fips140.ko`` between builds.
> + - All of this "build support" infrastructure is out of scope for
> + mainline.
> +
> +3. Verify that the FIPS module satisfies your specific operational
> + requirements.
> +
> +4. Submit the FIPS module to the certifying lab.
> +
> +.. warning::
> + Mainline developers cannot and will not assist in getting a specific
> + FIPS module certified. The code provided in the mainline source tree
> + is intended to make certification of standalone FIPS modules easier,
> + but we do not guarantee that a build will be certifiable as-is out of
> + the box. Moreover, different distributions have different use cases,
> + different requirements, etc. and all of this influences the specifics
> + of any given FIPS module. Mainline developers will not be responsible
> + for the certification or certifiability of your FIPS module.
> +
> +
> +Useful commands
> +===============
> +
> +
> +Extracting ``fips140.ko`` from ``vmlinux``
> +------------------------------------------
> +
> +To extract ``fips140.ko`` and ``fips140.hmac`` from an existing
> +``vmlinux`` build, use::
> +
> + $ scripts/extract-fips140 /path/to/vmlinux
> + extracted fips140.ko
> + extracted fips140.hmac
> +
> +
> +Verifying the ``fips140.ko`` HMAC digest
> +----------------------------------------
> +
> +To verify the HMAC digest of ``fips140.ko``, use::
> +
> + $ key="Sphinx of black quartz, judge my vow"
> + $ openssl dgst -sha256 -hmac "$key" -binary fips140.ko >
> fips140.hmac-computed
> + $ cmp -s fips140.hmac fips140.hmac-computed && echo ok
> + ok
> +
> +
> +List the symbols used by ``fips140.ko``
> +---------------------------------------
> +
> +To list the kernel symbols used by ``fips140.ko`` (useful for checking
> +whether all the necessary crypto functions have been included in the
> +module), use::
> +
> + $ nm --undefined-only fips140.ko
> +
> +
> +Quick crypto verification using AF_ALG
> +--------------------------------------
> +
> +Testing whether the code works properly is fairly easy using Python
> +and the ``AF_ALG`` interface, e.g.::
> +
> + import socket
> +
> + ALG_SET_KEY = 1
> +
> + s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
> + s.bind(('hash', 'hmac(sha256)'))
> + s.setsockopt(socket.SOL_ALG, ALG_SET_KEY, b'x' * 16)
> +
> + op, _ = s.accept()
> + op.sendall(b'x' * 32)
> + print(op.recv(32))
> +
> +
> +Tracing the crypto code
> +-----------------------
> +
> +Testing whether the FIPS module is used correctly can also be done
> +using a combination of Python (as above) and ``trace-cmd`` like this::
> +
> + $ sudo trace-cmd record -p function_graph -g __sys_bind python hmac.py
> + $ trace-cmd report
> +
> +
> +Contributing
> +============
> +
> +Patches welcome.
to what/where?
> +
> +
> +References
> +==========
> +
> +.. [#fips140] <https://csrc.nist.gov/pubs/fips/140-3/final>
> +.. [#static_call] <https://lwn.net/Articles/815908/>
Where are the other 103 patches?
thanks.
--
~Randy