diff --git a/.distro/dracut.spec b/.distro/dracut.spec index 364010e9..c97b507d 100644 --- a/.distro/dracut.spec +++ b/.distro/dracut.spec @@ -252,6 +252,7 @@ echo 'dracut_rescue_image="yes"' > $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/ %{dracutlibdir}/modules.d/00warpclock %endif %{dracutlibdir}/modules.d/01fips +%{dracutlibdir}/modules.d/01fips-crypto-policies %{dracutlibdir}/modules.d/01systemd-ac-power %{dracutlibdir}/modules.d/01systemd-ask-password %{dracutlibdir}/modules.d/01systemd-bsod diff --git a/modules.d/01fips-crypto-policies/fips-crypto-policies.sh b/modules.d/01fips-crypto-policies/fips-crypto-policies.sh new file mode 100755 index 00000000..ff298298 --- /dev/null +++ b/modules.d/01fips-crypto-policies/fips-crypto-policies.sh @@ -0,0 +1,52 @@ +#!/usr/bin/sh + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +if ! fipsmode=$(getarg fips) || [ "$fipsmode" = "0" ] || [ -z "$fipsmode" ]; then + # Do nothing if not in FIPS mode + return 0 +fi + +policyfile=/etc/crypto-policies/config +fipspolicyfile=/usr/share/crypto-policies/default-fips-config +backends=/etc/crypto-policies/back-ends +fipsbackends=/usr/share/crypto-policies/back-ends/FIPS + +# When in FIPS mode, check the active crypto policy by reading the +# $root/etc/crypto-policies/config file. If it is not "FIPS", or does not start +# with "FIPS:", automatically switch to the FIPS policy by creating +# bind-mounts. + +if ! [ -r "${NEWROOT}${policyfile}" ]; then + # No crypto-policies configured, possibly not a system that uses + # crypto-policies? + return 0 +fi + +if ! [ -f "${NEWROOT}${fipspolicyfile}" ]; then + # crypto-policies is too old to deal with automatic bind-mounting of the + # FIPS policy over the normal policy, do not attempt to do the bind-mount. + return 0 +fi + +policy=$(cat "${NEWROOT}${policyfile}") + +# Remove the largest suffix pattern matching ":*" from the string (i.e., the +# complete list of active policy modules), then check for FIPS. This is part of +# POSIX sh (https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02). +if [ "${policy%%:*}" = "FIPS" ]; then + return 0 +fi + +# Current crypto policy is not FIPS or FIPS-based, but the system is in FIPS +# mode; this is an inconsistent configuration. Automatically bind-mount a FIPS +# configuration over this. +if ! mount -o bind,ro "${NEWROOT}${fipsbackends}" "${NEWROOT}${backends}"; then + warn "Failed to bind-mount FIPS policy over ${backends} (the system is in FIPS mode, but the crypto-policy is not)." + # If this bind-mount failed, don't attempt to do the other one to avoid + # a system that seems to be in FIPS crypto-policy but actually is not. + return 0 +fi + +mount -o bind,ro "${NEWROOT}${fipspolicyfile}" "${NEWROOT}${policyfile}" \ + || warn "Failed to bind-mount FIPS crypto-policy state file over ${policyfile} (the system is in FIPS mode, but the crypto-policy is not)." diff --git a/modules.d/01fips-crypto-policies/module-setup.sh b/modules.d/01fips-crypto-policies/module-setup.sh new file mode 100755 index 00000000..140eae00 --- /dev/null +++ b/modules.d/01fips-crypto-policies/module-setup.sh @@ -0,0 +1,28 @@ +#!/usr/bin/bash + +# called by dracut +check() { + # only enable on systems that use crypto-policies + [ -d "$dracutsysrootdir/etc/crypto-policies" ] && return 0 + + # include when something else depends on it or it is explicitly requested + return 255 +} + +# called by dracut +depends() { + echo fips + return 0 +} + +# called by dracut +installkernel() { + return 0 +} + +# called by dracut +install() { + inst_hook pre-pivot 01 "$moddir/fips-crypto-policies.sh" + + inst_multiple mount +}