Skip to content

Commit cdd9717

Browse files
neverpanicpvalena
authored andcommitted
feat(fips-crypto-policies): make c-p follow FIPS mode automatically
For a system that uses crypto-policies to be switched to FIPS mode correctly, it needs to be - booted with `fips=1` on the kernel command line - switched to the FIPS crypto-policy (or a policy derived from it) - have the fips dracut module enabled On older systems, there were additional steps, for example, creating `/etc/system-fips`. We have repeatedly seen inconsistencies between those different toggles, either because the user space tooling to switch between those does not (for reliability, maintainability, and compliance reasons) undo some of the steps it does when disabling FIPS mode, or because other installation methods (bootc, containers, image builder) independently do some of those steps. Eventually, all of these ended with user confusion. We can avoid this situation by eliminating the difference by treating the `fips=1` kernel command line switch as a single source of truth, and making all others follow automatically. This module provides this for crypto-policies, by adding bind-mounts before pivot if the system has not already been switched to a FIPS-based crypto-policy. This requires some support from the crypto-policies package (because it needs to deal with the bind mounts when a user calls `update-crypto-policies --set`), so make it a no-op unless - `fips=1` is on the kernel command line - crypto-policies is installed - crypto-policies supports the bind-mounts (indicated by the presence of the `default-fips-config` file) - the policy isn't already FIPS These checks should make this safe to add to the initramfs on all current systems. The bind-mounts also need to happen in the initramfs already, because systemd links against OpenSSL, and doing them later means that systemd will start with an OpenSSL configuration that isn't tailored for FIPS. See also [1], which adds the user space support to crypto-policies, along with a systemd service that does the same steps in case dracut hasn't already done them (which is useful for environments that don't use an initramfs like containers). [1]: https://gitlab.com/redhat-crypto/fedora-crypto-policies/-/merge_requests/191 Signed-off-by: Clemens Lang <[email protected]> (cherry picked from commit bd3c1e1) Resolves: RHEL-59678
1 parent 8097dd4 commit cdd9717

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/sh
2+
3+
type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
4+
5+
if ! fipsmode=$(getarg fips) || [ "$fipsmode" = "0" ] || [ -z "$fipsmode" ]; then
6+
# Do nothing if not in FIPS mode
7+
return 0
8+
fi
9+
10+
policyfile=/etc/crypto-policies/config
11+
fipspolicyfile=/usr/share/crypto-policies/default-fips-config
12+
backends=/etc/crypto-policies/back-ends
13+
fipsbackends=/usr/share/crypto-policies/back-ends/FIPS
14+
15+
# When in FIPS mode, check the active crypto policy by reading the
16+
# $root/etc/crypto-policies/config file. If it is not "FIPS", or does not start
17+
# with "FIPS:", automatically switch to the FIPS policy by creating
18+
# bind-mounts.
19+
20+
if ! [ -r "${NEWROOT}${policyfile}" ]; then
21+
# No crypto-policies configured, possibly not a system that uses
22+
# crypto-policies?
23+
return 0
24+
fi
25+
26+
if ! [ -f "${NEWROOT}${fipspolicyfile}" ]; then
27+
# crypto-policies is too old to deal with automatic bind-mounting of the
28+
# FIPS policy over the normal policy, do not attempt to do the bind-mount.
29+
return 0
30+
fi
31+
32+
policy=$(cat "${NEWROOT}${policyfile}")
33+
34+
# Remove the largest suffix pattern matching ":*" from the string (i.e., the
35+
# complete list of active policy modules), then check for FIPS. This is part of
36+
# POSIX sh (https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02).
37+
if [ "${policy%%:*}" = "FIPS" ]; then
38+
return 0
39+
fi
40+
41+
# Current crypto policy is not FIPS or FIPS-based, but the system is in FIPS
42+
# mode; this is an inconsistent configuration. Automatically bind-mount a FIPS
43+
# configuration over this.
44+
if ! mount -o bind,ro "${NEWROOT}${fipsbackends}" "${NEWROOT}${backends}"; then
45+
warn "Failed to bind-mount FIPS policy over ${backends} (the system is in FIPS mode, but the crypto-policy is not)."
46+
# If this bind-mount failed, don't attempt to do the other one to avoid
47+
# a system that seems to be in FIPS crypto-policy but actually is not.
48+
return 0
49+
fi
50+
51+
mount -o bind,ro "${NEWROOT}${fipspolicyfile}" "${NEWROOT}${policyfile}" \
52+
|| warn "Failed to bind-mount FIPS crypto-policy state file over ${policyfile} (the system is in FIPS mode, but the crypto-policy is not)."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/bash
2+
3+
# called by dracut
4+
check() {
5+
# only enable on systems that use crypto-policies
6+
[ -d "$dracutsysrootdir/etc/crypto-policies" ] && return 0
7+
8+
# include when something else depends on it or it is explicitly requested
9+
return 255
10+
}
11+
12+
# called by dracut
13+
depends() {
14+
return 0
15+
}
16+
17+
# called by dracut
18+
installkernel() {
19+
return 0
20+
}
21+
22+
# called by dracut
23+
install() {
24+
inst_hook pre-pivot 01 "$moddir/fips-crypto-policies.sh"
25+
26+
inst_multiple mount
27+
}

0 commit comments

Comments
 (0)