Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add release-fips package for FIPS-related functionality #3893

Merged
merged 7 commits into from
Apr 30, 2024

Conversation

bcressey
Copy link
Contributor

Issue number:

Related: #1667

Description of changes:
Add a new "release-fips" package that is installed along with "release" when the FIPS image feature flag is set. This package collects all the functionality required for running in "FIPS mode":

  1. fips=1 is added to the kernel command line.
  2. A FIPS power-on self-test will run first thing on boot. If it fails, the system will halt.
    1. The kernel's HMAC signature must be verified.
    2. FIPS-related kernel modules must be loaded.
    3. The "tcrypt" test module must be loaded successfully.
  3. /usr/fips/bin and /usr/fips/libexec are mounted via overlayfs, so binaries in those directories are available in /usr/bin and /usr/libexec.

Testing done:
Booted aws-dev images for aarch64 and x86_64 with a local edit to enable the FIPS feature flag. The power-on self-test passed and the overlayfs directories were mounted.

In conjunction with the changes in #3887, I built aws-ecs-2 and aws-k8s-1.29 images and verified that they could join clusters and run containers with only the FIPS versions of binaries present.

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

Provide overlay mounts so that binaries installed to `/usr/fips/bin`
and `/usr/fips/libexec` will be available in the standard paths.

Install a bootconfig snippet so that `fips=1` will be added to the
kernel command line, and to "systemd.unit=fipsheck.target" to systemd
to override any default target.

Ensure that `/etc/system-fips` is created by default. This file can
be mounted into containers for certain distros (RHEL, Amazon Linux)
to trigger the use of FIPS certified crypto.

Signed-off-by: Ben Cressey <[email protected]>
This allows other "runlevel" targets to run before "preconfigured".

Signed-off-by: Ben Cressey <[email protected]>
The prepare-boot service calls `prairiedog prepare-boot`, which needs
to find the active partition set in order to mount the correct boot
filesystem.

Previously, this depended on the mark-boot-successful service, which
adjuts the GPT flags for the active partition set. However, it does
not actually change the active partition set, so it's not actually a
required dependency for prepare-boot.

This matters for FIPS integrity checks because the boot filesystem
must be mounted to verify the kernel's HMAC. If the boot is marked as
successful and then the integrity check fails, the system could not
then be rebooted back into the previous partition set.

Signed-off-by: Ben Cressey <[email protected]>
The `sha512hmac` program is required to check kernel integrity when
running in FIPS mode.

Signed-off-by: Ben Cressey <[email protected]>
On boot, before starting any other services, ensure that the kernel's
HMAC signature is valid. Then load any crypto modules included in the
FIPS module boundary before running the "tcrypt" self-test.

Any failures in these tests will cause the system to halt.

Signed-off-by: Ben Cressey <[email protected]>
No FIPS certification is planned for the upstream Amazon Linux 5.10
and 5.15 kernels, so prevent them from being installed in the image
when the FIPS image feature flag is enabled.

Signed-off-by: Ben Cressey <[email protected]>
Comment on lines 16 to 19
# This list of FIPS modules is extracted from /etc/fipsmodules in the initramfs
# after placing AL2023 in FIPS mode.
Source200: fipsmodules-x86_64
Source201: fipsmodules-aarch64
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my least favorite part of this change, but I'm not sure how else to generate this list of files.

The dracut package in AL23 has a list of modules in /usr/lib/dracut/modules.d/01fips/module-setup.sh, but some are architecture-specific and it's not really correct to include all of those. That list gets passed to dracut's instmods function which interacts with the available modules on the running system.

For what it's worth I don't expect this list to change much across the life of the 6.1 kernel - worst case only when it needed to be recertified.

Comment on lines +1 to +5
[Unit]
Description=Isolates preconfigured.target
DefaultDependencies=no
After=fipscheck.target
Requires=fipscheck.target
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very similar to the existing activate-configured.service and activate-multi-user.service.

Comment on lines +12 to +13
StandardOutput=tty
StandardError=inherit
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a common feature of the new units since journald isn't running yet when they run.

Comment on lines +14 to +15
WorkingDirectory=/boot
ExecStart=/usr/bin/sha512hmac -q -c /boot/.vmlinuz.hmac
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight subtlety here - /boot/.vmlinuz.hmac gives the SHA512 HMAC of "vmlinuz" so we need to change the directory first.

Comment on lines +13 to +22
[Service]
Type=oneshot
# Check if it's a generic algorithm the kernel provides. If so, don't continue.
ExecCondition=/usr/bin/grep -qvzE '(name|driver)\\s+:\\s+%i\\s+' /proc/crypto
# Otherwise, attempt to load the module.
ExecStart=-/sbin/modprobe %i
# Ensure that the stderr file exists. Otherwise, grep fails on an empty file.
ExecStart=-/usr/bin/touch /.read-only.%i
# Succeed unless there was a fatal error.
ExecStart=/usr/bin/grep -Fqvzw FATAL /etc/.fips-modprobe.%i
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my attempt at recreating fips_load_crypto from dracut, without a shell and with only systemd unit directives to work with.

@@ -0,0 +1,2 @@
f+ /etc/system-fips 0644 root root -
r /etc/.fips-modprobe.*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We end up writing at least one error to a file like this for every module. We only care about fatal errors from modprobe, which will halt the system before we get to the point of running systemd-tmpfiles. So this just cleans up the garbage with no diagnostic value.

Copy link
Contributor

@yeazelm yeazelm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LTGM!

%make_install

ln -s kcapi-hasher %{buildroot}%{_cross_bindir}/sha512hmac
find %{buildroot} -type f -name '*.hmac' -delete
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are passed the %make_install, why do we need to delete these? Shouldn't they be deleted before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are passed the %make_install, why do we need to delete these? Shouldn't they be deleted before?

The .hmac files are generated by make install, but they refer to the unstripped binaries and would be incorrect if retained.

Comment on lines 261 to 265
cat <<EOF > %{buildroot}%{_cross_unitdir}/check-fips-modules.service.d/"${drop_in}"
[Unit]
Requires=fips-modprobe@${fipsmod}.service
After=fips-modprobe@${fipsmod}.service
EOF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a drop-in.conf.in and sed the replacement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a drop-in.conf.in and sed the replacement?

I can do that. It's more consistent with what we do in other specs, plus it avoids the awkward indentation problem of heredocs.

What=overlay
Where=PREFIX/bin
Type=overlay
Options=lowerdir=PREFIX/fips/bin:PREFIX/bin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, in fips variant, we will be shipping the two versions of the binaries? And hide the no-fips binaries at runtime?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, in fips variant, we will be shipping the two versions of the binaries? And hide the no-fips binaries at runtime?

The packages with fips and non-fips binaries are set to conflict with each other, so they won't both be present. A binary like containerd will either be in /usr/fips/bin or /usr/bin depending on the package that's installed, but not in both places.

This overlay mount is to make sure that regardless of what directory they're in, they are available in /usr/bin and the standard PATH.

@bcressey
Copy link
Contributor Author

⬆️ force push uses a template-and-sed approach instead of a heredoc to generate the drop-in configs

@bcressey bcressey merged commit 2a0ad4c into bottlerocket-os:develop Apr 30, 2024
33 checks passed
@bcressey bcressey deleted the release-fips branch April 30, 2024 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants