Skip to content

Commit

Permalink
T861: sign all Kernel modules with an ephemeral key
Browse files Browse the repository at this point in the history
The shim review board (which is the secure boot base loader) recommends using
ephemeral keys when signing the Linux Kernel. This commit enables the Kernel
build system to generate a one-time ephemeral key that is used to:

* sign all build-in Kernel modules
* sign all other out-of-tree Kernel modules

The key lives in /tmp and is destroyed after the build container exits and is
named: "VyOS build time autogenerated kernel key".

In addition the Kernel now uses CONFIG_MODULE_SIG_FORCE. This now makes it
unable to load any Kernel Module to the image that is NOT signed by the
ephemeral key.
  • Loading branch information
c-po committed Sep 23, 2024
1 parent b93672d commit 3bdbad7
Show file tree
Hide file tree
Showing 16 changed files with 111 additions and 52 deletions.
13 changes: 13 additions & 0 deletions data/live-build-config/hooks/live/93-sb-sign-kernel.chroot
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh
SIGN_FILE=$(find /usr/lib -name sign-file)
MOK_KEY="/var/lib/shim-signed/mok/MOK.key"
MOK_CERT="/var/lib/shim-signed/mok/MOK.pem"
VMLINUZ=$(readlink /boot/vmlinuz)

if [ ! -f ${MOK_KEY} ]; then
echo "I: Signing key for Linux Kernel not found - Secure Boot not possible"
else
echo "I: Signing Linux Kernel for Secure Boot"
sbsign --key ${MOK_KEY} --cert ${MOK_CERT} /boot/${VMLINUZ} --output /boot/${VMLINUZ}
sbverify --list /boot/${VMLINUZ}
fi
18 changes: 0 additions & 18 deletions data/live-build-config/hooks/live/93-sign-kernel.chroot

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,6 @@ Create Certificate Authority used for Kernel signing. CA is loaded into the
Machine Owner Key store on the target system.

```bash
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -outform DER -out MOK.der -days 36500 -subj "/CN=VyOS Secure Boot CA/" -nodes
openssl req -new -x509 -newkey rsa:4096 -keyout MOK.key -outform DER -out MOK.der -days 36500 -subj "/CN=VyOS Secure Boot CA/" -nodes
openssl x509 -inform der -in MOK.der -out MOK.pem
```

## Kernel Module Signing Key

We do not make use of ephemeral keys for Kernel module signing. Instead a key
is generated and signed by the VyOS Secure Boot CA which signs all the Kernel
modules during ISO assembly if present.

```bash
openssl req -newkey rsa:2048 -keyout kernel.key -out kernel.csr -subj "/CN=VyOS Secure Boot Signer 2024 - linux/" -nodes
openssl x509 -req -in kernel.csr -CA MOK.pem -CAkey MOK.key -CAcreateserial -out kernel.pem -days 730 -sha256
```
2 changes: 2 additions & 0 deletions packages/linux-kernel/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
/QAT*
*.tar.xz
/*.postinst
/ephemeral.key
/ephemeral.pem

# Intel Driver source
i40e-*/
Expand Down
18 changes: 15 additions & 3 deletions packages/linux-kernel/arch/x86/configs/vyos_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,7 @@ CONFIG_FUNCTION_ALIGNMENT=16

CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULE_SIG_FORMAT=y
CONFIG_MODULES=y
# CONFIG_MODULE_DEBUG is not set
CONFIG_MODULE_FORCE_LOAD=y
Expand All @@ -851,7 +852,15 @@ CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_ASM_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_MODULE_SIG is not set
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
# CONFIG_MODULE_SIG_SHA1 is not set
# CONFIG_MODULE_SIG_SHA224 is not set
# CONFIG_MODULE_SIG_SHA256 is not set
# CONFIG_MODULE_SIG_SHA384 is not set
CONFIG_MODULE_SIG_SHA512=y
CONFIG_MODULE_SIG_HASH="sha512"
CONFIG_MODULE_COMPRESS_NONE=y
# CONFIG_MODULE_COMPRESS_GZIP is not set
# CONFIG_MODULE_COMPRESS_XZ is not set
Expand Down Expand Up @@ -5888,8 +5897,11 @@ CONFIG_SIGNED_PE_FILE_VERIFICATION=y
#
# Certificates for signature checking
#
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_MODULE_SIG_KEY_TYPE_RSA=y
# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set
# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
# CONFIG_SYSTEM_TRUSTED_KEYS is not set
# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
# CONFIG_SECONDARY_TRUSTED_KEYRING is not set
# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
Expand Down
4 changes: 4 additions & 0 deletions packages/linux-kernel/build-accel-ppp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ cmake -DBUILD_IPOE_DRIVER=TRUE \
-DMODULES_KDIR=${KERNEL_VERSION}${KERNEL_SUFFIX} \
-DCPACK_TYPE=Debian12 ..
make

