diff --git a/README.module-signing b/README.module-signing new file mode 100644 index 000000000..7f2f1acc8 --- /dev/null +++ b/README.module-signing @@ -0,0 +1,65 @@ +SCST and kernel module signing +============================== + +Introduction +------------ + +The purpose of kernel module signatures is to only allow those kernel modules +to be loaded that have been signed with an approved key. A signed kernel +module is a kernel module with a digital signature embedded into the module +stating the owner of the signature created that kernel module. This is a +security mechanism that was introduced in kernel v3.7. If this mechanism is +enabled the signature of a kernel module is verified against the public keys +embedded in the kernel and also against the UEFI public keys. This mechanism +restricts kernel module loading such that only kernel modules signed with +certain keys can be loaded. + +Module Signing and SCST +----------------------- +There are two options when using SCST in combination with a kernel that has +signed kernel modules: + +* Disable the signature verification mechanism by adding module.sig_enforce=0 + at the end of GRUB_CMDLINE_LINUX in /etc/default/grub, by updating grub.cfg + and by rebooting. grub.cfg can be updated by running e.g. the following + command: + + update-bootloader || update-grub || grub2-mkconfig -o /boot/grub2/grub.cfg + +* Enable the signature verification mechanism and load the public key that + was generated during the SCST build process into the UEFI keyring. + +Signing SCST Kernel Modules +--------------------------- +Build and install SCST as usual. During the build process a public/private +key pair will be generated in the scst/src/certs directory: + +ls -l scst/src/certs/scst_module_key* +-rw-------. 1 bart users 1325 Sep 28 16:42 scst/src/certs/scst_module_key.der +-rw-------. 1 bart users 3272 Sep 28 16:42 scst/src/certs/scst_module_key.priv + +Start the process of importing the public key into the UEFI key repository +as follows: + +mokutil --import scst/src/certs/scst_module_key.der + +The mokutil software will ask which password should be used for this key +during the import process. Since this password will be short-lived, any +simple password works. Next, verify with mokutil --list-new whether the +import process has been started. If this is the case, reboot. The bootloader +will start the EFI MOK manager. Use the menus on the screen to activate the +SCST kernel module key. After booting has finished, verify whether loading +and unloading of the main SCST kernel module works: + +modprobe scst && modprobe -r scst + +See Also +-------- +* Linux Kernel Module Signing Documentation, kernel.org + https://www.kernel.org/doc/html/latest/admin-guide/module-signing.html + +* Signed kernel module support, Gentoo Wiki + https://wiki.gentoo.org/wiki/Signed_kernel_module_support + +* Build and install signed Kvaser driver modules + https://www.kvaser.com/developer-blog/build-install-signed-kvaser-driver-modules/ diff --git a/fcst/Makefile b/fcst/Makefile index 76812370c..1b7888aa3 100644 --- a/fcst/Makefile +++ b/fcst/Makefile @@ -74,6 +74,7 @@ tgt: $(MODULE_SYMVERS) $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=n install: all + KDIR=$(KDIR) ../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=m \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/iscsi-scst/Makefile b/iscsi-scst/Makefile index cfb6f9aef..343ac6cbe 100644 --- a/iscsi-scst/Makefile +++ b/iscsi-scst/Makefile @@ -149,11 +149,13 @@ install: all @install -vD -m 644 doc/manpages/iscsi-scstd.8 $(DESTDIR)$(MANDIR)/man8/iscsi-scstd.8 @install -vD -m 755 usr/iscsi-scst-adm $(DESTDIR)$(SBINDIR)/iscsi-scst-adm @install -vD -m 644 doc/manpages/iscsi-scst-adm.8 $(DESTDIR)$(MANDIR)/man8/iscsi-scst-adm.8 + (cd $(KMOD) && KDIR=$(KDIR) ../../scripts/sign-modules) $(MAKE) -C $(KDIR) M=$(KMOD) \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install echo "$@: INFINIBAND_ENABLED = $(INFINIBAND_ENABLED)" if $(INFINIBAND_ENABLED); then \ + (cd $(ISERTMOD) && KDIR=$(KDIR) ../../../scripts/sign-modules) $(MAKE) -C $(KDIR) M=$(ISERTMOD) \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install; \ diff --git a/qla2x00t-32gbit/Makefile b/qla2x00t-32gbit/Makefile index 989beec9f..0576c8687 100644 --- a/qla2x00t-32gbit/Makefile +++ b/qla2x00t-32gbit/Makefile @@ -62,6 +62,7 @@ all: $(CONFIG_SCSI_QLA2XXX_TARGET)=CONFIG_SCSI_QLA2XXX_TARGET install: all + KDIR=$(KDIR) ../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=m \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/qla2x00t-32gbit/qla2x00-target/Makefile b/qla2x00t-32gbit/qla2x00-target/Makefile index 1b40554f4..eb665ff6b 100644 --- a/qla2x00t-32gbit/qla2x00-target/Makefile +++ b/qla2x00t-32gbit/qla2x00-target/Makefile @@ -101,6 +101,7 @@ install: all ifneq ($(BUILD_2X_MODULE),) $(MAKE) M=$(QLA2XXX_DIR) -C $(QLA2XXX_DIR) $@ endif + KDIR=$(KDIR) ../../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=m \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/qla2x00t/Makefile b/qla2x00t/Makefile index fa524ba3e..187755f76 100644 --- a/qla2x00t/Makefile +++ b/qla2x00t/Makefile @@ -59,6 +59,7 @@ all: $(CONFIG_SCSI_QLA2XXX_TARGET)=CONFIG_SCSI_QLA2XXX_TARGET install: all + KDIR=$(KDIR) ../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=m \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/qla2x00t/qla2x00-target/Makefile b/qla2x00t/qla2x00-target/Makefile index 38f48b73a..2b435e517 100644 --- a/qla2x00t/qla2x00-target/Makefile +++ b/qla2x00t/qla2x00-target/Makefile @@ -100,6 +100,7 @@ install: all ifneq ($(BUILD_2X_MODULE),) $(MAKE) M=$(QLA2XXX_DIR) -C $(QLA2XXX_DIR) $@ endif + KDIR=$(KDIR) ../../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=m \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/scripts/sign-modules b/scripts/sign-modules new file mode 100755 index 000000000..4be303ad9 --- /dev/null +++ b/scripts/sign-modules @@ -0,0 +1,18 @@ +#!/bin/bash + +# Parse modules.order and sign the modules found in that file. + +if [ -z "$KDIR" ]; then + echo "Error: \$KDIR has not been set" + exit 1 +fi + +scst_dir=$(dirname "$(cd "$(dirname "$0")" && pwd)") + +CONFIG_MODULE_SIG_HASH=$(sed -n 's/^CONFIG_MODULE_SIG_HASH="\([^"]*\)"$/\1/p' "${KDIR}/.config") + +sed -n 's,kernel/,,p' < modules.order | \ + while read -r f; do + echo "Signing $f" + "${KDIR}/scripts/sign-file" "${CONFIG_MODULE_SIG_HASH}" "${scst_dir}/scst/src/certs/scst_module_key.priv" "${scst_dir}/scst/src/certs/scst_module_key.der" "$f" || exit $? + done diff --git a/scst/src/Makefile b/scst/src/Makefile index e7e7356b1..fecff3214 100644 --- a/scst/src/Makefile +++ b/scst/src/Makefile @@ -111,6 +111,7 @@ $(SCST_INTF_VER_FILE): $(SCST_INC_DIR)/scst.h $(SCST_INC_DIR)/scst_const.h $(SCS echo "\"`sha1sum $(SCST_INC_DIR)/scst_user.h|awk '{printf $$1}'`\"" >>$(SCST_INTF_VER_FILE) all: $(SCST_INTF_VER_FILE) + $(MAKE) -C certs KDIR=$(KDIR) $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_DEV=m scst: @@ -127,6 +128,7 @@ install: all echo Error: the scst and/or scst-devel RPMs must be uninstalled first; \ false; fi -rm -f $(INSTALL_DIR)/scsi_tgt.ko + KDIR=$(KDIR) ../../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd)/dev_handlers \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/scst/src/certs/Makefile b/scst/src/certs/Makefile new file mode 100644 index 000000000..90818f69d --- /dev/null +++ b/scst/src/certs/Makefile @@ -0,0 +1,14 @@ +CONFIG_MODULE_SIG_HASH := $(shell sed -n 's/^CONFIG_MODULE_SIG_HASH="\([^"]*\)"$$/\1/p' "$(KDIR)/.config") + +all: $(shell grep -q '^CONFIG_MODULE_SIG=y$$' "$(KDIR)/.config" && \ + echo module_signing_enabled) + +module_signing_enabled: scst_module_key.der scst_module_key.priv + +scst_module_key.der scst_module_key.priv: x509.genkey + openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 365000 \ + -batch -x509 -config $< -outform DER -out scst_module_key.der \ + -keyout scst_module_key.priv + chmod 600 $@ + +.PHONY: module_signing_enabled diff --git a/scst/src/certs/x509.genkey b/scst/src/certs/x509.genkey new file mode 100644 index 000000000..a6cf048b5 --- /dev/null +++ b/scst/src/certs/x509.genkey @@ -0,0 +1,17 @@ +[ req ] +default_bits = 4096 +distinguished_name = req_distinguished_name +prompt = no +string_mask = utf8only +x509_extensions = myexts + +[ req_distinguished_name ] +#O = Unspecified company +CN = SCST Kernel Modules +#emailAddress = unspecified.user@unspecified.company + +[ myexts ] +basicConstraints=critical,CA:FALSE +keyUsage=digitalSignature +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid diff --git a/scst/src/dev_handlers/Makefile b/scst/src/dev_handlers/Makefile index e07722eb5..c054298e9 100644 --- a/scst/src/dev_handlers/Makefile +++ b/scst/src/dev_handlers/Makefile @@ -65,6 +65,7 @@ all: install: all mkdir -p $(DESTDIR)/var/lib/scst/vdev_mode_pages + KDIR=$(KDIR) ../../../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd) \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/scst_local/Makefile b/scst_local/Makefile index cbbd462a9..4e6173d25 100644 --- a/scst_local/Makefile +++ b/scst_local/Makefile @@ -51,6 +51,7 @@ all: $(MODULE_SYMVERS) $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=m install: all + KDIR=$(KDIR) ../scripts/sign-modules $(MAKE) -C $(KDIR) M=$(shell pwd) BUILD_INI=m \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install diff --git a/srpt/Makefile b/srpt/Makefile index de5a49e3e..2124043d8 100644 --- a/srpt/Makefile +++ b/srpt/Makefile @@ -108,6 +108,7 @@ install: all @[ -z "$(DESTDIR)$(INSTALL_MOD_PATH)" ] && \ find /lib/modules/$(KVER) -name ib_srpt.ko -exec rm {} \; ; \ true + (cd src && KDIR=$(KDIR) ../../scripts/sign-modules) $(MAKE) -C $(KDIR) M=$(shell pwd)/src PRE_CFLAGS="$(PRE_CFLAGS)" \ $$([ -n "$(DEPMOD)" ] && echo "DEPMOD=$(DEPMOD)") \ modules_install