From d8dd3ce56dd98f147d0178a929ffa94decd07107 Mon Sep 17 00:00:00 2001 From: Anderson Toshiyuki Sasaki Date: May 14 2020 16:32:00 +0000 Subject: distribution/fips: Update to work on Fedora On Fedora, crypto-policies and fips-mode-setup are available. --- diff --git a/distribution/fips/Makefile b/distribution/fips/Makefile index 71c57e0..635dd29 100644 --- a/distribution/fips/Makefile +++ b/distribution/fips/Makefile @@ -1,12 +1,12 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Makefile of /distribution/Library/fips -# Description: A set of helpers for FIPS related testing. +# Description: A set of helpers for FIPS 140 testing. # Author: Ondrej Moris # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # -# Copyright (c) 2012 Red Hat, Inc. All rights reserved. +# Copyright (c) 2018 Red Hat, Inc. All rights reserved. # # This copyrighted material is made available to anyone wishing # to use, modify, copy, or redistribute it subject to the terms @@ -29,7 +29,7 @@ export TESTVERSION=1.0 BUILT_FILES= -FILES=$(METADATA) runtest.sh lib.sh Makefile +FILES=$(METADATA) runtest.sh lib.sh Makefile rstrnt-package-workaround.sh .PHONY: all install download clean @@ -50,9 +50,9 @@ $(METADATA): Makefile @echo "Name: $(TEST)" >> $(METADATA) @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "Description: A set of helpers for FIPS related testing" >> $(METADATA) + @echo "Description: A set of helpers for FIPS 140 testing" >> $(METADATA) @echo "Type: Library" >> $(METADATA) - @echo "Requires: coreutils" >> $(METADATA) + @echo "Requires: coreutils crypto-policies fips-mode-setup" >> $(METADATA) @echo "TestTime: 30m" >> $(METADATA) @echo "Provides: library(distribution/fips)" >> $(METADATA) @echo "License: GPLv2" >> $(METADATA) diff --git a/distribution/fips/lib.sh b/distribution/fips/lib.sh index bd4f81b..b549b64 100755 --- a/distribution/fips/lib.sh +++ b/distribution/fips/lib.sh @@ -3,12 +3,12 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # lib.sh of /distribution/Library/fips -# Description: A set of helpers for FIPS related testing. +# Description: A set of helpers for FIPS 140 testing. # Author: Ondrej Moris # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # -# Copyright (c) 2012 Red Hat, Inc. All rights reserved. +# Copyright (c) 2018 Red Hat, Inc. All rights reserved. # # This copyrighted material is made available to anyone wishing # to use, modify, copy, or redistribute it subject to the terms @@ -33,51 +33,252 @@ true <<'=cut' =head1 NAME -distribution/fips - a set of helpers for FIPS related testing +distribution/fips - a set of helpers for FIPS 140 testing =head1 DESCRIPTION -This is a library intended for FIPS related testing. Currently it contains -just a single function checking FIPS status. The library is intended to be -extended. +This is a library intended for FIPS 140 testing. It can check status of +FIPS 140 mode and it can enable FIPS 140 mode. Importing this library +with misconfigured (neither fully disabled nor fully enabled) FIPS 140 mode +will produce an error. =cut # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Variables +# Internal Functions and Variabled # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -true <<'=cut' -=pod +# Directory with this library. +_fipsLIBDIR="" -=head1 GLOBAL VARIABLES +function _workarounds { -=over + local ret_val=0 -=item fipsBOOTDEV + if rlIsRHEL ">=8"; then -Boot device. + # On RHEL-8, rpm cannot verify digests of rpms using MD5 digest in FIPS 140. + # Unfortunately, older test rpms are do not have neither SHA1 nor SHA256 and + # hence cannot be installed. Test installation si done by restraint and we + # have to workaround it not to check digests. + rlRun "cp ${_fipsLIBDIR}/rstrnt-package-workaround.sh /usr/local/bin && \ + chmod a+x /usr/local/bin/rstrnt-package-workaround.sh && \ + echo 'RSTRNT_PKG_CMD=/usr/local/bin/rstrnt-package-workaround.sh' >/usr/share/restraint/pkg_commands.d/rhel" 0 \ + "Apply workaround for installation test rpms with MD5 digest" || ret_val=1 + fi -=item fipsBOOTCONFIG + return $ret_val +} -Location of bootloader configuration file. +function _disablePrelink { + if rlCheckRpm "prelink"; then -=back + # Sometimes prelink complains about files being changed during + # unlinking so let's run a simple yum command to make sure yum + # is not running in the background ("somehow") and wait for it + # to finish (yum automatically uses lockfiles for that). + if ! rlIsRHEL '<5'; then + rlRun "yum list --showduplicates prelink" 0 "Wait for yum" + fi + + # Make sure prelink job is not running now (e.g. started by cron). + rlRun "killall prelink" 0,1 "Kill all prelinks" + rlRun "sed -i 's/PRELINKING=.*/PRELINKING=no/g' /etc/sysconfig/prelink" 0 "Configure system not to use prelink" + rlRun "sync" 0 "Commit change to disk" + rlRun "killall prelink" 0,1 "Kill all prelinks (again)" + rlRun "prelink -u -a" 0 "Un-prelink the system" + fi + + return 0 +} + +function _enforceModulusBits { + if ! rlIsRHEL '<6.5' 5 4; then + if ! grep 'OPENSSL_ENFORCE_MODULUS_BITS' /etc/environment; then + rlRun "echo 'OPENSSL_ENFORCE_MODULUS_BITS=true' >> /etc/environment" 0 "Enable OPENSSL_ENFORCE_MODULUS_BITS (env)" + fi + rlRun "echo 'export OPENSSL_ENFORCE_MODULUS_BITS=true' > /etc/profile.d/openssl.sh && \ + chmod +x /etc/profile.d/openssl.sh && \ + echo 'setenv OPENSSL_ENFORCE_MODULUS_BITS true' > /etc/profile.d/openssl.csh && \ + chmod +x /etc/profile.d/openssl.csh" 0 "Enable OPENSSL_ENFORCE_MODULUS_BITS (profiles)" + + # Beaker tests don't use profile or environment so we have to set + # their environment separately. + BEAKERLIB=${BEAKERLIB:-"/usr/share/beakerlib"} + rlRun "mkdir -p ${BEAKERLIB}/plugins/ && \ + echo 'export OPENSSL_ENFORCE_MODULUS_BITS=true' > ${BEAKERLIB}/plugins/openssl-fips-override.sh && \ + chmod +x ${BEAKERLIB}/plugins/openssl-fips-override.sh" 0 "Enable OPENSSL_ENFORCE_MODULUS_BITS (beaker)" + fi + + return 0 +} + +function _enableFIPS { + + if ! rlIsRHEL "<8"; then + + # Use crypto-policies to set-up FIPS 140 mode. + rlRun "fips-mode-setup --enable" 0 "Enable FIPS 140 mode" + + elif rlIsRHEL ">=6"; then + + # Install dracut and dracut-fips on RHEL7 and RHEL6. + rlCheckRpm "dracut" || rlRun "yum --enablerepo='*' install dracut -y" 0 "Install dracut" + rlCheckRpm "dracut-fips" || rlRun "yum --enablerepo='*' install dracut-fips -y" 0 "Install dracut-fips" + + if grep -qE '\' /proc/cpuinfo && \ + grep -qE '\' /proc/cpuinfo; then + + rlLogInfo "AES instruction set on Intel CPU detected" + + if [ "$IGNORE_AESNI" == "1" ]; then + rlLogInfo "Installation of dracut-fips-aesni skipped" + else + rlCheckRpm "dracut-fips-aesni" || \ + rlRun "yum --enablerepo='*' install -y dracut-fips-aesni" 0 "Install dracut-fips-aesni" + fi + else + rlLogInfo "Intel AES instruction set not detected" + rlCheckRpm "dracut-fips-aesni" && rlRun "yum remove -y dracut-fips-aesni" 0 "Remove dracut-fips-aesni" + fi + + # Re-generate initramfs to include FIPS dracut modules. + rlRun "dracut -v -f" 0 "Regenerate initramfs" + fi + + return 0 +} + +function _modifyBootloader { + + # On RHEL-8, fips-mode-setup binary modifies bootloader. + rlIsRHEL "<8" || return 0 + + local arch=$(uname -i) + local sed_options="--follow-symlinks" + + rlIsRHEL 5 && sed_options="-c" + + # Get block device name. + local boot_dev=$(df -P /boot/ | tail -1 | awk '{print $1}') + if [ -z "$boot_dev" ]; then + rlFail "Can't detect /boot device name, cannot continue!" + rlLog "df /boot/ | tail -1" + return 1 + fi + + if [[ "${USE_UUID:-yes}" != "no" && "${USE_UUID:-1}" != "0" ]]; then + + # Get block device UUID, see BZ 1014527 if UUIDs don't work. + local old_boot_dev=$boot_dev + boot_dev="UUID=$(blkid -s UUID -o value $old_boot_dev)" + if [ "$boot_dev" == "UUID=" ]; then + rlFail "Cannnot detect /boot device UUID, cannot continue!" + rlLog "blkid -s UUID -o value $old_boot_dev" + return 1 + fi + fi + + local bootconf="" + case $arch in + i386|x86_64) + + # Since RHEL-7.4-20170421.1, grub2-efi packages were renamed + # to grub2-efi-ia32 and grub2-efi-x64 + if rpm -qa | grep "grub2-efi"; then + bootconf="/boot/efi/EFI/redhat/grub.cfg" + rlRun "sed -i $sed_options 's/ fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset GRUB fips configuration" + rlRun "sed -i $sed_options 's|\(vmlinuz.*\)|\1 fips=1 boot=$boot_dev|g' $bootconf" 0 \ + "Setup GRUB fips configuration" + elif rpm -qa | grep "grub2"; then + bootconf="/boot/grub2/grub.cfg" + rlRun "sed -i $sed_options 's/ fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset GRUB fips configuration" + rlRun "sed -i $sed_options 's|\(vmlinuz.*\)|\1 fips=1 boot=$boot_dev|g' $bootconf" 0 \ + "Setup GRUB fips configuration" + elif mount | grep -i efi; then + bootconf="/boot/efi/EFI/redhat/grub.conf" + rlRun "sed -i $sed_options 's/ fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset GRUB fips configuration" + rlRun "sed -i $sed_options 's|\(vmlinuz.*\)|\1 fips=1 boot=$boot_dev|g' $bootconf" 0 \ + "Setup GRUB fips configuration" + else + bootconf="/boot/grub/grub.conf" + rlRun "sed -i $sed_options 's/ fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset GRUB fips configuration" + rlRun "sed -i $sed_options 's|\(kernel.*\)|\1 fips=1 boot=$boot_dev|g' $bootconf" 0 \ + "Setup GRUB fips configuration" + fi + ;; + ia64) + bootconf="/etc/elilo.conf" + rlRun "sed -i $sed_options 's/fips=[01] boot=$boot_dev/ /g' $bootconf" 0 + if grep -q 'append' $bootconf; then + rlRun "sed -i $sed_options 's|\(append=.*\)\"|\1 fips=1 boot=$boot_dev\"|g' $bootconf" 0 \ + "Reset elilo fips configuration" + else + rlRun "sed -i $sed_options 's|\(initrd.*\)|\1\n\tappend=\"fips=1 boot=$boot_dev\"|g' $bootconf" 0 \ + "Setup elilo fips configuration" + fi + ;; + ppc|ppc64|ppc64le) + if rpm -qa | grep "grub2-efi"; then + bootconf="/boot/efi/EFI/redhat/grub.cfg" + rlRun "sed -i $sed_options 's/ fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset GRUB fips configuration" + rlRun "sed -i $sed_options 's|\(vmlinuz.*\)|\1 fips=1 boot=$boot_dev|g' $bootconf" 0 \ + "Setup GRUB fips configuration" + elif rpm -qa | grep "grub2"; then + bootconf="/boot/grub2/grub.cfg" + rlRun "sed -i $sed_options 's/ fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset GRUB fips configuration" + rlRun "sed -i $sed_options 's|\(vmlinuz.*\)|\1 fips=1 boot=$boot_dev|g' $bootconf" 0 \ + "Setup GRUB fips configuration" + else + bootconf="/etc/yaboot.conf" + grep -q 'append' $bootconf || \ + rlRun "sed -i $sed_options 's|\(root=.*\)|\1 append=\"\"|g' $bootconf" + rlRun "sed -i $sed_options 's/fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset yaboot configuration" + rlRun "sed -i $sed_options 's|\(append=.*\)\"|\1 fips=1 boot=$boot_dev\"|g' $bootconf" 0 \ + "Setup yaboot configuration" + fi + ;; + s390x) + bootconf="/etc/zipl.conf" + rlRun "sed -i $sed_options 's/ fips=[01] boot=$boot_dev/ /g' $bootconf" 0 \ + "Reset zipl configuration" + rlRun "sed -i $sed_options 's/parameters=\"\(.*\)\"/parameters=\"\1 fips=1 boot=$boot_dev\"/g' $bootconf" 0 \ + "Setup zipl configuration" + rlRun "zipl" 0 "Apply zipl configuration" + ;; + esac +} -=cut # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Functions +# Functions and Variables # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ true <<'=cut' =pod +=head1 VARIABLES + +=head2 fipsMode + +This variable holds state of FIPS mode at the time when library is loaded. + +=over + +=back + =head1 FUNCTIONS =head2 fipsIsEnabled -Function check current state of FIPS mode. Returns 0 if it is correctly +Function check current state of FIPS 140 mode. Returns 0 if it is correctly enabled, 1 if disabled and 2 otherwise (misconfiguration). =over @@ -87,7 +288,10 @@ enabled, 1 if disabled and 2 otherwise (misconfiguration). =cut function fipsIsEnabled { - rlLog "Checking FIPS mode status" + + rlLog "Checking FIPS 140 mode status" + + # Check OpenSSL setting. if rlIsRHEL '>6.5'; then if [[ -n $OPENSSL_ENFORCE_MODULUS_BITS ]]; then rlLog "OpenSSL working in new FIPS mode, 1024 bit RSA disallowed!" @@ -95,30 +299,69 @@ function fipsIsEnabled { rlLog "OpenSSL working in compatibility FIPS mode, 1024 bit allowed" fi fi - if grep -q 1 /proc/sys/crypto/fips_enabled; then - if rlIsRHEL 4 5 || rlIsRHEL '<6.5'; then + + # Check kernelspace FIPS mode. + local kernelspace_fips=$(cat /proc/sys/crypto/fips_enabled) + + # Check userspace FIPS mode. + local userspace_fips=$(test -e /etc/system-fips && echo 1 || echo 0) + + # Check crypto policy. + local cryptopolicy_fips=$(rlIsRHEL "<8" || update-crypto-policies --show) + + # Check crypto policy. + local check_fips=$(rlIsRHEL "<8" || fips-mode-setup --check | grep "FIPS mode") + + # Check FIPS mode. + if rlIsRHEL ">=5" && rlIsRHEL "<6.4"; then + + # In RHEL-5 and before RHEL-6.5, only kernel needs to be in FIPS mode. + if [ "$kernelspace_fips" == "1" ]; then rlLog "FIPS mode is enabled" return 0 else - if [ -e /etc/system-fips ]; then - rlLog "FIPS mode is enabled" - return 0 - else - rlLog "FIPS mode is misconfigured" - rlLog " (kernel flag fips=1 set, but /etc/system-fips is missing)" - return 2 - fi + rlLog "FIPS mode is disabled" + return 1 fi - else - if [ -e /etc/system-fips ]; then - rlLog "FIPS mode is misconfigured" - rlLog " (kernel flag fips=0 set, but /etc/system-fips is present)" - return 2 - else + + elif rlIsRHEL ">=6.5" && rlIsRHEL "<8"; then + + # Since RHEL-6.5 and before RHEL-8.0, both userspace and + # kernelspace need to be in FIPS mode. + if [ "$kernelspace_fips" == "1" ] && [ "$userspace_fips" == "1" ]; then + rlLog "FIPS mode is enabled" + return 0 + elif [ "$kernelspace_fips" == "0" ] && [ "$userspace_fips" == "0" ]; then rlLog "FIPS mode is disabled" return 1 fi + + elif ! rlIsRHEL "<8"; then + + # Since RHEL-8.0, both userspace and kernelspace need to be + # in FIPS mode and FIPS crypto policy must be set, also + # fips-mode-setup --check should report that enabling was + # completed. + if [ "$kernelspace_fips" == "1" ] && \ + [ "$userspace_fips" == "1" ] && \ + [ "$cryptopolicy_fips" == "FIPS" ] && \ + [ "$check_fips" == "FIPS mode is enabled." ] ; then + rlLog "FIPS mode is enabled" + return 0 + elif [ "$kernelspace_fips" == "0" ] && \ + [ "$userspace_fips" == "0" ] && \ + [ "$cryptopolicy_fips" != "FIPS" ] && \ + [ "$check_fips" == "FIPS mode is disabled." ] ; then + rlLog "FIPS mode is disabled" + return 1; + fi fi + + rlLog "FIPS mode is not correctly enabled!" + rlLog "kernelspace fips mode = $kernelspace_fips" + rlLog "userspace fips mode = $userspace_fips" + rlIsRHEL "<8" || rlLog "crypto policy = $cryptopolicy_fips" + rlIsRHEL "<8" || rlLog "fips-mode-setup --check = $check_fips" return 2 } @@ -138,41 +381,42 @@ Returns 0 if FIPS mode is supported, 1 if not. function fipsIsSupported { - local ARCH=`uname -i` - local VER=`cat /etc/redhat-release | sed -n 's/.*\([0-9]\.[0-9]*\).*/\1/p'` - local KERNEL=`uname -r | cut -d '.' -f 1` - local PASS=0 - - rlPhaseStartSetup "Checking FIPS support" + local arch=$(uname -i) + local rhel=$(cat /etc/redhat-release | sed -n 's/.*\([0-9]\.[0-9]*\).*/\1/p') + local kernel=$(uname -r) + local supported=1 - if [ `rlGetDistroRelease` -eq "7" ] && [ "$KERNEL" -eq "4" ]; then - rlLog "Product: RHEL-ALT-$VER" - PASS=1 - else - rlLog "Product: RHEL-$VER" - fi - - rlLog "Architecture: $ARCH" - - # FIPS is not allowed on s390x on RHEL <7.1. - if [[ $ARCH =~ s390 ]] && rlIsRHEL '<7.1'; then - PASS=1 - fi - - # FIPS is not allowed on AArch64. - if [[ $ARCH =~ aarch ]]; then - PASS=1 - fi + rlLog "Checking FIPS 140 support" - if [ "$PASS" -eq "1" ]; then - rlLog "FIPS mode is not supported" - return 1 - fi + # Check RHEL version. + if [[ $rhel =~ 7\. ]] && [[ $kernel =~ ^4\. ]]; then + rlLog "Product: RHEL-ALT-7" + rlLog "FIPS 140 is not supported in RHEL-ALT-7!" + supported=0 + else + rlLog "Product: RHEL-${rhel}" + fi - rlLog "FIPS mode is supported" - return 0 + # Check HW architecture. + rlLog "Architecture: $arch" + if [[ $arch =~ i[36]86 ]] && ! grep -q "sse2" /proc/cpuinfo; then + rlLog "FIPS 140 requires SSE2 instruction set for OpenSSL on Intel!" + supported=0 + elif [[ $arch =~ s390 ]] && rlIsRHEL '<7.1'; then + rlLog "FIPS 140 is not supported on s390x in RHEL older than 7.1!" + supported=0 + elif [[ $ARCH =~ aarch ]] && ! rlIsRHEL '8'; then + rlLog "FIPS 140 is not supported on aarch64 in RHEL older than 8.0!" + supported=0 + fi - rlPhaseEnd + # Report, + if [ "$supported" == "0" ]; then + rlLog "FIPS 140 mode is not supported" + return 1 + fi + rlLog "FIPS 140 mode is supported" + return 0 } true <<'=cut' @@ -180,237 +424,74 @@ true <<'=cut' =head2 fipsEnable -Function enables FIPS 140 product, please notice that the process includes -inevitable restart of the machine. Returns 0 if FIPS mode was correctly enabled, -1 if not and 2 in case that any error was encountered. +Function enables FIPS 140 mode. Enablement must be completed by system restart. +Returns 0 if enabling was successful, 1 otherwise. =over =back =cut - function fipsEnable { - local ARCH=`uname -i` - - rlPhaseStartSetup "Enable FIPS mode" - - # FIPS requires SSE2 instruction set for OpenSSL. - if echo $ARCH | grep "i[36]86" && ! grep "sse2" /proc/cpuinfo; then - rlLogError "FIPS requires SSE2 instruction set for OpenSSL"; - return 1 - fi - - # FIPS must be supported before its enabling. - if ! rlRun "fipsIsSupported"; then - return 1 - fi + rlLog "Enabling FIPS 140 mode" - # Verify the FIPS state. - if grep "1" "/proc/sys/crypto/fips_enabled"; then - if rlIsRHEL ">=6" && !rlCheckRpm "dracut-fips"; then - continue; - fi - rlLog "FIPS is already enabled!" - fi - - # Backup a message of the day. - rlRun "cp -f /etc/motd /var/tmp/motd.backup" 0 - # Turn-off prelink (if prelink is installed). - if rlCheckRpm "prelink"; then - # sometimes prelink complains about files being changed during - # unlinking so let's run a simple yum command to make sure yum - # is not running in the background ("somehow") and wait for it - # to finish (yum automatically uses lockfiles for that) - if ! rlIsRHEL '<5'; then - rlRun "yum list --showduplicates prelink" - fi - - # make sure prelink job is not running now (e.g. started by cron) - rlRun "killall prelink" 0,1 - rlRun "sed -i 's/PRELINKING=.*/PRELINKING=no/g' /etc/sysconfig/prelink" 0 - rlRun "sync" 0 "Commit change to disk" - rlRun "killall prelink" 0,1 - rlRun "prelink -u -a" 0 - fi - - # Enforce 2048 bit limit on RSA and DSA generation (RHBZ#1039105) - if ! rlIsRHEL '<6.5' 5 4; then - if ! grep 'OPENSSL_ENFORCE_MODULUS_BITS' /etc/environment; then - rlRun "echo 'OPENSSL_ENFORCE_MODULUS_BITS=true' >> /etc/environment" - fi - rlRun "echo 'export OPENSSL_ENFORCE_MODULUS_BITS=true' > /etc/profile.d/openssl.sh" - rlRun "chmod +x /etc/profile.d/openssl.sh" - rlRun "echo 'setenv OPENSSL_ENFORCE_MODULUS_BITS true' > /etc/profile.d/openssl.csh" - rlRun "chmod +x /etc/profile.d/openssl.csh" - # beaker tests don't use profile or environment so we have to set - # their environment separately - BEAKERLIB=${BEAKERLIB:-"/usr/share/beakerlib"} - rlRun "mkdir -p '${BEAKERLIB}/plugins/'" 0-255 - rlRun "echo 'export OPENSSL_ENFORCE_MODULUS_BITS=true' > '${BEAKERLIB}/plugins/openssl-fips-override.sh'" - rlRun "chmod +x '${BEAKERLIB}/plugins/openssl-fips-override.sh'" - fi - - if ! rlIsRHEL 5; then - - # Install dracut and dracut-fips on RHEL7 and RHEL6 - rlCheckRpm "dracut" || rlRun "yum --enablerepo='*' install dracut -y" 0 - rlCheckRpm "dracut-fips" || rlRun "yum --enablerepo='*' install dracut-fips -y" 0 - if grep -sE '\' /proc/cpuinfo && grep -sE '\' /proc/cpuinfo; then - rlLogInfo "AES instruction set on Intel CPU detected" - rlCheckRpm "dracut-fips-aesni" || \ - rlRun "yum --enablerepo='*' install -y dracut-fips-aesni" 0 \ - "Installing dracut-fips-aesni" - - else - rlLogInfo "CPU is a non-Intel or lacking AES instruction set" - rlCheckRpm "dracut-fips-aesni" && \ - rlRun "yum remove -y dracut-fips-aesni" 0 "Removing dracut-fips-aesni" - fi - - # Re-generate initramfs to include FIPS integrity checks. - rlLogInfo "Regenerating initramfs" - rlRun "dracut -v -f" 0 - fi - - - return 2 -} + _disablePrelink || return 1 + # Enforce 2048 bit limit on RSA and DSA generation (RHBZ#1039105). + _enforceModulusBits || return 1 -function _modifyBootLoader { + # Workarounds for testing in FIPS 140 mode. + _workarounds || return 1 - local ARCH=`uname -i` + # Enable FIPS 140 mode. + _enableFIPS || return 1 - # Fine-tune SED options - if rlIsRHEL 5; then - SED_OPTIONS='-c' - else - SED_OPTIONS='--follow-symlinks' - fi - - # Remove any FIPS-related kernel parameters first - sed -i $SED_OPTIONS 's/ fips=[01] boot=$fipsBOOTDEV/ /g' $fipsBOOTCONF - sed -i $SED_OPTIONS 's/ fips=[01] boot=$fipsBOOTDEV/ /g' $fipsBOOTCONF + # Modify bootloader. + _modifyBootloader || return 1 - case $ARCH in - i386|x86_64) - if rlCheckRpm "grub2" || rlCheckRpm "grub2-efi"; then - rlRun "sed -i $SED_OPTIONS 's|\(vmlinuz.*\)|\1 fips=1 boot=$BOOT_DEV|g' $BOOTCONF" - else - rlRun "sed -i $SED_OPTIONS 's|\(kernel.*\)|\1 fips=1 boot=$BOOT_DEV|g' $BOOTCONF" 0 - fi - ;; - ia64) - if grep -q 'append' $BOOTCONF; then - rlRun "sed -i $SED_OPTIONS 's|\(append=.*\)\"|\1 fips=1 boot=$BOOT_DEV\"|g' $BOOTCONF" 0 - else - rlRun "sed -i $SED_OPTIONS 's|\(initrd.*\)|\1\n\tappend=\"fips=1 boot=$BOOT_DEV\"|g' $BOOTCONF" 0 - fi - ;; - ppc|ppc64|ppc64le) - if rlCheckRpm "grub2" || rlCheckRpm "grub2-efi"; then - rlRun "sed -i $SED_OPTIONS 's|\(vmlinuz.*\)|\1 fips=1 boot=$BOOT_DEV|g' $BOOTCONF" - else - if grep -q 'append' $BOOTCONF; then - rlRun "sed -i $SED_OPTIONS 's|\(append=.*\)\"|\1 fips=1 boot=$BOOT_DEV\"|g' $BOOTCONF" 0 - else - rlRun "sed -i $SED_OPTIONS 's|\(root=.*\)|\1 append=\"\"|g' $BOOTCONF" - fi - fi - ;; - s390x) - rlRun "sed -i $SED_OPTIONS 's/parameters=\"\(.*\)\"/parameters=\"\1 fips=1 boot=$BOOT_DEV\"/g' $BOOTCONF" 0 - rlRun "zipl" 0 - ;; - - esac + # Success. + return 0 } -function fipsSetState { - - local new_state=$1 - - case "$new_state" in - 0) - ;; - *) - rlLogError "Unexpected state (\"$new_state\" given, 0-3 expected)" - esac - - return 2 -} true <<'=cut' =pod -=head2 fipsDisable +=head2 fipsLibraryLoaded -Function disables FIPS 140 product, please notice that the process includes -inevitable restart of the machine. Returns 0 if FIPS mode was correctly disabled, -1 if not and 2 in case that any error was encountered. +Initialization callback. +Importing this library with misconfigured (neither fully disabled nor +fully enabled) FIPS 140 mode will produce an error. =over =back =cut +function fipsLibraryLoaded { -function fipsDisable { - return 2 -} - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Initialization & Verification -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# This is an initialization and verification callback which will be -# called by rlImport after sourcing the library. The function -# returns 0 only when the library is ready to serve. - -fipsLibraryLoaded() { - - fipsBOOTDEV=`df -P /boot/ | tail -1 | awk '{print $1}'` - if [ -z "$fipsBOOTDEV" ]; then - rlLogError "Unable to detect /boot device name!" - - # debug - df /boot/ - - return 1 - fi + _fipsLIBDIR="/mnt/tests/distribution/Library/fips/" - if [[ "${USE_UUID:-yes}" != "no" && "${USE_UUID:-1}" != "0" ]]; then - - UUID=$(blkid -s UUID -o value $fipsBOOTDEV) - if [ -z "$UUID" ]; then - rlLogError "Unable to detect boot device UUID!" - - # debug - df /boot - blkid -s UUID -o value $fipsBOOTDEV - - return 1 - fi - - fipsBOOTDEV="UUID=$UUID" + # In Fedora, fips-mode-setup is separate package, but cannot + # be installed via fips library dependecies. + if rlIsFedora && ! which fips-mode-setup >/dev/null 2>&1; then + rlLog "Installing Missing fips-mode-setup package" + rlRun "dnf install fips-mode-setup -y" fi - fipsBOOTCONFIG="/boot/grub2/grub.cfg" - case "$(uname -i)" in - i386|x86_64) - rlCheckRpm "grub2" || fipsBOOTCONFIG="/boot/grub/grub.conf" - ;; - ia64) - fipsBOOTCONFIG="/etc/elilo.conf" - ;; - ppc|ppc64) - rlCheckRpm "grub2" || fipsBOOTCONFIG="/boot/etc/yaboot.conf" - ;; - esac - rlLog "Setting fipsBOOTCONFIG=$fipsBOOTCONFIG" + fipsIsEnabled + ret=$? + + if [ $ret == 0 ]; then + fipsMode="enabled" + elif [ $ret == 1 ]; then + fipsMode="disabled" + else + fipsMode="error" + rlFail "FIPS mode is already misconfigured, see above!" + fi return 0 } @@ -433,4 +514,3 @@ Ondrej Moris =back =cut - diff --git a/distribution/fips/rstrnt-package-workaround.sh b/distribution/fips/rstrnt-package-workaround.sh new file mode 100644 index 0000000..a8594d8 --- /dev/null +++ b/distribution/fips/rstrnt-package-workaround.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +tmp_dir=$(mktemp -d) + +shift +operation=$1 +shift +packages=$* + +if [[ "$operation" == "remove" ]]; then + + dnf remove -y $packages + +elif [[ "$operation" == "install" ]]; then + + pushd $tmp_dir + dnf install --downloadonly -y --downloaddir . --skip-broken $packages + rpm -Uhv --nodigest --nofiledigest --nodeps *.rpm + popd +fi + +rm -rf $tmp_dir diff --git a/distribution/fips/runtest.sh b/distribution/fips/runtest.sh index 0d810d9..7c99e77 100755 --- a/distribution/fips/runtest.sh +++ b/distribution/fips/runtest.sh @@ -3,12 +3,12 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # runtest.sh of /distribution/Library/fips -# Description: A set of helpers for FIPS related testing. +# Description: A set of helpers for FIPS 140 testing. # Author: Ondrej Moris # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # -# Copyright (c) 2012 Red Hat, Inc. All rights reserved. +# Copyright (c) 2018 Red Hat, Inc. All rights reserved. # # This copyrighted material is made available to anyone wishing # to use, modify, copy, or redistribute it subject to the terms @@ -27,23 +27,47 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Include Beaker environment -[ -e /usr/bin/rhts-environment.sh ] && . /usr/bin/rhts-environment.sh +[ -e /usr/bin/rhts-environment.sh ] && . /usr/bin/rhts-evironment.sh . /usr/share/beakerlib/beakerlib.sh || exit 1 -PHASE=${PHASE:-Test} - rlJournalStart rlPhaseStartSetup - rlRun "rlImport distribution/fips" + rlRun "rlImport distribution/fips" || rlDie rlPhaseEnd - # Self test - if [[ "$PHASE" =~ "Test" ]]; then + if ! [ -e /var/tmp/fips-reboot ]; then rlPhaseStartTest - rlRun "fipsIsEnabled" 0 - rlPhaseEnd - fi + # Check that FIPS 140 mode is supported. + rlRun "fipsIsSupported" 0,1 + if [ $? -eq 0 ]; then + + # Initially, FIPS mode is disabled. + rlRun "fipsIsEnabled" 1 + + # Enable it. + rlRun "fipsEnable" 0 + + # Before completing setup by restart, system is misconfigured. + rlIsRHEL ">6.5" && rlRun "fipsIsEnabled" 2 + + rlRun "touch /var/tmp/fips-reboot" 0 + + rlPhaseEnd + + rhts-reboot + fi + else + rlPhaseStartTest + + # Now, FIPS mode is enabled. + rlRun "fipsIsEnabled" 0 + + rlRun "rm -f /var/tmp/fips-reboot" 0 + + rlPhaseEnd + fi + rlPhaseStartCleanup rlPhaseEnd rlJournalPrintText