# Sign generated Kernel modules
${CWD}/sign-modules.sh .

cpack -G DEB

# rename resulting Debian package according git description
Expand Down
3 changes: 3 additions & 0 deletions packages/linux-kernel/build-intel-ixgbe.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ fi
echo "I: Building Debian package vyos-intel-${DRIVER_NAME}"
cd ${CWD}

# Sign generated Kernel modules
${CWD}/sign-modules.sh ${DEBIAN_DIR}

# delete non required files which are also present in the kernel package
# und thus lead to duplicated files
find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f
Expand Down
3 changes: 3 additions & 0 deletions packages/linux-kernel/build-intel-ixgbevf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ fi
echo "I: Building Debian package vyos-intel-${DRIVER_NAME}"
cd ${CWD}

# Sign generated Kernel modules
${CWD}/sign-modules.sh ${DEBIAN_DIR}

# delete non required files which are also present in the kernel package
# und thus lead to duplicated files
find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f
Expand Down
3 changes: 3 additions & 0 deletions packages/linux-kernel/build-intel-qat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ fi
echo "I: Building Debian package vyos-intel-${DRIVER_NAME}"
cd ${CWD}

# Sign generated Kernel modules
${CWD}/sign-modules.sh ${DEBIAN_DIR}

# delete non required files which are also present in the kernel package
# und thus lead to duplicated files
find ${DEBIAN_DIR} -name "modules.*" | xargs rm -f
Expand Down
4 changes: 2 additions & 2 deletions packages/linux-kernel/build-jool.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def add_depends(package_dir: str, package_name: str,
# main packaging script based on dh7 syntax
%:
dh $@
dh $@
override_dh_clean:
dh_clean --exclude=debian/{PACKAGE_NAME}.substvars
Expand All @@ -87,7 +87,7 @@ def add_depends(package_dir: str, package_name: str,
install -D -m 644 src/mod/common/jool_common.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/jool_common.ko
install -D -m 644 src/mod/nat64/jool.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/jool.ko
install -D -m 644 src/mod/siit/jool_siit.ko ${{PACKAGE_BUILD_DIR}}/lib/modules/${{KVER}}/${{MODULES_DIR}}/jool_siit.ko
${{KERNEL_DIR}}/../sign-modules.sh ${{PACKAGE_BUILD_DIR}}/lib
'''
bild_rules = Path(f'{PACKAGE_DIR}/debian/rules')
bild_rules.write_text(build_rules_text)
Expand Down
45 changes: 28 additions & 17 deletions packages/linux-kernel/build-kernel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ if [ ! -d ${KERNEL_SRC} ]; then
exit 1
fi

echo "I: Copy Kernel config (x86_64_vyos_defconfig) to Kernel Source"
cp -rv arch/ ${KERNEL_SRC}/

cd ${KERNEL_SRC}

echo "I: clean modified files"
git reset --hard HEAD
git clean --force -d -x

echo "I: Copy Kernel config (x86_64_vyos_defconfig) to Kernel Source"
cp -rv ${CWD}/arch/ .

KERNEL_VERSION=$(make kernelversion)
KERNEL_SUFFIX=-$(awk -F "= " '/kernel_flavor/ {print $2}' ../../../data/defaults.toml | tr -d \")
Expand All @@ -32,6 +33,9 @@ do
patch -p1 < ${PATCH_DIR}/${patch}
done

# Change name of Signing Cert
sed -i -e "s/CN =.*/CN=VyOS build time autogenerated kernel key/" certs/default_x509.genkey

TRUSTED_KEYS_FILE=trusted_keys.pem
# start with empty key file
echo -n "" > $TRUSTED_KEYS_FILE
Expand All @@ -41,16 +45,8 @@ if [ ! -z "${CERTS}" ]; then
for file in $CERTS; do
cat $file >> $TRUSTED_KEYS_FILE
done

# Force Kernel module signing and embed public keys
echo "CONFIG_MODULE_SIG_FORMAT=y" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG=y" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_FORCE=y" >> $KERNEL_CONFIG
echo "# CONFIG_MODULE_SIG_ALL is not set" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_SHA512=y" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_HASH=\"sha512\"" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_KEY=\"\"" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_KEY_TYPE_RSA=y" >> $KERNEL_CONFIG
echo "CONFIG_SYSTEM_TRUSTED_KEYRING" >> $KERNEL_CONFIG
echo "CONFIG_SYSTEM_TRUSTED_KEYS=\"$TRUSTED_KEYS_FILE\"" >> $KERNEL_CONFIG
fi

Expand All @@ -59,21 +55,36 @@ echo "I: make vyos_defconfig"
make vyos_defconfig

echo "I: Generate environment file containing Kernel variable"
EPHEMERAL_KEY="/tmp/ephemeral.key"
EPHEMERAL_PEM="/tmp/ephemeral.pem"
cat << EOF >${CWD}/kernel-vars
#!/bin/sh
export KERNEL_VERSION=${KERNEL_VERSION}
export KERNEL_SUFFIX=${KERNEL_SUFFIX}
export KERNEL_DIR=${CWD}/${KERNEL_SRC}
export EPHEMERAL_KEY=${EPHEMERAL_KEY}
export EPHEMERAL_CERT=${EPHEMERAL_PEM}
EOF

echo "I: Build Debian Kernel package"
touch .scmversion
make bindeb-pkg BUILD_TOOLS=1 LOCALVERSION=${KERNEL_SUFFIX} KDEB_PKGVERSION=${KERNEL_VERSION}-1 -j $(getconf _NPROCESSORS_ONLN)

# Back to the old Kernel build-scripts directory
cd $CWD
if [[ $? == 0 ]]; then
for package in $(ls linux-*.deb)
do
ln -sf linux-kernel/$package ..
done
EPHEMERAL_KERNEL_KEY=$(grep -E "^CONFIG_MODULE_SIG_KEY=" ${KERNEL_SRC}/$KERNEL_CONFIG | awk -F= '{print $2}' | tr -d \")
if test -f "${EPHEMERAL_KEY}"; then
rm -f ${EPHEMERAL_KEY}
fi
if test -f "${EPHEMERAL_PEM}"; then
rm -f ${EPHEMERAL_PEM}
fi
if test -f "${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY}"; then
openssl rsa -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_KEY}
openssl x509 -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_PEM}
fi

for package in $(ls linux-*.deb)
do
ln -sf linux-kernel/$package ..
done
12 changes: 12 additions & 0 deletions packages/linux-kernel/build-mellanox-ofed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ cp $(find $CWD/$DRIVER_DIR/DEBS/$DEB_DISTRO -type f | grep '\.deb$') "$CWD/"

echo "I: Cleanup ${DRIVER_NAME} source"
cd ${CWD}

# Sign modules
DEB_NAME=$(ls mlnx-ofed-kernel-modules_*)
TMP_DIR="tmp-ofed-sign"
dpkg-deb --raw-extract ${DEB_NAME} ${TMP_DIR}
# Sign generated Kernel modules
${CWD}/sign-modules.sh ${TMP_DIR}
# Cleanup and repack DEB
rm -f ${DEB_NAME}
dpkg-deb --build ${TMP_DIR} ${DEB_NAME}
rm -rf ${TMP_DIR}

if [ -f ${DRIVER_FILE} ]; then
rm -f ${DRIVER_FILE}
fi
Expand Down
3 changes: 3 additions & 0 deletions packages/linux-kernel/build-nat-rtsp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ fpm --input-type dir --output-type deb --name nat-rtsp \
--after-install ${DEBIAN_POSTINST} \
--license "GPL2" --chdir tmp

# Sign generated Kernel modules
${CWD}/sign-modules.sh ${DEBIAN_DIR}

mv *.deb ..

if [ -f ${DEBIAN_POSTINST} ]; then
Expand Down
3 changes: 3 additions & 0 deletions packages/linux-kernel/build-openvpn-dco.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ fpm --input-type dir --output-type deb --name openvpn-dco \
--depends linux-image-${KERNEL_VERSION}${KERNEL_SUFFIX} \
--license "GPL2" --chdir tmp

# Sign generated Kernel modules
${CWD}/sign-modules.sh ${DEBIAN_DIR}

mv *.deb ..
14 changes: 14 additions & 0 deletions packages/linux-kernel/sign-modules.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

BASE_DIR=$(dirname $0)
MODULE_DIR=$1
. ${BASE_DIR}/kernel-vars

SIGN_FILE="${KERNEL_DIR}/scripts/sign-file"

if [ -f ${EPHEMERAL_KEY} ] && [ -f ${EPHEMERAL_CERT} ]; then
find ${MODULE_DIR} -type f -name \*.ko | while read MODULE; do
${SIGN_FILE} sha512 ${EPHEMERAL_KEY} ${EPHEMERAL_CERT} ${MODULE}
done
fi

5 changes: 5 additions & 0 deletions scripts/check-qemu-install
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,11 @@ try:
c.sendline('systemd-detect-virt')
c.expect('kvm')
c.expect(op_mode_prompt)
# Ensure ephemeral key is loaded
vyos_kernel_key = 'VyOS build time autogenerated kernel key'
c.sendline(f'show log kernel | match "{vyos_kernel_key}"')
c.expect(f'.*{vyos_kernel_key}.*')
c.expect(op_mode_prompt)

#################################################
# Executing test-suite
Expand Down

0 comments on commit 3bdbad7

Please sign in to comment.