]> git.ipfire.org Git - thirdparty/dracut.git/blame - modules.d/01fips/fips.sh
fix: always use mkdir -p
[thirdparty/dracut.git] / modules.d / 01fips / fips.sh
CommitLineData
c2bcc5be 1#!/bin/sh
02c1bd6b 2
e096d861
DM
3# systemd lets stdout go to journal only, but the system
4# has to halt when the integrity check fails to satisfy FIPS.
5if [ -z "$DRACUT_SYSTEMD" ]; then
6 fips_info() {
7 info "$*"
8 }
9else
10 fips_info() {
11 echo "$*" >&2
12 }
13fi
14
4257798f 15mount_boot()
03d8ec26 16{
01583ae4 17 boot=$(getarg boot=)
4257798f
HH
18
19 if [ -n "$boot" ]; then
20 case "$boot" in
01583ae4 21 LABEL=*)
cc02093d
HH
22 boot="$(echo $boot | sed 's,/,\\x2f,g')"
23 boot="/dev/disk/by-label/${boot#LABEL=}"
01583ae4
HH
24 ;;
25 UUID=*)
26 boot="/dev/disk/by-uuid/${boot#UUID=}"
27 ;;
1e057b35
HH
28 PARTUUID=*)
29 boot="/dev/disk/by-partuuid/${boot#PARTUUID=}"
30 ;;
31 PARTLABEL=*)
32 boot="/dev/disk/by-partlabel/${boot#PARTLABEL=}"
33 ;;
cc02093d 34 /dev/*)
01583ae4 35 ;;
b60d5e90
HH
36 *)
37 die "You have to specify boot=<boot device> as a boot option for fips=1" ;;
4257798f 38 esac
674bdee8 39
4257798f
HH
40 if ! [ -e "$boot" ]; then
41 udevadm trigger --action=add >/dev/null 2>&1
42 [ -z "$UDEVVERSION" ] && UDEVVERSION=$(udevadm --version)
43 i=0
44 while ! [ -e $boot ]; do
45 if [ $UDEVVERSION -ge 143 ]; then
46 udevadm settle --exit-if-exists=$boot
47 else
48 udevadm settle --timeout=30
49 fi
50 [ -e $boot ] && break
4257798f
HH
51 sleep 0.5
52 i=$(($i+1))
53 [ $i -gt 40 ] && break
54 done
674bdee8 55 fi
03d8ec26 56
4257798f 57 [ -e "$boot" ] || return 1
03d8ec26 58
9cf7b1c5 59 mkdir -p /boot
e096d861 60 fips_info "Mounting $boot as /boot"
4257798f 61 mount -oro "$boot" /boot || return 1
c9a9968d 62 elif [ -d "$NEWROOT/boot" ]; then
32bd2fbb 63 rm -fr -- /boot
c9a9968d 64 ln -sf "$NEWROOT/boot" /boot
4257798f
HH
65 fi
66}
03d8ec26 67
190047f1
HH
68do_rhevh_check()
69{
70 KERNEL=$(uname -r)
71 kpath=${1}
72
928da574 73 # If we're on RHEV-H, the kernel is in /run/initramfs/live/vmlinuz0
6d58fa27
HH
74 HMAC_SUM_ORIG=$(cat $NEWROOT/boot/.vmlinuz-${KERNEL}.hmac | while read a b || [ -n "$a" ]; do printf "%s\n" $a; done)
75 HMAC_SUM_CALC=$(sha512hmac $kpath | while read a b || [ -n "$a" ]; do printf "%s\n" $a; done || return 1)
190047f1
HH
76 if [ -z "$HMAC_SUM_ORIG" ] || [ -z "$HMAC_SUM_CALC" ] || [ "${HMAC_SUM_ORIG}" != "${HMAC_SUM_CALC}" ]; then
77 warn "HMAC sum mismatch"
78 return 1
79 fi
e096d861 80 fips_info "rhevh_check OK"
190047f1
HH
81 return 0
82}
83
da4c9a95
DM
84nonfatal_modprobe()
85{
86 modprobe $1 2>&1 > /dev/stdout |
87 while read -r line || [ -n "$line" ]; do
88 echo "${line#modprobe: FATAL: }" >&2
89 done
90}
91
b988934a 92fips_load_crypto()
4257798f 93{
02c1bd6b
HH
94 FIPSMODULES=$(cat /etc/fipsmodules)
95
e096d861 96 fips_info "Loading and integrity checking all crypto modules"
748867d1
HH
97 mv /etc/modprobe.d/fips.conf /etc/modprobe.d/fips.conf.bak
98 for _module in $FIPSMODULES; do
99 if [ "$_module" != "tcrypt" ]; then
da4c9a95 100 if ! nonfatal_modprobe "${_module}" 2>/tmp/fips.modprobe_err; then
748867d1
HH
101 # check if kernel provides generic algo
102 _found=0
6d58fa27 103 while read _k _s _v || [ -n "$_k" ]; do
748867d1 104 [ "$_k" != "name" -a "$_k" != "driver" ] && continue
748867d1
HH
105 [ "$_v" != "$_module" ] && continue
106 _found=1
107 break
108 done </proc/crypto
01ffcf34 109 [ "$_found" = "0" ] && cat /tmp/fips.modprobe_err >&2 && return 1
748867d1 110 fi
03d8ec26
HH
111 fi
112 done
748867d1
HH
113 mv /etc/modprobe.d/fips.conf.bak /etc/modprobe.d/fips.conf
114
e096d861 115 fips_info "Self testing crypto algorithms"
10b5dca0 116 modprobe tcrypt || return 1
03d8ec26 117 rmmod tcrypt
b988934a
LN
118}
119
120do_fips()
121{
122 local _v
123 local _s
124 local _v
125 local _module
126
127 KERNEL=$(uname -r)
6f4c2dad 128
e096d861 129 fips_info "Checking integrity of kernel"
928da574
HH
130 if [ -e "/run/initramfs/live/vmlinuz0" ]; then
131 do_rhevh_check /run/initramfs/live/vmlinuz0 || return 1
132 elif [ -e "/run/initramfs/live/isolinux/vmlinuz0" ]; then
133 do_rhevh_check /run/initramfs/live/isolinux/vmlinuz0 || return 1
05b75703
BL
134 elif [ -e "/run/install/repo/images/pxeboot/vmlinuz" ]; then
135 # This is a boot.iso with the .hmac inside the install.img
136 do_rhevh_check /run/install/repo/images/pxeboot/vmlinuz || return 1
190047f1 137 else
3d875f77 138 BOOT_IMAGE="$(getarg BOOT_IMAGE)"
cc6792a0
JL
139
140 # Trim off any leading GRUB boot device (e.g. ($root) )
141 BOOT_IMAGE="$(echo "${BOOT_IMAGE}" | sed 's/^(.*)//')"
142
d818986d
LN
143 BOOT_IMAGE_NAME="${BOOT_IMAGE##*/}"
144 BOOT_IMAGE_PATH="${BOOT_IMAGE%${BOOT_IMAGE_NAME}}"
145
146 if [ -z "$BOOT_IMAGE_NAME" ]; then
147 BOOT_IMAGE_NAME="vmlinuz-${KERNEL}"
9e759aa9 148 elif ! [ -e "/boot/${BOOT_IMAGE_PATH}/${BOOT_IMAGE_NAME}" ]; then
8f5c564c 149 #if /boot is not a separate partition BOOT_IMAGE might start with /boot
d818986d
LN
150 BOOT_IMAGE_PATH=${BOOT_IMAGE_PATH#"/boot"}
151 #on some achitectures BOOT_IMAGE does not contain path to kernel
152 #so if we can't find anything, let's treat it in the same way as if it was empty
153 if ! [ -e "/boot/${BOOT_IMAGE_PATH}/${BOOT_IMAGE_NAME}" ]; then
154 BOOT_IMAGE_NAME="vmlinuz-${KERNEL}"
155 BOOT_IMAGE_PATH=""
156 fi
8f5c564c 157 fi
3d875f77 158
ca4aa848 159 BOOT_IMAGE_HMAC="/boot/${BOOT_IMAGE_PATH}/.${BOOT_IMAGE_NAME}.hmac"
8f5c564c
LN
160 if ! [ -e "${BOOT_IMAGE_HMAC}" ]; then
161 warn "${BOOT_IMAGE_HMAC} does not exist"
3d875f77
HH
162 return 1
163 fi
d818986d 164
ba813779 165 (cd "${BOOT_IMAGE_HMAC%/*}" && sha512hmac -c "${BOOT_IMAGE_HMAC}") || return 1
190047f1 166 fi
6f4c2dad 167
e096d861 168 fips_info "All initrd crypto checks done"
4257798f
HH
169
170 > /tmp/fipsdone
171
172 umount /boot >/dev/null 2>&1
03d8ec26
HH
173
174 return 0
175}